1use std::borrow::Cow;
14use std::sync::Arc;
15
16use crate::error::Result;
17use crate::expressions::*;
18use crate::DialectType;
19
20pub struct Generator {
45 config: Arc<GeneratorConfig>,
46 output: String,
47 unsupported_messages: Vec<String>,
48 indent_level: usize,
49 athena_hive_context: bool,
52 sqlite_inline_pk_columns: std::collections::HashSet<String>,
54 merge_strip_qualifiers: Vec<String>,
56 clickhouse_nullable_depth: i32,
61}
62
63#[derive(Debug, Clone, Copy, PartialEq, Default)]
69pub enum NormalizeFunctions {
70 #[default]
72 Upper,
73 Lower,
75 None,
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Default)]
81pub enum LimitFetchStyle {
82 #[default]
84 Limit,
85 Top,
87 FetchFirst,
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
93pub enum NotInStyle {
94 #[default]
96 Prefix,
97 Infix,
99}
100
101#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
103pub enum UnsupportedLevel {
104 Ignore,
106 #[default]
108 Warn,
109 Raise,
111 Immediate,
113}
114
115#[derive(Debug, Clone, Copy, PartialEq, Eq)]
116enum ConnectorOperator {
117 And,
118 Or,
119}
120
121impl ConnectorOperator {
122 fn keyword(self) -> &'static str {
123 match self {
124 Self::And => "AND",
125 Self::Or => "OR",
126 }
127 }
128}
129
130#[derive(Debug, Clone, Copy, PartialEq)]
132pub struct IdentifierQuoteStyle {
133 pub start: char,
135 pub end: char,
137}
138
139impl Default for IdentifierQuoteStyle {
140 fn default() -> Self {
141 Self {
142 start: '"',
143 end: '"',
144 }
145 }
146}
147
148impl IdentifierQuoteStyle {
149 pub const DOUBLE_QUOTE: Self = Self {
151 start: '"',
152 end: '"',
153 };
154 pub const BACKTICK: Self = Self {
156 start: '`',
157 end: '`',
158 };
159 pub const BRACKET: Self = Self {
161 start: '[',
162 end: ']',
163 };
164}
165
166#[derive(Debug, Clone)]
188pub struct GeneratorConfig {
189 pub pretty: bool,
192 pub indent: &'static str,
194 pub max_text_width: usize,
196 pub identifier_quote: char,
198 pub identifier_quote_style: IdentifierQuoteStyle,
200 pub uppercase_keywords: bool,
202 pub normalize_identifiers: bool,
204 pub dialect: Option<crate::dialects::DialectType>,
206 pub source_dialect: Option<crate::dialects::DialectType>,
208 pub unsupported_level: UnsupportedLevel,
210 pub max_unsupported: usize,
212 pub normalize_functions: NormalizeFunctions,
214 pub string_escape: char,
216 pub case_sensitive_identifiers: bool,
218 pub identifiers_can_start_with_digit: bool,
220 pub always_quote_identifiers: bool,
223 pub not_in_style: NotInStyle,
225
226 pub null_ordering_supported: bool,
230 pub ignore_nulls_in_func: bool,
233 pub nvl2_supported: bool,
235
236 pub limit_fetch_style: LimitFetchStyle,
239 pub limit_is_top: bool,
241 pub limit_only_literals: bool,
243
244 pub single_string_interval: bool,
247 pub interval_allows_plural_form: bool,
249
250 pub cte_recursive_keyword_required: bool,
253
254 pub values_as_table: bool,
257 pub wrap_derived_values: bool,
259
260 pub tablesample_seed_keyword: &'static str,
263 pub tablesample_requires_parens: bool,
265 pub tablesample_size_is_rows: bool,
267 pub tablesample_keywords: &'static str,
269 pub tablesample_with_method: bool,
271 pub alias_post_tablesample: bool,
273
274 pub aggregate_filter_supported: bool,
277 pub multi_arg_distinct: bool,
279 pub quantified_no_paren_space: bool,
281 pub supports_median: bool,
283
284 pub supports_select_into: bool,
287 pub locking_reads_supported: bool,
289
290 pub rename_table_with_db: bool,
293 pub semi_anti_join_with_side: bool,
295 pub supports_table_alias_columns: bool,
297 pub join_hints: bool,
299 pub table_hints: bool,
301 pub query_hints: bool,
303 pub query_hint_sep: &'static str,
305 pub supports_column_join_marks: bool,
307
308 pub index_using_no_space: bool,
312 pub supports_unlogged_tables: bool,
314 pub supports_create_table_like: bool,
316 pub like_property_inside_schema: bool,
318 pub alter_table_include_column_keyword: bool,
320 pub supports_table_copy: bool,
322 pub alter_set_type: &'static str,
324 pub alter_set_wrapped: bool,
326
327 pub tz_to_with_time_zone: bool,
330 pub supports_convert_timezone: bool,
332
333 pub json_type_required_for_extraction: bool,
336 pub json_path_bracketed_key_supported: bool,
338 pub json_path_single_quote_escape: bool,
340 pub quote_json_path: bool,
342 pub json_key_value_pair_sep: &'static str,
344
345 pub copy_params_are_wrapped: bool,
348 pub copy_params_eq_required: bool,
350 pub copy_has_into_keyword: bool,
352
353 pub supports_window_exclude: bool,
356 pub unnest_with_ordinality: bool,
358 pub lowercase_window_frame_keywords: bool,
361 pub normalize_window_frame_between: bool,
364
365 pub array_concat_is_var_len: bool,
368 pub array_size_dim_required: Option<bool>,
371 pub can_implement_array_any: bool,
373 pub array_size_name: &'static str,
375
376 pub supports_between_flags: bool,
379
380 pub is_bool_allowed: bool,
383 pub ensure_bools: bool,
385
386 pub extract_allows_quotes: bool,
389 pub normalize_extract_date_parts: bool,
391
392 pub try_supported: bool,
395 pub supports_uescape: bool,
397 pub supports_to_number: bool,
399 pub supports_single_arg_concat: bool,
401 pub last_day_supports_date_part: bool,
403 pub supports_exploding_projections: bool,
405 pub supports_unix_seconds: bool,
407 pub supports_like_quantifiers: bool,
409 pub supports_decode_case: bool,
411 pub set_op_modifiers: bool,
413 pub update_statement_supports_from: bool,
415
416 pub collate_is_func: bool,
419
420 pub duplicate_key_update_with_set: bool,
423 pub insert_overwrite: &'static str,
425
426 pub returning_end: bool,
429
430 pub matched_by_source: bool,
433
434 pub create_function_return_as: bool,
437 pub parameter_default_equals: bool,
439
440 pub computed_column_with_type: bool,
443
444 pub unpivot_aliases_are_identifiers: bool,
447
448 pub star_except: &'static str,
451
452 pub hex_func: &'static str,
455
456 pub with_properties_prefix: &'static str,
459
460 pub pad_fill_pattern_is_required: bool,
463
464 pub index_on: &'static str,
467
468 pub groupings_sep: &'static str,
471
472 pub struct_delimiter: (&'static str, &'static str),
475 pub struct_curly_brace_notation: bool,
477 pub array_bracket_only: bool,
479 pub struct_field_sep: &'static str,
481
482 pub except_intersect_support_all_clause: bool,
485
486 pub parameter_token: &'static str,
489 pub named_placeholder_token: &'static str,
491
492 pub data_type_specifiers_allowed: bool,
495
496 pub schema_comment_with_eq: bool,
500}
501
502impl Default for GeneratorConfig {
503 fn default() -> Self {
504 Self {
505 pretty: false,
507 indent: " ",
508 max_text_width: 80,
509 identifier_quote: '"',
510 identifier_quote_style: IdentifierQuoteStyle::DOUBLE_QUOTE,
511 uppercase_keywords: true,
512 normalize_identifiers: false,
513 dialect: None,
514 source_dialect: None,
515 unsupported_level: UnsupportedLevel::Warn,
516 max_unsupported: 3,
517 normalize_functions: NormalizeFunctions::Upper,
518 string_escape: '\'',
519 case_sensitive_identifiers: false,
520 identifiers_can_start_with_digit: false,
521 always_quote_identifiers: false,
522 not_in_style: NotInStyle::Prefix,
523
524 null_ordering_supported: true,
526 ignore_nulls_in_func: false,
527 nvl2_supported: true,
528
529 limit_fetch_style: LimitFetchStyle::Limit,
531 limit_is_top: false,
532 limit_only_literals: false,
533
534 single_string_interval: false,
536 interval_allows_plural_form: true,
537
538 cte_recursive_keyword_required: true,
540
541 values_as_table: true,
543 wrap_derived_values: true,
544
545 tablesample_seed_keyword: "SEED",
547 tablesample_requires_parens: true,
548 tablesample_size_is_rows: true,
549 tablesample_keywords: "TABLESAMPLE",
550 tablesample_with_method: true,
551 alias_post_tablesample: false,
552
553 aggregate_filter_supported: true,
555 multi_arg_distinct: true,
556 quantified_no_paren_space: false,
557 supports_median: true,
558
559 supports_select_into: false,
561 locking_reads_supported: true,
562
563 rename_table_with_db: true,
565 semi_anti_join_with_side: true,
566 supports_table_alias_columns: true,
567 join_hints: true,
568 table_hints: true,
569 query_hints: true,
570 query_hint_sep: ", ",
571 supports_column_join_marks: false,
572
573 index_using_no_space: false,
575 supports_unlogged_tables: false,
576 supports_create_table_like: true,
577 like_property_inside_schema: false,
578 alter_table_include_column_keyword: true,
579 supports_table_copy: true,
580 alter_set_type: "SET DATA TYPE",
581 alter_set_wrapped: false,
582
583 tz_to_with_time_zone: false,
585 supports_convert_timezone: false,
586
587 json_type_required_for_extraction: false,
589 json_path_bracketed_key_supported: true,
590 json_path_single_quote_escape: false,
591 quote_json_path: true,
592 json_key_value_pair_sep: ":",
593
594 copy_params_are_wrapped: true,
596 copy_params_eq_required: false,
597 copy_has_into_keyword: true,
598
599 supports_window_exclude: false,
601 unnest_with_ordinality: true,
602 lowercase_window_frame_keywords: false,
603 normalize_window_frame_between: false,
604
605 array_concat_is_var_len: true,
607 array_size_dim_required: None,
608 can_implement_array_any: false,
609 array_size_name: "ARRAY_LENGTH",
610
611 supports_between_flags: false,
613
614 is_bool_allowed: true,
616 ensure_bools: false,
617
618 extract_allows_quotes: true,
620 normalize_extract_date_parts: false,
621
622 try_supported: true,
624 supports_uescape: true,
625 supports_to_number: true,
626 supports_single_arg_concat: true,
627 last_day_supports_date_part: true,
628 supports_exploding_projections: true,
629 supports_unix_seconds: false,
630 supports_like_quantifiers: true,
631 supports_decode_case: true,
632 set_op_modifiers: true,
633 update_statement_supports_from: true,
634
635 collate_is_func: false,
637
638 duplicate_key_update_with_set: true,
640 insert_overwrite: " OVERWRITE TABLE",
641
642 returning_end: true,
644
645 matched_by_source: true,
647
648 create_function_return_as: true,
650 parameter_default_equals: false,
651
652 computed_column_with_type: true,
654
655 unpivot_aliases_are_identifiers: true,
657
658 star_except: "EXCEPT",
660
661 hex_func: "HEX",
663
664 with_properties_prefix: "WITH",
666
667 pad_fill_pattern_is_required: false,
669
670 index_on: "ON",
672
673 groupings_sep: ",",
675
676 struct_delimiter: ("<", ">"),
678 struct_curly_brace_notation: false,
679 array_bracket_only: false,
680 struct_field_sep: " ",
681
682 except_intersect_support_all_clause: true,
684
685 parameter_token: "@",
687 named_placeholder_token: ":",
688
689 data_type_specifiers_allowed: false,
691
692 schema_comment_with_eq: true,
694 }
695 }
696}
697
698mod reserved_keywords {
701 use std::collections::HashSet;
702 use std::sync::LazyLock;
703
704 pub static SQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
706 [
707 "all",
708 "alter",
709 "and",
710 "any",
711 "array",
712 "as",
713 "asc",
714 "at",
715 "authorization",
716 "begin",
717 "between",
718 "both",
719 "by",
720 "case",
721 "cast",
722 "check",
723 "collate",
724 "column",
725 "commit",
726 "constraint",
727 "create",
728 "cross",
729 "cube",
730 "current",
731 "current_date",
732 "current_time",
733 "current_timestamp",
734 "current_user",
735 "default",
736 "delete",
737 "desc",
738 "distinct",
739 "drop",
740 "else",
741 "end",
742 "escape",
743 "except",
744 "execute",
745 "exists",
746 "external",
747 "false",
748 "fetch",
749 "filter",
750 "for",
751 "foreign",
752 "from",
753 "full",
754 "function",
755 "grant",
756 "group",
757 "grouping",
758 "having",
759 "if",
760 "in",
761 "index",
762 "inner",
763 "insert",
764 "intersect",
765 "interval",
766 "into",
767 "is",
768 "join",
769 "key",
770 "leading",
771 "left",
772 "like",
773 "limit",
774 "local",
775 "localtime",
776 "localtimestamp",
777 "match",
778 "merge",
779 "natural",
780 "no",
781 "not",
782 "null",
783 "of",
784 "offset",
785 "on",
786 "only",
787 "or",
788 "order",
789 "outer",
790 "over",
791 "partition",
792 "primary",
793 "procedure",
794 "range",
795 "references",
796 "right",
797 "rollback",
798 "rollup",
799 "row",
800 "rows",
801 "select",
802 "session_user",
803 "set",
804 "some",
805 "table",
806 "tablesample",
807 "then",
808 "to",
809 "trailing",
810 "true",
811 "truncate",
812 "union",
813 "unique",
814 "unknown",
815 "update",
816 "user",
817 "using",
818 "values",
819 "view",
820 "when",
821 "where",
822 "window",
823 "with",
824 ]
825 .into_iter()
826 .collect()
827 });
828
829 pub static BIGQUERY_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
832 let mut set = SQL_RESERVED.clone();
833 set.extend([
834 "assert_rows_modified",
835 "at",
836 "contains",
837 "cube",
838 "current",
839 "define",
840 "enum",
841 "escape",
842 "exclude",
843 "following",
844 "for",
845 "groups",
846 "hash",
847 "ignore",
848 "lateral",
849 "lookup",
850 "new",
851 "no",
852 "nulls",
853 "of",
854 "over",
855 "preceding",
856 "proto",
857 "qualify",
858 "recursive",
859 "respect",
860 "struct",
861 "tablesample",
862 "treat",
863 "unbounded",
864 "unnest",
865 "window",
866 "within",
867 ]);
868 set.remove("grant");
870 set.remove("key");
871 set.remove("index");
872 set.remove("offset");
873 set.remove("values");
874 set.remove("table");
875 set
876 });
877
878 pub static MYSQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
880 let mut set = SQL_RESERVED.clone();
881 set.extend([
882 "accessible",
883 "add",
884 "analyze",
885 "asensitive",
886 "before",
887 "bigint",
888 "binary",
889 "blob",
890 "call",
891 "cascade",
892 "change",
893 "char",
894 "character",
895 "condition",
896 "continue",
897 "convert",
898 "current_date",
899 "current_time",
900 "current_timestamp",
901 "current_user",
902 "cursor",
903 "database",
904 "databases",
905 "day_hour",
906 "day_microsecond",
907 "day_minute",
908 "day_second",
909 "dec",
910 "decimal",
911 "declare",
912 "delayed",
913 "describe",
914 "deterministic",
915 "distinctrow",
916 "div",
917 "double",
918 "dual",
919 "each",
920 "elseif",
921 "enclosed",
922 "escaped",
923 "exit",
924 "explain",
925 "float",
926 "float4",
927 "float8",
928 "force",
929 "get",
930 "high_priority",
931 "hour_microsecond",
932 "hour_minute",
933 "hour_second",
934 "ignore",
935 "infile",
936 "inout",
937 "insensitive",
938 "int",
939 "int1",
940 "int2",
941 "int3",
942 "int4",
943 "int8",
944 "integer",
945 "iterate",
946 "keys",
947 "kill",
948 "leave",
949 "linear",
950 "lines",
951 "load",
952 "lock",
953 "long",
954 "longblob",
955 "longtext",
956 "loop",
957 "low_priority",
958 "master_ssl_verify_server_cert",
959 "maxvalue",
960 "mediumblob",
961 "mediumint",
962 "mediumtext",
963 "middleint",
964 "minute_microsecond",
965 "minute_second",
966 "mod",
967 "modifies",
968 "no_write_to_binlog",
969 "numeric",
970 "optimize",
971 "option",
972 "optionally",
973 "out",
974 "outfile",
975 "precision",
976 "purge",
977 "read",
978 "reads",
979 "real",
980 "regexp",
981 "release",
982 "rename",
983 "repeat",
984 "replace",
985 "require",
986 "resignal",
987 "restrict",
988 "return",
989 "revoke",
990 "rlike",
991 "schema",
992 "schemas",
993 "second_microsecond",
994 "sensitive",
995 "separator",
996 "show",
997 "signal",
998 "smallint",
999 "spatial",
1000 "specific",
1001 "sql",
1002 "sql_big_result",
1003 "sql_calc_found_rows",
1004 "sql_small_result",
1005 "sqlexception",
1006 "sqlstate",
1007 "sqlwarning",
1008 "ssl",
1009 "starting",
1010 "straight_join",
1011 "terminated",
1012 "text",
1013 "tinyblob",
1014 "tinyint",
1015 "tinytext",
1016 "trigger",
1017 "undo",
1018 "unlock",
1019 "unsigned",
1020 "usage",
1021 "utc_date",
1022 "utc_time",
1023 "utc_timestamp",
1024 "varbinary",
1025 "varchar",
1026 "varcharacter",
1027 "varying",
1028 "while",
1029 "write",
1030 "xor",
1031 "year_month",
1032 "zerofill",
1033 ]);
1034 set.remove("table");
1035 set
1036 });
1037
1038 pub static DORIS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1041 let mut set = MYSQL_RESERVED.clone();
1042 set.extend([
1043 "aggregate",
1044 "anti",
1045 "array",
1046 "backend",
1047 "backup",
1048 "begin",
1049 "bitmap",
1050 "boolean",
1051 "broker",
1052 "buckets",
1053 "cached",
1054 "cancel",
1055 "cast",
1056 "catalog",
1057 "charset",
1058 "cluster",
1059 "collation",
1060 "columns",
1061 "comment",
1062 "commit",
1063 "config",
1064 "connection",
1065 "count",
1066 "current",
1067 "data",
1068 "date",
1069 "datetime",
1070 "day",
1071 "deferred",
1072 "distributed",
1073 "dynamic",
1074 "enable",
1075 "end",
1076 "events",
1077 "export",
1078 "external",
1079 "fields",
1080 "first",
1081 "follower",
1082 "format",
1083 "free",
1084 "frontend",
1085 "full",
1086 "functions",
1087 "global",
1088 "grants",
1089 "hash",
1090 "help",
1091 "hour",
1092 "install",
1093 "intermediate",
1094 "json",
1095 "label",
1096 "last",
1097 "less",
1098 "level",
1099 "link",
1100 "local",
1101 "location",
1102 "max",
1103 "merge",
1104 "min",
1105 "minute",
1106 "modify",
1107 "month",
1108 "name",
1109 "names",
1110 "negative",
1111 "nulls",
1112 "observer",
1113 "offset",
1114 "only",
1115 "open",
1116 "overwrite",
1117 "password",
1118 "path",
1119 "plan",
1120 "plugin",
1121 "plugins",
1122 "policy",
1123 "process",
1124 "properties",
1125 "property",
1126 "query",
1127 "quota",
1128 "recover",
1129 "refresh",
1130 "repair",
1131 "replica",
1132 "repository",
1133 "resource",
1134 "restore",
1135 "resume",
1136 "role",
1137 "roles",
1138 "rollback",
1139 "rollup",
1140 "routine",
1141 "sample",
1142 "second",
1143 "semi",
1144 "session",
1145 "signed",
1146 "snapshot",
1147 "start",
1148 "stats",
1149 "status",
1150 "stop",
1151 "stream",
1152 "string",
1153 "sum",
1154 "tables",
1155 "tablet",
1156 "temporary",
1157 "text",
1158 "timestamp",
1159 "transaction",
1160 "trash",
1161 "trim",
1162 "truncate",
1163 "type",
1164 "user",
1165 "value",
1166 "variables",
1167 "verbose",
1168 "version",
1169 "view",
1170 "warnings",
1171 "week",
1172 "work",
1173 "year",
1174 ]);
1175 set
1176 });
1177
1178 pub static POSTGRES_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1180 let mut set = SQL_RESERVED.clone();
1181 set.extend([
1182 "analyse",
1183 "analyze",
1184 "asymmetric",
1185 "binary",
1186 "collation",
1187 "concurrently",
1188 "current_catalog",
1189 "current_role",
1190 "current_schema",
1191 "deferrable",
1192 "do",
1193 "freeze",
1194 "ilike",
1195 "initially",
1196 "isnull",
1197 "lateral",
1198 "notnull",
1199 "placing",
1200 "returning",
1201 "similar",
1202 "symmetric",
1203 "variadic",
1204 "verbose",
1205 ]);
1206 set.remove("default");
1208 set.remove("interval");
1209 set.remove("match");
1210 set.remove("offset");
1211 set.remove("table");
1212 set
1213 });
1214
1215 pub static REDSHIFT_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1219 [
1220 "aes128",
1221 "aes256",
1222 "all",
1223 "allowoverwrite",
1224 "analyse",
1225 "analyze",
1226 "and",
1227 "any",
1228 "array",
1229 "as",
1230 "asc",
1231 "authorization",
1232 "az64",
1233 "backup",
1234 "between",
1235 "binary",
1236 "blanksasnull",
1237 "both",
1238 "bytedict",
1239 "bzip2",
1240 "case",
1241 "cast",
1242 "check",
1243 "collate",
1244 "column",
1245 "constraint",
1246 "create",
1247 "credentials",
1248 "cross",
1249 "current_date",
1250 "current_time",
1251 "current_timestamp",
1252 "current_user",
1253 "current_user_id",
1254 "default",
1255 "deferrable",
1256 "deflate",
1257 "defrag",
1258 "delta",
1259 "delta32k",
1260 "desc",
1261 "disable",
1262 "distinct",
1263 "do",
1264 "else",
1265 "emptyasnull",
1266 "enable",
1267 "encode",
1268 "encrypt",
1269 "encryption",
1270 "end",
1271 "except",
1272 "explicit",
1273 "false",
1274 "for",
1275 "foreign",
1276 "freeze",
1277 "from",
1278 "full",
1279 "globaldict256",
1280 "globaldict64k",
1281 "grant",
1282 "group",
1283 "gzip",
1284 "having",
1285 "identity",
1286 "ignore",
1287 "ilike",
1288 "in",
1289 "initially",
1290 "inner",
1291 "intersect",
1292 "interval",
1293 "into",
1294 "is",
1295 "isnull",
1296 "join",
1297 "leading",
1298 "left",
1299 "like",
1300 "limit",
1301 "localtime",
1302 "localtimestamp",
1303 "lun",
1304 "luns",
1305 "lzo",
1306 "lzop",
1307 "minus",
1308 "mostly16",
1309 "mostly32",
1310 "mostly8",
1311 "natural",
1312 "new",
1313 "not",
1314 "notnull",
1315 "null",
1316 "nulls",
1317 "off",
1318 "offline",
1319 "offset",
1320 "oid",
1321 "old",
1322 "on",
1323 "only",
1324 "open",
1325 "or",
1326 "order",
1327 "outer",
1328 "overlaps",
1329 "parallel",
1330 "partition",
1331 "percent",
1332 "permissions",
1333 "pivot",
1334 "placing",
1335 "primary",
1336 "raw",
1337 "readratio",
1338 "recover",
1339 "references",
1340 "rejectlog",
1341 "resort",
1342 "respect",
1343 "restore",
1344 "right",
1345 "select",
1346 "session_user",
1347 "similar",
1348 "snapshot",
1349 "some",
1350 "sysdate",
1351 "system",
1352 "table",
1353 "tag",
1354 "tdes",
1355 "text255",
1356 "text32k",
1357 "then",
1358 "timestamp",
1359 "to",
1360 "top",
1361 "trailing",
1362 "true",
1363 "truncatecolumns",
1364 "type",
1365 "union",
1366 "unique",
1367 "unnest",
1368 "unpivot",
1369 "user",
1370 "using",
1371 "verbose",
1372 "wallet",
1373 "when",
1374 "where",
1375 "with",
1376 "without",
1377 ]
1378 .into_iter()
1379 .collect()
1380 });
1381
1382 pub static DUCKDB_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1384 let mut set = POSTGRES_RESERVED.clone();
1385 set.extend([
1386 "anti",
1387 "asof",
1388 "columns",
1389 "describe",
1390 "groups",
1391 "macro",
1392 "pivot",
1393 "pivot_longer",
1394 "pivot_wider",
1395 "qualify",
1396 "replace",
1397 "respect",
1398 "semi",
1399 "show",
1400 "table",
1401 "unpivot",
1402 ]);
1403 set.remove("at");
1404 set.remove("key");
1405 set.remove("range");
1406 set.remove("row");
1407 set.remove("values");
1408 set
1409 });
1410
1411 pub static PRESTO_TRINO_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1413 let mut set = SQL_RESERVED.clone();
1414 set.extend([
1415 "alter",
1416 "and",
1417 "as",
1418 "between",
1419 "by",
1420 "case",
1421 "cast",
1422 "constraint",
1423 "create",
1424 "cross",
1425 "cube",
1426 "current_catalog",
1427 "current_date",
1428 "current_path",
1429 "current_role",
1430 "current_schema",
1431 "current_time",
1432 "current_timestamp",
1433 "current_user",
1434 "deallocate",
1435 "delete",
1436 "describe",
1437 "distinct",
1438 "drop",
1439 "else",
1440 "end",
1441 "escape",
1442 "except",
1443 "execute",
1444 "exists",
1445 "extract",
1446 "false",
1447 "for",
1448 "from",
1449 "full",
1450 "group",
1451 "grouping",
1452 "having",
1453 "in",
1454 "inner",
1455 "insert",
1456 "intersect",
1457 "into",
1458 "is",
1459 "join",
1460 "json_array",
1461 "json_exists",
1462 "json_object",
1463 "json_query",
1464 "json_table",
1465 "json_value",
1466 "left",
1467 "like",
1468 "listagg",
1469 "localtime",
1470 "localtimestamp",
1471 "natural",
1472 "normalize",
1473 "not",
1474 "null",
1475 "on",
1476 "or",
1477 "order",
1478 "outer",
1479 "prepare",
1480 "recursive",
1481 "right",
1482 "rollup",
1483 "select",
1484 "skip",
1485 "table",
1486 "then",
1487 "trim",
1488 "true",
1489 "uescape",
1490 "union",
1491 "unnest",
1492 "using",
1493 "values",
1494 "when",
1495 "where",
1496 "with",
1497 ]);
1498 set.remove("key");
1500 set
1501 });
1502
1503 pub static STARROCKS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1506 [
1507 "add",
1508 "all",
1509 "alter",
1510 "analyze",
1511 "and",
1512 "array",
1513 "as",
1514 "asc",
1515 "between",
1516 "bigint",
1517 "bitmap",
1518 "both",
1519 "by",
1520 "case",
1521 "char",
1522 "character",
1523 "check",
1524 "collate",
1525 "column",
1526 "compaction",
1527 "convert",
1528 "create",
1529 "cross",
1530 "cube",
1531 "current_date",
1532 "current_role",
1533 "current_time",
1534 "current_timestamp",
1535 "current_user",
1536 "database",
1537 "databases",
1538 "decimal",
1539 "decimalv2",
1540 "decimal32",
1541 "decimal64",
1542 "decimal128",
1543 "default",
1544 "deferred",
1545 "delete",
1546 "dense_rank",
1547 "desc",
1548 "describe",
1549 "distinct",
1550 "double",
1551 "drop",
1552 "dual",
1553 "else",
1554 "except",
1555 "exists",
1556 "explain",
1557 "false",
1558 "first_value",
1559 "float",
1560 "for",
1561 "force",
1562 "from",
1563 "full",
1564 "function",
1565 "grant",
1566 "group",
1567 "grouping",
1568 "grouping_id",
1569 "groups",
1570 "having",
1571 "hll",
1572 "host",
1573 "if",
1574 "ignore",
1575 "immediate",
1576 "in",
1577 "index",
1578 "infile",
1579 "inner",
1580 "insert",
1581 "int",
1582 "integer",
1583 "intersect",
1584 "into",
1585 "is",
1586 "join",
1587 "json",
1588 "key",
1589 "keys",
1590 "kill",
1591 "lag",
1592 "largeint",
1593 "last_value",
1594 "lateral",
1595 "lead",
1596 "left",
1597 "like",
1598 "limit",
1599 "load",
1600 "localtime",
1601 "localtimestamp",
1602 "maxvalue",
1603 "minus",
1604 "mod",
1605 "not",
1606 "ntile",
1607 "null",
1608 "on",
1609 "or",
1610 "order",
1611 "outer",
1612 "outfile",
1613 "over",
1614 "partition",
1615 "percentile",
1616 "primary",
1617 "procedure",
1618 "qualify",
1619 "range",
1620 "rank",
1621 "read",
1622 "regexp",
1623 "release",
1624 "rename",
1625 "replace",
1626 "revoke",
1627 "right",
1628 "rlike",
1629 "row",
1630 "row_number",
1631 "rows",
1632 "schema",
1633 "schemas",
1634 "select",
1635 "set",
1636 "set_var",
1637 "show",
1638 "smallint",
1639 "system",
1640 "table",
1641 "terminated",
1642 "text",
1643 "then",
1644 "tinyint",
1645 "to",
1646 "true",
1647 "union",
1648 "unique",
1649 "unsigned",
1650 "update",
1651 "use",
1652 "using",
1653 "values",
1654 "varchar",
1655 "when",
1656 "where",
1657 "with",
1658 ]
1659 .into_iter()
1660 .collect()
1661 });
1662
1663 pub static SINGLESTORE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1666 let mut set = MYSQL_RESERVED.clone();
1667 set.extend([
1668 "abs",
1671 "account",
1672 "acos",
1673 "adddate",
1674 "addtime",
1675 "admin",
1676 "aes_decrypt",
1677 "aes_encrypt",
1678 "aggregate",
1679 "aggregates",
1680 "aggregator",
1681 "anti_join",
1682 "any_value",
1683 "approx_count_distinct",
1684 "approx_percentile",
1685 "arrange",
1686 "arrangement",
1687 "asin",
1688 "atan",
1689 "atan2",
1690 "attach",
1691 "autostats",
1692 "avro",
1693 "background",
1694 "backup",
1695 "batch",
1696 "batches",
1697 "boot_strapping",
1698 "ceil",
1699 "ceiling",
1700 "coercibility",
1701 "columnar",
1702 "columnstore",
1703 "compile",
1704 "concurrent",
1705 "connection_id",
1706 "cos",
1707 "cot",
1708 "current_security_groups",
1709 "current_security_roles",
1710 "dayname",
1711 "dayofmonth",
1712 "dayofweek",
1713 "dayofyear",
1714 "degrees",
1715 "dot_product",
1716 "dump",
1717 "durability",
1718 "earliest",
1719 "echo",
1720 "election",
1721 "euclidean_distance",
1722 "exp",
1723 "extractor",
1724 "extractors",
1725 "floor",
1726 "foreground",
1727 "found_rows",
1728 "from_base64",
1729 "from_days",
1730 "from_unixtime",
1731 "fs",
1732 "fulltext",
1733 "gc",
1734 "gcs",
1735 "geography",
1736 "geography_area",
1737 "geography_contains",
1738 "geography_distance",
1739 "geography_intersects",
1740 "geography_latitude",
1741 "geography_length",
1742 "geography_longitude",
1743 "geographypoint",
1744 "geography_point",
1745 "geography_within_distance",
1746 "geometry",
1747 "geometry_area",
1748 "geometry_contains",
1749 "geometry_distance",
1750 "geometry_filter",
1751 "geometry_intersects",
1752 "geometry_length",
1753 "geometrypoint",
1754 "geometry_point",
1755 "geometry_within_distance",
1756 "geometry_x",
1757 "geometry_y",
1758 "greatest",
1759 "groups",
1760 "group_concat",
1761 "gzip",
1762 "hdfs",
1763 "hex",
1764 "highlight",
1765 "ifnull",
1766 "ilike",
1767 "inet_aton",
1768 "inet_ntoa",
1769 "inet6_aton",
1770 "inet6_ntoa",
1771 "initcap",
1772 "instr",
1773 "interpreter_mode",
1774 "isnull",
1775 "json",
1776 "json_agg",
1777 "json_array_contains_double",
1778 "json_array_contains_json",
1779 "json_array_contains_string",
1780 "json_delete_key",
1781 "json_extract_double",
1782 "json_extract_json",
1783 "json_extract_string",
1784 "json_extract_bigint",
1785 "json_get_type",
1786 "json_length",
1787 "json_set_double",
1788 "json_set_json",
1789 "json_set_string",
1790 "kafka",
1791 "lag",
1792 "last_day",
1793 "last_insert_id",
1794 "latest",
1795 "lcase",
1796 "lead",
1797 "leaf",
1798 "least",
1799 "leaves",
1800 "length",
1801 "license",
1802 "links",
1803 "llvm",
1804 "ln",
1805 "load",
1806 "locate",
1807 "log",
1808 "log10",
1809 "log2",
1810 "lpad",
1811 "lz4",
1812 "management",
1813 "match",
1814 "mbc",
1815 "md5",
1816 "median",
1817 "memsql",
1818 "memsql_deserialize",
1819 "memsql_serialize",
1820 "metadata",
1821 "microsecond",
1822 "minute",
1823 "model",
1824 "monthname",
1825 "months_between",
1826 "mpl",
1827 "namespace",
1828 "node",
1829 "noparam",
1830 "now",
1831 "nth_value",
1832 "ntile",
1833 "nullcols",
1834 "nullif",
1835 "object",
1836 "octet_length",
1837 "offsets",
1838 "online",
1839 "optimizer",
1840 "orphan",
1841 "parquet",
1842 "partitions",
1843 "pause",
1844 "percentile_cont",
1845 "percentile_disc",
1846 "periodic",
1847 "persisted",
1848 "pi",
1849 "pipeline",
1850 "pipelines",
1851 "plancache",
1852 "plugins",
1853 "pool",
1854 "pools",
1855 "pow",
1856 "power",
1857 "process",
1858 "processlist",
1859 "profile",
1860 "profiles",
1861 "quarter",
1862 "queries",
1863 "query",
1864 "radians",
1865 "rand",
1866 "record",
1867 "reduce",
1868 "redundancy",
1869 "regexp_match",
1870 "regexp_substr",
1871 "remote",
1872 "replication",
1873 "resource",
1874 "resource_pool",
1875 "restore",
1876 "retry",
1877 "role",
1878 "roles",
1879 "round",
1880 "rpad",
1881 "rtrim",
1882 "running",
1883 "s3",
1884 "scalar",
1885 "sec_to_time",
1886 "second",
1887 "security_lists_intersect",
1888 "semi_join",
1889 "sha",
1890 "sha1",
1891 "sha2",
1892 "shard",
1893 "sharded",
1894 "sharded_id",
1895 "sigmoid",
1896 "sign",
1897 "sin",
1898 "skip",
1899 "sleep",
1900 "snapshot",
1901 "soname",
1902 "sparse",
1903 "spatial_check_index",
1904 "split",
1905 "sqrt",
1906 "standalone",
1907 "std",
1908 "stddev",
1909 "stddev_pop",
1910 "stddev_samp",
1911 "stop",
1912 "str_to_date",
1913 "subdate",
1914 "substr",
1915 "substring_index",
1916 "success",
1917 "synchronize",
1918 "table_checksum",
1919 "tan",
1920 "task",
1921 "timediff",
1922 "time_bucket",
1923 "time_format",
1924 "time_to_sec",
1925 "timestampadd",
1926 "timestampdiff",
1927 "to_base64",
1928 "to_char",
1929 "to_date",
1930 "to_days",
1931 "to_json",
1932 "to_number",
1933 "to_seconds",
1934 "to_timestamp",
1935 "tracelogs",
1936 "transform",
1937 "trim",
1938 "trunc",
1939 "truncate",
1940 "ucase",
1941 "unhex",
1942 "unix_timestamp",
1943 "utc_date",
1944 "utc_time",
1945 "utc_timestamp",
1946 "vacuum",
1947 "variance",
1948 "var_pop",
1949 "var_samp",
1950 "vector_sub",
1951 "voting",
1952 "week",
1953 "weekday",
1954 "weekofyear",
1955 "workload",
1956 "year",
1957 ]);
1958 set.remove("all");
1960 set
1961 });
1962
1963 pub static SQLITE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1967 [
1969 "abort",
1970 "action",
1971 "add",
1972 "after",
1973 "all",
1974 "alter",
1975 "always",
1976 "analyze",
1977 "and",
1978 "as",
1979 "asc",
1980 "attach",
1981 "autoincrement",
1982 "before",
1983 "begin",
1984 "between",
1985 "by",
1986 "cascade",
1987 "case",
1988 "cast",
1989 "check",
1990 "collate",
1991 "column",
1992 "commit",
1993 "conflict",
1994 "constraint",
1995 "create",
1996 "cross",
1997 "current",
1998 "current_date",
1999 "current_time",
2000 "current_timestamp",
2001 "database",
2002 "default",
2003 "deferrable",
2004 "deferred",
2005 "delete",
2006 "desc",
2007 "detach",
2008 "distinct",
2009 "do",
2010 "drop",
2011 "each",
2012 "else",
2013 "end",
2014 "escape",
2015 "except",
2016 "exclude",
2017 "exclusive",
2018 "exists",
2019 "explain",
2020 "fail",
2021 "filter",
2022 "first",
2023 "following",
2024 "for",
2025 "foreign",
2026 "from",
2027 "full",
2028 "generated",
2029 "glob",
2030 "group",
2031 "groups",
2032 "having",
2033 "if",
2034 "ignore",
2035 "immediate",
2036 "in",
2037 "index",
2038 "indexed",
2039 "initially",
2040 "inner",
2041 "insert",
2042 "instead",
2043 "intersect",
2044 "into",
2045 "is",
2046 "isnull",
2047 "join",
2048 "key",
2049 "last",
2050 "left",
2051 "like",
2052 "limit",
2053 "natural",
2054 "no",
2055 "not",
2056 "nothing",
2057 "notnull",
2058 "null",
2059 "nulls",
2060 "of",
2061 "offset",
2062 "on",
2063 "or",
2064 "order",
2065 "others",
2066 "outer",
2067 "partition",
2068 "plan",
2069 "pragma",
2070 "preceding",
2071 "primary",
2072 "query",
2073 "raise",
2074 "range",
2075 "recursive",
2076 "references",
2077 "regexp",
2078 "reindex",
2079 "release",
2080 "rename",
2081 "replace",
2082 "restrict",
2083 "returning",
2084 "right",
2085 "rollback",
2086 "row",
2087 "rows",
2088 "savepoint",
2089 "select",
2090 "set",
2091 "table",
2092 "temp",
2093 "temporary",
2094 "then",
2095 "ties",
2096 "to",
2097 "transaction",
2098 "trigger",
2099 "unbounded",
2100 "union",
2101 "unique",
2102 "update",
2103 "using",
2104 "vacuum",
2105 "values",
2106 "view",
2107 "virtual",
2108 "when",
2109 "where",
2110 "window",
2111 "with",
2112 "without",
2113 ]
2114 .into_iter()
2115 .collect()
2116 });
2117}
2118
2119impl Generator {
2120 pub fn new() -> Self {
2126 Self::with_config(GeneratorConfig::default())
2127 }
2128
2129 pub fn with_config(config: GeneratorConfig) -> Self {
2134 Self::with_arc_config(Arc::new(config))
2135 }
2136
2137 pub(crate) fn with_arc_config(config: Arc<GeneratorConfig>) -> Self {
2142 Self {
2143 config,
2144 output: String::new(),
2145 unsupported_messages: Vec::new(),
2146 indent_level: 0,
2147 athena_hive_context: false,
2148 sqlite_inline_pk_columns: std::collections::HashSet::new(),
2149 merge_strip_qualifiers: Vec::new(),
2150 clickhouse_nullable_depth: 0,
2151 }
2152 }
2153
2154 fn add_column_aliases_to_query(expr: Expression) -> Expression {
2158 match expr {
2159 Expression::Select(mut select) => {
2160 select.expressions = select
2162 .expressions
2163 .into_iter()
2164 .map(|e| Self::add_alias_to_expression(e))
2165 .collect();
2166
2167 if let Some(ref mut from) = select.from {
2169 from.expressions = from
2170 .expressions
2171 .iter()
2172 .cloned()
2173 .map(|e| Self::add_column_aliases_to_query(e))
2174 .collect();
2175 }
2176
2177 Expression::Select(select)
2178 }
2179 Expression::Subquery(mut sq) => {
2180 sq.this = Self::add_column_aliases_to_query(sq.this);
2181 Expression::Subquery(sq)
2182 }
2183 Expression::Paren(mut p) => {
2184 p.this = Self::add_column_aliases_to_query(p.this);
2185 Expression::Paren(p)
2186 }
2187 other => other,
2189 }
2190 }
2191
2192 fn add_alias_to_expression(expr: Expression) -> Expression {
2195 use crate::expressions::Alias;
2196
2197 match &expr {
2198 Expression::Alias(_) => expr,
2200
2201 Expression::Column(col) => Expression::Alias(Box::new(Alias {
2203 this: expr.clone(),
2204 alias: col.name.clone(),
2205 column_aliases: Vec::new(),
2206 alias_explicit_as: false,
2207 alias_keyword: None,
2208 pre_alias_comments: Vec::new(),
2209 trailing_comments: Vec::new(),
2210 inferred_type: None,
2211 })),
2212
2213 Expression::Identifier(ident) => Expression::Alias(Box::new(Alias {
2215 this: expr.clone(),
2216 alias: ident.clone(),
2217 column_aliases: Vec::new(),
2218 alias_explicit_as: false,
2219 alias_keyword: None,
2220 pre_alias_comments: Vec::new(),
2221 trailing_comments: Vec::new(),
2222 inferred_type: None,
2223 })),
2224
2225 Expression::Subquery(sq) => {
2227 let processed = Self::add_column_aliases_to_query(Expression::Subquery(sq.clone()));
2228 if sq.alias.is_some() {
2230 processed
2231 } else {
2232 processed
2234 }
2235 }
2236
2237 Expression::Star(_) => expr,
2239
2240 _ => expr,
2243 }
2244 }
2245
2246 fn try_evaluate_constant(expr: &Expression) -> Option<i64> {
2250 match expr {
2251 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
2252 let Literal::Number(n) = lit.as_ref() else {
2253 unreachable!()
2254 };
2255 n.parse::<i64>().ok()
2256 }
2257 Expression::Add(op) => {
2258 let left = Self::try_evaluate_constant(&op.left)?;
2259 let right = Self::try_evaluate_constant(&op.right)?;
2260 Some(left + right)
2261 }
2262 Expression::Sub(op) => {
2263 let left = Self::try_evaluate_constant(&op.left)?;
2264 let right = Self::try_evaluate_constant(&op.right)?;
2265 Some(left - right)
2266 }
2267 Expression::Mul(op) => {
2268 let left = Self::try_evaluate_constant(&op.left)?;
2269 let right = Self::try_evaluate_constant(&op.right)?;
2270 Some(left * right)
2271 }
2272 Expression::Div(op) => {
2273 let left = Self::try_evaluate_constant(&op.left)?;
2274 let right = Self::try_evaluate_constant(&op.right)?;
2275 if right != 0 {
2276 Some(left / right)
2277 } else {
2278 None
2279 }
2280 }
2281 Expression::Paren(p) => Self::try_evaluate_constant(&p.this),
2282 _ => None,
2283 }
2284 }
2285
2286 fn is_reserved_keyword(&self, name: &str) -> bool {
2288 use crate::dialects::DialectType;
2289 let mut buf = [0u8; 128];
2290 let lower_ref: &str = if name.len() <= 128 {
2291 for (i, b) in name.bytes().enumerate() {
2292 buf[i] = b.to_ascii_lowercase();
2293 }
2294 std::str::from_utf8(&buf[..name.len()]).unwrap_or(name)
2296 } else {
2297 return false;
2298 };
2299
2300 match self.config.dialect {
2301 Some(DialectType::BigQuery) => reserved_keywords::BIGQUERY_RESERVED.contains(lower_ref),
2302 Some(DialectType::MySQL) | Some(DialectType::TiDB) => {
2303 reserved_keywords::MYSQL_RESERVED.contains(lower_ref)
2304 }
2305 Some(DialectType::Doris) => reserved_keywords::DORIS_RESERVED.contains(lower_ref),
2306 Some(DialectType::SingleStore) => {
2307 reserved_keywords::SINGLESTORE_RESERVED.contains(lower_ref)
2308 }
2309 Some(DialectType::StarRocks) => {
2310 reserved_keywords::STARROCKS_RESERVED.contains(lower_ref)
2311 }
2312 Some(DialectType::PostgreSQL)
2313 | Some(DialectType::CockroachDB)
2314 | Some(DialectType::Materialize)
2315 | Some(DialectType::RisingWave) => {
2316 reserved_keywords::POSTGRES_RESERVED.contains(lower_ref)
2317 }
2318 Some(DialectType::Redshift) => reserved_keywords::REDSHIFT_RESERVED.contains(lower_ref),
2319 Some(DialectType::Snowflake) => false,
2322 Some(DialectType::ClickHouse) => false,
2324 Some(DialectType::DuckDB) => reserved_keywords::DUCKDB_RESERVED.contains(lower_ref),
2325 Some(DialectType::Teradata) => false,
2327 Some(DialectType::TSQL)
2329 | Some(DialectType::Fabric)
2330 | Some(DialectType::Oracle)
2331 | Some(DialectType::Spark)
2332 | Some(DialectType::Databricks)
2333 | Some(DialectType::Hive)
2334 | Some(DialectType::Solr) => false,
2335 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
2336 reserved_keywords::PRESTO_TRINO_RESERVED.contains(lower_ref)
2337 }
2338 Some(DialectType::SQLite) => reserved_keywords::SQLITE_RESERVED.contains(lower_ref),
2339 Some(DialectType::Generic) | None => false,
2341 _ => reserved_keywords::SQL_RESERVED.contains(lower_ref),
2343 }
2344 }
2345
2346 fn normalize_func_name<'a>(&self, name: &'a str) -> Cow<'a, str> {
2348 match self.config.normalize_functions {
2349 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
2350 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
2351 NormalizeFunctions::None => Cow::Borrowed(name),
2352 }
2353 }
2354
2355 pub fn generate(&mut self, expr: &Expression) -> Result<String> {
2364 self.output.clear();
2365 self.unsupported_messages.clear();
2366 self.generate_expression(expr)?;
2367 if self.config.unsupported_level == UnsupportedLevel::Raise
2368 && !self.unsupported_messages.is_empty()
2369 {
2370 return Err(crate::error::Error::generate(
2371 self.format_unsupported_messages(),
2372 ));
2373 }
2374 Ok(std::mem::take(&mut self.output))
2375 }
2376
2377 pub fn unsupported_messages(&self) -> &[String] {
2379 &self.unsupported_messages
2380 }
2381
2382 fn unsupported(&mut self, message: impl Into<String>) -> Result<()> {
2383 let message = message.into();
2384 if self.config.unsupported_level == UnsupportedLevel::Immediate {
2385 return Err(crate::error::Error::generate(message));
2386 }
2387 self.unsupported_messages.push(message);
2388 Ok(())
2389 }
2390
2391 fn write_unsupported_comment(&mut self, message: &str) -> Result<()> {
2392 self.unsupported(message.to_string())?;
2393 self.write("/* ");
2394 self.write(message);
2395 self.write(" */");
2396 Ok(())
2397 }
2398
2399 fn format_unsupported_messages(&self) -> String {
2400 let limit = self.config.max_unsupported.max(1);
2401 if self.unsupported_messages.len() <= limit {
2402 return self.unsupported_messages.join("; ");
2403 }
2404
2405 let mut messages = self
2406 .unsupported_messages
2407 .iter()
2408 .take(limit)
2409 .cloned()
2410 .collect::<Vec<_>>();
2411 messages.push(format!(
2412 "... and {} more",
2413 self.unsupported_messages.len() - limit
2414 ));
2415 messages.join("; ")
2416 }
2417
2418 pub fn sql(expr: &Expression) -> Result<String> {
2424 let mut gen = Generator::new();
2425 gen.generate(expr)
2426 }
2427
2428 pub fn pretty_sql(expr: &Expression) -> Result<String> {
2433 let config = GeneratorConfig {
2434 pretty: true,
2435 ..Default::default()
2436 };
2437 let mut gen = Generator::with_config(config);
2438 let mut sql = gen.generate(expr)?;
2439 if !sql.ends_with(';') {
2441 sql.push(';');
2442 }
2443 Ok(sql)
2444 }
2445
2446 fn generate_expression(&mut self, expr: &Expression) -> Result<()> {
2447 #[cfg(feature = "stacker")]
2448 {
2449 let red_zone = if cfg!(debug_assertions) {
2450 4 * 1024 * 1024
2451 } else {
2452 1024 * 1024
2453 };
2454 stacker::maybe_grow(red_zone, 8 * 1024 * 1024, || {
2455 self.generate_expression_inner(expr)
2456 })
2457 }
2458 #[cfg(not(feature = "stacker"))]
2459 {
2460 self.generate_expression_inner(expr)
2461 }
2462 }
2463
2464 fn generate_expression_inner(&mut self, expr: &Expression) -> Result<()> {
2465 match expr {
2466 Expression::Select(select) => self.generate_select(select),
2467 Expression::Union(union) => self.generate_union(union),
2468 Expression::Intersect(intersect) => self.generate_intersect(intersect),
2469 Expression::Except(except) => self.generate_except(except),
2470 Expression::Insert(insert) => self.generate_insert(insert),
2471 Expression::Update(update) => self.generate_update(update),
2472 Expression::Delete(delete) => self.generate_delete(delete),
2473 Expression::Literal(lit) => self.generate_literal(lit),
2474 Expression::Boolean(b) => self.generate_boolean(b),
2475 Expression::Null(_) => {
2476 self.write_keyword("NULL");
2477 Ok(())
2478 }
2479 Expression::Identifier(id) => self.generate_identifier(id),
2480 Expression::Column(col) => self.generate_column(col),
2481 Expression::Pseudocolumn(pc) => self.generate_pseudocolumn(pc),
2482 Expression::Connect(c) => self.generate_connect_expr(c),
2483 Expression::Prior(p) => self.generate_prior(p),
2484 Expression::ConnectByRoot(cbr) => self.generate_connect_by_root(cbr),
2485 Expression::MatchRecognize(mr) => self.generate_match_recognize(mr),
2486 Expression::Table(table) => self.generate_table(table),
2487 Expression::StageReference(sr) => self.generate_stage_reference(sr),
2488 Expression::HistoricalData(hd) => self.generate_historical_data(hd),
2489 Expression::JoinedTable(jt) => self.generate_joined_table(jt),
2490 Expression::Star(star) => self.generate_star(star),
2491 Expression::BracedWildcard(expr) => self.generate_braced_wildcard(expr),
2492 Expression::Alias(alias) => self.generate_alias(alias),
2493 Expression::Cast(cast) => self.generate_cast(cast),
2494 Expression::Collation(coll) => self.generate_collation(coll),
2495 Expression::Case(case) => self.generate_case(case),
2496 Expression::Function(func) => self.generate_function(func),
2497 Expression::FunctionEmits(fe) => self.generate_function_emits(fe),
2498 Expression::AggregateFunction(func) => self.generate_aggregate_function(func),
2499 Expression::WindowFunction(wf) => self.generate_window_function(wf),
2500 Expression::WithinGroup(wg) => self.generate_within_group(wg),
2501 Expression::Interval(interval) => self.generate_interval(interval),
2502
2503 Expression::ConcatWs(f) => self.generate_concat_ws(f),
2505 Expression::Substring(f) => self.generate_substring(f),
2506 Expression::Upper(f) => self.generate_unary_func("UPPER", f),
2507 Expression::Lower(f) => self.generate_unary_func("LOWER", f),
2508 Expression::Length(f) => self.generate_unary_func("LENGTH", f),
2509 Expression::Trim(f) => self.generate_trim(f),
2510 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
2511 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
2512 Expression::Replace(f) => self.generate_replace(f),
2513 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
2514 Expression::Left(f) => self.generate_left_right("LEFT", f),
2515 Expression::Right(f) => self.generate_left_right("RIGHT", f),
2516 Expression::Repeat(f) => self.generate_repeat(f),
2517 Expression::Lpad(f) => self.generate_pad("LPAD", f),
2518 Expression::Rpad(f) => self.generate_pad("RPAD", f),
2519 Expression::Split(f) => self.generate_split(f),
2520 Expression::RegexpLike(f) => self.generate_regexp_like(f),
2521 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
2522 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
2523 Expression::Overlay(f) => self.generate_overlay(f),
2524
2525 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
2527 Expression::Round(f) => self.generate_round(f),
2528 Expression::Floor(f) => self.generate_floor(f),
2529 Expression::Ceil(f) => self.generate_ceil(f),
2530 Expression::Power(f) => self.generate_power(f),
2531 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
2532 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
2533 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
2534 Expression::Log(f) => self.generate_log(f),
2535 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
2536 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
2537 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
2538 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
2539
2540 Expression::CurrentDate(_) => {
2542 self.write_keyword("CURRENT_DATE");
2543 Ok(())
2544 }
2545 Expression::CurrentTime(f) => self.generate_current_time(f),
2546 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
2547 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
2548 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
2549 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
2550 Expression::DateDiff(f) => self.generate_datediff(f),
2551 Expression::DateTrunc(f) => self.generate_date_trunc(f),
2552 Expression::Extract(f) => self.generate_extract(f),
2553 Expression::ToDate(f) => self.generate_to_date(f),
2554 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
2555
2556 Expression::Coalesce(f) => {
2558 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
2560 self.generate_vararg_func(func_name, &f.expressions)
2561 }
2562 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
2563 Expression::IfFunc(f) => self.generate_if_func(f),
2564 Expression::IfNull(f) => self.generate_ifnull(f),
2565 Expression::Nvl(f) => self.generate_nvl(f),
2566 Expression::Nvl2(f) => self.generate_nvl2(f),
2567
2568 Expression::TryCast(cast) => self.generate_try_cast(cast),
2570 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
2571
2572 Expression::Count(f) => self.generate_count(f),
2574 Expression::Sum(f) => self.generate_agg_func("SUM", f),
2575 Expression::Avg(f) => self.generate_agg_func("AVG", f),
2576 Expression::Min(f) => self.generate_agg_func("MIN", f),
2577 Expression::Max(f) => self.generate_agg_func("MAX", f),
2578 Expression::GroupConcat(f) => self.generate_group_concat(f),
2579 Expression::StringAgg(f) => self.generate_string_agg(f),
2580 Expression::ListAgg(f) => self.generate_listagg(f),
2581 Expression::ArrayAgg(f) => {
2582 let override_name = f
2585 .name
2586 .as_ref()
2587 .filter(|n| !n.eq_ignore_ascii_case("ARRAY_AGG"))
2588 .map(|n| n.to_ascii_uppercase());
2589 match override_name {
2590 Some(name) => self.generate_agg_func(&name, f),
2591 None => self.generate_agg_func("ARRAY_AGG", f),
2592 }
2593 }
2594 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
2595 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
2596 Expression::SumIf(f) => self.generate_sum_if(f),
2597 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
2598 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
2599 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
2600 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
2601 Expression::VarPop(f) => {
2602 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
2603 "VARIANCE_POP"
2604 } else {
2605 "VAR_POP"
2606 };
2607 self.generate_agg_func(name, f)
2608 }
2609 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
2610 Expression::Skewness(f) => {
2611 let name = match self.config.dialect {
2612 Some(DialectType::Snowflake) => "SKEW",
2613 _ => "SKEWNESS",
2614 };
2615 self.generate_agg_func(name, f)
2616 }
2617 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
2618 Expression::Mode(f) => self.generate_agg_func("MODE", f),
2619 Expression::First(f) => self.generate_agg_func_with_ignore_nulls_bool("FIRST", f),
2620 Expression::Last(f) => self.generate_agg_func_with_ignore_nulls_bool("LAST", f),
2621 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
2622 Expression::ApproxDistinct(f) => {
2623 match self.config.dialect {
2624 Some(DialectType::Hive)
2625 | Some(DialectType::Spark)
2626 | Some(DialectType::Databricks)
2627 | Some(DialectType::BigQuery) => {
2628 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2630 }
2631 Some(DialectType::Redshift) => {
2632 self.write_keyword("APPROXIMATE COUNT");
2634 self.write("(");
2635 self.write_keyword("DISTINCT");
2636 self.write(" ");
2637 self.generate_expression(&f.this)?;
2638 self.write(")");
2639 Ok(())
2640 }
2641 _ => self.generate_agg_func("APPROX_DISTINCT", f),
2642 }
2643 }
2644 Expression::ApproxCountDistinct(f) => {
2645 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2646 }
2647 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
2648 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
2649 Expression::LogicalAnd(f) => {
2650 let name = match self.config.dialect {
2651 Some(DialectType::Snowflake) => "BOOLAND_AGG",
2652 Some(DialectType::Spark)
2653 | Some(DialectType::Databricks)
2654 | Some(DialectType::PostgreSQL)
2655 | Some(DialectType::DuckDB)
2656 | Some(DialectType::Redshift) => "BOOL_AND",
2657 Some(DialectType::Oracle)
2658 | Some(DialectType::SQLite)
2659 | Some(DialectType::MySQL) => "MIN",
2660 _ => "BOOL_AND",
2661 };
2662 self.generate_agg_func(name, f)
2663 }
2664 Expression::LogicalOr(f) => {
2665 let name = match self.config.dialect {
2666 Some(DialectType::Snowflake) => "BOOLOR_AGG",
2667 Some(DialectType::Spark)
2668 | Some(DialectType::Databricks)
2669 | Some(DialectType::PostgreSQL)
2670 | Some(DialectType::DuckDB)
2671 | Some(DialectType::Redshift) => "BOOL_OR",
2672 Some(DialectType::Oracle)
2673 | Some(DialectType::SQLite)
2674 | Some(DialectType::MySQL) => "MAX",
2675 _ => "BOOL_OR",
2676 };
2677 self.generate_agg_func(name, f)
2678 }
2679
2680 Expression::RowNumber(_) => {
2682 if self.config.dialect == Some(DialectType::ClickHouse) {
2683 self.write("row_number");
2684 } else {
2685 self.write_keyword("ROW_NUMBER");
2686 }
2687 self.write("()");
2688 Ok(())
2689 }
2690 Expression::Rank(r) => {
2691 self.write_keyword("RANK");
2692 self.write("(");
2693 if !r.args.is_empty() {
2695 for (i, arg) in r.args.iter().enumerate() {
2696 if i > 0 {
2697 self.write(", ");
2698 }
2699 self.generate_expression(arg)?;
2700 }
2701 } else if let Some(order_by) = &r.order_by {
2702 self.write_keyword(" ORDER BY ");
2704 for (i, ob) in order_by.iter().enumerate() {
2705 if i > 0 {
2706 self.write(", ");
2707 }
2708 self.generate_ordered(ob)?;
2709 }
2710 }
2711 self.write(")");
2712 Ok(())
2713 }
2714 Expression::DenseRank(dr) => {
2715 self.write_keyword("DENSE_RANK");
2716 self.write("(");
2717 for (i, arg) in dr.args.iter().enumerate() {
2719 if i > 0 {
2720 self.write(", ");
2721 }
2722 self.generate_expression(arg)?;
2723 }
2724 self.write(")");
2725 Ok(())
2726 }
2727 Expression::NTile(f) => self.generate_ntile(f),
2728 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
2729 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
2730 Expression::FirstValue(f) => {
2731 self.generate_value_func_with_ignore_nulls_bool("FIRST_VALUE", f)
2732 }
2733 Expression::LastValue(f) => {
2734 self.generate_value_func_with_ignore_nulls_bool("LAST_VALUE", f)
2735 }
2736 Expression::NthValue(f) => self.generate_nth_value(f),
2737 Expression::PercentRank(pr) => {
2738 self.write_keyword("PERCENT_RANK");
2739 self.write("(");
2740 if !pr.args.is_empty() {
2742 for (i, arg) in pr.args.iter().enumerate() {
2743 if i > 0 {
2744 self.write(", ");
2745 }
2746 self.generate_expression(arg)?;
2747 }
2748 } else if let Some(order_by) = &pr.order_by {
2749 self.write_keyword(" ORDER BY ");
2751 for (i, ob) in order_by.iter().enumerate() {
2752 if i > 0 {
2753 self.write(", ");
2754 }
2755 self.generate_ordered(ob)?;
2756 }
2757 }
2758 self.write(")");
2759 Ok(())
2760 }
2761 Expression::CumeDist(cd) => {
2762 self.write_keyword("CUME_DIST");
2763 self.write("(");
2764 if !cd.args.is_empty() {
2766 for (i, arg) in cd.args.iter().enumerate() {
2767 if i > 0 {
2768 self.write(", ");
2769 }
2770 self.generate_expression(arg)?;
2771 }
2772 } else if let Some(order_by) = &cd.order_by {
2773 self.write_keyword(" ORDER BY ");
2775 for (i, ob) in order_by.iter().enumerate() {
2776 if i > 0 {
2777 self.write(", ");
2778 }
2779 self.generate_ordered(ob)?;
2780 }
2781 }
2782 self.write(")");
2783 Ok(())
2784 }
2785 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
2786 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
2787
2788 Expression::Contains(f) => {
2790 self.generate_binary_func("CONTAINS", &f.this, &f.expression)
2791 }
2792 Expression::StartsWith(f) => {
2793 let name = match self.config.dialect {
2794 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
2795 _ => "STARTS_WITH",
2796 };
2797 self.generate_binary_func(name, &f.this, &f.expression)
2798 }
2799 Expression::EndsWith(f) => {
2800 let name = match self.config.dialect {
2801 Some(DialectType::Snowflake) => "ENDSWITH",
2802 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
2803 Some(DialectType::ClickHouse) => "endsWith",
2804 _ => "ENDS_WITH",
2805 };
2806 self.generate_binary_func(name, &f.this, &f.expression)
2807 }
2808 Expression::Position(f) => self.generate_position(f),
2809 Expression::Initcap(f) => match self.config.dialect {
2810 Some(DialectType::Presto)
2811 | Some(DialectType::Trino)
2812 | Some(DialectType::Athena) => {
2813 self.write_keyword("REGEXP_REPLACE");
2814 self.write("(");
2815 self.generate_expression(&f.this)?;
2816 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
2817 Ok(())
2818 }
2819 _ => self.generate_simple_func("INITCAP", &f.this),
2820 },
2821 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
2822 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
2823 Expression::CharFunc(f) => self.generate_char_func(f),
2824 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
2825 Expression::Levenshtein(f) => {
2826 self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression)
2827 }
2828
2829 Expression::ModFunc(f) => self.generate_mod_func(f),
2831 Expression::Random(_) => {
2832 self.write_keyword("RANDOM");
2833 self.write("()");
2834 Ok(())
2835 }
2836 Expression::Rand(f) => self.generate_rand(f),
2837 Expression::TruncFunc(f) => self.generate_truncate_func(f),
2838 Expression::Pi(_) => {
2839 self.write_keyword("PI");
2840 self.write("()");
2841 Ok(())
2842 }
2843 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
2844 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
2845 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
2846 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
2847 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
2848 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
2849 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
2850 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
2851 Expression::Atan2(f) => {
2852 let name = f.original_name.as_deref().unwrap_or("ATAN2");
2853 self.generate_binary_func(name, &f.this, &f.expression)
2854 }
2855
2856 Expression::Decode(f) => self.generate_decode(f),
2858
2859 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
2861 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
2862 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
2863 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
2864 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
2865 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
2866 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
2867 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
2868 Expression::DayOfWeek(f) => {
2869 let name = match self.config.dialect {
2870 Some(DialectType::Presto)
2871 | Some(DialectType::Trino)
2872 | Some(DialectType::Athena) => "DAY_OF_WEEK",
2873 Some(DialectType::DuckDB) => "ISODOW",
2874 _ => "DAYOFWEEK",
2875 };
2876 self.generate_simple_func(name, &f.this)
2877 }
2878 Expression::DayOfMonth(f) => {
2879 let name = match self.config.dialect {
2880 Some(DialectType::Presto)
2881 | Some(DialectType::Trino)
2882 | Some(DialectType::Athena) => "DAY_OF_MONTH",
2883 _ => "DAYOFMONTH",
2884 };
2885 self.generate_simple_func(name, &f.this)
2886 }
2887 Expression::DayOfYear(f) => {
2888 let name = match self.config.dialect {
2889 Some(DialectType::Presto)
2890 | Some(DialectType::Trino)
2891 | Some(DialectType::Athena) => "DAY_OF_YEAR",
2892 _ => "DAYOFYEAR",
2893 };
2894 self.generate_simple_func(name, &f.this)
2895 }
2896 Expression::WeekOfYear(f) => {
2897 let name = match self.config.dialect {
2899 Some(DialectType::Hive)
2900 | Some(DialectType::DuckDB)
2901 | Some(DialectType::Spark)
2902 | Some(DialectType::Databricks)
2903 | Some(DialectType::MySQL) => "WEEKOFYEAR",
2904 _ => "WEEK_OF_YEAR",
2905 };
2906 self.generate_simple_func(name, &f.this)
2907 }
2908 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
2909 Expression::AddMonths(f) => {
2910 self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression)
2911 }
2912 Expression::MonthsBetween(f) => {
2913 self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression)
2914 }
2915 Expression::LastDay(f) => self.generate_last_day(f),
2916 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
2917 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
2918 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
2919 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
2920 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
2921 Expression::MakeDate(f) => self.generate_make_date(f),
2922 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
2923 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
2924
2925 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
2927 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
2928 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
2929 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
2930 Expression::ArrayContains(f) => {
2931 self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression)
2932 }
2933 Expression::ArrayPosition(f) => {
2934 self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression)
2935 }
2936 Expression::ArrayAppend(f) => {
2937 self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression)
2938 }
2939 Expression::ArrayPrepend(f) => {
2940 self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression)
2941 }
2942 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
2943 Expression::ArraySort(f) => self.generate_array_sort(f),
2944 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
2945 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
2946 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
2947 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
2948 Expression::Unnest(f) => self.generate_unnest(f),
2949 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
2950 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
2951 Expression::ArrayFilter(f) => self.generate_array_filter(f),
2952 Expression::ArrayTransform(f) => self.generate_array_transform(f),
2953 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
2954 Expression::ArrayCompact(f) => {
2955 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
2956 self.write("LIST_FILTER(");
2958 self.generate_expression(&f.this)?;
2959 self.write(", _u -> NOT _u IS NULL)");
2960 Ok(())
2961 } else {
2962 self.generate_simple_func("ARRAY_COMPACT", &f.this)
2963 }
2964 }
2965 Expression::ArrayIntersect(f) => {
2966 let func_name = f.original_name.as_deref().unwrap_or("ARRAY_INTERSECT");
2967 self.generate_vararg_func(func_name, &f.expressions)
2968 }
2969 Expression::ArrayUnion(f) => {
2970 self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression)
2971 }
2972 Expression::ArrayExcept(f) => {
2973 self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression)
2974 }
2975 Expression::ArrayRemove(f) => {
2976 self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression)
2977 }
2978 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
2979 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
2980 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
2981
2982 Expression::StructFunc(f) => self.generate_struct_constructor(f),
2984 Expression::StructExtract(f) => self.generate_struct_extract(f),
2985 Expression::NamedStruct(f) => self.generate_named_struct(f),
2986
2987 Expression::MapFunc(f) => self.generate_map_constructor(f),
2989 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
2990 Expression::MapFromArrays(f) => {
2991 self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression)
2992 }
2993 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
2994 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
2995 Expression::MapContainsKey(f) => {
2996 self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression)
2997 }
2998 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
2999 Expression::ElementAt(f) => {
3000 self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression)
3001 }
3002 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
3003 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
3004
3005 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
3007 Expression::JsonExtractScalar(f) => {
3008 self.generate_json_extract("JSON_EXTRACT_SCALAR", f)
3009 }
3010 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
3011 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
3012 Expression::JsonObject(f) => self.generate_json_object(f),
3013 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
3014 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
3015 Expression::JsonArrayLength(f) => {
3016 self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this)
3017 }
3018 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
3019 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
3020 Expression::ParseJson(f) => {
3021 let name = match self.config.dialect {
3022 Some(DialectType::Presto)
3023 | Some(DialectType::Trino)
3024 | Some(DialectType::Athena) => "JSON_PARSE",
3025 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
3026 self.write_keyword("CAST");
3028 self.write("(");
3029 self.generate_expression(&f.this)?;
3030 self.write_keyword(" AS ");
3031 self.write_keyword("JSON");
3032 self.write(")");
3033 return Ok(());
3034 }
3035 Some(DialectType::Hive)
3036 | Some(DialectType::Spark)
3037 | Some(DialectType::MySQL)
3038 | Some(DialectType::SingleStore)
3039 | Some(DialectType::TiDB)
3040 | Some(DialectType::TSQL) => {
3041 self.generate_expression(&f.this)?;
3043 return Ok(());
3044 }
3045 Some(DialectType::DuckDB) => "JSON",
3046 _ => "PARSE_JSON",
3047 };
3048 self.generate_simple_func(name, &f.this)
3049 }
3050 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
3051 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
3052 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
3053 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
3054 Expression::JsonMergePatch(f) => {
3055 self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression)
3056 }
3057 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
3058 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
3059
3060 Expression::Convert(f) => self.generate_convert(f),
3062 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
3063
3064 Expression::Lambda(f) => self.generate_lambda(f),
3066 Expression::Parameter(f) => self.generate_parameter(f),
3067 Expression::Placeholder(f) => self.generate_placeholder(f),
3068 Expression::NamedArgument(f) => self.generate_named_argument(f),
3069 Expression::TableArgument(f) => self.generate_table_argument(f),
3070 Expression::SqlComment(f) => self.generate_sql_comment(f),
3071
3072 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
3074 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
3075 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
3076 Expression::SimilarTo(f) => self.generate_similar_to(f),
3077 Expression::Any(f) => self.generate_quantified("ANY", f),
3078 Expression::All(f) => self.generate_quantified("ALL", f),
3079 Expression::Overlaps(f) => self.generate_overlaps(f),
3080
3081 Expression::BitwiseLeftShift(op) => {
3083 if matches!(
3084 self.config.dialect,
3085 Some(DialectType::Presto) | Some(DialectType::Trino)
3086 ) {
3087 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_LEFT");
3088 self.write("(");
3089 self.generate_expression(&op.left)?;
3090 self.write(", ");
3091 self.generate_expression(&op.right)?;
3092 self.write(")");
3093 Ok(())
3094 } else if matches!(
3095 self.config.dialect,
3096 Some(DialectType::Spark) | Some(DialectType::Databricks)
3097 ) {
3098 self.write_keyword("SHIFTLEFT");
3099 self.write("(");
3100 self.generate_expression(&op.left)?;
3101 self.write(", ");
3102 self.generate_expression(&op.right)?;
3103 self.write(")");
3104 Ok(())
3105 } else {
3106 self.generate_binary_op(op, "<<")
3107 }
3108 }
3109 Expression::BitwiseRightShift(op) => {
3110 if matches!(
3111 self.config.dialect,
3112 Some(DialectType::Presto) | Some(DialectType::Trino)
3113 ) {
3114 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_RIGHT");
3115 self.write("(");
3116 self.generate_expression(&op.left)?;
3117 self.write(", ");
3118 self.generate_expression(&op.right)?;
3119 self.write(")");
3120 Ok(())
3121 } else if matches!(
3122 self.config.dialect,
3123 Some(DialectType::Spark) | Some(DialectType::Databricks)
3124 ) {
3125 self.write_keyword("SHIFTRIGHT");
3126 self.write("(");
3127 self.generate_expression(&op.left)?;
3128 self.write(", ");
3129 self.generate_expression(&op.right)?;
3130 self.write(")");
3131 Ok(())
3132 } else {
3133 self.generate_binary_op(op, ">>")
3134 }
3135 }
3136 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
3137 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
3138 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
3139
3140 Expression::Subscript(s) => self.generate_subscript(s),
3142 Expression::Dot(d) => self.generate_dot_access(d),
3143 Expression::MethodCall(m) => self.generate_method_call(m),
3144 Expression::ArraySlice(s) => self.generate_array_slice(s),
3145
3146 Expression::And(op) => self.generate_connector_op(op, ConnectorOperator::And),
3147 Expression::Or(op) => self.generate_connector_op(op, ConnectorOperator::Or),
3148 Expression::Add(op) => self.generate_binary_op(op, "+"),
3149 Expression::Sub(op) => self.generate_binary_op(op, "-"),
3150 Expression::Mul(op) => self.generate_binary_op(op, "*"),
3151 Expression::Div(op) => self.generate_binary_op(op, "/"),
3152 Expression::IntDiv(f) => {
3153 use crate::dialects::DialectType;
3154 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
3155 self.generate_expression(&f.this)?;
3157 self.write(" // ");
3158 self.generate_expression(&f.expression)?;
3159 Ok(())
3160 } else if matches!(
3161 self.config.dialect,
3162 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
3163 ) {
3164 self.generate_expression(&f.this)?;
3166 self.write(" ");
3167 self.write_keyword("DIV");
3168 self.write(" ");
3169 self.generate_expression(&f.expression)?;
3170 Ok(())
3171 } else {
3172 self.write_keyword("DIV");
3174 self.write("(");
3175 self.generate_expression(&f.this)?;
3176 self.write(", ");
3177 self.generate_expression(&f.expression)?;
3178 self.write(")");
3179 Ok(())
3180 }
3181 }
3182 Expression::Mod(op) => {
3183 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
3184 self.generate_binary_op(op, "MOD")
3185 } else {
3186 self.generate_binary_op(op, "%")
3187 }
3188 }
3189 Expression::Eq(op) => self.generate_binary_op(op, "="),
3190 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
3191 Expression::Lt(op) => self.generate_binary_op(op, "<"),
3192 Expression::Lte(op) => self.generate_binary_op(op, "<="),
3193 Expression::Gt(op) => self.generate_binary_op(op, ">"),
3194 Expression::Gte(op) => self.generate_binary_op(op, ">="),
3195 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
3196 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
3197 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
3198 Expression::Concat(op) => {
3199 if self.config.dialect == Some(DialectType::Solr) {
3201 self.generate_binary_op(op, "OR")
3202 } else if self.config.dialect == Some(DialectType::MySQL) {
3203 self.generate_mysql_concat_from_concat(op)
3204 } else {
3205 self.generate_binary_op(op, "||")
3206 }
3207 }
3208 Expression::BitwiseAnd(op) => {
3209 if matches!(
3211 self.config.dialect,
3212 Some(DialectType::Presto) | Some(DialectType::Trino)
3213 ) {
3214 self.write_keyword("BITWISE_AND");
3215 self.write("(");
3216 self.generate_expression(&op.left)?;
3217 self.write(", ");
3218 self.generate_expression(&op.right)?;
3219 self.write(")");
3220 Ok(())
3221 } else {
3222 self.generate_binary_op(op, "&")
3223 }
3224 }
3225 Expression::BitwiseOr(op) => {
3226 if matches!(
3228 self.config.dialect,
3229 Some(DialectType::Presto) | Some(DialectType::Trino)
3230 ) {
3231 self.write_keyword("BITWISE_OR");
3232 self.write("(");
3233 self.generate_expression(&op.left)?;
3234 self.write(", ");
3235 self.generate_expression(&op.right)?;
3236 self.write(")");
3237 Ok(())
3238 } else {
3239 self.generate_binary_op(op, "|")
3240 }
3241 }
3242 Expression::BitwiseXor(op) => {
3243 if matches!(
3245 self.config.dialect,
3246 Some(DialectType::Presto) | Some(DialectType::Trino)
3247 ) {
3248 self.write_keyword("BITWISE_XOR");
3249 self.write("(");
3250 self.generate_expression(&op.left)?;
3251 self.write(", ");
3252 self.generate_expression(&op.right)?;
3253 self.write(")");
3254 Ok(())
3255 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
3256 self.generate_binary_op(op, "#")
3257 } else {
3258 self.generate_binary_op(op, "^")
3259 }
3260 }
3261 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
3262 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
3263 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
3264 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
3265 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
3266 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
3267 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
3268 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
3269 Expression::JSONBContains(f) => {
3270 self.generate_expression(&f.this)?;
3272 self.write_space();
3273 self.write("?");
3274 self.write_space();
3275 self.generate_expression(&f.expression)
3276 }
3277 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
3278 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
3279 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
3280 Expression::Not(op) => self.generate_unary_op(op, "NOT"),
3281 Expression::Neg(op) => self.generate_unary_op(op, "-"),
3282 Expression::BitwiseNot(op) => {
3283 if matches!(
3285 self.config.dialect,
3286 Some(DialectType::Presto) | Some(DialectType::Trino)
3287 ) {
3288 self.write_keyword("BITWISE_NOT");
3289 self.write("(");
3290 self.generate_expression(&op.this)?;
3291 self.write(")");
3292 Ok(())
3293 } else {
3294 self.generate_unary_op(op, "~")
3295 }
3296 }
3297 Expression::In(in_expr) => self.generate_in(in_expr),
3298 Expression::Between(between) => self.generate_between(between),
3299 Expression::IsNull(is_null) => self.generate_is_null(is_null),
3300 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
3301 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
3302 Expression::IsJson(is_json) => self.generate_is_json(is_json),
3303 Expression::Is(is_expr) => self.generate_is(is_expr),
3304 Expression::Exists(exists) => self.generate_exists(exists),
3305 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
3306 Expression::Subquery(subquery) => self.generate_subquery(subquery),
3307 Expression::Paren(paren) => {
3308 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
3310
3311 if !skip_parens {
3312 self.write("(");
3313 if self.config.pretty {
3314 self.write_newline();
3315 self.indent_level += 1;
3316 self.write_indent();
3317 }
3318 }
3319 self.generate_expression(&paren.this)?;
3320 if !skip_parens {
3321 if self.config.pretty {
3322 self.write_newline();
3323 self.indent_level -= 1;
3324 self.write_indent();
3325 }
3326 self.write(")");
3327 }
3328 for comment in &paren.trailing_comments {
3330 self.write(" ");
3331 self.write_formatted_comment(comment);
3332 }
3333 Ok(())
3334 }
3335 Expression::Array(arr) => self.generate_array(arr),
3336 Expression::Tuple(tuple) => self.generate_tuple(tuple),
3337 Expression::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
3338 Expression::Ordered(ordered) => self.generate_ordered(ordered),
3339 Expression::DataType(dt) => self.generate_data_type(dt),
3340 Expression::Raw(raw) => {
3341 self.write(&raw.sql);
3342 Ok(())
3343 }
3344 Expression::CreateTask(task) => self.generate_create_task(task),
3345 Expression::TryCatch(try_catch) => self.generate_try_catch(try_catch),
3346 Expression::Command(cmd) => {
3347 self.write(&cmd.this);
3348 Ok(())
3349 }
3350 Expression::Kill(kill) => {
3351 self.write_keyword("KILL");
3352 if let Some(kind) = &kill.kind {
3353 self.write_space();
3354 self.write_keyword(kind);
3355 }
3356 self.write_space();
3357 self.generate_expression(&kill.this)?;
3358 Ok(())
3359 }
3360 Expression::Execute(exec) => {
3361 self.write_keyword("EXECUTE");
3362 self.write_space();
3363 self.generate_expression(&exec.this)?;
3364 for (i, param) in exec.parameters.iter().enumerate() {
3365 if i == 0 {
3366 self.write_space();
3367 } else {
3368 self.write(", ");
3369 }
3370 self.write(¶m.name);
3371 if !param.positional {
3373 self.write(" = ");
3374 self.generate_expression(¶m.value)?;
3375 }
3376 if param.output {
3377 self.write_space();
3378 self.write_keyword("OUTPUT");
3379 }
3380 }
3381 if let Some(ref suffix) = exec.suffix {
3382 self.write_space();
3383 self.write(suffix);
3384 }
3385 Ok(())
3386 }
3387 Expression::Annotated(annotated) => {
3388 self.generate_expression(&annotated.this)?;
3389 for comment in &annotated.trailing_comments {
3390 self.write(" ");
3391 self.write_formatted_comment(comment);
3392 }
3393 Ok(())
3394 }
3395
3396 Expression::CreateTable(ct) => self.generate_create_table(ct),
3398 Expression::DropTable(dt) => self.generate_drop_table(dt),
3399 Expression::Undrop(u) => self.generate_undrop(u),
3400 Expression::AlterTable(at) => self.generate_alter_table(at),
3401 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3402 Expression::DropIndex(di) => self.generate_drop_index(di),
3403 Expression::CreateView(cv) => self.generate_create_view(cv),
3404 Expression::DropView(dv) => self.generate_drop_view(dv),
3405 Expression::AlterView(av) => self.generate_alter_view(av),
3406 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3407 Expression::Truncate(tr) => self.generate_truncate(tr),
3408 Expression::Use(u) => self.generate_use(u),
3409 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3411 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3412 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3413 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3414 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3415 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3416 Expression::DropFunction(df) => self.generate_drop_function(df),
3417 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3418 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3419 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3420 Expression::CreateSynonym(cs) => {
3421 self.write_keyword("CREATE SYNONYM");
3422 self.write_space();
3423 self.generate_table(&cs.name)?;
3424 self.write_space();
3425 self.write_keyword("FOR");
3426 self.write_space();
3427 self.generate_table(&cs.target)?;
3428 Ok(())
3429 }
3430 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3431 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3432 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3433 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3434 Expression::CreateType(ct) => self.generate_create_type(ct),
3435 Expression::DropType(dt) => self.generate_drop_type(dt),
3436 Expression::Describe(d) => self.generate_describe(d),
3437 Expression::Show(s) => self.generate_show(s),
3438
3439 Expression::Cache(c) => self.generate_cache(c),
3441 Expression::Uncache(u) => self.generate_uncache(u),
3442 Expression::LoadData(l) => self.generate_load_data(l),
3443 Expression::Pragma(p) => self.generate_pragma(p),
3444 Expression::Grant(g) => self.generate_grant(g),
3445 Expression::Revoke(r) => self.generate_revoke(r),
3446 Expression::Comment(c) => self.generate_comment(c),
3447 Expression::SetStatement(s) => self.generate_set_statement(s),
3448
3449 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3451 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3452
3453 Expression::Values(values) => self.generate_values(values),
3455
3456 Expression::AIAgg(e) => self.generate_ai_agg(e),
3458 Expression::AIClassify(e) => self.generate_ai_classify(e),
3459 Expression::AddPartition(e) => self.generate_add_partition(e),
3460 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3461 Expression::Aliases(e) => self.generate_aliases(e),
3462 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3463 Expression::AlterColumn(e) => self.generate_alter_column(e),
3464 Expression::AlterSession(e) => self.generate_alter_session(e),
3465 Expression::AlterSet(e) => self.generate_alter_set(e),
3466 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3467 Expression::Analyze(e) => self.generate_analyze(e),
3468 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3469 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3470 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3471 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3472 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3473 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3474 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3475 Expression::Anonymous(e) => self.generate_anonymous(e),
3476 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3477 Expression::Apply(e) => self.generate_apply(e),
3478 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3479 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3480 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3481 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3482 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3483 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3484 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3485 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3486 Expression::ArgMax(e) => self.generate_arg_max(e),
3487 Expression::ArgMin(e) => self.generate_arg_min(e),
3488 Expression::ArrayAll(e) => self.generate_array_all(e),
3489 Expression::ArrayAny(e) => self.generate_array_any(e),
3490 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3491 Expression::ArraySum(e) => self.generate_array_sum(e),
3492 Expression::AtIndex(e) => self.generate_at_index(e),
3493 Expression::Attach(e) => self.generate_attach(e),
3494 Expression::AttachOption(e) => self.generate_attach_option(e),
3495 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3496 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3497 Expression::BackupProperty(e) => self.generate_backup_property(e),
3498 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3499 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3500 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3501 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3502 Expression::Booland(e) => self.generate_booland(e),
3503 Expression::Boolor(e) => self.generate_boolor(e),
3504 Expression::BuildProperty(e) => self.generate_build_property(e),
3505 Expression::ByteString(e) => self.generate_byte_string(e),
3506 Expression::CaseSpecificColumnConstraint(e) => {
3507 self.generate_case_specific_column_constraint(e)
3508 }
3509 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3510 Expression::Changes(e) => self.generate_changes(e),
3511 Expression::CharacterSetColumnConstraint(e) => {
3512 self.generate_character_set_column_constraint(e)
3513 }
3514 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3515 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3516 Expression::AssumeColumnConstraint(e) => self.generate_assume_column_constraint(e),
3517 Expression::CheckJson(e) => self.generate_check_json(e),
3518 Expression::CheckXml(e) => self.generate_check_xml(e),
3519 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3520 Expression::Clone(e) => self.generate_clone(e),
3521 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3522 Expression::ClusterByColumnsProperty(e) => self.generate_cluster_by_columns_property(e),
3523 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3524 Expression::CollateProperty(e) => self.generate_collate_property(e),
3525 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3526 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3527 Expression::ColumnPosition(e) => self.generate_column_position(e),
3528 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3529 Expression::Columns(e) => self.generate_columns(e),
3530 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3531 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3532 Expression::Commit(e) => self.generate_commit(e),
3533 Expression::Comprehension(e) => self.generate_comprehension(e),
3534 Expression::Compress(e) => self.generate_compress(e),
3535 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3536 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3537 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3538 Expression::Constraint(e) => self.generate_constraint(e),
3539 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3540 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3541 Expression::Copy(e) => self.generate_copy(e),
3542 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3543 Expression::Corr(e) => self.generate_corr(e),
3544 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3545 Expression::CovarPop(e) => self.generate_covar_pop(e),
3546 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3547 Expression::Credentials(e) => self.generate_credentials(e),
3548 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3549 Expression::Cte(e) => self.generate_cte(e),
3550 Expression::Cube(e) => self.generate_cube(e),
3551 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3552 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3553 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3554 Expression::CurrentUser(e) => self.generate_current_user(e),
3555 Expression::DPipe(e) => self.generate_d_pipe(e),
3556 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3557 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3558 Expression::Date(e) => self.generate_date_func(e),
3559 Expression::DateBin(e) => self.generate_date_bin(e),
3560 Expression::DateFormatColumnConstraint(e) => {
3561 self.generate_date_format_column_constraint(e)
3562 }
3563 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3564 Expression::Datetime(e) => self.generate_datetime(e),
3565 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3566 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3567 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3568 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3569 Expression::Dayname(e) => self.generate_dayname(e),
3570 Expression::Declare(e) => self.generate_declare(e),
3571 Expression::DeclareItem(e) => self.generate_declare_item(e),
3572 Expression::DecodeCase(e) => self.generate_decode_case(e),
3573 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3574 Expression::DecompressString(e) => self.generate_decompress_string(e),
3575 Expression::Decrypt(e) => self.generate_decrypt(e),
3576 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3577 Expression::DefaultColumnConstraint(e) => {
3578 self.write_keyword("DEFAULT");
3579 self.write_space();
3580 self.generate_expression(&e.this)?;
3581 if let Some(ref col) = e.for_column {
3582 self.write_space();
3583 self.write_keyword("FOR");
3584 self.write_space();
3585 self.generate_identifier(col)?;
3586 }
3587 Ok(())
3588 }
3589 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3590 Expression::Detach(e) => self.generate_detach(e),
3591 Expression::DictProperty(e) => self.generate_dict_property(e),
3592 Expression::DictRange(e) => self.generate_dict_range(e),
3593 Expression::Directory(e) => self.generate_directory(e),
3594 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3595 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3596 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3597 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3598 Expression::DotProduct(e) => self.generate_dot_product(e),
3599 Expression::DropPartition(e) => self.generate_drop_partition(e),
3600 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3601 Expression::Elt(e) => self.generate_elt(e),
3602 Expression::Encode(e) => self.generate_encode(e),
3603 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3604 Expression::Encrypt(e) => self.generate_encrypt(e),
3605 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3606 Expression::EngineProperty(e) => self.generate_engine_property(e),
3607 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3608 Expression::EphemeralColumnConstraint(e) => {
3609 self.generate_ephemeral_column_constraint(e)
3610 }
3611 Expression::EqualNull(e) => self.generate_equal_null(e),
3612 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3613 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3614 Expression::Export(e) => self.generate_export(e),
3615 Expression::ExternalProperty(e) => self.generate_external_property(e),
3616 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3617 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3618 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3619 Expression::Fetch(e) => self.generate_fetch(e),
3620 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3621 Expression::Filter(e) => self.generate_filter(e),
3622 Expression::Float64(e) => self.generate_float64(e),
3623 Expression::ForIn(e) => self.generate_for_in(e),
3624 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3625 Expression::Format(e) => self.generate_format(e),
3626 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3627 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3628 Expression::From(e) => self.generate_from(e),
3629 Expression::FromBase(e) => self.generate_from_base(e),
3630 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3631 Expression::GapFill(e) => self.generate_gap_fill(e),
3632 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3633 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3634 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3635 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3636 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3637 self.generate_generated_as_identity_column_constraint(e)
3638 }
3639 Expression::GeneratedAsRowColumnConstraint(e) => {
3640 self.generate_generated_as_row_column_constraint(e)
3641 }
3642 Expression::Get(e) => self.generate_get(e),
3643 Expression::GetExtract(e) => self.generate_get_extract(e),
3644 Expression::Getbit(e) => self.generate_getbit(e),
3645 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3646 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3647 Expression::Group(e) => self.generate_group(e),
3648 Expression::GroupBy(e) => self.generate_group_by(e),
3649 Expression::Grouping(e) => self.generate_grouping(e),
3650 Expression::GroupingId(e) => self.generate_grouping_id(e),
3651 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3652 Expression::HashAgg(e) => self.generate_hash_agg(e),
3653 Expression::Having(e) => self.generate_having(e),
3654 Expression::HavingMax(e) => self.generate_having_max(e),
3655 Expression::Heredoc(e) => self.generate_heredoc(e),
3656 Expression::HexEncode(e) => self.generate_hex_encode(e),
3657 Expression::Hll(e) => self.generate_hll(e),
3658 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3659 Expression::IncludeProperty(e) => self.generate_include_property(e),
3660 Expression::Index(e) => self.generate_index(e),
3661 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3662 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3663 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3664 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3665 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3666 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3667 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3668 Expression::Install(e) => self.generate_install(e),
3669 Expression::IntervalOp(e) => self.generate_interval_op(e),
3670 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3671 Expression::IntoClause(e) => self.generate_into_clause(e),
3672 Expression::Introducer(e) => self.generate_introducer(e),
3673 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3674 Expression::JSON(e) => self.generate_json(e),
3675 Expression::JSONArray(e) => self.generate_json_array(e),
3676 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3677 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3678 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3679 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3680 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3681 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3682 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3683 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3684 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3685 Expression::JSONExists(e) => self.generate_json_exists(e),
3686 Expression::JSONCast(e) => self.generate_json_cast(e),
3687 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3688 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3689 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3690 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3691 Expression::JSONFormat(e) => self.generate_json_format(e),
3692 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3693 Expression::JSONKeys(e) => self.generate_json_keys(e),
3694 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3695 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3696 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3697 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3698 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3699 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3700 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3701 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3702 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3703 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3704 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3705 Expression::JSONRemove(e) => self.generate_json_remove(e),
3706 Expression::JSONSchema(e) => self.generate_json_schema(e),
3707 Expression::JSONSet(e) => self.generate_json_set(e),
3708 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3709 Expression::JSONTable(e) => self.generate_json_table(e),
3710 Expression::JSONType(e) => self.generate_json_type(e),
3711 Expression::JSONValue(e) => self.generate_json_value(e),
3712 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3713 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3714 Expression::JoinHint(e) => self.generate_join_hint(e),
3715 Expression::JournalProperty(e) => self.generate_journal_property(e),
3716 Expression::LanguageProperty(e) => self.generate_language_property(e),
3717 Expression::Lateral(e) => self.generate_lateral(e),
3718 Expression::LikeProperty(e) => self.generate_like_property(e),
3719 Expression::Limit(e) => self.generate_limit(e),
3720 Expression::LimitOptions(e) => self.generate_limit_options(e),
3721 Expression::List(e) => self.generate_list(e),
3722 Expression::ToMap(e) => self.generate_tomap(e),
3723 Expression::Localtime(e) => self.generate_localtime(e),
3724 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3725 Expression::LocationProperty(e) => self.generate_location_property(e),
3726 Expression::Lock(e) => self.generate_lock(e),
3727 Expression::LockProperty(e) => self.generate_lock_property(e),
3728 Expression::LockingProperty(e) => self.generate_locking_property(e),
3729 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3730 Expression::LogProperty(e) => self.generate_log_property(e),
3731 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3732 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3733 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3734 Expression::MakeInterval(e) => self.generate_make_interval(e),
3735 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3736 Expression::Map(e) => self.generate_map(e),
3737 Expression::MapCat(e) => self.generate_map_cat(e),
3738 Expression::MapDelete(e) => self.generate_map_delete(e),
3739 Expression::MapInsert(e) => self.generate_map_insert(e),
3740 Expression::MapPick(e) => self.generate_map_pick(e),
3741 Expression::MaskingPolicyColumnConstraint(e) => {
3742 self.generate_masking_policy_column_constraint(e)
3743 }
3744 Expression::MatchAgainst(e) => self.generate_match_against(e),
3745 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3746 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3747 Expression::Merge(e) => self.generate_merge(e),
3748 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3749 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3750 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3751 Expression::Minhash(e) => self.generate_minhash(e),
3752 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3753 Expression::Monthname(e) => self.generate_monthname(e),
3754 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3755 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3756 Expression::Normal(e) => self.generate_normal(e),
3757 Expression::Normalize(e) => self.generate_normalize(e),
3758 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3759 Expression::Nullif(e) => self.generate_nullif(e),
3760 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3761 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3762 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3763 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3764 Expression::Offset(e) => self.generate_offset(e),
3765 Expression::Qualify(e) => self.generate_qualify(e),
3766 Expression::OnCluster(e) => self.generate_on_cluster(e),
3767 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3768 Expression::OnCondition(e) => self.generate_on_condition(e),
3769 Expression::OnConflict(e) => self.generate_on_conflict(e),
3770 Expression::OnProperty(e) => self.generate_on_property(e),
3771 Expression::Opclass(e) => self.generate_opclass(e),
3772 Expression::OpenJSON(e) => self.generate_open_json(e),
3773 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3774 Expression::Operator(e) => self.generate_operator(e),
3775 Expression::OrderBy(e) => self.generate_order_by(e),
3776 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3777 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3778 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3779 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3780 Expression::ParseIp(e) => self.generate_parse_ip(e),
3781 Expression::ParseJSON(e) => self.generate_parse_json(e),
3782 Expression::ParseTime(e) => self.generate_parse_time(e),
3783 Expression::ParseUrl(e) => self.generate_parse_url(e),
3784 Expression::Partition(e) => self.generate_partition_expr(e),
3785 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3786 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3787 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3788 Expression::PartitionByRangePropertyDynamic(e) => {
3789 self.generate_partition_by_range_property_dynamic(e)
3790 }
3791 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3792 Expression::PartitionList(e) => self.generate_partition_list(e),
3793 Expression::PartitionRange(e) => self.generate_partition_range(e),
3794 Expression::PartitionByProperty(e) => self.generate_partition_by_property(e),
3795 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3796 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3797 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3798 Expression::PeriodForSystemTimeConstraint(e) => {
3799 self.generate_period_for_system_time_constraint(e)
3800 }
3801 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3802 Expression::PivotAny(e) => self.generate_pivot_any(e),
3803 Expression::Predict(e) => self.generate_predict(e),
3804 Expression::PreviousDay(e) => self.generate_previous_day(e),
3805 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3806 Expression::PrimaryKeyColumnConstraint(e) => {
3807 self.generate_primary_key_column_constraint(e)
3808 }
3809 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3810 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3811 Expression::OptionsProperty(e) => self.generate_options_property(e),
3812 Expression::Properties(e) => self.generate_properties(e),
3813 Expression::Property(e) => self.generate_property(e),
3814 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3815 Expression::Put(e) => self.generate_put(e),
3816 Expression::Quantile(e) => self.generate_quantile(e),
3817 Expression::QueryBand(e) => self.generate_query_band(e),
3818 Expression::QueryOption(e) => self.generate_query_option(e),
3819 Expression::QueryTransform(e) => self.generate_query_transform(e),
3820 Expression::Randn(e) => self.generate_randn(e),
3821 Expression::Randstr(e) => self.generate_randstr(e),
3822 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3823 Expression::RangeN(e) => self.generate_range_n(e),
3824 Expression::ReadCSV(e) => self.generate_read_csv(e),
3825 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3826 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3827 Expression::Reduce(e) => self.generate_reduce(e),
3828 Expression::Reference(e) => self.generate_reference(e),
3829 Expression::Refresh(e) => self.generate_refresh(e),
3830 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3831 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3832 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3833 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3834 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3835 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3836 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3837 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3838 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3839 Expression::RegrCount(e) => self.generate_regr_count(e),
3840 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3841 Expression::RegrR2(e) => self.generate_regr_r2(e),
3842 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3843 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3844 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3845 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3846 Expression::RegrValx(e) => self.generate_regr_valx(e),
3847 Expression::RegrValy(e) => self.generate_regr_valy(e),
3848 Expression::RemoteWithConnectionModelProperty(e) => {
3849 self.generate_remote_with_connection_model_property(e)
3850 }
3851 Expression::RenameColumn(e) => self.generate_rename_column(e),
3852 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3853 Expression::Returning(e) => self.generate_returning(e),
3854 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3855 Expression::Rollback(e) => self.generate_rollback(e),
3856 Expression::Rollup(e) => self.generate_rollup(e),
3857 Expression::RowFormatDelimitedProperty(e) => {
3858 self.generate_row_format_delimited_property(e)
3859 }
3860 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3861 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3862 Expression::SHA2(e) => self.generate_sha2(e),
3863 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3864 Expression::SafeAdd(e) => self.generate_safe_add(e),
3865 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3866 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3867 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3868 Expression::SampleProperty(e) => self.generate_sample_property(e),
3869 Expression::Schema(e) => self.generate_schema(e),
3870 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3871 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3872 Expression::Search(e) => self.generate_search(e),
3873 Expression::SearchIp(e) => self.generate_search_ip(e),
3874 Expression::SecurityProperty(e) => self.generate_security_property(e),
3875 Expression::SemanticView(e) => self.generate_semantic_view(e),
3876 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3877 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3878 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3879 Expression::Set(e) => self.generate_set(e),
3880 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3881 Expression::SetItem(e) => self.generate_set_item(e),
3882 Expression::SetOperation(e) => self.generate_set_operation(e),
3883 Expression::SetProperty(e) => self.generate_set_property(e),
3884 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3885 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3886 Expression::Slice(e) => self.generate_slice(e),
3887 Expression::SortArray(e) => self.generate_sort_array(e),
3888 Expression::SortBy(e) => self.generate_sort_by(e),
3889 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3890 Expression::SplitPart(e) => self.generate_split_part(e),
3891 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3892 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3893 Expression::StDistance(e) => self.generate_st_distance(e),
3894 Expression::StPoint(e) => self.generate_st_point(e),
3895 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3896 Expression::StandardHash(e) => self.generate_standard_hash(e),
3897 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3898 Expression::StrPosition(e) => self.generate_str_position(e),
3899 Expression::StrToDate(e) => self.generate_str_to_date(e),
3900 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3901 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3902 Expression::StrToMap(e) => self.generate_str_to_map(e),
3903 Expression::StrToTime(e) => self.generate_str_to_time(e),
3904 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3905 Expression::StringToArray(e) => self.generate_string_to_array(e),
3906 Expression::Struct(e) => self.generate_struct(e),
3907 Expression::Stuff(e) => self.generate_stuff(e),
3908 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3909 Expression::Summarize(e) => self.generate_summarize(e),
3910 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3911 Expression::TableAlias(e) => self.generate_table_alias(e),
3912 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3913 Expression::RowsFrom(e) => self.generate_rows_from(e),
3914 Expression::TableSample(e) => self.generate_table_sample(e),
3915 Expression::Tag(e) => self.generate_tag(e),
3916 Expression::Tags(e) => self.generate_tags(e),
3917 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3918 Expression::Time(e) => self.generate_time_func(e),
3919 Expression::TimeAdd(e) => self.generate_time_add(e),
3920 Expression::TimeDiff(e) => self.generate_time_diff(e),
3921 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3922 Expression::TimeSlice(e) => self.generate_time_slice(e),
3923 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3924 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3925 Expression::TimeSub(e) => self.generate_time_sub(e),
3926 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3927 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3928 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3929 Expression::TimeUnit(e) => self.generate_time_unit(e),
3930 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3931 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3932 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3933 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3934 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3935 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3936 Expression::ToBinary(e) => self.generate_to_binary(e),
3937 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3938 Expression::ToChar(e) => self.generate_to_char(e),
3939 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3940 Expression::ToDouble(e) => self.generate_to_double(e),
3941 Expression::ToFile(e) => self.generate_to_file(e),
3942 Expression::ToNumber(e) => self.generate_to_number(e),
3943 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3944 Expression::Transaction(e) => self.generate_transaction(e),
3945 Expression::Transform(e) => self.generate_transform(e),
3946 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3947 Expression::TransientProperty(e) => self.generate_transient_property(e),
3948 Expression::Translate(e) => self.generate_translate(e),
3949 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
3950 Expression::TruncateTable(e) => self.generate_truncate_table(e),
3951 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
3952 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
3953 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
3954 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
3955 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
3956 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
3957 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
3958 Expression::Unhex(e) => self.generate_unhex(e),
3959 Expression::UnicodeString(e) => self.generate_unicode_string(e),
3960 Expression::Uniform(e) => self.generate_uniform(e),
3961 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
3962 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
3963 Expression::RollupProperty(e) => self.generate_rollup_property(e),
3964 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
3965 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
3966 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
3967 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
3968 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
3969 Expression::UtcTime(e) => self.generate_utc_time(e),
3970 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
3971 Expression::Uuid(e) => self.generate_uuid(e),
3972 Expression::Var(v) => {
3973 if matches!(self.config.dialect, Some(DialectType::MySQL))
3974 && v.this.len() > 2
3975 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
3976 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
3977 {
3978 return self.generate_identifier(&Identifier {
3979 name: v.this.clone(),
3980 quoted: true,
3981 trailing_comments: Vec::new(),
3982 span: None,
3983 });
3984 }
3985 self.write(&v.this);
3986 Ok(())
3987 }
3988 Expression::Variadic(e) => {
3989 self.write_keyword("VARIADIC");
3990 self.write_space();
3991 self.generate_expression(&e.this)?;
3992 Ok(())
3993 }
3994 Expression::VarMap(e) => self.generate_var_map(e),
3995 Expression::VectorSearch(e) => self.generate_vector_search(e),
3996 Expression::Version(e) => self.generate_version(e),
3997 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
3998 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
3999 Expression::WatermarkColumnConstraint(e) => {
4000 self.generate_watermark_column_constraint(e)
4001 }
4002 Expression::Week(e) => self.generate_week(e),
4003 Expression::When(e) => self.generate_when(e),
4004 Expression::Whens(e) => self.generate_whens(e),
4005 Expression::Where(e) => self.generate_where(e),
4006 Expression::WidthBucket(e) => self.generate_width_bucket(e),
4007 Expression::Window(e) => self.generate_window(e),
4008 Expression::WindowSpec(e) => self.generate_window_spec(e),
4009 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
4010 Expression::WithFill(e) => self.generate_with_fill(e),
4011 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
4012 Expression::WithOperator(e) => self.generate_with_operator(e),
4013 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
4014 Expression::WithSchemaBindingProperty(e) => {
4015 self.generate_with_schema_binding_property(e)
4016 }
4017 Expression::WithSystemVersioningProperty(e) => {
4018 self.generate_with_system_versioning_property(e)
4019 }
4020 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
4021 Expression::XMLElement(e) => self.generate_xml_element(e),
4022 Expression::XMLGet(e) => self.generate_xml_get(e),
4023 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
4024 Expression::XMLTable(e) => self.generate_xml_table(e),
4025 Expression::Xor(e) => self.generate_xor(e),
4026 Expression::Zipf(e) => self.generate_zipf(e),
4027 _ => self.write_unsupported_comment("unsupported expression"),
4028 }
4029 }
4030
4031 fn generate_select(&mut self, select: &Select) -> Result<()> {
4032 use crate::dialects::DialectType;
4033
4034 if let Some(exclude) = &select.exclude {
4038 if !exclude.is_empty() && !matches!(self.config.dialect, Some(DialectType::Redshift)) {
4039 let mut inner_select = select.clone();
4041 inner_select.exclude = None;
4042 let inner_expr = Expression::Select(Box::new(inner_select));
4043
4044 let subquery = crate::expressions::Subquery {
4046 this: inner_expr,
4047 alias: None,
4048 column_aliases: Vec::new(),
4049 alias_explicit_as: false,
4050 alias_keyword: None,
4051 order_by: None,
4052 limit: None,
4053 offset: None,
4054 distribute_by: None,
4055 sort_by: None,
4056 cluster_by: None,
4057 lateral: false,
4058 modifiers_inside: false,
4059 trailing_comments: Vec::new(),
4060 inferred_type: None,
4061 };
4062
4063 let star = Expression::Star(crate::expressions::Star {
4065 table: None,
4066 except: Some(
4067 exclude
4068 .iter()
4069 .map(|e| match e {
4070 Expression::Column(col) => col.name.clone(),
4071 Expression::Identifier(id) => id.clone(),
4072 _ => crate::expressions::Identifier::new("unknown".to_string()),
4073 })
4074 .collect(),
4075 ),
4076 replace: None,
4077 rename: None,
4078 trailing_comments: Vec::new(),
4079 span: None,
4080 });
4081
4082 let outer_select = Select {
4083 expressions: vec![star],
4084 from: Some(crate::expressions::From {
4085 expressions: vec![Expression::Subquery(Box::new(subquery))],
4086 }),
4087 ..Select::new()
4088 };
4089
4090 return self.generate_select(&outer_select);
4091 }
4092 }
4093
4094 for comment in &select.leading_comments {
4096 self.write_formatted_comment(comment);
4097 self.write(" ");
4098 }
4099
4100 if let Some(with) = &select.with {
4102 self.generate_with(with)?;
4103 if self.config.pretty {
4104 self.write_newline();
4105 self.write_indent();
4106 } else {
4107 self.write_space();
4108 }
4109 }
4110
4111 for comment in &select.post_select_comments {
4114 self.write_formatted_comment(comment);
4115 self.write(" ");
4116 }
4117
4118 self.write_keyword("SELECT");
4119
4120 if let Some(hint) = &select.hint {
4122 self.generate_hint(hint)?;
4123 }
4124
4125 let use_top_from_limit = matches!(
4129 self.config.dialect,
4130 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4131 ) && select.top.is_none()
4132 && select.limit.is_some()
4133 && select.offset.is_none(); let is_top_dialect = matches!(
4138 self.config.dialect,
4139 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
4140 );
4141 let keep_top_verbatim = !is_top_dialect
4142 && select.limit.is_none()
4143 && select
4144 .top
4145 .as_ref()
4146 .map_or(false, |top| top.percent || top.with_ties);
4147
4148 if select.distinct && (is_top_dialect || select.top.is_some()) {
4149 self.write_space();
4150 self.write_keyword("DISTINCT");
4151 }
4152
4153 if is_top_dialect || keep_top_verbatim {
4154 if let Some(top) = &select.top {
4155 self.write_space();
4156 self.write_keyword("TOP");
4157 if top.parenthesized {
4158 if matches!(&top.this, Expression::Subquery(_) | Expression::Paren(_)) {
4159 self.write_space();
4160 self.generate_expression(&top.this)?;
4161 } else {
4162 self.write(" (");
4163 self.generate_expression(&top.this)?;
4164 self.write(")");
4165 }
4166 } else {
4167 self.write_space();
4168 self.generate_expression(&top.this)?;
4169 }
4170 if top.percent {
4171 self.write_space();
4172 self.write_keyword("PERCENT");
4173 }
4174 if top.with_ties {
4175 self.write_space();
4176 self.write_keyword("WITH TIES");
4177 }
4178 } else if use_top_from_limit {
4179 if let Some(limit) = &select.limit {
4181 self.write_space();
4182 self.write_keyword("TOP");
4183 let is_simple_literal = matches!(&limit.this, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)));
4185 if is_simple_literal {
4186 self.write_space();
4187 self.generate_expression(&limit.this)?;
4188 } else {
4189 self.write(" (");
4190 self.generate_expression(&limit.this)?;
4191 self.write(")");
4192 }
4193 }
4194 }
4195 }
4196
4197 if select.distinct && !is_top_dialect && select.top.is_none() {
4198 self.write_space();
4199 self.write_keyword("DISTINCT");
4200 }
4201
4202 if let Some(distinct_on) = &select.distinct_on {
4204 self.write_space();
4205 self.write_keyword("ON");
4206 self.write(" (");
4207 for (i, expr) in distinct_on.iter().enumerate() {
4208 if i > 0 {
4209 self.write(", ");
4210 }
4211 self.generate_expression(expr)?;
4212 }
4213 self.write(")");
4214 }
4215
4216 for modifier in &select.operation_modifiers {
4218 self.write_space();
4219 self.write_keyword(modifier);
4220 }
4221
4222 if let Some(kind) = &select.kind {
4224 self.write_space();
4225 self.write_keyword("AS");
4226 self.write_space();
4227 self.write_keyword(kind);
4228 }
4229
4230 if !select.expressions.is_empty() {
4232 if self.config.pretty {
4233 self.write_newline();
4234 self.indent_level += 1;
4235 } else {
4236 self.write_space();
4237 }
4238 }
4239
4240 for (i, expr) in select.expressions.iter().enumerate() {
4241 if i > 0 {
4242 self.write(",");
4243 if self.config.pretty {
4244 self.write_newline();
4245 } else {
4246 self.write_space();
4247 }
4248 }
4249 if self.config.pretty {
4250 self.write_indent();
4251 }
4252 self.generate_expression(expr)?;
4253 }
4254
4255 if self.config.pretty && !select.expressions.is_empty() {
4256 self.indent_level -= 1;
4257 }
4258
4259 if let Some(exclude) = &select.exclude {
4264 if !exclude.is_empty() && matches!(self.config.dialect, Some(DialectType::Redshift)) {
4265 self.write_space();
4266 self.write_keyword("EXCLUDE");
4267 self.write(" (");
4268 for (i, col) in exclude.iter().enumerate() {
4269 if i > 0 {
4270 self.write(", ");
4271 }
4272 self.generate_expression(col)?;
4273 }
4274 self.write(")");
4275 }
4276 }
4277
4278 if let Some(into) = &select.into {
4281 if self.config.pretty {
4282 self.write_newline();
4283 self.write_indent();
4284 } else {
4285 self.write_space();
4286 }
4287 if into.bulk_collect {
4288 self.write_keyword("BULK COLLECT INTO");
4289 } else {
4290 self.write_keyword("INTO");
4291 }
4292 if into.temporary {
4293 self.write_space();
4294 self.write_keyword("TEMPORARY");
4295 }
4296 if into.unlogged {
4297 self.write_space();
4298 self.write_keyword("UNLOGGED");
4299 }
4300 self.write_space();
4301 if !into.expressions.is_empty() {
4303 for (i, expr) in into.expressions.iter().enumerate() {
4304 if i > 0 {
4305 self.write(", ");
4306 }
4307 self.generate_expression(expr)?;
4308 }
4309 } else {
4310 self.generate_expression(&into.this)?;
4311 }
4312 }
4313
4314 if let Some(from) = &select.from {
4316 if self.config.pretty {
4317 self.write_newline();
4318 self.write_indent();
4319 } else {
4320 self.write_space();
4321 }
4322 self.write_keyword("FROM");
4323 self.write_space();
4324
4325 let has_tablesample = from
4330 .expressions
4331 .iter()
4332 .any(|e| matches!(e, Expression::TableSample(_)));
4333 let is_cross_join_dialect = matches!(
4334 self.config.dialect,
4335 Some(DialectType::BigQuery)
4336 | Some(DialectType::Hive)
4337 | Some(DialectType::Spark)
4338 | Some(DialectType::Databricks)
4339 | Some(DialectType::SQLite)
4340 | Some(DialectType::ClickHouse)
4341 );
4342 let source_is_same_as_target = self.config.source_dialect.is_some()
4345 && self.config.source_dialect == self.config.dialect;
4346 let source_is_cross_join_dialect = matches!(
4347 self.config.source_dialect,
4348 Some(DialectType::BigQuery)
4349 | Some(DialectType::Hive)
4350 | Some(DialectType::Spark)
4351 | Some(DialectType::Databricks)
4352 | Some(DialectType::SQLite)
4353 | Some(DialectType::ClickHouse)
4354 );
4355 let use_cross_join = !has_tablesample
4356 && is_cross_join_dialect
4357 && (source_is_same_as_target
4358 || source_is_cross_join_dialect
4359 || self.config.source_dialect.is_none());
4360
4361 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4363
4364 for (i, expr) in from.expressions.iter().enumerate() {
4365 if i > 0 {
4366 if use_cross_join {
4367 self.write(" CROSS JOIN ");
4368 } else {
4369 self.write(", ");
4370 }
4371 }
4372 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4373 self.write("(");
4374 self.generate_expression(expr)?;
4375 self.write(")");
4376 } else {
4377 self.generate_expression(expr)?;
4378 }
4379 let leading = Self::extract_table_leading_comments(expr);
4382 for comment in &leading {
4383 self.write_space();
4384 self.write_formatted_comment(comment);
4385 }
4386 }
4387 }
4388
4389 if self.config.pretty {
4393 self.generate_joins_with_nesting(&select.joins)?;
4394 } else {
4395 for join in &select.joins {
4396 self.generate_join(join)?;
4397 }
4398 for join in select.joins.iter().rev() {
4400 if join.deferred_condition {
4401 self.generate_join_condition(join)?;
4402 }
4403 }
4404 }
4405
4406 for (lv_idx, lateral_view) in select.lateral_views.iter().enumerate() {
4408 self.generate_lateral_view(lateral_view, lv_idx)?;
4409 }
4410
4411 if let Some(prewhere) = &select.prewhere {
4413 self.write_clause_condition("PREWHERE", prewhere)?;
4414 }
4415
4416 if let Some(where_clause) = &select.where_clause {
4418 self.write_clause_condition("WHERE", &where_clause.this)?;
4419 }
4420
4421 if let Some(connect) = &select.connect {
4423 self.generate_connect(connect)?;
4424 }
4425
4426 if let Some(group_by) = &select.group_by {
4428 if self.config.pretty {
4429 for comment in &group_by.comments {
4431 self.write_newline();
4432 self.write_indent();
4433 self.write_formatted_comment(comment);
4434 }
4435 self.write_newline();
4436 self.write_indent();
4437 } else {
4438 self.write_space();
4439 for comment in &group_by.comments {
4441 self.write_formatted_comment(comment);
4442 self.write_space();
4443 }
4444 }
4445 let clickhouse_bare_modifiers =
4446 matches!(self.config.dialect, Some(DialectType::ClickHouse))
4447 && group_by.all.is_none()
4448 && (group_by.totals || !group_by.expressions.is_empty())
4449 && group_by.expressions.iter().all(|expr| match expr {
4450 Expression::Cube(c) => c.expressions.is_empty(),
4451 Expression::Rollup(r) => r.expressions.is_empty(),
4452 _ => false,
4453 });
4454
4455 if clickhouse_bare_modifiers {
4456 let trailing_cube = group_by
4457 .expressions
4458 .iter()
4459 .any(|expr| matches!(expr, Expression::Cube(c) if c.expressions.is_empty()));
4460 let trailing_rollup = group_by
4461 .expressions
4462 .iter()
4463 .any(|expr| matches!(expr, Expression::Rollup(r) if r.expressions.is_empty()));
4464
4465 if trailing_cube {
4466 self.write_keyword("WITH CUBE");
4467 } else if trailing_rollup {
4468 self.write_keyword("WITH ROLLUP");
4469 }
4470
4471 if group_by.totals {
4472 if trailing_cube || trailing_rollup {
4473 self.write_space();
4474 }
4475 self.write_keyword("WITH TOTALS");
4476 }
4477 } else {
4478 self.write_keyword("GROUP BY");
4479 match group_by.all {
4481 Some(true) => {
4482 self.write_space();
4483 self.write_keyword("ALL");
4484 }
4485 Some(false) => {
4486 self.write_space();
4487 self.write_keyword("DISTINCT");
4488 }
4489 None => {}
4490 }
4491 if !group_by.expressions.is_empty() {
4492 let mut trailing_cube = false;
4495 let mut trailing_rollup = false;
4496 let mut plain_expressions: Vec<&Expression> = Vec::new();
4497 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4498 let mut cube_expressions: Vec<&Expression> = Vec::new();
4499 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4500
4501 for expr in &group_by.expressions {
4502 match expr {
4503 Expression::Cube(c) if c.expressions.is_empty() => {
4504 trailing_cube = true;
4505 }
4506 Expression::Rollup(r) if r.expressions.is_empty() => {
4507 trailing_rollup = true;
4508 }
4509 Expression::Function(f) if f.name == "CUBE" => {
4510 cube_expressions.push(expr);
4511 }
4512 Expression::Function(f) if f.name == "ROLLUP" => {
4513 rollup_expressions.push(expr);
4514 }
4515 Expression::Function(f) if f.name == "GROUPING SETS" => {
4516 grouping_sets_expressions.push(expr);
4517 }
4518 _ => {
4519 plain_expressions.push(expr);
4520 }
4521 }
4522 }
4523
4524 let mut regular_expressions: Vec<&Expression> = Vec::new();
4526 regular_expressions.extend(plain_expressions);
4527 regular_expressions.extend(grouping_sets_expressions);
4528 regular_expressions.extend(cube_expressions);
4529 regular_expressions.extend(rollup_expressions);
4530
4531 if self.config.pretty {
4532 self.write_newline();
4533 self.indent_level += 1;
4534 self.write_indent();
4535 } else {
4536 self.write_space();
4537 }
4538
4539 for (i, expr) in regular_expressions.iter().enumerate() {
4540 if i > 0 {
4541 if self.config.pretty {
4542 self.write(",");
4543 self.write_newline();
4544 self.write_indent();
4545 } else {
4546 self.write(", ");
4547 }
4548 }
4549 self.generate_expression(expr)?;
4550 }
4551
4552 if self.config.pretty {
4553 self.indent_level -= 1;
4554 }
4555
4556 if trailing_cube {
4558 self.write_space();
4559 self.write_keyword("WITH CUBE");
4560 } else if trailing_rollup {
4561 self.write_space();
4562 self.write_keyword("WITH ROLLUP");
4563 }
4564 }
4565
4566 if group_by.totals {
4568 self.write_space();
4569 self.write_keyword("WITH TOTALS");
4570 }
4571 }
4572 }
4573
4574 if let Some(having) = &select.having {
4576 if self.config.pretty {
4577 for comment in &having.comments {
4579 self.write_newline();
4580 self.write_indent();
4581 self.write_formatted_comment(comment);
4582 }
4583 } else {
4584 for comment in &having.comments {
4585 self.write_space();
4586 self.write_formatted_comment(comment);
4587 }
4588 }
4589 self.write_clause_condition("HAVING", &having.this)?;
4590 }
4591
4592 if select.qualify_after_window {
4594 if let Some(windows) = &select.windows {
4596 self.write_window_clause(windows)?;
4597 }
4598 if let Some(qualify) = &select.qualify {
4599 self.write_clause_condition("QUALIFY", &qualify.this)?;
4600 }
4601 } else {
4602 if let Some(qualify) = &select.qualify {
4604 self.write_clause_condition("QUALIFY", &qualify.this)?;
4605 }
4606 if let Some(windows) = &select.windows {
4607 self.write_window_clause(windows)?;
4608 }
4609 }
4610
4611 if let Some(distribute_by) = &select.distribute_by {
4613 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4614 }
4615
4616 if let Some(cluster_by) = &select.cluster_by {
4618 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4619 }
4620
4621 if let Some(sort_by) = &select.sort_by {
4623 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4624 }
4625
4626 if let Some(order_by) = &select.order_by {
4628 if self.config.pretty {
4629 for comment in &order_by.comments {
4631 self.write_newline();
4632 self.write_indent();
4633 self.write_formatted_comment(comment);
4634 }
4635 } else {
4636 for comment in &order_by.comments {
4637 self.write_space();
4638 self.write_formatted_comment(comment);
4639 }
4640 }
4641 let keyword = if order_by.siblings {
4642 "ORDER SIBLINGS BY"
4643 } else {
4644 "ORDER BY"
4645 };
4646 self.write_order_clause(keyword, &order_by.expressions)?;
4647 }
4648
4649 if select.order_by.is_none()
4651 && select.fetch.is_some()
4652 && matches!(
4653 self.config.dialect,
4654 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4655 )
4656 {
4657 if self.config.pretty {
4658 self.write_newline();
4659 self.write_indent();
4660 } else {
4661 self.write_space();
4662 }
4663 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4664 }
4665
4666 let is_presto_like = matches!(
4671 self.config.dialect,
4672 Some(DialectType::Presto) | Some(DialectType::Trino)
4673 );
4674
4675 if is_presto_like && select.offset.is_some() {
4676 if let Some(offset) = &select.offset {
4678 if self.config.pretty {
4679 self.write_newline();
4680 self.write_indent();
4681 } else {
4682 self.write_space();
4683 }
4684 self.write_keyword("OFFSET");
4685 self.write_space();
4686 self.write_limit_expr(&offset.this)?;
4687 if offset.rows == Some(true) {
4688 self.write_space();
4689 self.write_keyword("ROWS");
4690 }
4691 }
4692 if let Some(limit) = &select.limit {
4693 if self.config.pretty {
4694 self.write_newline();
4695 self.write_indent();
4696 } else {
4697 self.write_space();
4698 }
4699 self.write_keyword("LIMIT");
4700 self.write_space();
4701 self.write_limit_expr(&limit.this)?;
4702 if limit.percent {
4703 self.write_space();
4704 self.write_keyword("PERCENT");
4705 }
4706 for comment in &limit.comments {
4708 self.write(" ");
4709 self.write_formatted_comment(comment);
4710 }
4711 }
4712 } else {
4713 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
4715 !fetch.percent
4716 && !fetch.with_ties
4717 && fetch.count.is_some()
4718 && matches!(
4719 self.config.dialect,
4720 Some(DialectType::Spark)
4721 | Some(DialectType::Hive)
4722 | Some(DialectType::DuckDB)
4723 | Some(DialectType::SQLite)
4724 | Some(DialectType::MySQL)
4725 | Some(DialectType::BigQuery)
4726 | Some(DialectType::Databricks)
4727 | Some(DialectType::StarRocks)
4728 | Some(DialectType::Doris)
4729 | Some(DialectType::Athena)
4730 | Some(DialectType::ClickHouse)
4731 | Some(DialectType::Redshift)
4732 )
4733 });
4734
4735 if let Some(limit) = &select.limit {
4737 if !matches!(
4739 self.config.dialect,
4740 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4741 ) {
4742 if self.config.pretty {
4743 self.write_newline();
4744 self.write_indent();
4745 } else {
4746 self.write_space();
4747 }
4748 self.write_keyword("LIMIT");
4749 self.write_space();
4750 self.write_limit_expr(&limit.this)?;
4751 if limit.percent {
4752 self.write_space();
4753 self.write_keyword("PERCENT");
4754 }
4755 for comment in &limit.comments {
4757 self.write(" ");
4758 self.write_formatted_comment(comment);
4759 }
4760 }
4761 }
4762
4763 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
4765 if let Some(top) = &select.top {
4766 if !top.percent && !top.with_ties {
4767 if self.config.pretty {
4768 self.write_newline();
4769 self.write_indent();
4770 } else {
4771 self.write_space();
4772 }
4773 self.write_keyword("LIMIT");
4774 self.write_space();
4775 self.generate_expression(&top.this)?;
4776 }
4777 }
4778 }
4779
4780 if fetch_as_limit && select.offset.is_some() {
4783 if let Some(fetch) = &select.fetch {
4784 if self.config.pretty {
4785 self.write_newline();
4786 self.write_indent();
4787 } else {
4788 self.write_space();
4789 }
4790 self.write_keyword("LIMIT");
4791 self.write_space();
4792 self.generate_expression(fetch.count.as_ref().unwrap())?;
4793 }
4794 }
4795
4796 if let Some(offset) = &select.offset {
4800 if self.config.pretty {
4801 self.write_newline();
4802 self.write_indent();
4803 } else {
4804 self.write_space();
4805 }
4806 if matches!(
4807 self.config.dialect,
4808 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4809 ) {
4810 self.write_keyword("OFFSET");
4812 self.write_space();
4813 self.write_limit_expr(&offset.this)?;
4814 self.write_space();
4815 self.write_keyword("ROWS");
4816 if let Some(limit) = &select.limit {
4818 self.write_space();
4819 self.write_keyword("FETCH NEXT");
4820 self.write_space();
4821 self.write_limit_expr(&limit.this)?;
4822 self.write_space();
4823 self.write_keyword("ROWS ONLY");
4824 }
4825 } else {
4826 self.write_keyword("OFFSET");
4827 self.write_space();
4828 self.write_limit_expr(&offset.this)?;
4829 if offset.rows == Some(true) {
4831 self.write_space();
4832 self.write_keyword("ROWS");
4833 }
4834 }
4835 }
4836 }
4837
4838 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4840 if let Some(limit_by) = &select.limit_by {
4841 if !limit_by.is_empty() {
4842 self.write_space();
4843 self.write_keyword("BY");
4844 self.write_space();
4845 for (i, expr) in limit_by.iter().enumerate() {
4846 if i > 0 {
4847 self.write(", ");
4848 }
4849 self.generate_expression(expr)?;
4850 }
4851 }
4852 }
4853 }
4854
4855 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4857 if let Some(settings) = &select.settings {
4858 if self.config.pretty {
4859 self.write_newline();
4860 self.write_indent();
4861 } else {
4862 self.write_space();
4863 }
4864 self.write_keyword("SETTINGS");
4865 self.write_space();
4866 for (i, expr) in settings.iter().enumerate() {
4867 if i > 0 {
4868 self.write(", ");
4869 }
4870 self.generate_expression(expr)?;
4871 }
4872 }
4873
4874 if let Some(format_expr) = &select.format {
4875 if self.config.pretty {
4876 self.write_newline();
4877 self.write_indent();
4878 } else {
4879 self.write_space();
4880 }
4881 self.write_keyword("FORMAT");
4882 self.write_space();
4883 self.generate_expression(format_expr)?;
4884 }
4885 }
4886
4887 if let Some(fetch) = &select.fetch {
4889 let fetch_already_as_limit = select.offset.is_some()
4891 && !fetch.percent
4892 && !fetch.with_ties
4893 && fetch.count.is_some()
4894 && matches!(
4895 self.config.dialect,
4896 Some(DialectType::Spark)
4897 | Some(DialectType::Hive)
4898 | Some(DialectType::DuckDB)
4899 | Some(DialectType::SQLite)
4900 | Some(DialectType::MySQL)
4901 | Some(DialectType::BigQuery)
4902 | Some(DialectType::Databricks)
4903 | Some(DialectType::StarRocks)
4904 | Some(DialectType::Doris)
4905 | Some(DialectType::Athena)
4906 | Some(DialectType::ClickHouse)
4907 | Some(DialectType::Redshift)
4908 );
4909
4910 if fetch_already_as_limit {
4911 } else {
4913 if self.config.pretty {
4914 self.write_newline();
4915 self.write_indent();
4916 } else {
4917 self.write_space();
4918 }
4919
4920 let use_limit = !fetch.percent
4922 && !fetch.with_ties
4923 && fetch.count.is_some()
4924 && matches!(
4925 self.config.dialect,
4926 Some(DialectType::Spark)
4927 | Some(DialectType::Hive)
4928 | Some(DialectType::DuckDB)
4929 | Some(DialectType::SQLite)
4930 | Some(DialectType::MySQL)
4931 | Some(DialectType::BigQuery)
4932 | Some(DialectType::Databricks)
4933 | Some(DialectType::StarRocks)
4934 | Some(DialectType::Doris)
4935 | Some(DialectType::Athena)
4936 | Some(DialectType::ClickHouse)
4937 | Some(DialectType::Redshift)
4938 );
4939
4940 if use_limit {
4941 self.write_keyword("LIMIT");
4942 self.write_space();
4943 self.generate_expression(fetch.count.as_ref().unwrap())?;
4944 } else {
4945 self.write_keyword("FETCH");
4946 self.write_space();
4947 self.write_keyword(&fetch.direction);
4948 if let Some(ref count) = fetch.count {
4949 self.write_space();
4950 self.generate_expression(count)?;
4951 }
4952 if fetch.percent {
4953 self.write_space();
4954 self.write_keyword("PERCENT");
4955 }
4956 if fetch.rows {
4957 self.write_space();
4958 self.write_keyword("ROWS");
4959 }
4960 if fetch.with_ties {
4961 self.write_space();
4962 self.write_keyword("WITH TIES");
4963 } else {
4964 self.write_space();
4965 self.write_keyword("ONLY");
4966 }
4967 }
4968 } }
4970
4971 if let Some(sample) = &select.sample {
4973 use crate::dialects::DialectType;
4974 if self.config.pretty {
4975 self.write_newline();
4976 } else {
4977 self.write_space();
4978 }
4979
4980 if sample.is_using_sample {
4981 self.write_keyword("USING SAMPLE");
4983 self.generate_sample_body(sample)?;
4984 } else {
4985 self.write_keyword("TABLESAMPLE");
4986
4987 let snowflake_bernoulli =
4989 matches!(self.config.dialect, Some(DialectType::Snowflake))
4990 && !sample.explicit_method;
4991 if snowflake_bernoulli {
4992 self.write_space();
4993 self.write_keyword("BERNOULLI");
4994 }
4995
4996 if matches!(sample.method, SampleMethod::Bucket) {
4998 self.write_space();
4999 self.write("(");
5000 self.write_keyword("BUCKET");
5001 self.write_space();
5002 if let Some(ref num) = sample.bucket_numerator {
5003 self.generate_expression(num)?;
5004 }
5005 self.write_space();
5006 self.write_keyword("OUT OF");
5007 self.write_space();
5008 if let Some(ref denom) = sample.bucket_denominator {
5009 self.generate_expression(denom)?;
5010 }
5011 if let Some(ref field) = sample.bucket_field {
5012 self.write_space();
5013 self.write_keyword("ON");
5014 self.write_space();
5015 self.generate_expression(field)?;
5016 }
5017 self.write(")");
5018 } else if sample.unit_after_size {
5019 if sample.explicit_method && sample.method_before_size {
5021 self.write_space();
5022 match sample.method {
5023 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5024 SampleMethod::System => self.write_keyword("SYSTEM"),
5025 SampleMethod::Block => self.write_keyword("BLOCK"),
5026 SampleMethod::Row => self.write_keyword("ROW"),
5027 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5028 _ => {}
5029 }
5030 }
5031 self.write(" (");
5032 self.generate_expression(&sample.size)?;
5033 self.write_space();
5034 match sample.method {
5035 SampleMethod::Percent => self.write_keyword("PERCENT"),
5036 SampleMethod::Row => self.write_keyword("ROWS"),
5037 SampleMethod::Reservoir => self.write_keyword("ROWS"),
5038 _ => {
5039 self.write_keyword("PERCENT");
5040 }
5041 }
5042 self.write(")");
5043 } else {
5044 self.write_space();
5046 match sample.method {
5047 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5048 SampleMethod::System => self.write_keyword("SYSTEM"),
5049 SampleMethod::Block => self.write_keyword("BLOCK"),
5050 SampleMethod::Row => self.write_keyword("ROW"),
5051 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
5052 SampleMethod::Bucket => {}
5053 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5054 }
5055 self.write(" (");
5056 self.generate_expression(&sample.size)?;
5057 if matches!(sample.method, SampleMethod::Percent) {
5058 self.write_space();
5059 self.write_keyword("PERCENT");
5060 }
5061 self.write(")");
5062 }
5063 }
5064
5065 if let Some(seed) = &sample.seed {
5066 self.write_space();
5067 let use_seed = sample.use_seed_keyword
5069 && !matches!(
5070 self.config.dialect,
5071 Some(crate::dialects::DialectType::Databricks)
5072 | Some(crate::dialects::DialectType::Spark)
5073 );
5074 if use_seed {
5075 self.write_keyword("SEED");
5076 } else {
5077 self.write_keyword("REPEATABLE");
5078 }
5079 self.write(" (");
5080 self.generate_expression(seed)?;
5081 self.write(")");
5082 }
5083 }
5084
5085 if self.config.locking_reads_supported {
5088 for lock in &select.locks {
5089 if self.config.pretty {
5090 self.write_newline();
5091 self.write_indent();
5092 } else {
5093 self.write_space();
5094 }
5095 self.generate_lock(lock)?;
5096 }
5097 }
5098
5099 if !select.for_xml.is_empty() {
5101 if self.config.pretty {
5102 self.write_newline();
5103 self.write_indent();
5104 } else {
5105 self.write_space();
5106 }
5107 self.write_keyword("FOR XML");
5108 for (i, opt) in select.for_xml.iter().enumerate() {
5109 if self.config.pretty {
5110 if i > 0 {
5111 self.write(",");
5112 }
5113 self.write_newline();
5114 self.write_indent();
5115 self.write(" "); } else {
5117 if i > 0 {
5118 self.write(",");
5119 }
5120 self.write_space();
5121 }
5122 self.generate_for_xml_option(opt)?;
5123 }
5124 }
5125
5126 if !select.for_json.is_empty() {
5128 if self.config.pretty {
5129 self.write_newline();
5130 self.write_indent();
5131 } else {
5132 self.write_space();
5133 }
5134 self.write_keyword("FOR JSON");
5135 for (i, opt) in select.for_json.iter().enumerate() {
5136 if self.config.pretty {
5137 if i > 0 {
5138 self.write(",");
5139 }
5140 self.write_newline();
5141 self.write_indent();
5142 self.write(" "); } else {
5144 if i > 0 {
5145 self.write(",");
5146 }
5147 self.write_space();
5148 }
5149 self.generate_for_xml_option(opt)?;
5150 }
5151 }
5152
5153 if let Some(ref option) = select.option {
5155 if matches!(
5156 self.config.dialect,
5157 Some(crate::dialects::DialectType::TSQL)
5158 | Some(crate::dialects::DialectType::Fabric)
5159 ) {
5160 self.write_space();
5161 self.write(option);
5162 }
5163 }
5164
5165 Ok(())
5166 }
5167
5168 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
5170 match opt {
5171 Expression::QueryOption(qo) => {
5172 if let Expression::Var(var) = &*qo.this {
5174 self.write(&var.this);
5175 } else {
5176 self.generate_expression(&qo.this)?;
5177 }
5178 if let Some(expr) = &qo.expression {
5180 self.write("(");
5181 self.generate_expression(expr)?;
5182 self.write(")");
5183 }
5184 }
5185 _ => {
5186 self.generate_expression(opt)?;
5187 }
5188 }
5189 Ok(())
5190 }
5191
5192 fn generate_with(&mut self, with: &With) -> Result<()> {
5193 use crate::dialects::DialectType;
5194
5195 for comment in &with.leading_comments {
5197 self.write_formatted_comment(comment);
5198 self.write(" ");
5199 }
5200 self.write_keyword("WITH");
5201 if with.recursive && self.config.cte_recursive_keyword_required {
5202 self.write_space();
5203 self.write_keyword("RECURSIVE");
5204 }
5205 self.write_space();
5206
5207 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
5209
5210 for (i, cte) in with.ctes.iter().enumerate() {
5211 if i > 0 {
5212 self.write(",");
5213 if self.config.pretty {
5214 self.write_space();
5215 } else {
5216 self.write(" ");
5217 }
5218 }
5219 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
5220 self.generate_expression(&cte.this)?;
5221 self.write_space();
5222 self.write_keyword("AS");
5223 self.write_space();
5224 self.generate_identifier(&cte.alias)?;
5225 continue;
5226 }
5227 self.generate_identifier(&cte.alias)?;
5228 for comment in &cte.comments {
5230 self.write_space();
5231 self.write_formatted_comment(comment);
5232 }
5233 if !cte.columns.is_empty() && !skip_cte_columns {
5234 self.write("(");
5235 for (j, col) in cte.columns.iter().enumerate() {
5236 if j > 0 {
5237 self.write(", ");
5238 }
5239 self.generate_identifier(col)?;
5240 }
5241 self.write(")");
5242 }
5243 if !cte.key_expressions.is_empty() {
5245 self.write_space();
5246 self.write_keyword("USING KEY");
5247 self.write(" (");
5248 for (i, key) in cte.key_expressions.iter().enumerate() {
5249 if i > 0 {
5250 self.write(", ");
5251 }
5252 self.generate_identifier(key)?;
5253 }
5254 self.write(")");
5255 }
5256 self.write_space();
5257 self.write_keyword("AS");
5258 if let Some(materialized) = cte.materialized {
5260 self.write_space();
5261 if materialized {
5262 self.write_keyword("MATERIALIZED");
5263 } else {
5264 self.write_keyword("NOT MATERIALIZED");
5265 }
5266 }
5267 self.write(" (");
5268 if self.config.pretty {
5269 self.write_newline();
5270 self.indent_level += 1;
5271 self.write_indent();
5272 }
5273 let wrap_values_in_select = matches!(
5276 self.config.dialect,
5277 Some(DialectType::Spark) | Some(DialectType::Databricks)
5278 ) && matches!(&cte.this, Expression::Values(_));
5279
5280 if wrap_values_in_select {
5281 self.write_keyword("SELECT");
5282 self.write(" * ");
5283 self.write_keyword("FROM");
5284 self.write_space();
5285 }
5286 self.generate_expression(&cte.this)?;
5287 if self.config.pretty {
5288 self.write_newline();
5289 self.indent_level -= 1;
5290 self.write_indent();
5291 }
5292 self.write(")");
5293 }
5294
5295 if let Some(search) = &with.search {
5297 self.write_space();
5298 self.generate_expression(search)?;
5299 }
5300
5301 Ok(())
5302 }
5303
5304 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
5308 let mut i = 0;
5309 while i < joins.len() {
5310 if joins[i].deferred_condition {
5311 let parent_group = joins[i].nesting_group;
5312
5313 self.generate_join_without_condition(&joins[i])?;
5316
5317 let child_start = i + 1;
5319 let mut child_end = child_start;
5320 while child_end < joins.len()
5321 && !joins[child_end].deferred_condition
5322 && joins[child_end].nesting_group == parent_group
5323 {
5324 child_end += 1;
5325 }
5326
5327 if child_start < child_end {
5329 self.indent_level += 1;
5330 for j in child_start..child_end {
5331 self.generate_join(&joins[j])?;
5332 }
5333 self.indent_level -= 1;
5334 }
5335
5336 self.generate_join_condition(&joins[i])?;
5338
5339 i = child_end;
5340 } else {
5341 self.generate_join(&joins[i])?;
5343 i += 1;
5344 }
5345 }
5346 Ok(())
5347 }
5348
5349 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5352 let mut join_copy = join.clone();
5355 join_copy.on = None;
5356 join_copy.using = Vec::new();
5357 join_copy.deferred_condition = false;
5358 self.generate_join(&join_copy)
5359 }
5360
5361 fn generate_join(&mut self, join: &Join) -> Result<()> {
5362 if join.kind == JoinKind::Implicit {
5364 self.write(",");
5365 if self.config.pretty {
5366 self.write_newline();
5367 self.write_indent();
5368 } else {
5369 self.write_space();
5370 }
5371 self.generate_expression(&join.this)?;
5372 return Ok(());
5373 }
5374
5375 if self.config.pretty {
5376 self.write_newline();
5377 self.write_indent();
5378 } else {
5379 self.write_space();
5380 }
5381
5382 let hint_str = if self.config.join_hints {
5385 join.join_hint
5386 .as_ref()
5387 .map(|h| format!(" {}", h))
5388 .unwrap_or_default()
5389 } else {
5390 String::new()
5391 };
5392
5393 let clickhouse_join_keyword =
5394 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5395 if let Some(hint) = &join.join_hint {
5396 let mut global = false;
5397 let mut strictness: Option<&'static str> = None;
5398 for part in hint.split_whitespace() {
5399 if part.eq_ignore_ascii_case("GLOBAL") {
5400 global = true;
5401 } else if part.eq_ignore_ascii_case("ALL") {
5402 strictness = Some("ALL");
5403 } else if part.eq_ignore_ascii_case("ANY") {
5404 strictness = Some("ANY");
5405 } else if part.eq_ignore_ascii_case("ASOF") {
5406 strictness = Some("ASOF");
5407 } else if part.eq_ignore_ascii_case("SEMI") {
5408 strictness = Some("SEMI");
5409 } else if part.eq_ignore_ascii_case("ANTI") {
5410 strictness = Some("ANTI");
5411 }
5412 }
5413
5414 if global || strictness.is_some() {
5415 let join_type = match join.kind {
5416 JoinKind::Left => {
5417 if join.use_outer_keyword {
5418 "LEFT OUTER"
5419 } else if join.use_inner_keyword {
5420 "LEFT INNER"
5421 } else {
5422 "LEFT"
5423 }
5424 }
5425 JoinKind::Right => {
5426 if join.use_outer_keyword {
5427 "RIGHT OUTER"
5428 } else if join.use_inner_keyword {
5429 "RIGHT INNER"
5430 } else {
5431 "RIGHT"
5432 }
5433 }
5434 JoinKind::Full => {
5435 if join.use_outer_keyword {
5436 "FULL OUTER"
5437 } else {
5438 "FULL"
5439 }
5440 }
5441 JoinKind::Inner => {
5442 if join.use_inner_keyword {
5443 "INNER"
5444 } else {
5445 ""
5446 }
5447 }
5448 _ => "",
5449 };
5450
5451 let mut parts = Vec::new();
5452 if global {
5453 parts.push("GLOBAL");
5454 }
5455 if !join_type.is_empty() {
5456 parts.push(join_type);
5457 }
5458 if let Some(strict) = strictness {
5459 parts.push(strict);
5460 }
5461 parts.push("JOIN");
5462 Some(parts.join(" "))
5463 } else {
5464 None
5465 }
5466 } else {
5467 None
5468 }
5469 } else {
5470 None
5471 };
5472
5473 if !join.comments.is_empty() {
5477 if self.config.pretty {
5478 let trimmed = self.output.trim_end().len();
5483 self.output.truncate(trimmed);
5484 for comment in &join.comments {
5485 self.write_newline();
5486 self.write_indent();
5487 self.write_formatted_comment(comment);
5488 }
5489 self.write_newline();
5490 self.write_indent();
5491 } else {
5492 for comment in &join.comments {
5493 self.write_formatted_comment(comment);
5494 self.write_space();
5495 }
5496 }
5497 }
5498
5499 let directed_str = if join.directed { " DIRECTED" } else { "" };
5500
5501 if let Some(keyword) = clickhouse_join_keyword {
5502 self.write_keyword(&keyword);
5503 } else {
5504 match join.kind {
5505 JoinKind::Inner => {
5506 if join.use_inner_keyword {
5507 if hint_str.is_empty() && directed_str.is_empty() {
5508 self.write_keyword("INNER JOIN");
5509 } else {
5510 self.write_keyword("INNER");
5511 if !hint_str.is_empty() {
5512 self.write_keyword(&hint_str);
5513 }
5514 if !directed_str.is_empty() {
5515 self.write_keyword(directed_str);
5516 }
5517 self.write_keyword(" JOIN");
5518 }
5519 } else {
5520 if !hint_str.is_empty() {
5521 self.write_keyword(hint_str.trim());
5522 self.write_keyword(" ");
5523 }
5524 if !directed_str.is_empty() {
5525 self.write_keyword("DIRECTED ");
5526 }
5527 self.write_keyword("JOIN");
5528 }
5529 }
5530 JoinKind::Left => {
5531 if join.use_outer_keyword {
5532 if hint_str.is_empty() && directed_str.is_empty() {
5533 self.write_keyword("LEFT OUTER JOIN");
5534 } else {
5535 self.write_keyword("LEFT OUTER");
5536 if !hint_str.is_empty() {
5537 self.write_keyword(&hint_str);
5538 }
5539 if !directed_str.is_empty() {
5540 self.write_keyword(directed_str);
5541 }
5542 self.write_keyword(" JOIN");
5543 }
5544 } else if join.use_inner_keyword {
5545 if hint_str.is_empty() && directed_str.is_empty() {
5546 self.write_keyword("LEFT INNER JOIN");
5547 } else {
5548 self.write_keyword("LEFT INNER");
5549 if !hint_str.is_empty() {
5550 self.write_keyword(&hint_str);
5551 }
5552 if !directed_str.is_empty() {
5553 self.write_keyword(directed_str);
5554 }
5555 self.write_keyword(" JOIN");
5556 }
5557 } else {
5558 if hint_str.is_empty() && directed_str.is_empty() {
5559 self.write_keyword("LEFT JOIN");
5560 } else {
5561 self.write_keyword("LEFT");
5562 if !hint_str.is_empty() {
5563 self.write_keyword(&hint_str);
5564 }
5565 if !directed_str.is_empty() {
5566 self.write_keyword(directed_str);
5567 }
5568 self.write_keyword(" JOIN");
5569 }
5570 }
5571 }
5572 JoinKind::Right => {
5573 if join.use_outer_keyword {
5574 if hint_str.is_empty() && directed_str.is_empty() {
5575 self.write_keyword("RIGHT OUTER JOIN");
5576 } else {
5577 self.write_keyword("RIGHT OUTER");
5578 if !hint_str.is_empty() {
5579 self.write_keyword(&hint_str);
5580 }
5581 if !directed_str.is_empty() {
5582 self.write_keyword(directed_str);
5583 }
5584 self.write_keyword(" JOIN");
5585 }
5586 } else if join.use_inner_keyword {
5587 if hint_str.is_empty() && directed_str.is_empty() {
5588 self.write_keyword("RIGHT INNER JOIN");
5589 } else {
5590 self.write_keyword("RIGHT INNER");
5591 if !hint_str.is_empty() {
5592 self.write_keyword(&hint_str);
5593 }
5594 if !directed_str.is_empty() {
5595 self.write_keyword(directed_str);
5596 }
5597 self.write_keyword(" JOIN");
5598 }
5599 } else {
5600 if hint_str.is_empty() && directed_str.is_empty() {
5601 self.write_keyword("RIGHT JOIN");
5602 } else {
5603 self.write_keyword("RIGHT");
5604 if !hint_str.is_empty() {
5605 self.write_keyword(&hint_str);
5606 }
5607 if !directed_str.is_empty() {
5608 self.write_keyword(directed_str);
5609 }
5610 self.write_keyword(" JOIN");
5611 }
5612 }
5613 }
5614 JoinKind::Full => {
5615 if join.use_outer_keyword {
5616 if hint_str.is_empty() && directed_str.is_empty() {
5617 self.write_keyword("FULL OUTER JOIN");
5618 } else {
5619 self.write_keyword("FULL OUTER");
5620 if !hint_str.is_empty() {
5621 self.write_keyword(&hint_str);
5622 }
5623 if !directed_str.is_empty() {
5624 self.write_keyword(directed_str);
5625 }
5626 self.write_keyword(" JOIN");
5627 }
5628 } else {
5629 if hint_str.is_empty() && directed_str.is_empty() {
5630 self.write_keyword("FULL JOIN");
5631 } else {
5632 self.write_keyword("FULL");
5633 if !hint_str.is_empty() {
5634 self.write_keyword(&hint_str);
5635 }
5636 if !directed_str.is_empty() {
5637 self.write_keyword(directed_str);
5638 }
5639 self.write_keyword(" JOIN");
5640 }
5641 }
5642 }
5643 JoinKind::Outer => {
5644 if directed_str.is_empty() {
5645 self.write_keyword("OUTER JOIN");
5646 } else {
5647 self.write_keyword("OUTER");
5648 self.write_keyword(directed_str);
5649 self.write_keyword(" JOIN");
5650 }
5651 }
5652 JoinKind::Cross => {
5653 if directed_str.is_empty() {
5654 self.write_keyword("CROSS JOIN");
5655 } else {
5656 self.write_keyword("CROSS");
5657 self.write_keyword(directed_str);
5658 self.write_keyword(" JOIN");
5659 }
5660 }
5661 JoinKind::Natural => {
5662 if join.use_inner_keyword {
5663 if directed_str.is_empty() {
5664 self.write_keyword("NATURAL INNER JOIN");
5665 } else {
5666 self.write_keyword("NATURAL INNER");
5667 self.write_keyword(directed_str);
5668 self.write_keyword(" JOIN");
5669 }
5670 } else {
5671 if directed_str.is_empty() {
5672 self.write_keyword("NATURAL JOIN");
5673 } else {
5674 self.write_keyword("NATURAL");
5675 self.write_keyword(directed_str);
5676 self.write_keyword(" JOIN");
5677 }
5678 }
5679 }
5680 JoinKind::NaturalLeft => {
5681 if join.use_outer_keyword {
5682 if directed_str.is_empty() {
5683 self.write_keyword("NATURAL LEFT OUTER JOIN");
5684 } else {
5685 self.write_keyword("NATURAL LEFT OUTER");
5686 self.write_keyword(directed_str);
5687 self.write_keyword(" JOIN");
5688 }
5689 } else {
5690 if directed_str.is_empty() {
5691 self.write_keyword("NATURAL LEFT JOIN");
5692 } else {
5693 self.write_keyword("NATURAL LEFT");
5694 self.write_keyword(directed_str);
5695 self.write_keyword(" JOIN");
5696 }
5697 }
5698 }
5699 JoinKind::NaturalRight => {
5700 if join.use_outer_keyword {
5701 if directed_str.is_empty() {
5702 self.write_keyword("NATURAL RIGHT OUTER JOIN");
5703 } else {
5704 self.write_keyword("NATURAL RIGHT OUTER");
5705 self.write_keyword(directed_str);
5706 self.write_keyword(" JOIN");
5707 }
5708 } else {
5709 if directed_str.is_empty() {
5710 self.write_keyword("NATURAL RIGHT JOIN");
5711 } else {
5712 self.write_keyword("NATURAL RIGHT");
5713 self.write_keyword(directed_str);
5714 self.write_keyword(" JOIN");
5715 }
5716 }
5717 }
5718 JoinKind::NaturalFull => {
5719 if join.use_outer_keyword {
5720 if directed_str.is_empty() {
5721 self.write_keyword("NATURAL FULL OUTER JOIN");
5722 } else {
5723 self.write_keyword("NATURAL FULL OUTER");
5724 self.write_keyword(directed_str);
5725 self.write_keyword(" JOIN");
5726 }
5727 } else {
5728 if directed_str.is_empty() {
5729 self.write_keyword("NATURAL FULL JOIN");
5730 } else {
5731 self.write_keyword("NATURAL FULL");
5732 self.write_keyword(directed_str);
5733 self.write_keyword(" JOIN");
5734 }
5735 }
5736 }
5737 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
5738 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
5739 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
5740 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
5741 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
5742 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
5743 JoinKind::CrossApply => {
5744 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5746 self.write_keyword("CROSS APPLY");
5747 } else {
5748 self.write_keyword("INNER JOIN LATERAL");
5749 }
5750 }
5751 JoinKind::OuterApply => {
5752 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5754 self.write_keyword("OUTER APPLY");
5755 } else {
5756 self.write_keyword("LEFT JOIN LATERAL");
5757 }
5758 }
5759 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
5760 JoinKind::AsOfLeft => {
5761 if join.use_outer_keyword {
5762 self.write_keyword("ASOF LEFT OUTER JOIN");
5763 } else {
5764 self.write_keyword("ASOF LEFT JOIN");
5765 }
5766 }
5767 JoinKind::AsOfRight => {
5768 if join.use_outer_keyword {
5769 self.write_keyword("ASOF RIGHT OUTER JOIN");
5770 } else {
5771 self.write_keyword("ASOF RIGHT JOIN");
5772 }
5773 }
5774 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
5775 JoinKind::LeftLateral => {
5776 if join.use_outer_keyword {
5777 self.write_keyword("LEFT OUTER LATERAL JOIN");
5778 } else {
5779 self.write_keyword("LEFT LATERAL JOIN");
5780 }
5781 }
5782 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
5783 JoinKind::Implicit => {
5784 use crate::dialects::DialectType;
5788 let is_cj_dialect = matches!(
5789 self.config.dialect,
5790 Some(DialectType::BigQuery)
5791 | Some(DialectType::Hive)
5792 | Some(DialectType::Spark)
5793 | Some(DialectType::Databricks)
5794 );
5795 let source_is_same = self.config.source_dialect.is_some()
5796 && self.config.source_dialect == self.config.dialect;
5797 let source_is_cj = matches!(
5798 self.config.source_dialect,
5799 Some(DialectType::BigQuery)
5800 | Some(DialectType::Hive)
5801 | Some(DialectType::Spark)
5802 | Some(DialectType::Databricks)
5803 );
5804 if is_cj_dialect
5805 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
5806 {
5807 self.write_keyword("CROSS JOIN");
5808 } else {
5809 self.output.truncate(self.output.trim_end().len());
5813 self.write(",");
5814 }
5815 }
5816 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
5817 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
5818 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
5819 JoinKind::Positional => self.write_keyword("POSITIONAL JOIN"),
5820 }
5821 }
5822
5823 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
5825 match &join.this {
5826 Expression::Tuple(t) if t.expressions.is_empty() => {}
5827 Expression::Tuple(t) => {
5828 self.write_space();
5829 for (i, item) in t.expressions.iter().enumerate() {
5830 if i > 0 {
5831 self.write(", ");
5832 }
5833 self.generate_expression(item)?;
5834 }
5835 }
5836 other => {
5837 self.write_space();
5838 self.generate_expression(other)?;
5839 }
5840 }
5841 } else {
5842 self.write_space();
5843 self.generate_expression(&join.this)?;
5844 }
5845
5846 if !join.deferred_condition {
5848 if let Some(match_cond) = &join.match_condition {
5850 self.write_space();
5851 self.write_keyword("MATCH_CONDITION");
5852 self.write(" (");
5853 self.generate_expression(match_cond)?;
5854 self.write(")");
5855 }
5856
5857 if let Some(on) = &join.on {
5858 if self.config.pretty {
5859 self.write_newline();
5860 self.indent_level += 1;
5861 self.write_indent();
5862 self.write_keyword("ON");
5863 self.write_space();
5864 self.generate_join_on_condition(on)?;
5865 self.indent_level -= 1;
5866 } else {
5867 self.write_space();
5868 self.write_keyword("ON");
5869 self.write_space();
5870 self.generate_expression(on)?;
5871 }
5872 }
5873
5874 if !join.using.is_empty() {
5875 if self.config.pretty {
5876 self.write_newline();
5877 self.indent_level += 1;
5878 self.write_indent();
5879 self.write_keyword("USING");
5880 self.write(" (");
5881 for (i, col) in join.using.iter().enumerate() {
5882 if i > 0 {
5883 self.write(", ");
5884 }
5885 self.generate_identifier(col)?;
5886 }
5887 self.write(")");
5888 self.indent_level -= 1;
5889 } else {
5890 self.write_space();
5891 self.write_keyword("USING");
5892 self.write(" (");
5893 for (i, col) in join.using.iter().enumerate() {
5894 if i > 0 {
5895 self.write(", ");
5896 }
5897 self.generate_identifier(col)?;
5898 }
5899 self.write(")");
5900 }
5901 }
5902 }
5903
5904 for pivot in &join.pivots {
5906 self.write_space();
5907 self.generate_expression(pivot)?;
5908 }
5909
5910 Ok(())
5911 }
5912
5913 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
5915 if let Some(match_cond) = &join.match_condition {
5917 self.write_space();
5918 self.write_keyword("MATCH_CONDITION");
5919 self.write(" (");
5920 self.generate_expression(match_cond)?;
5921 self.write(")");
5922 }
5923
5924 if let Some(on) = &join.on {
5925 if self.config.pretty {
5926 self.write_newline();
5927 self.indent_level += 1;
5928 self.write_indent();
5929 self.write_keyword("ON");
5930 self.write_space();
5931 self.generate_join_on_condition(on)?;
5933 self.indent_level -= 1;
5934 } else {
5935 self.write_space();
5936 self.write_keyword("ON");
5937 self.write_space();
5938 self.generate_expression(on)?;
5939 }
5940 }
5941
5942 if !join.using.is_empty() {
5943 if self.config.pretty {
5944 self.write_newline();
5945 self.indent_level += 1;
5946 self.write_indent();
5947 self.write_keyword("USING");
5948 self.write(" (");
5949 for (i, col) in join.using.iter().enumerate() {
5950 if i > 0 {
5951 self.write(", ");
5952 }
5953 self.generate_identifier(col)?;
5954 }
5955 self.write(")");
5956 self.indent_level -= 1;
5957 } else {
5958 self.write_space();
5959 self.write_keyword("USING");
5960 self.write(" (");
5961 for (i, col) in join.using.iter().enumerate() {
5962 if i > 0 {
5963 self.write(", ");
5964 }
5965 self.generate_identifier(col)?;
5966 }
5967 self.write(")");
5968 }
5969 }
5970
5971 for pivot in &join.pivots {
5973 self.write_space();
5974 self.generate_expression(pivot)?;
5975 }
5976
5977 Ok(())
5978 }
5979
5980 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
5982 if let Expression::And(and_op) = expr {
5983 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
5984 self.generate_expression(conditions[0])?;
5985 for condition in conditions.iter().skip(1) {
5986 self.write_newline();
5987 self.write_indent();
5988 self.write_keyword("AND");
5989 self.write_space();
5990 self.generate_expression(condition)?;
5991 }
5992 return Ok(());
5993 }
5994 }
5995
5996 self.generate_expression(expr)
5997 }
5998
5999 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
6000 self.write("(");
6002 self.generate_expression(&jt.left)?;
6003
6004 for join in &jt.joins {
6006 self.generate_join(join)?;
6007 }
6008
6009 for (lv_idx, lv) in jt.lateral_views.iter().enumerate() {
6011 self.generate_lateral_view(lv, lv_idx)?;
6012 }
6013
6014 self.write(")");
6015
6016 if let Some(alias) = &jt.alias {
6018 self.write_space();
6019 self.write_keyword("AS");
6020 self.write_space();
6021 self.generate_identifier(alias)?;
6022 }
6023
6024 Ok(())
6025 }
6026
6027 fn generate_lateral_view(&mut self, lv: &LateralView, lv_index: usize) -> Result<()> {
6028 use crate::dialects::DialectType;
6029
6030 if self.config.pretty {
6031 self.write_newline();
6032 self.write_indent();
6033 } else {
6034 self.write_space();
6035 }
6036
6037 let use_lateral_join = matches!(
6040 self.config.dialect,
6041 Some(DialectType::PostgreSQL)
6042 | Some(DialectType::DuckDB)
6043 | Some(DialectType::Snowflake)
6044 | Some(DialectType::TSQL)
6045 | Some(DialectType::Presto)
6046 | Some(DialectType::Trino)
6047 | Some(DialectType::Athena)
6048 );
6049
6050 let use_unnest = matches!(
6052 self.config.dialect,
6053 Some(DialectType::DuckDB)
6054 | Some(DialectType::Presto)
6055 | Some(DialectType::Trino)
6056 | Some(DialectType::Athena)
6057 );
6058
6059 let (is_posexplode, is_inline, func_args) = match &lv.this {
6061 Expression::Explode(uf) => {
6062 (false, false, vec![uf.this.clone()])
6064 }
6065 Expression::Unnest(uf) => {
6066 let mut args = vec![uf.this.clone()];
6067 args.extend(uf.expressions.clone());
6068 (false, false, args)
6069 }
6070 Expression::Function(func) => {
6071 if func.name.eq_ignore_ascii_case("POSEXPLODE")
6072 || func.name.eq_ignore_ascii_case("POSEXPLODE_OUTER")
6073 {
6074 (true, false, func.args.clone())
6075 } else if func.name.eq_ignore_ascii_case("INLINE") {
6076 (false, true, func.args.clone())
6077 } else if func.name.eq_ignore_ascii_case("EXPLODE")
6078 || func.name.eq_ignore_ascii_case("EXPLODE_OUTER")
6079 {
6080 (false, false, func.args.clone())
6081 } else {
6082 (false, false, vec![])
6083 }
6084 }
6085 _ => (false, false, vec![]),
6086 };
6087
6088 if use_lateral_join {
6089 if lv.outer {
6091 self.write_keyword("LEFT JOIN LATERAL");
6092 } else {
6093 self.write_keyword("CROSS JOIN");
6094 }
6095 self.write_space();
6096
6097 if use_unnest && !func_args.is_empty() {
6098 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6101 func_args
6103 .iter()
6104 .map(|a| {
6105 if let Expression::Function(ref f) = a {
6106 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() == 1 {
6107 return Expression::ArrayFunc(Box::new(
6108 crate::expressions::ArrayConstructor {
6109 expressions: f.args.clone(),
6110 bracket_notation: true,
6111 use_list_keyword: false,
6112 },
6113 ));
6114 }
6115 }
6116 a.clone()
6117 })
6118 .collect::<Vec<_>>()
6119 } else if matches!(
6120 self.config.dialect,
6121 Some(DialectType::Presto)
6122 | Some(DialectType::Trino)
6123 | Some(DialectType::Athena)
6124 ) {
6125 func_args
6127 .iter()
6128 .map(|a| {
6129 if let Expression::Function(ref f) = a {
6130 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() >= 1 {
6131 return Expression::ArrayFunc(Box::new(
6132 crate::expressions::ArrayConstructor {
6133 expressions: f.args.clone(),
6134 bracket_notation: true,
6135 use_list_keyword: false,
6136 },
6137 ));
6138 }
6139 }
6140 a.clone()
6141 })
6142 .collect::<Vec<_>>()
6143 } else {
6144 func_args
6145 };
6146
6147 if is_posexplode {
6149 self.write_keyword("LATERAL");
6150 self.write(" (");
6151 self.write_keyword("SELECT");
6152 self.write_space();
6153
6154 let pos_alias = if !lv.column_aliases.is_empty() {
6157 lv.column_aliases[0].clone()
6158 } else {
6159 Identifier::new("pos")
6160 };
6161 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
6162 lv.column_aliases[1..].to_vec()
6163 } else {
6164 vec![Identifier::new("col")]
6165 };
6166
6167 self.generate_identifier(&pos_alias)?;
6169 self.write(" - 1");
6170 self.write_space();
6171 self.write_keyword("AS");
6172 self.write_space();
6173 self.generate_identifier(&pos_alias)?;
6174
6175 for data_col in &data_aliases {
6177 self.write(", ");
6178 self.generate_identifier(data_col)?;
6179 }
6180
6181 self.write_space();
6182 self.write_keyword("FROM");
6183 self.write_space();
6184 self.write_keyword("UNNEST");
6185 self.write("(");
6186 for (i, arg) in unnest_args.iter().enumerate() {
6187 if i > 0 {
6188 self.write(", ");
6189 }
6190 self.generate_expression(arg)?;
6191 }
6192 self.write(")");
6193 self.write_space();
6194 self.write_keyword("WITH ORDINALITY");
6195 self.write_space();
6196 self.write_keyword("AS");
6197 self.write_space();
6198
6199 let table_alias_ident = lv
6201 .table_alias
6202 .clone()
6203 .unwrap_or_else(|| Identifier::new("t"));
6204 self.generate_identifier(&table_alias_ident)?;
6205 self.write("(");
6206 for (i, data_col) in data_aliases.iter().enumerate() {
6207 if i > 0 {
6208 self.write(", ");
6209 }
6210 self.generate_identifier(data_col)?;
6211 }
6212 self.write(", ");
6213 self.generate_identifier(&pos_alias)?;
6214 self.write("))");
6215 } else if is_inline && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6216 self.write_keyword("LATERAL");
6218 self.write(" (");
6219 self.write_keyword("SELECT");
6220 self.write_space();
6221 self.write_keyword("UNNEST");
6222 self.write("(");
6223 for (i, arg) in unnest_args.iter().enumerate() {
6224 if i > 0 {
6225 self.write(", ");
6226 }
6227 self.generate_expression(arg)?;
6228 }
6229 self.write(", ");
6230 self.write_keyword("max_depth");
6231 self.write(" => 2))");
6232
6233 if let Some(alias) = &lv.table_alias {
6235 self.write_space();
6236 self.write_keyword("AS");
6237 self.write_space();
6238 self.generate_identifier(alias)?;
6239 if !lv.column_aliases.is_empty() {
6240 self.write("(");
6241 for (i, col) in lv.column_aliases.iter().enumerate() {
6242 if i > 0 {
6243 self.write(", ");
6244 }
6245 self.generate_identifier(col)?;
6246 }
6247 self.write(")");
6248 }
6249 } else if !lv.column_aliases.is_empty() {
6250 self.write_space();
6252 self.write_keyword("AS");
6253 self.write_space();
6254 self.write(&format!("_u_{}", lv_index));
6255 self.write("(");
6256 for (i, col) in lv.column_aliases.iter().enumerate() {
6257 if i > 0 {
6258 self.write(", ");
6259 }
6260 self.generate_identifier(col)?;
6261 }
6262 self.write(")");
6263 }
6264 } else {
6265 self.write_keyword("UNNEST");
6266 self.write("(");
6267 for (i, arg) in unnest_args.iter().enumerate() {
6268 if i > 0 {
6269 self.write(", ");
6270 }
6271 self.generate_expression(arg)?;
6272 }
6273 self.write(")");
6274
6275 if let Some(alias) = &lv.table_alias {
6277 self.write_space();
6278 self.write_keyword("AS");
6279 self.write_space();
6280 self.generate_identifier(alias)?;
6281 if !lv.column_aliases.is_empty() {
6282 self.write("(");
6283 for (i, col) in lv.column_aliases.iter().enumerate() {
6284 if i > 0 {
6285 self.write(", ");
6286 }
6287 self.generate_identifier(col)?;
6288 }
6289 self.write(")");
6290 }
6291 } else if !lv.column_aliases.is_empty() {
6292 self.write_space();
6293 self.write_keyword("AS");
6294 self.write(" t(");
6295 for (i, col) in lv.column_aliases.iter().enumerate() {
6296 if i > 0 {
6297 self.write(", ");
6298 }
6299 self.generate_identifier(col)?;
6300 }
6301 self.write(")");
6302 }
6303 }
6304 } else {
6305 if !lv.outer {
6307 self.write_keyword("LATERAL");
6308 self.write_space();
6309 }
6310 self.generate_expression(&lv.this)?;
6311
6312 if let Some(alias) = &lv.table_alias {
6314 self.write_space();
6315 self.write_keyword("AS");
6316 self.write_space();
6317 self.generate_identifier(alias)?;
6318 if !lv.column_aliases.is_empty() {
6319 self.write("(");
6320 for (i, col) in lv.column_aliases.iter().enumerate() {
6321 if i > 0 {
6322 self.write(", ");
6323 }
6324 self.generate_identifier(col)?;
6325 }
6326 self.write(")");
6327 }
6328 } else if !lv.column_aliases.is_empty() {
6329 self.write_space();
6330 self.write_keyword("AS");
6331 self.write(" t(");
6332 for (i, col) in lv.column_aliases.iter().enumerate() {
6333 if i > 0 {
6334 self.write(", ");
6335 }
6336 self.generate_identifier(col)?;
6337 }
6338 self.write(")");
6339 }
6340 }
6341
6342 if lv.outer {
6344 self.write_space();
6345 self.write_keyword("ON TRUE");
6346 }
6347 } else {
6348 self.write_keyword("LATERAL VIEW");
6350 if lv.outer {
6351 self.write_space();
6352 self.write_keyword("OUTER");
6353 }
6354 if self.config.pretty {
6355 self.write_newline();
6356 self.write_indent();
6357 } else {
6358 self.write_space();
6359 }
6360 self.generate_expression(&lv.this)?;
6361
6362 if let Some(alias) = &lv.table_alias {
6364 self.write_space();
6365 self.generate_identifier(alias)?;
6366 }
6367
6368 if !lv.column_aliases.is_empty() {
6370 self.write_space();
6371 self.write_keyword("AS");
6372 self.write_space();
6373 for (i, col) in lv.column_aliases.iter().enumerate() {
6374 if i > 0 {
6375 self.write(", ");
6376 }
6377 self.generate_identifier(col)?;
6378 }
6379 }
6380 }
6381
6382 Ok(())
6383 }
6384
6385 fn generate_union(&mut self, outermost: &Union) -> Result<()> {
6386 let mut chain: Vec<&Union> = vec![outermost];
6391 let mut leftmost: &Expression = &outermost.left;
6392 while let Expression::Union(inner) = leftmost {
6393 chain.push(inner);
6394 leftmost = &inner.left;
6395 }
6396 if let Some(with) = &outermost.with {
6401 self.generate_with(with)?;
6402 self.write_space();
6403 }
6404
6405 self.generate_expression(leftmost)?;
6407
6408 for union in chain.iter().rev() {
6410 self.generate_union_step(union)?;
6411 }
6412 Ok(())
6413 }
6414
6415 fn generate_union_step(&mut self, union: &Union) -> Result<()> {
6417 if self.config.pretty {
6418 self.write_newline();
6419 self.write_indent();
6420 } else {
6421 self.write_space();
6422 }
6423
6424 if let Some(side) = &union.side {
6426 self.write_keyword(side);
6427 self.write_space();
6428 }
6429 if let Some(kind) = &union.kind {
6430 self.write_keyword(kind);
6431 self.write_space();
6432 }
6433
6434 self.write_keyword("UNION");
6435 if union.all {
6436 self.write_space();
6437 self.write_keyword("ALL");
6438 } else if union.distinct {
6439 self.write_space();
6440 self.write_keyword("DISTINCT");
6441 }
6442
6443 if union.corresponding || union.by_name {
6446 self.write_space();
6447 self.write_keyword("BY NAME");
6448 }
6449 if !union.on_columns.is_empty() {
6450 self.write_space();
6451 self.write_keyword("ON");
6452 self.write(" (");
6453 for (i, col) in union.on_columns.iter().enumerate() {
6454 if i > 0 {
6455 self.write(", ");
6456 }
6457 self.generate_expression(col)?;
6458 }
6459 self.write(")");
6460 }
6461
6462 if self.config.pretty {
6463 self.write_newline();
6464 self.write_indent();
6465 } else {
6466 self.write_space();
6467 }
6468 self.generate_expression(&union.right)?;
6469 if let Some(order_by) = &union.order_by {
6471 if self.config.pretty {
6472 self.write_newline();
6473 } else {
6474 self.write_space();
6475 }
6476 self.write_keyword("ORDER BY");
6477 self.write_space();
6478 for (i, ordered) in order_by.expressions.iter().enumerate() {
6479 if i > 0 {
6480 self.write(", ");
6481 }
6482 self.generate_ordered(ordered)?;
6483 }
6484 }
6485 if let Some(limit) = &union.limit {
6486 if self.config.pretty {
6487 self.write_newline();
6488 } else {
6489 self.write_space();
6490 }
6491 self.write_keyword("LIMIT");
6492 self.write_space();
6493 self.generate_expression(limit)?;
6494 }
6495 if let Some(offset) = &union.offset {
6496 if self.config.pretty {
6497 self.write_newline();
6498 } else {
6499 self.write_space();
6500 }
6501 self.write_keyword("OFFSET");
6502 self.write_space();
6503 self.generate_expression(offset)?;
6504 }
6505 if let Some(distribute_by) = &union.distribute_by {
6507 self.write_space();
6508 self.write_keyword("DISTRIBUTE BY");
6509 self.write_space();
6510 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6511 if i > 0 {
6512 self.write(", ");
6513 }
6514 self.generate_expression(expr)?;
6515 }
6516 }
6517 if let Some(sort_by) = &union.sort_by {
6519 self.write_space();
6520 self.write_keyword("SORT BY");
6521 self.write_space();
6522 for (i, ord) in sort_by.expressions.iter().enumerate() {
6523 if i > 0 {
6524 self.write(", ");
6525 }
6526 self.generate_ordered(ord)?;
6527 }
6528 }
6529 if let Some(cluster_by) = &union.cluster_by {
6531 self.write_space();
6532 self.write_keyword("CLUSTER BY");
6533 self.write_space();
6534 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6535 if i > 0 {
6536 self.write(", ");
6537 }
6538 self.generate_ordered(ord)?;
6539 }
6540 }
6541 Ok(())
6542 }
6543
6544 fn generate_intersect(&mut self, outermost: &Intersect) -> Result<()> {
6545 let mut chain: Vec<&Intersect> = vec![outermost];
6547 let mut leftmost: &Expression = &outermost.left;
6548 while let Expression::Intersect(inner) = leftmost {
6549 chain.push(inner);
6550 leftmost = &inner.left;
6551 }
6552
6553 if let Some(with) = &outermost.with {
6554 self.generate_with(with)?;
6555 self.write_space();
6556 }
6557
6558 self.generate_expression(leftmost)?;
6559
6560 for intersect in chain.iter().rev() {
6561 self.generate_intersect_step(intersect)?;
6562 }
6563 Ok(())
6564 }
6565
6566 fn generate_intersect_step(&mut self, intersect: &Intersect) -> Result<()> {
6568 if self.config.pretty {
6569 self.write_newline();
6570 self.write_indent();
6571 } else {
6572 self.write_space();
6573 }
6574
6575 if let Some(side) = &intersect.side {
6577 self.write_keyword(side);
6578 self.write_space();
6579 }
6580 if let Some(kind) = &intersect.kind {
6581 self.write_keyword(kind);
6582 self.write_space();
6583 }
6584
6585 self.write_keyword("INTERSECT");
6586 if intersect.all {
6587 self.write_space();
6588 self.write_keyword("ALL");
6589 } else if intersect.distinct {
6590 self.write_space();
6591 self.write_keyword("DISTINCT");
6592 }
6593
6594 if intersect.corresponding || intersect.by_name {
6597 self.write_space();
6598 self.write_keyword("BY NAME");
6599 }
6600 if !intersect.on_columns.is_empty() {
6601 self.write_space();
6602 self.write_keyword("ON");
6603 self.write(" (");
6604 for (i, col) in intersect.on_columns.iter().enumerate() {
6605 if i > 0 {
6606 self.write(", ");
6607 }
6608 self.generate_expression(col)?;
6609 }
6610 self.write(")");
6611 }
6612
6613 if self.config.pretty {
6614 self.write_newline();
6615 self.write_indent();
6616 } else {
6617 self.write_space();
6618 }
6619 self.generate_expression(&intersect.right)?;
6620 if let Some(order_by) = &intersect.order_by {
6622 if self.config.pretty {
6623 self.write_newline();
6624 } else {
6625 self.write_space();
6626 }
6627 self.write_keyword("ORDER BY");
6628 self.write_space();
6629 for (i, ordered) in order_by.expressions.iter().enumerate() {
6630 if i > 0 {
6631 self.write(", ");
6632 }
6633 self.generate_ordered(ordered)?;
6634 }
6635 }
6636 if let Some(limit) = &intersect.limit {
6637 if self.config.pretty {
6638 self.write_newline();
6639 } else {
6640 self.write_space();
6641 }
6642 self.write_keyword("LIMIT");
6643 self.write_space();
6644 self.generate_expression(limit)?;
6645 }
6646 if let Some(offset) = &intersect.offset {
6647 if self.config.pretty {
6648 self.write_newline();
6649 } else {
6650 self.write_space();
6651 }
6652 self.write_keyword("OFFSET");
6653 self.write_space();
6654 self.generate_expression(offset)?;
6655 }
6656 if let Some(distribute_by) = &intersect.distribute_by {
6658 self.write_space();
6659 self.write_keyword("DISTRIBUTE BY");
6660 self.write_space();
6661 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6662 if i > 0 {
6663 self.write(", ");
6664 }
6665 self.generate_expression(expr)?;
6666 }
6667 }
6668 if let Some(sort_by) = &intersect.sort_by {
6670 self.write_space();
6671 self.write_keyword("SORT BY");
6672 self.write_space();
6673 for (i, ord) in sort_by.expressions.iter().enumerate() {
6674 if i > 0 {
6675 self.write(", ");
6676 }
6677 self.generate_ordered(ord)?;
6678 }
6679 }
6680 if let Some(cluster_by) = &intersect.cluster_by {
6682 self.write_space();
6683 self.write_keyword("CLUSTER BY");
6684 self.write_space();
6685 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6686 if i > 0 {
6687 self.write(", ");
6688 }
6689 self.generate_ordered(ord)?;
6690 }
6691 }
6692 Ok(())
6693 }
6694
6695 fn generate_except(&mut self, outermost: &Except) -> Result<()> {
6696 let mut chain: Vec<&Except> = vec![outermost];
6698 let mut leftmost: &Expression = &outermost.left;
6699 while let Expression::Except(inner) = leftmost {
6700 chain.push(inner);
6701 leftmost = &inner.left;
6702 }
6703
6704 if let Some(with) = &outermost.with {
6705 self.generate_with(with)?;
6706 self.write_space();
6707 }
6708
6709 self.generate_expression(leftmost)?;
6710
6711 for except in chain.iter().rev() {
6712 self.generate_except_step(except)?;
6713 }
6714 Ok(())
6715 }
6716
6717 fn generate_except_step(&mut self, except: &Except) -> Result<()> {
6719 use crate::dialects::DialectType;
6720
6721 if self.config.pretty {
6722 self.write_newline();
6723 self.write_indent();
6724 } else {
6725 self.write_space();
6726 }
6727
6728 if let Some(side) = &except.side {
6730 self.write_keyword(side);
6731 self.write_space();
6732 }
6733 if let Some(kind) = &except.kind {
6734 self.write_keyword(kind);
6735 self.write_space();
6736 }
6737
6738 match self.config.dialect {
6740 Some(DialectType::Oracle) if !except.all => {
6741 self.write_keyword("MINUS");
6742 }
6743 Some(DialectType::ClickHouse) => {
6744 self.write_keyword("EXCEPT");
6745 let preserve_all = self.config.source_dialect.is_none()
6746 || matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
6747 if except.all && preserve_all {
6748 self.write_space();
6749 self.write_keyword("ALL");
6750 }
6751 if except.distinct {
6752 self.write_space();
6753 self.write_keyword("DISTINCT");
6754 }
6755 }
6756 Some(DialectType::BigQuery) => {
6757 self.write_keyword("EXCEPT");
6759 if except.all {
6760 self.write_space();
6761 self.write_keyword("ALL");
6762 } else {
6763 self.write_space();
6764 self.write_keyword("DISTINCT");
6765 }
6766 }
6767 _ => {
6768 self.write_keyword("EXCEPT");
6769 if except.all {
6770 self.write_space();
6771 self.write_keyword("ALL");
6772 } else if except.distinct {
6773 self.write_space();
6774 self.write_keyword("DISTINCT");
6775 }
6776 }
6777 }
6778
6779 if except.corresponding || except.by_name {
6782 self.write_space();
6783 self.write_keyword("BY NAME");
6784 }
6785 if !except.on_columns.is_empty() {
6786 self.write_space();
6787 self.write_keyword("ON");
6788 self.write(" (");
6789 for (i, col) in except.on_columns.iter().enumerate() {
6790 if i > 0 {
6791 self.write(", ");
6792 }
6793 self.generate_expression(col)?;
6794 }
6795 self.write(")");
6796 }
6797
6798 if self.config.pretty {
6799 self.write_newline();
6800 self.write_indent();
6801 } else {
6802 self.write_space();
6803 }
6804 self.generate_expression(&except.right)?;
6805 if let Some(order_by) = &except.order_by {
6807 if self.config.pretty {
6808 self.write_newline();
6809 } else {
6810 self.write_space();
6811 }
6812 self.write_keyword("ORDER BY");
6813 self.write_space();
6814 for (i, ordered) in order_by.expressions.iter().enumerate() {
6815 if i > 0 {
6816 self.write(", ");
6817 }
6818 self.generate_ordered(ordered)?;
6819 }
6820 }
6821 if let Some(limit) = &except.limit {
6822 if self.config.pretty {
6823 self.write_newline();
6824 } else {
6825 self.write_space();
6826 }
6827 self.write_keyword("LIMIT");
6828 self.write_space();
6829 self.generate_expression(limit)?;
6830 }
6831 if let Some(offset) = &except.offset {
6832 if self.config.pretty {
6833 self.write_newline();
6834 } else {
6835 self.write_space();
6836 }
6837 self.write_keyword("OFFSET");
6838 self.write_space();
6839 self.generate_expression(offset)?;
6840 }
6841 if let Some(distribute_by) = &except.distribute_by {
6843 self.write_space();
6844 self.write_keyword("DISTRIBUTE BY");
6845 self.write_space();
6846 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6847 if i > 0 {
6848 self.write(", ");
6849 }
6850 self.generate_expression(expr)?;
6851 }
6852 }
6853 if let Some(sort_by) = &except.sort_by {
6855 self.write_space();
6856 self.write_keyword("SORT BY");
6857 self.write_space();
6858 for (i, ord) in sort_by.expressions.iter().enumerate() {
6859 if i > 0 {
6860 self.write(", ");
6861 }
6862 self.generate_ordered(ord)?;
6863 }
6864 }
6865 if let Some(cluster_by) = &except.cluster_by {
6867 self.write_space();
6868 self.write_keyword("CLUSTER BY");
6869 self.write_space();
6870 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6871 if i > 0 {
6872 self.write(", ");
6873 }
6874 self.generate_ordered(ord)?;
6875 }
6876 }
6877 Ok(())
6878 }
6879
6880 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
6881 let prepend_query_cte = if insert.with.is_none() {
6883 use crate::dialects::DialectType;
6884 let should_prepend = matches!(
6885 self.config.dialect,
6886 Some(DialectType::TSQL)
6887 | Some(DialectType::Fabric)
6888 | Some(DialectType::Spark)
6889 | Some(DialectType::Databricks)
6890 | Some(DialectType::Hive)
6891 );
6892 if should_prepend {
6893 if let Some(Expression::Select(select)) = &insert.query {
6894 select.with.clone()
6895 } else {
6896 None
6897 }
6898 } else {
6899 None
6900 }
6901 } else {
6902 None
6903 };
6904
6905 if let Some(with) = &insert.with {
6907 self.generate_with(with)?;
6908 self.write_space();
6909 } else if let Some(with) = &prepend_query_cte {
6910 self.generate_with(with)?;
6911 self.write_space();
6912 }
6913
6914 for comment in &insert.leading_comments {
6916 self.write_formatted_comment(comment);
6917 self.write(" ");
6918 }
6919
6920 if let Some(dir) = &insert.directory {
6922 self.write_keyword("INSERT OVERWRITE");
6923 if dir.local {
6924 self.write_space();
6925 self.write_keyword("LOCAL");
6926 }
6927 self.write_space();
6928 self.write_keyword("DIRECTORY");
6929 self.write_space();
6930 self.write("'");
6931 self.write(&dir.path);
6932 self.write("'");
6933
6934 if let Some(row_format) = &dir.row_format {
6936 self.write_space();
6937 self.write_keyword("ROW FORMAT");
6938 if row_format.delimited {
6939 self.write_space();
6940 self.write_keyword("DELIMITED");
6941 }
6942 if let Some(val) = &row_format.fields_terminated_by {
6943 self.write_space();
6944 self.write_keyword("FIELDS TERMINATED BY");
6945 self.write_space();
6946 self.generate_string_literal(val)?;
6947 }
6948 if let Some(val) = &row_format.collection_items_terminated_by {
6949 self.write_space();
6950 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
6951 self.write_space();
6952 self.write("'");
6953 self.write(val);
6954 self.write("'");
6955 }
6956 if let Some(val) = &row_format.map_keys_terminated_by {
6957 self.write_space();
6958 self.write_keyword("MAP KEYS TERMINATED BY");
6959 self.write_space();
6960 self.write("'");
6961 self.write(val);
6962 self.write("'");
6963 }
6964 if let Some(val) = &row_format.lines_terminated_by {
6965 self.write_space();
6966 self.write_keyword("LINES TERMINATED BY");
6967 self.write_space();
6968 self.write("'");
6969 self.write(val);
6970 self.write("'");
6971 }
6972 if let Some(val) = &row_format.null_defined_as {
6973 self.write_space();
6974 self.write_keyword("NULL DEFINED AS");
6975 self.write_space();
6976 self.write("'");
6977 self.write(val);
6978 self.write("'");
6979 }
6980 }
6981
6982 if let Some(format) = &dir.stored_as {
6984 self.write_space();
6985 self.write_keyword("STORED AS");
6986 self.write_space();
6987 self.write_keyword(format);
6988 }
6989
6990 if let Some(query) = &insert.query {
6992 self.write_space();
6993 self.generate_expression(query)?;
6994 }
6995
6996 return Ok(());
6997 }
6998
6999 if insert.is_replace {
7000 self.write_keyword("REPLACE INTO");
7002 } else if insert.overwrite {
7003 self.write_keyword("INSERT");
7005 if let Some(ref hint) = insert.hint {
7007 self.generate_hint(hint)?;
7008 }
7009 self.write(&self.config.insert_overwrite.to_ascii_uppercase());
7010 } else if let Some(ref action) = insert.conflict_action {
7011 self.write_keyword("INSERT OR");
7013 self.write_space();
7014 self.write_keyword(action);
7015 self.write_space();
7016 self.write_keyword("INTO");
7017 } else if insert.ignore {
7018 self.write_keyword("INSERT IGNORE INTO");
7020 } else {
7021 self.write_keyword("INSERT");
7022 if let Some(ref hint) = insert.hint {
7024 self.generate_hint(hint)?;
7025 }
7026 self.write_space();
7027 self.write_keyword("INTO");
7028 }
7029 if let Some(ref func) = insert.function_target {
7031 self.write_space();
7032 self.write_keyword("FUNCTION");
7033 self.write_space();
7034 self.generate_expression(func)?;
7035 } else {
7036 self.write_space();
7037 self.generate_table(&insert.table)?;
7038 }
7039
7040 if let Some(ref alias) = insert.alias {
7042 self.write_space();
7043 if insert.alias_explicit_as {
7044 self.write_keyword("AS");
7045 self.write_space();
7046 }
7047 self.generate_identifier(alias)?;
7048 }
7049
7050 if insert.if_exists {
7052 self.write_space();
7053 self.write_keyword("IF EXISTS");
7054 }
7055
7056 if let Some(ref replace_where) = insert.replace_where {
7058 if self.config.pretty {
7059 self.write_newline();
7060 self.write_indent();
7061 } else {
7062 self.write_space();
7063 }
7064 self.write_keyword("REPLACE WHERE");
7065 self.write_space();
7066 self.generate_expression(replace_where)?;
7067 }
7068
7069 if !insert.partition.is_empty() {
7071 self.write_space();
7072 self.write_keyword("PARTITION");
7073 self.write("(");
7074 for (i, (col, val)) in insert.partition.iter().enumerate() {
7075 if i > 0 {
7076 self.write(", ");
7077 }
7078 self.generate_identifier(col)?;
7079 if let Some(v) = val {
7080 self.write(" = ");
7081 self.generate_expression(v)?;
7082 }
7083 }
7084 self.write(")");
7085 }
7086
7087 if let Some(ref partition_by) = insert.partition_by {
7089 self.write_space();
7090 self.write_keyword("PARTITION BY");
7091 self.write_space();
7092 self.generate_expression(partition_by)?;
7093 }
7094
7095 if !insert.settings.is_empty() {
7097 self.write_space();
7098 self.write_keyword("SETTINGS");
7099 self.write_space();
7100 for (i, setting) in insert.settings.iter().enumerate() {
7101 if i > 0 {
7102 self.write(", ");
7103 }
7104 self.generate_expression(setting)?;
7105 }
7106 }
7107
7108 if !insert.columns.is_empty() {
7109 if insert.alias.is_some() && insert.alias_explicit_as {
7110 self.write("(");
7112 } else {
7113 self.write(" (");
7115 }
7116 for (i, col) in insert.columns.iter().enumerate() {
7117 if i > 0 {
7118 self.write(", ");
7119 }
7120 self.generate_identifier(col)?;
7121 }
7122 self.write(")");
7123 }
7124
7125 if let Some(ref output) = insert.output {
7127 self.generate_output_clause(output)?;
7128 }
7129
7130 if insert.by_name {
7132 self.write_space();
7133 self.write_keyword("BY NAME");
7134 }
7135
7136 if insert.default_values {
7137 self.write_space();
7138 self.write_keyword("DEFAULT VALUES");
7139 } else if let Some(query) = &insert.query {
7140 if self.config.pretty {
7141 self.write_newline();
7142 } else {
7143 self.write_space();
7144 }
7145 if prepend_query_cte.is_some() {
7147 if let Expression::Select(select) = query {
7148 let mut select_no_with = select.clone();
7149 select_no_with.with = None;
7150 self.generate_select(&select_no_with)?;
7151 } else {
7152 self.generate_expression(query)?;
7153 }
7154 } else {
7155 self.generate_expression(query)?;
7156 }
7157 } else if !insert.values.is_empty() {
7158 if self.config.pretty {
7159 self.write_newline();
7161 self.write_keyword("VALUES");
7162 self.write_newline();
7163 self.indent_level += 1;
7164 for (i, row) in insert.values.iter().enumerate() {
7165 if i > 0 {
7166 self.write(",");
7167 self.write_newline();
7168 }
7169 self.write_indent();
7170 self.write("(");
7171 for (j, val) in row.iter().enumerate() {
7172 if j > 0 {
7173 self.write(", ");
7174 }
7175 self.generate_expression(val)?;
7176 }
7177 self.write(")");
7178 }
7179 self.indent_level -= 1;
7180 } else {
7181 self.write_space();
7183 self.write_keyword("VALUES");
7184 for (i, row) in insert.values.iter().enumerate() {
7185 if i > 0 {
7186 self.write(",");
7187 }
7188 self.write(" (");
7189 for (j, val) in row.iter().enumerate() {
7190 if j > 0 {
7191 self.write(", ");
7192 }
7193 self.generate_expression(val)?;
7194 }
7195 self.write(")");
7196 }
7197 }
7198 }
7199
7200 if let Some(ref source) = insert.source {
7202 self.write_space();
7203 self.write_keyword("TABLE");
7204 self.write_space();
7205 self.generate_expression(source)?;
7206 }
7207
7208 if let Some(alias) = &insert.source_alias {
7210 self.write_space();
7211 self.write_keyword("AS");
7212 self.write_space();
7213 self.generate_identifier(alias)?;
7214 }
7215
7216 if let Some(on_conflict) = &insert.on_conflict {
7218 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
7219 self.write_space();
7220 self.generate_expression(on_conflict)?;
7221 }
7222 }
7223
7224 if !insert.returning.is_empty() {
7226 self.write_space();
7227 self.write_keyword("RETURNING");
7228 self.write_space();
7229 for (i, expr) in insert.returning.iter().enumerate() {
7230 if i > 0 {
7231 self.write(", ");
7232 }
7233 self.generate_expression(expr)?;
7234 }
7235 }
7236
7237 Ok(())
7238 }
7239
7240 fn generate_update(&mut self, update: &Update) -> Result<()> {
7241 for comment in &update.leading_comments {
7243 self.write_formatted_comment(comment);
7244 self.write(" ");
7245 }
7246
7247 if let Some(ref with) = update.with {
7249 self.generate_with(with)?;
7250 self.write_space();
7251 }
7252
7253 self.write_keyword("UPDATE");
7254 if let Some(hint) = &update.hint {
7255 self.generate_hint(hint)?;
7256 }
7257 self.write_space();
7258 self.generate_table(&update.table)?;
7259
7260 let mysql_like_update_from = matches!(
7261 self.config.dialect,
7262 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
7263 ) && update.from_clause.is_some();
7264
7265 let mut set_pairs = update.set.clone();
7266
7267 let mut pre_set_joins = update.table_joins.clone();
7269 if mysql_like_update_from {
7270 let target_name = update
7271 .table
7272 .alias
7273 .as_ref()
7274 .map(|a| a.name.clone())
7275 .unwrap_or_else(|| update.table.name.name.clone());
7276
7277 for (col, _) in &mut set_pairs {
7278 if !col.name.contains('.') {
7279 col.name = format!("{}.{}", target_name, col.name);
7280 }
7281 }
7282
7283 if let Some(from_clause) = &update.from_clause {
7284 for table_expr in &from_clause.expressions {
7285 pre_set_joins.push(crate::expressions::Join {
7286 this: table_expr.clone(),
7287 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7288 value: true,
7289 })),
7290 using: Vec::new(),
7291 kind: crate::expressions::JoinKind::Inner,
7292 use_inner_keyword: false,
7293 use_outer_keyword: false,
7294 deferred_condition: false,
7295 join_hint: None,
7296 match_condition: None,
7297 pivots: Vec::new(),
7298 comments: Vec::new(),
7299 nesting_group: 0,
7300 directed: false,
7301 });
7302 }
7303 }
7304 for join in &update.from_joins {
7305 let mut join = join.clone();
7306 if join.on.is_none() && join.using.is_empty() {
7307 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7308 value: true,
7309 }));
7310 }
7311 pre_set_joins.push(join);
7312 }
7313 }
7314
7315 for extra_table in &update.extra_tables {
7317 self.write(", ");
7318 self.generate_table(extra_table)?;
7319 }
7320
7321 for join in &pre_set_joins {
7323 self.generate_join(join)?;
7325 }
7326
7327 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
7329 if teradata_from_before_set && !mysql_like_update_from {
7330 if let Some(ref from_clause) = update.from_clause {
7331 self.write_space();
7332 self.write_keyword("FROM");
7333 self.write_space();
7334 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7335 if i > 0 {
7336 self.write(", ");
7337 }
7338 self.generate_expression(table_expr)?;
7339 }
7340 }
7341 for join in &update.from_joins {
7342 self.generate_join(join)?;
7343 }
7344 }
7345
7346 self.write_space();
7347 self.write_keyword("SET");
7348 self.write_space();
7349
7350 for (i, (col, val)) in set_pairs.iter().enumerate() {
7351 if i > 0 {
7352 self.write(", ");
7353 }
7354 self.generate_identifier(col)?;
7355 self.write(" = ");
7356 self.generate_expression(val)?;
7357 }
7358
7359 if let Some(ref output) = update.output {
7361 self.generate_output_clause(output)?;
7362 }
7363
7364 if !mysql_like_update_from && !teradata_from_before_set {
7366 if let Some(ref from_clause) = update.from_clause {
7367 self.write_space();
7368 self.write_keyword("FROM");
7369 self.write_space();
7370 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7372 if i > 0 {
7373 self.write(", ");
7374 }
7375 self.generate_expression(table_expr)?;
7376 }
7377 }
7378 }
7379
7380 if !mysql_like_update_from && !teradata_from_before_set {
7381 for join in &update.from_joins {
7383 self.generate_join(join)?;
7384 }
7385 }
7386
7387 if let Some(where_clause) = &update.where_clause {
7388 self.write_space();
7389 self.write_keyword("WHERE");
7390 self.write_space();
7391 self.generate_expression(&where_clause.this)?;
7392 }
7393
7394 if !update.returning.is_empty() {
7396 self.write_space();
7397 self.write_keyword("RETURNING");
7398 self.write_space();
7399 for (i, expr) in update.returning.iter().enumerate() {
7400 if i > 0 {
7401 self.write(", ");
7402 }
7403 self.generate_expression(expr)?;
7404 }
7405 }
7406
7407 if let Some(ref order_by) = update.order_by {
7409 self.write_space();
7410 self.generate_order_by(order_by)?;
7411 }
7412
7413 if let Some(ref limit) = update.limit {
7415 self.write_space();
7416 self.write_keyword("LIMIT");
7417 self.write_space();
7418 self.generate_expression(limit)?;
7419 }
7420
7421 Ok(())
7422 }
7423
7424 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
7425 if let Some(with) = &delete.with {
7427 self.generate_with(with)?;
7428 self.write_space();
7429 }
7430
7431 for comment in &delete.leading_comments {
7433 self.write_formatted_comment(comment);
7434 self.write(" ");
7435 }
7436
7437 if !delete.tables.is_empty() && !delete.tables_from_using {
7439 self.write_keyword("DELETE");
7441 if let Some(hint) = &delete.hint {
7442 self.generate_hint(hint)?;
7443 }
7444 self.write_space();
7445 for (i, tbl) in delete.tables.iter().enumerate() {
7446 if i > 0 {
7447 self.write(", ");
7448 }
7449 self.generate_table(tbl)?;
7450 }
7451 if let Some(ref output) = delete.output {
7453 self.generate_output_clause(output)?;
7454 }
7455 self.write_space();
7456 self.write_keyword("FROM");
7457 self.write_space();
7458 self.generate_table(&delete.table)?;
7459 } else if !delete.tables.is_empty() && delete.tables_from_using {
7460 self.write_keyword("DELETE");
7462 if let Some(hint) = &delete.hint {
7463 self.generate_hint(hint)?;
7464 }
7465 self.write_space();
7466 self.write_keyword("FROM");
7467 self.write_space();
7468 for (i, tbl) in delete.tables.iter().enumerate() {
7469 if i > 0 {
7470 self.write(", ");
7471 }
7472 self.generate_table(tbl)?;
7473 }
7474 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
7475 self.write_keyword("DELETE");
7477 if let Some(hint) = &delete.hint {
7478 self.generate_hint(hint)?;
7479 }
7480 self.write_space();
7481 self.generate_table(&delete.table)?;
7482 } else {
7483 self.write_keyword("DELETE");
7484 if let Some(hint) = &delete.hint {
7485 self.generate_hint(hint)?;
7486 }
7487 self.write_space();
7488 self.write_keyword("FROM");
7489 self.write_space();
7490 self.generate_table(&delete.table)?;
7491 }
7492
7493 if let Some(ref on_cluster) = delete.on_cluster {
7495 self.write_space();
7496 self.generate_on_cluster(on_cluster)?;
7497 }
7498
7499 if let Some(ref idx) = delete.force_index {
7501 self.write_space();
7502 self.write_keyword("FORCE INDEX");
7503 self.write(" (");
7504 self.write(idx);
7505 self.write(")");
7506 }
7507
7508 if let Some(ref alias) = delete.alias {
7510 self.write_space();
7511 if delete.alias_explicit_as
7512 || matches!(self.config.dialect, Some(DialectType::BigQuery))
7513 {
7514 self.write_keyword("AS");
7515 self.write_space();
7516 }
7517 self.generate_identifier(alias)?;
7518 }
7519
7520 if !delete.tables_from_using {
7522 for join in &delete.joins {
7523 self.generate_join(join)?;
7524 }
7525 }
7526
7527 if !delete.using.is_empty() {
7529 self.write_space();
7530 self.write_keyword("USING");
7531 for (i, table) in delete.using.iter().enumerate() {
7532 if i > 0 {
7533 self.write(",");
7534 }
7535 self.write_space();
7536 if !table.hints.is_empty() && table.name.is_empty() {
7538 self.generate_expression(&table.hints[0])?;
7540 if let Some(ref alias) = table.alias {
7541 self.write_space();
7542 if table.alias_explicit_as {
7543 self.write_keyword("AS");
7544 self.write_space();
7545 }
7546 self.generate_identifier(alias)?;
7547 if !table.column_aliases.is_empty() {
7548 self.write("(");
7549 for (j, col_alias) in table.column_aliases.iter().enumerate() {
7550 if j > 0 {
7551 self.write(", ");
7552 }
7553 self.generate_identifier(col_alias)?;
7554 }
7555 self.write(")");
7556 }
7557 }
7558 } else {
7559 self.generate_table(table)?;
7560 }
7561 }
7562 }
7563
7564 if delete.tables_from_using {
7566 for join in &delete.joins {
7567 self.generate_join(join)?;
7568 }
7569 }
7570
7571 let output_already_emitted =
7573 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
7574 if !output_already_emitted {
7575 if let Some(ref output) = delete.output {
7576 self.generate_output_clause(output)?;
7577 }
7578 }
7579
7580 if let Some(where_clause) = &delete.where_clause {
7581 self.write_space();
7582 self.write_keyword("WHERE");
7583 self.write_space();
7584 self.generate_expression(&where_clause.this)?;
7585 }
7586
7587 if let Some(ref order_by) = delete.order_by {
7589 self.write_space();
7590 self.generate_order_by(order_by)?;
7591 }
7592
7593 if let Some(ref limit) = delete.limit {
7595 self.write_space();
7596 self.write_keyword("LIMIT");
7597 self.write_space();
7598 self.generate_expression(limit)?;
7599 }
7600
7601 if !delete.returning.is_empty() {
7603 self.write_space();
7604 self.write_keyword("RETURNING");
7605 self.write_space();
7606 for (i, expr) in delete.returning.iter().enumerate() {
7607 if i > 0 {
7608 self.write(", ");
7609 }
7610 self.generate_expression(expr)?;
7611 }
7612 }
7613
7614 Ok(())
7615 }
7616
7617 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
7620 let saved_athena_hive_context = self.athena_hive_context;
7624 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
7625 if matches!(
7626 self.config.dialect,
7627 Some(crate::dialects::DialectType::Athena)
7628 ) {
7629 let is_external = ct
7633 .table_modifier
7634 .as_ref()
7635 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
7636 .unwrap_or(false);
7637 let has_as_select = ct.as_select.is_some();
7638 self.athena_hive_context = is_external || !has_as_select;
7639 }
7640
7641 if matches!(
7643 self.config.dialect,
7644 Some(crate::dialects::DialectType::TSQL)
7645 ) {
7646 if let Some(ref query) = ct.as_select {
7647 if let Some(with_cte) = &ct.with_cte {
7649 self.generate_with(with_cte)?;
7650 self.write_space();
7651 }
7652
7653 self.write_keyword("SELECT");
7655 self.write(" * ");
7656 self.write_keyword("INTO");
7657 self.write_space();
7658
7659 if ct.temporary {
7661 self.write("#");
7662 }
7663 self.generate_table(&ct.name)?;
7664
7665 self.write_space();
7666 self.write_keyword("FROM");
7667 self.write(" (");
7668 let aliased_query = Self::add_column_aliases_to_query(query.clone());
7670 self.generate_expression(&aliased_query)?;
7671 self.write(") ");
7672 self.write_keyword("AS");
7673 self.write(" temp");
7674 return Ok(());
7675 }
7676 }
7677
7678 if let Some(with_cte) = &ct.with_cte {
7680 self.generate_with(with_cte)?;
7681 self.write_space();
7682 }
7683
7684 for comment in &ct.leading_comments {
7686 self.write_formatted_comment(comment);
7687 self.write(" ");
7688 }
7689 self.write_keyword("CREATE");
7690
7691 if ct.or_replace {
7692 self.write_space();
7693 self.write_keyword("OR REPLACE");
7694 }
7695
7696 if ct.temporary {
7697 self.write_space();
7698 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
7700 self.write_keyword("GLOBAL TEMPORARY");
7701 } else {
7702 self.write_keyword("TEMPORARY");
7703 }
7704 }
7705
7706 let is_dictionary = ct
7708 .table_modifier
7709 .as_ref()
7710 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
7711 .unwrap_or(false);
7712 if let Some(ref modifier) = ct.table_modifier {
7713 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
7715 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
7716 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
7718 || modifier.eq_ignore_ascii_case("SET")
7719 || modifier.eq_ignore_ascii_case("MULTISET")
7720 || modifier.to_ascii_uppercase().contains("VOLATILE")
7721 || modifier.to_ascii_uppercase().starts_with("SET ")
7722 || modifier.to_ascii_uppercase().starts_with("MULTISET ");
7723 let skip_teradata =
7724 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
7725 if !skip_transient && !skip_teradata {
7726 self.write_space();
7727 self.write_keyword(modifier);
7728 }
7729 }
7730
7731 if !is_dictionary {
7732 self.write_space();
7733 self.write_keyword("TABLE");
7734 }
7735
7736 if ct.if_not_exists {
7737 self.write_space();
7738 self.write_keyword("IF NOT EXISTS");
7739 }
7740
7741 self.write_space();
7742 self.generate_table(&ct.name)?;
7743
7744 if let Some(ref uuid) = ct.uuid {
7746 self.write_space();
7747 self.write_keyword("UUID");
7748 self.write(" '");
7749 self.write(uuid);
7750 self.write("'");
7751 }
7752
7753 if let Some(ref on_cluster) = ct.on_cluster {
7755 self.write_space();
7756 self.generate_on_cluster(on_cluster)?;
7757 }
7758
7759 if matches!(
7761 self.config.dialect,
7762 Some(crate::dialects::DialectType::Teradata)
7763 ) && !ct.teradata_post_name_options.is_empty()
7764 {
7765 for opt in &ct.teradata_post_name_options {
7766 self.write(", ");
7767 self.write(opt);
7768 }
7769 }
7770
7771 if ct.copy_grants {
7773 self.write_space();
7774 self.write_keyword("COPY GRANTS");
7775 }
7776
7777 if let Some(ref using_template) = ct.using_template {
7779 self.write_space();
7780 self.write_keyword("USING TEMPLATE");
7781 self.write_space();
7782 self.generate_expression(using_template)?;
7783 return Ok(());
7784 }
7785
7786 if is_clickhouse {
7788 if let Some(ref clone_source) = ct.clone_source {
7789 self.write_space();
7790 self.write_keyword("AS");
7791 self.write_space();
7792 self.generate_table(clone_source)?;
7793 }
7794 }
7795
7796 if !is_clickhouse {
7798 if let Some(ref clone_source) = ct.clone_source {
7799 self.write_space();
7800 if ct.is_copy && self.config.supports_table_copy {
7801 self.write_keyword("COPY");
7803 } else if ct.shallow_clone {
7804 self.write_keyword("SHALLOW CLONE");
7805 } else if ct.deep_clone {
7806 self.write_keyword("DEEP CLONE");
7807 } else {
7808 self.write_keyword("CLONE");
7809 }
7810 self.write_space();
7811 self.generate_table(clone_source)?;
7812 if let Some(ref at_clause) = ct.clone_at_clause {
7814 self.write_space();
7815 self.generate_expression(at_clause)?;
7816 }
7817 return Ok(());
7818 }
7819 }
7820
7821 if let Some(ref partition_of) = ct.partition_of {
7825 self.write_space();
7826
7827 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
7829 self.write_keyword("PARTITION OF");
7831 self.write_space();
7832 self.generate_expression(&pop.this)?;
7833
7834 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7836 self.write(" (");
7837 let mut first = true;
7838 for col in &ct.columns {
7839 if !first {
7840 self.write(", ");
7841 }
7842 first = false;
7843 self.generate_column_def(col)?;
7844 }
7845 for constraint in &ct.constraints {
7846 if !first {
7847 self.write(", ");
7848 }
7849 first = false;
7850 self.generate_table_constraint(constraint)?;
7851 }
7852 self.write(")");
7853 }
7854
7855 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
7857 self.write_space();
7858 self.write_keyword("FOR VALUES");
7859 self.write_space();
7860 self.generate_expression(&pop.expression)?;
7861 } else {
7862 self.write_space();
7863 self.write_keyword("DEFAULT");
7864 }
7865 } else {
7866 self.generate_expression(partition_of)?;
7868
7869 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7871 self.write(" (");
7872 let mut first = true;
7873 for col in &ct.columns {
7874 if !first {
7875 self.write(", ");
7876 }
7877 first = false;
7878 self.generate_column_def(col)?;
7879 }
7880 for constraint in &ct.constraints {
7881 if !first {
7882 self.write(", ");
7883 }
7884 first = false;
7885 self.generate_table_constraint(constraint)?;
7886 }
7887 self.write(")");
7888 }
7889 }
7890
7891 for prop in &ct.properties {
7893 self.write_space();
7894 self.generate_expression(prop)?;
7895 }
7896
7897 return Ok(());
7898 }
7899
7900 self.sqlite_inline_pk_columns.clear();
7903 if matches!(
7904 self.config.dialect,
7905 Some(crate::dialects::DialectType::SQLite)
7906 ) {
7907 for constraint in &ct.constraints {
7908 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7909 if columns.len() == 1 && name.is_none() {
7911 let pk_col_name = columns[0].name.to_ascii_lowercase();
7912 if ct
7914 .columns
7915 .iter()
7916 .any(|c| c.name.name.to_ascii_lowercase() == pk_col_name)
7917 {
7918 self.sqlite_inline_pk_columns.insert(pk_col_name);
7919 }
7920 }
7921 }
7922 }
7923 }
7924
7925 if !ct.columns.is_empty() {
7927 if self.config.pretty {
7928 self.write(" (");
7930 self.write_newline();
7931 self.indent_level += 1;
7932 for (i, col) in ct.columns.iter().enumerate() {
7933 if i > 0 {
7934 self.write(",");
7935 self.write_newline();
7936 }
7937 self.write_indent();
7938 self.generate_column_def(col)?;
7939 }
7940 for constraint in &ct.constraints {
7942 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7944 if columns.len() == 1
7945 && name.is_none()
7946 && self
7947 .sqlite_inline_pk_columns
7948 .contains(&columns[0].name.to_ascii_lowercase())
7949 {
7950 continue;
7951 }
7952 }
7953 self.write(",");
7954 self.write_newline();
7955 self.write_indent();
7956 self.generate_table_constraint(constraint)?;
7957 }
7958 self.indent_level -= 1;
7959 self.write_newline();
7960 self.write(")");
7961 } else {
7962 self.write(" (");
7963 for (i, col) in ct.columns.iter().enumerate() {
7964 if i > 0 {
7965 self.write(", ");
7966 }
7967 self.generate_column_def(col)?;
7968 }
7969 let mut first_constraint = true;
7971 for constraint in &ct.constraints {
7972 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7974 if columns.len() == 1
7975 && name.is_none()
7976 && self
7977 .sqlite_inline_pk_columns
7978 .contains(&columns[0].name.to_ascii_lowercase())
7979 {
7980 continue;
7981 }
7982 }
7983 if first_constraint {
7984 self.write(", ");
7985 first_constraint = false;
7986 } else {
7987 self.write(", ");
7988 }
7989 self.generate_table_constraint(constraint)?;
7990 }
7991 self.write(")");
7992 }
7993 } else if !ct.constraints.is_empty() {
7994 let has_like_only = ct
7996 .constraints
7997 .iter()
7998 .all(|c| matches!(c, TableConstraint::Like { .. }));
7999 let has_tags_only = ct
8000 .constraints
8001 .iter()
8002 .all(|c| matches!(c, TableConstraint::Tags(_)));
8003 let is_pg_like = matches!(
8007 self.config.dialect,
8008 Some(crate::dialects::DialectType::PostgreSQL)
8009 | Some(crate::dialects::DialectType::CockroachDB)
8010 | Some(crate::dialects::DialectType::Materialize)
8011 | Some(crate::dialects::DialectType::RisingWave)
8012 | Some(crate::dialects::DialectType::Redshift)
8013 | Some(crate::dialects::DialectType::Presto)
8014 | Some(crate::dialects::DialectType::Trino)
8015 | Some(crate::dialects::DialectType::Athena)
8016 );
8017 let use_parens = if has_like_only {
8018 is_pg_like
8019 } else {
8020 !has_tags_only
8021 };
8022 if self.config.pretty && use_parens {
8023 self.write(" (");
8024 self.write_newline();
8025 self.indent_level += 1;
8026 for (i, constraint) in ct.constraints.iter().enumerate() {
8027 if i > 0 {
8028 self.write(",");
8029 self.write_newline();
8030 }
8031 self.write_indent();
8032 self.generate_table_constraint(constraint)?;
8033 }
8034 self.indent_level -= 1;
8035 self.write_newline();
8036 self.write(")");
8037 } else {
8038 if use_parens {
8039 self.write(" (");
8040 } else {
8041 self.write_space();
8042 }
8043 for (i, constraint) in ct.constraints.iter().enumerate() {
8044 if i > 0 {
8045 self.write(", ");
8046 }
8047 self.generate_table_constraint(constraint)?;
8048 }
8049 if use_parens {
8050 self.write(")");
8051 }
8052 }
8053 }
8054
8055 if let Some(ref on_prop) = ct.on_property {
8057 self.write(" ");
8058 self.write_keyword("ON");
8059 self.write(" ");
8060 self.generate_expression(&on_prop.this)?;
8061 }
8062
8063 if !ct.with_partition_columns.is_empty() {
8065 if self.config.pretty {
8066 self.write_newline();
8067 } else {
8068 self.write_space();
8069 }
8070 self.write_keyword("WITH PARTITION COLUMNS");
8071 self.write(" (");
8072 if self.config.pretty {
8073 self.write_newline();
8074 self.indent_level += 1;
8075 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8076 if i > 0 {
8077 self.write(",");
8078 self.write_newline();
8079 }
8080 self.write_indent();
8081 self.generate_column_def(col)?;
8082 }
8083 self.indent_level -= 1;
8084 self.write_newline();
8085 } else {
8086 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8087 if i > 0 {
8088 self.write(", ");
8089 }
8090 self.generate_column_def(col)?;
8091 }
8092 }
8093 self.write(")");
8094 }
8095
8096 if let Some(ref conn) = ct.with_connection {
8098 if self.config.pretty {
8099 self.write_newline();
8100 } else {
8101 self.write_space();
8102 }
8103 self.write_keyword("WITH CONNECTION");
8104 self.write_space();
8105 self.generate_table(conn)?;
8106 }
8107
8108 if !is_clickhouse {
8111 for prop in &ct.properties {
8112 if let Expression::SchemaCommentProperty(_) = prop {
8113 if self.config.pretty {
8114 self.write_newline();
8115 } else {
8116 self.write_space();
8117 }
8118 self.generate_expression(prop)?;
8119 }
8120 }
8121 }
8122
8123 if !ct.with_properties.is_empty() {
8125 let is_snowflake_special_table = matches!(
8127 self.config.dialect,
8128 Some(crate::dialects::DialectType::Snowflake)
8129 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
8130 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
8131 if is_snowflake_special_table {
8132 for (key, value) in &ct.with_properties {
8133 self.write_space();
8134 self.write(key);
8135 self.write("=");
8136 self.write(value);
8137 }
8138 } else if self.config.pretty {
8139 self.write_newline();
8140 self.write_keyword("WITH");
8141 self.write(" (");
8142 self.write_newline();
8143 self.indent_level += 1;
8144 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8145 if i > 0 {
8146 self.write(",");
8147 self.write_newline();
8148 }
8149 self.write_indent();
8150 self.write(key);
8151 self.write("=");
8152 self.write(value);
8153 }
8154 self.indent_level -= 1;
8155 self.write_newline();
8156 self.write(")");
8157 } else {
8158 self.write_space();
8159 self.write_keyword("WITH");
8160 self.write(" (");
8161 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8162 if i > 0 {
8163 self.write(", ");
8164 }
8165 self.write(key);
8166 self.write("=");
8167 self.write(value);
8168 }
8169 self.write(")");
8170 }
8171 }
8172
8173 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
8174 if is_clickhouse && ct.as_select.is_some() {
8175 let mut pre = Vec::new();
8176 let mut post = Vec::new();
8177 for prop in &ct.properties {
8178 if matches!(prop, Expression::SchemaCommentProperty(_)) {
8179 post.push(prop);
8180 } else {
8181 pre.push(prop);
8182 }
8183 }
8184 (pre, post)
8185 } else {
8186 (ct.properties.iter().collect(), Vec::new())
8187 };
8188
8189 for prop in pre_as_properties {
8191 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
8193 continue;
8194 }
8195 if self.config.pretty {
8196 self.write_newline();
8197 } else {
8198 self.write_space();
8199 }
8200 if let Expression::Properties(props) = prop {
8204 let is_hive_dialect = matches!(
8205 self.config.dialect,
8206 Some(crate::dialects::DialectType::Hive)
8207 | Some(crate::dialects::DialectType::Spark)
8208 | Some(crate::dialects::DialectType::Databricks)
8209 | Some(crate::dialects::DialectType::Athena)
8210 );
8211 let is_doris_starrocks = matches!(
8212 self.config.dialect,
8213 Some(crate::dialects::DialectType::Doris)
8214 | Some(crate::dialects::DialectType::StarRocks)
8215 );
8216 if is_hive_dialect {
8217 self.generate_tblproperties_clause(&props.expressions)?;
8218 } else if is_doris_starrocks {
8219 self.generate_properties_clause(&props.expressions)?;
8220 } else {
8221 self.generate_options_clause(&props.expressions)?;
8222 }
8223 } else {
8224 self.generate_expression(prop)?;
8225 }
8226 }
8227
8228 for prop in &ct.post_table_properties {
8230 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
8231 self.write(" WITH(");
8232 self.generate_system_versioning_content(svp)?;
8233 self.write(")");
8234 } else if let Expression::Properties(props) = prop {
8235 let is_doris_starrocks = matches!(
8237 self.config.dialect,
8238 Some(crate::dialects::DialectType::Doris)
8239 | Some(crate::dialects::DialectType::StarRocks)
8240 );
8241 self.write_space();
8242 if is_doris_starrocks {
8243 self.generate_properties_clause(&props.expressions)?;
8244 } else {
8245 self.generate_options_clause(&props.expressions)?;
8246 }
8247 } else {
8248 self.write_space();
8249 self.generate_expression(prop)?;
8250 }
8251 }
8252
8253 if let Some(ref rollup) = ct.rollup {
8256 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
8257 self.write_space();
8258 self.generate_rollup_property(rollup)?;
8259 }
8260 }
8261
8262 let is_mysql_compatible = matches!(
8266 self.config.dialect,
8267 Some(DialectType::MySQL)
8268 | Some(DialectType::SingleStore)
8269 | Some(DialectType::Doris)
8270 | Some(DialectType::StarRocks)
8271 | None
8272 );
8273 let is_hive_compatible = matches!(
8274 self.config.dialect,
8275 Some(DialectType::Hive)
8276 | Some(DialectType::Spark)
8277 | Some(DialectType::Databricks)
8278 | Some(DialectType::Athena)
8279 );
8280 let mysql_pretty_options =
8281 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
8282 for (key, value) in &ct.mysql_table_options {
8283 let should_output = if is_mysql_compatible {
8285 true
8286 } else if is_hive_compatible && key == "COMMENT" {
8287 true } else {
8289 false
8290 };
8291 if should_output {
8292 if mysql_pretty_options {
8293 self.write_newline();
8294 self.write_indent();
8295 } else {
8296 self.write_space();
8297 }
8298 self.write_keyword(key);
8299 if key == "COMMENT" && !self.config.schema_comment_with_eq {
8301 self.write_space();
8302 } else {
8303 self.write("=");
8304 }
8305 self.write(value);
8306 }
8307 }
8308
8309 if ct.temporary
8311 && matches!(
8312 self.config.dialect,
8313 Some(DialectType::Spark) | Some(DialectType::Databricks)
8314 )
8315 && ct.as_select.is_none()
8316 {
8317 self.write_space();
8318 self.write_keyword("USING PARQUET");
8319 }
8320
8321 if !ct.inherits.is_empty() {
8323 self.write_space();
8324 self.write_keyword("INHERITS");
8325 self.write(" (");
8326 for (i, parent) in ct.inherits.iter().enumerate() {
8327 if i > 0 {
8328 self.write(", ");
8329 }
8330 self.generate_table(parent)?;
8331 }
8332 self.write(")");
8333 }
8334
8335 if let Some(ref query) = ct.as_select {
8337 self.write_space();
8338 self.write_keyword("AS");
8339 self.write_space();
8340 let source_is_clickhouse =
8341 matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
8342 let wrap_as_select =
8343 ct.as_select_parenthesized && !(is_clickhouse && source_is_clickhouse);
8344 if wrap_as_select {
8345 self.write("(");
8346 }
8347 self.generate_expression(query)?;
8348 if wrap_as_select {
8349 self.write(")");
8350 }
8351
8352 if let Some(with_data) = ct.with_data {
8354 self.write_space();
8355 self.write_keyword("WITH");
8356 if !with_data {
8357 self.write_space();
8358 self.write_keyword("NO");
8359 }
8360 self.write_space();
8361 self.write_keyword("DATA");
8362 }
8363
8364 if let Some(with_statistics) = ct.with_statistics {
8366 self.write_space();
8367 self.write_keyword("AND");
8368 if !with_statistics {
8369 self.write_space();
8370 self.write_keyword("NO");
8371 }
8372 self.write_space();
8373 self.write_keyword("STATISTICS");
8374 }
8375
8376 for index in &ct.teradata_indexes {
8378 self.write_space();
8379 match index.kind {
8380 TeradataIndexKind::NoPrimary => {
8381 self.write_keyword("NO PRIMARY INDEX");
8382 }
8383 TeradataIndexKind::Primary => {
8384 self.write_keyword("PRIMARY INDEX");
8385 }
8386 TeradataIndexKind::PrimaryAmp => {
8387 self.write_keyword("PRIMARY AMP INDEX");
8388 }
8389 TeradataIndexKind::Unique => {
8390 self.write_keyword("UNIQUE INDEX");
8391 }
8392 TeradataIndexKind::UniquePrimary => {
8393 self.write_keyword("UNIQUE PRIMARY INDEX");
8394 }
8395 TeradataIndexKind::Secondary => {
8396 self.write_keyword("INDEX");
8397 }
8398 }
8399 if let Some(ref name) = index.name {
8401 self.write_space();
8402 self.write(name);
8403 }
8404 if !index.columns.is_empty() {
8406 self.write(" (");
8407 for (i, col) in index.columns.iter().enumerate() {
8408 if i > 0 {
8409 self.write(", ");
8410 }
8411 self.write(col);
8412 }
8413 self.write(")");
8414 }
8415 }
8416
8417 if let Some(ref on_commit) = ct.on_commit {
8419 self.write_space();
8420 self.write_keyword("ON COMMIT");
8421 self.write_space();
8422 match on_commit {
8423 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8424 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8425 }
8426 }
8427
8428 if !post_as_properties.is_empty() {
8429 for prop in post_as_properties {
8430 self.write_space();
8431 self.generate_expression(prop)?;
8432 }
8433 }
8434
8435 self.athena_hive_context = saved_athena_hive_context;
8437 return Ok(());
8438 }
8439
8440 if let Some(ref on_commit) = ct.on_commit {
8442 self.write_space();
8443 self.write_keyword("ON COMMIT");
8444 self.write_space();
8445 match on_commit {
8446 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8447 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8448 }
8449 }
8450
8451 self.athena_hive_context = saved_athena_hive_context;
8453
8454 Ok(())
8455 }
8456
8457 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
8460 self.generate_identifier(&col.name)?;
8462 if !matches!(col.data_type, DataType::Unknown) {
8464 self.write_space();
8465 self.generate_data_type(&col.data_type)?;
8466 }
8467 for constraint in &col.constraints {
8469 if let ColumnConstraint::Path(path_expr) = constraint {
8470 self.write_space();
8471 self.write_keyword("PATH");
8472 self.write_space();
8473 self.generate_expression(path_expr)?;
8474 }
8475 }
8476 Ok(())
8477 }
8478
8479 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
8480 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8482 && col
8483 .constraints
8484 .iter()
8485 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8486 let omit_computed_type = !self.config.computed_column_with_type
8488 && col
8489 .constraints
8490 .iter()
8491 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8492
8493 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
8496
8497 let has_no_type = col.no_type
8500 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8501 && col.constraints.is_empty());
8502
8503 self.generate_identifier(&col.name)?;
8504
8505 let serial_expansion = if matches!(
8507 self.config.dialect,
8508 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
8509 ) {
8510 if let DataType::Custom { ref name } = col.data_type {
8511 if name.eq_ignore_ascii_case("SERIAL") {
8512 Some("INT")
8513 } else if name.eq_ignore_ascii_case("BIGSERIAL") {
8514 Some("BIGINT")
8515 } else if name.eq_ignore_ascii_case("SMALLSERIAL") {
8516 Some("SMALLINT")
8517 } else {
8518 None
8519 }
8520 } else {
8521 None
8522 }
8523 } else {
8524 None
8525 };
8526
8527 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
8528 {
8529 self.write_space();
8530 let saved_nullable_depth = self.clickhouse_nullable_depth;
8533 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
8534 self.clickhouse_nullable_depth = -1;
8535 }
8536 if let Some(int_type) = serial_expansion {
8537 self.write_keyword(int_type);
8539 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8540 let unsigned_type = match &col.data_type {
8542 DataType::Int { .. } => Some("UINTEGER"),
8543 DataType::BigInt { .. } => Some("UBIGINT"),
8544 DataType::SmallInt { .. } => Some("USMALLINT"),
8545 DataType::TinyInt { .. } => Some("UTINYINT"),
8546 _ => None,
8547 };
8548 if let Some(utype) = unsigned_type {
8549 self.write_keyword(utype);
8550 } else {
8551 self.generate_data_type(&col.data_type)?;
8552 }
8553 } else {
8554 self.generate_data_type(&col.data_type)?;
8555 }
8556 self.clickhouse_nullable_depth = saved_nullable_depth;
8557 }
8558
8559 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8562 self.write_space();
8563 self.write_keyword("UNSIGNED");
8564 }
8565 if col.zerofill {
8566 self.write_space();
8567 self.write_keyword("ZEROFILL");
8568 }
8569
8570 if let Some(ref charset) = col.character_set {
8574 self.write_space();
8575 self.write_keyword("CHARACTER SET");
8576 self.write_space();
8577 self.write(charset);
8578 }
8579
8580 if col.uppercase {
8581 self.write_space();
8582 self.write_keyword("UPPERCASE");
8583 }
8584
8585 if let Some(casespecific) = col.casespecific {
8586 self.write_space();
8587 if casespecific {
8588 self.write_keyword("CASESPECIFIC");
8589 } else {
8590 self.write_keyword("NOT CASESPECIFIC");
8591 }
8592 }
8593
8594 if let Some(ref format) = col.format {
8595 self.write_space();
8596 self.write_keyword("FORMAT");
8597 self.write(" '");
8598 self.write(format);
8599 self.write("'");
8600 }
8601
8602 if let Some(ref title) = col.title {
8603 self.write_space();
8604 self.write_keyword("TITLE");
8605 self.write(" '");
8606 self.write(title);
8607 self.write("'");
8608 }
8609
8610 if let Some(length) = col.inline_length {
8611 self.write_space();
8612 self.write_keyword("INLINE LENGTH");
8613 self.write(" ");
8614 self.write(&length.to_string());
8615 }
8616
8617 if let Some(ref compress) = col.compress {
8618 self.write_space();
8619 self.write_keyword("COMPRESS");
8620 if !compress.is_empty() {
8621 if compress.len() == 1 {
8623 if let Expression::Literal(lit) = &compress[0] {
8624 if let Literal::String(_) = lit.as_ref() {
8625 self.write_space();
8626 self.generate_expression(&compress[0])?;
8627 }
8628 } else {
8629 self.write(" (");
8630 self.generate_expression(&compress[0])?;
8631 self.write(")");
8632 }
8633 } else {
8634 self.write(" (");
8635 for (i, val) in compress.iter().enumerate() {
8636 if i > 0 {
8637 self.write(", ");
8638 }
8639 self.generate_expression(val)?;
8640 }
8641 self.write(")");
8642 }
8643 }
8644 }
8645
8646 if !col.constraint_order.is_empty() {
8649 let mut references_idx = 0;
8652 let mut check_idx = 0;
8653 let mut generated_idx = 0;
8654 let mut collate_idx = 0;
8655 let mut comment_idx = 0;
8656 let defer_not_null_after_identity = false;
8659 let mut pending_not_null_after_identity = false;
8660
8661 for constraint_type in &col.constraint_order {
8662 match constraint_type {
8663 ConstraintType::PrimaryKey => {
8664 if col.primary_key
8666 && !matches!(self.config.dialect, Some(DialectType::Materialize))
8667 {
8668 if let Some(ref cname) = col.primary_key_constraint_name {
8669 self.write_space();
8670 self.write_keyword("CONSTRAINT");
8671 self.write_space();
8672 self.write(cname);
8673 }
8674 self.write_space();
8675 self.write_keyword("PRIMARY KEY");
8676 if let Some(ref order) = col.primary_key_order {
8677 self.write_space();
8678 match order {
8679 SortOrder::Asc => self.write_keyword("ASC"),
8680 SortOrder::Desc => self.write_keyword("DESC"),
8681 }
8682 }
8683 }
8684 }
8685 ConstraintType::Unique => {
8686 if col.unique {
8687 if let Some(ref cname) = col.unique_constraint_name {
8688 self.write_space();
8689 self.write_keyword("CONSTRAINT");
8690 self.write_space();
8691 self.write(cname);
8692 }
8693 self.write_space();
8694 self.write_keyword("UNIQUE");
8695 if col.unique_nulls_not_distinct {
8697 self.write(" NULLS NOT DISTINCT");
8698 }
8699 }
8700 }
8701 ConstraintType::NotNull => {
8702 if col.nullable == Some(false) {
8703 if defer_not_null_after_identity {
8704 pending_not_null_after_identity = true;
8705 continue;
8706 }
8707 if let Some(ref cname) = col.not_null_constraint_name {
8708 self.write_space();
8709 self.write_keyword("CONSTRAINT");
8710 self.write_space();
8711 self.write(cname);
8712 }
8713 self.write_space();
8714 self.write_keyword("NOT NULL");
8715 }
8716 }
8717 ConstraintType::Null => {
8718 if col.nullable == Some(true) {
8719 self.write_space();
8720 self.write_keyword("NULL");
8721 }
8722 }
8723 ConstraintType::Default => {
8724 if let Some(ref default) = col.default {
8725 self.write_space();
8726 self.write_keyword("DEFAULT");
8727 self.write_space();
8728 self.generate_expression(default)?;
8729 }
8730 }
8731 ConstraintType::AutoIncrement => {
8732 if col.auto_increment {
8733 if matches!(
8735 self.config.dialect,
8736 Some(crate::dialects::DialectType::DuckDB)
8737 ) {
8738 } else if matches!(
8740 self.config.dialect,
8741 Some(crate::dialects::DialectType::Materialize)
8742 ) {
8743 if !matches!(col.nullable, Some(false)) {
8745 self.write_space();
8746 self.write_keyword("NOT NULL");
8747 }
8748 } else if matches!(
8749 self.config.dialect,
8750 Some(crate::dialects::DialectType::PostgreSQL)
8751 ) {
8752 self.write_space();
8754 self.generate_auto_increment_keyword(col)?;
8755 } else {
8756 self.write_space();
8757 self.generate_auto_increment_keyword(col)?;
8758 if pending_not_null_after_identity {
8759 self.write_space();
8760 self.write_keyword("NOT NULL");
8761 pending_not_null_after_identity = false;
8762 }
8763 }
8764 } }
8766 ConstraintType::References => {
8767 while references_idx < col.constraints.len() {
8769 if let ColumnConstraint::References(fk_ref) =
8770 &col.constraints[references_idx]
8771 {
8772 if let Some(ref name) = fk_ref.constraint_name {
8774 self.write_space();
8775 self.write_keyword("CONSTRAINT");
8776 self.write_space();
8777 self.write(name);
8778 }
8779 self.write_space();
8780 if fk_ref.has_foreign_key_keywords {
8781 self.write_keyword("FOREIGN KEY");
8782 self.write_space();
8783 }
8784 self.write_keyword("REFERENCES");
8785 self.write_space();
8786 self.generate_table(&fk_ref.table)?;
8787 if !fk_ref.columns.is_empty() {
8788 self.write(" (");
8789 for (i, c) in fk_ref.columns.iter().enumerate() {
8790 if i > 0 {
8791 self.write(", ");
8792 }
8793 self.generate_identifier(c)?;
8794 }
8795 self.write(")");
8796 }
8797 self.generate_referential_actions(fk_ref)?;
8798 references_idx += 1;
8799 break;
8800 }
8801 references_idx += 1;
8802 }
8803 }
8804 ConstraintType::Check => {
8805 while check_idx < col.constraints.len() {
8807 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
8808 if check_idx == 0 {
8810 if let Some(ref cname) = col.check_constraint_name {
8811 self.write_space();
8812 self.write_keyword("CONSTRAINT");
8813 self.write_space();
8814 self.write(cname);
8815 }
8816 }
8817 self.write_space();
8818 self.write_keyword("CHECK");
8819 self.write(" (");
8820 self.generate_expression(expr)?;
8821 self.write(")");
8822 check_idx += 1;
8823 break;
8824 }
8825 check_idx += 1;
8826 }
8827 }
8828 ConstraintType::GeneratedAsIdentity => {
8829 while generated_idx < col.constraints.len() {
8831 if let ColumnConstraint::GeneratedAsIdentity(gen) =
8832 &col.constraints[generated_idx]
8833 {
8834 self.write_space();
8835 if matches!(
8837 self.config.dialect,
8838 Some(crate::dialects::DialectType::Redshift)
8839 ) {
8840 self.write_keyword("IDENTITY");
8841 self.write("(");
8842 if let Some(ref start) = gen.start {
8843 self.generate_expression(start)?;
8844 } else {
8845 self.write("0");
8846 }
8847 self.write(", ");
8848 if let Some(ref incr) = gen.increment {
8849 self.generate_expression(incr)?;
8850 } else {
8851 self.write("1");
8852 }
8853 self.write(")");
8854 } else {
8855 self.write_keyword("GENERATED");
8856 if gen.always {
8857 self.write_space();
8858 self.write_keyword("ALWAYS");
8859 } else {
8860 self.write_space();
8861 self.write_keyword("BY DEFAULT");
8862 if gen.on_null {
8863 self.write_space();
8864 self.write_keyword("ON NULL");
8865 }
8866 }
8867 self.write_space();
8868 self.write_keyword("AS IDENTITY");
8869
8870 let has_options = gen.start.is_some()
8871 || gen.increment.is_some()
8872 || gen.minvalue.is_some()
8873 || gen.maxvalue.is_some()
8874 || gen.cycle.is_some();
8875 if has_options {
8876 self.write(" (");
8877 let mut first = true;
8878 if let Some(ref start) = gen.start {
8879 if !first {
8880 self.write(" ");
8881 }
8882 first = false;
8883 self.write_keyword("START WITH");
8884 self.write_space();
8885 self.generate_expression(start)?;
8886 }
8887 if let Some(ref incr) = gen.increment {
8888 if !first {
8889 self.write(" ");
8890 }
8891 first = false;
8892 self.write_keyword("INCREMENT BY");
8893 self.write_space();
8894 self.generate_expression(incr)?;
8895 }
8896 if let Some(ref minv) = gen.minvalue {
8897 if !first {
8898 self.write(" ");
8899 }
8900 first = false;
8901 self.write_keyword("MINVALUE");
8902 self.write_space();
8903 self.generate_expression(minv)?;
8904 }
8905 if let Some(ref maxv) = gen.maxvalue {
8906 if !first {
8907 self.write(" ");
8908 }
8909 first = false;
8910 self.write_keyword("MAXVALUE");
8911 self.write_space();
8912 self.generate_expression(maxv)?;
8913 }
8914 if let Some(cycle) = gen.cycle {
8915 if !first {
8916 self.write(" ");
8917 }
8918 if cycle {
8919 self.write_keyword("CYCLE");
8920 } else {
8921 self.write_keyword("NO CYCLE");
8922 }
8923 }
8924 self.write(")");
8925 }
8926 }
8927 generated_idx += 1;
8928 break;
8929 }
8930 generated_idx += 1;
8931 }
8932 }
8933 ConstraintType::Collate => {
8934 while collate_idx < col.constraints.len() {
8936 if let ColumnConstraint::Collate(collation) =
8937 &col.constraints[collate_idx]
8938 {
8939 self.write_space();
8940 self.write_keyword("COLLATE");
8941 self.write_space();
8942 self.generate_identifier(collation)?;
8943 collate_idx += 1;
8944 break;
8945 }
8946 collate_idx += 1;
8947 }
8948 }
8949 ConstraintType::Comment => {
8950 while comment_idx < col.constraints.len() {
8952 if let ColumnConstraint::Comment(comment) =
8953 &col.constraints[comment_idx]
8954 {
8955 self.write_space();
8956 self.write_keyword("COMMENT");
8957 self.write_space();
8958 self.generate_string_literal(comment)?;
8959 comment_idx += 1;
8960 break;
8961 }
8962 comment_idx += 1;
8963 }
8964 }
8965 ConstraintType::Tags => {
8966 for constraint in &col.constraints {
8968 if let ColumnConstraint::Tags(tags) = constraint {
8969 self.write_space();
8970 self.write_keyword("TAG");
8971 self.write(" (");
8972 for (i, expr) in tags.expressions.iter().enumerate() {
8973 if i > 0 {
8974 self.write(", ");
8975 }
8976 self.generate_expression(expr)?;
8977 }
8978 self.write(")");
8979 break;
8980 }
8981 }
8982 }
8983 ConstraintType::ComputedColumn => {
8984 for constraint in &col.constraints {
8986 if let ColumnConstraint::ComputedColumn(cc) = constraint {
8987 self.write_space();
8988 self.generate_computed_column_inline(cc)?;
8989 break;
8990 }
8991 }
8992 }
8993 ConstraintType::GeneratedAsRow => {
8994 for constraint in &col.constraints {
8996 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
8997 self.write_space();
8998 self.generate_generated_as_row_inline(gar)?;
8999 break;
9000 }
9001 }
9002 }
9003 ConstraintType::OnUpdate => {
9004 if let Some(ref expr) = col.on_update {
9005 self.write_space();
9006 self.write_keyword("ON UPDATE");
9007 self.write_space();
9008 self.generate_expression(expr)?;
9009 }
9010 }
9011 ConstraintType::Encode => {
9012 if let Some(ref encoding) = col.encoding {
9013 self.write_space();
9014 self.write_keyword("ENCODE");
9015 self.write_space();
9016 self.write(encoding);
9017 }
9018 }
9019 ConstraintType::Path => {
9020 for constraint in &col.constraints {
9022 if let ColumnConstraint::Path(path_expr) = constraint {
9023 self.write_space();
9024 self.write_keyword("PATH");
9025 self.write_space();
9026 self.generate_expression(path_expr)?;
9027 break;
9028 }
9029 }
9030 }
9031 }
9032 }
9033 if pending_not_null_after_identity {
9034 self.write_space();
9035 self.write_keyword("NOT NULL");
9036 }
9037 } else {
9038 if col.primary_key {
9040 self.write_space();
9041 self.write_keyword("PRIMARY KEY");
9042 if let Some(ref order) = col.primary_key_order {
9043 self.write_space();
9044 match order {
9045 SortOrder::Asc => self.write_keyword("ASC"),
9046 SortOrder::Desc => self.write_keyword("DESC"),
9047 }
9048 }
9049 }
9050
9051 if col.unique {
9052 self.write_space();
9053 self.write_keyword("UNIQUE");
9054 if col.unique_nulls_not_distinct {
9056 self.write(" NULLS NOT DISTINCT");
9057 }
9058 }
9059
9060 match col.nullable {
9061 Some(false) => {
9062 self.write_space();
9063 self.write_keyword("NOT NULL");
9064 }
9065 Some(true) => {
9066 self.write_space();
9067 self.write_keyword("NULL");
9068 }
9069 None => {}
9070 }
9071
9072 if let Some(ref default) = col.default {
9073 self.write_space();
9074 self.write_keyword("DEFAULT");
9075 self.write_space();
9076 self.generate_expression(default)?;
9077 }
9078
9079 if col.auto_increment {
9080 self.write_space();
9081 self.generate_auto_increment_keyword(col)?;
9082 }
9083
9084 for constraint in &col.constraints {
9086 match constraint {
9087 ColumnConstraint::References(fk_ref) => {
9088 self.write_space();
9089 if fk_ref.has_foreign_key_keywords {
9090 self.write_keyword("FOREIGN KEY");
9091 self.write_space();
9092 }
9093 self.write_keyword("REFERENCES");
9094 self.write_space();
9095 self.generate_table(&fk_ref.table)?;
9096 if !fk_ref.columns.is_empty() {
9097 self.write(" (");
9098 for (i, c) in fk_ref.columns.iter().enumerate() {
9099 if i > 0 {
9100 self.write(", ");
9101 }
9102 self.generate_identifier(c)?;
9103 }
9104 self.write(")");
9105 }
9106 self.generate_referential_actions(fk_ref)?;
9107 }
9108 ColumnConstraint::Check(expr) => {
9109 self.write_space();
9110 self.write_keyword("CHECK");
9111 self.write(" (");
9112 self.generate_expression(expr)?;
9113 self.write(")");
9114 }
9115 ColumnConstraint::GeneratedAsIdentity(gen) => {
9116 self.write_space();
9117 if matches!(
9119 self.config.dialect,
9120 Some(crate::dialects::DialectType::Redshift)
9121 ) {
9122 self.write_keyword("IDENTITY");
9123 self.write("(");
9124 if let Some(ref start) = gen.start {
9125 self.generate_expression(start)?;
9126 } else {
9127 self.write("0");
9128 }
9129 self.write(", ");
9130 if let Some(ref incr) = gen.increment {
9131 self.generate_expression(incr)?;
9132 } else {
9133 self.write("1");
9134 }
9135 self.write(")");
9136 } else {
9137 self.write_keyword("GENERATED");
9138 if gen.always {
9139 self.write_space();
9140 self.write_keyword("ALWAYS");
9141 } else {
9142 self.write_space();
9143 self.write_keyword("BY DEFAULT");
9144 if gen.on_null {
9145 self.write_space();
9146 self.write_keyword("ON NULL");
9147 }
9148 }
9149 self.write_space();
9150 self.write_keyword("AS IDENTITY");
9151
9152 let has_options = gen.start.is_some()
9153 || gen.increment.is_some()
9154 || gen.minvalue.is_some()
9155 || gen.maxvalue.is_some()
9156 || gen.cycle.is_some();
9157 if has_options {
9158 self.write(" (");
9159 let mut first = true;
9160 if let Some(ref start) = gen.start {
9161 if !first {
9162 self.write(" ");
9163 }
9164 first = false;
9165 self.write_keyword("START WITH");
9166 self.write_space();
9167 self.generate_expression(start)?;
9168 }
9169 if let Some(ref incr) = gen.increment {
9170 if !first {
9171 self.write(" ");
9172 }
9173 first = false;
9174 self.write_keyword("INCREMENT BY");
9175 self.write_space();
9176 self.generate_expression(incr)?;
9177 }
9178 if let Some(ref minv) = gen.minvalue {
9179 if !first {
9180 self.write(" ");
9181 }
9182 first = false;
9183 self.write_keyword("MINVALUE");
9184 self.write_space();
9185 self.generate_expression(minv)?;
9186 }
9187 if let Some(ref maxv) = gen.maxvalue {
9188 if !first {
9189 self.write(" ");
9190 }
9191 first = false;
9192 self.write_keyword("MAXVALUE");
9193 self.write_space();
9194 self.generate_expression(maxv)?;
9195 }
9196 if let Some(cycle) = gen.cycle {
9197 if !first {
9198 self.write(" ");
9199 }
9200 if cycle {
9201 self.write_keyword("CYCLE");
9202 } else {
9203 self.write_keyword("NO CYCLE");
9204 }
9205 }
9206 self.write(")");
9207 }
9208 }
9209 }
9210 ColumnConstraint::Collate(collation) => {
9211 self.write_space();
9212 self.write_keyword("COLLATE");
9213 self.write_space();
9214 self.generate_identifier(collation)?;
9215 }
9216 ColumnConstraint::Comment(comment) => {
9217 self.write_space();
9218 self.write_keyword("COMMENT");
9219 self.write_space();
9220 self.generate_string_literal(comment)?;
9221 }
9222 ColumnConstraint::Path(path_expr) => {
9223 self.write_space();
9224 self.write_keyword("PATH");
9225 self.write_space();
9226 self.generate_expression(path_expr)?;
9227 }
9228 _ => {} }
9230 }
9231
9232 if let Some(ref encoding) = col.encoding {
9234 self.write_space();
9235 self.write_keyword("ENCODE");
9236 self.write_space();
9237 self.write(encoding);
9238 }
9239 }
9240
9241 if let Some(ref codec) = col.codec {
9243 self.write_space();
9244 self.write_keyword("CODEC");
9245 self.write("(");
9246 self.write(codec);
9247 self.write(")");
9248 }
9249
9250 if let Some(visible) = col.visible {
9251 self.write_space();
9252 if visible {
9253 self.write_keyword("VISIBLE");
9254 } else {
9255 self.write_keyword("INVISIBLE");
9256 }
9257 }
9258
9259 if let Some(ref ephemeral) = col.ephemeral {
9261 self.write_space();
9262 self.write_keyword("EPHEMERAL");
9263 if let Some(ref expr) = ephemeral {
9264 self.write_space();
9265 self.generate_expression(expr)?;
9266 }
9267 }
9268
9269 if let Some(ref mat_expr) = col.materialized_expr {
9271 self.write_space();
9272 self.write_keyword("MATERIALIZED");
9273 self.write_space();
9274 self.generate_expression(mat_expr)?;
9275 }
9276
9277 if let Some(ref alias_expr) = col.alias_expr {
9279 self.write_space();
9280 self.write_keyword("ALIAS");
9281 self.write_space();
9282 self.generate_expression(alias_expr)?;
9283 }
9284
9285 if let Some(ref ttl_expr) = col.ttl_expr {
9287 self.write_space();
9288 self.write_keyword("TTL");
9289 self.write_space();
9290 self.generate_expression(ttl_expr)?;
9291 }
9292
9293 if col.not_for_replication
9295 && matches!(
9296 self.config.dialect,
9297 Some(crate::dialects::DialectType::TSQL)
9298 | Some(crate::dialects::DialectType::Fabric)
9299 )
9300 {
9301 self.write_space();
9302 self.write_keyword("NOT FOR REPLICATION");
9303 }
9304
9305 if !col.options.is_empty() {
9307 self.write_space();
9308 self.generate_options_clause(&col.options)?;
9309 }
9310
9311 if !col.primary_key
9314 && self
9315 .sqlite_inline_pk_columns
9316 .contains(&col.name.name.to_ascii_lowercase())
9317 {
9318 self.write_space();
9319 self.write_keyword("PRIMARY KEY");
9320 }
9321
9322 if serial_expansion.is_some() {
9325 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
9326 self.write_space();
9327 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
9328 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
9329 self.write_space();
9330 self.write_keyword("NOT NULL");
9331 }
9332 }
9333
9334 Ok(())
9335 }
9336
9337 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
9338 match constraint {
9339 TableConstraint::PrimaryKey {
9340 name,
9341 columns,
9342 include_columns,
9343 modifiers,
9344 has_constraint_keyword,
9345 } => {
9346 if let Some(ref n) = name {
9347 if *has_constraint_keyword {
9348 self.write_keyword("CONSTRAINT");
9349 self.write_space();
9350 self.generate_identifier(n)?;
9351 self.write_space();
9352 }
9353 }
9354 self.write_keyword("PRIMARY KEY");
9355 if let Some(ref clustered) = modifiers.clustered {
9357 self.write_space();
9358 self.write_keyword(clustered);
9359 }
9360 if let Some(ref n) = name {
9362 if !*has_constraint_keyword {
9363 self.write_space();
9364 self.generate_identifier(n)?;
9365 }
9366 }
9367 self.write(" (");
9368 for (i, col) in columns.iter().enumerate() {
9369 if i > 0 {
9370 self.write(", ");
9371 }
9372 self.generate_identifier(col)?;
9373 }
9374 self.write(")");
9375 if !include_columns.is_empty() {
9376 self.write_space();
9377 self.write_keyword("INCLUDE");
9378 self.write(" (");
9379 for (i, col) in include_columns.iter().enumerate() {
9380 if i > 0 {
9381 self.write(", ");
9382 }
9383 self.generate_identifier(col)?;
9384 }
9385 self.write(")");
9386 }
9387 self.generate_constraint_modifiers(modifiers);
9388 }
9389 TableConstraint::Unique {
9390 name,
9391 columns,
9392 columns_parenthesized,
9393 modifiers,
9394 has_constraint_keyword,
9395 nulls_not_distinct,
9396 } => {
9397 if let Some(ref n) = name {
9398 if *has_constraint_keyword {
9399 self.write_keyword("CONSTRAINT");
9400 self.write_space();
9401 self.generate_identifier(n)?;
9402 self.write_space();
9403 }
9404 }
9405 self.write_keyword("UNIQUE");
9406 if let Some(ref clustered) = modifiers.clustered {
9408 self.write_space();
9409 self.write_keyword(clustered);
9410 }
9411 if *nulls_not_distinct {
9413 self.write(" NULLS NOT DISTINCT");
9414 }
9415 if let Some(ref n) = name {
9417 if !*has_constraint_keyword {
9418 self.write_space();
9419 self.generate_identifier(n)?;
9420 }
9421 }
9422 if *columns_parenthesized {
9423 self.write(" (");
9424 for (i, col) in columns.iter().enumerate() {
9425 if i > 0 {
9426 self.write(", ");
9427 }
9428 self.generate_identifier(col)?;
9429 }
9430 self.write(")");
9431 } else {
9432 for col in columns.iter() {
9434 self.write_space();
9435 self.generate_identifier(col)?;
9436 }
9437 }
9438 self.generate_constraint_modifiers(modifiers);
9439 }
9440 TableConstraint::ForeignKey {
9441 name,
9442 columns,
9443 references,
9444 on_delete,
9445 on_update,
9446 modifiers,
9447 } => {
9448 if let Some(ref n) = name {
9449 self.write_keyword("CONSTRAINT");
9450 self.write_space();
9451 self.generate_identifier(n)?;
9452 self.write_space();
9453 }
9454 self.write_keyword("FOREIGN KEY");
9455 self.write(" (");
9456 for (i, col) in columns.iter().enumerate() {
9457 if i > 0 {
9458 self.write(", ");
9459 }
9460 self.generate_identifier(col)?;
9461 }
9462 self.write(")");
9463 if let Some(ref refs) = references {
9464 self.write(" ");
9465 self.write_keyword("REFERENCES");
9466 self.write_space();
9467 self.generate_table(&refs.table)?;
9468 if !refs.columns.is_empty() {
9469 if self.config.pretty {
9470 self.write(" (");
9471 self.write_newline();
9472 self.indent_level += 1;
9473 for (i, col) in refs.columns.iter().enumerate() {
9474 if i > 0 {
9475 self.write(",");
9476 self.write_newline();
9477 }
9478 self.write_indent();
9479 self.generate_identifier(col)?;
9480 }
9481 self.indent_level -= 1;
9482 self.write_newline();
9483 self.write_indent();
9484 self.write(")");
9485 } else {
9486 self.write(" (");
9487 for (i, col) in refs.columns.iter().enumerate() {
9488 if i > 0 {
9489 self.write(", ");
9490 }
9491 self.generate_identifier(col)?;
9492 }
9493 self.write(")");
9494 }
9495 }
9496 self.generate_referential_actions(refs)?;
9497 } else {
9498 if let Some(ref action) = on_delete {
9500 self.write_space();
9501 self.write_keyword("ON DELETE");
9502 self.write_space();
9503 self.generate_referential_action(action);
9504 }
9505 if let Some(ref action) = on_update {
9506 self.write_space();
9507 self.write_keyword("ON UPDATE");
9508 self.write_space();
9509 self.generate_referential_action(action);
9510 }
9511 }
9512 self.generate_constraint_modifiers(modifiers);
9513 }
9514 TableConstraint::Check {
9515 name,
9516 expression,
9517 modifiers,
9518 } => {
9519 if let Some(ref n) = name {
9520 self.write_keyword("CONSTRAINT");
9521 self.write_space();
9522 self.generate_identifier(n)?;
9523 self.write_space();
9524 }
9525 self.write_keyword("CHECK");
9526 self.write(" (");
9527 self.generate_expression(expression)?;
9528 self.write(")");
9529 self.generate_constraint_modifiers(modifiers);
9530 }
9531 TableConstraint::Assume { name, expression } => {
9532 if let Some(ref n) = name {
9533 self.write_keyword("CONSTRAINT");
9534 self.write_space();
9535 self.generate_identifier(n)?;
9536 self.write_space();
9537 }
9538 self.write_keyword("ASSUME");
9539 self.write(" (");
9540 self.generate_expression(expression)?;
9541 self.write(")");
9542 }
9543 TableConstraint::Default {
9544 name,
9545 expression,
9546 column,
9547 } => {
9548 if let Some(ref n) = name {
9549 self.write_keyword("CONSTRAINT");
9550 self.write_space();
9551 self.generate_identifier(n)?;
9552 self.write_space();
9553 }
9554 self.write_keyword("DEFAULT");
9555 self.write_space();
9556 self.generate_expression(expression)?;
9557 self.write_space();
9558 self.write_keyword("FOR");
9559 self.write_space();
9560 self.generate_identifier(column)?;
9561 }
9562 TableConstraint::Index {
9563 name,
9564 columns,
9565 kind,
9566 modifiers,
9567 use_key_keyword,
9568 expression,
9569 index_type,
9570 granularity,
9571 } => {
9572 if expression.is_some() {
9574 self.write_keyword("INDEX");
9575 if let Some(ref n) = name {
9576 self.write_space();
9577 self.generate_identifier(n)?;
9578 }
9579 if let Some(ref expr) = expression {
9580 self.write_space();
9581 self.generate_expression(expr)?;
9582 }
9583 if let Some(ref idx_type) = index_type {
9584 self.write_space();
9585 self.write_keyword("TYPE");
9586 self.write_space();
9587 self.generate_expression(idx_type)?;
9588 }
9589 if let Some(ref gran) = granularity {
9590 self.write_space();
9591 self.write_keyword("GRANULARITY");
9592 self.write_space();
9593 self.generate_expression(gran)?;
9594 }
9595 } else {
9596 use crate::dialects::DialectType;
9600 let index_keyword = if *use_key_keyword
9601 && !matches!(self.config.dialect, Some(DialectType::MySQL))
9602 {
9603 "KEY"
9604 } else {
9605 "INDEX"
9606 };
9607
9608 if let Some(ref k) = kind {
9610 self.write_keyword(k);
9611 if k != "UNIQUE" {
9613 self.write_space();
9614 self.write_keyword(index_keyword);
9615 }
9616 } else {
9617 self.write_keyword(index_keyword);
9618 }
9619
9620 if modifiers.using_before_columns && name.is_none() {
9622 if let Some(ref using) = modifiers.using {
9623 self.write_space();
9624 self.write_keyword("USING");
9625 self.write_space();
9626 self.write_keyword(using);
9627 }
9628 }
9629
9630 if let Some(ref n) = name {
9632 self.write_space();
9633 self.generate_identifier(n)?;
9634 }
9635
9636 if modifiers.using_before_columns && name.is_some() {
9638 if let Some(ref using) = modifiers.using {
9639 self.write_space();
9640 self.write_keyword("USING");
9641 self.write_space();
9642 self.write_keyword(using);
9643 }
9644 }
9645
9646 self.write(" (");
9648 for (i, col) in columns.iter().enumerate() {
9649 if i > 0 {
9650 self.write(", ");
9651 }
9652 self.generate_identifier(col)?;
9653 }
9654 self.write(")");
9655
9656 if !modifiers.using_before_columns {
9658 if let Some(ref using) = modifiers.using {
9659 self.write_space();
9660 self.write_keyword("USING");
9661 self.write_space();
9662 self.write_keyword(using);
9663 }
9664 }
9665
9666 self.generate_constraint_modifiers_without_using(modifiers);
9668 }
9669 }
9670 TableConstraint::Projection { name, expression } => {
9671 self.write_keyword("PROJECTION");
9673 self.write_space();
9674 self.generate_identifier(name)?;
9675 self.write(" (");
9676 self.generate_expression(expression)?;
9677 self.write(")");
9678 }
9679 TableConstraint::Like { source, options } => {
9680 self.write_keyword("LIKE");
9681 self.write_space();
9682 self.generate_table(source)?;
9683 for (action, prop) in options {
9684 self.write_space();
9685 match action {
9686 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
9687 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
9688 }
9689 self.write_space();
9690 self.write_keyword(prop);
9691 }
9692 }
9693 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
9694 self.write_keyword("PERIOD FOR SYSTEM_TIME");
9695 self.write(" (");
9696 self.generate_identifier(start_col)?;
9697 self.write(", ");
9698 self.generate_identifier(end_col)?;
9699 self.write(")");
9700 }
9701 TableConstraint::Exclude {
9702 name,
9703 using,
9704 elements,
9705 include_columns,
9706 where_clause,
9707 with_params,
9708 using_index_tablespace,
9709 modifiers: _,
9710 } => {
9711 if let Some(ref n) = name {
9712 self.write_keyword("CONSTRAINT");
9713 self.write_space();
9714 self.generate_identifier(n)?;
9715 self.write_space();
9716 }
9717 self.write_keyword("EXCLUDE");
9718 if let Some(ref method) = using {
9719 self.write_space();
9720 self.write_keyword("USING");
9721 self.write_space();
9722 self.write(method);
9723 self.write("(");
9724 } else {
9725 self.write(" (");
9726 }
9727 for (i, elem) in elements.iter().enumerate() {
9728 if i > 0 {
9729 self.write(", ");
9730 }
9731 self.write(&elem.expression);
9732 self.write_space();
9733 self.write_keyword("WITH");
9734 self.write_space();
9735 self.write(&elem.operator);
9736 }
9737 self.write(")");
9738 if !include_columns.is_empty() {
9739 self.write_space();
9740 self.write_keyword("INCLUDE");
9741 self.write(" (");
9742 for (i, col) in include_columns.iter().enumerate() {
9743 if i > 0 {
9744 self.write(", ");
9745 }
9746 self.generate_identifier(col)?;
9747 }
9748 self.write(")");
9749 }
9750 if !with_params.is_empty() {
9751 self.write_space();
9752 self.write_keyword("WITH");
9753 self.write(" (");
9754 for (i, (key, val)) in with_params.iter().enumerate() {
9755 if i > 0 {
9756 self.write(", ");
9757 }
9758 self.write(key);
9759 self.write("=");
9760 self.write(val);
9761 }
9762 self.write(")");
9763 }
9764 if let Some(ref tablespace) = using_index_tablespace {
9765 self.write_space();
9766 self.write_keyword("USING INDEX TABLESPACE");
9767 self.write_space();
9768 self.write(tablespace);
9769 }
9770 if let Some(ref where_expr) = where_clause {
9771 self.write_space();
9772 self.write_keyword("WHERE");
9773 self.write(" (");
9774 self.generate_expression(where_expr)?;
9775 self.write(")");
9776 }
9777 }
9778 TableConstraint::Tags(tags) => {
9779 self.write_keyword("TAG");
9780 self.write(" (");
9781 for (i, expr) in tags.expressions.iter().enumerate() {
9782 if i > 0 {
9783 self.write(", ");
9784 }
9785 self.generate_expression(expr)?;
9786 }
9787 self.write(")");
9788 }
9789 TableConstraint::InitiallyDeferred { deferred } => {
9790 self.write_keyword("INITIALLY");
9791 self.write_space();
9792 if *deferred {
9793 self.write_keyword("DEFERRED");
9794 } else {
9795 self.write_keyword("IMMEDIATE");
9796 }
9797 }
9798 }
9799 Ok(())
9800 }
9801
9802 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9803 if let Some(using) = &modifiers.using {
9805 self.write_space();
9806 self.write_keyword("USING");
9807 self.write_space();
9808 self.write_keyword(using);
9809 }
9810 if let Some(enforced) = modifiers.enforced {
9812 self.write_space();
9813 if enforced {
9814 self.write_keyword("ENFORCED");
9815 } else {
9816 self.write_keyword("NOT ENFORCED");
9817 }
9818 }
9819 if let Some(deferrable) = modifiers.deferrable {
9821 self.write_space();
9822 if deferrable {
9823 self.write_keyword("DEFERRABLE");
9824 } else {
9825 self.write_keyword("NOT DEFERRABLE");
9826 }
9827 }
9828 if let Some(initially_deferred) = modifiers.initially_deferred {
9830 self.write_space();
9831 if initially_deferred {
9832 self.write_keyword("INITIALLY DEFERRED");
9833 } else {
9834 self.write_keyword("INITIALLY IMMEDIATE");
9835 }
9836 }
9837 if modifiers.norely {
9839 self.write_space();
9840 self.write_keyword("NORELY");
9841 }
9842 if modifiers.rely {
9844 self.write_space();
9845 self.write_keyword("RELY");
9846 }
9847 if modifiers.not_valid {
9849 self.write_space();
9850 self.write_keyword("NOT VALID");
9851 }
9852 if let Some(on_conflict) = &modifiers.on_conflict {
9854 self.write_space();
9855 self.write_keyword("ON CONFLICT");
9856 self.write_space();
9857 self.write_keyword(on_conflict);
9858 }
9859 if !modifiers.with_options.is_empty() {
9861 self.write_space();
9862 self.write_keyword("WITH");
9863 self.write(" (");
9864 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
9865 if i > 0 {
9866 self.write(", ");
9867 }
9868 self.write(key);
9869 self.write("=");
9870 self.write(value);
9871 }
9872 self.write(")");
9873 }
9874 if let Some(ref fg) = modifiers.on_filegroup {
9876 self.write_space();
9877 self.write_keyword("ON");
9878 self.write_space();
9879 let _ = self.generate_identifier(fg);
9880 }
9881 }
9882
9883 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
9885 if let Some(enforced) = modifiers.enforced {
9887 self.write_space();
9888 if enforced {
9889 self.write_keyword("ENFORCED");
9890 } else {
9891 self.write_keyword("NOT ENFORCED");
9892 }
9893 }
9894 if let Some(deferrable) = modifiers.deferrable {
9896 self.write_space();
9897 if deferrable {
9898 self.write_keyword("DEFERRABLE");
9899 } else {
9900 self.write_keyword("NOT DEFERRABLE");
9901 }
9902 }
9903 if let Some(initially_deferred) = modifiers.initially_deferred {
9905 self.write_space();
9906 if initially_deferred {
9907 self.write_keyword("INITIALLY DEFERRED");
9908 } else {
9909 self.write_keyword("INITIALLY IMMEDIATE");
9910 }
9911 }
9912 if modifiers.norely {
9914 self.write_space();
9915 self.write_keyword("NORELY");
9916 }
9917 if modifiers.rely {
9919 self.write_space();
9920 self.write_keyword("RELY");
9921 }
9922 if modifiers.not_valid {
9924 self.write_space();
9925 self.write_keyword("NOT VALID");
9926 }
9927 if let Some(on_conflict) = &modifiers.on_conflict {
9929 self.write_space();
9930 self.write_keyword("ON CONFLICT");
9931 self.write_space();
9932 self.write_keyword(on_conflict);
9933 }
9934 self.generate_index_specific_modifiers(modifiers);
9936 }
9937
9938 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9940 if let Some(ref comment) = modifiers.comment {
9941 self.write_space();
9942 self.write_keyword("COMMENT");
9943 self.write(" '");
9944 self.write(comment);
9945 self.write("'");
9946 }
9947 if let Some(visible) = modifiers.visible {
9948 self.write_space();
9949 if visible {
9950 self.write_keyword("VISIBLE");
9951 } else {
9952 self.write_keyword("INVISIBLE");
9953 }
9954 }
9955 if let Some(ref attr) = modifiers.engine_attribute {
9956 self.write_space();
9957 self.write_keyword("ENGINE_ATTRIBUTE");
9958 self.write(" = '");
9959 self.write(attr);
9960 self.write("'");
9961 }
9962 if let Some(ref parser) = modifiers.with_parser {
9963 self.write_space();
9964 self.write_keyword("WITH PARSER");
9965 self.write_space();
9966 self.write(parser);
9967 }
9968 }
9969
9970 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
9971 if !fk_ref.match_after_actions {
9973 if let Some(ref match_type) = fk_ref.match_type {
9974 self.write_space();
9975 self.write_keyword("MATCH");
9976 self.write_space();
9977 match match_type {
9978 MatchType::Full => self.write_keyword("FULL"),
9979 MatchType::Partial => self.write_keyword("PARTIAL"),
9980 MatchType::Simple => self.write_keyword("SIMPLE"),
9981 }
9982 }
9983 }
9984
9985 if fk_ref.on_update_first {
9987 if let Some(ref action) = fk_ref.on_update {
9988 self.write_space();
9989 self.write_keyword("ON UPDATE");
9990 self.write_space();
9991 self.generate_referential_action(action);
9992 }
9993 if let Some(ref action) = fk_ref.on_delete {
9994 self.write_space();
9995 self.write_keyword("ON DELETE");
9996 self.write_space();
9997 self.generate_referential_action(action);
9998 }
9999 } else {
10000 if let Some(ref action) = fk_ref.on_delete {
10001 self.write_space();
10002 self.write_keyword("ON DELETE");
10003 self.write_space();
10004 self.generate_referential_action(action);
10005 }
10006 if let Some(ref action) = fk_ref.on_update {
10007 self.write_space();
10008 self.write_keyword("ON UPDATE");
10009 self.write_space();
10010 self.generate_referential_action(action);
10011 }
10012 }
10013
10014 if fk_ref.match_after_actions {
10016 if let Some(ref match_type) = fk_ref.match_type {
10017 self.write_space();
10018 self.write_keyword("MATCH");
10019 self.write_space();
10020 match match_type {
10021 MatchType::Full => self.write_keyword("FULL"),
10022 MatchType::Partial => self.write_keyword("PARTIAL"),
10023 MatchType::Simple => self.write_keyword("SIMPLE"),
10024 }
10025 }
10026 }
10027
10028 if let Some(deferrable) = fk_ref.deferrable {
10030 self.write_space();
10031 if deferrable {
10032 self.write_keyword("DEFERRABLE");
10033 } else {
10034 self.write_keyword("NOT DEFERRABLE");
10035 }
10036 }
10037
10038 Ok(())
10039 }
10040
10041 fn generate_referential_action(&mut self, action: &ReferentialAction) {
10042 match action {
10043 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
10044 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
10045 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
10046 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
10047 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
10048 }
10049 }
10050
10051 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
10052 if let Some(ref object_id_args) = dt.object_id_args {
10054 if matches!(
10055 self.config.dialect,
10056 Some(crate::dialects::DialectType::TSQL)
10057 | Some(crate::dialects::DialectType::Fabric)
10058 ) {
10059 self.write_keyword("IF NOT OBJECT_ID");
10060 self.write("(");
10061 self.write(object_id_args);
10062 self.write(")");
10063 self.write_space();
10064 self.write_keyword("IS NULL BEGIN DROP TABLE");
10065 self.write_space();
10066 for (i, table) in dt.names.iter().enumerate() {
10067 if i > 0 {
10068 self.write(", ");
10069 }
10070 self.generate_table(table)?;
10071 }
10072 self.write("; ");
10073 self.write_keyword("END");
10074 return Ok(());
10075 }
10076 }
10077
10078 let saved_athena_hive_context = self.athena_hive_context;
10080 if matches!(
10081 self.config.dialect,
10082 Some(crate::dialects::DialectType::Athena)
10083 ) {
10084 self.athena_hive_context = true;
10085 }
10086
10087 for comment in &dt.leading_comments {
10089 self.write_formatted_comment(comment);
10090 self.write_space();
10091 }
10092 if dt.iceberg {
10093 self.write_keyword("DROP ICEBERG TABLE");
10094 } else {
10095 self.write_keyword("DROP TABLE");
10096 }
10097
10098 if dt.if_exists {
10099 self.write_space();
10100 self.write_keyword("IF EXISTS");
10101 }
10102
10103 self.write_space();
10104 for (i, table) in dt.names.iter().enumerate() {
10105 if i > 0 {
10106 self.write(", ");
10107 }
10108 self.generate_table(table)?;
10109 }
10110
10111 if dt.cascade_constraints {
10112 self.write_space();
10113 self.write_keyword("CASCADE CONSTRAINTS");
10114 } else if dt.cascade {
10115 self.write_space();
10116 self.write_keyword("CASCADE");
10117 }
10118
10119 if dt.restrict {
10120 self.write_space();
10121 self.write_keyword("RESTRICT");
10122 }
10123
10124 if dt.purge {
10125 self.write_space();
10126 self.write_keyword("PURGE");
10127 }
10128
10129 if dt.sync {
10130 self.write_space();
10131 self.write_keyword("SYNC");
10132 }
10133
10134 self.athena_hive_context = saved_athena_hive_context;
10136
10137 Ok(())
10138 }
10139
10140 fn generate_undrop(&mut self, u: &Undrop) -> Result<()> {
10141 self.write_keyword("UNDROP");
10142 self.write_space();
10143 self.write_keyword(&u.kind);
10144 if u.if_exists {
10145 self.write_space();
10146 self.write_keyword("IF EXISTS");
10147 }
10148 self.write_space();
10149 self.generate_table(&u.name)?;
10150 Ok(())
10151 }
10152
10153 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
10154 let saved_athena_hive_context = self.athena_hive_context;
10156 if matches!(
10157 self.config.dialect,
10158 Some(crate::dialects::DialectType::Athena)
10159 ) {
10160 self.athena_hive_context = true;
10161 }
10162
10163 self.write_keyword("ALTER");
10164 if let Some(ref modifier) = at.table_modifier {
10166 if !matches!(
10167 self.config.dialect,
10168 Some(crate::dialects::DialectType::DuckDB)
10169 ) {
10170 self.write_space();
10171 self.write_keyword(modifier);
10172 }
10173 }
10174 self.write(" ");
10175 self.write_keyword("TABLE");
10176 if at.if_exists {
10177 self.write_space();
10178 self.write_keyword("IF EXISTS");
10179 }
10180 self.write_space();
10181 self.generate_table(&at.name)?;
10182
10183 if let Some(ref on_cluster) = at.on_cluster {
10185 self.write_space();
10186 self.generate_on_cluster(on_cluster)?;
10187 }
10188
10189 if let Some(ref partition) = at.partition {
10191 self.write_space();
10192 self.write_keyword("PARTITION");
10193 self.write("(");
10194 for (i, (key, value)) in partition.iter().enumerate() {
10195 if i > 0 {
10196 self.write(", ");
10197 }
10198 self.generate_identifier(key)?;
10199 self.write(" = ");
10200 self.generate_expression(value)?;
10201 }
10202 self.write(")");
10203 }
10204
10205 if let Some(ref with_check) = at.with_check {
10207 self.write_space();
10208 self.write_keyword(with_check);
10209 }
10210
10211 if self.config.pretty {
10212 self.write_newline();
10214 self.indent_level += 1;
10215 for (i, action) in at.actions.iter().enumerate() {
10216 let is_continuation = i > 0
10218 && matches!(
10219 (&at.actions[i - 1], action),
10220 (
10221 AlterTableAction::AddColumn { .. },
10222 AlterTableAction::AddColumn { .. }
10223 ) | (
10224 AlterTableAction::AddConstraint(_),
10225 AlterTableAction::AddConstraint(_)
10226 )
10227 );
10228 if i > 0 {
10229 self.write(",");
10230 self.write_newline();
10231 }
10232 self.write_indent();
10233 self.generate_alter_action_with_continuation(action, is_continuation)?;
10234 }
10235 self.indent_level -= 1;
10236 } else {
10237 for (i, action) in at.actions.iter().enumerate() {
10238 let is_continuation = i > 0
10240 && matches!(
10241 (&at.actions[i - 1], action),
10242 (
10243 AlterTableAction::AddColumn { .. },
10244 AlterTableAction::AddColumn { .. }
10245 ) | (
10246 AlterTableAction::AddConstraint(_),
10247 AlterTableAction::AddConstraint(_)
10248 )
10249 );
10250 if i > 0 {
10251 self.write(",");
10252 }
10253 self.write_space();
10254 self.generate_alter_action_with_continuation(action, is_continuation)?;
10255 }
10256 }
10257
10258 if let Some(ref algorithm) = at.algorithm {
10260 self.write(", ");
10261 self.write_keyword("ALGORITHM");
10262 self.write("=");
10263 self.write_keyword(algorithm);
10264 }
10265 if let Some(ref lock) = at.lock {
10266 self.write(", ");
10267 self.write_keyword("LOCK");
10268 self.write("=");
10269 self.write_keyword(lock);
10270 }
10271
10272 self.athena_hive_context = saved_athena_hive_context;
10274
10275 Ok(())
10276 }
10277
10278 fn generate_alter_action_with_continuation(
10279 &mut self,
10280 action: &AlterTableAction,
10281 is_continuation: bool,
10282 ) -> Result<()> {
10283 match action {
10284 AlterTableAction::AddColumn {
10285 column,
10286 if_not_exists,
10287 position,
10288 } => {
10289 use crate::dialects::DialectType;
10290 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
10294 let is_tsql_like = matches!(
10295 self.config.dialect,
10296 Some(DialectType::TSQL) | Some(DialectType::Fabric)
10297 );
10298 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
10300
10301 if is_continuation && (is_snowflake || is_tsql_like) {
10302 } else if is_snowflake {
10304 self.write_keyword("ADD");
10305 self.write_space();
10306 } else if is_athena {
10307 self.write_keyword("ADD COLUMNS");
10309 self.write(" (");
10310 } else if self.config.alter_table_include_column_keyword {
10311 self.write_keyword("ADD COLUMN");
10312 self.write_space();
10313 } else {
10314 self.write_keyword("ADD");
10316 self.write_space();
10317 }
10318
10319 if *if_not_exists {
10320 self.write_keyword("IF NOT EXISTS");
10321 self.write_space();
10322 }
10323 self.generate_column_def(column)?;
10324
10325 if is_athena {
10327 self.write(")");
10328 }
10329
10330 if let Some(pos) = position {
10332 self.write_space();
10333 match pos {
10334 ColumnPosition::First => self.write_keyword("FIRST"),
10335 ColumnPosition::After(col_name) => {
10336 self.write_keyword("AFTER");
10337 self.write_space();
10338 self.generate_identifier(col_name)?;
10339 }
10340 }
10341 }
10342 }
10343 AlterTableAction::DropColumn {
10344 name,
10345 if_exists,
10346 cascade,
10347 } => {
10348 self.write_keyword("DROP COLUMN");
10349 if *if_exists {
10350 self.write_space();
10351 self.write_keyword("IF EXISTS");
10352 }
10353 self.write_space();
10354 self.generate_identifier(name)?;
10355 if *cascade {
10356 self.write_space();
10357 self.write_keyword("CASCADE");
10358 }
10359 }
10360 AlterTableAction::DropColumns { names } => {
10361 self.write_keyword("DROP COLUMNS");
10362 self.write(" (");
10363 for (i, name) in names.iter().enumerate() {
10364 if i > 0 {
10365 self.write(", ");
10366 }
10367 self.generate_identifier(name)?;
10368 }
10369 self.write(")");
10370 }
10371 AlterTableAction::RenameColumn {
10372 old_name,
10373 new_name,
10374 if_exists,
10375 } => {
10376 self.write_keyword("RENAME COLUMN");
10377 if *if_exists {
10378 self.write_space();
10379 self.write_keyword("IF EXISTS");
10380 }
10381 self.write_space();
10382 self.generate_identifier(old_name)?;
10383 self.write_space();
10384 self.write_keyword("TO");
10385 self.write_space();
10386 self.generate_identifier(new_name)?;
10387 }
10388 AlterTableAction::AlterColumn {
10389 name,
10390 action,
10391 use_modify_keyword,
10392 } => {
10393 use crate::dialects::DialectType;
10394 let use_modify = *use_modify_keyword
10397 || (matches!(self.config.dialect, Some(DialectType::MySQL))
10398 && matches!(action, AlterColumnAction::SetDataType { .. }));
10399 if use_modify {
10400 self.write_keyword("MODIFY COLUMN");
10401 self.write_space();
10402 self.generate_identifier(name)?;
10403 if let AlterColumnAction::SetDataType {
10405 data_type,
10406 using: _,
10407 collate,
10408 } = action
10409 {
10410 self.write_space();
10411 self.generate_data_type(data_type)?;
10412 if let Some(collate_name) = collate {
10414 self.write_space();
10415 self.write_keyword("COLLATE");
10416 self.write_space();
10417 self.write(&format!("'{}'", collate_name));
10419 }
10420 } else {
10421 self.write_space();
10422 self.generate_alter_column_action(action)?;
10423 }
10424 } else if matches!(self.config.dialect, Some(DialectType::Hive))
10425 && matches!(action, AlterColumnAction::SetDataType { .. })
10426 {
10427 self.write_keyword("CHANGE COLUMN");
10429 self.write_space();
10430 self.generate_identifier(name)?;
10431 self.write_space();
10432 self.generate_identifier(name)?;
10433 if let AlterColumnAction::SetDataType { data_type, .. } = action {
10434 self.write_space();
10435 self.generate_data_type(data_type)?;
10436 }
10437 } else {
10438 self.write_keyword("ALTER COLUMN");
10439 self.write_space();
10440 self.generate_identifier(name)?;
10441 self.write_space();
10442 self.generate_alter_column_action(action)?;
10443 }
10444 }
10445 AlterTableAction::RenameTable(new_name) => {
10446 let mysql_like = matches!(
10448 self.config.dialect,
10449 Some(DialectType::MySQL)
10450 | Some(DialectType::Doris)
10451 | Some(DialectType::StarRocks)
10452 | Some(DialectType::SingleStore)
10453 );
10454 if mysql_like {
10455 self.write_keyword("RENAME");
10456 } else {
10457 self.write_keyword("RENAME TO");
10458 }
10459 self.write_space();
10460 let rename_table_with_db = !matches!(
10462 self.config.dialect,
10463 Some(DialectType::Doris)
10464 | Some(DialectType::DuckDB)
10465 | Some(DialectType::BigQuery)
10466 | Some(DialectType::PostgreSQL)
10467 );
10468 if !rename_table_with_db {
10469 let mut stripped = new_name.clone();
10470 stripped.schema = None;
10471 stripped.catalog = None;
10472 self.generate_table(&stripped)?;
10473 } else {
10474 self.generate_table(new_name)?;
10475 }
10476 }
10477 AlterTableAction::AddConstraint(constraint) => {
10478 if !is_continuation {
10481 self.write_keyword("ADD");
10482 self.write_space();
10483 }
10484 self.generate_table_constraint(constraint)?;
10485 }
10486 AlterTableAction::DropConstraint { name, if_exists } => {
10487 self.write_keyword("DROP CONSTRAINT");
10488 if *if_exists {
10489 self.write_space();
10490 self.write_keyword("IF EXISTS");
10491 }
10492 self.write_space();
10493 self.generate_identifier(name)?;
10494 }
10495 AlterTableAction::DropForeignKey { name } => {
10496 self.write_keyword("DROP FOREIGN KEY");
10497 self.write_space();
10498 self.generate_identifier(name)?;
10499 }
10500 AlterTableAction::DropPartition {
10501 partitions,
10502 if_exists,
10503 } => {
10504 self.write_keyword("DROP");
10505 if *if_exists {
10506 self.write_space();
10507 self.write_keyword("IF EXISTS");
10508 }
10509 for (i, partition) in partitions.iter().enumerate() {
10510 if i > 0 {
10511 self.write(",");
10512 }
10513 self.write_space();
10514 self.write_keyword("PARTITION");
10515 if partition.len() == 1 && partition[0].0.name == "__expr__" {
10517 self.write_space();
10519 self.generate_expression(&partition[0].1)?;
10520 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
10521 self.write_space();
10523 self.write_keyword("ALL");
10524 } else if partition.len() == 1 && partition[0].0.name == "ID" {
10525 self.write_space();
10527 self.write_keyword("ID");
10528 self.write_space();
10529 self.generate_expression(&partition[0].1)?;
10530 } else {
10531 self.write("(");
10533 for (j, (key, value)) in partition.iter().enumerate() {
10534 if j > 0 {
10535 self.write(", ");
10536 }
10537 self.generate_identifier(key)?;
10538 self.write(" = ");
10539 self.generate_expression(value)?;
10540 }
10541 self.write(")");
10542 }
10543 }
10544 }
10545 AlterTableAction::Delete { where_clause } => {
10546 self.write_keyword("DELETE");
10547 self.write_space();
10548 self.write_keyword("WHERE");
10549 self.write_space();
10550 self.generate_expression(where_clause)?;
10551 }
10552 AlterTableAction::SwapWith(target) => {
10553 self.write_keyword("SWAP WITH");
10554 self.write_space();
10555 self.generate_table(target)?;
10556 }
10557 AlterTableAction::SetProperty { properties } => {
10558 use crate::dialects::DialectType;
10559 self.write_keyword("SET");
10560 let is_trino_presto = matches!(
10562 self.config.dialect,
10563 Some(DialectType::Trino) | Some(DialectType::Presto)
10564 );
10565 if is_trino_presto {
10566 self.write_space();
10567 self.write_keyword("PROPERTIES");
10568 }
10569 let eq = if is_trino_presto { " = " } else { "=" };
10570 for (i, (key, value)) in properties.iter().enumerate() {
10571 if i > 0 {
10572 self.write(",");
10573 }
10574 self.write_space();
10575 if key.contains(' ') {
10577 self.generate_string_literal(key)?;
10578 } else {
10579 self.write(key);
10580 }
10581 self.write(eq);
10582 self.generate_expression(value)?;
10583 }
10584 }
10585 AlterTableAction::UnsetProperty { properties } => {
10586 self.write_keyword("UNSET");
10587 for (i, name) in properties.iter().enumerate() {
10588 if i > 0 {
10589 self.write(",");
10590 }
10591 self.write_space();
10592 self.write(name);
10593 }
10594 }
10595 AlterTableAction::ClusterBy { expressions } => {
10596 self.write_keyword("CLUSTER BY");
10597 self.write(" (");
10598 for (i, expr) in expressions.iter().enumerate() {
10599 if i > 0 {
10600 self.write(", ");
10601 }
10602 self.generate_expression(expr)?;
10603 }
10604 self.write(")");
10605 }
10606 AlterTableAction::SetTag { expressions } => {
10607 self.write_keyword("SET TAG");
10608 for (i, (key, value)) in expressions.iter().enumerate() {
10609 if i > 0 {
10610 self.write(",");
10611 }
10612 self.write_space();
10613 self.write(key);
10614 self.write(" = ");
10615 self.generate_expression(value)?;
10616 }
10617 }
10618 AlterTableAction::UnsetTag { names } => {
10619 self.write_keyword("UNSET TAG");
10620 for (i, name) in names.iter().enumerate() {
10621 if i > 0 {
10622 self.write(",");
10623 }
10624 self.write_space();
10625 self.write(name);
10626 }
10627 }
10628 AlterTableAction::SetOptions { expressions } => {
10629 self.write_keyword("SET");
10630 self.write(" (");
10631 for (i, expr) in expressions.iter().enumerate() {
10632 if i > 0 {
10633 self.write(", ");
10634 }
10635 self.generate_expression(expr)?;
10636 }
10637 self.write(")");
10638 }
10639 AlterTableAction::AlterIndex { name, visible } => {
10640 self.write_keyword("ALTER INDEX");
10641 self.write_space();
10642 self.generate_identifier(name)?;
10643 self.write_space();
10644 if *visible {
10645 self.write_keyword("VISIBLE");
10646 } else {
10647 self.write_keyword("INVISIBLE");
10648 }
10649 }
10650 AlterTableAction::SetAttribute { attribute } => {
10651 self.write_keyword("SET");
10652 self.write_space();
10653 self.write_keyword(attribute);
10654 }
10655 AlterTableAction::SetStageFileFormat { options } => {
10656 self.write_keyword("SET");
10657 self.write_space();
10658 self.write_keyword("STAGE_FILE_FORMAT");
10659 self.write(" = (");
10660 if let Some(opts) = options {
10661 self.generate_space_separated_properties(opts)?;
10662 }
10663 self.write(")");
10664 }
10665 AlterTableAction::SetStageCopyOptions { options } => {
10666 self.write_keyword("SET");
10667 self.write_space();
10668 self.write_keyword("STAGE_COPY_OPTIONS");
10669 self.write(" = (");
10670 if let Some(opts) = options {
10671 self.generate_space_separated_properties(opts)?;
10672 }
10673 self.write(")");
10674 }
10675 AlterTableAction::AddColumns { columns, cascade } => {
10676 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
10679 if is_oracle {
10680 self.write_keyword("ADD");
10681 } else {
10682 self.write_keyword("ADD COLUMNS");
10683 }
10684 self.write(" (");
10685 for (i, col) in columns.iter().enumerate() {
10686 if i > 0 {
10687 self.write(", ");
10688 }
10689 self.generate_column_def(col)?;
10690 }
10691 self.write(")");
10692 if *cascade {
10693 self.write_space();
10694 self.write_keyword("CASCADE");
10695 }
10696 }
10697 AlterTableAction::ChangeColumn {
10698 old_name,
10699 new_name,
10700 data_type,
10701 comment,
10702 cascade,
10703 } => {
10704 use crate::dialects::DialectType;
10705 let is_spark = matches!(
10706 self.config.dialect,
10707 Some(DialectType::Spark) | Some(DialectType::Databricks)
10708 );
10709 let is_rename = old_name.name != new_name.name;
10710
10711 if is_spark {
10712 if is_rename {
10713 self.write_keyword("RENAME COLUMN");
10715 self.write_space();
10716 self.generate_identifier(old_name)?;
10717 self.write_space();
10718 self.write_keyword("TO");
10719 self.write_space();
10720 self.generate_identifier(new_name)?;
10721 } else if comment.is_some() {
10722 self.write_keyword("ALTER COLUMN");
10724 self.write_space();
10725 self.generate_identifier(old_name)?;
10726 self.write_space();
10727 self.write_keyword("COMMENT");
10728 self.write_space();
10729 self.write("'");
10730 self.write(comment.as_ref().unwrap());
10731 self.write("'");
10732 } else if data_type.is_some() {
10733 self.write_keyword("ALTER COLUMN");
10735 self.write_space();
10736 self.generate_identifier(old_name)?;
10737 self.write_space();
10738 self.write_keyword("TYPE");
10739 self.write_space();
10740 self.generate_data_type(data_type.as_ref().unwrap())?;
10741 } else {
10742 self.write_keyword("CHANGE COLUMN");
10744 self.write_space();
10745 self.generate_identifier(old_name)?;
10746 self.write_space();
10747 self.generate_identifier(new_name)?;
10748 }
10749 } else {
10750 if data_type.is_some() {
10752 self.write_keyword("CHANGE COLUMN");
10753 } else {
10754 self.write_keyword("CHANGE");
10755 }
10756 self.write_space();
10757 self.generate_identifier(old_name)?;
10758 self.write_space();
10759 self.generate_identifier(new_name)?;
10760 if let Some(ref dt) = data_type {
10761 self.write_space();
10762 self.generate_data_type(dt)?;
10763 }
10764 if let Some(ref c) = comment {
10765 self.write_space();
10766 self.write_keyword("COMMENT");
10767 self.write_space();
10768 self.write("'");
10769 self.write(c);
10770 self.write("'");
10771 }
10772 if *cascade {
10773 self.write_space();
10774 self.write_keyword("CASCADE");
10775 }
10776 }
10777 }
10778 AlterTableAction::AddPartition {
10779 partition,
10780 if_not_exists,
10781 location,
10782 } => {
10783 self.write_keyword("ADD");
10784 self.write_space();
10785 if *if_not_exists {
10786 self.write_keyword("IF NOT EXISTS");
10787 self.write_space();
10788 }
10789 self.generate_expression(partition)?;
10790 if let Some(ref loc) = location {
10791 self.write_space();
10792 self.write_keyword("LOCATION");
10793 self.write_space();
10794 self.generate_expression(loc)?;
10795 }
10796 }
10797 AlterTableAction::AlterSortKey {
10798 this,
10799 expressions,
10800 compound,
10801 } => {
10802 self.write_keyword("ALTER");
10804 if *compound {
10805 self.write_space();
10806 self.write_keyword("COMPOUND");
10807 }
10808 self.write_space();
10809 self.write_keyword("SORTKEY");
10810 self.write_space();
10811 if let Some(style) = this {
10812 self.write_keyword(style);
10813 } else if !expressions.is_empty() {
10814 self.write("(");
10815 for (i, expr) in expressions.iter().enumerate() {
10816 if i > 0 {
10817 self.write(", ");
10818 }
10819 self.generate_expression(expr)?;
10820 }
10821 self.write(")");
10822 }
10823 }
10824 AlterTableAction::AlterDistStyle { style, distkey } => {
10825 self.write_keyword("ALTER");
10827 self.write_space();
10828 self.write_keyword("DISTSTYLE");
10829 self.write_space();
10830 self.write_keyword(style);
10831 if let Some(col) = distkey {
10832 self.write_space();
10833 self.write_keyword("DISTKEY");
10834 self.write_space();
10835 self.generate_identifier(col)?;
10836 }
10837 }
10838 AlterTableAction::SetTableProperties { properties } => {
10839 self.write_keyword("SET TABLE PROPERTIES");
10841 self.write(" (");
10842 for (i, (key, value)) in properties.iter().enumerate() {
10843 if i > 0 {
10844 self.write(", ");
10845 }
10846 self.generate_expression(key)?;
10847 self.write(" = ");
10848 self.generate_expression(value)?;
10849 }
10850 self.write(")");
10851 }
10852 AlterTableAction::SetLocation { location } => {
10853 self.write_keyword("SET LOCATION");
10855 self.write_space();
10856 self.write("'");
10857 self.write(location);
10858 self.write("'");
10859 }
10860 AlterTableAction::SetFileFormat { format } => {
10861 self.write_keyword("SET FILE FORMAT");
10863 self.write_space();
10864 self.write_keyword(format);
10865 }
10866 AlterTableAction::ReplacePartition { partition, source } => {
10867 self.write_keyword("REPLACE PARTITION");
10869 self.write_space();
10870 self.generate_expression(partition)?;
10871 if let Some(src) = source {
10872 self.write_space();
10873 self.write_keyword("FROM");
10874 self.write_space();
10875 self.generate_expression(src)?;
10876 }
10877 }
10878 AlterTableAction::Raw { sql } => {
10879 self.write(sql);
10880 }
10881 }
10882 Ok(())
10883 }
10884
10885 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
10886 match action {
10887 AlterColumnAction::SetDataType {
10888 data_type,
10889 using,
10890 collate,
10891 } => {
10892 use crate::dialects::DialectType;
10893 let is_no_prefix = matches!(
10898 self.config.dialect,
10899 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
10900 );
10901 let is_type_only = matches!(
10902 self.config.dialect,
10903 Some(DialectType::Redshift)
10904 | Some(DialectType::Spark)
10905 | Some(DialectType::Databricks)
10906 );
10907 if is_type_only {
10908 self.write_keyword("TYPE");
10909 self.write_space();
10910 } else if !is_no_prefix {
10911 self.write_keyword("SET DATA TYPE");
10912 self.write_space();
10913 }
10914 self.generate_data_type(data_type)?;
10915 if let Some(ref collation) = collate {
10916 self.write_space();
10917 self.write_keyword("COLLATE");
10918 self.write_space();
10919 self.write(collation);
10920 }
10921 if let Some(ref using_expr) = using {
10922 self.write_space();
10923 self.write_keyword("USING");
10924 self.write_space();
10925 self.generate_expression(using_expr)?;
10926 }
10927 }
10928 AlterColumnAction::SetDefault(expr) => {
10929 self.write_keyword("SET DEFAULT");
10930 self.write_space();
10931 self.generate_expression(expr)?;
10932 }
10933 AlterColumnAction::DropDefault => {
10934 self.write_keyword("DROP DEFAULT");
10935 }
10936 AlterColumnAction::SetNotNull => {
10937 self.write_keyword("SET NOT NULL");
10938 }
10939 AlterColumnAction::DropNotNull => {
10940 self.write_keyword("DROP NOT NULL");
10941 }
10942 AlterColumnAction::Comment(comment) => {
10943 self.write_keyword("COMMENT");
10944 self.write_space();
10945 self.generate_string_literal(comment)?;
10946 }
10947 AlterColumnAction::SetVisible => {
10948 self.write_keyword("SET VISIBLE");
10949 }
10950 AlterColumnAction::SetInvisible => {
10951 self.write_keyword("SET INVISIBLE");
10952 }
10953 }
10954 Ok(())
10955 }
10956
10957 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
10958 self.write_keyword("CREATE");
10959
10960 if ci.unique {
10961 self.write_space();
10962 self.write_keyword("UNIQUE");
10963 }
10964
10965 if let Some(ref clustered) = ci.clustered {
10967 self.write_space();
10968 self.write_keyword(clustered);
10969 }
10970
10971 self.write_space();
10972 self.write_keyword("INDEX");
10973
10974 if ci.concurrently {
10976 self.write_space();
10977 self.write_keyword("CONCURRENTLY");
10978 }
10979
10980 if ci.if_not_exists {
10981 self.write_space();
10982 self.write_keyword("IF NOT EXISTS");
10983 }
10984
10985 if !ci.name.name.is_empty() {
10987 self.write_space();
10988 self.generate_identifier(&ci.name)?;
10989 }
10990 self.write_space();
10991 self.write_keyword("ON");
10992 if matches!(self.config.dialect, Some(DialectType::Hive)) {
10994 self.write_space();
10995 self.write_keyword("TABLE");
10996 }
10997 self.write_space();
10998 self.generate_table(&ci.table)?;
10999
11000 if !ci.columns.is_empty() || ci.using.is_some() {
11003 let space_before_paren = false;
11004
11005 if let Some(ref using) = ci.using {
11006 self.write_space();
11007 self.write_keyword("USING");
11008 self.write_space();
11009 self.write(using);
11010 if space_before_paren {
11011 self.write(" (");
11012 } else {
11013 self.write("(");
11014 }
11015 } else {
11016 if space_before_paren {
11017 self.write(" (");
11018 } else {
11019 self.write("(");
11020 }
11021 }
11022 for (i, col) in ci.columns.iter().enumerate() {
11023 if i > 0 {
11024 self.write(", ");
11025 }
11026 self.generate_identifier(&col.column)?;
11027 if let Some(ref opclass) = col.opclass {
11028 self.write_space();
11029 self.write(opclass);
11030 }
11031 if col.desc {
11032 self.write_space();
11033 self.write_keyword("DESC");
11034 } else if col.asc {
11035 self.write_space();
11036 self.write_keyword("ASC");
11037 }
11038 if let Some(nulls_first) = col.nulls_first {
11039 self.write_space();
11040 self.write_keyword("NULLS");
11041 self.write_space();
11042 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
11043 }
11044 }
11045 self.write(")");
11046 }
11047
11048 if !ci.include_columns.is_empty() {
11050 self.write_space();
11051 self.write_keyword("INCLUDE");
11052 self.write(" (");
11053 for (i, col) in ci.include_columns.iter().enumerate() {
11054 if i > 0 {
11055 self.write(", ");
11056 }
11057 self.generate_identifier(col)?;
11058 }
11059 self.write(")");
11060 }
11061
11062 if !ci.with_options.is_empty() {
11064 self.write_space();
11065 self.write_keyword("WITH");
11066 self.write(" (");
11067 for (i, (key, value)) in ci.with_options.iter().enumerate() {
11068 if i > 0 {
11069 self.write(", ");
11070 }
11071 self.write(key);
11072 self.write("=");
11073 self.write(value);
11074 }
11075 self.write(")");
11076 }
11077
11078 if let Some(ref where_clause) = ci.where_clause {
11080 self.write_space();
11081 self.write_keyword("WHERE");
11082 self.write_space();
11083 self.generate_expression(where_clause)?;
11084 }
11085
11086 if let Some(ref on_fg) = ci.on_filegroup {
11088 self.write_space();
11089 self.write_keyword("ON");
11090 self.write_space();
11091 self.write(on_fg);
11092 }
11093
11094 Ok(())
11095 }
11096
11097 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
11098 self.write_keyword("DROP INDEX");
11099
11100 if di.concurrently {
11101 self.write_space();
11102 self.write_keyword("CONCURRENTLY");
11103 }
11104
11105 if di.if_exists {
11106 self.write_space();
11107 self.write_keyword("IF EXISTS");
11108 }
11109
11110 self.write_space();
11111 self.generate_identifier(&di.name)?;
11112
11113 if let Some(ref table) = di.table {
11114 self.write_space();
11115 self.write_keyword("ON");
11116 self.write_space();
11117 self.generate_table(table)?;
11118 }
11119
11120 Ok(())
11121 }
11122
11123 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
11124 self.write_keyword("CREATE");
11125
11126 if let Some(ref algorithm) = cv.algorithm {
11128 self.write_space();
11129 self.write_keyword("ALGORITHM");
11130 self.write("=");
11131 self.write_keyword(algorithm);
11132 }
11133
11134 if let Some(ref definer) = cv.definer {
11136 self.write_space();
11137 self.write_keyword("DEFINER");
11138 self.write("=");
11139 self.write(definer);
11140 }
11141
11142 if cv.security_sql_style && !cv.security_after_name {
11144 if let Some(ref security) = cv.security {
11145 self.write_space();
11146 self.write_keyword("SQL SECURITY");
11147 self.write_space();
11148 match security {
11149 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11150 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11151 FunctionSecurity::None => self.write_keyword("NONE"),
11152 }
11153 }
11154 }
11155
11156 if cv.or_alter {
11157 self.write_space();
11158 self.write_keyword("OR ALTER");
11159 } else if cv.or_replace {
11160 self.write_space();
11161 self.write_keyword("OR REPLACE");
11162 }
11163
11164 if cv.temporary {
11165 self.write_space();
11166 self.write_keyword("TEMPORARY");
11167 }
11168
11169 if cv.materialized {
11170 self.write_space();
11171 self.write_keyword("MATERIALIZED");
11172 }
11173
11174 if cv.secure {
11176 self.write_space();
11177 self.write_keyword("SECURE");
11178 }
11179
11180 self.write_space();
11181 self.write_keyword("VIEW");
11182
11183 if cv.if_not_exists {
11184 self.write_space();
11185 self.write_keyword("IF NOT EXISTS");
11186 }
11187
11188 self.write_space();
11189 self.generate_table(&cv.name)?;
11190
11191 if let Some(ref on_cluster) = cv.on_cluster {
11193 self.write_space();
11194 self.generate_on_cluster(on_cluster)?;
11195 }
11196
11197 if let Some(ref to_table) = cv.to_table {
11199 self.write_space();
11200 self.write_keyword("TO");
11201 self.write_space();
11202 self.generate_table(to_table)?;
11203 }
11204
11205 if !cv.materialized {
11208 if !cv.columns.is_empty() {
11210 self.write(" (");
11211 for (i, col) in cv.columns.iter().enumerate() {
11212 if i > 0 {
11213 self.write(", ");
11214 }
11215 self.generate_identifier(&col.name)?;
11216 if !col.options.is_empty() {
11218 self.write_space();
11219 self.generate_options_clause(&col.options)?;
11220 }
11221 if let Some(ref comment) = col.comment {
11222 self.write_space();
11223 self.write_keyword("COMMENT");
11224 self.write_space();
11225 self.generate_string_literal(comment)?;
11226 }
11227 }
11228 self.write(")");
11229 }
11230
11231 if !cv.security_sql_style || cv.security_after_name {
11234 if let Some(ref security) = cv.security {
11235 self.write_space();
11236 if cv.security_sql_style {
11237 self.write_keyword("SQL SECURITY");
11238 } else {
11239 self.write_keyword("SECURITY");
11240 }
11241 self.write_space();
11242 match security {
11243 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11244 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11245 FunctionSecurity::None => self.write_keyword("NONE"),
11246 }
11247 }
11248 }
11249
11250 if cv.copy_grants {
11252 self.write_space();
11253 self.write_keyword("COPY GRANTS");
11254 }
11255 } else {
11256 if cv.copy_grants {
11258 self.write_space();
11259 self.write_keyword("COPY GRANTS");
11260 }
11261
11262 if let Some(ref schema) = cv.schema {
11264 self.write(" (");
11265 for (i, expr) in schema.expressions.iter().enumerate() {
11266 if i > 0 {
11267 self.write(", ");
11268 }
11269 self.generate_expression(expr)?;
11270 }
11271 self.write(")");
11272 } else if !cv.columns.is_empty() {
11273 self.write(" (");
11275 for (i, col) in cv.columns.iter().enumerate() {
11276 if i > 0 {
11277 self.write(", ");
11278 }
11279 self.generate_identifier(&col.name)?;
11280 if !col.options.is_empty() {
11282 self.write_space();
11283 self.generate_options_clause(&col.options)?;
11284 }
11285 if let Some(ref comment) = col.comment {
11286 self.write_space();
11287 self.write_keyword("COMMENT");
11288 self.write_space();
11289 self.generate_string_literal(comment)?;
11290 }
11291 }
11292 self.write(")");
11293 }
11294
11295 if let Some(ref unique_key) = cv.unique_key {
11297 self.write_space();
11298 self.write_keyword("KEY");
11299 self.write(" (");
11300 for (i, expr) in unique_key.expressions.iter().enumerate() {
11301 if i > 0 {
11302 self.write(", ");
11303 }
11304 self.generate_expression(expr)?;
11305 }
11306 self.write(")");
11307 }
11308 }
11309
11310 if let Some(ref row_access_policy) = cv.row_access_policy {
11311 self.write_space();
11312 self.write_keyword("WITH");
11313 self.write_space();
11314 self.write(row_access_policy);
11315 }
11316
11317 if let Some(ref comment) = cv.comment {
11319 self.write_space();
11320 self.write_keyword("COMMENT");
11321 self.write("=");
11322 self.generate_string_literal(comment)?;
11323 }
11324
11325 if !cv.tags.is_empty() {
11327 self.write_space();
11328 self.write_keyword("TAG");
11329 self.write(" (");
11330 for (i, (name, value)) in cv.tags.iter().enumerate() {
11331 if i > 0 {
11332 self.write(", ");
11333 }
11334 self.write(name);
11335 self.write("='");
11336 self.write(value);
11337 self.write("'");
11338 }
11339 self.write(")");
11340 }
11341
11342 if !cv.options.is_empty() {
11344 self.write_space();
11345 self.generate_options_clause(&cv.options)?;
11346 }
11347
11348 if let Some(ref build) = cv.build {
11350 self.write_space();
11351 self.write_keyword("BUILD");
11352 self.write_space();
11353 self.write_keyword(build);
11354 }
11355
11356 if let Some(ref refresh) = cv.refresh {
11358 self.write_space();
11359 self.generate_refresh_trigger_property(refresh)?;
11360 }
11361
11362 if let Some(auto_refresh) = cv.auto_refresh {
11364 self.write_space();
11365 self.write_keyword("AUTO REFRESH");
11366 self.write_space();
11367 if auto_refresh {
11368 self.write_keyword("YES");
11369 } else {
11370 self.write_keyword("NO");
11371 }
11372 }
11373
11374 for prop in &cv.table_properties {
11376 self.write_space();
11377 self.generate_expression(prop)?;
11378 }
11379
11380 if let Some(ref population) = cv.clickhouse_population {
11382 self.write_space();
11383 self.write_keyword(population);
11384 }
11385
11386 if !matches!(&cv.query, Expression::Null(_)) {
11388 self.write_space();
11389 self.write_keyword("AS");
11390 self.write_space();
11391
11392 if let Some(ref mode) = cv.locking_mode {
11394 self.write_keyword("LOCKING");
11395 self.write_space();
11396 self.write_keyword(mode);
11397 if let Some(ref access) = cv.locking_access {
11398 self.write_space();
11399 self.write_keyword("FOR");
11400 self.write_space();
11401 self.write_keyword(access);
11402 }
11403 self.write_space();
11404 }
11405
11406 if cv.query_parenthesized {
11407 self.write("(");
11408 }
11409 self.generate_expression(&cv.query)?;
11410 if cv.query_parenthesized {
11411 self.write(")");
11412 }
11413 }
11414
11415 if cv.no_schema_binding {
11417 self.write_space();
11418 self.write_keyword("WITH NO SCHEMA BINDING");
11419 }
11420
11421 Ok(())
11422 }
11423
11424 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
11425 self.write_keyword("DROP");
11426
11427 if dv.materialized {
11428 self.write_space();
11429 self.write_keyword("MATERIALIZED");
11430 }
11431
11432 self.write_space();
11433 self.write_keyword("VIEW");
11434
11435 if dv.if_exists {
11436 self.write_space();
11437 self.write_keyword("IF EXISTS");
11438 }
11439
11440 self.write_space();
11441 self.generate_table(&dv.name)?;
11442
11443 Ok(())
11444 }
11445
11446 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
11447 match tr.target {
11448 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
11449 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
11450 }
11451 if tr.if_exists {
11452 self.write_space();
11453 self.write_keyword("IF EXISTS");
11454 }
11455 self.write_space();
11456 self.generate_table(&tr.table)?;
11457
11458 if let Some(ref on_cluster) = tr.on_cluster {
11460 self.write_space();
11461 self.generate_on_cluster(on_cluster)?;
11462 }
11463
11464 if !tr.extra_tables.is_empty() {
11466 let skip_first = if let Some(first) = tr.extra_tables.first() {
11468 first.table.name == tr.table.name && first.star
11469 } else {
11470 false
11471 };
11472
11473 let strip_star = matches!(
11475 self.config.dialect,
11476 Some(crate::dialects::DialectType::PostgreSQL)
11477 | Some(crate::dialects::DialectType::Redshift)
11478 );
11479 if skip_first && !strip_star {
11480 self.write("*");
11481 }
11482
11483 for (i, entry) in tr.extra_tables.iter().enumerate() {
11485 if i == 0 && skip_first {
11486 continue; }
11488 self.write(", ");
11489 self.generate_table(&entry.table)?;
11490 if entry.star && !strip_star {
11491 self.write("*");
11492 }
11493 }
11494 }
11495
11496 if let Some(identity) = &tr.identity {
11498 self.write_space();
11499 match identity {
11500 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
11501 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
11502 }
11503 }
11504
11505 if tr.cascade {
11506 self.write_space();
11507 self.write_keyword("CASCADE");
11508 }
11509
11510 if tr.restrict {
11511 self.write_space();
11512 self.write_keyword("RESTRICT");
11513 }
11514
11515 if let Some(ref partition) = tr.partition {
11517 self.write_space();
11518 self.generate_expression(partition)?;
11519 }
11520
11521 Ok(())
11522 }
11523
11524 fn generate_use(&mut self, u: &Use) -> Result<()> {
11525 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
11527 self.write_keyword("DATABASE");
11528 self.write_space();
11529 self.generate_identifier(&u.this)?;
11530 return Ok(());
11531 }
11532
11533 self.write_keyword("USE");
11534
11535 if let Some(kind) = &u.kind {
11536 self.write_space();
11537 match kind {
11538 UseKind::Database => self.write_keyword("DATABASE"),
11539 UseKind::Schema => self.write_keyword("SCHEMA"),
11540 UseKind::Role => self.write_keyword("ROLE"),
11541 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
11542 UseKind::Catalog => self.write_keyword("CATALOG"),
11543 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
11544 }
11545 }
11546
11547 self.write_space();
11548 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
11551 self.write(&u.this.name);
11552 } else {
11553 self.generate_identifier(&u.this)?;
11554 }
11555 Ok(())
11556 }
11557
11558 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
11559 self.write_keyword("CACHE");
11560 if c.lazy {
11561 self.write_space();
11562 self.write_keyword("LAZY");
11563 }
11564 self.write_space();
11565 self.write_keyword("TABLE");
11566 self.write_space();
11567 self.generate_identifier(&c.table)?;
11568
11569 if !c.options.is_empty() {
11571 self.write_space();
11572 self.write_keyword("OPTIONS");
11573 self.write("(");
11574 for (i, (key, value)) in c.options.iter().enumerate() {
11575 if i > 0 {
11576 self.write(", ");
11577 }
11578 self.generate_expression(key)?;
11579 self.write(" = ");
11580 self.generate_expression(value)?;
11581 }
11582 self.write(")");
11583 }
11584
11585 if let Some(query) = &c.query {
11587 self.write_space();
11588 self.write_keyword("AS");
11589 self.write_space();
11590 self.generate_expression(query)?;
11591 }
11592
11593 Ok(())
11594 }
11595
11596 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
11597 self.write_keyword("UNCACHE TABLE");
11598 if u.if_exists {
11599 self.write_space();
11600 self.write_keyword("IF EXISTS");
11601 }
11602 self.write_space();
11603 self.generate_identifier(&u.table)?;
11604 Ok(())
11605 }
11606
11607 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
11608 self.write_keyword("LOAD DATA");
11609 if l.local {
11610 self.write_space();
11611 self.write_keyword("LOCAL");
11612 }
11613 self.write_space();
11614 self.write_keyword("INPATH");
11615 self.write_space();
11616 self.write("'");
11617 self.write(&l.inpath);
11618 self.write("'");
11619
11620 if l.overwrite {
11621 self.write_space();
11622 self.write_keyword("OVERWRITE");
11623 }
11624
11625 self.write_space();
11626 self.write_keyword("INTO TABLE");
11627 self.write_space();
11628 self.generate_expression(&l.table)?;
11629
11630 if !l.partition.is_empty() {
11632 self.write_space();
11633 self.write_keyword("PARTITION");
11634 self.write("(");
11635 for (i, (col, val)) in l.partition.iter().enumerate() {
11636 if i > 0 {
11637 self.write(", ");
11638 }
11639 self.generate_identifier(col)?;
11640 self.write(" = ");
11641 self.generate_expression(val)?;
11642 }
11643 self.write(")");
11644 }
11645
11646 if let Some(fmt) = &l.input_format {
11648 self.write_space();
11649 self.write_keyword("INPUTFORMAT");
11650 self.write_space();
11651 self.write("'");
11652 self.write(fmt);
11653 self.write("'");
11654 }
11655
11656 if let Some(serde) = &l.serde {
11658 self.write_space();
11659 self.write_keyword("SERDE");
11660 self.write_space();
11661 self.write("'");
11662 self.write(serde);
11663 self.write("'");
11664 }
11665
11666 Ok(())
11667 }
11668
11669 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
11670 self.write_keyword("PRAGMA");
11671 self.write_space();
11672
11673 if let Some(schema) = &p.schema {
11675 self.generate_identifier(schema)?;
11676 self.write(".");
11677 }
11678
11679 self.generate_identifier(&p.name)?;
11681
11682 if p.use_assignment_syntax {
11684 self.write(" = ");
11685 if let Some(value) = &p.value {
11686 self.generate_expression(value)?;
11687 } else if let Some(arg) = p.args.first() {
11688 self.generate_expression(arg)?;
11689 }
11690 } else if !p.args.is_empty() {
11691 self.write("(");
11692 for (i, arg) in p.args.iter().enumerate() {
11693 if i > 0 {
11694 self.write(", ");
11695 }
11696 self.generate_expression(arg)?;
11697 }
11698 self.write(")");
11699 }
11700
11701 Ok(())
11702 }
11703
11704 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
11705 self.write_keyword("GRANT");
11706 self.write_space();
11707
11708 for (i, privilege) in g.privileges.iter().enumerate() {
11710 if i > 0 {
11711 self.write(", ");
11712 }
11713 self.write_keyword(&privilege.name);
11714 if !privilege.columns.is_empty() {
11716 self.write("(");
11717 for (j, col) in privilege.columns.iter().enumerate() {
11718 if j > 0 {
11719 self.write(", ");
11720 }
11721 self.write(col);
11722 }
11723 self.write(")");
11724 }
11725 }
11726
11727 self.write_space();
11728 self.write_keyword("ON");
11729 self.write_space();
11730
11731 if let Some(kind) = &g.kind {
11733 self.write_keyword(kind);
11734 self.write_space();
11735 }
11736
11737 {
11739 use crate::dialects::DialectType;
11740 let should_upper = matches!(
11741 self.config.dialect,
11742 Some(DialectType::PostgreSQL)
11743 | Some(DialectType::CockroachDB)
11744 | Some(DialectType::Materialize)
11745 | Some(DialectType::RisingWave)
11746 ) && (g.kind.as_deref() == Some("FUNCTION")
11747 || g.kind.as_deref() == Some("PROCEDURE"));
11748 if should_upper {
11749 use crate::expressions::Identifier;
11750 let upper_id = Identifier {
11751 name: g.securable.name.to_ascii_uppercase(),
11752 quoted: g.securable.quoted,
11753 ..g.securable.clone()
11754 };
11755 self.generate_identifier(&upper_id)?;
11756 } else {
11757 self.generate_identifier(&g.securable)?;
11758 }
11759 }
11760
11761 if !g.function_params.is_empty() {
11763 self.write("(");
11764 for (i, param) in g.function_params.iter().enumerate() {
11765 if i > 0 {
11766 self.write(", ");
11767 }
11768 self.write(param);
11769 }
11770 self.write(")");
11771 }
11772
11773 self.write_space();
11774 self.write_keyword("TO");
11775 self.write_space();
11776
11777 for (i, principal) in g.principals.iter().enumerate() {
11779 if i > 0 {
11780 self.write(", ");
11781 }
11782 if principal.is_role {
11783 self.write_keyword("ROLE");
11784 self.write_space();
11785 } else if principal.is_group {
11786 self.write_keyword("GROUP");
11787 self.write_space();
11788 } else if principal.is_share {
11789 self.write_keyword("SHARE");
11790 self.write_space();
11791 }
11792 self.generate_identifier(&principal.name)?;
11793 }
11794
11795 if g.grant_option {
11797 self.write_space();
11798 self.write_keyword("WITH GRANT OPTION");
11799 }
11800
11801 if let Some(ref principal) = g.as_principal {
11803 self.write_space();
11804 self.write_keyword("AS");
11805 self.write_space();
11806 self.generate_identifier(principal)?;
11807 }
11808
11809 Ok(())
11810 }
11811
11812 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
11813 self.write_keyword("REVOKE");
11814 self.write_space();
11815
11816 if r.grant_option {
11818 self.write_keyword("GRANT OPTION FOR");
11819 self.write_space();
11820 }
11821
11822 for (i, privilege) in r.privileges.iter().enumerate() {
11824 if i > 0 {
11825 self.write(", ");
11826 }
11827 self.write_keyword(&privilege.name);
11828 if !privilege.columns.is_empty() {
11830 self.write("(");
11831 for (j, col) in privilege.columns.iter().enumerate() {
11832 if j > 0 {
11833 self.write(", ");
11834 }
11835 self.write(col);
11836 }
11837 self.write(")");
11838 }
11839 }
11840
11841 self.write_space();
11842 self.write_keyword("ON");
11843 self.write_space();
11844
11845 if let Some(kind) = &r.kind {
11847 self.write_keyword(kind);
11848 self.write_space();
11849 }
11850
11851 {
11853 use crate::dialects::DialectType;
11854 let should_upper = matches!(
11855 self.config.dialect,
11856 Some(DialectType::PostgreSQL)
11857 | Some(DialectType::CockroachDB)
11858 | Some(DialectType::Materialize)
11859 | Some(DialectType::RisingWave)
11860 ) && (r.kind.as_deref() == Some("FUNCTION")
11861 || r.kind.as_deref() == Some("PROCEDURE"));
11862 if should_upper {
11863 use crate::expressions::Identifier;
11864 let upper_id = Identifier {
11865 name: r.securable.name.to_ascii_uppercase(),
11866 quoted: r.securable.quoted,
11867 ..r.securable.clone()
11868 };
11869 self.generate_identifier(&upper_id)?;
11870 } else {
11871 self.generate_identifier(&r.securable)?;
11872 }
11873 }
11874
11875 if !r.function_params.is_empty() {
11877 self.write("(");
11878 for (i, param) in r.function_params.iter().enumerate() {
11879 if i > 0 {
11880 self.write(", ");
11881 }
11882 self.write(param);
11883 }
11884 self.write(")");
11885 }
11886
11887 self.write_space();
11888 self.write_keyword("FROM");
11889 self.write_space();
11890
11891 for (i, principal) in r.principals.iter().enumerate() {
11893 if i > 0 {
11894 self.write(", ");
11895 }
11896 if principal.is_role {
11897 self.write_keyword("ROLE");
11898 self.write_space();
11899 } else if principal.is_group {
11900 self.write_keyword("GROUP");
11901 self.write_space();
11902 } else if principal.is_share {
11903 self.write_keyword("SHARE");
11904 self.write_space();
11905 }
11906 self.generate_identifier(&principal.name)?;
11907 }
11908
11909 if r.cascade {
11911 self.write_space();
11912 self.write_keyword("CASCADE");
11913 } else if r.restrict {
11914 self.write_space();
11915 self.write_keyword("RESTRICT");
11916 }
11917
11918 Ok(())
11919 }
11920
11921 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
11922 self.write_keyword("COMMENT");
11923
11924 if c.exists {
11926 self.write_space();
11927 self.write_keyword("IF EXISTS");
11928 }
11929
11930 self.write_space();
11931 self.write_keyword("ON");
11932
11933 if c.materialized {
11935 self.write_space();
11936 self.write_keyword("MATERIALIZED");
11937 }
11938
11939 self.write_space();
11940 self.write_keyword(&c.kind);
11941 self.write_space();
11942
11943 self.generate_expression(&c.this)?;
11945
11946 self.write_space();
11947 self.write_keyword("IS");
11948 self.write_space();
11949
11950 self.generate_expression(&c.expression)?;
11952
11953 Ok(())
11954 }
11955
11956 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
11957 self.write_keyword("SET");
11958
11959 for (i, item) in s.items.iter().enumerate() {
11960 if i > 0 {
11961 self.write(",");
11962 }
11963 self.write_space();
11964
11965 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
11967 if let Some(ref kind) = item.kind {
11968 if has_variable_kind {
11972 if matches!(
11973 self.config.dialect,
11974 Some(DialectType::Spark | DialectType::Databricks | DialectType::DuckDB)
11975 ) {
11976 self.write_keyword("VARIABLE");
11977 self.write_space();
11978 }
11979 } else {
11980 self.write_keyword(kind);
11981 self.write_space();
11982 }
11983 }
11984
11985 let name_str = match &item.name {
11987 Expression::Identifier(id) => Some(id.name.as_str()),
11988 _ => None,
11989 };
11990
11991 let is_transaction = name_str == Some("TRANSACTION");
11992 let is_character_set = name_str == Some("CHARACTER SET");
11993 let is_names = name_str == Some("NAMES");
11994 let is_collate = name_str == Some("COLLATE");
11995 let is_value_only =
11996 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
11997
11998 if is_transaction {
11999 self.write_keyword("TRANSACTION");
12001 if let Expression::Identifier(id) = &item.value {
12002 if !id.name.is_empty() {
12003 self.write_space();
12004 self.write(&id.name);
12005 }
12006 }
12007 } else if is_character_set {
12008 self.write_keyword("CHARACTER SET");
12010 self.write_space();
12011 self.generate_set_value(&item.value)?;
12012 } else if is_names {
12013 self.write_keyword("NAMES");
12015 self.write_space();
12016 self.generate_set_value(&item.value)?;
12017 } else if is_collate {
12018 self.write_keyword("COLLATE");
12020 self.write_space();
12021 self.generate_set_value(&item.value)?;
12022 } else if has_variable_kind {
12023 if let Some(ns) = name_str {
12026 self.write(ns);
12027 } else {
12028 self.generate_expression(&item.name)?;
12029 }
12030 self.write(" = ");
12031 self.generate_set_value(&item.value)?;
12032 } else if is_value_only {
12033 self.generate_expression(&item.name)?;
12035 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
12036 self.generate_expression(&item.name)?;
12038 self.write_space();
12039 self.generate_set_value(&item.value)?;
12040 } else {
12041 match &item.name {
12044 Expression::Identifier(id) => {
12045 self.write(&id.name);
12046 }
12047 _ => {
12048 self.generate_expression(&item.name)?;
12049 }
12050 }
12051 self.write(" = ");
12052 self.generate_set_value(&item.value)?;
12053 }
12054 }
12055
12056 Ok(())
12057 }
12058
12059 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
12062 if let Expression::Identifier(id) = value {
12063 match id.name.as_str() {
12064 "DEFAULT" | "ON" | "OFF" => {
12065 self.write_keyword(&id.name);
12066 return Ok(());
12067 }
12068 _ => {}
12069 }
12070 }
12071 self.generate_expression(value)
12072 }
12073
12074 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
12077 self.write_keyword("ALTER");
12078 if let Some(ref algorithm) = av.algorithm {
12080 self.write_space();
12081 self.write_keyword("ALGORITHM");
12082 self.write(" = ");
12083 self.write_keyword(algorithm);
12084 }
12085 if let Some(ref definer) = av.definer {
12086 self.write_space();
12087 self.write_keyword("DEFINER");
12088 self.write(" = ");
12089 self.write(definer);
12090 }
12091 if let Some(ref sql_security) = av.sql_security {
12092 self.write_space();
12093 self.write_keyword("SQL SECURITY");
12094 self.write(" = ");
12095 self.write_keyword(sql_security);
12096 }
12097 self.write_space();
12098 self.write_keyword("VIEW");
12099 self.write_space();
12100 self.generate_table(&av.name)?;
12101
12102 if !av.columns.is_empty() {
12104 self.write(" (");
12105 for (i, col) in av.columns.iter().enumerate() {
12106 if i > 0 {
12107 self.write(", ");
12108 }
12109 self.generate_identifier(&col.name)?;
12110 if let Some(ref comment) = col.comment {
12111 self.write_space();
12112 self.write_keyword("COMMENT");
12113 self.write(" ");
12114 self.generate_string_literal(comment)?;
12115 }
12116 }
12117 self.write(")");
12118 }
12119
12120 if let Some(ref opt) = av.with_option {
12122 self.write_space();
12123 self.write_keyword("WITH");
12124 self.write_space();
12125 self.write_keyword(opt);
12126 }
12127
12128 for action in &av.actions {
12129 self.write_space();
12130 match action {
12131 AlterViewAction::Rename(new_name) => {
12132 self.write_keyword("RENAME TO");
12133 self.write_space();
12134 self.generate_table(new_name)?;
12135 }
12136 AlterViewAction::OwnerTo(owner) => {
12137 self.write_keyword("OWNER TO");
12138 self.write_space();
12139 self.generate_identifier(owner)?;
12140 }
12141 AlterViewAction::SetSchema(schema) => {
12142 self.write_keyword("SET SCHEMA");
12143 self.write_space();
12144 self.generate_identifier(schema)?;
12145 }
12146 AlterViewAction::SetAuthorization(auth) => {
12147 self.write_keyword("SET AUTHORIZATION");
12148 self.write_space();
12149 self.write(auth);
12150 }
12151 AlterViewAction::AlterColumn { name, action } => {
12152 self.write_keyword("ALTER COLUMN");
12153 self.write_space();
12154 self.generate_identifier(name)?;
12155 self.write_space();
12156 self.generate_alter_column_action(action)?;
12157 }
12158 AlterViewAction::AsSelect(query) => {
12159 self.write_keyword("AS");
12160 self.write_space();
12161 self.generate_expression(query)?;
12162 }
12163 AlterViewAction::SetTblproperties(props) => {
12164 self.write_keyword("SET TBLPROPERTIES");
12165 self.write(" (");
12166 for (i, (key, value)) in props.iter().enumerate() {
12167 if i > 0 {
12168 self.write(", ");
12169 }
12170 self.generate_string_literal(key)?;
12171 self.write("=");
12172 self.generate_string_literal(value)?;
12173 }
12174 self.write(")");
12175 }
12176 AlterViewAction::UnsetTblproperties(keys) => {
12177 self.write_keyword("UNSET TBLPROPERTIES");
12178 self.write(" (");
12179 for (i, key) in keys.iter().enumerate() {
12180 if i > 0 {
12181 self.write(", ");
12182 }
12183 self.generate_string_literal(key)?;
12184 }
12185 self.write(")");
12186 }
12187 }
12188 }
12189
12190 Ok(())
12191 }
12192
12193 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
12194 self.write_keyword("ALTER INDEX");
12195 self.write_space();
12196 self.generate_identifier(&ai.name)?;
12197
12198 if let Some(table) = &ai.table {
12199 self.write_space();
12200 self.write_keyword("ON");
12201 self.write_space();
12202 self.generate_table(table)?;
12203 }
12204
12205 for action in &ai.actions {
12206 self.write_space();
12207 match action {
12208 AlterIndexAction::Rename(new_name) => {
12209 self.write_keyword("RENAME TO");
12210 self.write_space();
12211 self.generate_identifier(new_name)?;
12212 }
12213 AlterIndexAction::SetTablespace(tablespace) => {
12214 self.write_keyword("SET TABLESPACE");
12215 self.write_space();
12216 self.generate_identifier(tablespace)?;
12217 }
12218 AlterIndexAction::Visible(visible) => {
12219 if *visible {
12220 self.write_keyword("VISIBLE");
12221 } else {
12222 self.write_keyword("INVISIBLE");
12223 }
12224 }
12225 }
12226 }
12227
12228 Ok(())
12229 }
12230
12231 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
12232 for comment in &cs.leading_comments {
12234 self.write_formatted_comment(comment);
12235 self.write_space();
12236 }
12237
12238 let saved_athena_hive_context = self.athena_hive_context;
12240 if matches!(
12241 self.config.dialect,
12242 Some(crate::dialects::DialectType::Athena)
12243 ) {
12244 self.athena_hive_context = true;
12245 }
12246
12247 self.write_keyword("CREATE SCHEMA");
12248
12249 if cs.if_not_exists {
12250 self.write_space();
12251 self.write_keyword("IF NOT EXISTS");
12252 }
12253
12254 self.write_space();
12255 for (i, part) in cs.name.iter().enumerate() {
12256 if i > 0 {
12257 self.write(".");
12258 }
12259 self.generate_identifier(part)?;
12260 }
12261
12262 if let Some(ref clone_parts) = cs.clone_from {
12263 self.write_keyword(" CLONE ");
12264 for (i, part) in clone_parts.iter().enumerate() {
12265 if i > 0 {
12266 self.write(".");
12267 }
12268 self.generate_identifier(part)?;
12269 }
12270 }
12271
12272 if let Some(ref at_clause) = cs.at_clause {
12273 self.write_space();
12274 self.generate_expression(at_clause)?;
12275 }
12276
12277 if let Some(auth) = &cs.authorization {
12278 self.write_space();
12279 self.write_keyword("AUTHORIZATION");
12280 self.write_space();
12281 self.generate_identifier(auth)?;
12282 }
12283
12284 let with_properties: Vec<_> = cs
12287 .properties
12288 .iter()
12289 .filter(|p| matches!(p, Expression::Property(_)))
12290 .collect();
12291 let other_properties: Vec<_> = cs
12292 .properties
12293 .iter()
12294 .filter(|p| !matches!(p, Expression::Property(_)))
12295 .collect();
12296
12297 if !with_properties.is_empty() {
12299 self.write_space();
12300 self.write_keyword("WITH");
12301 self.write(" (");
12302 for (i, prop) in with_properties.iter().enumerate() {
12303 if i > 0 {
12304 self.write(", ");
12305 }
12306 self.generate_expression(prop)?;
12307 }
12308 self.write(")");
12309 }
12310
12311 for prop in other_properties {
12313 self.write_space();
12314 self.generate_expression(prop)?;
12315 }
12316
12317 self.athena_hive_context = saved_athena_hive_context;
12319
12320 Ok(())
12321 }
12322
12323 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
12324 self.write_keyword("DROP SCHEMA");
12325
12326 if ds.if_exists {
12327 self.write_space();
12328 self.write_keyword("IF EXISTS");
12329 }
12330
12331 self.write_space();
12332 self.generate_identifier(&ds.name)?;
12333
12334 if ds.cascade {
12335 self.write_space();
12336 self.write_keyword("CASCADE");
12337 }
12338
12339 Ok(())
12340 }
12341
12342 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
12343 self.write_keyword("DROP NAMESPACE");
12344
12345 if dn.if_exists {
12346 self.write_space();
12347 self.write_keyword("IF EXISTS");
12348 }
12349
12350 self.write_space();
12351 self.generate_identifier(&dn.name)?;
12352
12353 if dn.cascade {
12354 self.write_space();
12355 self.write_keyword("CASCADE");
12356 }
12357
12358 Ok(())
12359 }
12360
12361 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
12362 self.write_keyword("CREATE DATABASE");
12363
12364 if cd.if_not_exists {
12365 self.write_space();
12366 self.write_keyword("IF NOT EXISTS");
12367 }
12368
12369 self.write_space();
12370 self.generate_identifier(&cd.name)?;
12371
12372 if let Some(ref clone_src) = cd.clone_from {
12373 self.write_keyword(" CLONE ");
12374 self.generate_identifier(clone_src)?;
12375 }
12376
12377 if let Some(ref at_clause) = cd.at_clause {
12379 self.write_space();
12380 self.generate_expression(at_clause)?;
12381 }
12382
12383 for option in &cd.options {
12384 self.write_space();
12385 match option {
12386 DatabaseOption::CharacterSet(charset) => {
12387 self.write_keyword("CHARACTER SET");
12388 self.write(" = ");
12389 self.write(&format!("'{}'", charset));
12390 }
12391 DatabaseOption::Collate(collate) => {
12392 self.write_keyword("COLLATE");
12393 self.write(" = ");
12394 self.write(&format!("'{}'", collate));
12395 }
12396 DatabaseOption::Owner(owner) => {
12397 self.write_keyword("OWNER");
12398 self.write(" = ");
12399 self.generate_identifier(owner)?;
12400 }
12401 DatabaseOption::Template(template) => {
12402 self.write_keyword("TEMPLATE");
12403 self.write(" = ");
12404 self.generate_identifier(template)?;
12405 }
12406 DatabaseOption::Encoding(encoding) => {
12407 self.write_keyword("ENCODING");
12408 self.write(" = ");
12409 self.write(&format!("'{}'", encoding));
12410 }
12411 DatabaseOption::Location(location) => {
12412 self.write_keyword("LOCATION");
12413 self.write(" = ");
12414 self.write(&format!("'{}'", location));
12415 }
12416 }
12417 }
12418
12419 Ok(())
12420 }
12421
12422 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
12423 self.write_keyword("DROP DATABASE");
12424
12425 if dd.if_exists {
12426 self.write_space();
12427 self.write_keyword("IF EXISTS");
12428 }
12429
12430 self.write_space();
12431 self.generate_identifier(&dd.name)?;
12432
12433 if dd.sync {
12434 self.write_space();
12435 self.write_keyword("SYNC");
12436 }
12437
12438 Ok(())
12439 }
12440
12441 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
12442 self.write_keyword("CREATE");
12443
12444 if cf.or_alter {
12445 self.write_space();
12446 self.write_keyword("OR ALTER");
12447 } else if cf.or_replace {
12448 self.write_space();
12449 self.write_keyword("OR REPLACE");
12450 }
12451
12452 if cf.temporary {
12453 self.write_space();
12454 self.write_keyword("TEMPORARY");
12455 }
12456
12457 self.write_space();
12458 if cf.is_table_function {
12459 self.write_keyword("TABLE FUNCTION");
12460 } else {
12461 self.write_keyword("FUNCTION");
12462 }
12463
12464 if cf.if_not_exists {
12465 self.write_space();
12466 self.write_keyword("IF NOT EXISTS");
12467 }
12468
12469 self.write_space();
12470 self.generate_table(&cf.name)?;
12471 if cf.has_parens {
12472 let func_multiline = self.config.pretty
12473 && matches!(
12474 self.config.dialect,
12475 Some(crate::dialects::DialectType::TSQL)
12476 | Some(crate::dialects::DialectType::Fabric)
12477 )
12478 && !cf.parameters.is_empty();
12479 if func_multiline {
12480 self.write("(\n");
12481 self.indent_level += 2;
12482 self.write_indent();
12483 self.generate_function_parameters(&cf.parameters)?;
12484 self.write("\n");
12485 self.indent_level -= 2;
12486 self.write(")");
12487 } else {
12488 self.write("(");
12489 self.generate_function_parameters(&cf.parameters)?;
12490 self.write(")");
12491 }
12492 }
12493
12494 let use_multiline = self.config.pretty
12497 && matches!(
12498 self.config.dialect,
12499 Some(crate::dialects::DialectType::BigQuery)
12500 | Some(crate::dialects::DialectType::TSQL)
12501 | Some(crate::dialects::DialectType::Fabric)
12502 );
12503
12504 if cf.language_first {
12505 if let Some(lang) = &cf.language {
12507 if use_multiline {
12508 self.write_newline();
12509 } else {
12510 self.write_space();
12511 }
12512 self.write_keyword("LANGUAGE");
12513 self.write_space();
12514 self.write(lang);
12515 }
12516
12517 if let Some(sql_data) = &cf.sql_data_access {
12519 self.write_space();
12520 match sql_data {
12521 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12522 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12523 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12524 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12525 }
12526 }
12527
12528 if let Some(ref rtb) = cf.returns_table_body {
12529 if use_multiline {
12530 self.write_newline();
12531 } else {
12532 self.write_space();
12533 }
12534 self.write_keyword("RETURNS");
12535 self.write_space();
12536 self.write(rtb);
12537 } else if let Some(return_type) = &cf.return_type {
12538 if use_multiline {
12539 self.write_newline();
12540 } else {
12541 self.write_space();
12542 }
12543 self.write_keyword("RETURNS");
12544 self.write_space();
12545 self.generate_data_type(return_type)?;
12546 }
12547 } else {
12548 let is_duckdb = matches!(
12551 self.config.dialect,
12552 Some(crate::dialects::DialectType::DuckDB)
12553 );
12554 if let Some(ref rtb) = cf.returns_table_body {
12555 if !(is_duckdb && rtb.is_empty()) {
12556 if use_multiline {
12557 self.write_newline();
12558 } else {
12559 self.write_space();
12560 }
12561 self.write_keyword("RETURNS");
12562 self.write_space();
12563 self.write(rtb);
12564 }
12565 } else if let Some(return_type) = &cf.return_type {
12566 if !is_duckdb {
12568 let is_table_return = matches!(return_type, crate::expressions::DataType::Custom { ref name } if name.eq_ignore_ascii_case("TABLE"));
12569 if use_multiline {
12570 self.write_newline();
12571 } else {
12572 self.write_space();
12573 }
12574 self.write_keyword("RETURNS");
12575 self.write_space();
12576 if is_table_return {
12577 self.write_keyword("TABLE");
12578 } else {
12579 self.generate_data_type(return_type)?;
12580 }
12581 }
12582 }
12583 }
12584
12585 if !cf.property_order.is_empty() {
12587 let is_bigquery = matches!(
12589 self.config.dialect,
12590 Some(crate::dialects::DialectType::BigQuery)
12591 );
12592 let property_order = if is_bigquery {
12593 let mut reordered = Vec::new();
12595 let mut has_as = false;
12596 let mut has_options = false;
12597 for prop in &cf.property_order {
12598 match prop {
12599 FunctionPropertyKind::As => has_as = true,
12600 FunctionPropertyKind::Options => has_options = true,
12601 _ => {}
12602 }
12603 }
12604 if has_as && has_options {
12605 for prop in &cf.property_order {
12607 if *prop != FunctionPropertyKind::As
12608 && *prop != FunctionPropertyKind::Options
12609 {
12610 reordered.push(*prop);
12611 }
12612 }
12613 reordered.push(FunctionPropertyKind::Options);
12614 reordered.push(FunctionPropertyKind::As);
12615 reordered
12616 } else {
12617 cf.property_order.clone()
12618 }
12619 } else {
12620 cf.property_order.clone()
12621 };
12622
12623 for prop in &property_order {
12624 match prop {
12625 FunctionPropertyKind::Set => {
12626 self.generate_function_set_options(cf)?;
12627 }
12628 FunctionPropertyKind::As => {
12629 self.generate_function_body(cf)?;
12630 }
12631 FunctionPropertyKind::Using => {
12632 self.generate_function_using_resources(cf)?;
12633 }
12634 FunctionPropertyKind::Language => {
12635 if !cf.language_first {
12636 if let Some(lang) = &cf.language {
12638 let use_multiline = self.config.pretty
12640 && matches!(
12641 self.config.dialect,
12642 Some(crate::dialects::DialectType::BigQuery)
12643 );
12644 if use_multiline {
12645 self.write_newline();
12646 } else {
12647 self.write_space();
12648 }
12649 self.write_keyword("LANGUAGE");
12650 self.write_space();
12651 self.write(lang);
12652 }
12653 }
12654 }
12655 FunctionPropertyKind::Determinism => {
12656 self.generate_function_determinism(cf)?;
12657 }
12658 FunctionPropertyKind::NullInput => {
12659 self.generate_function_null_input(cf)?;
12660 }
12661 FunctionPropertyKind::Security => {
12662 self.generate_function_security(cf)?;
12663 }
12664 FunctionPropertyKind::SqlDataAccess => {
12665 if !cf.language_first {
12666 self.generate_function_sql_data_access(cf)?;
12668 }
12669 }
12670 FunctionPropertyKind::Options => {
12671 if !cf.options.is_empty() {
12672 self.write_space();
12673 self.generate_options_clause(&cf.options)?;
12674 }
12675 }
12676 FunctionPropertyKind::Environment => {
12677 if !cf.environment.is_empty() {
12678 self.write_space();
12679 self.generate_environment_clause(&cf.environment)?;
12680 }
12681 }
12682 FunctionPropertyKind::Handler => {
12683 if let Some(ref h) = cf.handler {
12684 self.write_space();
12685 self.write_keyword("HANDLER");
12686 if cf.handler_uses_eq {
12687 self.write(" = ");
12688 } else {
12689 self.write_space();
12690 }
12691 self.write("'");
12692 self.write(h);
12693 self.write("'");
12694 }
12695 }
12696 FunctionPropertyKind::RuntimeVersion => {
12697 if let Some(ref runtime_version) = cf.runtime_version {
12698 self.write_space();
12699 self.write_keyword("RUNTIME_VERSION");
12700 self.write("='");
12701 self.write(runtime_version);
12702 self.write("'");
12703 }
12704 }
12705 FunctionPropertyKind::Packages => {
12706 if let Some(ref packages) = cf.packages {
12707 self.write_space();
12708 self.write_keyword("PACKAGES");
12709 self.write("=(");
12710 for (i, package) in packages.iter().enumerate() {
12711 if i > 0 {
12712 self.write(", ");
12713 }
12714 self.write("'");
12715 self.write(package);
12716 self.write("'");
12717 }
12718 self.write(")");
12719 }
12720 }
12721 FunctionPropertyKind::ParameterStyle => {
12722 if let Some(ref ps) = cf.parameter_style {
12723 self.write_space();
12724 self.write_keyword("PARAMETER STYLE");
12725 self.write_space();
12726 self.write_keyword(ps);
12727 }
12728 }
12729 }
12730 }
12731
12732 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
12734 {
12735 self.write_space();
12736 self.generate_options_clause(&cf.options)?;
12737 }
12738
12739 if !cf.environment.is_empty()
12741 && !cf
12742 .property_order
12743 .contains(&FunctionPropertyKind::Environment)
12744 {
12745 self.write_space();
12746 self.generate_environment_clause(&cf.environment)?;
12747 }
12748 } else {
12749 if matches!(
12752 self.config.dialect,
12753 Some(crate::dialects::DialectType::BigQuery)
12754 ) {
12755 self.generate_function_determinism(cf)?;
12756 }
12757
12758 let use_multiline = self.config.pretty
12760 && matches!(
12761 self.config.dialect,
12762 Some(crate::dialects::DialectType::BigQuery)
12763 );
12764
12765 if !cf.language_first {
12766 if let Some(lang) = &cf.language {
12767 if use_multiline {
12768 self.write_newline();
12769 } else {
12770 self.write_space();
12771 }
12772 self.write_keyword("LANGUAGE");
12773 self.write_space();
12774 self.write(lang);
12775 }
12776
12777 self.generate_function_sql_data_access(cf)?;
12779 }
12780
12781 if !matches!(
12783 self.config.dialect,
12784 Some(crate::dialects::DialectType::BigQuery)
12785 ) {
12786 self.generate_function_determinism(cf)?;
12787 }
12788
12789 self.generate_function_null_input(cf)?;
12790 self.generate_function_security(cf)?;
12791 self.generate_function_set_options(cf)?;
12792
12793 if !cf.options.is_empty() {
12795 self.write_space();
12796 self.generate_options_clause(&cf.options)?;
12797 }
12798
12799 if !cf.environment.is_empty() {
12801 self.write_space();
12802 self.generate_environment_clause(&cf.environment)?;
12803 }
12804
12805 if let Some(ref h) = cf.handler {
12806 self.write_space();
12807 self.write_keyword("HANDLER");
12808 if cf.handler_uses_eq {
12809 self.write(" = ");
12810 } else {
12811 self.write_space();
12812 }
12813 self.write("'");
12814 self.write(h);
12815 self.write("'");
12816 }
12817
12818 if let Some(ref runtime_version) = cf.runtime_version {
12819 self.write_space();
12820 self.write_keyword("RUNTIME_VERSION");
12821 self.write("='");
12822 self.write(runtime_version);
12823 self.write("'");
12824 }
12825
12826 if let Some(ref packages) = cf.packages {
12827 self.write_space();
12828 self.write_keyword("PACKAGES");
12829 self.write("=(");
12830 for (i, package) in packages.iter().enumerate() {
12831 if i > 0 {
12832 self.write(", ");
12833 }
12834 self.write("'");
12835 self.write(package);
12836 self.write("'");
12837 }
12838 self.write(")");
12839 }
12840
12841 self.generate_function_body(cf)?;
12842 self.generate_function_using_resources(cf)?;
12843 }
12844
12845 Ok(())
12846 }
12847
12848 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
12850 for opt in &cf.set_options {
12851 self.write_space();
12852 self.write_keyword("SET");
12853 self.write_space();
12854 self.write(&opt.name);
12855 match &opt.value {
12856 FunctionSetValue::Value { value, use_to } => {
12857 if *use_to {
12858 self.write(" TO ");
12859 } else {
12860 self.write(" = ");
12861 }
12862 self.write(value);
12863 }
12864 FunctionSetValue::FromCurrent => {
12865 self.write_space();
12866 self.write_keyword("FROM CURRENT");
12867 }
12868 }
12869 }
12870 Ok(())
12871 }
12872
12873 fn generate_function_using_resources(&mut self, cf: &CreateFunction) -> Result<()> {
12874 if cf.using_resources.is_empty() {
12875 return Ok(());
12876 }
12877
12878 self.write_space();
12879 self.write_keyword("USING");
12880 for resource in &cf.using_resources {
12881 self.write_space();
12882 self.write_keyword(&resource.kind);
12883 self.write_space();
12884 self.generate_string_literal(&resource.uri)?;
12885 }
12886 Ok(())
12887 }
12888
12889 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
12891 if let Some(body) = &cf.body {
12892 self.write_space();
12894 let use_multiline = self.config.pretty
12896 && matches!(
12897 self.config.dialect,
12898 Some(crate::dialects::DialectType::BigQuery)
12899 );
12900 match body {
12901 FunctionBody::Block(block) => {
12902 self.write_keyword("AS");
12903 if matches!(
12904 self.config.dialect,
12905 Some(crate::dialects::DialectType::TSQL)
12906 ) {
12907 self.write(" BEGIN ");
12908 self.write(block);
12909 self.write(" END");
12910 } else if matches!(
12911 self.config.dialect,
12912 Some(crate::dialects::DialectType::PostgreSQL)
12913 ) {
12914 self.write(" $$");
12915 self.write(block);
12916 self.write("$$");
12917 } else {
12918 let escaped = self.escape_block_for_single_quote(block);
12920 if use_multiline {
12922 self.write_newline();
12923 } else {
12924 self.write(" ");
12925 }
12926 self.write("'");
12927 self.write(&escaped);
12928 self.write("'");
12929 }
12930 }
12931 FunctionBody::StringLiteral(s) => {
12932 self.write_keyword("AS");
12933 if use_multiline {
12935 self.write_newline();
12936 } else {
12937 self.write(" ");
12938 }
12939 self.write("'");
12940 self.write(s);
12941 self.write("'");
12942 }
12943 FunctionBody::Expression(expr) => {
12944 self.write_keyword("AS");
12945 self.write_space();
12946 self.generate_expression(expr)?;
12947 }
12948 FunctionBody::External(name) => {
12949 self.write_keyword("EXTERNAL NAME");
12950 self.write(" '");
12951 self.write(name);
12952 self.write("'");
12953 }
12954 FunctionBody::Return(expr) => {
12955 if matches!(
12956 self.config.dialect,
12957 Some(crate::dialects::DialectType::DuckDB)
12958 ) {
12959 self.write_keyword("AS");
12961 self.write_space();
12962 let is_table_return = cf.returns_table_body.is_some()
12964 || matches!(&cf.return_type, Some(crate::expressions::DataType::Custom { ref name }) if name.eq_ignore_ascii_case("TABLE"));
12965 if is_table_return {
12966 self.write_keyword("TABLE");
12967 self.write_space();
12968 }
12969 self.generate_expression(expr)?;
12970 } else {
12971 if self.config.create_function_return_as {
12972 self.write_keyword("AS");
12973 if self.config.pretty
12975 && matches!(
12976 self.config.dialect,
12977 Some(crate::dialects::DialectType::TSQL)
12978 | Some(crate::dialects::DialectType::Fabric)
12979 )
12980 {
12981 self.write_newline();
12982 } else {
12983 self.write_space();
12984 }
12985 }
12986 self.write_keyword("RETURN");
12987 self.write_space();
12988 self.generate_expression(expr)?;
12989 }
12990 }
12991 FunctionBody::Statements(stmts) => {
12992 self.write_keyword("AS");
12993 self.write(" BEGIN ");
12994 for (i, stmt) in stmts.iter().enumerate() {
12995 if i > 0 {
12996 self.write(" ");
12997 }
12998 self.generate_expression(stmt)?;
12999 self.write(";");
13000 }
13001 self.write(" END");
13002 }
13003 FunctionBody::RawBlock(text) => {
13004 self.write_newline();
13005 self.write(text);
13006 }
13007 FunctionBody::DollarQuoted { content, tag } => {
13008 self.write_keyword("AS");
13009 self.write(" ");
13010 let supports_dollar_quoting = matches!(
13012 self.config.dialect,
13013 Some(crate::dialects::DialectType::PostgreSQL)
13014 | Some(crate::dialects::DialectType::Databricks)
13015 | Some(crate::dialects::DialectType::Redshift)
13016 | Some(crate::dialects::DialectType::DuckDB)
13017 );
13018 if supports_dollar_quoting {
13019 self.write("$");
13021 if let Some(t) = tag {
13022 self.write(t);
13023 }
13024 self.write("$");
13025 self.write(content);
13026 self.write("$");
13027 if let Some(t) = tag {
13028 self.write(t);
13029 }
13030 self.write("$");
13031 } else {
13032 let escaped = self.escape_block_for_single_quote(content);
13034 self.write("'");
13035 self.write(&escaped);
13036 self.write("'");
13037 }
13038 }
13039 }
13040 }
13041 Ok(())
13042 }
13043
13044 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
13046 if let Some(det) = cf.deterministic {
13047 self.write_space();
13048 if matches!(
13049 self.config.dialect,
13050 Some(crate::dialects::DialectType::BigQuery)
13051 ) {
13052 if det {
13054 self.write_keyword("DETERMINISTIC");
13055 } else {
13056 self.write_keyword("NOT DETERMINISTIC");
13057 }
13058 } else {
13059 if det {
13061 self.write_keyword("IMMUTABLE");
13062 } else {
13063 self.write_keyword("VOLATILE");
13064 }
13065 }
13066 }
13067 Ok(())
13068 }
13069
13070 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
13072 if let Some(returns_null) = cf.returns_null_on_null_input {
13073 self.write_space();
13074 if returns_null {
13075 if cf.strict {
13076 self.write_keyword("STRICT");
13077 } else {
13078 self.write_keyword("RETURNS NULL ON NULL INPUT");
13079 }
13080 } else {
13081 self.write_keyword("CALLED ON NULL INPUT");
13082 }
13083 }
13084 Ok(())
13085 }
13086
13087 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
13089 if let Some(security) = &cf.security {
13090 self.write_space();
13091 if matches!(
13093 self.config.dialect,
13094 Some(crate::dialects::DialectType::MySQL)
13095 ) {
13096 self.write_keyword("SQL SECURITY");
13097 } else {
13098 self.write_keyword("SECURITY");
13099 }
13100 self.write_space();
13101 match security {
13102 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13103 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13104 FunctionSecurity::None => self.write_keyword("NONE"),
13105 }
13106 }
13107 Ok(())
13108 }
13109
13110 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
13112 if let Some(sql_data) = &cf.sql_data_access {
13113 self.write_space();
13114 match sql_data {
13115 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
13116 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
13117 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
13118 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
13119 }
13120 }
13121 Ok(())
13122 }
13123
13124 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
13125 for (i, param) in params.iter().enumerate() {
13126 if i > 0 {
13127 self.write(", ");
13128 }
13129
13130 if let Some(mode) = ¶m.mode {
13131 if let Some(text) = ¶m.mode_text {
13132 self.write(text);
13133 } else {
13134 match mode {
13135 ParameterMode::In => self.write_keyword("IN"),
13136 ParameterMode::Out => self.write_keyword("OUT"),
13137 ParameterMode::InOut => self.write_keyword("INOUT"),
13138 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
13139 }
13140 }
13141 self.write_space();
13142 }
13143
13144 if let Some(name) = ¶m.name {
13145 self.generate_identifier(name)?;
13146 let skip_type =
13148 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
13149 if !skip_type {
13150 self.write_space();
13151 self.generate_data_type(¶m.data_type)?;
13152 }
13153 } else {
13154 self.generate_data_type(¶m.data_type)?;
13155 }
13156
13157 if let Some(default) = ¶m.default {
13158 if self.config.parameter_default_equals {
13159 self.write(" = ");
13160 } else {
13161 self.write(" DEFAULT ");
13162 }
13163 self.generate_expression(default)?;
13164 }
13165 }
13166
13167 Ok(())
13168 }
13169
13170 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
13171 self.write_keyword("DROP FUNCTION");
13172
13173 if df.if_exists {
13174 self.write_space();
13175 self.write_keyword("IF EXISTS");
13176 }
13177
13178 self.write_space();
13179 self.generate_table(&df.name)?;
13180
13181 if let Some(params) = &df.parameters {
13182 self.write(" (");
13183 for (i, dt) in params.iter().enumerate() {
13184 if i > 0 {
13185 self.write(", ");
13186 }
13187 self.generate_data_type(dt)?;
13188 }
13189 self.write(")");
13190 }
13191
13192 if df.cascade {
13193 self.write_space();
13194 self.write_keyword("CASCADE");
13195 }
13196
13197 Ok(())
13198 }
13199
13200 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
13201 self.write_keyword("CREATE");
13202
13203 if cp.or_alter {
13204 self.write_space();
13205 self.write_keyword("OR ALTER");
13206 } else if cp.or_replace {
13207 self.write_space();
13208 self.write_keyword("OR REPLACE");
13209 }
13210
13211 self.write_space();
13212 if cp.use_proc_keyword {
13213 self.write_keyword("PROC");
13214 } else {
13215 self.write_keyword("PROCEDURE");
13216 }
13217
13218 if cp.if_not_exists {
13219 self.write_space();
13220 self.write_keyword("IF NOT EXISTS");
13221 }
13222
13223 self.write_space();
13224 self.generate_table(&cp.name)?;
13225 if cp.has_parens {
13226 self.write("(");
13227 self.generate_function_parameters(&cp.parameters)?;
13228 self.write(")");
13229 } else if !cp.parameters.is_empty() {
13230 self.write_space();
13232 self.generate_function_parameters(&cp.parameters)?;
13233 }
13234
13235 if let Some(return_type) = &cp.return_type {
13237 self.write_space();
13238 self.write_keyword("RETURNS");
13239 self.write_space();
13240 self.generate_data_type(return_type)?;
13241 }
13242
13243 if let Some(execute_as) = &cp.execute_as {
13245 self.write_space();
13246 self.write_keyword("EXECUTE AS");
13247 self.write_space();
13248 self.write_keyword(execute_as);
13249 }
13250
13251 if let Some(lang) = &cp.language {
13252 self.write_space();
13253 self.write_keyword("LANGUAGE");
13254 self.write_space();
13255 self.write(lang);
13256 }
13257
13258 if let Some(security) = &cp.security {
13259 self.write_space();
13260 self.write_keyword("SECURITY");
13261 self.write_space();
13262 match security {
13263 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13264 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13265 FunctionSecurity::None => self.write_keyword("NONE"),
13266 }
13267 }
13268
13269 if !cp.with_options.is_empty() {
13271 self.write_space();
13272 self.write_keyword("WITH");
13273 self.write_space();
13274 for (i, opt) in cp.with_options.iter().enumerate() {
13275 if i > 0 {
13276 self.write(", ");
13277 }
13278 self.write(opt);
13279 }
13280 }
13281
13282 if let Some(body) = &cp.body {
13283 self.write_space();
13284 match body {
13285 FunctionBody::Block(block) => {
13286 self.write_keyword("AS");
13287 if matches!(
13288 self.config.dialect,
13289 Some(crate::dialects::DialectType::TSQL)
13290 ) {
13291 self.write(" BEGIN ");
13292 self.write(block);
13293 self.write(" END");
13294 } else if matches!(
13295 self.config.dialect,
13296 Some(crate::dialects::DialectType::PostgreSQL)
13297 ) {
13298 self.write(" $$");
13299 self.write(block);
13300 self.write("$$");
13301 } else {
13302 let escaped = self.escape_block_for_single_quote(block);
13304 self.write(" '");
13305 self.write(&escaped);
13306 self.write("'");
13307 }
13308 }
13309 FunctionBody::StringLiteral(s) => {
13310 self.write_keyword("AS");
13311 self.write(" '");
13312 self.write(s);
13313 self.write("'");
13314 }
13315 FunctionBody::Expression(expr) => {
13316 self.write_keyword("AS");
13317 self.write_space();
13318 self.generate_expression(expr)?;
13319 }
13320 FunctionBody::External(name) => {
13321 self.write_keyword("EXTERNAL NAME");
13322 self.write(" '");
13323 self.write(name);
13324 self.write("'");
13325 }
13326 FunctionBody::Return(expr) => {
13327 self.write_keyword("RETURN");
13328 self.write_space();
13329 self.generate_expression(expr)?;
13330 }
13331 FunctionBody::Statements(stmts) => {
13332 self.write_keyword("AS");
13333 self.write(" BEGIN ");
13334 for (i, stmt) in stmts.iter().enumerate() {
13335 if i > 0 {
13336 self.write(" ");
13337 }
13338 self.generate_expression(stmt)?;
13339 self.write(";");
13340 }
13341 self.write(" END");
13342 }
13343 FunctionBody::RawBlock(text) => {
13344 self.write_newline();
13345 self.write(text);
13346 }
13347 FunctionBody::DollarQuoted { content, tag } => {
13348 self.write_keyword("AS");
13349 self.write(" ");
13350 let supports_dollar_quoting = matches!(
13352 self.config.dialect,
13353 Some(crate::dialects::DialectType::PostgreSQL)
13354 | Some(crate::dialects::DialectType::Databricks)
13355 | Some(crate::dialects::DialectType::Redshift)
13356 | Some(crate::dialects::DialectType::DuckDB)
13357 );
13358 if supports_dollar_quoting {
13359 self.write("$");
13361 if let Some(t) = tag {
13362 self.write(t);
13363 }
13364 self.write("$");
13365 self.write(content);
13366 self.write("$");
13367 if let Some(t) = tag {
13368 self.write(t);
13369 }
13370 self.write("$");
13371 } else {
13372 let escaped = self.escape_block_for_single_quote(content);
13374 self.write("'");
13375 self.write(&escaped);
13376 self.write("'");
13377 }
13378 }
13379 }
13380 }
13381
13382 Ok(())
13383 }
13384
13385 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
13386 self.write_keyword("DROP PROCEDURE");
13387
13388 if dp.if_exists {
13389 self.write_space();
13390 self.write_keyword("IF EXISTS");
13391 }
13392
13393 self.write_space();
13394 self.generate_table(&dp.name)?;
13395
13396 if let Some(params) = &dp.parameters {
13397 self.write(" (");
13398 for (i, dt) in params.iter().enumerate() {
13399 if i > 0 {
13400 self.write(", ");
13401 }
13402 self.generate_data_type(dt)?;
13403 }
13404 self.write(")");
13405 }
13406
13407 if dp.cascade {
13408 self.write_space();
13409 self.write_keyword("CASCADE");
13410 }
13411
13412 Ok(())
13413 }
13414
13415 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
13416 self.write_keyword("CREATE");
13417
13418 if cs.or_replace {
13419 self.write_space();
13420 self.write_keyword("OR REPLACE");
13421 }
13422
13423 if cs.temporary {
13424 self.write_space();
13425 self.write_keyword("TEMPORARY");
13426 }
13427
13428 self.write_space();
13429 self.write_keyword("SEQUENCE");
13430
13431 if cs.if_not_exists {
13432 self.write_space();
13433 self.write_keyword("IF NOT EXISTS");
13434 }
13435
13436 self.write_space();
13437 self.generate_table(&cs.name)?;
13438
13439 if let Some(as_type) = &cs.as_type {
13441 self.write_space();
13442 self.write_keyword("AS");
13443 self.write_space();
13444 self.generate_data_type(as_type)?;
13445 }
13446
13447 if let Some(comment) = &cs.comment {
13449 self.write_space();
13450 self.write_keyword("COMMENT");
13451 self.write("=");
13452 self.generate_string_literal(comment)?;
13453 }
13454
13455 if !cs.property_order.is_empty() {
13457 for prop in &cs.property_order {
13458 match prop {
13459 SeqPropKind::Start => {
13460 if let Some(start) = cs.start {
13461 self.write_space();
13462 self.write_keyword("START WITH");
13463 self.write(&format!(" {}", start));
13464 }
13465 }
13466 SeqPropKind::Increment => {
13467 if let Some(inc) = cs.increment {
13468 self.write_space();
13469 self.write_keyword("INCREMENT BY");
13470 self.write(&format!(" {}", inc));
13471 }
13472 }
13473 SeqPropKind::Minvalue => {
13474 if let Some(min) = &cs.minvalue {
13475 self.write_space();
13476 match min {
13477 SequenceBound::Value(v) => {
13478 self.write_keyword("MINVALUE");
13479 self.write(&format!(" {}", v));
13480 }
13481 SequenceBound::None => {
13482 self.write_keyword("NO MINVALUE");
13483 }
13484 }
13485 }
13486 }
13487 SeqPropKind::Maxvalue => {
13488 if let Some(max) = &cs.maxvalue {
13489 self.write_space();
13490 match max {
13491 SequenceBound::Value(v) => {
13492 self.write_keyword("MAXVALUE");
13493 self.write(&format!(" {}", v));
13494 }
13495 SequenceBound::None => {
13496 self.write_keyword("NO MAXVALUE");
13497 }
13498 }
13499 }
13500 }
13501 SeqPropKind::Cache => {
13502 if let Some(cache) = cs.cache {
13503 self.write_space();
13504 self.write_keyword("CACHE");
13505 self.write(&format!(" {}", cache));
13506 }
13507 }
13508 SeqPropKind::NoCache => {
13509 self.write_space();
13510 self.write_keyword("NO CACHE");
13511 }
13512 SeqPropKind::NoCacheWord => {
13513 self.write_space();
13514 self.write_keyword("NOCACHE");
13515 }
13516 SeqPropKind::Cycle => {
13517 self.write_space();
13518 self.write_keyword("CYCLE");
13519 }
13520 SeqPropKind::NoCycle => {
13521 self.write_space();
13522 self.write_keyword("NO CYCLE");
13523 }
13524 SeqPropKind::NoCycleWord => {
13525 self.write_space();
13526 self.write_keyword("NOCYCLE");
13527 }
13528 SeqPropKind::OwnedBy => {
13529 if !cs.owned_by_none {
13531 if let Some(owned) = &cs.owned_by {
13532 self.write_space();
13533 self.write_keyword("OWNED BY");
13534 self.write_space();
13535 self.generate_table(owned)?;
13536 }
13537 }
13538 }
13539 SeqPropKind::Order => {
13540 self.write_space();
13541 self.write_keyword("ORDER");
13542 }
13543 SeqPropKind::NoOrder => {
13544 self.write_space();
13545 self.write_keyword("NOORDER");
13546 }
13547 SeqPropKind::Comment => {
13548 }
13550 SeqPropKind::Sharing => {
13551 if let Some(val) = &cs.sharing {
13552 self.write_space();
13553 self.write(&format!("SHARING={}", val));
13554 }
13555 }
13556 SeqPropKind::Keep => {
13557 self.write_space();
13558 self.write_keyword("KEEP");
13559 }
13560 SeqPropKind::NoKeep => {
13561 self.write_space();
13562 self.write_keyword("NOKEEP");
13563 }
13564 SeqPropKind::Scale => {
13565 self.write_space();
13566 self.write_keyword("SCALE");
13567 if let Some(modifier) = &cs.scale_modifier {
13568 if !modifier.is_empty() {
13569 self.write_space();
13570 self.write_keyword(modifier);
13571 }
13572 }
13573 }
13574 SeqPropKind::NoScale => {
13575 self.write_space();
13576 self.write_keyword("NOSCALE");
13577 }
13578 SeqPropKind::Shard => {
13579 self.write_space();
13580 self.write_keyword("SHARD");
13581 if let Some(modifier) = &cs.shard_modifier {
13582 if !modifier.is_empty() {
13583 self.write_space();
13584 self.write_keyword(modifier);
13585 }
13586 }
13587 }
13588 SeqPropKind::NoShard => {
13589 self.write_space();
13590 self.write_keyword("NOSHARD");
13591 }
13592 SeqPropKind::Session => {
13593 self.write_space();
13594 self.write_keyword("SESSION");
13595 }
13596 SeqPropKind::Global => {
13597 self.write_space();
13598 self.write_keyword("GLOBAL");
13599 }
13600 SeqPropKind::NoMinvalueWord => {
13601 self.write_space();
13602 self.write_keyword("NOMINVALUE");
13603 }
13604 SeqPropKind::NoMaxvalueWord => {
13605 self.write_space();
13606 self.write_keyword("NOMAXVALUE");
13607 }
13608 }
13609 }
13610 } else {
13611 if let Some(inc) = cs.increment {
13613 self.write_space();
13614 self.write_keyword("INCREMENT BY");
13615 self.write(&format!(" {}", inc));
13616 }
13617
13618 if let Some(min) = &cs.minvalue {
13619 self.write_space();
13620 match min {
13621 SequenceBound::Value(v) => {
13622 self.write_keyword("MINVALUE");
13623 self.write(&format!(" {}", v));
13624 }
13625 SequenceBound::None => {
13626 self.write_keyword("NO MINVALUE");
13627 }
13628 }
13629 }
13630
13631 if let Some(max) = &cs.maxvalue {
13632 self.write_space();
13633 match max {
13634 SequenceBound::Value(v) => {
13635 self.write_keyword("MAXVALUE");
13636 self.write(&format!(" {}", v));
13637 }
13638 SequenceBound::None => {
13639 self.write_keyword("NO MAXVALUE");
13640 }
13641 }
13642 }
13643
13644 if let Some(start) = cs.start {
13645 self.write_space();
13646 self.write_keyword("START WITH");
13647 self.write(&format!(" {}", start));
13648 }
13649
13650 if let Some(cache) = cs.cache {
13651 self.write_space();
13652 self.write_keyword("CACHE");
13653 self.write(&format!(" {}", cache));
13654 }
13655
13656 if cs.cycle {
13657 self.write_space();
13658 self.write_keyword("CYCLE");
13659 }
13660
13661 if let Some(owned) = &cs.owned_by {
13662 self.write_space();
13663 self.write_keyword("OWNED BY");
13664 self.write_space();
13665 self.generate_table(owned)?;
13666 }
13667 }
13668
13669 Ok(())
13670 }
13671
13672 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
13673 self.write_keyword("DROP SEQUENCE");
13674
13675 if ds.if_exists {
13676 self.write_space();
13677 self.write_keyword("IF EXISTS");
13678 }
13679
13680 self.write_space();
13681 self.generate_table(&ds.name)?;
13682
13683 if ds.cascade {
13684 self.write_space();
13685 self.write_keyword("CASCADE");
13686 }
13687
13688 Ok(())
13689 }
13690
13691 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
13692 self.write_keyword("ALTER SEQUENCE");
13693
13694 if als.if_exists {
13695 self.write_space();
13696 self.write_keyword("IF EXISTS");
13697 }
13698
13699 self.write_space();
13700 self.generate_table(&als.name)?;
13701
13702 if let Some(inc) = als.increment {
13703 self.write_space();
13704 self.write_keyword("INCREMENT BY");
13705 self.write(&format!(" {}", inc));
13706 }
13707
13708 if let Some(min) = &als.minvalue {
13709 self.write_space();
13710 match min {
13711 SequenceBound::Value(v) => {
13712 self.write_keyword("MINVALUE");
13713 self.write(&format!(" {}", v));
13714 }
13715 SequenceBound::None => {
13716 self.write_keyword("NO MINVALUE");
13717 }
13718 }
13719 }
13720
13721 if let Some(max) = &als.maxvalue {
13722 self.write_space();
13723 match max {
13724 SequenceBound::Value(v) => {
13725 self.write_keyword("MAXVALUE");
13726 self.write(&format!(" {}", v));
13727 }
13728 SequenceBound::None => {
13729 self.write_keyword("NO MAXVALUE");
13730 }
13731 }
13732 }
13733
13734 if let Some(start) = als.start {
13735 self.write_space();
13736 self.write_keyword("START WITH");
13737 self.write(&format!(" {}", start));
13738 }
13739
13740 if let Some(restart) = &als.restart {
13741 self.write_space();
13742 self.write_keyword("RESTART");
13743 if let Some(val) = restart {
13744 self.write_keyword(" WITH");
13745 self.write(&format!(" {}", val));
13746 }
13747 }
13748
13749 if let Some(cache) = als.cache {
13750 self.write_space();
13751 self.write_keyword("CACHE");
13752 self.write(&format!(" {}", cache));
13753 }
13754
13755 if let Some(cycle) = als.cycle {
13756 self.write_space();
13757 if cycle {
13758 self.write_keyword("CYCLE");
13759 } else {
13760 self.write_keyword("NO CYCLE");
13761 }
13762 }
13763
13764 if let Some(owned) = &als.owned_by {
13765 self.write_space();
13766 self.write_keyword("OWNED BY");
13767 self.write_space();
13768 if let Some(table) = owned {
13769 self.generate_table(table)?;
13770 } else {
13771 self.write_keyword("NONE");
13772 }
13773 }
13774
13775 Ok(())
13776 }
13777
13778 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
13779 self.write_keyword("CREATE");
13780
13781 if ct.or_alter {
13782 self.write_space();
13783 self.write_keyword("OR ALTER");
13784 } else if ct.or_replace {
13785 self.write_space();
13786 self.write_keyword("OR REPLACE");
13787 }
13788
13789 if ct.constraint {
13790 self.write_space();
13791 self.write_keyword("CONSTRAINT");
13792 }
13793
13794 self.write_space();
13795 self.write_keyword("TRIGGER");
13796 self.write_space();
13797 self.generate_identifier(&ct.name)?;
13798
13799 self.write_space();
13800 match ct.timing {
13801 TriggerTiming::Before => self.write_keyword("BEFORE"),
13802 TriggerTiming::After => self.write_keyword("AFTER"),
13803 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
13804 }
13805
13806 for (i, event) in ct.events.iter().enumerate() {
13808 if i > 0 {
13809 self.write_keyword(" OR");
13810 }
13811 self.write_space();
13812 match event {
13813 TriggerEvent::Insert => self.write_keyword("INSERT"),
13814 TriggerEvent::Update(cols) => {
13815 self.write_keyword("UPDATE");
13816 if let Some(cols) = cols {
13817 self.write_space();
13818 self.write_keyword("OF");
13819 for (j, col) in cols.iter().enumerate() {
13820 if j > 0 {
13821 self.write(",");
13822 }
13823 self.write_space();
13824 self.generate_identifier(col)?;
13825 }
13826 }
13827 }
13828 TriggerEvent::Delete => self.write_keyword("DELETE"),
13829 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
13830 }
13831 }
13832
13833 self.write_space();
13834 self.write_keyword("ON");
13835 self.write_space();
13836 self.generate_table(&ct.table)?;
13837
13838 if let Some(ref_clause) = &ct.referencing {
13840 self.write_space();
13841 self.write_keyword("REFERENCING");
13842 if let Some(old_table) = &ref_clause.old_table {
13843 self.write_space();
13844 self.write_keyword("OLD TABLE AS");
13845 self.write_space();
13846 self.generate_identifier(old_table)?;
13847 }
13848 if let Some(new_table) = &ref_clause.new_table {
13849 self.write_space();
13850 self.write_keyword("NEW TABLE AS");
13851 self.write_space();
13852 self.generate_identifier(new_table)?;
13853 }
13854 if let Some(old_row) = &ref_clause.old_row {
13855 self.write_space();
13856 self.write_keyword("OLD ROW AS");
13857 self.write_space();
13858 self.generate_identifier(old_row)?;
13859 }
13860 if let Some(new_row) = &ref_clause.new_row {
13861 self.write_space();
13862 self.write_keyword("NEW ROW AS");
13863 self.write_space();
13864 self.generate_identifier(new_row)?;
13865 }
13866 }
13867
13868 if let Some(deferrable) = ct.deferrable {
13870 self.write_space();
13871 if deferrable {
13872 self.write_keyword("DEFERRABLE");
13873 } else {
13874 self.write_keyword("NOT DEFERRABLE");
13875 }
13876 }
13877
13878 if let Some(initially) = ct.initially_deferred {
13879 self.write_space();
13880 self.write_keyword("INITIALLY");
13881 self.write_space();
13882 if initially {
13883 self.write_keyword("DEFERRED");
13884 } else {
13885 self.write_keyword("IMMEDIATE");
13886 }
13887 }
13888
13889 if let Some(for_each) = ct.for_each {
13890 self.write_space();
13891 self.write_keyword("FOR EACH");
13892 self.write_space();
13893 match for_each {
13894 TriggerForEach::Row => self.write_keyword("ROW"),
13895 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
13896 }
13897 }
13898
13899 if let Some(when) = &ct.when {
13901 self.write_space();
13902 self.write_keyword("WHEN");
13903 if ct.when_paren {
13904 self.write(" (");
13905 self.generate_expression(when)?;
13906 self.write(")");
13907 } else {
13908 self.write_space();
13909 self.generate_expression(when)?;
13910 }
13911 }
13912
13913 self.write_space();
13915 match &ct.body {
13916 TriggerBody::Execute { function, args } => {
13917 self.write_keyword("EXECUTE FUNCTION");
13918 self.write_space();
13919 self.generate_table(function)?;
13920 self.write("(");
13921 for (i, arg) in args.iter().enumerate() {
13922 if i > 0 {
13923 self.write(", ");
13924 }
13925 self.generate_expression(arg)?;
13926 }
13927 self.write(")");
13928 }
13929 TriggerBody::Block(block) => {
13930 self.write_keyword("BEGIN");
13931 self.write_space();
13932 self.write(block);
13933 self.write_space();
13934 self.write_keyword("END");
13935 }
13936 }
13937
13938 Ok(())
13939 }
13940
13941 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
13942 self.write_keyword("DROP TRIGGER");
13943
13944 if dt.if_exists {
13945 self.write_space();
13946 self.write_keyword("IF EXISTS");
13947 }
13948
13949 self.write_space();
13950 self.generate_identifier(&dt.name)?;
13951
13952 if let Some(table) = &dt.table {
13953 self.write_space();
13954 self.write_keyword("ON");
13955 self.write_space();
13956 self.generate_table(table)?;
13957 }
13958
13959 if dt.cascade {
13960 self.write_space();
13961 self.write_keyword("CASCADE");
13962 }
13963
13964 Ok(())
13965 }
13966
13967 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
13968 self.write_keyword("CREATE TYPE");
13969
13970 if ct.if_not_exists {
13971 self.write_space();
13972 self.write_keyword("IF NOT EXISTS");
13973 }
13974
13975 self.write_space();
13976 self.generate_table(&ct.name)?;
13977
13978 self.write_space();
13979 self.write_keyword("AS");
13980 self.write_space();
13981
13982 match &ct.definition {
13983 TypeDefinition::Enum(values) => {
13984 self.write_keyword("ENUM");
13985 self.write(" (");
13986 for (i, val) in values.iter().enumerate() {
13987 if i > 0 {
13988 self.write(", ");
13989 }
13990 self.write(&format!("'{}'", val));
13991 }
13992 self.write(")");
13993 }
13994 TypeDefinition::Composite(attrs) => {
13995 self.write("(");
13996 for (i, attr) in attrs.iter().enumerate() {
13997 if i > 0 {
13998 self.write(", ");
13999 }
14000 self.generate_identifier(&attr.name)?;
14001 self.write_space();
14002 self.generate_data_type(&attr.data_type)?;
14003 if let Some(collate) = &attr.collate {
14004 self.write_space();
14005 self.write_keyword("COLLATE");
14006 self.write_space();
14007 self.generate_identifier(collate)?;
14008 }
14009 }
14010 self.write(")");
14011 }
14012 TypeDefinition::Range {
14013 subtype,
14014 subtype_diff,
14015 canonical,
14016 } => {
14017 self.write_keyword("RANGE");
14018 self.write(" (");
14019 self.write_keyword("SUBTYPE");
14020 self.write(" = ");
14021 self.generate_data_type(subtype)?;
14022 if let Some(diff) = subtype_diff {
14023 self.write(", ");
14024 self.write_keyword("SUBTYPE_DIFF");
14025 self.write(" = ");
14026 self.write(diff);
14027 }
14028 if let Some(canon) = canonical {
14029 self.write(", ");
14030 self.write_keyword("CANONICAL");
14031 self.write(" = ");
14032 self.write(canon);
14033 }
14034 self.write(")");
14035 }
14036 TypeDefinition::Base {
14037 input,
14038 output,
14039 internallength,
14040 } => {
14041 self.write("(");
14042 self.write_keyword("INPUT");
14043 self.write(" = ");
14044 self.write(input);
14045 self.write(", ");
14046 self.write_keyword("OUTPUT");
14047 self.write(" = ");
14048 self.write(output);
14049 if let Some(len) = internallength {
14050 self.write(", ");
14051 self.write_keyword("INTERNALLENGTH");
14052 self.write(" = ");
14053 self.write(&len.to_string());
14054 }
14055 self.write(")");
14056 }
14057 TypeDefinition::Domain {
14058 base_type,
14059 default,
14060 constraints,
14061 } => {
14062 self.generate_data_type(base_type)?;
14063 if let Some(def) = default {
14064 self.write_space();
14065 self.write_keyword("DEFAULT");
14066 self.write_space();
14067 self.generate_expression(def)?;
14068 }
14069 for constr in constraints {
14070 self.write_space();
14071 if let Some(name) = &constr.name {
14072 self.write_keyword("CONSTRAINT");
14073 self.write_space();
14074 self.generate_identifier(name)?;
14075 self.write_space();
14076 }
14077 self.write_keyword("CHECK");
14078 self.write(" (");
14079 self.generate_expression(&constr.check)?;
14080 self.write(")");
14081 }
14082 }
14083 }
14084
14085 Ok(())
14086 }
14087
14088 fn generate_create_task(&mut self, task: &crate::expressions::CreateTask) -> Result<()> {
14089 self.write_keyword("CREATE");
14090 if task.or_replace {
14091 self.write_space();
14092 self.write_keyword("OR REPLACE");
14093 }
14094 self.write_space();
14095 self.write_keyword("TASK");
14096 if task.if_not_exists {
14097 self.write_space();
14098 self.write_keyword("IF NOT EXISTS");
14099 }
14100 self.write_space();
14101 self.write(&task.name);
14102 if !task.properties.is_empty() {
14103 if !task.properties.starts_with('\n') && !task.properties.starts_with(' ') {
14105 self.write_space();
14106 }
14107 self.write(&task.properties);
14108 }
14109 self.write_space();
14110 self.write_keyword("AS");
14111 self.write_space();
14112 self.generate_expression(&task.body)?;
14113 Ok(())
14114 }
14115
14116 fn generate_try_catch(&mut self, try_catch: &TryCatch) -> Result<()> {
14117 self.write_keyword("BEGIN TRY");
14118 self.generate_tsql_block_statements(&try_catch.try_body)?;
14119 self.write_keyword("END TRY");
14120
14121 if let Some(catch_body) = &try_catch.catch_body {
14122 if self.config.pretty {
14123 self.write_newline();
14124 self.write_indent();
14125 } else {
14126 self.write_space();
14127 }
14128 self.write_keyword("BEGIN CATCH");
14129 self.generate_tsql_block_statements(catch_body)?;
14130 self.write_keyword("END CATCH");
14131 }
14132
14133 Ok(())
14134 }
14135
14136 fn generate_tsql_block_statements(&mut self, statements: &[Expression]) -> Result<()> {
14137 if statements.is_empty() {
14138 self.write_space();
14139 return Ok(());
14140 }
14141
14142 if self.config.pretty {
14143 self.indent_level += 1;
14144 for stmt in statements {
14145 self.write_newline();
14146 self.write_indent();
14147 self.generate_expression(stmt)?;
14148 self.write(";");
14149 }
14150 self.indent_level -= 1;
14151 self.write_newline();
14152 self.write_indent();
14153 } else {
14154 self.write_space();
14155 for (i, stmt) in statements.iter().enumerate() {
14156 if i > 0 {
14157 self.write_space();
14158 }
14159 self.generate_expression(stmt)?;
14160 self.write(";");
14161 }
14162 self.write_space();
14163 }
14164
14165 Ok(())
14166 }
14167
14168 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
14169 self.write_keyword("DROP TYPE");
14170
14171 if dt.if_exists {
14172 self.write_space();
14173 self.write_keyword("IF EXISTS");
14174 }
14175
14176 self.write_space();
14177 self.generate_table(&dt.name)?;
14178
14179 if dt.cascade {
14180 self.write_space();
14181 self.write_keyword("CASCADE");
14182 }
14183
14184 Ok(())
14185 }
14186
14187 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
14188 let saved_athena_hive_context = self.athena_hive_context;
14190 if matches!(
14191 self.config.dialect,
14192 Some(crate::dialects::DialectType::Athena)
14193 ) {
14194 self.athena_hive_context = true;
14195 }
14196
14197 for comment in &d.leading_comments {
14199 self.write_formatted_comment(comment);
14200 self.write(" ");
14201 }
14202
14203 self.write_keyword("DESCRIBE");
14204
14205 if d.extended {
14206 self.write_space();
14207 self.write_keyword("EXTENDED");
14208 } else if d.formatted {
14209 self.write_space();
14210 self.write_keyword("FORMATTED");
14211 }
14212
14213 if let Some(ref style) = d.style {
14215 self.write_space();
14216 self.write_keyword(style);
14217 }
14218
14219 let should_output_kind = match self.config.dialect {
14221 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
14223 false
14224 }
14225 Some(DialectType::Snowflake) => true,
14227 _ => d.kind.is_some(),
14228 };
14229 if should_output_kind {
14230 if let Some(ref kind) = d.kind {
14231 self.write_space();
14232 self.write_keyword(kind);
14233 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
14234 self.write_space();
14235 self.write_keyword("TABLE");
14236 }
14237 }
14238
14239 self.write_space();
14240 self.generate_expression(&d.target)?;
14241
14242 if !d.params.is_empty() {
14244 self.write("(");
14245 for (i, param) in d.params.iter().enumerate() {
14246 if i > 0 {
14247 self.write(", ");
14248 }
14249 self.write(param);
14250 }
14251 self.write(")");
14252 }
14253
14254 if let Some(ref partition) = d.partition {
14256 self.write_space();
14257 self.generate_expression(partition)?;
14258 }
14259
14260 if d.as_json {
14262 self.write_space();
14263 self.write_keyword("AS JSON");
14264 }
14265
14266 for (name, value) in &d.properties {
14268 self.write_space();
14269 self.write(name);
14270 self.write("=");
14271 self.write(value);
14272 }
14273
14274 self.athena_hive_context = saved_athena_hive_context;
14276
14277 Ok(())
14278 }
14279
14280 fn generate_show(&mut self, s: &Show) -> Result<()> {
14283 self.write_keyword("SHOW");
14284 self.write_space();
14285
14286 let show_terse = s.terse
14289 && !matches!(
14290 s.this.as_str(),
14291 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
14292 );
14293 if show_terse {
14294 self.write_keyword("TERSE");
14295 self.write_space();
14296 }
14297
14298 self.write_keyword(&s.this);
14300
14301 if let Some(ref target_expr) = s.target {
14303 self.write_space();
14304 self.generate_expression(target_expr)?;
14305 }
14306
14307 if s.history {
14309 self.write_space();
14310 self.write_keyword("HISTORY");
14311 }
14312
14313 if let Some(ref for_target) = s.for_target {
14315 self.write_space();
14316 self.write_keyword("FOR");
14317 self.write_space();
14318 self.generate_expression(for_target)?;
14319 }
14320
14321 use crate::dialects::DialectType;
14325 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
14326 let is_mysql = matches!(self.config.dialect, Some(DialectType::MySQL));
14327 let mysql_tables_scope_as_from = is_mysql
14328 && matches!(s.this.as_str(), "TABLES" | "FULL TABLES")
14329 && s.scope_kind.as_deref() == Some("SCHEMA")
14330 && s.scope.is_some()
14331 && s.from.is_none();
14332
14333 if !is_snowflake && s.from.is_some() {
14334 if let Some(ref scope_kind) = s.scope_kind {
14338 self.write_space();
14339 self.write_keyword("IN");
14340 self.write_space();
14341 self.write_keyword(scope_kind);
14342 if let Some(ref scope) = s.scope {
14343 self.write_space();
14344 self.generate_expression(scope)?;
14345 }
14346 } else if let Some(ref scope) = s.scope {
14347 self.write_space();
14348 self.write_keyword("IN");
14349 self.write_space();
14350 self.generate_expression(scope)?;
14351 }
14352
14353 if let Some(ref from) = s.from {
14355 self.write_space();
14356 self.write_keyword("FROM");
14357 self.write_space();
14358 self.generate_expression(from)?;
14359 }
14360
14361 if let Some(ref db) = s.db {
14363 self.write_space();
14364 self.write_keyword("FROM");
14365 self.write_space();
14366 self.generate_expression(db)?;
14367 }
14368
14369 if let Some(ref like) = s.like {
14371 self.write_space();
14372 self.write_keyword("LIKE");
14373 self.write_space();
14374 self.generate_expression(like)?;
14375 }
14376 } else {
14377 if let Some(ref like) = s.like {
14381 self.write_space();
14382 self.write_keyword("LIKE");
14383 self.write_space();
14384 self.generate_expression(like)?;
14385 }
14386
14387 if mysql_tables_scope_as_from {
14389 self.write_space();
14390 self.write_keyword("FROM");
14391 self.write_space();
14392 self.generate_expression(s.scope.as_ref().unwrap())?;
14393 } else if let Some(ref scope_kind) = s.scope_kind {
14394 self.write_space();
14395 self.write_keyword("IN");
14396 self.write_space();
14397 self.write_keyword(scope_kind);
14398 if let Some(ref scope) = s.scope {
14399 self.write_space();
14400 self.generate_expression(scope)?;
14401 }
14402 } else if let Some(ref scope) = s.scope {
14403 self.write_space();
14404 self.write_keyword("IN");
14405 self.write_space();
14406 self.generate_expression(scope)?;
14407 }
14408 }
14409
14410 if let Some(ref starts_with) = s.starts_with {
14412 self.write_space();
14413 self.write_keyword("STARTS WITH");
14414 self.write_space();
14415 self.generate_expression(starts_with)?;
14416 }
14417
14418 if let Some(ref limit) = s.limit {
14420 self.write_space();
14421 self.generate_limit(limit)?;
14422 }
14423
14424 if is_snowflake {
14426 if let Some(ref from) = s.from {
14427 self.write_space();
14428 self.write_keyword("FROM");
14429 self.write_space();
14430 self.generate_expression(from)?;
14431 }
14432 }
14433
14434 if let Some(ref where_clause) = s.where_clause {
14436 self.write_space();
14437 self.write_keyword("WHERE");
14438 self.write_space();
14439 self.generate_expression(where_clause)?;
14440 }
14441
14442 if let Some(is_mutex) = s.mutex {
14444 self.write_space();
14445 if is_mutex {
14446 self.write_keyword("MUTEX");
14447 } else {
14448 self.write_keyword("STATUS");
14449 }
14450 }
14451
14452 if !s.privileges.is_empty() {
14454 self.write_space();
14455 self.write_keyword("WITH PRIVILEGES");
14456 self.write_space();
14457 for (i, priv_name) in s.privileges.iter().enumerate() {
14458 if i > 0 {
14459 self.write(", ");
14460 }
14461 self.write_keyword(priv_name);
14462 }
14463 }
14464
14465 Ok(())
14466 }
14467
14468 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
14471 use crate::dialects::DialectType;
14472 match lit {
14473 Literal::String(s) => {
14474 self.generate_string_literal(s)?;
14475 }
14476 Literal::Number(n) => {
14477 if matches!(self.config.dialect, Some(DialectType::MySQL))
14478 && n.len() > 2
14479 && (n.starts_with("0x") || n.starts_with("0X"))
14480 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
14481 {
14482 return self.generate_identifier(&Identifier {
14483 name: n.clone(),
14484 quoted: true,
14485 trailing_comments: Vec::new(),
14486 span: None,
14487 });
14488 }
14489 let n = if n.contains('_')
14493 && !matches!(
14494 self.config.dialect,
14495 Some(DialectType::ClickHouse)
14496 | Some(DialectType::DuckDB)
14497 | Some(DialectType::PostgreSQL)
14498 | Some(DialectType::Hive)
14499 | Some(DialectType::Spark)
14500 | Some(DialectType::Databricks)
14501 ) {
14502 std::borrow::Cow::Owned(n.replace('_', ""))
14503 } else {
14504 std::borrow::Cow::Borrowed(n.as_str())
14505 };
14506 if n.starts_with('.') {
14509 self.write("0");
14510 self.write(&n);
14511 } else if n.starts_with("-.") {
14512 self.write("-0");
14514 self.write(&n[1..]);
14515 } else {
14516 self.write(&n);
14517 }
14518 }
14519 Literal::HexString(h) => {
14520 match self.config.dialect {
14522 Some(DialectType::Spark)
14523 | Some(DialectType::Databricks)
14524 | Some(DialectType::Teradata) => self.write("X'"),
14525 _ => self.write("x'"),
14526 }
14527 self.write(h);
14528 self.write("'");
14529 }
14530 Literal::HexNumber(h) => {
14531 match self.config.dialect {
14535 Some(DialectType::BigQuery)
14536 | Some(DialectType::ClickHouse)
14537 | Some(DialectType::TSQL)
14538 | Some(DialectType::Fabric) => {
14539 self.write("0x");
14540 self.write(h);
14541 }
14542 _ => {
14543 if let Ok(val) = u64::from_str_radix(h, 16) {
14545 self.write(&val.to_string());
14546 } else {
14547 self.write("0x");
14549 self.write(h);
14550 }
14551 }
14552 }
14553 }
14554 Literal::BitString(b) => {
14555 self.write("B'");
14557 self.write(b);
14558 self.write("'");
14559 }
14560 Literal::ByteString(b) => {
14561 self.write("b'");
14563 self.write_escaped_byte_string(b);
14565 self.write("'");
14566 }
14567 Literal::NationalString(s) => {
14568 let keep_n_prefix = matches!(
14571 self.config.dialect,
14572 Some(DialectType::TSQL)
14573 | Some(DialectType::Oracle)
14574 | Some(DialectType::MySQL)
14575 | None
14576 );
14577 if keep_n_prefix {
14578 self.write("N'");
14579 } else {
14580 self.write("'");
14581 }
14582 self.write(s);
14583 self.write("'");
14584 }
14585 Literal::Date(d) => {
14586 self.generate_date_literal(d)?;
14587 }
14588 Literal::Time(t) => {
14589 self.generate_time_literal(t)?;
14590 }
14591 Literal::Timestamp(ts) => {
14592 self.generate_timestamp_literal(ts)?;
14593 }
14594 Literal::Datetime(dt) => {
14595 self.generate_datetime_literal(dt)?;
14596 }
14597 Literal::TripleQuotedString(s, _quote_char) => {
14598 if matches!(
14600 self.config.dialect,
14601 Some(crate::dialects::DialectType::BigQuery)
14602 | Some(crate::dialects::DialectType::DuckDB)
14603 | Some(crate::dialects::DialectType::Snowflake)
14604 | Some(crate::dialects::DialectType::Spark)
14605 | Some(crate::dialects::DialectType::Hive)
14606 | Some(crate::dialects::DialectType::Presto)
14607 | Some(crate::dialects::DialectType::Trino)
14608 | Some(crate::dialects::DialectType::PostgreSQL)
14609 | Some(crate::dialects::DialectType::MySQL)
14610 | Some(crate::dialects::DialectType::Redshift)
14611 | Some(crate::dialects::DialectType::TSQL)
14612 | Some(crate::dialects::DialectType::Oracle)
14613 | Some(crate::dialects::DialectType::ClickHouse)
14614 | Some(crate::dialects::DialectType::Databricks)
14615 | Some(crate::dialects::DialectType::SQLite)
14616 ) {
14617 self.generate_string_literal(s)?;
14618 } else {
14619 let quotes = format!("{0}{0}{0}", _quote_char);
14621 self.write("es);
14622 self.write(s);
14623 self.write("es);
14624 }
14625 }
14626 Literal::EscapeString(s) => {
14627 use crate::dialects::DialectType;
14631 let content = if let Some(c) = s.strip_prefix("e:") {
14632 c
14633 } else if let Some(c) = s.strip_prefix("E:") {
14634 c
14635 } else {
14636 s.as_str()
14637 };
14638
14639 if matches!(
14641 self.config.dialect,
14642 Some(DialectType::MySQL) | Some(DialectType::TiDB)
14643 ) {
14644 self.write(content);
14645 } else {
14646 let prefix = if matches!(
14648 self.config.dialect,
14649 Some(DialectType::SingleStore)
14650 | Some(DialectType::DuckDB)
14651 | Some(DialectType::PostgreSQL)
14652 | Some(DialectType::CockroachDB)
14653 | Some(DialectType::Materialize)
14654 | Some(DialectType::RisingWave)
14655 ) {
14656 "e'"
14657 } else {
14658 "E'"
14659 };
14660
14661 let normalized = content.replace("\\'", "''");
14663 self.write(prefix);
14664 self.write(&normalized);
14665 self.write("'");
14666 }
14667 }
14668 Literal::DollarString(s) => {
14669 use crate::dialects::DialectType;
14672 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
14674 let escape_backslash = matches!(
14676 self.config.dialect,
14677 Some(DialectType::ClickHouse) | Some(DialectType::Snowflake)
14678 );
14679 let use_backslash_quote =
14683 matches!(self.config.dialect, Some(DialectType::Snowflake));
14684
14685 let mut escaped = String::with_capacity(content.len() + 4);
14686 for ch in content.chars() {
14687 if escape_backslash && ch == '\\' {
14688 escaped.push('\\');
14690 escaped.push('\\');
14691 } else if ch == '\'' {
14692 if use_backslash_quote {
14693 escaped.push('\\');
14694 escaped.push('\'');
14695 } else {
14696 escaped.push('\'');
14697 escaped.push('\'');
14698 }
14699 } else {
14700 escaped.push(ch);
14701 }
14702 }
14703 self.write("'");
14704 self.write(&escaped);
14705 self.write("'");
14706 }
14707 Literal::RawString(s) => {
14708 use crate::dialects::DialectType;
14714
14715 let escape_backslash = matches!(
14717 self.config.dialect,
14718 Some(DialectType::BigQuery)
14719 | Some(DialectType::MySQL)
14720 | Some(DialectType::SingleStore)
14721 | Some(DialectType::TiDB)
14722 | Some(DialectType::Hive)
14723 | Some(DialectType::Spark)
14724 | Some(DialectType::Databricks)
14725 | Some(DialectType::Drill)
14726 | Some(DialectType::Snowflake)
14727 | Some(DialectType::Redshift)
14728 | Some(DialectType::ClickHouse)
14729 );
14730
14731 let backslash_escapes_quote = matches!(
14734 self.config.dialect,
14735 Some(DialectType::BigQuery)
14736 | Some(DialectType::Hive)
14737 | Some(DialectType::Spark)
14738 | Some(DialectType::Databricks)
14739 | Some(DialectType::Drill)
14740 | Some(DialectType::Snowflake)
14741 | Some(DialectType::Redshift)
14742 );
14743
14744 let supports_escape_sequences = escape_backslash;
14747
14748 let mut escaped = String::with_capacity(s.len() + 4);
14749 for ch in s.chars() {
14750 if escape_backslash && ch == '\\' {
14751 escaped.push('\\');
14753 escaped.push('\\');
14754 } else if ch == '\'' {
14755 if backslash_escapes_quote {
14756 escaped.push('\\');
14758 escaped.push('\'');
14759 } else {
14760 escaped.push('\'');
14762 escaped.push('\'');
14763 }
14764 } else if supports_escape_sequences {
14765 match ch {
14768 '\n' => {
14769 escaped.push('\\');
14770 escaped.push('n');
14771 }
14772 '\r' => {
14773 escaped.push('\\');
14774 escaped.push('r');
14775 }
14776 '\t' => {
14777 escaped.push('\\');
14778 escaped.push('t');
14779 }
14780 '\x07' => {
14781 escaped.push('\\');
14782 escaped.push('a');
14783 }
14784 '\x08' => {
14785 escaped.push('\\');
14786 escaped.push('b');
14787 }
14788 '\x0C' => {
14789 escaped.push('\\');
14790 escaped.push('f');
14791 }
14792 '\x0B' => {
14793 escaped.push('\\');
14794 escaped.push('v');
14795 }
14796 _ => escaped.push(ch),
14797 }
14798 } else {
14799 escaped.push(ch);
14800 }
14801 }
14802 self.write("'");
14803 self.write(&escaped);
14804 self.write("'");
14805 }
14806 }
14807 Ok(())
14808 }
14809
14810 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
14812 use crate::dialects::DialectType;
14813
14814 match self.config.dialect {
14815 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
14817 self.write("CAST('");
14818 self.write(d);
14819 self.write("' AS DATE)");
14820 }
14821 Some(DialectType::BigQuery) => {
14824 self.write("CAST('");
14825 self.write(d);
14826 self.write("' AS DATE)");
14827 }
14828 Some(DialectType::Exasol) => {
14831 self.write("CAST('");
14832 self.write(d);
14833 self.write("' AS DATE)");
14834 }
14835 Some(DialectType::Snowflake) => {
14838 self.write("CAST('");
14839 self.write(d);
14840 self.write("' AS DATE)");
14841 }
14842 Some(DialectType::PostgreSQL)
14844 | Some(DialectType::MySQL)
14845 | Some(DialectType::SingleStore)
14846 | Some(DialectType::TiDB)
14847 | Some(DialectType::Redshift) => {
14848 self.write("CAST('");
14849 self.write(d);
14850 self.write("' AS DATE)");
14851 }
14852 Some(DialectType::DuckDB)
14854 | Some(DialectType::Presto)
14855 | Some(DialectType::Trino)
14856 | Some(DialectType::Athena)
14857 | Some(DialectType::Spark)
14858 | Some(DialectType::Databricks)
14859 | Some(DialectType::Hive) => {
14860 self.write("CAST('");
14861 self.write(d);
14862 self.write("' AS DATE)");
14863 }
14864 Some(DialectType::Oracle) => {
14866 self.write("TO_DATE('");
14867 self.write(d);
14868 self.write("', 'YYYY-MM-DD')");
14869 }
14870 _ => {
14872 self.write_keyword("DATE");
14873 self.write(" '");
14874 self.write(d);
14875 self.write("'");
14876 }
14877 }
14878 Ok(())
14879 }
14880
14881 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
14883 use crate::dialects::DialectType;
14884
14885 match self.config.dialect {
14886 Some(DialectType::TSQL) => {
14888 self.write("CAST('");
14889 self.write(t);
14890 self.write("' AS TIME)");
14891 }
14892 _ => {
14894 self.write_keyword("TIME");
14895 self.write(" '");
14896 self.write(t);
14897 self.write("'");
14898 }
14899 }
14900 Ok(())
14901 }
14902
14903 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
14905 use crate::expressions::Literal;
14906
14907 match expr {
14908 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
14909 let Literal::Date(d) = lit.as_ref() else {
14910 unreachable!()
14911 };
14912 self.write("CAST('");
14914 self.write(d);
14915 self.write("' AS DATE)");
14916 }
14917 _ => {
14918 self.generate_expression(expr)?;
14920 }
14921 }
14922 Ok(())
14923 }
14924
14925 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
14927 use crate::dialects::DialectType;
14928
14929 match self.config.dialect {
14930 Some(DialectType::TSQL) => {
14932 self.write("CAST('");
14933 self.write(ts);
14934 self.write("' AS DATETIME2)");
14935 }
14936 Some(DialectType::BigQuery) => {
14939 self.write("CAST('");
14940 self.write(ts);
14941 self.write("' AS TIMESTAMP)");
14942 }
14943 Some(DialectType::Snowflake) => {
14946 self.write("CAST('");
14947 self.write(ts);
14948 self.write("' AS TIMESTAMP)");
14949 }
14950 Some(DialectType::Dremio) => {
14953 self.write("CAST('");
14954 self.write(ts);
14955 self.write("' AS TIMESTAMP)");
14956 }
14957 Some(DialectType::Exasol) => {
14960 self.write("CAST('");
14961 self.write(ts);
14962 self.write("' AS TIMESTAMP)");
14963 }
14964 Some(DialectType::Oracle) => {
14967 self.write("TO_TIMESTAMP('");
14968 self.write(ts);
14969 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
14970 }
14971 Some(DialectType::Presto) | Some(DialectType::Trino) => {
14973 if Self::timestamp_has_timezone(ts) {
14974 self.write("CAST('");
14975 self.write(ts);
14976 self.write("' AS TIMESTAMP WITH TIME ZONE)");
14977 } else {
14978 self.write("CAST('");
14979 self.write(ts);
14980 self.write("' AS TIMESTAMP)");
14981 }
14982 }
14983 Some(DialectType::ClickHouse) => {
14985 self.write("CAST('");
14986 self.write(ts);
14987 self.write("' AS Nullable(DateTime))");
14988 }
14989 Some(DialectType::Spark) => {
14991 self.write("CAST('");
14992 self.write(ts);
14993 self.write("' AS TIMESTAMP)");
14994 }
14995 Some(DialectType::Redshift) => {
14998 if ts == "epoch" {
14999 self.write_keyword("TIMESTAMP");
15000 self.write(" '");
15001 self.write(ts);
15002 self.write("'");
15003 } else {
15004 self.write("CAST('");
15005 self.write(ts);
15006 self.write("' AS TIMESTAMP)");
15007 }
15008 }
15009 Some(DialectType::PostgreSQL)
15011 | Some(DialectType::Hive)
15012 | Some(DialectType::SQLite)
15013 | Some(DialectType::DuckDB)
15014 | Some(DialectType::Athena)
15015 | Some(DialectType::Drill)
15016 | Some(DialectType::Teradata) => {
15017 self.write("CAST('");
15018 self.write(ts);
15019 self.write("' AS TIMESTAMP)");
15020 }
15021 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
15023 self.write("CAST('");
15024 self.write(ts);
15025 self.write("' AS DATETIME)");
15026 }
15027 Some(DialectType::Databricks) => {
15029 self.write("CAST('");
15030 self.write(ts);
15031 self.write("' AS TIMESTAMP_NTZ)");
15032 }
15033 _ => {
15035 self.write_keyword("TIMESTAMP");
15036 self.write(" '");
15037 self.write(ts);
15038 self.write("'");
15039 }
15040 }
15041 Ok(())
15042 }
15043
15044 fn timestamp_has_timezone(ts: &str) -> bool {
15047 let ts_lower = ts.to_ascii_lowercase();
15051
15052 let continent_prefixes = [
15054 "africa/",
15055 "america/",
15056 "antarctica/",
15057 "arctic/",
15058 "asia/",
15059 "atlantic/",
15060 "australia/",
15061 "europe/",
15062 "indian/",
15063 "pacific/",
15064 "etc/",
15065 "brazil/",
15066 "canada/",
15067 "chile/",
15068 "mexico/",
15069 "us/",
15070 ];
15071
15072 for prefix in &continent_prefixes {
15073 if ts_lower.contains(prefix) {
15074 return true;
15075 }
15076 }
15077
15078 let tz_abbrevs = [
15081 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
15082 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
15083 " sgt", " aest", " aedt", " acst", " acdt", " awst",
15084 ];
15085
15086 for abbrev in &tz_abbrevs {
15087 if ts_lower.ends_with(abbrev) {
15088 return true;
15089 }
15090 }
15091
15092 let trimmed = ts.trim();
15096 if let Some(last_space) = trimmed.rfind(' ') {
15097 let suffix = &trimmed[last_space + 1..];
15098 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
15099 let rest = &suffix[1..];
15101 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
15102 return true;
15103 }
15104 }
15105 }
15106
15107 false
15108 }
15109
15110 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
15112 use crate::dialects::DialectType;
15113
15114 match self.config.dialect {
15115 Some(DialectType::BigQuery) => {
15118 self.write("CAST('");
15119 self.write(dt);
15120 self.write("' AS DATETIME)");
15121 }
15122 Some(DialectType::DuckDB) => {
15124 self.write("CAST('");
15125 self.write(dt);
15126 self.write("' AS TIMESTAMP)");
15127 }
15128 _ => {
15131 self.write_keyword("DATETIME");
15132 self.write(" '");
15133 self.write(dt);
15134 self.write("'");
15135 }
15136 }
15137 Ok(())
15138 }
15139
15140 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
15142 use crate::dialects::DialectType;
15143
15144 match self.config.dialect {
15145 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
15149 self.write("'");
15151 for c in s.chars() {
15152 match c {
15153 '\'' => self.write("\\'"),
15154 '\\' => self.write("\\\\"),
15155 '\n' => self.write("\\n"),
15156 '\r' => self.write("\\r"),
15157 '\t' => self.write("\\t"),
15158 '\0' => self.write("\\0"),
15159 _ => self.output.push(c),
15160 }
15161 }
15162 self.write("'");
15163 }
15164 Some(DialectType::Drill) => {
15165 self.write("'");
15168 for c in s.chars() {
15169 match c {
15170 '\'' => self.write("''"),
15171 '\\' => self.write("\\\\"),
15172 '\n' => self.write("\\n"),
15173 '\r' => self.write("\\r"),
15174 '\t' => self.write("\\t"),
15175 '\0' => self.write("\\0"),
15176 _ => self.output.push(c),
15177 }
15178 }
15179 self.write("'");
15180 }
15181 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
15182 self.write("'");
15183 for c in s.chars() {
15184 match c {
15185 '\'' => self.write("''"),
15187 '\\' => self.write("\\\\"),
15188 '\n' => self.write("\\n"),
15189 '\r' => self.write("\\r"),
15190 '\t' => self.write("\\t"),
15191 '\0' => self.output.push('\0'),
15193 _ => self.output.push(c),
15194 }
15195 }
15196 self.write("'");
15197 }
15198 Some(DialectType::BigQuery) => {
15200 self.write("'");
15201 for c in s.chars() {
15202 match c {
15203 '\'' => self.write("\\'"),
15204 '\\' => self.write("\\\\"),
15205 '\n' => self.write("\\n"),
15206 '\r' => self.write("\\r"),
15207 '\t' => self.write("\\t"),
15208 '\0' => self.write("\\0"),
15209 '\x07' => self.write("\\a"),
15210 '\x08' => self.write("\\b"),
15211 '\x0C' => self.write("\\f"),
15212 '\x0B' => self.write("\\v"),
15213 _ => self.output.push(c),
15214 }
15215 }
15216 self.write("'");
15217 }
15218 Some(DialectType::Athena) => {
15222 if self.athena_hive_context {
15223 self.write("'");
15225 for c in s.chars() {
15226 match c {
15227 '\'' => self.write("\\'"),
15228 '\\' => self.write("\\\\"),
15229 '\n' => self.write("\\n"),
15230 '\r' => self.write("\\r"),
15231 '\t' => self.write("\\t"),
15232 '\0' => self.write("\\0"),
15233 _ => self.output.push(c),
15234 }
15235 }
15236 self.write("'");
15237 } else {
15238 self.write("'");
15240 for c in s.chars() {
15241 match c {
15242 '\'' => self.write("''"),
15243 _ => self.output.push(c),
15245 }
15246 }
15247 self.write("'");
15248 }
15249 }
15250 Some(DialectType::Snowflake) => {
15255 self.write("'");
15256 for c in s.chars() {
15257 match c {
15258 '\'' => self.write("\\'"),
15259 '\n' => self.write("\\n"),
15262 '\r' => self.write("\\r"),
15263 '\t' => self.write("\\t"),
15264 _ => self.output.push(c),
15265 }
15266 }
15267 self.write("'");
15268 }
15269 Some(DialectType::PostgreSQL) => {
15271 self.write("'");
15272 for c in s.chars() {
15273 match c {
15274 '\'' => self.write("''"),
15275 _ => self.output.push(c),
15276 }
15277 }
15278 self.write("'");
15279 }
15280 Some(DialectType::Redshift) => {
15282 self.write("'");
15283 for c in s.chars() {
15284 match c {
15285 '\'' => self.write("\\'"),
15286 _ => self.output.push(c),
15287 }
15288 }
15289 self.write("'");
15290 }
15291 Some(DialectType::Oracle) => {
15293 self.write("'");
15294 for ch in s.chars() {
15295 if ch == '\'' {
15296 self.output.push_str("''");
15297 } else {
15298 self.output.push(ch);
15299 }
15300 }
15301 self.write("'");
15302 }
15303 Some(DialectType::ClickHouse) => {
15306 self.write("'");
15307 for c in s.chars() {
15308 match c {
15309 '\'' => self.write("''"),
15310 '\\' => self.write("\\\\"),
15311 '\n' => self.write("\\n"),
15312 '\r' => self.write("\\r"),
15313 '\t' => self.write("\\t"),
15314 '\0' => self.write("\\0"),
15315 '\x07' => self.write("\\a"),
15316 '\x08' => self.write("\\b"),
15317 '\x0C' => self.write("\\f"),
15318 '\x0B' => self.write("\\v"),
15319 c if c.is_control() || (c as u32) < 0x20 => {
15321 let byte = c as u32;
15322 if byte < 256 {
15323 self.write(&format!("\\x{:02X}", byte));
15324 } else {
15325 self.output.push(c);
15326 }
15327 }
15328 _ => self.output.push(c),
15329 }
15330 }
15331 self.write("'");
15332 }
15333 _ => {
15336 self.write("'");
15337 for ch in s.chars() {
15338 if ch == '\'' {
15339 self.output.push_str("''");
15340 } else {
15341 self.output.push(ch);
15342 }
15343 }
15344 self.write("'");
15345 }
15346 }
15347 Ok(())
15348 }
15349
15350 fn write_escaped_byte_string(&mut self, s: &str) {
15353 for c in s.chars() {
15354 match c {
15355 '\'' => self.write("\\'"),
15357 '\\' => self.write("\\\\"),
15359 _ if !c.is_control() => self.output.push(c),
15361 _ => {
15363 let byte = c as u32;
15364 if byte < 256 {
15365 self.write(&format!("\\x{:02x}", byte));
15366 } else {
15367 for b in c.to_string().as_bytes() {
15369 self.write(&format!("\\x{:02x}", b));
15370 }
15371 }
15372 }
15373 }
15374 }
15375 }
15376
15377 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
15378 use crate::dialects::DialectType;
15379
15380 match self.config.dialect {
15382 Some(DialectType::TSQL) => {
15385 self.write(if b.value { "1" } else { "0" });
15386 }
15387 Some(DialectType::Oracle) => {
15389 self.write(if b.value { "1" } else { "0" });
15390 }
15391 Some(DialectType::MySQL) => {
15393 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15394 }
15395 _ => {
15397 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15398 }
15399 }
15400 Ok(())
15401 }
15402
15403 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
15406 let name = &id.name;
15407 let quote_style = &self.config.identifier_quote_style;
15408
15409 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
15413
15414 let output_name = if self.config.normalize_identifiers && !id.quoted {
15416 name.to_ascii_lowercase()
15417 } else {
15418 name.to_string()
15419 };
15420
15421 if needs_quoting {
15422 let quote_style = if matches!(self.config.dialect, Some(DialectType::ClickHouse))
15423 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
15424 && quote_style.start == '"'
15425 && output_name.contains('"')
15426 {
15427 &IdentifierQuoteStyle::BACKTICK
15428 } else {
15429 quote_style
15430 };
15431 let escaped_name = if quote_style.start == quote_style.end {
15433 output_name.replace(
15434 quote_style.end,
15435 &format!("{}{}", quote_style.end, quote_style.end),
15436 )
15437 } else {
15438 output_name.replace(
15439 quote_style.end,
15440 &format!("{}{}", quote_style.end, quote_style.end),
15441 )
15442 };
15443 self.write(&format!(
15444 "{}{}{}",
15445 quote_style.start, escaped_name, quote_style.end
15446 ));
15447 } else {
15448 self.write(&output_name);
15449 }
15450
15451 for comment in &id.trailing_comments {
15453 self.write(" ");
15454 self.write_formatted_comment(comment);
15455 }
15456 Ok(())
15457 }
15458
15459 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
15460 use crate::dialects::DialectType;
15461
15462 let name = &id.name;
15463
15464 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
15466 && self.athena_hive_context
15467 {
15468 &IdentifierQuoteStyle::BACKTICK
15469 } else {
15470 &self.config.identifier_quote_style
15471 };
15472
15473 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
15480 let needs_digit_quoting = starts_with_digit
15481 && !self.config.identifiers_can_start_with_digit
15482 && self.config.dialect.is_some();
15483 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
15484 && name.len() > 2
15485 && (name.starts_with("0x") || name.starts_with("0X"))
15486 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
15487 let clickhouse_unsafe_identifier =
15488 matches!(self.config.dialect, Some(DialectType::ClickHouse))
15489 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
15490 && !name.starts_with('{')
15491 && !name.contains('(')
15492 && !name.contains(')')
15493 && name != "?"
15494 && name
15495 .chars()
15496 .any(|c| !(c.is_ascii_alphanumeric() || c == '_'));
15497 let needs_quoting = id.quoted
15498 || self.is_reserved_keyword(name)
15499 || self.config.always_quote_identifiers
15500 || needs_digit_quoting
15501 || mysql_invalid_hex_identifier
15502 || clickhouse_unsafe_identifier;
15503
15504 let (base_name, suffix) = if needs_quoting {
15507 if let Some(paren_pos) = name.find('(') {
15509 let base = &name[..paren_pos];
15510 let rest = &name[paren_pos..];
15511 if rest.starts_with('(')
15513 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
15514 {
15515 let close_paren = rest.find(')').unwrap_or(rest.len());
15517 let inside = &rest[1..close_paren];
15518 if inside.chars().all(|c| c.is_ascii_digit()) {
15519 (base.to_string(), rest.to_string())
15520 } else {
15521 (name.to_string(), String::new())
15522 }
15523 } else {
15524 (name.to_string(), String::new())
15525 }
15526 } else if name.ends_with(" ASC") {
15527 let base = &name[..name.len() - 4];
15528 (base.to_string(), " ASC".to_string())
15529 } else if name.ends_with(" DESC") {
15530 let base = &name[..name.len() - 5];
15531 (base.to_string(), " DESC".to_string())
15532 } else {
15533 (name.to_string(), String::new())
15534 }
15535 } else {
15536 (name.to_string(), String::new())
15537 };
15538
15539 let output_name = if self.config.normalize_identifiers && !id.quoted {
15543 base_name.to_ascii_lowercase()
15544 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
15545 && !id.quoted
15546 && self.is_reserved_keyword(name)
15547 {
15548 base_name.to_ascii_uppercase()
15551 } else {
15552 base_name
15553 };
15554
15555 if needs_quoting {
15556 let escaped_name = if quote_style.start == quote_style.end {
15558 output_name.replace(
15560 quote_style.end,
15561 &format!("{}{}", quote_style.end, quote_style.end),
15562 )
15563 } else {
15564 output_name.replace(
15566 quote_style.end,
15567 &format!("{}{}", quote_style.end, quote_style.end),
15568 )
15569 };
15570 self.write(&format!(
15571 "{}{}{}{}",
15572 quote_style.start, escaped_name, quote_style.end, suffix
15573 ));
15574 } else {
15575 self.write(&output_name);
15576 }
15577
15578 for comment in &id.trailing_comments {
15580 self.write(" ");
15581 self.write_formatted_comment(comment);
15582 }
15583 Ok(())
15584 }
15585
15586 fn generate_column(&mut self, col: &Column) -> Result<()> {
15587 use crate::dialects::DialectType;
15588
15589 if let Some(table) = &col.table {
15590 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
15594 && !table.quoted
15595 && table.name.eq_ignore_ascii_case("LOCAL");
15596
15597 if is_exasol_local_prefix {
15598 self.write("LOCAL");
15600 } else {
15601 self.generate_identifier(table)?;
15602 }
15603 self.write(".");
15604 }
15605 self.generate_identifier(&col.name)?;
15606 if col.join_mark && self.config.supports_column_join_marks {
15609 self.write(" (+)");
15610 }
15611 for comment in &col.trailing_comments {
15613 self.write_space();
15614 self.write_formatted_comment(comment);
15615 }
15616 Ok(())
15617 }
15618
15619 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
15622 use crate::dialects::DialectType;
15623 use crate::expressions::PseudocolumnType;
15624
15625 if pc.kind == PseudocolumnType::Sysdate
15627 && !matches!(
15628 self.config.dialect,
15629 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
15630 )
15631 {
15632 self.write_keyword("CURRENT_TIMESTAMP");
15633 if matches!(
15635 self.config.dialect,
15636 Some(DialectType::MySQL)
15637 | Some(DialectType::ClickHouse)
15638 | Some(DialectType::Spark)
15639 | Some(DialectType::Databricks)
15640 | Some(DialectType::Hive)
15641 ) {
15642 self.write("()");
15643 }
15644 } else {
15645 self.write(pc.kind.as_str());
15646 }
15647 Ok(())
15648 }
15649
15650 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
15652 use crate::dialects::DialectType;
15653
15654 let supports_connect_by = matches!(
15657 self.config.dialect,
15658 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
15659 );
15660
15661 if !supports_connect_by && self.config.dialect.is_some() {
15662 if self.config.pretty {
15664 self.write_newline();
15665 } else {
15666 self.write_space();
15667 }
15668 self.write_unsupported_comment(
15669 "CONNECT BY requires manual conversion to recursive CTE",
15670 )?;
15671 }
15672
15673 if let Some(start) = &connect.start {
15675 if self.config.pretty {
15676 self.write_newline();
15677 } else {
15678 self.write_space();
15679 }
15680 self.write_keyword("START WITH");
15681 self.write_space();
15682 self.generate_expression(start)?;
15683 }
15684
15685 if self.config.pretty {
15687 self.write_newline();
15688 } else {
15689 self.write_space();
15690 }
15691 self.write_keyword("CONNECT BY");
15692 if connect.nocycle {
15693 self.write_space();
15694 self.write_keyword("NOCYCLE");
15695 }
15696 self.write_space();
15697 self.generate_expression(&connect.connect)?;
15698
15699 Ok(())
15700 }
15701
15702 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
15704 self.generate_connect(connect)
15705 }
15706
15707 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
15709 self.write_keyword("PRIOR");
15710 self.write_space();
15711 self.generate_expression(&prior.this)?;
15712 Ok(())
15713 }
15714
15715 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
15718 self.write_keyword("CONNECT_BY_ROOT");
15719 self.write_space();
15720 self.generate_expression(&cbr.this)?;
15721 Ok(())
15722 }
15723
15724 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
15726 use crate::dialects::DialectType;
15727
15728 let supports_match_recognize = matches!(
15730 self.config.dialect,
15731 Some(DialectType::Oracle)
15732 | Some(DialectType::Snowflake)
15733 | Some(DialectType::Presto)
15734 | Some(DialectType::Trino)
15735 );
15736
15737 if let Some(source) = &mr.this {
15739 self.generate_expression(source)?;
15740 }
15741
15742 if !supports_match_recognize {
15743 self.write_unsupported_comment("MATCH_RECOGNIZE not supported in this dialect")?;
15744 return Ok(());
15745 }
15746
15747 if self.config.pretty {
15749 self.write_newline();
15750 } else {
15751 self.write_space();
15752 }
15753
15754 self.write_keyword("MATCH_RECOGNIZE");
15755 self.write(" (");
15756
15757 if self.config.pretty {
15758 self.indent_level += 1;
15759 }
15760
15761 let mut needs_separator = false;
15762
15763 if let Some(partition_by) = &mr.partition_by {
15765 if !partition_by.is_empty() {
15766 if self.config.pretty {
15767 self.write_newline();
15768 self.write_indent();
15769 }
15770 self.write_keyword("PARTITION BY");
15771 self.write_space();
15772 for (i, expr) in partition_by.iter().enumerate() {
15773 if i > 0 {
15774 self.write(", ");
15775 }
15776 self.generate_expression(expr)?;
15777 }
15778 needs_separator = true;
15779 }
15780 }
15781
15782 if let Some(order_by) = &mr.order_by {
15784 if !order_by.is_empty() {
15785 if needs_separator {
15786 if self.config.pretty {
15787 self.write_newline();
15788 self.write_indent();
15789 } else {
15790 self.write_space();
15791 }
15792 } else if self.config.pretty {
15793 self.write_newline();
15794 self.write_indent();
15795 }
15796 self.write_keyword("ORDER BY");
15797 if self.config.pretty {
15799 self.indent_level += 1;
15800 for (i, ordered) in order_by.iter().enumerate() {
15801 if i > 0 {
15802 self.write(",");
15803 }
15804 self.write_newline();
15805 self.write_indent();
15806 self.generate_ordered(ordered)?;
15807 }
15808 self.indent_level -= 1;
15809 } else {
15810 self.write_space();
15811 for (i, ordered) in order_by.iter().enumerate() {
15812 if i > 0 {
15813 self.write(", ");
15814 }
15815 self.generate_ordered(ordered)?;
15816 }
15817 }
15818 needs_separator = true;
15819 }
15820 }
15821
15822 if let Some(measures) = &mr.measures {
15824 if !measures.is_empty() {
15825 if needs_separator {
15826 if self.config.pretty {
15827 self.write_newline();
15828 self.write_indent();
15829 } else {
15830 self.write_space();
15831 }
15832 } else if self.config.pretty {
15833 self.write_newline();
15834 self.write_indent();
15835 }
15836 self.write_keyword("MEASURES");
15837 if self.config.pretty {
15839 self.indent_level += 1;
15840 for (i, measure) in measures.iter().enumerate() {
15841 if i > 0 {
15842 self.write(",");
15843 }
15844 self.write_newline();
15845 self.write_indent();
15846 if let Some(semantics) = &measure.window_frame {
15848 match semantics {
15849 MatchRecognizeSemantics::Running => {
15850 self.write_keyword("RUNNING");
15851 self.write_space();
15852 }
15853 MatchRecognizeSemantics::Final => {
15854 self.write_keyword("FINAL");
15855 self.write_space();
15856 }
15857 }
15858 }
15859 self.generate_expression(&measure.this)?;
15860 }
15861 self.indent_level -= 1;
15862 } else {
15863 self.write_space();
15864 for (i, measure) in measures.iter().enumerate() {
15865 if i > 0 {
15866 self.write(", ");
15867 }
15868 if let Some(semantics) = &measure.window_frame {
15870 match semantics {
15871 MatchRecognizeSemantics::Running => {
15872 self.write_keyword("RUNNING");
15873 self.write_space();
15874 }
15875 MatchRecognizeSemantics::Final => {
15876 self.write_keyword("FINAL");
15877 self.write_space();
15878 }
15879 }
15880 }
15881 self.generate_expression(&measure.this)?;
15882 }
15883 }
15884 needs_separator = true;
15885 }
15886 }
15887
15888 if let Some(rows) = &mr.rows {
15890 if needs_separator {
15891 if self.config.pretty {
15892 self.write_newline();
15893 self.write_indent();
15894 } else {
15895 self.write_space();
15896 }
15897 } else if self.config.pretty {
15898 self.write_newline();
15899 self.write_indent();
15900 }
15901 match rows {
15902 MatchRecognizeRows::OneRowPerMatch => {
15903 self.write_keyword("ONE ROW PER MATCH");
15904 }
15905 MatchRecognizeRows::AllRowsPerMatch => {
15906 self.write_keyword("ALL ROWS PER MATCH");
15907 }
15908 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
15909 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
15910 }
15911 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
15912 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
15913 }
15914 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
15915 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
15916 }
15917 }
15918 needs_separator = true;
15919 }
15920
15921 if let Some(after) = &mr.after {
15923 if needs_separator {
15924 if self.config.pretty {
15925 self.write_newline();
15926 self.write_indent();
15927 } else {
15928 self.write_space();
15929 }
15930 } else if self.config.pretty {
15931 self.write_newline();
15932 self.write_indent();
15933 }
15934 match after {
15935 MatchRecognizeAfter::PastLastRow => {
15936 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
15937 }
15938 MatchRecognizeAfter::ToNextRow => {
15939 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
15940 }
15941 MatchRecognizeAfter::ToFirst(ident) => {
15942 self.write_keyword("AFTER MATCH SKIP TO FIRST");
15943 self.write_space();
15944 self.generate_identifier(ident)?;
15945 }
15946 MatchRecognizeAfter::ToLast(ident) => {
15947 self.write_keyword("AFTER MATCH SKIP TO LAST");
15948 self.write_space();
15949 self.generate_identifier(ident)?;
15950 }
15951 }
15952 needs_separator = true;
15953 }
15954
15955 if let Some(pattern) = &mr.pattern {
15957 if needs_separator {
15958 if self.config.pretty {
15959 self.write_newline();
15960 self.write_indent();
15961 } else {
15962 self.write_space();
15963 }
15964 } else if self.config.pretty {
15965 self.write_newline();
15966 self.write_indent();
15967 }
15968 self.write_keyword("PATTERN");
15969 self.write_space();
15970 self.write("(");
15971 self.write(pattern);
15972 self.write(")");
15973 needs_separator = true;
15974 }
15975
15976 if let Some(define) = &mr.define {
15978 if !define.is_empty() {
15979 if needs_separator {
15980 if self.config.pretty {
15981 self.write_newline();
15982 self.write_indent();
15983 } else {
15984 self.write_space();
15985 }
15986 } else if self.config.pretty {
15987 self.write_newline();
15988 self.write_indent();
15989 }
15990 self.write_keyword("DEFINE");
15991 if self.config.pretty {
15993 self.indent_level += 1;
15994 for (i, (name, expr)) in define.iter().enumerate() {
15995 if i > 0 {
15996 self.write(",");
15997 }
15998 self.write_newline();
15999 self.write_indent();
16000 self.generate_identifier(name)?;
16001 self.write(" AS ");
16002 self.generate_expression(expr)?;
16003 }
16004 self.indent_level -= 1;
16005 } else {
16006 self.write_space();
16007 for (i, (name, expr)) in define.iter().enumerate() {
16008 if i > 0 {
16009 self.write(", ");
16010 }
16011 self.generate_identifier(name)?;
16012 self.write(" AS ");
16013 self.generate_expression(expr)?;
16014 }
16015 }
16016 }
16017 }
16018
16019 if self.config.pretty {
16020 self.indent_level -= 1;
16021 self.write_newline();
16022 }
16023 self.write(")");
16024
16025 if let Some(alias) = &mr.alias {
16027 self.write(" ");
16028 if mr.alias_explicit_as {
16029 self.write_keyword("AS");
16030 self.write(" ");
16031 }
16032 self.generate_identifier(alias)?;
16033 }
16034
16035 Ok(())
16036 }
16037
16038 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
16040 use crate::dialects::DialectType;
16041
16042 let supports_hints = matches!(
16044 self.config.dialect,
16045 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
16047 Some(DialectType::Spark) | Some(DialectType::Hive) |
16048 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
16049 );
16050
16051 if !supports_hints || hint.expressions.is_empty() {
16052 return Ok(());
16053 }
16054
16055 let mut hint_strings: Vec<String> = Vec::new();
16058 for expr in &hint.expressions {
16059 match expr {
16060 HintExpression::Raw(text) => {
16061 let parsed = self.parse_raw_hint_text(text);
16063 hint_strings.extend(parsed);
16064 }
16065 _ => {
16066 hint_strings.push(self.hint_expression_to_string(expr)?);
16067 }
16068 }
16069 }
16070
16071 let use_multiline = self.config.pretty && hint_strings.len() > 1;
16075
16076 if use_multiline {
16077 self.write(" /*+ ");
16079 for (i, hint_str) in hint_strings.iter().enumerate() {
16080 if i > 0 {
16081 self.write_newline();
16082 self.write(" "); }
16084 self.write(hint_str);
16085 }
16086 self.write(" */");
16087 } else {
16088 self.write(" /*+ ");
16090 let sep = match self.config.dialect {
16091 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
16092 _ => " ",
16093 };
16094 for (i, hint_str) in hint_strings.iter().enumerate() {
16095 if i > 0 {
16096 self.write(sep);
16097 }
16098 self.write(hint_str);
16099 }
16100 self.write(" */");
16101 }
16102
16103 Ok(())
16104 }
16105
16106 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
16110 let mut results = Vec::new();
16111 let mut chars = text.chars().peekable();
16112 let mut current = String::new();
16113 let mut paren_depth = 0;
16114 let mut has_unparseable_content = false;
16115 let mut position_after_last_function = 0;
16116 let mut char_position = 0;
16117
16118 while let Some(c) = chars.next() {
16119 char_position += c.len_utf8();
16120 match c {
16121 '(' => {
16122 paren_depth += 1;
16123 current.push(c);
16124 }
16125 ')' => {
16126 paren_depth -= 1;
16127 current.push(c);
16128 if paren_depth == 0 {
16130 let trimmed = current.trim().to_string();
16131 if !trimmed.is_empty() {
16132 let formatted = self.format_hint_function(&trimmed);
16134 results.push(formatted);
16135 }
16136 current.clear();
16137 position_after_last_function = char_position;
16138 }
16139 }
16140 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
16141 }
16143 _ if paren_depth == 0 => {
16144 current.push(c);
16146 }
16147 _ => {
16148 current.push(c);
16149 }
16150 }
16151 }
16152
16153 let remaining_text = text[position_after_last_function..].trim();
16155 if !remaining_text.is_empty() {
16156 let words: Vec<&str> = remaining_text.split_whitespace().collect();
16160 let looks_like_hint_functions = words.iter().all(|word| {
16161 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
16163 });
16164
16165 if !looks_like_hint_functions && words.len() > 1 {
16166 has_unparseable_content = true;
16167 }
16168 }
16169
16170 if has_unparseable_content {
16172 return vec![text.trim().to_string()];
16173 }
16174
16175 if results.is_empty() {
16177 results.push(text.trim().to_string());
16178 }
16179
16180 results
16181 }
16182
16183 fn format_hint_function(&self, hint: &str) -> String {
16186 if !self.config.pretty {
16187 return hint.to_string();
16188 }
16189
16190 if let Some(paren_pos) = hint.find('(') {
16192 if hint.ends_with(')') {
16193 let name = &hint[..paren_pos];
16194 let args_str = &hint[paren_pos + 1..hint.len() - 1];
16195
16196 let args: Vec<&str> = args_str.split_whitespace().collect();
16198
16199 let total_args_width: usize =
16201 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() {
16205 let mut result = format!("{}(\n", name);
16206 for arg in &args {
16207 result.push_str(" "); result.push_str(arg);
16209 result.push('\n');
16210 }
16211 result.push_str(" )"); return result;
16213 }
16214 }
16215 }
16216
16217 hint.to_string()
16218 }
16219
16220 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
16222 match expr {
16223 HintExpression::Function { name, args } => {
16224 let arg_strings: Vec<String> = args
16226 .iter()
16227 .map(|arg| {
16228 let mut gen = Generator::with_arc_config(self.config.clone());
16229 gen.generate_expression(arg)?;
16230 Ok(gen.output)
16231 })
16232 .collect::<Result<Vec<_>>>()?;
16233
16234 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
16236 + arg_strings.len().saturating_sub(1); let args_multiline =
16241 self.config.pretty && total_args_width > self.config.max_text_width;
16242
16243 if args_multiline && !arg_strings.is_empty() {
16244 let mut result = format!("{}(\n", name);
16246 for arg_str in &arg_strings {
16247 result.push_str(" "); result.push_str(arg_str);
16249 result.push('\n');
16250 }
16251 result.push_str(" )"); Ok(result)
16253 } else {
16254 let args_str = arg_strings.join(" ");
16256 Ok(format!("{}({})", name, args_str))
16257 }
16258 }
16259 HintExpression::Identifier(name) => Ok(name.clone()),
16260 HintExpression::Raw(text) => {
16261 if self.config.pretty {
16263 Ok(self.format_hint_function(text))
16264 } else {
16265 Ok(text.clone())
16266 }
16267 }
16268 }
16269 }
16270
16271 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
16272 if table.only {
16274 self.write_keyword("ONLY");
16275 self.write_space();
16276 }
16277
16278 if let Some(ref identifier_func) = table.identifier_func {
16280 self.generate_expression(identifier_func)?;
16281 if !table.name.name.is_empty() {
16283 if let Some(catalog) = &table.catalog {
16284 self.write(".");
16285 self.generate_identifier(catalog)?;
16286 }
16287 if let Some(schema) = &table.schema {
16288 self.write(".");
16289 self.generate_identifier(schema)?;
16290 }
16291 self.write(".");
16292 self.generate_identifier(&table.name)?;
16293 }
16294 } else {
16295 if let Some(catalog) = &table.catalog {
16296 self.generate_identifier(catalog)?;
16297 self.write(".");
16298 }
16299 if let Some(schema) = &table.schema {
16300 self.generate_identifier(schema)?;
16301 self.write(".");
16302 }
16303 self.generate_identifier(&table.name)?;
16304 }
16305
16306 if let Some(changes) = &table.changes {
16308 self.write(" ");
16309 self.generate_changes(changes)?;
16310 }
16311
16312 if !table.partitions.is_empty() {
16314 self.write_space();
16315 self.write_keyword("PARTITION");
16316 self.write("(");
16317 for (i, partition) in table.partitions.iter().enumerate() {
16318 if i > 0 {
16319 self.write(", ");
16320 }
16321 self.generate_identifier(partition)?;
16322 }
16323 self.write(")");
16324 }
16325
16326 if table.changes.is_none() {
16329 if let Some(when) = &table.when {
16330 self.write_space();
16331 self.generate_historical_data(when)?;
16332 }
16333 }
16334
16335 let system_time_post_alias = matches!(self.config.dialect, Some(DialectType::BigQuery));
16337 if !system_time_post_alias {
16338 if let Some(ref system_time) = table.system_time {
16339 self.write_space();
16340 self.write(system_time);
16341 }
16342 }
16343
16344 if let Some(ref version) = table.version {
16346 self.write_space();
16347 self.generate_version(version)?;
16348 }
16349
16350 let alias_post_tablesample = self.config.alias_post_tablesample;
16354
16355 if alias_post_tablesample {
16356 self.generate_table_sample_clause(table)?;
16358 }
16359
16360 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
16363 && table.hints.iter().any(|h| {
16364 if let Expression::Identifier(id) = h {
16365 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
16366 } else {
16367 false
16368 }
16369 });
16370 if !table.hints.is_empty() && !is_sqlite_hint {
16371 for hint in &table.hints {
16372 self.write_space();
16373 self.generate_expression(hint)?;
16374 }
16375 }
16376
16377 if let Some(alias) = &table.alias {
16378 self.write_space();
16379 let always_use_as = self.config.dialect.is_none()
16382 || matches!(
16383 self.config.dialect,
16384 Some(DialectType::Generic)
16385 | Some(DialectType::PostgreSQL)
16386 | Some(DialectType::Redshift)
16387 | Some(DialectType::Snowflake)
16388 | Some(DialectType::BigQuery)
16389 | Some(DialectType::DuckDB)
16390 | Some(DialectType::Presto)
16391 | Some(DialectType::Trino)
16392 | Some(DialectType::TSQL)
16393 | Some(DialectType::Fabric)
16394 | Some(DialectType::MySQL)
16395 | Some(DialectType::Spark)
16396 | Some(DialectType::Hive)
16397 | Some(DialectType::SQLite)
16398 | Some(DialectType::Drill)
16399 );
16400 let is_stage_ref = table.name.name.starts_with('@');
16401 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
16403 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
16404 self.write_keyword("AS");
16405 self.write_space();
16406 }
16407 self.generate_identifier(alias)?;
16408
16409 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
16412 self.write("(");
16413 for (i, col_alias) in table.column_aliases.iter().enumerate() {
16414 if i > 0 {
16415 self.write(", ");
16416 }
16417 self.generate_identifier(col_alias)?;
16418 }
16419 self.write(")");
16420 }
16421 }
16422
16423 if system_time_post_alias {
16425 if let Some(ref system_time) = table.system_time {
16426 self.write_space();
16427 self.write(system_time);
16428 }
16429 }
16430
16431 if !alias_post_tablesample {
16433 self.generate_table_sample_clause(table)?;
16434 }
16435
16436 if is_sqlite_hint {
16438 for hint in &table.hints {
16439 self.write_space();
16440 self.generate_expression(hint)?;
16441 }
16442 }
16443
16444 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
16446 self.write_space();
16447 self.write_keyword("FINAL");
16448 }
16449
16450 for comment in &table.trailing_comments {
16452 self.write_space();
16453 self.write_formatted_comment(comment);
16454 }
16455 Ok(())
16459 }
16460
16461 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
16463 if let Some(ref ts) = table.table_sample {
16464 self.write_space();
16465 if ts.is_using_sample {
16466 self.write_keyword("USING SAMPLE");
16467 } else {
16468 self.write_keyword(self.config.tablesample_keywords);
16470 }
16471 self.generate_sample_body(ts)?;
16472 if let Some(ref seed) = ts.seed {
16474 self.write_space();
16475 self.write_keyword(self.config.tablesample_seed_keyword);
16476 self.write(" (");
16477 self.generate_expression(seed)?;
16478 self.write(")");
16479 }
16480 }
16481 Ok(())
16482 }
16483
16484 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
16485 if sr.quoted {
16489 self.write("'");
16490 }
16491
16492 self.write(&sr.name);
16493 if let Some(path) = &sr.path {
16494 self.write(path);
16495 }
16496
16497 if sr.quoted {
16498 self.write("'");
16499 }
16500
16501 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
16503 if has_options {
16504 self.write(" (");
16505 let mut first = true;
16506
16507 if let Some(file_format) = &sr.file_format {
16508 if !first {
16509 self.write(", ");
16510 }
16511 self.write_keyword("FILE_FORMAT");
16512 self.write(" => ");
16513 self.generate_expression(file_format)?;
16514 first = false;
16515 }
16516
16517 if let Some(pattern) = &sr.pattern {
16518 if !first {
16519 self.write(", ");
16520 }
16521 self.write_keyword("PATTERN");
16522 self.write(" => '");
16523 self.write(pattern);
16524 self.write("'");
16525 }
16526
16527 self.write(")");
16528 }
16529 Ok(())
16530 }
16531
16532 fn generate_star(&mut self, star: &Star) -> Result<()> {
16533 use crate::dialects::DialectType;
16534
16535 if let Some(table) = &star.table {
16536 self.generate_identifier(table)?;
16537 self.write(".");
16538 }
16539 self.write("*");
16540
16541 if let Some(except) = &star.except {
16543 if !except.is_empty() {
16544 self.write_space();
16545 match self.config.dialect {
16547 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
16548 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
16549 self.write_keyword("EXCLUDE")
16550 }
16551 _ => self.write_keyword("EXCEPT"), }
16553 self.write(" (");
16554 for (i, col) in except.iter().enumerate() {
16555 if i > 0 {
16556 self.write(", ");
16557 }
16558 self.generate_identifier(col)?;
16559 }
16560 self.write(")");
16561 }
16562 }
16563
16564 if let Some(replace) = &star.replace {
16566 if !replace.is_empty() {
16567 self.write_space();
16568 self.write_keyword("REPLACE");
16569 self.write(" (");
16570 for (i, alias) in replace.iter().enumerate() {
16571 if i > 0 {
16572 self.write(", ");
16573 }
16574 self.generate_expression(&alias.this)?;
16575 self.write_space();
16576 self.write_keyword("AS");
16577 self.write_space();
16578 self.generate_identifier(&alias.alias)?;
16579 }
16580 self.write(")");
16581 }
16582 }
16583
16584 if let Some(rename) = &star.rename {
16586 if !rename.is_empty() {
16587 self.write_space();
16588 self.write_keyword("RENAME");
16589 self.write(" (");
16590 for (i, (old_name, new_name)) in rename.iter().enumerate() {
16591 if i > 0 {
16592 self.write(", ");
16593 }
16594 self.generate_identifier(old_name)?;
16595 self.write_space();
16596 self.write_keyword("AS");
16597 self.write_space();
16598 self.generate_identifier(new_name)?;
16599 }
16600 self.write(")");
16601 }
16602 }
16603
16604 for comment in &star.trailing_comments {
16606 self.write_space();
16607 self.write_formatted_comment(comment);
16608 }
16609
16610 Ok(())
16611 }
16612
16613 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
16615 self.write("{");
16616 match expr {
16617 Expression::Star(star) => {
16618 self.generate_star(star)?;
16620 }
16621 Expression::ILike(ilike) => {
16622 self.generate_expression(&ilike.left)?;
16624 self.write_space();
16625 self.write_keyword("ILIKE");
16626 self.write_space();
16627 self.generate_expression(&ilike.right)?;
16628 }
16629 _ => {
16630 self.generate_expression(expr)?;
16631 }
16632 }
16633 self.write("}");
16634 Ok(())
16635 }
16636
16637 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
16638 match &alias.this {
16642 Expression::Column(col) => {
16643 if let Some(table) = &col.table {
16645 self.generate_identifier(table)?;
16646 self.write(".");
16647 }
16648 self.generate_identifier(&col.name)?;
16649 }
16650 _ => {
16651 self.generate_expression(&alias.this)?;
16652 }
16653 }
16654
16655 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
16659 for comment in &alias.pre_alias_comments {
16660 self.write_space();
16661 self.write_formatted_comment(comment);
16662 }
16663 }
16664
16665 use crate::dialects::DialectType;
16666
16667 let is_table_source = matches!(
16673 &alias.this,
16674 Expression::JSONTable(_)
16675 | Expression::XMLTable(_)
16676 | Expression::TableFromRows(_)
16677 | Expression::Unnest(_)
16678 | Expression::MatchRecognize(_)
16679 | Expression::Select(_)
16680 | Expression::Subquery(_)
16681 | Expression::Paren(_)
16682 );
16683 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
16684 let skip_as = is_table_source && dialect_skips_table_alias_as;
16685
16686 self.write_space();
16687 if !skip_as {
16688 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
16689 if let Some(ref alias_keyword) = alias.alias_keyword {
16690 self.write(alias_keyword);
16691 } else {
16692 self.write_keyword("AS");
16693 }
16694 } else {
16695 self.write_keyword("AS");
16696 }
16697 self.write_space();
16698 }
16699
16700 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
16702
16703 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
16705 self.write("(");
16707 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16708 if i > 0 {
16709 self.write(", ");
16710 }
16711 self.generate_alias_identifier(col_alias)?;
16712 }
16713 self.write(")");
16714 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
16715 self.generate_alias_identifier(&alias.alias)?;
16717 self.write("(");
16718 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16719 if i > 0 {
16720 self.write(", ");
16721 }
16722 self.generate_alias_identifier(col_alias)?;
16723 }
16724 self.write(")");
16725 } else {
16726 self.generate_alias_identifier(&alias.alias)?;
16728 }
16729
16730 for comment in &alias.trailing_comments {
16732 self.write_space();
16733 self.write_formatted_comment(comment);
16734 }
16735
16736 if alias.trailing_comments.is_empty() {
16741 for comment in &alias.pre_alias_comments {
16742 self.write_space();
16743 self.write_formatted_comment(comment);
16744 }
16745 }
16746
16747 Ok(())
16748 }
16749
16750 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
16751 use crate::dialects::DialectType;
16752
16753 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
16755 self.generate_expression(&cast.this)?;
16756 self.write(" :> ");
16757 self.generate_data_type(&cast.to)?;
16758 return Ok(());
16759 }
16760
16761 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
16763 let is_unknown_type = matches!(cast.to, DataType::Unknown)
16764 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
16765 if is_unknown_type {
16766 if let Some(format) = &cast.format {
16767 self.write_keyword("CAST");
16768 self.write("(");
16769 self.generate_expression(&cast.this)?;
16770 self.write_space();
16771 self.write_keyword("AS");
16772 self.write_space();
16773 self.write_keyword("FORMAT");
16774 self.write_space();
16775 self.generate_expression(format)?;
16776 self.write(")");
16777 return Ok(());
16778 }
16779 }
16780 }
16781
16782 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
16785 if let Some(format) = &cast.format {
16786 let is_date = matches!(cast.to, DataType::Date);
16788 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
16789
16790 if is_date || is_timestamp {
16791 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
16792 self.write_keyword(func_name);
16793 self.write("(");
16794 self.generate_expression(&cast.this)?;
16795 self.write(", ");
16796
16797 if let Expression::Literal(lit) = format.as_ref() {
16800 if let Literal::String(fmt_str) = lit.as_ref() {
16801 let normalized = self.normalize_oracle_format(fmt_str);
16802 self.write("'");
16803 self.write(&normalized);
16804 self.write("'");
16805 }
16806 } else {
16807 self.generate_expression(format)?;
16808 }
16809
16810 self.write(")");
16811 return Ok(());
16812 }
16813 }
16814 }
16815
16816 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
16819 if let Expression::Array(arr) = &cast.this {
16820 self.generate_data_type(&cast.to)?;
16821 self.write("[");
16823 for (i, expr) in arr.expressions.iter().enumerate() {
16824 if i > 0 {
16825 self.write(", ");
16826 }
16827 self.generate_expression(expr)?;
16828 }
16829 self.write("]");
16830 return Ok(());
16831 }
16832 if matches!(&cast.this, Expression::ArrayFunc(_)) {
16833 self.generate_data_type(&cast.to)?;
16834 self.generate_expression(&cast.this)?;
16835 return Ok(());
16836 }
16837 }
16838
16839 if matches!(
16842 self.config.dialect,
16843 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
16844 ) {
16845 if let Expression::Struct(ref s) = cast.this {
16846 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
16847 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
16848 self.write_keyword("CAST");
16849 self.write("(");
16850 self.generate_struct_as_row(s)?;
16851 self.write_space();
16852 self.write_keyword("AS");
16853 self.write_space();
16854 self.generate_data_type(&cast.to)?;
16855 self.write(")");
16856 return Ok(());
16857 }
16858 }
16859 }
16860
16861 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
16864
16865 if use_double_colon {
16866 self.generate_expression(&cast.this)?;
16868 self.write("::");
16869 self.generate_data_type(&cast.to)?;
16870 } else {
16871 self.write_keyword("CAST");
16873 self.write("(");
16874 self.generate_expression(&cast.this)?;
16875 self.write_space();
16876 self.write_keyword("AS");
16877 self.write_space();
16878 if matches!(
16881 self.config.dialect,
16882 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
16883 ) {
16884 match &cast.to {
16885 DataType::Custom { ref name } => {
16886 if name.eq_ignore_ascii_case("LONGTEXT")
16887 || name.eq_ignore_ascii_case("MEDIUMTEXT")
16888 || name.eq_ignore_ascii_case("TINYTEXT")
16889 || name.eq_ignore_ascii_case("LONGBLOB")
16890 || name.eq_ignore_ascii_case("MEDIUMBLOB")
16891 || name.eq_ignore_ascii_case("TINYBLOB")
16892 {
16893 self.write_keyword("CHAR");
16894 } else {
16895 self.generate_data_type(&cast.to)?;
16896 }
16897 }
16898 DataType::VarChar { length, .. } => {
16899 self.write_keyword("CHAR");
16901 if let Some(n) = length {
16902 self.write(&format!("({})", n));
16903 }
16904 }
16905 DataType::Text => {
16906 self.write_keyword("CHAR");
16908 }
16909 DataType::Timestamp {
16910 precision,
16911 timezone: false,
16912 } => {
16913 self.write_keyword("DATETIME");
16915 if let Some(p) = precision {
16916 self.write(&format!("({})", p));
16917 }
16918 }
16919 _ => {
16920 self.generate_data_type(&cast.to)?;
16921 }
16922 }
16923 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
16924 match &cast.to {
16926 DataType::String { length } => {
16927 self.write_keyword("VARCHAR");
16928 if let Some(n) = length {
16929 self.write(&format!("({})", n));
16930 }
16931 }
16932 _ => {
16933 self.generate_data_type(&cast.to)?;
16934 }
16935 }
16936 } else {
16937 self.generate_data_type(&cast.to)?;
16938 }
16939
16940 if let Some(default) = &cast.default {
16942 self.write_space();
16943 self.write_keyword("DEFAULT");
16944 self.write_space();
16945 self.generate_expression(default)?;
16946 self.write_space();
16947 self.write_keyword("ON");
16948 self.write_space();
16949 self.write_keyword("CONVERSION");
16950 self.write_space();
16951 self.write_keyword("ERROR");
16952 }
16953
16954 if let Some(format) = &cast.format {
16957 if matches!(
16959 self.config.dialect,
16960 Some(crate::dialects::DialectType::Oracle)
16961 ) {
16962 self.write(", ");
16963 } else {
16964 self.write_space();
16965 self.write_keyword("FORMAT");
16966 self.write_space();
16967 }
16968 self.generate_expression(format)?;
16969 }
16970
16971 self.write(")");
16972 for comment in &cast.trailing_comments {
16974 self.write_space();
16975 self.write_formatted_comment(comment);
16976 }
16977 }
16978 Ok(())
16979 }
16980
16981 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
16984 self.write_keyword("ROW");
16985 self.write("(");
16986 for (i, (_, expr)) in s.fields.iter().enumerate() {
16987 if i > 0 {
16988 self.write(", ");
16989 }
16990 if let Expression::Struct(ref inner_s) = expr {
16992 self.generate_struct_as_row(inner_s)?;
16993 } else {
16994 self.generate_expression(expr)?;
16995 }
16996 }
16997 self.write(")");
16998 Ok(())
16999 }
17000
17001 fn normalize_oracle_format(&self, format: &str) -> String {
17004 let mut result = String::new();
17007 let chars: Vec<char> = format.chars().collect();
17008 let mut i = 0;
17009
17010 while i < chars.len() {
17011 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
17012 if i + 2 < chars.len() {
17014 let next = chars[i + 2];
17015 if next == '1' || next == '2' {
17016 result.push('H');
17018 result.push('H');
17019 i += 2;
17020 continue;
17021 }
17022 }
17023 result.push_str("HH12");
17025 i += 2;
17026 } else {
17027 result.push(chars[i]);
17028 i += 1;
17029 }
17030 }
17031
17032 result
17033 }
17034
17035 fn dialect_prefers_double_colon(&self) -> bool {
17038 matches!(self.config.dialect, Some(DialectType::ClickHouse))
17039 }
17040
17041 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17043 use crate::dialects::DialectType;
17044
17045 let use_percent_operator = matches!(
17047 self.config.dialect,
17048 Some(DialectType::Snowflake)
17049 | Some(DialectType::MySQL)
17050 | Some(DialectType::Presto)
17051 | Some(DialectType::Trino)
17052 | Some(DialectType::PostgreSQL)
17053 | Some(DialectType::DuckDB)
17054 | Some(DialectType::Hive)
17055 | Some(DialectType::Spark)
17056 | Some(DialectType::Databricks)
17057 | Some(DialectType::Athena)
17058 );
17059
17060 if use_percent_operator {
17061 let needs_paren = |e: &Expression| matches!(e, Expression::Add(_) | Expression::Sub(_));
17064 if needs_paren(&f.this) {
17065 self.write("(");
17066 self.generate_expression(&f.this)?;
17067 self.write(")");
17068 } else {
17069 self.generate_expression(&f.this)?;
17070 }
17071 self.write(" % ");
17072 if needs_paren(&f.expression) {
17073 self.write("(");
17074 self.generate_expression(&f.expression)?;
17075 self.write(")");
17076 } else {
17077 self.generate_expression(&f.expression)?;
17078 }
17079 Ok(())
17080 } else {
17081 self.generate_binary_func("MOD", &f.this, &f.expression)
17082 }
17083 }
17084
17085 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17087 use crate::dialects::DialectType;
17088
17089 let func_name = match self.config.dialect {
17091 Some(DialectType::Snowflake) => "COALESCE",
17092 _ => "IFNULL",
17093 };
17094
17095 self.generate_binary_func(func_name, &f.this, &f.expression)
17096 }
17097
17098 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17100 if let Some(ref original_name) = f.original_name {
17102 return self.generate_binary_func(original_name, &f.this, &f.expression);
17103 }
17104
17105 use crate::dialects::DialectType;
17107 let func_name = match self.config.dialect {
17108 Some(DialectType::Snowflake)
17109 | Some(DialectType::ClickHouse)
17110 | Some(DialectType::PostgreSQL)
17111 | Some(DialectType::Presto)
17112 | Some(DialectType::Trino)
17113 | Some(DialectType::Athena)
17114 | Some(DialectType::DuckDB)
17115 | Some(DialectType::BigQuery)
17116 | Some(DialectType::Spark)
17117 | Some(DialectType::Databricks)
17118 | Some(DialectType::Hive) => "COALESCE",
17119 Some(DialectType::MySQL)
17120 | Some(DialectType::Doris)
17121 | Some(DialectType::StarRocks)
17122 | Some(DialectType::SingleStore)
17123 | Some(DialectType::TiDB) => "IFNULL",
17124 _ => "NVL",
17125 };
17126
17127 self.generate_binary_func(func_name, &f.this, &f.expression)
17128 }
17129
17130 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
17132 use crate::dialects::DialectType;
17133
17134 let func_name = match self.config.dialect {
17136 Some(DialectType::Snowflake) => "STDDEV",
17137 _ => "STDDEV_SAMP",
17138 };
17139
17140 self.generate_agg_func(func_name, f)
17141 }
17142
17143 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
17144 self.generate_expression(&coll.this)?;
17145 self.write_space();
17146 self.write_keyword("COLLATE");
17147 self.write_space();
17148 if coll.quoted {
17149 self.write("'");
17151 self.write(&coll.collation);
17152 self.write("'");
17153 } else if coll.double_quoted {
17154 self.write("\"");
17156 self.write(&coll.collation);
17157 self.write("\"");
17158 } else {
17159 self.write(&coll.collation);
17161 }
17162 Ok(())
17163 }
17164
17165 fn generate_case(&mut self, case: &Case) -> Result<()> {
17166 let multiline_case = if self.config.pretty {
17168 let mut statements: Vec<String> = Vec::new();
17170 let operand_str = if let Some(operand) = &case.operand {
17171 let s = self.generate_to_string(operand)?;
17172 statements.push(format!("CASE {}", s));
17173 s
17174 } else {
17175 statements.push("CASE".to_string());
17176 String::new()
17177 };
17178 let _ = operand_str;
17179 for (condition, result) in &case.whens {
17180 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
17181 statements.push(format!("THEN {}", self.generate_to_string(result)?));
17182 }
17183 if let Some(else_) = &case.else_ {
17184 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
17185 }
17186 statements.push("END".to_string());
17187 self.too_wide(&statements)
17188 } else {
17189 false
17190 };
17191
17192 self.write_keyword("CASE");
17193 if let Some(operand) = &case.operand {
17194 self.write_space();
17195 self.generate_expression(operand)?;
17196 }
17197 if multiline_case {
17198 self.indent_level += 1;
17199 }
17200 for (condition, result) in &case.whens {
17201 if multiline_case {
17202 self.write_newline();
17203 self.write_indent();
17204 } else {
17205 self.write_space();
17206 }
17207 self.write_keyword("WHEN");
17208 self.write_space();
17209 self.generate_expression(condition)?;
17210 if multiline_case {
17211 self.write_newline();
17212 self.write_indent();
17213 } else {
17214 self.write_space();
17215 }
17216 self.write_keyword("THEN");
17217 self.write_space();
17218 self.generate_expression(result)?;
17219 }
17220 if let Some(else_) = &case.else_ {
17221 if multiline_case {
17222 self.write_newline();
17223 self.write_indent();
17224 } else {
17225 self.write_space();
17226 }
17227 self.write_keyword("ELSE");
17228 self.write_space();
17229 self.generate_expression(else_)?;
17230 }
17231 if multiline_case {
17232 self.indent_level -= 1;
17233 self.write_newline();
17234 self.write_indent();
17235 } else {
17236 self.write_space();
17237 }
17238 self.write_keyword("END");
17239 for comment in &case.comments {
17241 self.write(" ");
17242 self.write_formatted_comment(comment);
17243 }
17244 Ok(())
17245 }
17246
17247 fn generate_function(&mut self, func: &Function) -> Result<()> {
17248 let normalized_name = self.normalize_func_name(&func.name);
17250
17251 if matches!(self.config.dialect, Some(DialectType::DuckDB))
17253 && func.name.eq_ignore_ascii_case("ARRAY_CONSTRUCT_COMPACT")
17254 {
17255 self.write("LIST_FILTER(");
17256 self.write("[");
17257 for (i, arg) in func.args.iter().enumerate() {
17258 if i > 0 {
17259 self.write(", ");
17260 }
17261 self.generate_expression(arg)?;
17262 }
17263 self.write("], _u -> NOT _u IS NULL)");
17264 return Ok(());
17265 }
17266
17267 if matches!(self.config.dialect, Some(DialectType::Snowflake))
17270 && func.name.eq_ignore_ascii_case("TO_VARIANT")
17271 && func.args.len() == 1
17272 {
17273 let array_expressions = match &func.args[0] {
17274 Expression::ArrayFunc(arr) => Some(&arr.expressions),
17275 Expression::Array(arr) => Some(&arr.expressions),
17276 _ => None,
17277 };
17278 if let Some(expressions) = array_expressions {
17279 self.write_keyword("TO_VARIANT");
17280 self.write("(");
17281 self.write_keyword("ARRAY_CONSTRUCT");
17282 self.write("(");
17283 for (i, arg) in expressions.iter().enumerate() {
17284 if i > 0 {
17285 self.write(", ");
17286 }
17287 self.generate_expression(arg)?;
17288 }
17289 self.write(")");
17290 self.write(")");
17291 return Ok(());
17292 }
17293 }
17294
17295 if func.name.eq_ignore_ascii_case("STRUCT")
17297 && !matches!(
17298 self.config.dialect,
17299 Some(DialectType::BigQuery)
17300 | Some(DialectType::Spark)
17301 | Some(DialectType::Databricks)
17302 | Some(DialectType::Hive)
17303 | None
17304 )
17305 {
17306 return self.generate_struct_function_cross_dialect(func);
17307 }
17308
17309 if func.name.eq_ignore_ascii_case("__SS_JSON_PATH_QMARK__") && func.args.len() == 2 {
17312 self.generate_expression(&func.args[0])?;
17313 self.write("::?");
17314 if let Expression::Literal(lit) = &func.args[1] {
17316 if let crate::expressions::Literal::String(key) = lit.as_ref() {
17317 self.write(key);
17318 }
17319 } else {
17320 self.generate_expression(&func.args[1])?;
17321 }
17322 return Ok(());
17323 }
17324
17325 if func.name.eq_ignore_ascii_case("__PG_BITWISE_XOR__") && func.args.len() == 2 {
17327 self.generate_expression(&func.args[0])?;
17328 self.write(" # ");
17329 self.generate_expression(&func.args[1])?;
17330 return Ok(());
17331 }
17332
17333 if matches!(
17335 self.config.dialect,
17336 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
17337 ) && func.name.eq_ignore_ascii_case("TRY")
17338 && func.args.len() == 1
17339 {
17340 self.generate_expression(&func.args[0])?;
17341 return Ok(());
17342 }
17343
17344 if self.config.dialect == Some(DialectType::ClickHouse)
17346 && func.name.eq_ignore_ascii_case("TOSTARTOFDAY")
17347 && func.args.len() == 1
17348 {
17349 self.write("dateTrunc('DAY', ");
17350 self.generate_expression(&func.args[0])?;
17351 self.write(")");
17352 return Ok(());
17353 }
17354
17355 if self.config.dialect == Some(DialectType::ClickHouse)
17357 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
17358 && func.args.len() == 2
17359 {
17360 self.write("dateTrunc(");
17361 self.generate_expression(&func.args[0])?;
17362 self.write(", ");
17363 self.generate_expression(&func.args[1])?;
17364 self.write(")");
17365 return Ok(());
17366 }
17367
17368 if matches!(
17370 self.config.dialect,
17371 Some(DialectType::Presto | DialectType::Trino | DialectType::Athena)
17372 ) && func.name.eq_ignore_ascii_case("SUBSTRING")
17373 {
17374 self.write_keyword("SUBSTR");
17375 self.write("(");
17376 for (i, arg) in func.args.iter().enumerate() {
17377 if i > 0 {
17378 self.write(", ");
17379 }
17380 self.generate_expression(arg)?;
17381 }
17382 self.write(")");
17383 return Ok(());
17384 }
17385
17386 if self.config.dialect == Some(DialectType::Snowflake)
17387 && func.name.eq_ignore_ascii_case("LIST_DISTINCT")
17388 && func.args.len() == 1
17389 {
17390 self.write_keyword("ARRAY_DISTINCT");
17391 self.write("(");
17392 self.write_keyword("ARRAY_COMPACT");
17393 self.write("(");
17394 self.generate_expression(&func.args[0])?;
17395 self.write("))");
17396 return Ok(());
17397 }
17398
17399 if self.config.dialect == Some(DialectType::Snowflake)
17400 && func.name.eq_ignore_ascii_case("LIST")
17401 && func.args.len() == 1
17402 && !matches!(func.args.first(), Some(Expression::Select(_)))
17403 {
17404 self.write_keyword("ARRAY_AGG");
17405 self.write("(");
17406 self.generate_expression(&func.args[0])?;
17407 self.write(")");
17408 return Ok(());
17409 }
17410
17411 if self.config.dialect == Some(DialectType::Redshift)
17413 && func.name.eq_ignore_ascii_case("CONCAT")
17414 && func.args.len() >= 2
17415 {
17416 for (i, arg) in func.args.iter().enumerate() {
17417 if i > 0 {
17418 self.write(" || ");
17419 }
17420 self.generate_expression(arg)?;
17421 }
17422 return Ok(());
17423 }
17424
17425 if self.config.dialect == Some(DialectType::Redshift)
17427 && func.name.eq_ignore_ascii_case("CONCAT_WS")
17428 && func.args.len() >= 2
17429 {
17430 let sep = &func.args[0];
17431 for (i, arg) in func.args.iter().skip(1).enumerate() {
17432 if i > 0 {
17433 self.write(" || ");
17434 self.generate_expression(sep)?;
17435 self.write(" || ");
17436 }
17437 self.generate_expression(arg)?;
17438 }
17439 return Ok(());
17440 }
17441
17442 if self.config.dialect == Some(DialectType::Redshift)
17445 && (func.name.eq_ignore_ascii_case("DATEDIFF")
17446 || func.name.eq_ignore_ascii_case("DATE_DIFF"))
17447 && func.args.len() == 3
17448 {
17449 self.write_keyword("DATEDIFF");
17450 self.write("(");
17451 self.write_redshift_date_part(&func.args[0]);
17453 self.write(", ");
17454 self.generate_expression(&func.args[1])?;
17455 self.write(", ");
17456 self.generate_expression(&func.args[2])?;
17457 self.write(")");
17458 return Ok(());
17459 }
17460
17461 if self.config.dialect == Some(DialectType::Redshift)
17464 && (func.name.eq_ignore_ascii_case("DATEADD")
17465 || func.name.eq_ignore_ascii_case("DATE_ADD"))
17466 && func.args.len() == 3
17467 {
17468 self.write_keyword("DATEADD");
17469 self.write("(");
17470 self.write_redshift_date_part(&func.args[0]);
17472 self.write(", ");
17473 self.generate_expression(&func.args[1])?;
17474 self.write(", ");
17475 self.generate_expression(&func.args[2])?;
17476 self.write(")");
17477 return Ok(());
17478 }
17479
17480 if func.name.eq_ignore_ascii_case("UUID_STRING")
17482 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
17483 {
17484 if matches!(
17485 self.config.dialect,
17486 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
17487 ) {
17488 self.write_keyword("CAST");
17489 self.write("(");
17490 self.write_keyword("UUID");
17491 self.write("() ");
17492 self.write_keyword("AS");
17493 self.write(" ");
17494 self.write_keyword("STRING");
17495 self.write(")");
17496 return Ok(());
17497 }
17498
17499 if matches!(
17500 self.config.dialect,
17501 Some(DialectType::Presto | DialectType::Trino)
17502 ) {
17503 self.write_keyword("CAST");
17504 self.write("(");
17505 self.write_keyword("UUID");
17506 self.write("() ");
17507 self.write_keyword("AS");
17508 self.write(" ");
17509 self.write_keyword("VARCHAR");
17510 self.write(")");
17511 return Ok(());
17512 }
17513
17514 if self.config.dialect == Some(DialectType::DuckDB) && func.args.len() == 2 {
17515 self.write("(SELECT LOWER(SUBSTRING(h, 1, 8) || '-' || SUBSTRING(h, 9, 4) || '-' || '5' || SUBSTRING(h, 14, 3) || '-' || FORMAT('{:02x}', CAST('0x' || SUBSTRING(h, 17, 2) AS INT) & 63 | 128) || SUBSTRING(h, 19, 2) || '-' || SUBSTRING(h, 21, 12)) FROM (SELECT SUBSTRING(SHA1(UNHEX(REPLACE(");
17516 self.generate_expression(&func.args[0])?;
17517 self.write(", '-', '')) || ENCODE(");
17518 self.generate_expression(&func.args[1])?;
17519 self.write(")), 1, 32) AS h))");
17520 return Ok(());
17521 }
17522
17523 let func_name = match self.config.dialect {
17524 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
17525 Some(DialectType::BigQuery) => "GENERATE_UUID",
17526 _ => "UUID",
17527 };
17528 self.write_keyword(func_name);
17529 self.write("()");
17530 return Ok(());
17531 }
17532
17533 if matches!(self.config.dialect, Some(DialectType::Snowflake))
17537 && func.name.eq_ignore_ascii_case("GENERATOR")
17538 {
17539 let has_positional_args =
17540 !func.args.is_empty() && !matches!(&func.args[0], Expression::NamedArgument(_));
17541 if has_positional_args {
17542 let param_names = ["ROWCOUNT", "TIMELIMIT"];
17543 self.write_keyword("GENERATOR");
17544 self.write("(");
17545 for (i, arg) in func.args.iter().enumerate() {
17546 if i > 0 {
17547 self.write(", ");
17548 }
17549 if i < param_names.len() {
17550 self.write_keyword(param_names[i]);
17551 self.write(" => ");
17552 self.generate_expression(arg)?;
17553 } else {
17554 self.generate_expression(arg)?;
17555 }
17556 }
17557 self.write(")");
17558 return Ok(());
17559 }
17560 }
17561
17562 if self.config.dialect == Some(DialectType::Redshift)
17565 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
17566 && func.args.len() == 2
17567 {
17568 self.write_keyword("DATE_TRUNC");
17569 self.write("(");
17570 self.write_redshift_date_part_quoted(&func.args[0]);
17572 self.write(", ");
17573 self.generate_expression(&func.args[1])?;
17574 self.write(")");
17575 return Ok(());
17576 }
17577
17578 if matches!(
17580 self.config.dialect,
17581 Some(DialectType::TSQL) | Some(DialectType::Fabric)
17582 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17583 || func.name.eq_ignore_ascii_case("DATEPART"))
17584 && func.args.len() == 2
17585 {
17586 self.write_keyword("DATEPART");
17587 self.write("(");
17588 self.generate_expression(&func.args[0])?;
17589 self.write(", ");
17590 self.generate_expression(&func.args[1])?;
17591 self.write(")");
17592 return Ok(());
17593 }
17594
17595 if matches!(
17597 self.config.dialect,
17598 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
17599 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17600 || func.name.eq_ignore_ascii_case("DATEPART"))
17601 && func.args.len() == 2
17602 {
17603 self.write_keyword("EXTRACT");
17604 self.write("(");
17605 match &func.args[0] {
17607 Expression::Literal(lit)
17608 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
17609 {
17610 let crate::expressions::Literal::String(s) = lit.as_ref() else {
17611 unreachable!()
17612 };
17613 self.write(&s.to_ascii_lowercase());
17614 }
17615 _ => self.generate_expression(&func.args[0])?,
17616 }
17617 self.write_space();
17618 self.write_keyword("FROM");
17619 self.write_space();
17620 self.generate_expression(&func.args[1])?;
17621 self.write(")");
17622 return Ok(());
17623 }
17624
17625 if self.config.dialect == Some(DialectType::PostgreSQL)
17627 && matches!(
17628 func.name.to_ascii_uppercase().as_str(),
17629 "DATE_ADD" | "DATE_SUB"
17630 )
17631 && func.args.len() == 2
17632 && matches!(func.args[1], Expression::Interval(_))
17633 {
17634 self.generate_expression(&func.args[0])?;
17635 self.write_space();
17636 if func.name.eq_ignore_ascii_case("DATE_SUB") {
17637 self.write("-");
17638 } else {
17639 self.write("+");
17640 }
17641 self.write_space();
17642 self.generate_expression(&func.args[1])?;
17643 return Ok(());
17644 }
17645
17646 if self.config.dialect == Some(DialectType::Dremio)
17649 && (func.name.eq_ignore_ascii_case("DATE_PART")
17650 || func.name.eq_ignore_ascii_case("DATEPART"))
17651 && func.args.len() == 2
17652 {
17653 self.write_keyword("EXTRACT");
17654 self.write("(");
17655 self.generate_expression(&func.args[0])?;
17656 self.write_space();
17657 self.write_keyword("FROM");
17658 self.write_space();
17659 self.generate_dremio_date_expression(&func.args[1])?;
17661 self.write(")");
17662 return Ok(());
17663 }
17664
17665 if self.config.dialect == Some(DialectType::Dremio)
17667 && func.name.eq_ignore_ascii_case("CURRENT_DATE_UTC")
17668 && func.args.is_empty()
17669 {
17670 self.write_keyword("CURRENT_DATE_UTC");
17671 return Ok(());
17672 }
17673
17674 if self.config.dialect == Some(DialectType::Dremio)
17678 && func.name.eq_ignore_ascii_case("DATETYPE")
17679 && func.args.len() == 3
17680 {
17681 fn get_int_literal(expr: &Expression) -> Option<i64> {
17683 if let Expression::Literal(lit) = expr {
17684 if let crate::expressions::Literal::Number(s) = lit.as_ref() {
17685 s.parse::<i64>().ok()
17686 } else {
17687 None
17688 }
17689 } else {
17690 None
17691 }
17692 }
17693
17694 if let (Some(year), Some(month), Some(day)) = (
17696 get_int_literal(&func.args[0]),
17697 get_int_literal(&func.args[1]),
17698 get_int_literal(&func.args[2]),
17699 ) {
17700 self.write_keyword("DATE");
17702 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
17703 return Ok(());
17704 }
17705
17706 self.write_keyword("CAST");
17708 self.write("(");
17709 self.write_keyword("CONCAT");
17710 self.write("(");
17711 self.generate_expression(&func.args[0])?;
17712 self.write(", '-', ");
17713 self.generate_expression(&func.args[1])?;
17714 self.write(", '-', ");
17715 self.generate_expression(&func.args[2])?;
17716 self.write(")");
17717 self.write_space();
17718 self.write_keyword("AS");
17719 self.write_space();
17720 self.write_keyword("DATE");
17721 self.write(")");
17722 return Ok(());
17723 }
17724
17725 let is_presto_like = matches!(
17728 self.config.dialect,
17729 Some(DialectType::Presto) | Some(DialectType::Trino)
17730 );
17731 if is_presto_like && func.name.eq_ignore_ascii_case("DATE_ADD") && func.args.len() == 3 {
17732 self.write_keyword("DATE_ADD");
17733 self.write("(");
17734 self.generate_expression(&func.args[0])?;
17736 self.write(", ");
17737 let interval = &func.args[1];
17739 let needs_cast = !self.returns_integer_type(interval);
17740 if needs_cast {
17741 self.write_keyword("CAST");
17742 self.write("(");
17743 }
17744 self.generate_expression(interval)?;
17745 if needs_cast {
17746 self.write_space();
17747 self.write_keyword("AS");
17748 self.write_space();
17749 self.write_keyword("BIGINT");
17750 self.write(")");
17751 }
17752 self.write(", ");
17753 self.generate_expression(&func.args[2])?;
17755 self.write(")");
17756 return Ok(());
17757 }
17758
17759 let use_brackets = func.use_bracket_syntax;
17761
17762 let has_ordinality = func.name.len() >= 16
17767 && func.name[func.name.len() - 16..].eq_ignore_ascii_case(" WITH ORDINALITY");
17768 let output_name = if has_ordinality {
17769 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
17770 self.normalize_func_name(base_name)
17771 } else {
17772 normalized_name.clone()
17773 };
17774
17775 let quote_source_clickhouse_function =
17778 matches!(self.config.dialect, Some(DialectType::ClickHouse))
17779 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
17780 && func.quoted;
17781
17782 if quote_source_clickhouse_function {
17783 self.generate_identifier(&Identifier {
17784 name: func.name.clone(),
17785 quoted: true,
17786 trailing_comments: Vec::new(),
17787 span: None,
17788 })?;
17789 } else if func.name.contains('.') && !has_ordinality {
17790 if func.quoted {
17793 self.write("`");
17794 self.write(&func.name);
17795 self.write("`");
17796 } else {
17797 self.write(&func.name);
17798 }
17799 } else {
17800 self.write(&output_name);
17801 }
17802
17803 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
17806 let needs_parens = if func.name.eq_ignore_ascii_case("CURRENT_USER")
17807 || func.name.eq_ignore_ascii_case("SESSION_USER")
17808 || func.name.eq_ignore_ascii_case("SYSTEM_USER")
17809 {
17810 matches!(
17811 self.config.dialect,
17812 Some(DialectType::Snowflake)
17813 | Some(DialectType::Spark)
17814 | Some(DialectType::Databricks)
17815 | Some(DialectType::Hive)
17816 )
17817 } else {
17818 false
17819 };
17820 !needs_parens
17821 };
17822 if force_parens {
17823 for comment in &func.trailing_comments {
17825 self.write_space();
17826 self.write_formatted_comment(comment);
17827 }
17828 return Ok(());
17829 }
17830
17831 if func.name.eq_ignore_ascii_case("CUBE")
17833 || func.name.eq_ignore_ascii_case("ROLLUP")
17834 || func.name.eq_ignore_ascii_case("GROUPING SETS")
17835 {
17836 self.write(" (");
17837 } else if use_brackets {
17838 self.write("[");
17839 } else {
17840 self.write("(");
17841 }
17842 if func.distinct {
17843 self.write_keyword("DISTINCT");
17844 self.write_space();
17845 }
17846
17847 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
17849 && (func.name.eq_ignore_ascii_case("TABLE")
17850 || func.name.eq_ignore_ascii_case("FLATTEN"));
17851 let is_grouping_func = func.name.eq_ignore_ascii_case("GROUPING SETS")
17853 || func.name.eq_ignore_ascii_case("CUBE")
17854 || func.name.eq_ignore_ascii_case("ROLLUP");
17855 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
17856 if is_grouping_func {
17857 true
17858 } else {
17859 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
17861 for arg in &func.args {
17862 let mut temp_gen = Generator::with_arc_config(self.config.clone());
17863 Arc::make_mut(&mut temp_gen.config).pretty = false; temp_gen.generate_expression(arg)?;
17865 expr_strings.push(temp_gen.output);
17866 }
17867 self.too_wide(&expr_strings)
17868 }
17869 } else {
17870 false
17871 };
17872
17873 if should_split {
17874 self.write_newline();
17876 self.indent_level += 1;
17877 for (i, arg) in func.args.iter().enumerate() {
17878 self.write_indent();
17879 self.generate_expression(arg)?;
17880 if i + 1 < func.args.len() {
17881 self.write(",");
17882 }
17883 self.write_newline();
17884 }
17885 self.indent_level -= 1;
17886 self.write_indent();
17887 } else {
17888 for (i, arg) in func.args.iter().enumerate() {
17890 if i > 0 {
17891 self.write(", ");
17892 }
17893 self.generate_expression(arg)?;
17894 }
17895 }
17896
17897 if use_brackets {
17898 self.write("]");
17899 } else {
17900 self.write(")");
17901 }
17902 if has_ordinality {
17904 self.write_space();
17905 self.write_keyword("WITH ORDINALITY");
17906 }
17907 for comment in &func.trailing_comments {
17909 self.write_space();
17910 self.write_formatted_comment(comment);
17911 }
17912 Ok(())
17913 }
17914
17915 fn generate_function_emits(&mut self, fe: &FunctionEmits) -> Result<()> {
17916 self.generate_expression(&fe.this)?;
17917 self.write_keyword(" EMITS ");
17918 self.generate_expression(&fe.emits)?;
17919 Ok(())
17920 }
17921
17922 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
17923 let mut normalized_name = self.normalize_func_name(&func.name);
17925
17926 if func.name.eq_ignore_ascii_case("MAX_BY") || func.name.eq_ignore_ascii_case("MIN_BY") {
17928 let is_max = func.name.eq_ignore_ascii_case("MAX_BY");
17929 match self.config.dialect {
17930 Some(DialectType::ClickHouse) => {
17931 normalized_name = if is_max {
17932 Cow::Borrowed("argMax")
17933 } else {
17934 Cow::Borrowed("argMin")
17935 };
17936 }
17937 Some(DialectType::DuckDB) => {
17938 normalized_name = if is_max {
17939 Cow::Borrowed("ARG_MAX")
17940 } else {
17941 Cow::Borrowed("ARG_MIN")
17942 };
17943 }
17944 _ => {}
17945 }
17946 }
17947 self.write(normalized_name.as_ref());
17948 self.write("(");
17949 if func.distinct {
17950 self.write_keyword("DISTINCT");
17951 self.write_space();
17952 }
17953
17954 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
17958 let needs_multi_arg_transform =
17959 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
17960
17961 if needs_multi_arg_transform {
17962 self.write_keyword("CASE");
17964 for arg in &func.args {
17965 self.write_space();
17966 self.write_keyword("WHEN");
17967 self.write_space();
17968 self.generate_expression(arg)?;
17969 self.write_space();
17970 self.write_keyword("IS NULL THEN NULL");
17971 }
17972 self.write_space();
17973 self.write_keyword("ELSE");
17974 self.write(" (");
17975 for (i, arg) in func.args.iter().enumerate() {
17976 if i > 0 {
17977 self.write(", ");
17978 }
17979 self.generate_expression(arg)?;
17980 }
17981 self.write(")");
17982 self.write_space();
17983 self.write_keyword("END");
17984 } else {
17985 for (i, arg) in func.args.iter().enumerate() {
17986 if i > 0 {
17987 self.write(", ");
17988 }
17989 self.generate_expression(arg)?;
17990 }
17991 }
17992
17993 let clickhouse_ignore_nulls_outside =
17995 matches!(self.config.dialect, Some(DialectType::ClickHouse));
17996 if self.config.ignore_nulls_in_func
17997 && !matches!(
17998 self.config.dialect,
17999 Some(DialectType::DuckDB) | Some(DialectType::ClickHouse)
18000 )
18001 {
18002 if let Some(ignore) = func.ignore_nulls {
18003 self.write_space();
18004 if ignore {
18005 self.write_keyword("IGNORE NULLS");
18006 } else {
18007 self.write_keyword("RESPECT NULLS");
18008 }
18009 }
18010 }
18011
18012 if !func.order_by.is_empty() {
18014 self.write_space();
18015 self.write_keyword("ORDER BY");
18016 self.write_space();
18017 for (i, ord) in func.order_by.iter().enumerate() {
18018 if i > 0 {
18019 self.write(", ");
18020 }
18021 self.generate_ordered(ord)?;
18022 }
18023 }
18024
18025 if let Some(limit) = &func.limit {
18027 self.write_space();
18028 self.write_keyword("LIMIT");
18029 self.write_space();
18030 if let Expression::Tuple(t) = limit.as_ref() {
18032 if t.expressions.len() == 2 {
18033 self.generate_expression(&t.expressions[0])?;
18034 self.write(", ");
18035 self.generate_expression(&t.expressions[1])?;
18036 } else {
18037 self.generate_expression(limit)?;
18038 }
18039 } else {
18040 self.generate_expression(limit)?;
18041 }
18042 }
18043
18044 self.write(")");
18045
18046 if (!self.config.ignore_nulls_in_func || clickhouse_ignore_nulls_outside)
18048 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18049 {
18050 if let Some(ignore) = func.ignore_nulls {
18051 self.write_space();
18052 if ignore {
18053 self.write_keyword("IGNORE NULLS");
18054 } else {
18055 self.write_keyword("RESPECT NULLS");
18056 }
18057 }
18058 }
18059
18060 if let Some(filter) = &func.filter {
18061 self.write_space();
18062 self.write_keyword("FILTER");
18063 self.write("(");
18064 self.write_keyword("WHERE");
18065 self.write_space();
18066 self.generate_expression(filter)?;
18067 self.write(")");
18068 }
18069
18070 Ok(())
18071 }
18072
18073 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
18074 self.generate_expression(&wf.this)?;
18075
18076 if let Some(keep) = &wf.keep {
18078 self.write_space();
18079 self.write_keyword("KEEP");
18080 self.write(" (");
18081 self.write_keyword("DENSE_RANK");
18082 self.write_space();
18083 if keep.first {
18084 self.write_keyword("FIRST");
18085 } else {
18086 self.write_keyword("LAST");
18087 }
18088 self.write_space();
18089 self.write_keyword("ORDER BY");
18090 self.write_space();
18091 for (i, ord) in keep.order_by.iter().enumerate() {
18092 if i > 0 {
18093 self.write(", ");
18094 }
18095 self.generate_ordered(ord)?;
18096 }
18097 self.write(")");
18098 }
18099
18100 let has_over = !wf.over.partition_by.is_empty()
18102 || !wf.over.order_by.is_empty()
18103 || wf.over.frame.is_some()
18104 || wf.over.window_name.is_some();
18105
18106 if has_over {
18108 self.write_space();
18109 self.write_keyword("OVER");
18110
18111 let has_specs = !wf.over.partition_by.is_empty()
18113 || !wf.over.order_by.is_empty()
18114 || wf.over.frame.is_some();
18115
18116 if wf.over.window_name.is_some() && !has_specs {
18117 self.write_space();
18119 self.write(&wf.over.window_name.as_ref().unwrap().name);
18120 } else {
18121 self.write(" (");
18123 self.generate_over(&wf.over)?;
18124 self.write(")");
18125 }
18126 } else if wf.keep.is_none() {
18127 self.write_space();
18129 self.write_keyword("OVER");
18130 self.write(" ()");
18131 }
18132
18133 Ok(())
18134 }
18135
18136 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
18138 self.generate_expression(&wg.this)?;
18139 self.write_space();
18140 self.write_keyword("WITHIN GROUP");
18141 self.write(" (");
18142 self.write_keyword("ORDER BY");
18143 self.write_space();
18144 for (i, ord) in wg.order_by.iter().enumerate() {
18145 if i > 0 {
18146 self.write(", ");
18147 }
18148 self.generate_ordered(ord)?;
18149 }
18150 self.write(")");
18151 Ok(())
18152 }
18153
18154 fn generate_over(&mut self, over: &Over) -> Result<()> {
18156 let mut has_content = false;
18157
18158 if let Some(name) = &over.window_name {
18160 self.write(&name.name);
18161 has_content = true;
18162 }
18163
18164 if !over.partition_by.is_empty() {
18166 if has_content {
18167 self.write_space();
18168 }
18169 self.write_keyword("PARTITION BY");
18170 self.write_space();
18171 for (i, expr) in over.partition_by.iter().enumerate() {
18172 if i > 0 {
18173 self.write(", ");
18174 }
18175 self.generate_expression(expr)?;
18176 }
18177 has_content = true;
18178 }
18179
18180 if !over.order_by.is_empty() {
18182 if has_content {
18183 self.write_space();
18184 }
18185 self.write_keyword("ORDER BY");
18186 self.write_space();
18187 for (i, ordered) in over.order_by.iter().enumerate() {
18188 if i > 0 {
18189 self.write(", ");
18190 }
18191 self.generate_ordered(ordered)?;
18192 }
18193 has_content = true;
18194 }
18195
18196 if let Some(frame) = &over.frame {
18198 if has_content {
18199 self.write_space();
18200 }
18201 self.generate_window_frame(frame)?;
18202 }
18203
18204 Ok(())
18205 }
18206
18207 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
18208 let lowercase_frame = self.config.lowercase_window_frame_keywords;
18210
18211 if !lowercase_frame {
18213 if let Some(kind_text) = &frame.kind_text {
18214 self.write(kind_text);
18215 } else {
18216 match frame.kind {
18217 WindowFrameKind::Rows => self.write_keyword("ROWS"),
18218 WindowFrameKind::Range => self.write_keyword("RANGE"),
18219 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
18220 }
18221 }
18222 } else {
18223 match frame.kind {
18224 WindowFrameKind::Rows => self.write("rows"),
18225 WindowFrameKind::Range => self.write("range"),
18226 WindowFrameKind::Groups => self.write("groups"),
18227 }
18228 }
18229
18230 self.write_space();
18233 let should_normalize = self.config.normalize_window_frame_between
18234 && frame.end.is_none()
18235 && matches!(
18236 frame.start,
18237 WindowFrameBound::Preceding(_)
18238 | WindowFrameBound::Following(_)
18239 | WindowFrameBound::UnboundedPreceding
18240 | WindowFrameBound::UnboundedFollowing
18241 );
18242
18243 if let Some(end) = &frame.end {
18244 self.write_keyword("BETWEEN");
18246 self.write_space();
18247 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18248 self.write_space();
18249 self.write_keyword("AND");
18250 self.write_space();
18251 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
18252 } else if should_normalize {
18253 self.write_keyword("BETWEEN");
18255 self.write_space();
18256 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18257 self.write_space();
18258 self.write_keyword("AND");
18259 self.write_space();
18260 self.write_keyword("CURRENT ROW");
18261 } else {
18262 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18264 }
18265
18266 if let Some(exclude) = &frame.exclude {
18268 self.write_space();
18269 self.write_keyword("EXCLUDE");
18270 self.write_space();
18271 match exclude {
18272 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
18273 WindowFrameExclude::Group => self.write_keyword("GROUP"),
18274 WindowFrameExclude::Ties => self.write_keyword("TIES"),
18275 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
18276 }
18277 }
18278
18279 Ok(())
18280 }
18281
18282 fn generate_window_frame_bound(
18283 &mut self,
18284 bound: &WindowFrameBound,
18285 side_text: Option<&str>,
18286 ) -> Result<()> {
18287 let lowercase_frame = self.config.lowercase_window_frame_keywords;
18289
18290 match bound {
18291 WindowFrameBound::CurrentRow => {
18292 self.write_keyword("CURRENT ROW");
18293 }
18294 WindowFrameBound::UnboundedPreceding => {
18295 self.write_keyword("UNBOUNDED");
18296 self.write_space();
18297 if lowercase_frame {
18298 self.write("preceding");
18299 } else if let Some(text) = side_text {
18300 self.write(text);
18301 } else {
18302 self.write_keyword("PRECEDING");
18303 }
18304 }
18305 WindowFrameBound::UnboundedFollowing => {
18306 self.write_keyword("UNBOUNDED");
18307 self.write_space();
18308 if lowercase_frame {
18309 self.write("following");
18310 } else if let Some(text) = side_text {
18311 self.write(text);
18312 } else {
18313 self.write_keyword("FOLLOWING");
18314 }
18315 }
18316 WindowFrameBound::Preceding(expr) => {
18317 self.generate_expression(expr)?;
18318 self.write_space();
18319 if lowercase_frame {
18320 self.write("preceding");
18321 } else if let Some(text) = side_text {
18322 self.write(text);
18323 } else {
18324 self.write_keyword("PRECEDING");
18325 }
18326 }
18327 WindowFrameBound::Following(expr) => {
18328 self.generate_expression(expr)?;
18329 self.write_space();
18330 if lowercase_frame {
18331 self.write("following");
18332 } else if let Some(text) = side_text {
18333 self.write(text);
18334 } else {
18335 self.write_keyword("FOLLOWING");
18336 }
18337 }
18338 WindowFrameBound::BarePreceding => {
18339 if lowercase_frame {
18340 self.write("preceding");
18341 } else if let Some(text) = side_text {
18342 self.write(text);
18343 } else {
18344 self.write_keyword("PRECEDING");
18345 }
18346 }
18347 WindowFrameBound::BareFollowing => {
18348 if lowercase_frame {
18349 self.write("following");
18350 } else if let Some(text) = side_text {
18351 self.write(text);
18352 } else {
18353 self.write_keyword("FOLLOWING");
18354 }
18355 }
18356 WindowFrameBound::Value(expr) => {
18357 self.generate_expression(expr)?;
18359 }
18360 }
18361 Ok(())
18362 }
18363
18364 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
18365 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
18368 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
18369 && !matches!(&interval.this, Some(Expression::Literal(_)));
18370
18371 if self.config.single_string_interval {
18374 if let (
18375 Some(Expression::Literal(lit)),
18376 Some(IntervalUnitSpec::Simple {
18377 ref unit,
18378 ref use_plural,
18379 }),
18380 ) = (&interval.this, &interval.unit)
18381 {
18382 if let Literal::String(ref val) = lit.as_ref() {
18383 self.write_keyword("INTERVAL");
18384 self.write_space();
18385 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
18386 let unit_str = self.interval_unit_str(unit, effective_plural);
18387 self.write("'");
18388 self.write(val);
18389 self.write(" ");
18390 self.write(&unit_str);
18391 self.write("'");
18392 return Ok(());
18393 }
18394 }
18395 }
18396
18397 if !skip_interval_keyword {
18398 self.write_keyword("INTERVAL");
18399 }
18400
18401 if let Some(ref value) = interval.this {
18403 if !skip_interval_keyword {
18404 self.write_space();
18405 }
18406 let needs_parens = interval.unit.is_some()
18410 && matches!(
18411 value,
18412 Expression::Add(_)
18413 | Expression::Sub(_)
18414 | Expression::Mul(_)
18415 | Expression::Div(_)
18416 | Expression::Mod(_)
18417 | Expression::BitwiseAnd(_)
18418 | Expression::BitwiseOr(_)
18419 | Expression::BitwiseXor(_)
18420 );
18421 if needs_parens {
18422 self.write("(");
18423 }
18424 self.generate_expression(value)?;
18425 if needs_parens {
18426 self.write(")");
18427 }
18428 }
18429
18430 if let Some(ref unit_spec) = interval.unit {
18432 self.write_space();
18433 self.write_interval_unit_spec(unit_spec)?;
18434 }
18435
18436 Ok(())
18437 }
18438
18439 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
18441 match (unit, use_plural) {
18442 (IntervalUnit::Year, false) => "YEAR",
18443 (IntervalUnit::Year, true) => "YEARS",
18444 (IntervalUnit::Quarter, false) => "QUARTER",
18445 (IntervalUnit::Quarter, true) => "QUARTERS",
18446 (IntervalUnit::Month, false) => "MONTH",
18447 (IntervalUnit::Month, true) => "MONTHS",
18448 (IntervalUnit::Week, false) => "WEEK",
18449 (IntervalUnit::Week, true) => "WEEKS",
18450 (IntervalUnit::Day, false) => "DAY",
18451 (IntervalUnit::Day, true) => "DAYS",
18452 (IntervalUnit::Hour, false) => "HOUR",
18453 (IntervalUnit::Hour, true) => "HOURS",
18454 (IntervalUnit::Minute, false) => "MINUTE",
18455 (IntervalUnit::Minute, true) => "MINUTES",
18456 (IntervalUnit::Second, false) => "SECOND",
18457 (IntervalUnit::Second, true) => "SECONDS",
18458 (IntervalUnit::Millisecond, false) => "MILLISECOND",
18459 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
18460 (IntervalUnit::Microsecond, false) => "MICROSECOND",
18461 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
18462 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
18463 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
18464 }
18465 }
18466
18467 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
18468 match unit_spec {
18469 IntervalUnitSpec::Simple { unit, use_plural } => {
18470 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
18472 self.write_simple_interval_unit(unit, effective_plural);
18473 }
18474 IntervalUnitSpec::Span(span) => {
18475 self.write_simple_interval_unit(&span.this, false);
18476 self.write_space();
18477 self.write_keyword("TO");
18478 self.write_space();
18479 self.write_simple_interval_unit(&span.expression, false);
18480 }
18481 IntervalUnitSpec::ExprSpan(span) => {
18482 self.generate_expression(&span.this)?;
18484 self.write_space();
18485 self.write_keyword("TO");
18486 self.write_space();
18487 self.generate_expression(&span.expression)?;
18488 }
18489 IntervalUnitSpec::Expr(expr) => {
18490 self.generate_expression(expr)?;
18491 }
18492 }
18493 Ok(())
18494 }
18495
18496 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
18497 match (unit, use_plural) {
18499 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
18500 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
18501 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
18502 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
18503 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
18504 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
18505 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
18506 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
18507 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
18508 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
18509 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
18510 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
18511 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
18512 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
18513 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
18514 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
18515 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
18516 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
18517 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
18518 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
18519 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
18520 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
18521 }
18522 }
18523
18524 fn write_redshift_date_part(&mut self, expr: &Expression) {
18527 let part_str = self.extract_date_part_string(expr);
18528 if let Some(part) = part_str {
18529 let normalized = self.normalize_date_part(&part);
18530 self.write_keyword(&normalized);
18531 } else {
18532 let _ = self.generate_expression(expr);
18534 }
18535 }
18536
18537 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
18540 let part_str = self.extract_date_part_string(expr);
18541 if let Some(part) = part_str {
18542 let normalized = self.normalize_date_part(&part);
18543 self.write("'");
18544 self.write(&normalized);
18545 self.write("'");
18546 } else {
18547 let _ = self.generate_expression(expr);
18549 }
18550 }
18551
18552 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
18554 match expr {
18555 Expression::Literal(lit)
18556 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
18557 {
18558 let crate::expressions::Literal::String(s) = lit.as_ref() else {
18559 unreachable!()
18560 };
18561 Some(s.clone())
18562 }
18563 Expression::Identifier(id) => Some(id.name.clone()),
18564 Expression::Var(v) => Some(v.this.clone()),
18565 Expression::Column(col) if col.table.is_none() => {
18566 Some(col.name.name.clone())
18568 }
18569 _ => None,
18570 }
18571 }
18572
18573 fn normalize_date_part(&self, part: &str) -> String {
18576 let mut buf = [0u8; 64];
18577 let lower: &str = if part.len() <= 64 {
18578 for (i, b) in part.bytes().enumerate() {
18579 buf[i] = b.to_ascii_lowercase();
18580 }
18581 std::str::from_utf8(&buf[..part.len()]).unwrap_or(part)
18582 } else {
18583 return part.to_ascii_uppercase();
18584 };
18585 match lower {
18586 "day" | "days" | "d" => "DAY".to_string(),
18587 "month" | "months" | "mon" | "mons" | "mm" => "MONTH".to_string(),
18588 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
18589 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
18590 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
18591 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
18592 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
18593 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
18594 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
18595 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
18596 _ => part.to_ascii_uppercase(),
18597 }
18598 }
18599
18600 fn write_datetime_field(&mut self, field: &DateTimeField) {
18601 match field {
18602 DateTimeField::Year => self.write_keyword("YEAR"),
18603 DateTimeField::Month => self.write_keyword("MONTH"),
18604 DateTimeField::Day => self.write_keyword("DAY"),
18605 DateTimeField::Hour => self.write_keyword("HOUR"),
18606 DateTimeField::Minute => self.write_keyword("MINUTE"),
18607 DateTimeField::Second => self.write_keyword("SECOND"),
18608 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
18609 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
18610 DateTimeField::DayOfWeek => {
18611 let name = match self.config.dialect {
18612 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
18613 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "WEEKDAY",
18614 _ => "DOW",
18615 };
18616 self.write_keyword(name);
18617 }
18618 DateTimeField::DayOfYear => {
18619 let name = match self.config.dialect {
18620 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
18621 _ => "DOY",
18622 };
18623 self.write_keyword(name);
18624 }
18625 DateTimeField::Week => self.write_keyword("WEEK"),
18626 DateTimeField::WeekWithModifier(modifier) => {
18627 self.write_keyword("WEEK");
18628 self.write("(");
18629 self.write(modifier);
18630 self.write(")");
18631 }
18632 DateTimeField::Quarter => self.write_keyword("QUARTER"),
18633 DateTimeField::Epoch => self.write_keyword("EPOCH"),
18634 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
18635 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
18636 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
18637 DateTimeField::Date => self.write_keyword("DATE"),
18638 DateTimeField::Time => self.write_keyword("TIME"),
18639 DateTimeField::Custom(name) => self.write(name),
18640 }
18641 }
18642
18643 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
18645 match field {
18646 DateTimeField::Year => self.write("year"),
18647 DateTimeField::Month => self.write("month"),
18648 DateTimeField::Day => self.write("day"),
18649 DateTimeField::Hour => self.write("hour"),
18650 DateTimeField::Minute => self.write("minute"),
18651 DateTimeField::Second => self.write("second"),
18652 DateTimeField::Millisecond => self.write("millisecond"),
18653 DateTimeField::Microsecond => self.write("microsecond"),
18654 DateTimeField::DayOfWeek => self.write("dow"),
18655 DateTimeField::DayOfYear => self.write("doy"),
18656 DateTimeField::Week => self.write("week"),
18657 DateTimeField::WeekWithModifier(modifier) => {
18658 self.write("week(");
18659 self.write(modifier);
18660 self.write(")");
18661 }
18662 DateTimeField::Quarter => self.write("quarter"),
18663 DateTimeField::Epoch => self.write("epoch"),
18664 DateTimeField::Timezone => self.write("timezone"),
18665 DateTimeField::TimezoneHour => self.write("timezone_hour"),
18666 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
18667 DateTimeField::Date => self.write("date"),
18668 DateTimeField::Time => self.write("time"),
18669 DateTimeField::Custom(name) => self.write(name),
18670 }
18671 }
18672
18673 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
18676 self.write_keyword(name);
18677 self.write("(");
18678 self.generate_expression(arg)?;
18679 self.write(")");
18680 Ok(())
18681 }
18682
18683 fn generate_unary_func(
18685 &mut self,
18686 default_name: &str,
18687 f: &crate::expressions::UnaryFunc,
18688 ) -> Result<()> {
18689 let name = f.original_name.as_deref().unwrap_or(default_name);
18690 self.write_keyword(name);
18691 self.write("(");
18692 self.generate_expression(&f.this)?;
18693 self.write(")");
18694 Ok(())
18695 }
18696
18697 fn generate_sqrt_cbrt(
18699 &mut self,
18700 f: &crate::expressions::UnaryFunc,
18701 func_name: &str,
18702 _op: &str,
18703 ) -> Result<()> {
18704 self.write_keyword(func_name);
18707 self.write("(");
18708 self.generate_expression(&f.this)?;
18709 self.write(")");
18710 Ok(())
18711 }
18712
18713 fn generate_binary_func(
18714 &mut self,
18715 name: &str,
18716 arg1: &Expression,
18717 arg2: &Expression,
18718 ) -> Result<()> {
18719 self.write_keyword(name);
18720 self.write("(");
18721 self.generate_expression(arg1)?;
18722 self.write(", ");
18723 self.generate_expression(arg2)?;
18724 self.write(")");
18725 Ok(())
18726 }
18727
18728 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
18732 let func_name = f.name.as_deref().unwrap_or("CHAR");
18734 self.write_keyword(func_name);
18735 self.write("(");
18736 for (i, arg) in f.args.iter().enumerate() {
18737 if i > 0 {
18738 self.write(", ");
18739 }
18740 self.generate_expression(arg)?;
18741 }
18742 if let Some(ref charset) = f.charset {
18743 self.write(" ");
18744 self.write_keyword("USING");
18745 self.write(" ");
18746 self.write(charset);
18747 }
18748 self.write(")");
18749 Ok(())
18750 }
18751
18752 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
18753 use crate::dialects::DialectType;
18754
18755 match self.config.dialect {
18756 Some(DialectType::Teradata) => {
18757 self.generate_expression(&f.this)?;
18759 self.write(" ** ");
18760 self.generate_expression(&f.expression)?;
18761 Ok(())
18762 }
18763 _ => {
18764 self.generate_binary_func("POWER", &f.this, &f.expression)
18766 }
18767 }
18768 }
18769
18770 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
18771 self.write_func_name(name);
18772 self.write("(");
18773 for (i, arg) in args.iter().enumerate() {
18774 if i > 0 {
18775 self.write(", ");
18776 }
18777 self.generate_expression(arg)?;
18778 }
18779 self.write(")");
18780 Ok(())
18781 }
18782
18783 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
18786 self.write_keyword("CONCAT_WS");
18787 self.write("(");
18788 self.generate_expression(&f.separator)?;
18789 for expr in &f.expressions {
18790 self.write(", ");
18791 self.generate_expression(expr)?;
18792 }
18793 self.write(")");
18794 Ok(())
18795 }
18796
18797 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
18798 if let Expression::Concat(op) = expr {
18799 Self::collect_concat_operands(&op.left, out);
18800 Self::collect_concat_operands(&op.right, out);
18801 } else {
18802 out.push(expr);
18803 }
18804 }
18805
18806 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
18807 let mut operands = Vec::new();
18808 Self::collect_concat_operands(&op.left, &mut operands);
18809 Self::collect_concat_operands(&op.right, &mut operands);
18810
18811 self.write_keyword("CONCAT");
18812 self.write("(");
18813 for (i, operand) in operands.iter().enumerate() {
18814 if i > 0 {
18815 self.write(", ");
18816 }
18817 self.generate_expression(operand)?;
18818 }
18819 self.write(")");
18820 Ok(())
18821 }
18822
18823 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
18824 if let Expression::DPipe(dpipe) = expr {
18825 Self::collect_dpipe_operands(&dpipe.this, out);
18826 Self::collect_dpipe_operands(&dpipe.expression, out);
18827 } else {
18828 out.push(expr);
18829 }
18830 }
18831
18832 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
18833 let mut operands = Vec::new();
18834 Self::collect_dpipe_operands(&e.this, &mut operands);
18835 Self::collect_dpipe_operands(&e.expression, &mut operands);
18836
18837 self.write_keyword("CONCAT");
18838 self.write("(");
18839 for (i, operand) in operands.iter().enumerate() {
18840 if i > 0 {
18841 self.write(", ");
18842 }
18843 self.generate_expression(operand)?;
18844 }
18845 self.write(")");
18846 Ok(())
18847 }
18848
18849 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
18850 let use_substr = matches!(
18852 self.config.dialect,
18853 Some(
18854 DialectType::Oracle
18855 | DialectType::Presto
18856 | DialectType::Trino
18857 | DialectType::Athena
18858 )
18859 );
18860 if use_substr {
18861 self.write_keyword("SUBSTR");
18862 } else {
18863 self.write_keyword("SUBSTRING");
18864 }
18865 self.write("(");
18866 self.generate_expression(&f.this)?;
18867 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
18869 let use_comma_syntax = matches!(
18871 self.config.dialect,
18872 Some(DialectType::Spark)
18873 | Some(DialectType::Hive)
18874 | Some(DialectType::Databricks)
18875 | Some(DialectType::TSQL)
18876 | Some(DialectType::Fabric)
18877 );
18878 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
18879 self.write_space();
18881 self.write_keyword("FROM");
18882 self.write_space();
18883 self.generate_expression(&f.start)?;
18884 if let Some(length) = &f.length {
18885 self.write_space();
18886 self.write_keyword("FOR");
18887 self.write_space();
18888 self.generate_expression(length)?;
18889 }
18890 } else {
18891 self.write(", ");
18893 self.generate_expression(&f.start)?;
18894 if let Some(length) = &f.length {
18895 self.write(", ");
18896 self.generate_expression(length)?;
18897 }
18898 }
18899 self.write(")");
18900 Ok(())
18901 }
18902
18903 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
18904 self.write_keyword("OVERLAY");
18905 self.write("(");
18906 self.generate_expression(&f.this)?;
18907 self.write_space();
18908 self.write_keyword("PLACING");
18909 self.write_space();
18910 self.generate_expression(&f.replacement)?;
18911 self.write_space();
18912 self.write_keyword("FROM");
18913 self.write_space();
18914 self.generate_expression(&f.from)?;
18915 if let Some(length) = &f.length {
18916 self.write_space();
18917 self.write_keyword("FOR");
18918 self.write_space();
18919 self.generate_expression(length)?;
18920 }
18921 self.write(")");
18922 Ok(())
18923 }
18924
18925 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
18926 if f.position_explicit && f.characters.is_none() {
18929 match f.position {
18930 TrimPosition::Leading => {
18931 self.write_keyword("LTRIM");
18932 self.write("(");
18933 self.generate_expression(&f.this)?;
18934 self.write(")");
18935 return Ok(());
18936 }
18937 TrimPosition::Trailing => {
18938 self.write_keyword("RTRIM");
18939 self.write("(");
18940 self.generate_expression(&f.this)?;
18941 self.write(")");
18942 return Ok(());
18943 }
18944 TrimPosition::Both => {
18945 }
18948 }
18949 }
18950
18951 self.write_keyword("TRIM");
18952 self.write("(");
18953 let force_standard = f.characters.is_some()
18956 && !f.sql_standard_syntax
18957 && matches!(
18958 self.config.dialect,
18959 Some(DialectType::Hive)
18960 | Some(DialectType::Spark)
18961 | Some(DialectType::Databricks)
18962 | Some(DialectType::ClickHouse)
18963 );
18964 let use_standard = (f.sql_standard_syntax || force_standard)
18965 && !(f.position_explicit
18966 && f.characters.is_none()
18967 && matches!(f.position, TrimPosition::Both));
18968 if use_standard {
18969 if f.position_explicit {
18972 match f.position {
18973 TrimPosition::Both => self.write_keyword("BOTH"),
18974 TrimPosition::Leading => self.write_keyword("LEADING"),
18975 TrimPosition::Trailing => self.write_keyword("TRAILING"),
18976 }
18977 self.write_space();
18978 }
18979 if let Some(chars) = &f.characters {
18980 self.generate_expression(chars)?;
18981 self.write_space();
18982 }
18983 self.write_keyword("FROM");
18984 self.write_space();
18985 self.generate_expression(&f.this)?;
18986 } else {
18987 self.generate_expression(&f.this)?;
18989 if let Some(chars) = &f.characters {
18990 self.write(", ");
18991 self.generate_expression(chars)?;
18992 }
18993 }
18994 self.write(")");
18995 Ok(())
18996 }
18997
18998 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
18999 self.write_keyword("REPLACE");
19000 self.write("(");
19001 self.generate_expression(&f.this)?;
19002 self.write(", ");
19003 self.generate_expression(&f.old)?;
19004 self.write(", ");
19005 self.generate_expression(&f.new)?;
19006 self.write(")");
19007 Ok(())
19008 }
19009
19010 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
19011 self.write_keyword(name);
19012 self.write("(");
19013 self.generate_expression(&f.this)?;
19014 self.write(", ");
19015 self.generate_expression(&f.length)?;
19016 self.write(")");
19017 Ok(())
19018 }
19019
19020 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
19021 self.write_keyword("REPEAT");
19022 self.write("(");
19023 self.generate_expression(&f.this)?;
19024 self.write(", ");
19025 self.generate_expression(&f.times)?;
19026 self.write(")");
19027 Ok(())
19028 }
19029
19030 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
19031 self.write_keyword(name);
19032 self.write("(");
19033 self.generate_expression(&f.this)?;
19034 self.write(", ");
19035 self.generate_expression(&f.length)?;
19036 if let Some(fill) = &f.fill {
19037 self.write(", ");
19038 self.generate_expression(fill)?;
19039 }
19040 self.write(")");
19041 Ok(())
19042 }
19043
19044 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
19045 self.write_keyword("SPLIT");
19046 self.write("(");
19047 self.generate_expression(&f.this)?;
19048 self.write(", ");
19049 self.generate_expression(&f.delimiter)?;
19050 self.write(")");
19051 Ok(())
19052 }
19053
19054 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
19055 use crate::dialects::DialectType;
19056 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
19058 self.generate_expression(&f.this)?;
19059 self.write(" ~ ");
19060 self.generate_expression(&f.pattern)?;
19061 } else if matches!(self.config.dialect, Some(DialectType::Exasol)) && f.flags.is_none() {
19062 self.generate_expression(&f.this)?;
19064 self.write_keyword(" REGEXP_LIKE ");
19065 self.generate_expression(&f.pattern)?;
19066 } else if matches!(
19067 self.config.dialect,
19068 Some(DialectType::SingleStore)
19069 | Some(DialectType::Spark)
19070 | Some(DialectType::Hive)
19071 | Some(DialectType::Databricks)
19072 ) && f.flags.is_none()
19073 {
19074 self.generate_expression(&f.this)?;
19076 self.write_keyword(" RLIKE ");
19077 self.generate_expression(&f.pattern)?;
19078 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
19079 self.write_keyword("REGEXP");
19081 self.write("(");
19082 self.generate_expression(&f.this)?;
19083 self.write(", ");
19084 self.generate_expression(&f.pattern)?;
19085 if let Some(flags) = &f.flags {
19086 self.write(", ");
19087 self.generate_expression(flags)?;
19088 }
19089 self.write(")");
19090 } else {
19091 self.write_keyword("REGEXP_LIKE");
19092 self.write("(");
19093 self.generate_expression(&f.this)?;
19094 self.write(", ");
19095 self.generate_expression(&f.pattern)?;
19096 if let Some(flags) = &f.flags {
19097 self.write(", ");
19098 self.generate_expression(flags)?;
19099 }
19100 self.write(")");
19101 }
19102 Ok(())
19103 }
19104
19105 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
19106 self.write_keyword("REGEXP_REPLACE");
19107 self.write("(");
19108 self.generate_expression(&f.this)?;
19109 self.write(", ");
19110 self.generate_expression(&f.pattern)?;
19111 self.write(", ");
19112 self.generate_expression(&f.replacement)?;
19113 if let Some(flags) = &f.flags {
19114 self.write(", ");
19115 self.generate_expression(flags)?;
19116 }
19117 self.write(")");
19118 Ok(())
19119 }
19120
19121 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
19122 self.write_keyword("REGEXP_EXTRACT");
19123 self.write("(");
19124 self.generate_expression(&f.this)?;
19125 self.write(", ");
19126 self.generate_expression(&f.pattern)?;
19127 if let Some(group) = &f.group {
19128 self.write(", ");
19129 self.generate_expression(group)?;
19130 }
19131 self.write(")");
19132 Ok(())
19133 }
19134
19135 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
19138 self.write_keyword("ROUND");
19139 self.write("(");
19140 self.generate_expression(&f.this)?;
19141 if let Some(decimals) = &f.decimals {
19142 self.write(", ");
19143 self.generate_expression(decimals)?;
19144 }
19145 self.write(")");
19146 Ok(())
19147 }
19148
19149 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
19150 self.write_keyword("FLOOR");
19151 self.write("(");
19152 self.generate_expression(&f.this)?;
19153 if let Some(to) = &f.to {
19155 self.write(" ");
19156 self.write_keyword("TO");
19157 self.write(" ");
19158 self.generate_expression(to)?;
19159 } else if let Some(scale) = &f.scale {
19160 self.write(", ");
19161 self.generate_expression(scale)?;
19162 }
19163 self.write(")");
19164 Ok(())
19165 }
19166
19167 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
19168 self.write_keyword("CEIL");
19169 self.write("(");
19170 self.generate_expression(&f.this)?;
19171 if let Some(to) = &f.to {
19173 self.write(" ");
19174 self.write_keyword("TO");
19175 self.write(" ");
19176 self.generate_expression(to)?;
19177 } else if let Some(decimals) = &f.decimals {
19178 self.write(", ");
19179 self.generate_expression(decimals)?;
19180 }
19181 self.write(")");
19182 Ok(())
19183 }
19184
19185 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
19186 use crate::expressions::Literal;
19187
19188 if let Some(base) = &f.base {
19189 if self.is_log_base_none() {
19192 if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "2"))
19193 {
19194 self.write_func_name("LOG2");
19195 self.write("(");
19196 self.generate_expression(&f.this)?;
19197 self.write(")");
19198 return Ok(());
19199 } else if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "10"))
19200 {
19201 self.write_func_name("LOG10");
19202 self.write("(");
19203 self.generate_expression(&f.this)?;
19204 self.write(")");
19205 return Ok(());
19206 }
19207 }
19209
19210 self.write_func_name("LOG");
19211 self.write("(");
19212 if self.is_log_value_first() {
19213 self.generate_expression(&f.this)?;
19215 self.write(", ");
19216 self.generate_expression(base)?;
19217 } else {
19218 self.generate_expression(base)?;
19220 self.write(", ");
19221 self.generate_expression(&f.this)?;
19222 }
19223 self.write(")");
19224 } else {
19225 self.write_func_name("LOG");
19227 self.write("(");
19228 self.generate_expression(&f.this)?;
19229 self.write(")");
19230 }
19231 Ok(())
19232 }
19233
19234 fn is_log_value_first(&self) -> bool {
19237 use crate::dialects::DialectType;
19238 matches!(
19239 self.config.dialect,
19240 Some(DialectType::BigQuery)
19241 | Some(DialectType::TSQL)
19242 | Some(DialectType::Tableau)
19243 | Some(DialectType::Fabric)
19244 )
19245 }
19246
19247 fn is_log_base_none(&self) -> bool {
19250 use crate::dialects::DialectType;
19251 matches!(
19252 self.config.dialect,
19253 Some(DialectType::Presto)
19254 | Some(DialectType::Trino)
19255 | Some(DialectType::ClickHouse)
19256 | Some(DialectType::Athena)
19257 )
19258 }
19259
19260 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
19263 self.write_keyword("CURRENT_TIME");
19264 if let Some(precision) = f.precision {
19265 self.write(&format!("({})", precision));
19266 } else if matches!(
19267 self.config.dialect,
19268 Some(crate::dialects::DialectType::MySQL)
19269 | Some(crate::dialects::DialectType::SingleStore)
19270 | Some(crate::dialects::DialectType::TiDB)
19271 ) {
19272 self.write("()");
19273 }
19274 Ok(())
19275 }
19276
19277 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
19278 use crate::dialects::DialectType;
19279
19280 if f.sysdate {
19282 match self.config.dialect {
19283 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
19284 self.write_keyword("SYSDATE");
19285 return Ok(());
19286 }
19287 Some(DialectType::Snowflake) => {
19288 self.write_keyword("SYSDATE");
19290 self.write("()");
19291 return Ok(());
19292 }
19293 _ => {
19294 }
19296 }
19297 }
19298
19299 self.write_keyword("CURRENT_TIMESTAMP");
19300 if let Some(precision) = f.precision {
19302 self.write(&format!("({})", precision));
19303 } else if matches!(
19304 self.config.dialect,
19305 Some(crate::dialects::DialectType::MySQL)
19306 | Some(crate::dialects::DialectType::SingleStore)
19307 | Some(crate::dialects::DialectType::TiDB)
19308 | Some(crate::dialects::DialectType::Spark)
19309 | Some(crate::dialects::DialectType::Hive)
19310 | Some(crate::dialects::DialectType::Databricks)
19311 | Some(crate::dialects::DialectType::ClickHouse)
19312 | Some(crate::dialects::DialectType::BigQuery)
19313 | Some(crate::dialects::DialectType::Snowflake)
19314 | Some(crate::dialects::DialectType::Exasol)
19315 ) {
19316 self.write("()");
19317 }
19318 Ok(())
19319 }
19320
19321 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
19322 if self.config.dialect == Some(DialectType::Exasol) {
19324 self.write_keyword("CONVERT_TZ");
19325 self.write("(");
19326 self.generate_expression(&f.this)?;
19327 self.write(", 'UTC', ");
19328 self.generate_expression(&f.zone)?;
19329 self.write(")");
19330 return Ok(());
19331 }
19332
19333 self.generate_expression(&f.this)?;
19334 self.write_space();
19335 self.write_keyword("AT TIME ZONE");
19336 self.write_space();
19337 self.generate_expression(&f.zone)?;
19338 Ok(())
19339 }
19340
19341 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
19342 use crate::dialects::DialectType;
19343
19344 let is_presto_like = matches!(
19347 self.config.dialect,
19348 Some(DialectType::Presto) | Some(DialectType::Trino)
19349 );
19350
19351 if is_presto_like {
19352 self.write_keyword(name);
19353 self.write("(");
19354 self.write("'");
19356 self.write_simple_interval_unit(&f.unit, false);
19357 self.write("'");
19358 self.write(", ");
19359 let needs_cast = !self.returns_integer_type(&f.interval);
19361 if needs_cast {
19362 self.write_keyword("CAST");
19363 self.write("(");
19364 }
19365 self.generate_expression(&f.interval)?;
19366 if needs_cast {
19367 self.write_space();
19368 self.write_keyword("AS");
19369 self.write_space();
19370 self.write_keyword("BIGINT");
19371 self.write(")");
19372 }
19373 self.write(", ");
19374 self.generate_expression(&f.this)?;
19375 self.write(")");
19376 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
19377 self.generate_expression(&f.this)?;
19378 self.write_space();
19379 if name.eq_ignore_ascii_case("DATE_SUB") {
19380 self.write("-");
19381 } else {
19382 self.write("+");
19383 }
19384 self.write_space();
19385 self.write_keyword("INTERVAL");
19386 self.write_space();
19387 self.write("'");
19388 let mut interval_gen = Generator::with_arc_config(self.config.clone());
19389 let interval_sql = interval_gen.generate(&f.interval)?;
19390 self.write(&interval_sql);
19391 self.write(" ");
19392 self.write_simple_interval_unit(&f.unit, false);
19393 self.write("'");
19394 } else {
19395 self.write_keyword(name);
19396 self.write("(");
19397 self.generate_expression(&f.this)?;
19398 self.write(", ");
19399 self.write_keyword("INTERVAL");
19400 self.write_space();
19401 self.generate_expression(&f.interval)?;
19402 self.write_space();
19403 self.write_simple_interval_unit(&f.unit, false); self.write(")");
19405 }
19406 Ok(())
19407 }
19408
19409 fn returns_integer_type(&self, expr: &Expression) -> bool {
19412 use crate::expressions::{DataType, Literal};
19413 match expr {
19414 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
19416 let Literal::Number(n) = lit.as_ref() else {
19417 unreachable!()
19418 };
19419 !n.contains('.')
19420 }
19421
19422 Expression::Floor(f) => self.returns_integer_type(&f.this),
19424
19425 Expression::Round(f) => {
19427 f.decimals.is_none() && self.returns_integer_type(&f.this)
19429 }
19430
19431 Expression::Sign(f) => self.returns_integer_type(&f.this),
19433
19434 Expression::Abs(f) => self.returns_integer_type(&f.this),
19436
19437 Expression::Mul(op) => {
19439 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19440 }
19441 Expression::Add(op) => {
19442 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19443 }
19444 Expression::Sub(op) => {
19445 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19446 }
19447 Expression::Mod(op) => self.returns_integer_type(&op.left),
19448
19449 Expression::Cast(c) => matches!(
19451 &c.to,
19452 DataType::BigInt { .. }
19453 | DataType::Int { .. }
19454 | DataType::SmallInt { .. }
19455 | DataType::TinyInt { .. }
19456 ),
19457
19458 Expression::Neg(op) => self.returns_integer_type(&op.this),
19460
19461 Expression::Paren(p) => self.returns_integer_type(&p.this),
19463
19464 _ => false,
19467 }
19468 }
19469
19470 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
19471 self.write_keyword("DATEDIFF");
19472 self.write("(");
19473 if let Some(unit) = &f.unit {
19474 self.write_simple_interval_unit(unit, false); self.write(", ");
19476 }
19477 self.generate_expression(&f.this)?;
19478 self.write(", ");
19479 self.generate_expression(&f.expression)?;
19480 self.write(")");
19481 Ok(())
19482 }
19483
19484 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
19485 if self.config.dialect == Some(DialectType::ClickHouse) {
19486 self.write("dateTrunc");
19487 } else {
19488 self.write_keyword("DATE_TRUNC");
19489 }
19490 self.write("('");
19491 self.write_datetime_field(&f.unit);
19492 self.write("', ");
19493 self.generate_expression(&f.this)?;
19494 self.write(")");
19495 Ok(())
19496 }
19497
19498 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
19499 use crate::dialects::DialectType;
19500 use crate::expressions::DateTimeField;
19501
19502 self.write_keyword("LAST_DAY");
19503 self.write("(");
19504 self.generate_expression(&f.this)?;
19505 if let Some(unit) = &f.unit {
19506 self.write(", ");
19507 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
19510 if let DateTimeField::WeekWithModifier(_) = unit {
19511 self.write_keyword("WEEK");
19512 } else {
19513 self.write_datetime_field(unit);
19514 }
19515 } else {
19516 self.write_datetime_field(unit);
19517 }
19518 }
19519 self.write(")");
19520 Ok(())
19521 }
19522
19523 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
19524 if matches!(
19526 self.config.dialect,
19527 Some(DialectType::TSQL) | Some(DialectType::Fabric)
19528 ) {
19529 self.write_keyword("DATEPART");
19530 self.write("(");
19531 self.write_datetime_field(&f.field);
19532 self.write(", ");
19533 self.generate_expression(&f.this)?;
19534 self.write(")");
19535 return Ok(());
19536 }
19537 self.write_keyword("EXTRACT");
19538 self.write("(");
19539 if matches!(
19541 self.config.dialect,
19542 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
19543 ) {
19544 self.write_datetime_field_lower(&f.field);
19545 } else {
19546 self.write_datetime_field(&f.field);
19547 }
19548 self.write_space();
19549 self.write_keyword("FROM");
19550 self.write_space();
19551 self.generate_expression(&f.this)?;
19552 self.write(")");
19553 Ok(())
19554 }
19555
19556 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
19557 self.write_keyword("TO_DATE");
19558 self.write("(");
19559 self.generate_expression(&f.this)?;
19560 if let Some(format) = &f.format {
19561 self.write(", ");
19562 self.generate_expression(format)?;
19563 }
19564 self.write(")");
19565 Ok(())
19566 }
19567
19568 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
19569 self.write_keyword("TO_TIMESTAMP");
19570 self.write("(");
19571 self.generate_expression(&f.this)?;
19572 if let Some(format) = &f.format {
19573 self.write(", ");
19574 self.generate_expression(format)?;
19575 }
19576 self.write(")");
19577 Ok(())
19578 }
19579
19580 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
19583 use crate::dialects::DialectType;
19584
19585 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
19587 self.write_keyword("CASE WHEN");
19588 self.write_space();
19589 self.generate_expression(&f.condition)?;
19590 self.write_space();
19591 self.write_keyword("THEN");
19592 self.write_space();
19593 self.generate_expression(&f.true_value)?;
19594 if let Some(false_val) = &f.false_value {
19595 self.write_space();
19596 self.write_keyword("ELSE");
19597 self.write_space();
19598 self.generate_expression(false_val)?;
19599 }
19600 self.write_space();
19601 self.write_keyword("END");
19602 return Ok(());
19603 }
19604
19605 if self.config.dialect == Some(DialectType::Exasol) {
19607 self.write_keyword("IF");
19608 self.write_space();
19609 self.generate_expression(&f.condition)?;
19610 self.write_space();
19611 self.write_keyword("THEN");
19612 self.write_space();
19613 self.generate_expression(&f.true_value)?;
19614 if let Some(false_val) = &f.false_value {
19615 self.write_space();
19616 self.write_keyword("ELSE");
19617 self.write_space();
19618 self.generate_expression(false_val)?;
19619 }
19620 self.write_space();
19621 self.write_keyword("ENDIF");
19622 return Ok(());
19623 }
19624
19625 let func_name = match self.config.dialect {
19627 Some(DialectType::ClickHouse) => f.original_name.as_deref().unwrap_or("IF"),
19628 Some(DialectType::Snowflake) => "IFF",
19629 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
19630 Some(DialectType::Drill) => "`IF`",
19631 _ => "IF",
19632 };
19633 self.write(func_name);
19634 self.write("(");
19635 self.generate_expression(&f.condition)?;
19636 self.write(", ");
19637 self.generate_expression(&f.true_value)?;
19638 if let Some(false_val) = &f.false_value {
19639 self.write(", ");
19640 self.generate_expression(false_val)?;
19641 }
19642 self.write(")");
19643 Ok(())
19644 }
19645
19646 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
19647 self.write_keyword("NVL2");
19648 self.write("(");
19649 self.generate_expression(&f.this)?;
19650 self.write(", ");
19651 self.generate_expression(&f.true_value)?;
19652 self.write(", ");
19653 self.generate_expression(&f.false_value)?;
19654 self.write(")");
19655 Ok(())
19656 }
19657
19658 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
19661 let count_name = match self.config.normalize_functions {
19663 NormalizeFunctions::Upper => "COUNT".to_string(),
19664 NormalizeFunctions::Lower => "count".to_string(),
19665 NormalizeFunctions::None => f
19666 .original_name
19667 .clone()
19668 .unwrap_or_else(|| "COUNT".to_string()),
19669 };
19670 self.write(&count_name);
19671 self.write("(");
19672 if f.distinct {
19673 self.write_keyword("DISTINCT");
19674 self.write_space();
19675 }
19676 if f.star {
19677 self.write("*");
19678 } else if let Some(ref expr) = f.this {
19679 if let Expression::Tuple(tuple) = expr {
19681 let needs_transform =
19685 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
19686
19687 if needs_transform {
19688 self.write_keyword("CASE");
19690 for e in &tuple.expressions {
19691 self.write_space();
19692 self.write_keyword("WHEN");
19693 self.write_space();
19694 self.generate_expression(e)?;
19695 self.write_space();
19696 self.write_keyword("IS NULL THEN NULL");
19697 }
19698 self.write_space();
19699 self.write_keyword("ELSE");
19700 self.write(" (");
19701 for (i, e) in tuple.expressions.iter().enumerate() {
19702 if i > 0 {
19703 self.write(", ");
19704 }
19705 self.generate_expression(e)?;
19706 }
19707 self.write(")");
19708 self.write_space();
19709 self.write_keyword("END");
19710 } else {
19711 for (i, e) in tuple.expressions.iter().enumerate() {
19712 if i > 0 {
19713 self.write(", ");
19714 }
19715 self.generate_expression(e)?;
19716 }
19717 }
19718 } else {
19719 self.generate_expression(expr)?;
19720 }
19721 }
19722 let clickhouse_ignore_nulls_outside =
19723 matches!(self.config.dialect, Some(DialectType::ClickHouse));
19724 if let Some(ignore) = f.ignore_nulls.filter(|_| !clickhouse_ignore_nulls_outside) {
19725 self.write_space();
19726 if ignore {
19727 self.write_keyword("IGNORE NULLS");
19728 } else {
19729 self.write_keyword("RESPECT NULLS");
19730 }
19731 }
19732 self.write(")");
19733 if let Some(ignore) = f.ignore_nulls.filter(|_| clickhouse_ignore_nulls_outside) {
19734 self.write_space();
19735 if ignore {
19736 self.write_keyword("IGNORE NULLS");
19737 } else {
19738 self.write_keyword("RESPECT NULLS");
19739 }
19740 }
19741 if let Some(ref filter) = f.filter {
19742 self.write_space();
19743 self.write_keyword("FILTER");
19744 self.write("(");
19745 self.write_keyword("WHERE");
19746 self.write_space();
19747 self.generate_expression(filter)?;
19748 self.write(")");
19749 }
19750 Ok(())
19751 }
19752
19753 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
19754 let func_name: Cow<'_, str> = match self.config.normalize_functions {
19756 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
19757 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
19758 NormalizeFunctions::None => {
19759 if let Some(ref original) = f.name {
19762 Cow::Owned(original.clone())
19763 } else {
19764 Cow::Owned(name.to_ascii_lowercase())
19765 }
19766 }
19767 };
19768 self.write(func_name.as_ref());
19769 self.write("(");
19770 if f.distinct {
19771 self.write_keyword("DISTINCT");
19772 self.write_space();
19773 }
19774 let is_zero_arg_mode =
19777 name.eq_ignore_ascii_case("MODE") && matches!(f.this, Expression::Null(_));
19778 if !is_zero_arg_mode {
19779 self.generate_expression(&f.this)?;
19780 }
19781 if self.config.ignore_nulls_in_func
19784 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19785 {
19786 match f.ignore_nulls {
19787 Some(true) => {
19788 self.write_space();
19789 self.write_keyword("IGNORE NULLS");
19790 }
19791 Some(false) => {
19792 self.write_space();
19793 self.write_keyword("RESPECT NULLS");
19794 }
19795 None => {}
19796 }
19797 }
19798 if let Some((ref expr, is_max)) = f.having_max {
19801 self.write_space();
19802 self.write_keyword("HAVING");
19803 self.write_space();
19804 if is_max {
19805 self.write_keyword("MAX");
19806 } else {
19807 self.write_keyword("MIN");
19808 }
19809 self.write_space();
19810 self.generate_expression(expr)?;
19811 }
19812 if !f.order_by.is_empty() {
19814 self.write_space();
19815 self.write_keyword("ORDER BY");
19816 self.write_space();
19817 for (i, ord) in f.order_by.iter().enumerate() {
19818 if i > 0 {
19819 self.write(", ");
19820 }
19821 self.generate_ordered(ord)?;
19822 }
19823 }
19824 if let Some(ref limit) = f.limit {
19826 self.write_space();
19827 self.write_keyword("LIMIT");
19828 self.write_space();
19829 if let Expression::Tuple(t) = limit.as_ref() {
19831 if t.expressions.len() == 2 {
19832 self.generate_expression(&t.expressions[0])?;
19833 self.write(", ");
19834 self.generate_expression(&t.expressions[1])?;
19835 } else {
19836 self.generate_expression(limit)?;
19837 }
19838 } else {
19839 self.generate_expression(limit)?;
19840 }
19841 }
19842 self.write(")");
19843 if !self.config.ignore_nulls_in_func
19846 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19847 {
19848 match f.ignore_nulls {
19849 Some(true) => {
19850 self.write_space();
19851 self.write_keyword("IGNORE NULLS");
19852 }
19853 Some(false) => {
19854 self.write_space();
19855 self.write_keyword("RESPECT NULLS");
19856 }
19857 None => {}
19858 }
19859 }
19860 if let Some(ref filter) = f.filter {
19861 self.write_space();
19862 self.write_keyword("FILTER");
19863 self.write("(");
19864 self.write_keyword("WHERE");
19865 self.write_space();
19866 self.generate_expression(filter)?;
19867 self.write(")");
19868 }
19869 Ok(())
19870 }
19871
19872 fn generate_agg_func_with_ignore_nulls_bool(&mut self, name: &str, f: &AggFunc) -> Result<()> {
19875 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
19877 let func_name: Cow<'_, str> = match self.config.normalize_functions {
19879 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
19880 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
19881 NormalizeFunctions::None => {
19882 if let Some(ref original) = f.name {
19883 Cow::Owned(original.clone())
19884 } else {
19885 Cow::Owned(name.to_ascii_lowercase())
19886 }
19887 }
19888 };
19889 self.write(func_name.as_ref());
19890 self.write("(");
19891 if f.distinct {
19892 self.write_keyword("DISTINCT");
19893 self.write_space();
19894 }
19895 if !matches!(f.this, Expression::Null(_)) {
19896 self.generate_expression(&f.this)?;
19897 }
19898 self.write(", ");
19899 self.write_keyword("TRUE");
19900 self.write(")");
19901 return Ok(());
19902 }
19903 self.generate_agg_func(name, f)
19904 }
19905
19906 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
19907 self.write_keyword("GROUP_CONCAT");
19908 self.write("(");
19909 if f.distinct {
19910 self.write_keyword("DISTINCT");
19911 self.write_space();
19912 }
19913 self.generate_expression(&f.this)?;
19914 if let Some(ref order_by) = f.order_by {
19915 self.write_space();
19916 self.write_keyword("ORDER BY");
19917 self.write_space();
19918 for (i, ord) in order_by.iter().enumerate() {
19919 if i > 0 {
19920 self.write(", ");
19921 }
19922 self.generate_ordered(ord)?;
19923 }
19924 }
19925 if let Some(ref sep) = f.separator {
19926 if matches!(
19929 self.config.dialect,
19930 Some(crate::dialects::DialectType::SQLite)
19931 ) {
19932 self.write(", ");
19933 self.generate_expression(sep)?;
19934 } else {
19935 self.write_space();
19936 self.write_keyword("SEPARATOR");
19937 self.write_space();
19938 self.generate_expression(sep)?;
19939 }
19940 }
19941 if let Some(ref limit) = f.limit {
19942 self.write_space();
19943 self.write_keyword("LIMIT");
19944 self.write_space();
19945 self.generate_expression(limit)?;
19946 }
19947 self.write(")");
19948 if let Some(ref filter) = f.filter {
19949 self.write_space();
19950 self.write_keyword("FILTER");
19951 self.write("(");
19952 self.write_keyword("WHERE");
19953 self.write_space();
19954 self.generate_expression(filter)?;
19955 self.write(")");
19956 }
19957 Ok(())
19958 }
19959
19960 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
19961 let is_tsql = matches!(
19962 self.config.dialect,
19963 Some(crate::dialects::DialectType::TSQL)
19964 );
19965 self.write_keyword("STRING_AGG");
19966 self.write("(");
19967 if f.distinct {
19968 self.write_keyword("DISTINCT");
19969 self.write_space();
19970 }
19971 self.generate_expression(&f.this)?;
19972 if let Some(ref separator) = f.separator {
19973 self.write(", ");
19974 self.generate_expression(separator)?;
19975 }
19976 if !is_tsql {
19978 if let Some(ref order_by) = f.order_by {
19979 self.write_space();
19980 self.write_keyword("ORDER BY");
19981 self.write_space();
19982 for (i, ord) in order_by.iter().enumerate() {
19983 if i > 0 {
19984 self.write(", ");
19985 }
19986 self.generate_ordered(ord)?;
19987 }
19988 }
19989 }
19990 if let Some(ref limit) = f.limit {
19991 self.write_space();
19992 self.write_keyword("LIMIT");
19993 self.write_space();
19994 self.generate_expression(limit)?;
19995 }
19996 self.write(")");
19997 if is_tsql {
19999 if let Some(ref order_by) = f.order_by {
20000 self.write_space();
20001 self.write_keyword("WITHIN GROUP");
20002 self.write(" (");
20003 self.write_keyword("ORDER BY");
20004 self.write_space();
20005 for (i, ord) in order_by.iter().enumerate() {
20006 if i > 0 {
20007 self.write(", ");
20008 }
20009 self.generate_ordered(ord)?;
20010 }
20011 self.write(")");
20012 }
20013 }
20014 if let Some(ref filter) = f.filter {
20015 self.write_space();
20016 self.write_keyword("FILTER");
20017 self.write("(");
20018 self.write_keyword("WHERE");
20019 self.write_space();
20020 self.generate_expression(filter)?;
20021 self.write(")");
20022 }
20023 Ok(())
20024 }
20025
20026 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
20027 use crate::dialects::DialectType;
20028 self.write_keyword("LISTAGG");
20029 self.write("(");
20030 if f.distinct {
20031 self.write_keyword("DISTINCT");
20032 self.write_space();
20033 }
20034 self.generate_expression(&f.this)?;
20035 if let Some(ref sep) = f.separator {
20036 self.write(", ");
20037 self.generate_expression(sep)?;
20038 } else if matches!(
20039 self.config.dialect,
20040 Some(DialectType::Trino) | Some(DialectType::Presto)
20041 ) {
20042 self.write(", ','");
20044 }
20045 if let Some(ref overflow) = f.on_overflow {
20046 self.write_space();
20047 self.write_keyword("ON OVERFLOW");
20048 self.write_space();
20049 match overflow {
20050 ListAggOverflow::Error => self.write_keyword("ERROR"),
20051 ListAggOverflow::Truncate { filler, with_count } => {
20052 self.write_keyword("TRUNCATE");
20053 if let Some(ref fill) = filler {
20054 self.write_space();
20055 self.generate_expression(fill)?;
20056 }
20057 if *with_count {
20058 self.write_space();
20059 self.write_keyword("WITH COUNT");
20060 } else {
20061 self.write_space();
20062 self.write_keyword("WITHOUT COUNT");
20063 }
20064 }
20065 }
20066 }
20067 self.write(")");
20068 if let Some(ref order_by) = f.order_by {
20069 self.write_space();
20070 self.write_keyword("WITHIN GROUP");
20071 self.write(" (");
20072 self.write_keyword("ORDER BY");
20073 self.write_space();
20074 for (i, ord) in order_by.iter().enumerate() {
20075 if i > 0 {
20076 self.write(", ");
20077 }
20078 self.generate_ordered(ord)?;
20079 }
20080 self.write(")");
20081 }
20082 if let Some(ref filter) = f.filter {
20083 self.write_space();
20084 self.write_keyword("FILTER");
20085 self.write("(");
20086 self.write_keyword("WHERE");
20087 self.write_space();
20088 self.generate_expression(filter)?;
20089 self.write(")");
20090 }
20091 Ok(())
20092 }
20093
20094 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
20095 self.write_keyword("SUM_IF");
20096 self.write("(");
20097 self.generate_expression(&f.this)?;
20098 self.write(", ");
20099 self.generate_expression(&f.condition)?;
20100 self.write(")");
20101 if let Some(ref filter) = f.filter {
20102 self.write_space();
20103 self.write_keyword("FILTER");
20104 self.write("(");
20105 self.write_keyword("WHERE");
20106 self.write_space();
20107 self.generate_expression(filter)?;
20108 self.write(")");
20109 }
20110 Ok(())
20111 }
20112
20113 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
20114 self.write_keyword("APPROX_PERCENTILE");
20115 self.write("(");
20116 self.generate_expression(&f.this)?;
20117 self.write(", ");
20118 self.generate_expression(&f.percentile)?;
20119 if let Some(ref acc) = f.accuracy {
20120 self.write(", ");
20121 self.generate_expression(acc)?;
20122 }
20123 self.write(")");
20124 if let Some(ref filter) = f.filter {
20125 self.write_space();
20126 self.write_keyword("FILTER");
20127 self.write("(");
20128 self.write_keyword("WHERE");
20129 self.write_space();
20130 self.generate_expression(filter)?;
20131 self.write(")");
20132 }
20133 Ok(())
20134 }
20135
20136 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
20137 self.write_keyword(name);
20138 self.write("(");
20139 self.generate_expression(&f.percentile)?;
20140 self.write(")");
20141 if let Some(ref order_by) = f.order_by {
20142 self.write_space();
20143 self.write_keyword("WITHIN GROUP");
20144 self.write(" (");
20145 self.write_keyword("ORDER BY");
20146 self.write_space();
20147 self.generate_expression(&f.this)?;
20148 for ord in order_by.iter() {
20149 if ord.desc {
20150 self.write_space();
20151 self.write_keyword("DESC");
20152 }
20153 }
20154 self.write(")");
20155 }
20156 if let Some(ref filter) = f.filter {
20157 self.write_space();
20158 self.write_keyword("FILTER");
20159 self.write("(");
20160 self.write_keyword("WHERE");
20161 self.write_space();
20162 self.generate_expression(filter)?;
20163 self.write(")");
20164 }
20165 Ok(())
20166 }
20167
20168 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
20171 self.write_keyword("NTILE");
20172 self.write("(");
20173 if let Some(num_buckets) = &f.num_buckets {
20174 self.generate_expression(num_buckets)?;
20175 }
20176 if let Some(order_by) = &f.order_by {
20177 self.write_keyword(" ORDER BY ");
20178 for (i, ob) in order_by.iter().enumerate() {
20179 if i > 0 {
20180 self.write(", ");
20181 }
20182 self.generate_ordered(ob)?;
20183 }
20184 }
20185 self.write(")");
20186 Ok(())
20187 }
20188
20189 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
20190 self.write_keyword(name);
20191 self.write("(");
20192 self.generate_expression(&f.this)?;
20193 if let Some(ref offset) = f.offset {
20194 self.write(", ");
20195 self.generate_expression(offset)?;
20196 if let Some(ref default) = f.default {
20197 self.write(", ");
20198 self.generate_expression(default)?;
20199 }
20200 }
20201 if self.config.ignore_nulls_in_func {
20203 match f.ignore_nulls {
20204 Some(true) => {
20205 self.write_space();
20206 self.write_keyword("IGNORE NULLS");
20207 }
20208 Some(false) => {
20209 self.write_space();
20210 self.write_keyword("RESPECT NULLS");
20211 }
20212 None => {}
20213 }
20214 }
20215 self.write(")");
20216 if !self.config.ignore_nulls_in_func {
20218 match f.ignore_nulls {
20219 Some(true) => {
20220 self.write_space();
20221 self.write_keyword("IGNORE NULLS");
20222 }
20223 Some(false) => {
20224 self.write_space();
20225 self.write_keyword("RESPECT NULLS");
20226 }
20227 None => {}
20228 }
20229 }
20230 Ok(())
20231 }
20232
20233 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
20234 self.write_keyword(name);
20235 self.write("(");
20236 self.generate_expression(&f.this)?;
20237 if !f.order_by.is_empty() {
20239 self.write_space();
20240 self.write_keyword("ORDER BY");
20241 self.write_space();
20242 for (i, ordered) in f.order_by.iter().enumerate() {
20243 if i > 0 {
20244 self.write(", ");
20245 }
20246 self.generate_ordered(ordered)?;
20247 }
20248 }
20249 if self.config.ignore_nulls_in_func {
20251 match f.ignore_nulls {
20252 Some(true) => {
20253 self.write_space();
20254 self.write_keyword("IGNORE NULLS");
20255 }
20256 Some(false) => {
20257 self.write_space();
20258 self.write_keyword("RESPECT NULLS");
20259 }
20260 None => {}
20261 }
20262 }
20263 self.write(")");
20264 if !self.config.ignore_nulls_in_func {
20266 match f.ignore_nulls {
20267 Some(true) => {
20268 self.write_space();
20269 self.write_keyword("IGNORE NULLS");
20270 }
20271 Some(false) => {
20272 self.write_space();
20273 self.write_keyword("RESPECT NULLS");
20274 }
20275 None => {}
20276 }
20277 }
20278 Ok(())
20279 }
20280
20281 fn generate_value_func_with_ignore_nulls_bool(
20284 &mut self,
20285 name: &str,
20286 f: &ValueFunc,
20287 ) -> Result<()> {
20288 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
20289 self.write_keyword(name);
20290 self.write("(");
20291 self.generate_expression(&f.this)?;
20292 self.write(", ");
20293 self.write_keyword("TRUE");
20294 self.write(")");
20295 return Ok(());
20296 }
20297 self.generate_value_func(name, f)
20298 }
20299
20300 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
20301 self.write_keyword("NTH_VALUE");
20302 self.write("(");
20303 self.generate_expression(&f.this)?;
20304 self.write(", ");
20305 self.generate_expression(&f.offset)?;
20306 if self.config.ignore_nulls_in_func {
20308 match f.ignore_nulls {
20309 Some(true) => {
20310 self.write_space();
20311 self.write_keyword("IGNORE NULLS");
20312 }
20313 Some(false) => {
20314 self.write_space();
20315 self.write_keyword("RESPECT NULLS");
20316 }
20317 None => {}
20318 }
20319 }
20320 self.write(")");
20321 if matches!(
20323 self.config.dialect,
20324 Some(crate::dialects::DialectType::Snowflake)
20325 ) {
20326 match f.from_first {
20327 Some(true) => {
20328 self.write_space();
20329 self.write_keyword("FROM FIRST");
20330 }
20331 Some(false) => {
20332 self.write_space();
20333 self.write_keyword("FROM LAST");
20334 }
20335 None => {}
20336 }
20337 }
20338 if !self.config.ignore_nulls_in_func {
20340 match f.ignore_nulls {
20341 Some(true) => {
20342 self.write_space();
20343 self.write_keyword("IGNORE NULLS");
20344 }
20345 Some(false) => {
20346 self.write_space();
20347 self.write_keyword("RESPECT NULLS");
20348 }
20349 None => {}
20350 }
20351 }
20352 Ok(())
20353 }
20354
20355 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
20358 if matches!(
20361 self.config.dialect,
20362 Some(crate::dialects::DialectType::ClickHouse)
20363 ) {
20364 self.write_keyword("POSITION");
20365 self.write("(");
20366 self.generate_expression(&f.string)?;
20367 self.write(", ");
20368 self.generate_expression(&f.substring)?;
20369 if let Some(ref start) = f.start {
20370 self.write(", ");
20371 self.generate_expression(start)?;
20372 }
20373 self.write(")");
20374 return Ok(());
20375 }
20376
20377 self.write_keyword("POSITION");
20378 self.write("(");
20379 self.generate_expression(&f.substring)?;
20380 self.write_space();
20381 self.write_keyword("IN");
20382 self.write_space();
20383 self.generate_expression(&f.string)?;
20384 if let Some(ref start) = f.start {
20385 self.write(", ");
20386 self.generate_expression(start)?;
20387 }
20388 self.write(")");
20389 Ok(())
20390 }
20391
20392 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
20395 if f.lower.is_some() || f.upper.is_some() {
20397 self.write_keyword("RANDOM");
20398 self.write("(");
20399 if let Some(ref lower) = f.lower {
20400 self.generate_expression(lower)?;
20401 }
20402 if let Some(ref upper) = f.upper {
20403 self.write(", ");
20404 self.generate_expression(upper)?;
20405 }
20406 self.write(")");
20407 return Ok(());
20408 }
20409 let func_name = match self.config.dialect {
20411 Some(crate::dialects::DialectType::Snowflake)
20412 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
20413 _ => "RAND",
20414 };
20415 self.write_keyword(func_name);
20416 self.write("(");
20417 if !matches!(
20419 self.config.dialect,
20420 Some(crate::dialects::DialectType::DuckDB)
20421 ) {
20422 if let Some(ref seed) = f.seed {
20423 self.generate_expression(seed)?;
20424 }
20425 }
20426 self.write(")");
20427 Ok(())
20428 }
20429
20430 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
20431 self.write_keyword("TRUNCATE");
20432 self.write("(");
20433 self.generate_expression(&f.this)?;
20434 if let Some(ref decimals) = f.decimals {
20435 self.write(", ");
20436 self.generate_expression(decimals)?;
20437 }
20438 self.write(")");
20439 Ok(())
20440 }
20441
20442 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
20445 self.write_keyword("DECODE");
20446 self.write("(");
20447 self.generate_expression(&f.this)?;
20448 for (search, result) in &f.search_results {
20449 self.write(", ");
20450 self.generate_expression(search)?;
20451 self.write(", ");
20452 self.generate_expression(result)?;
20453 }
20454 if let Some(ref default) = f.default {
20455 self.write(", ");
20456 self.generate_expression(default)?;
20457 }
20458 self.write(")");
20459 Ok(())
20460 }
20461
20462 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
20465 self.write_keyword(name);
20466 self.write("(");
20467 self.generate_expression(&f.this)?;
20468 self.write(", ");
20469 self.generate_expression(&f.format)?;
20470 self.write(")");
20471 Ok(())
20472 }
20473
20474 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
20475 self.write_keyword("FROM_UNIXTIME");
20476 self.write("(");
20477 self.generate_expression(&f.this)?;
20478 if let Some(ref format) = f.format {
20479 self.write(", ");
20480 self.generate_expression(format)?;
20481 }
20482 self.write(")");
20483 Ok(())
20484 }
20485
20486 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
20487 self.write_keyword("UNIX_TIMESTAMP");
20488 self.write("(");
20489 if let Some(ref expr) = f.this {
20490 self.generate_expression(expr)?;
20491 if let Some(ref format) = f.format {
20492 self.write(", ");
20493 self.generate_expression(format)?;
20494 }
20495 } else if matches!(
20496 self.config.dialect,
20497 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
20498 ) {
20499 self.write_keyword("CURRENT_TIMESTAMP");
20501 self.write("()");
20502 }
20503 self.write(")");
20504 Ok(())
20505 }
20506
20507 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
20508 self.write_keyword("MAKE_DATE");
20509 self.write("(");
20510 self.generate_expression(&f.year)?;
20511 self.write(", ");
20512 self.generate_expression(&f.month)?;
20513 self.write(", ");
20514 self.generate_expression(&f.day)?;
20515 self.write(")");
20516 Ok(())
20517 }
20518
20519 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
20520 self.write_keyword("MAKE_TIMESTAMP");
20521 self.write("(");
20522 self.generate_expression(&f.year)?;
20523 self.write(", ");
20524 self.generate_expression(&f.month)?;
20525 self.write(", ");
20526 self.generate_expression(&f.day)?;
20527 self.write(", ");
20528 self.generate_expression(&f.hour)?;
20529 self.write(", ");
20530 self.generate_expression(&f.minute)?;
20531 self.write(", ");
20532 self.generate_expression(&f.second)?;
20533 if let Some(ref tz) = f.timezone {
20534 self.write(", ");
20535 self.generate_expression(tz)?;
20536 }
20537 self.write(")");
20538 Ok(())
20539 }
20540
20541 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
20543 match expr {
20544 Expression::Struct(s) => {
20545 if s.fields.iter().all(|(name, _)| name.is_some()) {
20546 Some(
20547 s.fields
20548 .iter()
20549 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
20550 .collect(),
20551 )
20552 } else {
20553 None
20554 }
20555 }
20556 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20557 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
20559 Some(
20560 f.args
20561 .iter()
20562 .filter_map(|a| {
20563 if let Expression::Alias(alias) = a {
20564 Some(alias.alias.name.clone())
20565 } else {
20566 None
20567 }
20568 })
20569 .collect(),
20570 )
20571 } else {
20572 None
20573 }
20574 }
20575 _ => None,
20576 }
20577 }
20578
20579 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
20581 match expr {
20582 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
20583 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20584 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
20585 }
20586 _ => false,
20587 }
20588 }
20589
20590 fn struct_field_count(expr: &Expression) -> usize {
20592 match expr {
20593 Expression::Struct(s) => s.fields.len(),
20594 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => f.args.len(),
20595 _ => 0,
20596 }
20597 }
20598
20599 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
20601 match expr {
20602 Expression::Struct(s) => {
20603 let mut new_fields = Vec::with_capacity(s.fields.len());
20604 for (i, (name, value)) in s.fields.iter().enumerate() {
20605 if name.is_none() && i < field_names.len() {
20606 new_fields.push((Some(field_names[i].clone()), value.clone()));
20607 } else {
20608 new_fields.push((name.clone(), value.clone()));
20609 }
20610 }
20611 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
20612 }
20613 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20614 let mut new_args = Vec::with_capacity(f.args.len());
20615 for (i, arg) in f.args.iter().enumerate() {
20616 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
20617 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
20619 this: arg.clone(),
20620 alias: crate::expressions::Identifier::new(field_names[i].clone()),
20621 column_aliases: Vec::new(),
20622 alias_explicit_as: false,
20623 alias_keyword: None,
20624 pre_alias_comments: Vec::new(),
20625 trailing_comments: Vec::new(),
20626 inferred_type: None,
20627 })));
20628 } else {
20629 new_args.push(arg.clone());
20630 }
20631 }
20632 Expression::Function(Box::new(crate::expressions::Function {
20633 name: f.name.clone(),
20634 args: new_args,
20635 distinct: f.distinct,
20636 trailing_comments: f.trailing_comments.clone(),
20637 use_bracket_syntax: f.use_bracket_syntax,
20638 no_parens: f.no_parens,
20639 quoted: f.quoted,
20640 span: None,
20641 inferred_type: None,
20642 }))
20643 }
20644 _ => expr.clone(),
20645 }
20646 }
20647
20648 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
20652 let first = match expressions.first() {
20653 Some(e) => e,
20654 None => return expressions.to_vec(),
20655 };
20656
20657 let field_names = match Self::extract_struct_field_names(first) {
20658 Some(names) if !names.is_empty() => names,
20659 _ => return expressions.to_vec(),
20660 };
20661
20662 let mut result = Vec::with_capacity(expressions.len());
20663 for (idx, expr) in expressions.iter().enumerate() {
20664 if idx == 0 {
20665 result.push(expr.clone());
20666 continue;
20667 }
20668 if Self::struct_field_count(expr) == field_names.len()
20670 && Self::struct_has_unnamed_fields(expr)
20671 {
20672 result.push(Self::apply_struct_field_names(expr, &field_names));
20673 } else {
20674 result.push(expr.clone());
20675 }
20676 }
20677 result
20678 }
20679
20680 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
20683 let needs_inheritance = matches!(
20686 self.config.dialect,
20687 Some(DialectType::DuckDB)
20688 | Some(DialectType::Spark)
20689 | Some(DialectType::Databricks)
20690 | Some(DialectType::Hive)
20691 | Some(DialectType::Snowflake)
20692 | Some(DialectType::Presto)
20693 | Some(DialectType::Trino)
20694 );
20695 let propagated: Vec<Expression>;
20696 let expressions = if needs_inheritance && f.expressions.len() > 1 {
20697 propagated = Self::inherit_struct_field_names(&f.expressions);
20698 &propagated
20699 } else {
20700 &f.expressions
20701 };
20702
20703 let should_split = if self.config.pretty && !expressions.is_empty() {
20705 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
20706 for expr in expressions {
20707 let mut temp_gen = Generator::with_arc_config(self.config.clone());
20708 Arc::make_mut(&mut temp_gen.config).pretty = false;
20709 temp_gen.generate_expression(expr)?;
20710 expr_strings.push(temp_gen.output);
20711 }
20712 self.too_wide(&expr_strings)
20713 } else {
20714 false
20715 };
20716
20717 if f.bracket_notation {
20718 let (open, close) = match self.config.dialect {
20722 None
20723 | Some(DialectType::Generic)
20724 | Some(DialectType::Spark)
20725 | Some(DialectType::Databricks)
20726 | Some(DialectType::Hive) => {
20727 self.write_keyword("ARRAY");
20728 ("(", ")")
20729 }
20730 Some(DialectType::Presto)
20731 | Some(DialectType::Trino)
20732 | Some(DialectType::PostgreSQL)
20733 | Some(DialectType::Redshift)
20734 | Some(DialectType::Materialize)
20735 | Some(DialectType::RisingWave)
20736 | Some(DialectType::CockroachDB) => {
20737 self.write_keyword("ARRAY");
20738 ("[", "]")
20739 }
20740 _ => ("[", "]"),
20741 };
20742 self.write(open);
20743 if should_split {
20744 self.write_newline();
20745 self.indent_level += 1;
20746 for (i, expr) in expressions.iter().enumerate() {
20747 self.write_indent();
20748 self.generate_expression(expr)?;
20749 if i + 1 < expressions.len() {
20750 self.write(",");
20751 }
20752 self.write_newline();
20753 }
20754 self.indent_level -= 1;
20755 self.write_indent();
20756 } else {
20757 for (i, expr) in expressions.iter().enumerate() {
20758 if i > 0 {
20759 self.write(", ");
20760 }
20761 self.generate_expression(expr)?;
20762 }
20763 }
20764 self.write(close);
20765 } else {
20766 if f.use_list_keyword {
20768 self.write_keyword("LIST");
20769 } else {
20770 self.write_keyword("ARRAY");
20771 }
20772 let has_subquery = expressions
20775 .iter()
20776 .any(|e| matches!(e, Expression::Select(_)));
20777 let (open, close) = if matches!(
20778 self.config.dialect,
20779 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
20780 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
20781 && has_subquery)
20782 {
20783 ("(", ")")
20784 } else {
20785 ("[", "]")
20786 };
20787 self.write(open);
20788 if should_split {
20789 self.write_newline();
20790 self.indent_level += 1;
20791 for (i, expr) in expressions.iter().enumerate() {
20792 self.write_indent();
20793 self.generate_expression(expr)?;
20794 if i + 1 < expressions.len() {
20795 self.write(",");
20796 }
20797 self.write_newline();
20798 }
20799 self.indent_level -= 1;
20800 self.write_indent();
20801 } else {
20802 for (i, expr) in expressions.iter().enumerate() {
20803 if i > 0 {
20804 self.write(", ");
20805 }
20806 self.generate_expression(expr)?;
20807 }
20808 }
20809 self.write(close);
20810 }
20811 Ok(())
20812 }
20813
20814 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
20815 self.write_keyword("ARRAY_SORT");
20816 self.write("(");
20817 self.generate_expression(&f.this)?;
20818 if let Some(ref comp) = f.comparator {
20819 self.write(", ");
20820 self.generate_expression(comp)?;
20821 }
20822 self.write(")");
20823 Ok(())
20824 }
20825
20826 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
20827 self.write_keyword(name);
20828 self.write("(");
20829 self.generate_expression(&f.this)?;
20830 self.write(", ");
20831 self.generate_expression(&f.separator)?;
20832 if let Some(ref null_rep) = f.null_replacement {
20833 self.write(", ");
20834 self.generate_expression(null_rep)?;
20835 }
20836 self.write(")");
20837 Ok(())
20838 }
20839
20840 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
20841 self.write_keyword("UNNEST");
20842 self.write("(");
20843 self.generate_expression(&f.this)?;
20844 for extra in &f.expressions {
20845 self.write(", ");
20846 self.generate_expression(extra)?;
20847 }
20848 self.write(")");
20849 if f.with_ordinality {
20850 self.write_space();
20851 if self.config.unnest_with_ordinality {
20852 self.write_keyword("WITH ORDINALITY");
20854 } else if f.offset_alias.is_some() {
20855 if let Some(ref alias) = f.alias {
20858 self.write_keyword("AS");
20859 self.write_space();
20860 self.generate_identifier(alias)?;
20861 self.write_space();
20862 }
20863 self.write_keyword("WITH OFFSET");
20864 if let Some(ref offset_alias) = f.offset_alias {
20865 self.write_space();
20866 self.write_keyword("AS");
20867 self.write_space();
20868 self.generate_identifier(offset_alias)?;
20869 }
20870 } else {
20871 self.write_keyword("WITH OFFSET");
20873 if f.alias.is_none() {
20874 self.write(" AS offset");
20875 }
20876 }
20877 }
20878 if let Some(ref alias) = f.alias {
20879 let should_add_alias = if !f.with_ordinality {
20881 true
20882 } else if self.config.unnest_with_ordinality {
20883 true
20885 } else if f.offset_alias.is_some() {
20886 false
20888 } else {
20889 true
20891 };
20892 if should_add_alias {
20893 self.write_space();
20894 self.write_keyword("AS");
20895 self.write_space();
20896 self.generate_identifier(alias)?;
20897 }
20898 }
20899 Ok(())
20900 }
20901
20902 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
20903 self.write_keyword("FILTER");
20904 self.write("(");
20905 self.generate_expression(&f.this)?;
20906 self.write(", ");
20907 self.generate_expression(&f.filter)?;
20908 self.write(")");
20909 Ok(())
20910 }
20911
20912 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
20913 self.write_keyword("TRANSFORM");
20914 self.write("(");
20915 self.generate_expression(&f.this)?;
20916 self.write(", ");
20917 self.generate_expression(&f.transform)?;
20918 self.write(")");
20919 Ok(())
20920 }
20921
20922 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
20923 self.write_keyword(name);
20924 self.write("(");
20925 self.generate_expression(&f.start)?;
20926 self.write(", ");
20927 self.generate_expression(&f.stop)?;
20928 if let Some(ref step) = f.step {
20929 self.write(", ");
20930 self.generate_expression(step)?;
20931 }
20932 self.write(")");
20933 Ok(())
20934 }
20935
20936 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
20939 self.write_keyword("STRUCT");
20940 self.write("(");
20941 for (i, (name, expr)) in f.fields.iter().enumerate() {
20942 if i > 0 {
20943 self.write(", ");
20944 }
20945 if let Some(ref id) = name {
20946 self.generate_identifier(id)?;
20947 self.write(" ");
20948 self.write_keyword("AS");
20949 self.write(" ");
20950 }
20951 self.generate_expression(expr)?;
20952 }
20953 self.write(")");
20954 Ok(())
20955 }
20956
20957 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
20959 let mut names: Vec<Option<String>> = Vec::new();
20962 let mut values: Vec<&Expression> = Vec::new();
20963 let mut all_named = true;
20964
20965 for arg in &func.args {
20966 match arg {
20967 Expression::Alias(a) => {
20968 names.push(Some(a.alias.name.clone()));
20969 values.push(&a.this);
20970 }
20971 _ => {
20972 names.push(None);
20973 values.push(arg);
20974 all_named = false;
20975 }
20976 }
20977 }
20978
20979 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
20980 self.write("{");
20982 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20983 if i > 0 {
20984 self.write(", ");
20985 }
20986 if let Some(n) = name {
20987 self.write("'");
20988 self.write(n);
20989 self.write("'");
20990 } else {
20991 self.write("'_");
20992 self.write(&i.to_string());
20993 self.write("'");
20994 }
20995 self.write(": ");
20996 self.generate_expression(value)?;
20997 }
20998 self.write("}");
20999 return Ok(());
21000 }
21001
21002 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
21003 self.write_keyword("OBJECT_CONSTRUCT");
21005 self.write("(");
21006 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
21007 if i > 0 {
21008 self.write(", ");
21009 }
21010 if let Some(n) = name {
21011 self.write("'");
21012 self.write(n);
21013 self.write("'");
21014 } else {
21015 self.write("'_");
21016 self.write(&i.to_string());
21017 self.write("'");
21018 }
21019 self.write(", ");
21020 self.generate_expression(value)?;
21021 }
21022 self.write(")");
21023 return Ok(());
21024 }
21025
21026 if matches!(
21027 self.config.dialect,
21028 Some(DialectType::Presto) | Some(DialectType::Trino)
21029 ) {
21030 if all_named && !names.is_empty() {
21031 self.write_keyword("CAST");
21034 self.write("(");
21035 self.write_keyword("ROW");
21036 self.write("(");
21037 for (i, value) in values.iter().enumerate() {
21038 if i > 0 {
21039 self.write(", ");
21040 }
21041 self.generate_expression(value)?;
21042 }
21043 self.write(")");
21044 self.write(" ");
21045 self.write_keyword("AS");
21046 self.write(" ");
21047 self.write_keyword("ROW");
21048 self.write("(");
21049 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
21050 if i > 0 {
21051 self.write(", ");
21052 }
21053 if let Some(n) = name {
21054 self.write(n);
21055 }
21056 self.write(" ");
21057 let type_str = Self::infer_sql_type_for_presto(value);
21058 self.write_keyword(&type_str);
21059 }
21060 self.write(")");
21061 self.write(")");
21062 } else {
21063 self.write_keyword("ROW");
21065 self.write("(");
21066 for (i, value) in values.iter().enumerate() {
21067 if i > 0 {
21068 self.write(", ");
21069 }
21070 self.generate_expression(value)?;
21071 }
21072 self.write(")");
21073 }
21074 return Ok(());
21075 }
21076
21077 self.write_keyword("ROW");
21079 self.write("(");
21080 for (i, value) in values.iter().enumerate() {
21081 if i > 0 {
21082 self.write(", ");
21083 }
21084 self.generate_expression(value)?;
21085 }
21086 self.write(")");
21087 Ok(())
21088 }
21089
21090 fn infer_sql_type_for_presto(expr: &Expression) -> String {
21092 match expr {
21093 Expression::Literal(lit)
21094 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
21095 {
21096 "VARCHAR".to_string()
21097 }
21098 Expression::Literal(lit)
21099 if matches!(lit.as_ref(), crate::expressions::Literal::Number(_)) =>
21100 {
21101 let crate::expressions::Literal::Number(n) = lit.as_ref() else {
21102 unreachable!()
21103 };
21104 if n.contains('.') {
21105 "DOUBLE".to_string()
21106 } else {
21107 "INTEGER".to_string()
21108 }
21109 }
21110 Expression::Boolean(_) => "BOOLEAN".to_string(),
21111 Expression::Literal(lit)
21112 if matches!(lit.as_ref(), crate::expressions::Literal::Date(_)) =>
21113 {
21114 "DATE".to_string()
21115 }
21116 Expression::Literal(lit)
21117 if matches!(lit.as_ref(), crate::expressions::Literal::Timestamp(_)) =>
21118 {
21119 "TIMESTAMP".to_string()
21120 }
21121 Expression::Literal(lit)
21122 if matches!(lit.as_ref(), crate::expressions::Literal::Datetime(_)) =>
21123 {
21124 "TIMESTAMP".to_string()
21125 }
21126 Expression::Array(_) | Expression::ArrayFunc(_) => {
21127 "ARRAY(VARCHAR)".to_string()
21129 }
21130 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
21132 Expression::Function(f) => {
21133 if f.name.eq_ignore_ascii_case("STRUCT") {
21134 "ROW".to_string()
21135 } else if f.name.eq_ignore_ascii_case("CURRENT_DATE") {
21136 "DATE".to_string()
21137 } else if f.name.eq_ignore_ascii_case("CURRENT_TIMESTAMP")
21138 || f.name.eq_ignore_ascii_case("NOW")
21139 {
21140 "TIMESTAMP".to_string()
21141 } else {
21142 "VARCHAR".to_string()
21143 }
21144 }
21145 _ => "VARCHAR".to_string(),
21146 }
21147 }
21148
21149 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
21150 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
21152 self.write_keyword("STRUCT_EXTRACT");
21153 self.write("(");
21154 self.generate_expression(&f.this)?;
21155 self.write(", ");
21156 self.write("'");
21158 self.write(&f.field.name);
21159 self.write("'");
21160 self.write(")");
21161 return Ok(());
21162 }
21163 self.generate_expression(&f.this)?;
21164 self.write(".");
21165 self.generate_identifier(&f.field)
21166 }
21167
21168 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
21169 if matches!(
21170 self.config.dialect,
21171 Some(DialectType::Spark | DialectType::Databricks)
21172 ) {
21173 self.write_keyword("STRUCT");
21174 self.write("(");
21175 for (i, (name, value)) in f.pairs.iter().enumerate() {
21176 if i > 0 {
21177 self.write(", ");
21178 }
21179 self.generate_expression(value)?;
21180 self.write(" ");
21181 self.write_keyword("AS");
21182 self.write(" ");
21183 if let Expression::Literal(lit) = name {
21184 if let Literal::String(field_name) = lit.as_ref() {
21185 self.generate_identifier(&Identifier::new(field_name))?;
21186 } else {
21187 self.generate_expression(name)?;
21188 }
21189 } else {
21190 self.generate_expression(name)?;
21191 }
21192 }
21193 self.write(")");
21194 return Ok(());
21195 }
21196
21197 self.write_keyword("NAMED_STRUCT");
21198 self.write("(");
21199 for (i, (name, value)) in f.pairs.iter().enumerate() {
21200 if i > 0 {
21201 self.write(", ");
21202 }
21203 self.generate_expression(name)?;
21204 self.write(", ");
21205 self.generate_expression(value)?;
21206 }
21207 self.write(")");
21208 Ok(())
21209 }
21210
21211 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
21214 if f.curly_brace_syntax {
21215 if f.with_map_keyword {
21217 self.write_keyword("MAP");
21218 self.write(" ");
21219 }
21220 self.write("{");
21221 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
21222 if i > 0 {
21223 self.write(", ");
21224 }
21225 self.generate_expression(key)?;
21226 self.write(": ");
21227 self.generate_expression(val)?;
21228 }
21229 self.write("}");
21230 } else {
21231 self.write_keyword("MAP");
21233 self.write("(");
21234 self.write_keyword("ARRAY");
21235 self.write("[");
21236 for (i, key) in f.keys.iter().enumerate() {
21237 if i > 0 {
21238 self.write(", ");
21239 }
21240 self.generate_expression(key)?;
21241 }
21242 self.write("], ");
21243 self.write_keyword("ARRAY");
21244 self.write("[");
21245 for (i, val) in f.values.iter().enumerate() {
21246 if i > 0 {
21247 self.write(", ");
21248 }
21249 self.generate_expression(val)?;
21250 }
21251 self.write("])");
21252 }
21253 Ok(())
21254 }
21255
21256 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
21257 self.write_keyword(name);
21258 self.write("(");
21259 self.generate_expression(&f.this)?;
21260 self.write(", ");
21261 self.generate_expression(&f.transform)?;
21262 self.write(")");
21263 Ok(())
21264 }
21265
21266 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
21269 use crate::dialects::DialectType;
21270
21271 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
21273
21274 if use_arrow {
21275 self.generate_expression(&f.this)?;
21277 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
21278 self.write(" ->> ");
21279 } else {
21280 self.write(" -> ");
21281 }
21282 self.generate_expression(&f.path)?;
21283 return Ok(());
21284 }
21285
21286 if f.hash_arrow_syntax
21288 && matches!(
21289 self.config.dialect,
21290 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21291 )
21292 {
21293 self.generate_expression(&f.this)?;
21294 self.write(" #>> ");
21295 self.generate_expression(&f.path)?;
21296 return Ok(());
21297 }
21298
21299 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
21302 match name {
21303 "JSON_EXTRACT_SCALAR"
21304 | "JSON_EXTRACT_PATH_TEXT"
21305 | "JSON_EXTRACT"
21306 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
21307 _ => name,
21308 }
21309 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
21310 match name {
21311 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
21312 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
21313 _ => name,
21314 }
21315 } else {
21316 name
21317 };
21318
21319 self.write_keyword(func_name);
21320 self.write("(");
21321 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
21323 if let Expression::Cast(ref cast) = f.this {
21324 if matches!(cast.to, crate::expressions::DataType::Json) {
21325 self.generate_expression(&cast.this)?;
21326 } else {
21327 self.generate_expression(&f.this)?;
21328 }
21329 } else {
21330 self.generate_expression(&f.this)?;
21331 }
21332 } else {
21333 self.generate_expression(&f.this)?;
21334 }
21335 if matches!(
21338 self.config.dialect,
21339 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21340 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
21341 {
21342 if let Expression::Literal(ref lit) = f.path {
21343 if let Literal::String(ref s) = lit.as_ref() {
21344 let parts = Self::decompose_json_path(s);
21345 for part in &parts {
21346 self.write(", '");
21347 self.write(part);
21348 self.write("'");
21349 }
21350 }
21351 } else {
21352 self.write(", ");
21353 self.generate_expression(&f.path)?;
21354 }
21355 } else {
21356 self.write(", ");
21357 self.generate_expression(&f.path)?;
21358 }
21359
21360 if let Some(ref wrapper) = f.wrapper_option {
21363 self.write_space();
21364 self.write_keyword(wrapper);
21365 }
21366 if let Some(ref quotes) = f.quotes_option {
21367 self.write_space();
21368 self.write_keyword(quotes);
21369 if f.on_scalar_string {
21370 self.write_space();
21371 self.write_keyword("ON SCALAR STRING");
21372 }
21373 }
21374 if let Some(ref on_err) = f.on_error {
21375 self.write_space();
21376 self.write_keyword(on_err);
21377 }
21378 if let Some(ref ret_type) = f.returning {
21379 self.write_space();
21380 self.write_keyword("RETURNING");
21381 self.write_space();
21382 self.generate_data_type(ret_type)?;
21383 }
21384
21385 self.write(")");
21386 Ok(())
21387 }
21388
21389 fn dialect_supports_json_arrow(&self) -> bool {
21391 use crate::dialects::DialectType;
21392 match self.config.dialect {
21393 Some(DialectType::PostgreSQL) => true,
21395 Some(DialectType::MySQL) => true,
21396 Some(DialectType::DuckDB) => true,
21397 Some(DialectType::CockroachDB) => true,
21398 Some(DialectType::StarRocks) => true,
21399 Some(DialectType::SQLite) => true,
21400 _ => false,
21402 }
21403 }
21404
21405 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
21406 use crate::dialects::DialectType;
21407
21408 if matches!(
21410 self.config.dialect,
21411 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21412 ) && name == "JSON_EXTRACT_PATH"
21413 {
21414 self.generate_expression(&f.this)?;
21415 self.write(" #> ");
21416 if f.paths.len() == 1 {
21417 self.generate_expression(&f.paths[0])?;
21418 } else {
21419 self.write_keyword("ARRAY");
21421 self.write("[");
21422 for (i, path) in f.paths.iter().enumerate() {
21423 if i > 0 {
21424 self.write(", ");
21425 }
21426 self.generate_expression(path)?;
21427 }
21428 self.write("]");
21429 }
21430 return Ok(());
21431 }
21432
21433 self.write_keyword(name);
21434 self.write("(");
21435 self.generate_expression(&f.this)?;
21436 for path in &f.paths {
21437 self.write(", ");
21438 self.generate_expression(path)?;
21439 }
21440 self.write(")");
21441 Ok(())
21442 }
21443
21444 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
21445 use crate::dialects::DialectType;
21446
21447 self.write_keyword("JSON_OBJECT");
21448 self.write("(");
21449 if f.star {
21450 self.write("*");
21451 } else {
21452 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
21456 || matches!(
21457 self.config.dialect,
21458 Some(DialectType::BigQuery)
21459 | Some(DialectType::MySQL)
21460 | Some(DialectType::SQLite)
21461 );
21462
21463 for (i, (key, value)) in f.pairs.iter().enumerate() {
21464 if i > 0 {
21465 self.write(", ");
21466 }
21467 self.generate_expression(key)?;
21468 if use_comma_syntax {
21469 self.write(", ");
21470 } else {
21471 self.write(": ");
21472 }
21473 self.generate_expression(value)?;
21474 }
21475 }
21476 if let Some(null_handling) = f.null_handling {
21477 self.write_space();
21478 match null_handling {
21479 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21480 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21481 }
21482 }
21483 if f.with_unique_keys {
21484 self.write_space();
21485 self.write_keyword("WITH UNIQUE KEYS");
21486 }
21487 if let Some(ref ret_type) = f.returning_type {
21488 self.write_space();
21489 self.write_keyword("RETURNING");
21490 self.write_space();
21491 self.generate_data_type(ret_type)?;
21492 if f.format_json {
21493 self.write_space();
21494 self.write_keyword("FORMAT JSON");
21495 }
21496 if let Some(ref enc) = f.encoding {
21497 self.write_space();
21498 self.write_keyword("ENCODING");
21499 self.write_space();
21500 self.write(enc);
21501 }
21502 }
21503 self.write(")");
21504 Ok(())
21505 }
21506
21507 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
21508 self.write_keyword(name);
21509 self.write("(");
21510 self.generate_expression(&f.this)?;
21511 for (path, value) in &f.path_values {
21512 self.write(", ");
21513 self.generate_expression(path)?;
21514 self.write(", ");
21515 self.generate_expression(value)?;
21516 }
21517 self.write(")");
21518 Ok(())
21519 }
21520
21521 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
21522 self.write_keyword("JSON_ARRAYAGG");
21523 self.write("(");
21524 self.generate_expression(&f.this)?;
21525 if let Some(ref order_by) = f.order_by {
21526 self.write_space();
21527 self.write_keyword("ORDER BY");
21528 self.write_space();
21529 for (i, ord) in order_by.iter().enumerate() {
21530 if i > 0 {
21531 self.write(", ");
21532 }
21533 self.generate_ordered(ord)?;
21534 }
21535 }
21536 if let Some(null_handling) = f.null_handling {
21537 self.write_space();
21538 match null_handling {
21539 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21540 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21541 }
21542 }
21543 self.write(")");
21544 if let Some(ref filter) = f.filter {
21545 self.write_space();
21546 self.write_keyword("FILTER");
21547 self.write("(");
21548 self.write_keyword("WHERE");
21549 self.write_space();
21550 self.generate_expression(filter)?;
21551 self.write(")");
21552 }
21553 Ok(())
21554 }
21555
21556 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
21557 self.write_keyword("JSON_OBJECTAGG");
21558 self.write("(");
21559 self.generate_expression(&f.key)?;
21560 self.write(": ");
21561 self.generate_expression(&f.value)?;
21562 if let Some(null_handling) = f.null_handling {
21563 self.write_space();
21564 match null_handling {
21565 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21566 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21567 }
21568 }
21569 self.write(")");
21570 if let Some(ref filter) = f.filter {
21571 self.write_space();
21572 self.write_keyword("FILTER");
21573 self.write("(");
21574 self.write_keyword("WHERE");
21575 self.write_space();
21576 self.generate_expression(filter)?;
21577 self.write(")");
21578 }
21579 Ok(())
21580 }
21581
21582 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
21585 use crate::dialects::DialectType;
21586
21587 if self.config.dialect == Some(DialectType::Redshift) {
21589 self.write_keyword("CAST");
21590 self.write("(");
21591 self.generate_expression(&f.this)?;
21592 self.write_space();
21593 self.write_keyword("AS");
21594 self.write_space();
21595 self.generate_data_type(&f.to)?;
21596 self.write(")");
21597 return Ok(());
21598 }
21599
21600 self.write_keyword("CONVERT");
21601 self.write("(");
21602 self.generate_data_type(&f.to)?;
21603 self.write(", ");
21604 self.generate_expression(&f.this)?;
21605 if let Some(ref style) = f.style {
21606 self.write(", ");
21607 self.generate_expression(style)?;
21608 }
21609 self.write(")");
21610 Ok(())
21611 }
21612
21613 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
21616 if f.colon {
21617 self.write_keyword("LAMBDA");
21619 self.write_space();
21620 for (i, param) in f.parameters.iter().enumerate() {
21621 if i > 0 {
21622 self.write(", ");
21623 }
21624 self.generate_identifier(param)?;
21625 }
21626 self.write(" : ");
21627 } else {
21628 if f.parameters.len() == 1 {
21630 self.generate_identifier(&f.parameters[0])?;
21631 } else {
21632 self.write("(");
21633 for (i, param) in f.parameters.iter().enumerate() {
21634 if i > 0 {
21635 self.write(", ");
21636 }
21637 self.generate_identifier(param)?;
21638 }
21639 self.write(")");
21640 }
21641 self.write(" -> ");
21642 }
21643 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21644 if let Expression::Lambda(inner) = &f.body {
21645 self.generate_lambda_with_parenthesized_single_param(inner)?;
21646 return Ok(());
21647 }
21648 }
21649
21650 self.generate_expression(&f.body)
21651 }
21652
21653 fn generate_lambda_with_parenthesized_single_param(&mut self, f: &LambdaExpr) -> Result<()> {
21654 if f.colon {
21655 return self.generate_lambda(f);
21656 }
21657
21658 self.write("(");
21659 for (i, param) in f.parameters.iter().enumerate() {
21660 if i > 0 {
21661 self.write(", ");
21662 }
21663 self.generate_identifier(param)?;
21664 }
21665 self.write(") -> ");
21666 self.generate_expression(&f.body)
21667 }
21668
21669 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
21670 self.generate_identifier(&f.name)?;
21671 match f.separator {
21672 NamedArgSeparator::DArrow => self.write(" => "),
21673 NamedArgSeparator::ColonEq => self.write(" := "),
21674 NamedArgSeparator::Eq => self.write(" = "),
21675 }
21676 self.generate_expression(&f.value)
21677 }
21678
21679 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
21680 self.write_keyword(&f.prefix);
21681 self.write(" ");
21682 self.generate_expression(&f.this)
21683 }
21684
21685 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
21686 match f.style {
21687 ParameterStyle::Question => self.write("?"),
21688 ParameterStyle::Dollar => {
21689 self.write("$");
21690 if let Some(idx) = f.index {
21691 self.write(&idx.to_string());
21692 } else if let Some(ref name) = f.name {
21693 self.write(name);
21695 }
21696 }
21697 ParameterStyle::DollarBrace => {
21698 self.write("${");
21700 if let Some(ref name) = f.name {
21701 self.write(name);
21702 }
21703 if let Some(ref expr) = f.expression {
21704 self.write(":");
21705 self.write(expr);
21706 }
21707 self.write("}");
21708 }
21709 ParameterStyle::Colon => {
21710 self.write(":");
21711 if let Some(idx) = f.index {
21712 self.write(&idx.to_string());
21713 } else if let Some(ref name) = f.name {
21714 self.write(name);
21715 }
21716 }
21717 ParameterStyle::At => {
21718 self.write("@");
21719 if let Some(ref name) = f.name {
21720 if f.string_quoted {
21721 self.write("'");
21722 self.write(name);
21723 self.write("'");
21724 } else if f.quoted {
21725 self.write("\"");
21726 self.write(name);
21727 self.write("\"");
21728 } else {
21729 self.write(name);
21730 }
21731 }
21732 }
21733 ParameterStyle::DoubleAt => {
21734 self.write("@@");
21735 if let Some(ref name) = f.name {
21736 self.write(name);
21737 }
21738 }
21739 ParameterStyle::DoubleDollar => {
21740 self.write("$$");
21741 if let Some(ref name) = f.name {
21742 self.write(name);
21743 }
21744 }
21745 ParameterStyle::Percent => {
21746 if let Some(ref name) = f.name {
21747 self.write("%(");
21749 self.write(name);
21750 self.write(")s");
21751 } else {
21752 self.write("%s");
21754 }
21755 }
21756 ParameterStyle::Brace => {
21757 self.write("{");
21760 if let Some(ref name) = f.name {
21761 self.write(name);
21762 }
21763 if let Some(ref expr) = f.expression {
21764 self.write(": ");
21765 self.write(expr);
21766 }
21767 self.write("}");
21768 }
21769 }
21770 Ok(())
21771 }
21772
21773 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
21774 self.write("?");
21775 if let Some(idx) = f.index {
21776 self.write(&idx.to_string());
21777 }
21778 Ok(())
21779 }
21780
21781 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
21782 if f.is_block {
21783 self.write("/*");
21784 self.write(&f.text);
21785 self.write("*/");
21786 } else {
21787 self.write("--");
21788 self.write(&f.text);
21789 }
21790 Ok(())
21791 }
21792
21793 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
21796 self.generate_expression(&f.this)?;
21797 if f.not {
21798 self.write_space();
21799 self.write_keyword("NOT");
21800 }
21801 self.write_space();
21802 self.write_keyword("SIMILAR TO");
21803 self.write_space();
21804 self.generate_expression(&f.pattern)?;
21805 if let Some(ref escape) = f.escape {
21806 self.write_space();
21807 self.write_keyword("ESCAPE");
21808 self.write_space();
21809 self.generate_expression(escape)?;
21810 }
21811 Ok(())
21812 }
21813
21814 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
21815 self.generate_expression(&f.this)?;
21816 self.write_space();
21817 if let Some(op) = &f.op {
21819 match op {
21820 QuantifiedOp::Eq => self.write("="),
21821 QuantifiedOp::Neq => self.write("<>"),
21822 QuantifiedOp::Lt => self.write("<"),
21823 QuantifiedOp::Lte => self.write("<="),
21824 QuantifiedOp::Gt => self.write(">"),
21825 QuantifiedOp::Gte => self.write(">="),
21826 }
21827 self.write_space();
21828 }
21829 self.write_keyword(name);
21830
21831 if matches!(&f.subquery, Expression::Subquery(_)) {
21833 self.write_space();
21834 self.generate_expression(&f.subquery)?;
21835 } else {
21836 self.write("(");
21837
21838 let is_statement = matches!(
21839 &f.subquery,
21840 Expression::Select(_)
21841 | Expression::Union(_)
21842 | Expression::Intersect(_)
21843 | Expression::Except(_)
21844 );
21845
21846 if self.config.pretty && is_statement {
21847 self.write_newline();
21848 self.indent_level += 1;
21849 self.write_indent();
21850 }
21851 self.generate_expression(&f.subquery)?;
21852 if self.config.pretty && is_statement {
21853 self.write_newline();
21854 self.indent_level -= 1;
21855 self.write_indent();
21856 }
21857 self.write(")");
21858 }
21859 Ok(())
21860 }
21861
21862 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
21863 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
21865 self.generate_expression(this)?;
21866 self.write_space();
21867 self.write_keyword("OVERLAPS");
21868 self.write_space();
21869 self.generate_expression(expr)?;
21870 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
21871 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
21872 {
21873 self.write("(");
21875 self.generate_expression(ls)?;
21876 self.write(", ");
21877 self.generate_expression(le)?;
21878 self.write(")");
21879 self.write_space();
21880 self.write_keyword("OVERLAPS");
21881 self.write_space();
21882 self.write("(");
21883 self.generate_expression(rs)?;
21884 self.write(", ");
21885 self.generate_expression(re)?;
21886 self.write(")");
21887 }
21888 Ok(())
21889 }
21890
21891 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
21894 use crate::dialects::DialectType;
21895
21896 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
21898 self.generate_expression(&cast.this)?;
21899 self.write(" !:> ");
21900 self.generate_data_type(&cast.to)?;
21901 return Ok(());
21902 }
21903
21904 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
21906 self.write_keyword("TRYCAST");
21907 self.write("(");
21908 self.generate_expression(&cast.this)?;
21909 self.write_space();
21910 self.write_keyword("AS");
21911 self.write_space();
21912 self.generate_data_type(&cast.to)?;
21913 self.write(")");
21914 return Ok(());
21915 }
21916
21917 let keyword = if matches!(
21919 self.config.dialect,
21920 Some(DialectType::Hive)
21921 | Some(DialectType::MySQL)
21922 | Some(DialectType::SQLite)
21923 | Some(DialectType::Oracle)
21924 | Some(DialectType::ClickHouse)
21925 | Some(DialectType::Redshift)
21926 | Some(DialectType::PostgreSQL)
21927 | Some(DialectType::StarRocks)
21928 | Some(DialectType::Doris)
21929 ) {
21930 "CAST"
21931 } else {
21932 "TRY_CAST"
21933 };
21934
21935 self.write_keyword(keyword);
21936 self.write("(");
21937 self.generate_expression(&cast.this)?;
21938 self.write_space();
21939 self.write_keyword("AS");
21940 self.write_space();
21941 self.generate_data_type(&cast.to)?;
21942
21943 if let Some(format) = &cast.format {
21945 self.write_space();
21946 self.write_keyword("FORMAT");
21947 self.write_space();
21948 self.generate_expression(format)?;
21949 }
21950
21951 self.write(")");
21952 Ok(())
21953 }
21954
21955 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
21956 self.write_keyword("SAFE_CAST");
21957 self.write("(");
21958 self.generate_expression(&cast.this)?;
21959 self.write_space();
21960 self.write_keyword("AS");
21961 self.write_space();
21962 self.generate_data_type(&cast.to)?;
21963
21964 if let Some(format) = &cast.format {
21966 self.write_space();
21967 self.write_keyword("FORMAT");
21968 self.write_space();
21969 self.generate_expression(format)?;
21970 }
21971
21972 self.write(")");
21973 Ok(())
21974 }
21975
21976 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
21979 let needs_parens = matches!(&s.this, Expression::JsonExtract(ref f) if f.arrow_syntax);
21983 if needs_parens {
21984 self.write("(");
21985 }
21986 self.generate_expression(&s.this)?;
21987 if needs_parens {
21988 self.write(")");
21989 }
21990 self.write("[");
21991 self.generate_expression(&s.index)?;
21992 self.write("]");
21993 Ok(())
21994 }
21995
21996 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
21997 self.generate_expression(&d.this)?;
21998 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
22001 && matches!(
22002 &d.this,
22003 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
22004 );
22005 if use_colon {
22006 self.write(":");
22007 } else {
22008 self.write(".");
22009 }
22010 self.generate_identifier(&d.field)
22011 }
22012
22013 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
22014 self.generate_expression(&m.this)?;
22015 self.write(".");
22016 if m.method.quoted {
22019 let q = self.config.identifier_quote;
22020 self.write(&format!("{}{}{}", q, m.method.name, q));
22021 } else {
22022 self.write(&m.method.name);
22023 }
22024 self.write("(");
22025 for (i, arg) in m.args.iter().enumerate() {
22026 if i > 0 {
22027 self.write(", ");
22028 }
22029 self.generate_expression(arg)?;
22030 }
22031 self.write(")");
22032 Ok(())
22033 }
22034
22035 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
22036 let needs_parens = matches!(
22039 &s.this,
22040 Expression::JsonExtract(f) if f.arrow_syntax
22041 ) || matches!(
22042 &s.this,
22043 Expression::JsonExtractScalar(f) if f.arrow_syntax
22044 );
22045
22046 if needs_parens {
22047 self.write("(");
22048 }
22049 self.generate_expression(&s.this)?;
22050 if needs_parens {
22051 self.write(")");
22052 }
22053 self.write("[");
22054 if let Some(start) = &s.start {
22055 self.generate_expression(start)?;
22056 }
22057 self.write(":");
22058 if let Some(end) = &s.end {
22059 self.generate_expression(end)?;
22060 }
22061 self.write("]");
22062 Ok(())
22063 }
22064
22065 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
22066 match &op.left {
22070 Expression::Column(col) => {
22071 if let Some(table) = &col.table {
22074 self.generate_identifier(table)?;
22075 self.write(".");
22076 }
22077 self.generate_identifier(&col.name)?;
22078 if col.join_mark && self.config.supports_column_join_marks {
22080 self.write(" (+)");
22081 }
22082 if op.left_comments.is_empty() {
22084 for comment in &col.trailing_comments {
22085 self.write_space();
22086 self.write_formatted_comment(comment);
22087 }
22088 }
22089 }
22090 Expression::Add(inner_op)
22091 | Expression::Sub(inner_op)
22092 | Expression::Mul(inner_op)
22093 | Expression::Div(inner_op)
22094 | Expression::Concat(inner_op) => {
22095 self.generate_binary_op_no_trailing(inner_op, match &op.left {
22097 Expression::Add(_) => "+",
22098 Expression::Sub(_) => "-",
22099 Expression::Mul(_) => "*",
22100 Expression::Div(_) => "/",
22101 Expression::Concat(_) => "||",
22102 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
22103 })?;
22104 }
22105 _ => {
22106 self.generate_expression(&op.left)?;
22107 }
22108 }
22109 for comment in &op.left_comments {
22111 self.write_space();
22112 self.write_formatted_comment(comment);
22113 }
22114 if self.config.pretty
22115 && matches!(self.config.dialect, Some(DialectType::Snowflake))
22116 && (operator == "AND" || operator == "OR")
22117 {
22118 self.write_newline();
22119 self.write_indent();
22120 self.write_keyword(operator);
22121 } else {
22122 self.write_space();
22123 if operator.chars().all(|c| c.is_alphabetic()) {
22124 self.write_keyword(operator);
22125 } else {
22126 self.write(operator);
22127 }
22128 }
22129 for comment in &op.operator_comments {
22131 self.write_space();
22132 self.write_formatted_comment(comment);
22133 }
22134 self.write_space();
22135 self.generate_expression(&op.right)?;
22136 for comment in &op.trailing_comments {
22138 self.write_space();
22139 self.write_formatted_comment(comment);
22140 }
22141 Ok(())
22142 }
22143
22144 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
22145 let keyword = connector.keyword();
22146 let Some(terms) = self.flatten_connector_terms(op, connector) else {
22147 return self.generate_binary_op(op, keyword);
22148 };
22149
22150 let wrap_clickhouse_or_term = |generator: &mut Self, term: &Expression| -> Result<()> {
22151 let should_wrap = matches!(connector, ConnectorOperator::Or)
22152 && matches!(generator.config.dialect, Some(DialectType::ClickHouse))
22153 && matches!(
22154 generator.config.source_dialect,
22155 Some(DialectType::ClickHouse)
22156 )
22157 && matches!(term, Expression::And(_));
22158 if should_wrap {
22159 generator.write("(");
22160 generator.generate_expression(term)?;
22161 generator.write(")");
22162 } else {
22163 generator.generate_expression(term)?;
22164 }
22165 Ok(())
22166 };
22167
22168 wrap_clickhouse_or_term(self, terms[0])?;
22169 for term in terms.iter().skip(1) {
22170 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
22171 self.write_newline();
22172 self.write_indent();
22173 self.write_keyword(keyword);
22174 } else {
22175 self.write_space();
22176 self.write_keyword(keyword);
22177 }
22178 self.write_space();
22179 wrap_clickhouse_or_term(self, term)?;
22180 }
22181
22182 Ok(())
22183 }
22184
22185 fn flatten_connector_terms<'a>(
22186 &self,
22187 root: &'a BinaryOp,
22188 connector: ConnectorOperator,
22189 ) -> Option<Vec<&'a Expression>> {
22190 if !root.left_comments.is_empty()
22191 || !root.operator_comments.is_empty()
22192 || !root.trailing_comments.is_empty()
22193 {
22194 return None;
22195 }
22196
22197 let mut terms = Vec::new();
22198 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
22199
22200 while let Some(expr) = stack.pop() {
22201 match (connector, expr) {
22202 (ConnectorOperator::And, Expression::And(inner))
22203 if inner.left_comments.is_empty()
22204 && inner.operator_comments.is_empty()
22205 && inner.trailing_comments.is_empty() =>
22206 {
22207 stack.push(&inner.right);
22208 stack.push(&inner.left);
22209 }
22210 (ConnectorOperator::Or, Expression::Or(inner))
22211 if inner.left_comments.is_empty()
22212 && inner.operator_comments.is_empty()
22213 && inner.trailing_comments.is_empty() =>
22214 {
22215 stack.push(&inner.right);
22216 stack.push(&inner.left);
22217 }
22218 _ => terms.push(expr),
22219 }
22220 }
22221
22222 if terms.len() > 1 {
22223 Some(terms)
22224 } else {
22225 None
22226 }
22227 }
22228
22229 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
22231 self.generate_expression(&op.left)?;
22232 self.write_space();
22233 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
22235 self.write("`ILIKE`");
22236 } else {
22237 self.write_keyword(operator);
22238 }
22239 if let Some(quantifier) = &op.quantifier {
22240 self.write_space();
22241 self.write_keyword(quantifier);
22242 let is_any =
22247 quantifier.eq_ignore_ascii_case("ANY") || quantifier.eq_ignore_ascii_case("SOME");
22248 if !(is_any && matches!(&op.right, Expression::Paren(_))) {
22249 self.write_space();
22250 }
22251 } else {
22252 self.write_space();
22253 }
22254 self.generate_expression(&op.right)?;
22255 if let Some(escape) = &op.escape {
22256 self.write_space();
22257 self.write_keyword("ESCAPE");
22258 self.write_space();
22259 self.generate_expression(escape)?;
22260 }
22261 Ok(())
22262 }
22263
22264 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
22267 use crate::dialects::DialectType;
22268 self.generate_expression(&op.left)?;
22269 self.write_space();
22270 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
22271 self.write("<=>");
22272 } else {
22273 self.write_keyword("IS NOT DISTINCT FROM");
22274 }
22275 self.write_space();
22276 self.generate_expression(&op.right)?;
22277 Ok(())
22278 }
22279
22280 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
22282 self.generate_expression(&op.left)?;
22283 self.write_space();
22284 self.write_keyword("IS DISTINCT FROM");
22285 self.write_space();
22286 self.generate_expression(&op.right)?;
22287 Ok(())
22288 }
22289
22290 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
22292 match &op.left {
22294 Expression::Column(col) => {
22295 if let Some(table) = &col.table {
22296 self.generate_identifier(table)?;
22297 self.write(".");
22298 }
22299 self.generate_identifier(&col.name)?;
22300 if col.join_mark && self.config.supports_column_join_marks {
22302 self.write(" (+)");
22303 }
22304 }
22305 Expression::Add(inner_op)
22306 | Expression::Sub(inner_op)
22307 | Expression::Mul(inner_op)
22308 | Expression::Div(inner_op)
22309 | Expression::Concat(inner_op) => {
22310 self.generate_binary_op_no_trailing(inner_op, match &op.left {
22311 Expression::Add(_) => "+",
22312 Expression::Sub(_) => "-",
22313 Expression::Mul(_) => "*",
22314 Expression::Div(_) => "/",
22315 Expression::Concat(_) => "||",
22316 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
22317 })?;
22318 }
22319 _ => {
22320 self.generate_expression(&op.left)?;
22321 }
22322 }
22323 for comment in &op.left_comments {
22325 self.write_space();
22326 self.write_formatted_comment(comment);
22327 }
22328 self.write_space();
22329 if operator.chars().all(|c| c.is_alphabetic()) {
22330 self.write_keyword(operator);
22331 } else {
22332 self.write(operator);
22333 }
22334 for comment in &op.operator_comments {
22336 self.write_space();
22337 self.write_formatted_comment(comment);
22338 }
22339 self.write_space();
22340 match &op.right {
22343 Expression::Column(col) => {
22344 if let Some(table) = &col.table {
22345 self.generate_identifier(table)?;
22346 self.write(".");
22347 }
22348 self.generate_identifier(&col.name)?;
22349 if col.join_mark && self.config.supports_column_join_marks {
22351 self.write(" (+)");
22352 }
22353 }
22354 _ => {
22355 self.generate_expression(&op.right)?;
22356 }
22357 }
22358 Ok(())
22360 }
22361
22362 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
22363 if operator.chars().all(|c| c.is_alphabetic()) {
22364 self.write_keyword(operator);
22365 self.write_space();
22366 } else {
22367 self.write(operator);
22368 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
22370 self.write_space();
22371 }
22372 }
22373 self.generate_expression(&op.this)
22374 }
22375
22376 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
22377 let is_generic =
22381 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
22382 let use_prefix_not =
22383 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
22384 if use_prefix_not {
22385 self.write_keyword("NOT");
22386 self.write_space();
22387 }
22388 self.generate_expression(&in_expr.this)?;
22389 if in_expr.global {
22390 self.write_space();
22391 self.write_keyword("GLOBAL");
22392 }
22393 if in_expr.not && !use_prefix_not {
22394 self.write_space();
22395 self.write_keyword("NOT");
22396 }
22397 self.write_space();
22398 self.write_keyword("IN");
22399
22400 if let Some(unnest_expr) = &in_expr.unnest {
22402 self.write_space();
22403 self.write_keyword("UNNEST");
22404 self.write("(");
22405 self.generate_expression(unnest_expr)?;
22406 self.write(")");
22407 return Ok(());
22408 }
22409
22410 if let Some(query) = &in_expr.query {
22411 let is_bare = in_expr.expressions.is_empty()
22414 && !matches!(
22415 query,
22416 Expression::Select(_)
22417 | Expression::Union(_)
22418 | Expression::Intersect(_)
22419 | Expression::Except(_)
22420 | Expression::Subquery(_)
22421 );
22422 if is_bare {
22423 self.write_space();
22425 self.generate_expression(query)?;
22426 } else {
22427 self.write(" (");
22429 let is_statement = matches!(
22430 query,
22431 Expression::Select(_)
22432 | Expression::Union(_)
22433 | Expression::Intersect(_)
22434 | Expression::Except(_)
22435 | Expression::Subquery(_)
22436 );
22437 if self.config.pretty && is_statement {
22438 self.write_newline();
22439 self.indent_level += 1;
22440 self.write_indent();
22441 }
22442 self.generate_expression(query)?;
22443 if self.config.pretty && is_statement {
22444 self.write_newline();
22445 self.indent_level -= 1;
22446 self.write_indent();
22447 }
22448 self.write(")");
22449 }
22450 } else {
22451 let is_duckdb = matches!(
22455 self.config.dialect,
22456 Some(crate::dialects::DialectType::DuckDB)
22457 );
22458 let is_clickhouse = matches!(
22459 self.config.dialect,
22460 Some(crate::dialects::DialectType::ClickHouse)
22461 );
22462 let single_expr = in_expr.expressions.len() == 1;
22463 if is_clickhouse && single_expr {
22464 if let Expression::Array(arr) = &in_expr.expressions[0] {
22465 self.write(" (");
22467 for (i, expr) in arr.expressions.iter().enumerate() {
22468 if i > 0 {
22469 self.write(", ");
22470 }
22471 self.generate_expression(expr)?;
22472 }
22473 self.write(")");
22474 } else if in_expr.is_field {
22475 self.write_space();
22476 self.generate_expression(&in_expr.expressions[0])?;
22477 } else {
22478 self.write(" (");
22479 self.generate_expression(&in_expr.expressions[0])?;
22480 self.write(")");
22481 }
22482 } else {
22483 let is_bare_ref = single_expr
22484 && matches!(
22485 &in_expr.expressions[0],
22486 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
22487 );
22488 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
22489 self.write_space();
22492 self.generate_expression(&in_expr.expressions[0])?;
22493 } else {
22494 self.write(" (");
22496 for (i, expr) in in_expr.expressions.iter().enumerate() {
22497 if i > 0 {
22498 self.write(", ");
22499 }
22500 self.generate_expression(expr)?;
22501 }
22502 self.write(")");
22503 }
22504 }
22505 }
22506
22507 Ok(())
22508 }
22509
22510 fn generate_between(&mut self, between: &Between) -> Result<()> {
22511 let use_prefix_not = between.not
22513 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
22514 if use_prefix_not {
22515 self.write_keyword("NOT");
22516 self.write_space();
22517 }
22518 self.generate_expression(&between.this)?;
22519 if between.not && !use_prefix_not {
22520 self.write_space();
22521 self.write_keyword("NOT");
22522 }
22523 self.write_space();
22524 self.write_keyword("BETWEEN");
22525 if let Some(sym) = between.symmetric {
22527 if sym {
22528 self.write(" SYMMETRIC");
22529 } else {
22530 self.write(" ASYMMETRIC");
22531 }
22532 }
22533 self.write_space();
22534 self.generate_expression(&between.low)?;
22535 self.write_space();
22536 self.write_keyword("AND");
22537 self.write_space();
22538 self.generate_expression(&between.high)
22539 }
22540
22541 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
22542 let use_prefix_not = is_null.not
22544 && (self.config.dialect.is_none()
22545 || self.config.dialect == Some(DialectType::Generic)
22546 || is_null.postfix_form);
22547 if use_prefix_not {
22548 self.write_keyword("NOT");
22550 self.write_space();
22551 self.generate_expression(&is_null.this)?;
22552 self.write_space();
22553 self.write_keyword("IS");
22554 self.write_space();
22555 self.write_keyword("NULL");
22556 } else {
22557 self.generate_expression(&is_null.this)?;
22558 self.write_space();
22559 self.write_keyword("IS");
22560 if is_null.not {
22561 self.write_space();
22562 self.write_keyword("NOT");
22563 }
22564 self.write_space();
22565 self.write_keyword("NULL");
22566 }
22567 Ok(())
22568 }
22569
22570 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
22571 self.generate_expression(&is_true.this)?;
22572 self.write_space();
22573 self.write_keyword("IS");
22574 if is_true.not {
22575 self.write_space();
22576 self.write_keyword("NOT");
22577 }
22578 self.write_space();
22579 self.write_keyword("TRUE");
22580 Ok(())
22581 }
22582
22583 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
22584 self.generate_expression(&is_false.this)?;
22585 self.write_space();
22586 self.write_keyword("IS");
22587 if is_false.not {
22588 self.write_space();
22589 self.write_keyword("NOT");
22590 }
22591 self.write_space();
22592 self.write_keyword("FALSE");
22593 Ok(())
22594 }
22595
22596 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
22597 self.generate_expression(&is_json.this)?;
22598 self.write_space();
22599 self.write_keyword("IS");
22600 if is_json.negated {
22601 self.write_space();
22602 self.write_keyword("NOT");
22603 }
22604 self.write_space();
22605 self.write_keyword("JSON");
22606
22607 if let Some(ref json_type) = is_json.json_type {
22609 self.write_space();
22610 self.write_keyword(json_type);
22611 }
22612
22613 match &is_json.unique_keys {
22615 Some(JsonUniqueKeys::With) => {
22616 self.write_space();
22617 self.write_keyword("WITH UNIQUE KEYS");
22618 }
22619 Some(JsonUniqueKeys::Without) => {
22620 self.write_space();
22621 self.write_keyword("WITHOUT UNIQUE KEYS");
22622 }
22623 Some(JsonUniqueKeys::Shorthand) => {
22624 self.write_space();
22625 self.write_keyword("UNIQUE KEYS");
22626 }
22627 None => {}
22628 }
22629
22630 Ok(())
22631 }
22632
22633 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
22634 self.generate_expression(&is_expr.left)?;
22635 self.write_space();
22636 self.write_keyword("IS");
22637 self.write_space();
22638 self.generate_expression(&is_expr.right)
22639 }
22640
22641 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
22642 if exists.not {
22643 self.write_keyword("NOT");
22644 self.write_space();
22645 }
22646 self.write_keyword("EXISTS");
22647 self.write("(");
22648 let is_statement = matches!(
22649 &exists.this,
22650 Expression::Select(_)
22651 | Expression::Union(_)
22652 | Expression::Intersect(_)
22653 | Expression::Except(_)
22654 );
22655 if self.config.pretty && is_statement {
22656 self.write_newline();
22657 self.indent_level += 1;
22658 self.write_indent();
22659 self.generate_expression(&exists.this)?;
22660 self.write_newline();
22661 self.indent_level -= 1;
22662 self.write_indent();
22663 self.write(")");
22664 } else {
22665 self.generate_expression(&exists.this)?;
22666 self.write(")");
22667 }
22668 Ok(())
22669 }
22670
22671 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
22672 self.generate_expression(&op.left)?;
22673 self.write_space();
22674 self.write_keyword("MEMBER OF");
22675 self.write("(");
22676 self.generate_expression(&op.right)?;
22677 self.write(")");
22678 Ok(())
22679 }
22680
22681 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
22682 if subquery.lateral {
22683 self.write_keyword("LATERAL");
22684 self.write_space();
22685 }
22686
22687 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
22691 matches!(
22692 &p.this,
22693 Expression::Select(_)
22694 | Expression::Union(_)
22695 | Expression::Intersect(_)
22696 | Expression::Except(_)
22697 | Expression::Subquery(_)
22698 )
22699 } else {
22700 false
22701 };
22702
22703 let is_statement = matches!(
22705 &subquery.this,
22706 Expression::Select(_)
22707 | Expression::Union(_)
22708 | Expression::Intersect(_)
22709 | Expression::Except(_)
22710 | Expression::Merge(_)
22711 );
22712
22713 if !skip_outer_parens {
22714 self.write("(");
22715 if self.config.pretty && is_statement {
22716 self.write_newline();
22717 self.indent_level += 1;
22718 self.write_indent();
22719 }
22720 }
22721 self.generate_expression(&subquery.this)?;
22722
22723 if subquery.modifiers_inside {
22725 if let Some(order_by) = &subquery.order_by {
22727 self.write_space();
22728 self.write_keyword("ORDER BY");
22729 self.write_space();
22730 for (i, ord) in order_by.expressions.iter().enumerate() {
22731 if i > 0 {
22732 self.write(", ");
22733 }
22734 self.generate_ordered(ord)?;
22735 }
22736 }
22737
22738 if let Some(limit) = &subquery.limit {
22739 self.write_space();
22740 self.write_keyword("LIMIT");
22741 self.write_space();
22742 self.generate_expression(&limit.this)?;
22743 if limit.percent {
22744 self.write_space();
22745 self.write_keyword("PERCENT");
22746 }
22747 }
22748
22749 if let Some(offset) = &subquery.offset {
22750 self.write_space();
22751 self.write_keyword("OFFSET");
22752 self.write_space();
22753 self.generate_expression(&offset.this)?;
22754 }
22755 }
22756
22757 if !skip_outer_parens {
22758 if self.config.pretty && is_statement {
22759 self.write_newline();
22760 self.indent_level -= 1;
22761 self.write_indent();
22762 }
22763 self.write(")");
22764 }
22765
22766 if !subquery.modifiers_inside {
22768 if let Some(order_by) = &subquery.order_by {
22769 self.write_space();
22770 self.write_keyword("ORDER BY");
22771 self.write_space();
22772 for (i, ord) in order_by.expressions.iter().enumerate() {
22773 if i > 0 {
22774 self.write(", ");
22775 }
22776 self.generate_ordered(ord)?;
22777 }
22778 }
22779
22780 if let Some(limit) = &subquery.limit {
22781 self.write_space();
22782 self.write_keyword("LIMIT");
22783 self.write_space();
22784 self.generate_expression(&limit.this)?;
22785 if limit.percent {
22786 self.write_space();
22787 self.write_keyword("PERCENT");
22788 }
22789 }
22790
22791 if let Some(offset) = &subquery.offset {
22792 self.write_space();
22793 self.write_keyword("OFFSET");
22794 self.write_space();
22795 self.generate_expression(&offset.this)?;
22796 }
22797
22798 if let Some(distribute_by) = &subquery.distribute_by {
22800 self.write_space();
22801 self.write_keyword("DISTRIBUTE BY");
22802 self.write_space();
22803 for (i, expr) in distribute_by.expressions.iter().enumerate() {
22804 if i > 0 {
22805 self.write(", ");
22806 }
22807 self.generate_expression(expr)?;
22808 }
22809 }
22810
22811 if let Some(sort_by) = &subquery.sort_by {
22813 self.write_space();
22814 self.write_keyword("SORT BY");
22815 self.write_space();
22816 for (i, ord) in sort_by.expressions.iter().enumerate() {
22817 if i > 0 {
22818 self.write(", ");
22819 }
22820 self.generate_ordered(ord)?;
22821 }
22822 }
22823
22824 if let Some(cluster_by) = &subquery.cluster_by {
22826 self.write_space();
22827 self.write_keyword("CLUSTER BY");
22828 self.write_space();
22829 for (i, ord) in cluster_by.expressions.iter().enumerate() {
22830 if i > 0 {
22831 self.write(", ");
22832 }
22833 self.generate_ordered(ord)?;
22834 }
22835 }
22836 }
22837
22838 if let Some(alias) = &subquery.alias {
22839 self.write_space();
22840 let skip_as = matches!(self.config.dialect, Some(DialectType::Oracle))
22841 || (matches!(self.config.dialect, Some(DialectType::ClickHouse))
22842 && !subquery.alias_explicit_as);
22843 if !skip_as {
22844 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22845 self.write(subquery.alias_keyword.as_deref().unwrap_or("AS"));
22846 } else {
22847 self.write_keyword("AS");
22848 }
22849 self.write_space();
22850 }
22851 self.generate_identifier(alias)?;
22852 if !subquery.column_aliases.is_empty() {
22853 self.write("(");
22854 for (i, col) in subquery.column_aliases.iter().enumerate() {
22855 if i > 0 {
22856 self.write(", ");
22857 }
22858 self.generate_identifier(col)?;
22859 }
22860 self.write(")");
22861 }
22862 }
22863 for comment in &subquery.trailing_comments {
22865 self.write(" ");
22866 self.write_formatted_comment(comment);
22867 }
22868 Ok(())
22869 }
22870
22871 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
22872 if let Some(ref with) = pivot.with {
22874 self.generate_with(with)?;
22875 self.write_space();
22876 }
22877
22878 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
22879
22880 let is_redshift_unpivot = pivot.unpivot
22884 && pivot.expressions.is_empty()
22885 && pivot.fields.is_empty()
22886 && pivot.using.is_empty()
22887 && pivot.into.is_none()
22888 && !matches!(&pivot.this, Expression::Null(_));
22889
22890 if is_redshift_unpivot {
22891 self.write_keyword("UNPIVOT");
22893 self.write_space();
22894 self.generate_expression(&pivot.this)?;
22895 if let Some(alias) = &pivot.alias {
22897 self.write_space();
22898 self.write_keyword("AS");
22899 self.write_space();
22900 self.write(&alias.name);
22902 }
22903 return Ok(());
22904 }
22905
22906 let is_simplified = !pivot.using.is_empty()
22908 || pivot.into.is_some()
22909 || (pivot.fields.is_empty()
22910 && !pivot.expressions.is_empty()
22911 && !matches!(&pivot.this, Expression::Null(_)));
22912
22913 if is_simplified {
22914 self.write_keyword(direction);
22918 self.write_space();
22919 self.generate_expression(&pivot.this)?;
22920
22921 if !pivot.expressions.is_empty() {
22922 self.write_space();
22923 self.write_keyword("ON");
22924 self.write_space();
22925 for (i, expr) in pivot.expressions.iter().enumerate() {
22926 if i > 0 {
22927 self.write(", ");
22928 }
22929 self.generate_expression(expr)?;
22930 }
22931 }
22932
22933 if let Some(into) = &pivot.into {
22935 self.write_space();
22936 self.write_keyword("INTO");
22937 self.write_space();
22938 self.generate_expression(into)?;
22939 }
22940
22941 if !pivot.using.is_empty() {
22943 self.write_space();
22944 self.write_keyword("USING");
22945 self.write_space();
22946 for (i, expr) in pivot.using.iter().enumerate() {
22947 if i > 0 {
22948 self.write(", ");
22949 }
22950 self.generate_expression(expr)?;
22951 }
22952 }
22953
22954 if let Some(group) = &pivot.group {
22956 self.write_space();
22957 self.generate_expression(group)?;
22958 }
22959 } else {
22960 if !matches!(&pivot.this, Expression::Null(_)) {
22965 self.generate_expression(&pivot.this)?;
22966 self.write_space();
22967 }
22968 self.write_keyword(direction);
22969 self.write("(");
22970
22971 for (i, expr) in pivot.expressions.iter().enumerate() {
22973 if i > 0 {
22974 self.write(", ");
22975 }
22976 self.generate_expression(expr)?;
22977 }
22978
22979 if !pivot.fields.is_empty() {
22981 if !pivot.expressions.is_empty() {
22982 self.write_space();
22983 }
22984 self.write_keyword("FOR");
22985 self.write_space();
22986 for (i, field) in pivot.fields.iter().enumerate() {
22987 if i > 0 {
22988 self.write_space();
22989 }
22990 self.generate_expression(field)?;
22992 }
22993 }
22994
22995 if let Some(default_val) = &pivot.default_on_null {
22997 self.write_space();
22998 self.write_keyword("DEFAULT ON NULL");
22999 self.write(" (");
23000 self.generate_expression(default_val)?;
23001 self.write(")");
23002 }
23003
23004 if let Some(group) = &pivot.group {
23006 self.write_space();
23007 self.generate_expression(group)?;
23008 }
23009
23010 self.write(")");
23011 }
23012
23013 if let Some(alias) = &pivot.alias {
23015 self.write_space();
23016 self.write_keyword("AS");
23017 self.write_space();
23018 self.generate_identifier(alias)?;
23019 }
23020
23021 Ok(())
23022 }
23023
23024 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
23025 self.generate_expression(&unpivot.this)?;
23026 self.write_space();
23027 self.write_keyword("UNPIVOT");
23028 if let Some(include) = unpivot.include_nulls {
23030 self.write_space();
23031 if include {
23032 self.write_keyword("INCLUDE NULLS");
23033 } else {
23034 self.write_keyword("EXCLUDE NULLS");
23035 }
23036 self.write_space();
23037 }
23038 self.write("(");
23039 if unpivot.value_column_parenthesized {
23040 self.write("(");
23041 }
23042 self.generate_identifier(&unpivot.value_column)?;
23043 for extra_col in &unpivot.extra_value_columns {
23045 self.write(", ");
23046 self.generate_identifier(extra_col)?;
23047 }
23048 if unpivot.value_column_parenthesized {
23049 self.write(")");
23050 }
23051 self.write_space();
23052 self.write_keyword("FOR");
23053 self.write_space();
23054 self.generate_identifier(&unpivot.name_column)?;
23055 self.write_space();
23056 self.write_keyword("IN");
23057 self.write(" (");
23058 for (i, col) in unpivot.columns.iter().enumerate() {
23059 if i > 0 {
23060 self.write(", ");
23061 }
23062 self.generate_expression(col)?;
23063 }
23064 self.write("))");
23065 if let Some(alias) = &unpivot.alias {
23066 self.write_space();
23067 self.write_keyword("AS");
23068 self.write_space();
23069 self.generate_identifier(alias)?;
23070 }
23071 Ok(())
23072 }
23073
23074 fn generate_values(&mut self, values: &Values) -> Result<()> {
23075 self.write_keyword("VALUES");
23076 for (i, row) in values.expressions.iter().enumerate() {
23077 if i > 0 {
23078 self.write(",");
23079 }
23080 self.write(" (");
23081 for (j, expr) in row.expressions.iter().enumerate() {
23082 if j > 0 {
23083 self.write(", ");
23084 }
23085 self.generate_expression(expr)?;
23086 }
23087 self.write(")");
23088 }
23089 if let Some(alias) = &values.alias {
23090 self.write_space();
23091 self.write_keyword("AS");
23092 self.write_space();
23093 self.generate_identifier(alias)?;
23094 if !values.column_aliases.is_empty() {
23095 self.write("(");
23096 for (i, col) in values.column_aliases.iter().enumerate() {
23097 if i > 0 {
23098 self.write(", ");
23099 }
23100 self.generate_identifier(col)?;
23101 }
23102 self.write(")");
23103 }
23104 }
23105 Ok(())
23106 }
23107
23108 fn generate_array(&mut self, arr: &Array) -> Result<()> {
23109 let needs_inheritance = matches!(
23111 self.config.dialect,
23112 Some(DialectType::DuckDB)
23113 | Some(DialectType::Spark)
23114 | Some(DialectType::Databricks)
23115 | Some(DialectType::Hive)
23116 | Some(DialectType::Snowflake)
23117 | Some(DialectType::Presto)
23118 | Some(DialectType::Trino)
23119 );
23120 let propagated: Vec<Expression>;
23121 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
23122 propagated = Self::inherit_struct_field_names(&arr.expressions);
23123 &propagated
23124 } else {
23125 &arr.expressions
23126 };
23127
23128 let use_parens =
23131 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
23132 if !self.config.array_bracket_only {
23133 self.write_keyword("ARRAY");
23134 }
23135 if use_parens {
23136 self.write("(");
23137 } else {
23138 self.write("[");
23139 }
23140 for (i, expr) in expressions.iter().enumerate() {
23141 if i > 0 {
23142 self.write(", ");
23143 }
23144 self.generate_expression(expr)?;
23145 }
23146 if use_parens {
23147 self.write(")");
23148 } else {
23149 self.write("]");
23150 }
23151 Ok(())
23152 }
23153
23154 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
23155 if tuple.expressions.len() == 2 {
23158 if let Expression::TableAlias(_) = &tuple.expressions[1] {
23159 self.generate_expression(&tuple.expressions[0])?;
23161 self.write_space();
23162 self.write_keyword("AS");
23163 self.write_space();
23164 self.generate_expression(&tuple.expressions[1])?;
23165 return Ok(());
23166 }
23167 }
23168
23169 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
23172 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
23173 for expr in &tuple.expressions {
23174 expr_strings.push(self.generate_to_string(expr)?);
23175 }
23176 self.too_wide(&expr_strings)
23177 } else {
23178 false
23179 };
23180
23181 if expand_tuple {
23182 self.write("(");
23183 self.write_newline();
23184 self.indent_level += 1;
23185 for (i, expr) in tuple.expressions.iter().enumerate() {
23186 if i > 0 {
23187 self.write(",");
23188 self.write_newline();
23189 }
23190 self.write_indent();
23191 self.generate_expression(expr)?;
23192 }
23193 self.indent_level -= 1;
23194 self.write_newline();
23195 self.write_indent();
23196 self.write(")");
23197 } else {
23198 self.write("(");
23199 for (i, expr) in tuple.expressions.iter().enumerate() {
23200 if i > 0 {
23201 self.write(", ");
23202 }
23203 self.generate_expression(expr)?;
23204 }
23205 self.write(")");
23206 }
23207 Ok(())
23208 }
23209
23210 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
23211 self.generate_expression(&pipe.this)?;
23212 self.write(" |> ");
23213 self.generate_expression(&pipe.expression)?;
23214 Ok(())
23215 }
23216
23217 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
23218 let unsupported_tsql_null_ordering = ordered.nulls_first.is_some()
23219 && !self.config.null_ordering_supported
23220 && matches!(
23221 self.config.dialect,
23222 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23223 );
23224 let random_ordering = matches!(ordered.this, Expression::Rand(_) | Expression::Random(_));
23225 let emulate_tsql_null_ordering = if let Some(nulls_first) = ordered.nulls_first {
23226 let target_default_nulls_first = !ordered.desc;
23227
23228 unsupported_tsql_null_ordering
23229 && nulls_first != target_default_nulls_first
23230 && !random_ordering
23231 } else {
23232 false
23233 };
23234
23235 if emulate_tsql_null_ordering {
23236 self.write_keyword("CASE WHEN");
23237 self.write_space();
23238 self.generate_expression(&ordered.this)?;
23239 self.write_space();
23240 self.write_keyword("IS NULL THEN 1 ELSE 0 END");
23241 if ordered.nulls_first == Some(true) {
23242 self.write_space();
23243 self.write_keyword("DESC");
23244 }
23245 self.write(", ");
23246 }
23247
23248 self.generate_expression(&ordered.this)?;
23249 if ordered.desc {
23250 self.write_space();
23251 self.write_keyword("DESC");
23252 } else if ordered.explicit_asc {
23253 self.write_space();
23254 self.write_keyword("ASC");
23255 }
23256 if let Some(nulls_first) = ordered.nulls_first {
23257 if !unsupported_tsql_null_ordering
23258 && (self.config.null_ordering_supported
23259 || !matches!(self.config.dialect, Some(DialectType::Fabric)))
23260 {
23261 let is_asc = !ordered.desc;
23275 let is_nulls_are_large = matches!(
23276 self.config.dialect,
23277 Some(DialectType::Oracle)
23278 | Some(DialectType::PostgreSQL)
23279 | Some(DialectType::Redshift)
23280 | Some(DialectType::Snowflake)
23281 );
23282 let is_nulls_are_last = matches!(
23283 self.config.dialect,
23284 Some(DialectType::Dremio)
23285 | Some(DialectType::DuckDB)
23286 | Some(DialectType::Presto)
23287 | Some(DialectType::Trino)
23288 | Some(DialectType::Athena)
23289 | Some(DialectType::ClickHouse)
23290 | Some(DialectType::Drill)
23291 | Some(DialectType::Exasol)
23292 );
23293
23294 let is_default_nulls = if is_nulls_are_large {
23296 (is_asc && !nulls_first) || (!is_asc && nulls_first)
23298 } else if is_nulls_are_last {
23299 !nulls_first
23301 } else {
23302 false
23303 };
23304
23305 if !is_default_nulls {
23306 self.write_space();
23307 self.write_keyword("NULLS");
23308 self.write_space();
23309 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
23310 }
23311 }
23312 }
23313 if let Some(ref with_fill) = ordered.with_fill {
23315 self.write_space();
23316 self.generate_with_fill(with_fill)?;
23317 }
23318 Ok(())
23319 }
23320
23321 fn write_clickhouse_type(&mut self, type_str: &str) {
23323 if self.clickhouse_nullable_depth < 0 {
23324 self.write(type_str);
23326 } else {
23327 self.write(&format!("Nullable({})", type_str));
23328 }
23329 }
23330
23331 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
23332 use crate::dialects::DialectType;
23333
23334 match dt {
23335 DataType::Boolean => {
23336 match self.config.dialect {
23338 Some(DialectType::TSQL) => self.write_keyword("BIT"),
23339 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
23341 self.write_keyword("NUMBER(1)")
23343 }
23344 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
23346 }
23347 }
23348 DataType::TinyInt { length } => {
23349 match self.config.dialect {
23353 Some(DialectType::PostgreSQL)
23354 | Some(DialectType::Redshift)
23355 | Some(DialectType::Oracle)
23356 | Some(DialectType::Exasol) => {
23357 self.write_keyword("SMALLINT");
23358 }
23359 Some(DialectType::Teradata) => {
23360 self.write_keyword("BYTEINT");
23362 }
23363 Some(DialectType::Dremio) => {
23364 self.write_keyword("INT");
23366 }
23367 Some(DialectType::ClickHouse) => {
23368 self.write_clickhouse_type("Int8");
23369 }
23370 _ => {
23371 self.write_keyword("TINYINT");
23372 }
23373 }
23374 if let Some(n) = length {
23375 if !matches!(
23376 self.config.dialect,
23377 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
23378 ) {
23379 self.write(&format!("({})", n));
23380 }
23381 }
23382 }
23383 DataType::SmallInt { length } => {
23384 match self.config.dialect {
23386 Some(DialectType::Dremio) => {
23387 self.write_keyword("INT");
23388 }
23389 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
23390 self.write_keyword("INTEGER");
23391 }
23392 Some(DialectType::BigQuery) => {
23393 self.write_keyword("INT64");
23394 }
23395 Some(DialectType::ClickHouse) => {
23396 self.write_clickhouse_type("Int16");
23397 }
23398 _ => {
23399 self.write_keyword("SMALLINT");
23400 if let Some(n) = length {
23401 self.write(&format!("({})", n));
23402 }
23403 }
23404 }
23405 }
23406 DataType::Int {
23407 length,
23408 integer_spelling: _,
23409 } => {
23410 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
23412 self.write_keyword("INT64");
23413 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23414 self.write_clickhouse_type("Int32");
23415 } else {
23416 let use_integer = match self.config.dialect {
23418 Some(DialectType::TSQL)
23419 | Some(DialectType::Fabric)
23420 | Some(DialectType::Presto)
23421 | Some(DialectType::Trino)
23422 | Some(DialectType::SQLite)
23423 | Some(DialectType::Redshift) => true,
23424 _ => false,
23425 };
23426 if use_integer {
23427 self.write_keyword("INTEGER");
23428 } else {
23429 self.write_keyword("INT");
23430 }
23431 if let Some(n) = length {
23432 self.write(&format!("({})", n));
23433 }
23434 }
23435 }
23436 DataType::BigInt { length } => {
23437 match self.config.dialect {
23439 Some(DialectType::Oracle) => {
23440 self.write_keyword("INT");
23442 }
23443 Some(DialectType::ClickHouse) => {
23444 self.write_clickhouse_type("Int64");
23445 }
23446 _ => {
23447 self.write_keyword("BIGINT");
23448 if let Some(n) = length {
23449 self.write(&format!("({})", n));
23450 }
23451 }
23452 }
23453 }
23454 DataType::Float {
23455 precision,
23456 scale,
23457 real_spelling,
23458 } => {
23459 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23463 self.write_clickhouse_type("Float32");
23464 } else if *real_spelling
23465 && !matches!(
23466 self.config.dialect,
23467 Some(DialectType::Spark)
23468 | Some(DialectType::Databricks)
23469 | Some(DialectType::Hive)
23470 | Some(DialectType::Snowflake)
23471 | Some(DialectType::MySQL)
23472 | Some(DialectType::BigQuery)
23473 )
23474 {
23475 self.write_keyword("REAL")
23476 } else {
23477 match self.config.dialect {
23478 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
23479 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
23480 _ => self.write_keyword("FLOAT"),
23481 }
23482 }
23483 if !matches!(
23486 self.config.dialect,
23487 Some(DialectType::Spark)
23488 | Some(DialectType::Databricks)
23489 | Some(DialectType::Hive)
23490 | Some(DialectType::Presto)
23491 | Some(DialectType::Trino)
23492 ) {
23493 if let Some(p) = precision {
23494 self.write(&format!("({}", p));
23495 if let Some(s) = scale {
23496 self.write(&format!(", {})", s));
23497 } else {
23498 self.write(")");
23499 }
23500 }
23501 }
23502 }
23503 DataType::Double { precision, scale } => {
23504 match self.config.dialect {
23506 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23507 self.write_keyword("FLOAT")
23508 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
23510 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
23511 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
23512 Some(DialectType::SQLite) => self.write_keyword("REAL"),
23513 Some(DialectType::PostgreSQL)
23514 | Some(DialectType::Redshift)
23515 | Some(DialectType::Teradata)
23516 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
23517 _ => self.write_keyword("DOUBLE"),
23518 }
23519 if let Some(p) = precision {
23521 self.write(&format!("({}", p));
23522 if let Some(s) = scale {
23523 self.write(&format!(", {})", s));
23524 } else {
23525 self.write(")");
23526 }
23527 }
23528 }
23529 DataType::Decimal { precision, scale } => {
23530 match self.config.dialect {
23532 Some(DialectType::ClickHouse) => {
23533 self.write("Decimal");
23534 if let Some(p) = precision {
23535 self.write(&format!("({}", p));
23536 if let Some(s) = scale {
23537 self.write(&format!(", {}", s));
23538 }
23539 self.write(")");
23540 }
23541 }
23542 Some(DialectType::Oracle) => {
23543 self.write_keyword("NUMBER");
23545 if let Some(p) = precision {
23546 self.write(&format!("({}", p));
23547 if let Some(s) = scale {
23548 self.write(&format!(", {}", s));
23549 }
23550 self.write(")");
23551 }
23552 }
23553 Some(DialectType::BigQuery) => {
23554 self.write_keyword("NUMERIC");
23556 if let Some(p) = precision {
23557 self.write(&format!("({}", p));
23558 if let Some(s) = scale {
23559 self.write(&format!(", {}", s));
23560 }
23561 self.write(")");
23562 }
23563 }
23564 _ => {
23565 self.write_keyword("DECIMAL");
23566 if let Some(p) = precision {
23567 self.write(&format!("({}", p));
23568 if let Some(s) = scale {
23569 self.write(&format!(", {}", s));
23570 }
23571 self.write(")");
23572 }
23573 }
23574 }
23575 }
23576 DataType::Char { length } => {
23577 match self.config.dialect {
23579 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23580 self.write_keyword("TEXT");
23582 }
23583 Some(DialectType::Hive)
23584 | Some(DialectType::Spark)
23585 | Some(DialectType::Databricks) => {
23586 if length.is_some()
23589 && !matches!(self.config.dialect, Some(DialectType::Hive))
23590 {
23591 self.write_keyword("CHAR");
23592 if let Some(n) = length {
23593 self.write(&format!("({})", n));
23594 }
23595 } else {
23596 self.write_keyword("STRING");
23597 }
23598 }
23599 Some(DialectType::Dremio) => {
23600 self.write_keyword("VARCHAR");
23602 if let Some(n) = length {
23603 self.write(&format!("({})", n));
23604 }
23605 }
23606 _ => {
23607 self.write_keyword("CHAR");
23608 if let Some(n) = length {
23609 self.write(&format!("({})", n));
23610 }
23611 }
23612 }
23613 }
23614 DataType::VarChar {
23615 length,
23616 parenthesized_length,
23617 } => {
23618 match self.config.dialect {
23620 Some(DialectType::Oracle) => {
23621 self.write_keyword("VARCHAR2");
23622 if let Some(n) = length {
23623 self.write(&format!("({})", n));
23624 }
23625 }
23626 Some(DialectType::DuckDB) => {
23627 self.write_keyword("TEXT");
23629 if let Some(n) = length {
23630 self.write(&format!("({})", n));
23631 }
23632 }
23633 Some(DialectType::SQLite) => {
23634 self.write_keyword("TEXT");
23636 if let Some(n) = length {
23637 self.write(&format!("({})", n));
23638 }
23639 }
23640 Some(DialectType::MySQL) if length.is_none() => {
23641 self.write_keyword("TEXT");
23643 }
23644 Some(DialectType::Hive)
23645 | Some(DialectType::Spark)
23646 | Some(DialectType::Databricks)
23647 if length.is_none() =>
23648 {
23649 self.write_keyword("STRING");
23651 }
23652 _ => {
23653 self.write_keyword("VARCHAR");
23654 if let Some(n) = length {
23655 if *parenthesized_length {
23657 self.write(&format!("(({}))", n));
23658 } else {
23659 self.write(&format!("({})", n));
23660 }
23661 }
23662 }
23663 }
23664 }
23665 DataType::Text => {
23666 match self.config.dialect {
23668 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
23669 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23670 self.write_keyword("VARCHAR(MAX)")
23671 }
23672 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
23673 Some(DialectType::Snowflake)
23674 | Some(DialectType::Dremio)
23675 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
23676 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
23677 Some(DialectType::Presto)
23678 | Some(DialectType::Trino)
23679 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
23680 Some(DialectType::Spark)
23681 | Some(DialectType::Databricks)
23682 | Some(DialectType::Hive) => self.write_keyword("STRING"),
23683 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
23684 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
23685 self.write_keyword("STRING")
23686 }
23687 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
23688 _ => self.write_keyword("TEXT"),
23689 }
23690 }
23691 DataType::TextWithLength { length } => {
23692 match self.config.dialect {
23694 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
23695 Some(DialectType::Hive)
23696 | Some(DialectType::Spark)
23697 | Some(DialectType::Databricks) => {
23698 self.write(&format!("VARCHAR({})", length));
23699 }
23700 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
23701 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
23702 Some(DialectType::Snowflake)
23703 | Some(DialectType::Presto)
23704 | Some(DialectType::Trino)
23705 | Some(DialectType::Athena)
23706 | Some(DialectType::Drill)
23707 | Some(DialectType::Dremio) => {
23708 self.write(&format!("VARCHAR({})", length));
23709 }
23710 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23711 self.write(&format!("VARCHAR({})", length))
23712 }
23713 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
23714 self.write(&format!("STRING({})", length))
23715 }
23716 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
23717 _ => self.write(&format!("TEXT({})", length)),
23718 }
23719 }
23720 DataType::String { length } => {
23721 match self.config.dialect {
23723 Some(DialectType::ClickHouse) => {
23724 self.write("String");
23726 if let Some(n) = length {
23727 self.write(&format!("({})", n));
23728 }
23729 }
23730 Some(DialectType::BigQuery)
23731 | Some(DialectType::Hive)
23732 | Some(DialectType::Spark)
23733 | Some(DialectType::Databricks)
23734 | Some(DialectType::StarRocks)
23735 | Some(DialectType::Doris) => {
23736 self.write_keyword("STRING");
23737 if let Some(n) = length {
23738 self.write(&format!("({})", n));
23739 }
23740 }
23741 Some(DialectType::PostgreSQL) => {
23742 if let Some(n) = length {
23744 self.write_keyword("VARCHAR");
23745 self.write(&format!("({})", n));
23746 } else {
23747 self.write_keyword("TEXT");
23748 }
23749 }
23750 Some(DialectType::Redshift) => {
23751 if let Some(n) = length {
23753 self.write_keyword("VARCHAR");
23754 self.write(&format!("({})", n));
23755 } else {
23756 self.write_keyword("VARCHAR(MAX)");
23757 }
23758 }
23759 Some(DialectType::MySQL) => {
23760 if let Some(n) = length {
23762 self.write_keyword("VARCHAR");
23763 self.write(&format!("({})", n));
23764 } else {
23765 self.write_keyword("TEXT");
23766 }
23767 }
23768 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23769 if let Some(n) = length {
23771 self.write_keyword("VARCHAR");
23772 self.write(&format!("({})", n));
23773 } else {
23774 self.write_keyword("VARCHAR(MAX)");
23775 }
23776 }
23777 Some(DialectType::Oracle) => {
23778 self.write_keyword("CLOB");
23780 }
23781 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
23782 self.write_keyword("TEXT");
23784 if let Some(n) = length {
23785 self.write(&format!("({})", n));
23786 }
23787 }
23788 Some(DialectType::Presto)
23789 | Some(DialectType::Trino)
23790 | Some(DialectType::Drill)
23791 | Some(DialectType::Dremio) => {
23792 self.write_keyword("VARCHAR");
23794 if let Some(n) = length {
23795 self.write(&format!("({})", n));
23796 }
23797 }
23798 Some(DialectType::Snowflake) => {
23799 self.write_keyword("STRING");
23802 if let Some(n) = length {
23803 self.write(&format!("({})", n));
23804 }
23805 }
23806 _ => {
23807 self.write_keyword("STRING");
23809 if let Some(n) = length {
23810 self.write(&format!("({})", n));
23811 }
23812 }
23813 }
23814 }
23815 DataType::Binary { length } => {
23816 match self.config.dialect {
23818 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
23819 self.write_keyword("BYTEA");
23820 if let Some(n) = length {
23821 self.write(&format!("({})", n));
23822 }
23823 }
23824 Some(DialectType::Redshift) => {
23825 self.write_keyword("VARBYTE");
23826 if let Some(n) = length {
23827 self.write(&format!("({})", n));
23828 }
23829 }
23830 Some(DialectType::DuckDB)
23831 | Some(DialectType::SQLite)
23832 | Some(DialectType::Oracle) => {
23833 self.write_keyword("BLOB");
23835 if let Some(n) = length {
23836 self.write(&format!("({})", n));
23837 }
23838 }
23839 Some(DialectType::Presto)
23840 | Some(DialectType::Trino)
23841 | Some(DialectType::Athena)
23842 | Some(DialectType::Drill)
23843 | Some(DialectType::Dremio) => {
23844 self.write_keyword("VARBINARY");
23846 if let Some(n) = length {
23847 self.write(&format!("({})", n));
23848 }
23849 }
23850 Some(DialectType::ClickHouse) => {
23851 if self.clickhouse_nullable_depth < 0 {
23853 self.write("BINARY");
23854 } else {
23855 self.write("Nullable(BINARY");
23856 }
23857 if let Some(n) = length {
23858 self.write(&format!("({})", n));
23859 }
23860 if self.clickhouse_nullable_depth >= 0 {
23861 self.write(")");
23862 }
23863 }
23864 _ => {
23865 self.write_keyword("BINARY");
23866 if let Some(n) = length {
23867 self.write(&format!("({})", n));
23868 }
23869 }
23870 }
23871 }
23872 DataType::VarBinary { length } => {
23873 match self.config.dialect {
23875 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
23876 self.write_keyword("BYTEA");
23877 if let Some(n) = length {
23878 self.write(&format!("({})", n));
23879 }
23880 }
23881 Some(DialectType::Redshift) => {
23882 self.write_keyword("VARBYTE");
23883 if let Some(n) = length {
23884 self.write(&format!("({})", n));
23885 }
23886 }
23887 Some(DialectType::DuckDB)
23888 | Some(DialectType::SQLite)
23889 | Some(DialectType::Oracle) => {
23890 self.write_keyword("BLOB");
23892 if let Some(n) = length {
23893 self.write(&format!("({})", n));
23894 }
23895 }
23896 Some(DialectType::Exasol) => {
23897 self.write_keyword("VARCHAR");
23899 }
23900 Some(DialectType::Spark)
23901 | Some(DialectType::Hive)
23902 | Some(DialectType::Databricks) => {
23903 self.write_keyword("BINARY");
23905 if let Some(n) = length {
23906 self.write(&format!("({})", n));
23907 }
23908 }
23909 Some(DialectType::ClickHouse) => {
23910 self.write_clickhouse_type("String");
23912 }
23913 _ => {
23914 self.write_keyword("VARBINARY");
23915 if let Some(n) = length {
23916 self.write(&format!("({})", n));
23917 }
23918 }
23919 }
23920 }
23921 DataType::Blob => {
23922 match self.config.dialect {
23924 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
23925 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
23926 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23927 self.write_keyword("VARBINARY")
23928 }
23929 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
23930 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
23931 Some(DialectType::Presto)
23932 | Some(DialectType::Trino)
23933 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
23934 Some(DialectType::DuckDB) => {
23935 self.write_keyword("VARBINARY");
23938 }
23939 Some(DialectType::Spark)
23940 | Some(DialectType::Databricks)
23941 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
23942 Some(DialectType::ClickHouse) => {
23943 self.write("Nullable(String)");
23947 }
23948 _ => self.write_keyword("BLOB"),
23949 }
23950 }
23951 DataType::Bit { length } => {
23952 match self.config.dialect {
23954 Some(DialectType::Dremio)
23955 | Some(DialectType::Spark)
23956 | Some(DialectType::Databricks)
23957 | Some(DialectType::Hive)
23958 | Some(DialectType::Snowflake)
23959 | Some(DialectType::BigQuery)
23960 | Some(DialectType::Presto)
23961 | Some(DialectType::Trino)
23962 | Some(DialectType::ClickHouse)
23963 | Some(DialectType::Redshift) => {
23964 self.write_keyword("BOOLEAN");
23966 }
23967 _ => {
23968 self.write_keyword("BIT");
23969 if let Some(n) = length {
23970 self.write(&format!("({})", n));
23971 }
23972 }
23973 }
23974 }
23975 DataType::VarBit { length } => {
23976 self.write_keyword("VARBIT");
23977 if let Some(n) = length {
23978 self.write(&format!("({})", n));
23979 }
23980 }
23981 DataType::Date => self.write_keyword("DATE"),
23982 DataType::Time {
23983 precision,
23984 timezone,
23985 } => {
23986 if *timezone {
23987 match self.config.dialect {
23989 Some(DialectType::DuckDB) => {
23990 self.write_keyword("TIMETZ");
23992 }
23993 Some(DialectType::PostgreSQL) => {
23994 self.write_keyword("TIMETZ");
23996 if let Some(p) = precision {
23997 self.write(&format!("({})", p));
23998 }
23999 }
24000 _ => {
24001 self.write_keyword("TIME");
24003 if let Some(p) = precision {
24004 self.write(&format!("({})", p));
24005 }
24006 self.write_keyword(" WITH TIME ZONE");
24007 }
24008 }
24009 } else {
24010 if matches!(
24012 self.config.dialect,
24013 Some(DialectType::Spark)
24014 | Some(DialectType::Databricks)
24015 | Some(DialectType::Hive)
24016 ) {
24017 self.write_keyword("TIMESTAMP");
24018 } else {
24019 self.write_keyword("TIME");
24020 if let Some(p) = precision {
24021 self.write(&format!("({})", p));
24022 }
24023 }
24024 }
24025 }
24026 DataType::Timestamp {
24027 precision,
24028 timezone,
24029 } => {
24030 match self.config.dialect {
24032 Some(DialectType::Snowflake) if *timezone => {
24033 self.write_keyword("TIMESTAMPTZ");
24034 if let Some(p) = precision {
24035 self.write(&format!("({})", p));
24036 }
24037 }
24038 Some(DialectType::ClickHouse) => {
24039 self.write("DateTime");
24040 if let Some(p) = precision {
24041 self.write(&format!("({})", p));
24042 }
24043 }
24044 Some(DialectType::TSQL) => {
24045 if *timezone {
24046 self.write_keyword("DATETIMEOFFSET");
24047 } else {
24048 self.write_keyword("DATETIME2");
24049 }
24050 if let Some(p) = precision {
24051 self.write(&format!("({})", p));
24052 }
24053 }
24054 Some(DialectType::MySQL) => {
24055 self.write_keyword("TIMESTAMP");
24057 if let Some(p) = precision {
24058 self.write(&format!("({})", p));
24059 }
24060 }
24061 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
24062 self.write_keyword("DATETIME");
24064 if let Some(p) = precision {
24065 self.write(&format!("({})", p));
24066 }
24067 }
24068 Some(DialectType::BigQuery) => {
24069 if *timezone {
24071 self.write_keyword("TIMESTAMP");
24072 } else {
24073 self.write_keyword("DATETIME");
24074 }
24075 }
24076 Some(DialectType::DuckDB) => {
24077 if *timezone {
24079 self.write_keyword("TIMESTAMPTZ");
24080 } else {
24081 self.write_keyword("TIMESTAMP");
24082 if let Some(p) = precision {
24083 self.write(&format!("({})", p));
24084 }
24085 }
24086 }
24087 _ => {
24088 if *timezone && !self.config.tz_to_with_time_zone {
24089 self.write_keyword("TIMESTAMPTZ");
24091 if let Some(p) = precision {
24092 self.write(&format!("({})", p));
24093 }
24094 } else {
24095 self.write_keyword("TIMESTAMP");
24096 if let Some(p) = precision {
24097 self.write(&format!("({})", p));
24098 }
24099 if *timezone {
24100 self.write_space();
24101 self.write_keyword("WITH TIME ZONE");
24102 }
24103 }
24104 }
24105 }
24106 }
24107 DataType::Interval { unit, to } => {
24108 self.write_keyword("INTERVAL");
24109 if let Some(u) = unit {
24110 self.write_space();
24111 self.write_keyword(u);
24112 }
24113 if let Some(t) = to {
24115 self.write_space();
24116 self.write_keyword("TO");
24117 self.write_space();
24118 self.write_keyword(t);
24119 }
24120 }
24121 DataType::Json => {
24122 match self.config.dialect {
24124 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
24127 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
24128 _ => self.write_keyword("JSON"),
24129 }
24130 }
24131 DataType::JsonB => {
24132 match self.config.dialect {
24134 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
24135 Some(DialectType::Doris) => self.write_keyword("JSONB"),
24136 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
24137 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
24138 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
24141 }
24142 DataType::Uuid => {
24143 match self.config.dialect {
24145 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
24146 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
24147 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
24148 Some(DialectType::BigQuery)
24149 | Some(DialectType::Spark)
24150 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
24151 _ => self.write_keyword("UUID"),
24152 }
24153 }
24154 DataType::Array {
24155 element_type,
24156 dimension,
24157 } => {
24158 match self.config.dialect {
24160 Some(DialectType::PostgreSQL)
24161 | Some(DialectType::Redshift)
24162 | Some(DialectType::DuckDB) => {
24163 self.generate_data_type(element_type)?;
24165 if let Some(dim) = dimension {
24166 self.write(&format!("[{}]", dim));
24167 } else {
24168 self.write("[]");
24169 }
24170 }
24171 Some(DialectType::BigQuery) => {
24172 self.write_keyword("ARRAY<");
24173 self.generate_data_type(element_type)?;
24174 self.write(">");
24175 }
24176 Some(DialectType::Snowflake)
24177 | Some(DialectType::Presto)
24178 | Some(DialectType::Trino)
24179 | Some(DialectType::ClickHouse) => {
24180 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24182 self.write("Array(");
24183 } else {
24184 self.write_keyword("ARRAY(");
24185 }
24186 self.generate_data_type(element_type)?;
24187 self.write(")");
24188 }
24189 Some(DialectType::TSQL)
24190 | Some(DialectType::MySQL)
24191 | Some(DialectType::Oracle) => {
24192 match self.config.dialect {
24195 Some(DialectType::MySQL) => self.write_keyword("JSON"),
24196 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
24197 _ => self.write_keyword("JSON"),
24198 }
24199 }
24200 _ => {
24201 self.write_keyword("ARRAY<");
24203 self.generate_data_type(element_type)?;
24204 self.write(">");
24205 }
24206 }
24207 }
24208 DataType::List { element_type } => {
24209 self.generate_data_type(element_type)?;
24211 self.write_keyword(" LIST");
24212 }
24213 DataType::Map {
24214 key_type,
24215 value_type,
24216 } => {
24217 match self.config.dialect {
24219 Some(DialectType::Materialize) => {
24220 self.write_keyword("MAP[");
24222 self.generate_data_type(key_type)?;
24223 self.write(" => ");
24224 self.generate_data_type(value_type)?;
24225 self.write("]");
24226 }
24227 Some(DialectType::Snowflake)
24228 | Some(DialectType::RisingWave)
24229 | Some(DialectType::DuckDB)
24230 | Some(DialectType::Presto)
24231 | Some(DialectType::Trino)
24232 | Some(DialectType::Athena) => {
24233 self.write_keyword("MAP(");
24234 self.generate_data_type(key_type)?;
24235 self.write(", ");
24236 self.generate_data_type(value_type)?;
24237 self.write(")");
24238 }
24239 Some(DialectType::ClickHouse) => {
24240 self.write("Map(");
24243 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
24245 self.clickhouse_nullable_depth = 0;
24246 self.write(", ");
24247 self.generate_data_type(value_type)?;
24248 self.write(")");
24249 }
24250 _ => {
24251 self.write_keyword("MAP<");
24252 self.generate_data_type(key_type)?;
24253 self.write(", ");
24254 self.generate_data_type(value_type)?;
24255 self.write(">");
24256 }
24257 }
24258 }
24259 DataType::Vector {
24260 element_type,
24261 dimension,
24262 } => {
24263 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
24264 self.write_keyword("VECTOR(");
24266 if let Some(dim) = dimension {
24267 self.write(&dim.to_string());
24268 }
24269 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
24271 DataType::TinyInt { .. } => Some("I8"),
24272 DataType::SmallInt { .. } => Some("I16"),
24273 DataType::Int { .. } => Some("I32"),
24274 DataType::BigInt { .. } => Some("I64"),
24275 DataType::Float { .. } => Some("F32"),
24276 DataType::Double { .. } => Some("F64"),
24277 _ => None,
24278 });
24279 if let Some(alias) = type_alias {
24280 if dimension.is_some() {
24281 self.write(", ");
24282 }
24283 self.write(alias);
24284 }
24285 self.write(")");
24286 } else {
24287 self.write_keyword("VECTOR(");
24289 if let Some(ref et) = element_type {
24290 self.generate_data_type(et)?;
24291 if dimension.is_some() {
24292 self.write(", ");
24293 }
24294 }
24295 if let Some(dim) = dimension {
24296 self.write(&dim.to_string());
24297 }
24298 self.write(")");
24299 }
24300 }
24301 DataType::Object { fields, modifier } => {
24302 self.write_keyword("OBJECT(");
24303 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
24304 if i > 0 {
24305 self.write(", ");
24306 }
24307 self.write(name);
24308 self.write(" ");
24309 self.generate_data_type(dt)?;
24310 if *not_null {
24311 self.write_keyword(" NOT NULL");
24312 }
24313 }
24314 self.write(")");
24315 if let Some(mod_str) = modifier {
24316 self.write(" ");
24317 self.write_keyword(mod_str);
24318 }
24319 }
24320 DataType::Struct { fields, nested } => {
24321 match self.config.dialect {
24323 Some(DialectType::Snowflake) => {
24324 self.write_keyword("OBJECT(");
24326 for (i, field) in fields.iter().enumerate() {
24327 if i > 0 {
24328 self.write(", ");
24329 }
24330 if !field.name.is_empty() {
24331 self.write(&field.name);
24332 self.write(" ");
24333 }
24334 self.generate_data_type(&field.data_type)?;
24335 }
24336 self.write(")");
24337 }
24338 Some(DialectType::Presto) | Some(DialectType::Trino) => {
24339 self.write_keyword("ROW(");
24341 for (i, field) in fields.iter().enumerate() {
24342 if i > 0 {
24343 self.write(", ");
24344 }
24345 if !field.name.is_empty() {
24346 self.write(&field.name);
24347 self.write(" ");
24348 }
24349 self.generate_data_type(&field.data_type)?;
24350 }
24351 self.write(")");
24352 }
24353 Some(DialectType::DuckDB) => {
24354 self.write_keyword("STRUCT(");
24356 for (i, field) in fields.iter().enumerate() {
24357 if i > 0 {
24358 self.write(", ");
24359 }
24360 if !field.name.is_empty() {
24361 self.write(&field.name);
24362 self.write(" ");
24363 }
24364 self.generate_data_type(&field.data_type)?;
24365 }
24366 self.write(")");
24367 }
24368 Some(DialectType::ClickHouse) => {
24369 self.write("Tuple(");
24371 for (i, field) in fields.iter().enumerate() {
24372 if i > 0 {
24373 self.write(", ");
24374 }
24375 if !field.name.is_empty() {
24376 self.write(&field.name);
24377 self.write(" ");
24378 }
24379 self.generate_data_type(&field.data_type)?;
24380 }
24381 self.write(")");
24382 }
24383 Some(DialectType::SingleStore) => {
24384 self.write_keyword("RECORD(");
24386 for (i, field) in fields.iter().enumerate() {
24387 if i > 0 {
24388 self.write(", ");
24389 }
24390 if !field.name.is_empty() {
24391 self.write(&field.name);
24392 self.write(" ");
24393 }
24394 self.generate_data_type(&field.data_type)?;
24395 }
24396 self.write(")");
24397 }
24398 _ => {
24399 let force_angle_brackets = matches!(
24401 self.config.dialect,
24402 Some(DialectType::Hive)
24403 | Some(DialectType::Spark)
24404 | Some(DialectType::Databricks)
24405 );
24406 if *nested && !force_angle_brackets {
24407 self.write_keyword("STRUCT(");
24408 for (i, field) in fields.iter().enumerate() {
24409 if i > 0 {
24410 self.write(", ");
24411 }
24412 if !field.name.is_empty() {
24413 self.write(&field.name);
24414 self.write(" ");
24415 }
24416 self.generate_data_type(&field.data_type)?;
24417 }
24418 self.write(")");
24419 } else {
24420 self.write_keyword("STRUCT<");
24421 for (i, field) in fields.iter().enumerate() {
24422 if i > 0 {
24423 self.write(", ");
24424 }
24425 if !field.name.is_empty() {
24426 self.write(&field.name);
24428 self.write(self.config.struct_field_sep);
24429 }
24430 self.generate_data_type(&field.data_type)?;
24432 if let Some(comment) = &field.comment {
24434 self.write(" COMMENT '");
24435 self.write(comment);
24436 self.write("'");
24437 }
24438 if !field.options.is_empty() {
24440 self.write(" ");
24441 self.generate_options_clause(&field.options)?;
24442 }
24443 }
24444 self.write(">");
24445 }
24446 }
24447 }
24448 }
24449 DataType::Enum {
24450 values,
24451 assignments,
24452 } => {
24453 if self.config.dialect == Some(DialectType::ClickHouse) {
24456 self.write("Enum(");
24457 } else {
24458 self.write_keyword("ENUM(");
24459 }
24460 for (i, val) in values.iter().enumerate() {
24461 if i > 0 {
24462 self.write(", ");
24463 }
24464 self.write("'");
24465 self.write(val);
24466 self.write("'");
24467 if let Some(Some(assignment)) = assignments.get(i) {
24468 self.write(" = ");
24469 self.write(assignment);
24470 }
24471 }
24472 self.write(")");
24473 }
24474 DataType::Set { values } => {
24475 self.write_keyword("SET(");
24477 for (i, val) in values.iter().enumerate() {
24478 if i > 0 {
24479 self.write(", ");
24480 }
24481 self.write("'");
24482 self.write(val);
24483 self.write("'");
24484 }
24485 self.write(")");
24486 }
24487 DataType::Union { fields } => {
24488 self.write_keyword("UNION(");
24490 for (i, (name, dt)) in fields.iter().enumerate() {
24491 if i > 0 {
24492 self.write(", ");
24493 }
24494 if !name.is_empty() {
24495 self.write(name);
24496 self.write(" ");
24497 }
24498 self.generate_data_type(dt)?;
24499 }
24500 self.write(")");
24501 }
24502 DataType::Nullable { inner } => {
24503 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24505 self.write("Nullable(");
24506 let saved_depth = self.clickhouse_nullable_depth;
24508 self.clickhouse_nullable_depth = -1;
24509 self.generate_data_type(inner)?;
24510 self.clickhouse_nullable_depth = saved_depth;
24511 self.write(")");
24512 } else {
24513 match inner.as_ref() {
24515 DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
24516 self.generate_data_type(&DataType::Timestamp {
24517 precision: None,
24518 timezone: false,
24519 })?;
24520 }
24521 _ => {
24522 self.generate_data_type(inner)?;
24523 }
24524 }
24525 }
24526 }
24527 DataType::Custom { name } => {
24528 let name_upper = name.to_ascii_uppercase();
24530 match self.config.dialect {
24531 Some(DialectType::ClickHouse) => {
24532 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
24533 (name_upper[..idx].to_string(), &name[idx..])
24534 } else {
24535 (name_upper.clone(), "")
24536 };
24537 let mapped = match base_upper.as_str() {
24538 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
24539 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
24540 "DATETIME64" => "DateTime64",
24541 "DATE32" => "Date32",
24542 "INT" => "Int32",
24543 "MEDIUMINT" => "Int32",
24544 "INT8" => "Int8",
24545 "INT16" => "Int16",
24546 "INT32" => "Int32",
24547 "INT64" => "Int64",
24548 "INT128" => "Int128",
24549 "INT256" => "Int256",
24550 "UINT8" => "UInt8",
24551 "UINT16" => "UInt16",
24552 "UINT32" => "UInt32",
24553 "UINT64" => "UInt64",
24554 "UINT128" => "UInt128",
24555 "UINT256" => "UInt256",
24556 "FLOAT32" => "Float32",
24557 "FLOAT64" => "Float64",
24558 "DECIMAL32" => "Decimal32",
24559 "DECIMAL64" => "Decimal64",
24560 "DECIMAL128" => "Decimal128",
24561 "DECIMAL256" => "Decimal256",
24562 "ENUM" => "Enum",
24563 "ENUM8" => "Enum8",
24564 "ENUM16" => "Enum16",
24565 "FIXEDSTRING" => "FixedString",
24566 "NESTED" => "Nested",
24567 "LOWCARDINALITY" => "LowCardinality",
24568 "NULLABLE" => "Nullable",
24569 "IPV4" => "IPv4",
24570 "IPV6" => "IPv6",
24571 "POINT" => "Point",
24572 "RING" => "Ring",
24573 "LINESTRING" => "LineString",
24574 "MULTILINESTRING" => "MultiLineString",
24575 "POLYGON" => "Polygon",
24576 "MULTIPOLYGON" => "MultiPolygon",
24577 "AGGREGATEFUNCTION" => "AggregateFunction",
24578 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
24579 "DYNAMIC" => "Dynamic",
24580 _ => "",
24581 };
24582 if mapped.is_empty() {
24583 self.write(name);
24584 } else {
24585 self.write(mapped);
24586 if matches!(base_upper.as_str(), "ENUM8" | "ENUM16")
24587 && !suffix.is_empty()
24588 {
24589 let escaped_suffix = suffix
24590 .replace('\\', "\\\\")
24591 .replace('\t', "\\t")
24592 .replace('\n', "\\n")
24593 .replace('\r', "\\r");
24594 self.write(&escaped_suffix);
24595 } else {
24596 self.write(suffix);
24597 }
24598 }
24599 }
24600 Some(DialectType::MySQL)
24601 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
24602 {
24603 self.write_keyword("TIMESTAMP");
24605 }
24606 Some(DialectType::Snowflake) => {
24607 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
24608 (name_upper[..idx].to_string(), &name[idx..])
24609 } else {
24610 (name_upper.clone(), "")
24611 };
24612
24613 match base_upper.as_str() {
24614 "TIMESTAMPNTZ" | "TIMESTAMP_NTZ" => {
24615 self.write_keyword("TIMESTAMPNTZ");
24616 self.write(suffix);
24617 }
24618 "TIMESTAMPLTZ" | "TIMESTAMP_LTZ" => {
24619 self.write_keyword("TIMESTAMPLTZ");
24620 self.write(suffix);
24621 }
24622 "TIMESTAMPTZ" | "TIMESTAMP_TZ" => {
24623 self.write_keyword("TIMESTAMPTZ");
24624 self.write(suffix);
24625 }
24626 _ => self.write(name),
24627 }
24628 }
24629 Some(DialectType::Fabric) => {
24630 let (base_upper, args_str) = if let Some(idx) = name.find('(') {
24631 (name_upper[..idx].to_string(), Some(&name[idx..]))
24632 } else {
24633 (name_upper.clone(), None)
24634 };
24635
24636 match base_upper.as_str() {
24637 "NVARCHAR" => {
24638 self.write_keyword("VARCHAR");
24639 if let Some(args) = args_str {
24640 self.write(args);
24641 }
24642 }
24643 "NCHAR" => {
24644 self.write_keyword("CHAR");
24645 if let Some(args) = args_str {
24646 self.write(args);
24647 }
24648 }
24649 _ => self.write(name),
24650 }
24651 }
24652 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
24653 self.write_keyword("SQL_VARIANT");
24654 }
24655 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
24656 self.write_keyword("DECIMAL(38, 5)");
24657 }
24658 Some(DialectType::Exasol) => {
24659 match name_upper.as_str() {
24661 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
24663 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
24665 "MEDIUMINT" => self.write_keyword("INT"),
24667 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
24669 self.write_keyword("DECIMAL")
24670 }
24671 "DATETIME" => self.write_keyword("TIMESTAMP"),
24673 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
24674 _ => self.write(name),
24675 }
24676 }
24677 Some(DialectType::Dremio) => {
24678 match name_upper.as_str() {
24680 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
24681 "ARRAY" => self.write_keyword("LIST"),
24682 "NCHAR" => self.write_keyword("VARCHAR"),
24683 _ => self.write(name),
24684 }
24685 }
24686 _ => {
24688 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
24690 (name_upper[..idx].to_string(), Some(&name[idx..]))
24691 } else {
24692 (name_upper.clone(), None)
24693 };
24694
24695 match base_upper.as_str() {
24696 "INT64"
24697 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24698 {
24699 self.write_keyword("BIGINT");
24700 }
24701 "FLOAT64"
24702 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24703 {
24704 self.write_keyword("DOUBLE");
24705 }
24706 "BOOL"
24707 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24708 {
24709 self.write_keyword("BOOLEAN");
24710 }
24711 "BYTES"
24712 if matches!(
24713 self.config.dialect,
24714 Some(DialectType::Spark)
24715 | Some(DialectType::Hive)
24716 | Some(DialectType::Databricks)
24717 ) =>
24718 {
24719 self.write_keyword("BINARY");
24720 }
24721 "BYTES"
24722 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24723 {
24724 self.write_keyword("VARBINARY");
24725 }
24726 "DATETIME2" | "SMALLDATETIME"
24728 if !matches!(
24729 self.config.dialect,
24730 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24731 ) =>
24732 {
24733 if matches!(
24735 self.config.dialect,
24736 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
24737 ) {
24738 self.write_keyword("TIMESTAMP");
24739 if let Some(args) = _args_str {
24740 self.write(args);
24741 }
24742 } else {
24743 self.write_keyword("TIMESTAMP");
24744 }
24745 }
24746 "DATETIMEOFFSET"
24748 if !matches!(
24749 self.config.dialect,
24750 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24751 ) =>
24752 {
24753 if matches!(
24754 self.config.dialect,
24755 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
24756 ) {
24757 self.write_keyword("TIMESTAMPTZ");
24758 if let Some(args) = _args_str {
24759 self.write(args);
24760 }
24761 } else {
24762 self.write_keyword("TIMESTAMPTZ");
24763 }
24764 }
24765 "UNIQUEIDENTIFIER"
24767 if !matches!(
24768 self.config.dialect,
24769 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24770 ) =>
24771 {
24772 match self.config.dialect {
24773 Some(DialectType::Spark)
24774 | Some(DialectType::Databricks)
24775 | Some(DialectType::Hive) => self.write_keyword("STRING"),
24776 _ => self.write_keyword("UUID"),
24777 }
24778 }
24779 "BIT"
24781 if !matches!(
24782 self.config.dialect,
24783 Some(DialectType::TSQL)
24784 | Some(DialectType::Fabric)
24785 | Some(DialectType::PostgreSQL)
24786 | Some(DialectType::MySQL)
24787 | Some(DialectType::DuckDB)
24788 ) =>
24789 {
24790 self.write_keyword("BOOLEAN");
24791 }
24792 "NVARCHAR"
24794 if !matches!(
24795 self.config.dialect,
24796 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24797 ) =>
24798 {
24799 match self.config.dialect {
24800 Some(DialectType::Oracle) => {
24801 self.write_keyword("NVARCHAR2");
24803 if let Some(args) = _args_str {
24804 self.write(args);
24805 }
24806 }
24807 Some(DialectType::BigQuery) => {
24808 self.write_keyword("STRING");
24810 }
24811 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
24812 self.write_keyword("TEXT");
24813 if let Some(args) = _args_str {
24814 self.write(args);
24815 }
24816 }
24817 Some(DialectType::Hive) => {
24818 self.write_keyword("STRING");
24820 }
24821 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
24822 if _args_str.is_some() {
24823 self.write_keyword("VARCHAR");
24824 self.write(_args_str.unwrap());
24825 } else {
24826 self.write_keyword("STRING");
24827 }
24828 }
24829 _ => {
24830 self.write_keyword("VARCHAR");
24831 if let Some(args) = _args_str {
24832 self.write(args);
24833 }
24834 }
24835 }
24836 }
24837 "NCHAR"
24839 if !matches!(
24840 self.config.dialect,
24841 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24842 ) =>
24843 {
24844 match self.config.dialect {
24845 Some(DialectType::Oracle) => {
24846 self.write_keyword("NCHAR");
24848 if let Some(args) = _args_str {
24849 self.write(args);
24850 }
24851 }
24852 Some(DialectType::BigQuery) => {
24853 self.write_keyword("STRING");
24855 }
24856 Some(DialectType::Hive) => {
24857 self.write_keyword("STRING");
24859 }
24860 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
24861 self.write_keyword("TEXT");
24862 if let Some(args) = _args_str {
24863 self.write(args);
24864 }
24865 }
24866 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
24867 if _args_str.is_some() {
24868 self.write_keyword("CHAR");
24869 self.write(_args_str.unwrap());
24870 } else {
24871 self.write_keyword("STRING");
24872 }
24873 }
24874 _ => {
24875 self.write_keyword("CHAR");
24876 if let Some(args) = _args_str {
24877 self.write(args);
24878 }
24879 }
24880 }
24881 }
24882 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
24885 Some(DialectType::MySQL)
24886 | Some(DialectType::SingleStore)
24887 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
24888 Some(DialectType::Spark)
24889 | Some(DialectType::Databricks)
24890 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
24891 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
24892 Some(DialectType::Presto)
24893 | Some(DialectType::Trino)
24894 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
24895 Some(DialectType::Snowflake)
24896 | Some(DialectType::Redshift)
24897 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
24898 _ => self.write_keyword("TEXT"),
24899 },
24900 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
24903 Some(DialectType::MySQL)
24904 | Some(DialectType::SingleStore)
24905 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
24906 Some(DialectType::Spark)
24907 | Some(DialectType::Databricks)
24908 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
24909 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
24910 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
24911 Some(DialectType::Presto)
24912 | Some(DialectType::Trino)
24913 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
24914 Some(DialectType::Snowflake)
24915 | Some(DialectType::Redshift)
24916 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
24917 _ => self.write_keyword("BLOB"),
24918 },
24919 "LONGVARCHAR" => match self.config.dialect {
24921 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
24922 _ => self.write_keyword("VARCHAR"),
24923 },
24924 "DATETIME" => {
24926 match self.config.dialect {
24927 Some(DialectType::MySQL)
24928 | Some(DialectType::Doris)
24929 | Some(DialectType::StarRocks)
24930 | Some(DialectType::TSQL)
24931 | Some(DialectType::Fabric)
24932 | Some(DialectType::BigQuery)
24933 | Some(DialectType::SQLite)
24934 | Some(DialectType::Snowflake) => {
24935 self.write_keyword("DATETIME");
24936 if let Some(args) = _args_str {
24937 self.write(args);
24938 }
24939 }
24940 Some(_) => {
24941 self.write_keyword("TIMESTAMP");
24943 if let Some(args) = _args_str {
24944 self.write(args);
24945 }
24946 }
24947 None => {
24948 self.write(name);
24950 }
24951 }
24952 }
24953 "VARCHAR2"
24955 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
24956 {
24957 match self.config.dialect {
24958 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24959 self.write_keyword("TEXT");
24960 }
24961 Some(DialectType::Hive)
24962 | Some(DialectType::Spark)
24963 | Some(DialectType::Databricks)
24964 | Some(DialectType::BigQuery)
24965 | Some(DialectType::ClickHouse)
24966 | Some(DialectType::StarRocks)
24967 | Some(DialectType::Doris) => {
24968 self.write_keyword("STRING");
24969 }
24970 _ => {
24971 self.write_keyword("VARCHAR");
24972 if let Some(args) = _args_str {
24973 self.write(args);
24974 }
24975 }
24976 }
24977 }
24978 "NVARCHAR2"
24979 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
24980 {
24981 match self.config.dialect {
24982 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24983 self.write_keyword("TEXT");
24984 }
24985 Some(DialectType::Hive)
24986 | Some(DialectType::Spark)
24987 | Some(DialectType::Databricks)
24988 | Some(DialectType::BigQuery)
24989 | Some(DialectType::ClickHouse)
24990 | Some(DialectType::StarRocks)
24991 | Some(DialectType::Doris) => {
24992 self.write_keyword("STRING");
24993 }
24994 _ => {
24995 self.write_keyword("VARCHAR");
24996 if let Some(args) = _args_str {
24997 self.write(args);
24998 }
24999 }
25000 }
25001 }
25002 _ => self.write(name),
25003 }
25004 }
25005 }
25006 }
25007 DataType::Geometry { subtype, srid } => {
25008 match self.config.dialect {
25010 Some(DialectType::MySQL) => {
25011 if let Some(sub) = subtype {
25013 self.write_keyword(sub);
25014 if let Some(s) = srid {
25015 self.write(" SRID ");
25016 self.write(&s.to_string());
25017 }
25018 } else {
25019 self.write_keyword("GEOMETRY");
25020 }
25021 }
25022 Some(DialectType::BigQuery) => {
25023 self.write_keyword("GEOGRAPHY");
25025 }
25026 Some(DialectType::Teradata) => {
25027 self.write_keyword("ST_GEOMETRY");
25029 if subtype.is_some() || srid.is_some() {
25030 self.write("(");
25031 if let Some(sub) = subtype {
25032 self.write_keyword(sub);
25033 }
25034 if let Some(s) = srid {
25035 if subtype.is_some() {
25036 self.write(", ");
25037 }
25038 self.write(&s.to_string());
25039 }
25040 self.write(")");
25041 }
25042 }
25043 _ => {
25044 self.write_keyword("GEOMETRY");
25046 if subtype.is_some() || srid.is_some() {
25047 self.write("(");
25048 if let Some(sub) = subtype {
25049 self.write_keyword(sub);
25050 }
25051 if let Some(s) = srid {
25052 if subtype.is_some() {
25053 self.write(", ");
25054 }
25055 self.write(&s.to_string());
25056 }
25057 self.write(")");
25058 }
25059 }
25060 }
25061 }
25062 DataType::Geography { subtype, srid } => {
25063 match self.config.dialect {
25065 Some(DialectType::MySQL) => {
25066 if let Some(sub) = subtype {
25068 self.write_keyword(sub);
25069 } else {
25070 self.write_keyword("GEOMETRY");
25071 }
25072 let effective_srid = srid.unwrap_or(4326);
25074 self.write(" SRID ");
25075 self.write(&effective_srid.to_string());
25076 }
25077 Some(DialectType::BigQuery) => {
25078 self.write_keyword("GEOGRAPHY");
25080 }
25081 Some(DialectType::Snowflake) => {
25082 self.write_keyword("GEOGRAPHY");
25084 }
25085 _ => {
25086 self.write_keyword("GEOGRAPHY");
25088 if subtype.is_some() || srid.is_some() {
25089 self.write("(");
25090 if let Some(sub) = subtype {
25091 self.write_keyword(sub);
25092 }
25093 if let Some(s) = srid {
25094 if subtype.is_some() {
25095 self.write(", ");
25096 }
25097 self.write(&s.to_string());
25098 }
25099 self.write(")");
25100 }
25101 }
25102 }
25103 }
25104 DataType::CharacterSet { name } => {
25105 self.write_keyword("CHAR CHARACTER SET ");
25107 self.write(name);
25108 }
25109 _ => self.write("UNKNOWN"),
25110 }
25111 Ok(())
25112 }
25113
25114 #[inline]
25117 fn write(&mut self, s: &str) {
25118 self.output.push_str(s);
25119 }
25120
25121 #[inline]
25122 fn write_space(&mut self) {
25123 self.output.push(' ');
25124 }
25125
25126 #[inline]
25127 fn write_keyword(&mut self, keyword: &str) {
25128 if self.config.uppercase_keywords {
25129 self.output.push_str(keyword);
25130 } else {
25131 for b in keyword.bytes() {
25132 self.output.push(b.to_ascii_lowercase() as char);
25133 }
25134 }
25135 }
25136
25137 fn write_func_name(&mut self, name: &str) {
25139 let normalized = self.normalize_func_name(name);
25140 self.output.push_str(normalized.as_ref());
25141 }
25142
25143 fn convert_strptime_to_exasol_format(format: &str) -> String {
25147 let mut result = String::new();
25148 let chars: Vec<char> = format.chars().collect();
25149 let mut i = 0;
25150 while i < chars.len() {
25151 if chars[i] == '%' && i + 1 < chars.len() {
25152 let spec = chars[i + 1];
25153 let exasol_spec = match spec {
25154 'Y' => "YYYY",
25155 'y' => "YY",
25156 'm' => "MM",
25157 'd' => "DD",
25158 'H' => "HH",
25159 'M' => "MI",
25160 'S' => "SS",
25161 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
25173 result.push('%');
25175 result.push(spec);
25176 i += 2;
25177 continue;
25178 }
25179 };
25180 result.push_str(exasol_spec);
25181 i += 2;
25182 } else {
25183 result.push(chars[i]);
25184 i += 1;
25185 }
25186 }
25187 result
25188 }
25189
25190 fn convert_strptime_to_postgres_format(format: &str) -> String {
25194 let mut result = String::new();
25195 let chars: Vec<char> = format.chars().collect();
25196 let mut i = 0;
25197 while i < chars.len() {
25198 if chars[i] == '%' && i + 1 < chars.len() {
25199 if chars[i + 1] == '-' && i + 2 < chars.len() {
25201 let spec = chars[i + 2];
25202 let pg_spec = match spec {
25203 'd' => "FMDD",
25204 'm' => "FMMM",
25205 'H' => "FMHH24",
25206 'M' => "FMMI",
25207 'S' => "FMSS",
25208 _ => {
25209 result.push('%');
25210 result.push('-');
25211 result.push(spec);
25212 i += 3;
25213 continue;
25214 }
25215 };
25216 result.push_str(pg_spec);
25217 i += 3;
25218 continue;
25219 }
25220 let spec = chars[i + 1];
25221 let pg_spec = match spec {
25222 'Y' => "YYYY",
25223 'y' => "YY",
25224 'm' => "MM",
25225 'd' => "DD",
25226 'H' => "HH24",
25227 'I' => "HH12",
25228 'M' => "MI",
25229 'S' => "SS",
25230 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
25241 result.push('%');
25243 result.push(spec);
25244 i += 2;
25245 continue;
25246 }
25247 };
25248 result.push_str(pg_spec);
25249 i += 2;
25250 } else {
25251 result.push(chars[i]);
25252 i += 1;
25253 }
25254 }
25255 result
25256 }
25257
25258 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
25260 if self.config.limit_only_literals {
25261 if let Some(value) = Self::try_evaluate_constant(expr) {
25262 self.write(&value.to_string());
25263 return Ok(());
25264 }
25265 }
25266 self.generate_expression(expr)
25267 }
25268
25269 fn write_formatted_comment(&mut self, comment: &str) {
25273 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
25276 &comment[2..comment.len() - 2]
25279 } else if comment.starts_with("--") {
25280 &comment[2..]
25283 } else {
25284 comment
25286 };
25287 if content.trim().is_empty() {
25289 return;
25290 }
25291 let sanitized = content.replace("*/", "* /").replace("/*", "/ *");
25294 let content = &sanitized;
25295 self.output.push_str("/*");
25297 if !content.starts_with(' ') {
25298 self.output.push(' ');
25299 }
25300 self.output.push_str(content);
25301 if !content.ends_with(' ') {
25302 self.output.push(' ');
25303 }
25304 self.output.push_str("*/");
25305 }
25306
25307 fn escape_block_for_single_quote(&self, block: &str) -> String {
25310 let escape_backslash = matches!(
25311 self.config.dialect,
25312 Some(crate::dialects::DialectType::Snowflake)
25313 );
25314 let mut escaped = String::with_capacity(block.len() + 4);
25315 for ch in block.chars() {
25316 if ch == '\'' {
25317 escaped.push('\\');
25318 escaped.push('\'');
25319 } else if escape_backslash && ch == '\\' {
25320 escaped.push('\\');
25321 escaped.push('\\');
25322 } else {
25323 escaped.push(ch);
25324 }
25325 }
25326 escaped
25327 }
25328
25329 fn write_newline(&mut self) {
25330 self.output.push('\n');
25331 }
25332
25333 fn write_indent(&mut self) {
25334 for _ in 0..self.indent_level {
25335 self.output.push_str(self.config.indent);
25336 }
25337 }
25338
25339 fn too_wide(&self, args: &[String]) -> bool {
25345 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
25346 }
25347
25348 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
25351 let config = GeneratorConfig {
25352 pretty: false,
25353 dialect: self.config.dialect,
25354 ..Default::default()
25355 };
25356 let mut gen = Generator::with_config(config);
25357 gen.generate_expression(expr)?;
25358 Ok(gen.output)
25359 }
25360
25361 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
25364 if self.config.pretty {
25365 self.write_newline();
25366 self.write_indent();
25367 self.write_keyword(keyword);
25368 self.write_newline();
25369 self.indent_level += 1;
25370 self.write_indent();
25371 self.generate_expression(condition)?;
25372 self.indent_level -= 1;
25373 } else {
25374 self.write_space();
25375 self.write_keyword(keyword);
25376 self.write_space();
25377 self.generate_expression(condition)?;
25378 }
25379 Ok(())
25380 }
25381
25382 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
25385 if exprs.is_empty() {
25386 return Ok(());
25387 }
25388
25389 if self.config.pretty {
25390 self.write_newline();
25391 self.write_indent();
25392 self.write_keyword(keyword);
25393 self.write_newline();
25394 self.indent_level += 1;
25395 for (i, expr) in exprs.iter().enumerate() {
25396 if i > 0 {
25397 self.write(",");
25398 self.write_newline();
25399 }
25400 self.write_indent();
25401 self.generate_expression(expr)?;
25402 }
25403 self.indent_level -= 1;
25404 } else {
25405 self.write_space();
25406 self.write_keyword(keyword);
25407 self.write_space();
25408 for (i, expr) in exprs.iter().enumerate() {
25409 if i > 0 {
25410 self.write(", ");
25411 }
25412 self.generate_expression(expr)?;
25413 }
25414 }
25415 Ok(())
25416 }
25417
25418 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
25420 if orderings.is_empty() {
25421 return Ok(());
25422 }
25423
25424 if self.config.pretty {
25425 self.write_newline();
25426 self.write_indent();
25427 self.write_keyword(keyword);
25428 self.write_newline();
25429 self.indent_level += 1;
25430 for (i, ordered) in orderings.iter().enumerate() {
25431 if i > 0 {
25432 self.write(",");
25433 self.write_newline();
25434 }
25435 self.write_indent();
25436 self.generate_ordered(ordered)?;
25437 }
25438 self.indent_level -= 1;
25439 } else {
25440 self.write_space();
25441 self.write_keyword(keyword);
25442 self.write_space();
25443 for (i, ordered) in orderings.iter().enumerate() {
25444 if i > 0 {
25445 self.write(", ");
25446 }
25447 self.generate_ordered(ordered)?;
25448 }
25449 }
25450 Ok(())
25451 }
25452
25453 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
25455 if windows.is_empty() {
25456 return Ok(());
25457 }
25458
25459 if self.config.pretty {
25460 self.write_newline();
25461 self.write_indent();
25462 self.write_keyword("WINDOW");
25463 self.write_newline();
25464 self.indent_level += 1;
25465 for (i, named_window) in windows.iter().enumerate() {
25466 if i > 0 {
25467 self.write(",");
25468 self.write_newline();
25469 }
25470 self.write_indent();
25471 self.generate_identifier(&named_window.name)?;
25472 self.write_space();
25473 self.write_keyword("AS");
25474 self.write(" (");
25475 self.generate_over(&named_window.spec)?;
25476 self.write(")");
25477 }
25478 self.indent_level -= 1;
25479 } else {
25480 self.write_space();
25481 self.write_keyword("WINDOW");
25482 self.write_space();
25483 for (i, named_window) in windows.iter().enumerate() {
25484 if i > 0 {
25485 self.write(", ");
25486 }
25487 self.generate_identifier(&named_window.name)?;
25488 self.write_space();
25489 self.write_keyword("AS");
25490 self.write(" (");
25491 self.generate_over(&named_window.spec)?;
25492 self.write(")");
25493 }
25494 }
25495 Ok(())
25496 }
25497
25498 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
25500 self.write_keyword("AI_AGG");
25502 self.write("(");
25503 self.generate_expression(&e.this)?;
25504 self.write(", ");
25505 self.generate_expression(&e.expression)?;
25506 self.write(")");
25507 Ok(())
25508 }
25509
25510 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
25511 self.write_keyword("AI_CLASSIFY");
25513 self.write("(");
25514 self.generate_expression(&e.this)?;
25515 if let Some(categories) = &e.categories {
25516 self.write(", ");
25517 self.generate_expression(categories)?;
25518 }
25519 if let Some(config) = &e.config {
25520 self.write(", ");
25521 self.generate_expression(config)?;
25522 }
25523 self.write(")");
25524 Ok(())
25525 }
25526
25527 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
25528 self.write_keyword("ADD");
25530 self.write_space();
25531 if e.exists {
25532 self.write_keyword("IF NOT EXISTS");
25533 self.write_space();
25534 }
25535 self.generate_expression(&e.this)?;
25536 if let Some(location) = &e.location {
25537 self.write_space();
25538 self.generate_expression(location)?;
25539 }
25540 Ok(())
25541 }
25542
25543 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
25544 self.write_keyword("ALGORITHM");
25546 self.write("=");
25547 self.generate_expression(&e.this)?;
25548 Ok(())
25549 }
25550
25551 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
25552 self.generate_expression(&e.this)?;
25554 self.write_space();
25555 self.write_keyword("AS");
25556 self.write(" (");
25557 for (i, expr) in e.expressions.iter().enumerate() {
25558 if i > 0 {
25559 self.write(", ");
25560 }
25561 self.generate_expression(expr)?;
25562 }
25563 self.write(")");
25564 Ok(())
25565 }
25566
25567 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
25568 self.write_keyword("ALLOWED_VALUES");
25570 self.write_space();
25571 for (i, expr) in e.expressions.iter().enumerate() {
25572 if i > 0 {
25573 self.write(", ");
25574 }
25575 self.generate_expression(expr)?;
25576 }
25577 Ok(())
25578 }
25579
25580 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
25581 self.write_keyword("ALTER COLUMN");
25583 self.write_space();
25584 self.generate_expression(&e.this)?;
25585
25586 if let Some(dtype) = &e.dtype {
25587 self.write_space();
25588 self.write_keyword("SET DATA TYPE");
25589 self.write_space();
25590 self.generate_expression(dtype)?;
25591 if let Some(collate) = &e.collate {
25592 self.write_space();
25593 self.write_keyword("COLLATE");
25594 self.write_space();
25595 self.generate_expression(collate)?;
25596 }
25597 if let Some(using) = &e.using {
25598 self.write_space();
25599 self.write_keyword("USING");
25600 self.write_space();
25601 self.generate_expression(using)?;
25602 }
25603 } else if let Some(default) = &e.default {
25604 self.write_space();
25605 self.write_keyword("SET DEFAULT");
25606 self.write_space();
25607 self.generate_expression(default)?;
25608 } else if let Some(comment) = &e.comment {
25609 self.write_space();
25610 self.write_keyword("COMMENT");
25611 self.write_space();
25612 self.generate_expression(comment)?;
25613 } else if let Some(drop) = &e.drop {
25614 self.write_space();
25615 self.write_keyword("DROP");
25616 self.write_space();
25617 self.generate_expression(drop)?;
25618 } else if let Some(visible) = &e.visible {
25619 self.write_space();
25620 self.generate_expression(visible)?;
25621 } else if let Some(rename_to) = &e.rename_to {
25622 self.write_space();
25623 self.write_keyword("RENAME TO");
25624 self.write_space();
25625 self.generate_expression(rename_to)?;
25626 } else if let Some(allow_null) = &e.allow_null {
25627 self.write_space();
25628 self.generate_expression(allow_null)?;
25629 }
25630 Ok(())
25631 }
25632
25633 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
25634 self.write_keyword("ALTER SESSION");
25636 self.write_space();
25637 if e.unset.is_some() {
25638 self.write_keyword("UNSET");
25639 } else {
25640 self.write_keyword("SET");
25641 }
25642 self.write_space();
25643 for (i, expr) in e.expressions.iter().enumerate() {
25644 if i > 0 {
25645 self.write(", ");
25646 }
25647 self.generate_expression(expr)?;
25648 }
25649 Ok(())
25650 }
25651
25652 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
25653 self.write_keyword("SET");
25655
25656 if let Some(opt) = &e.option {
25658 self.write_space();
25659 self.generate_expression(opt)?;
25660 }
25661
25662 if !e.expressions.is_empty() {
25665 let is_properties = e
25667 .expressions
25668 .iter()
25669 .any(|expr| matches!(expr, Expression::Eq(_)));
25670 if is_properties && e.option.is_none() {
25671 self.write_space();
25672 self.write_keyword("PROPERTIES");
25673 }
25674 self.write_space();
25675 for (i, expr) in e.expressions.iter().enumerate() {
25676 if i > 0 {
25677 self.write(", ");
25678 }
25679 self.generate_expression(expr)?;
25680 }
25681 }
25682
25683 if let Some(file_format) = &e.file_format {
25685 self.write(" ");
25686 self.write_keyword("STAGE_FILE_FORMAT");
25687 self.write(" = (");
25688 self.generate_space_separated_properties(file_format)?;
25689 self.write(")");
25690 }
25691
25692 if let Some(copy_options) = &e.copy_options {
25694 self.write(" ");
25695 self.write_keyword("STAGE_COPY_OPTIONS");
25696 self.write(" = (");
25697 self.generate_space_separated_properties(copy_options)?;
25698 self.write(")");
25699 }
25700
25701 if let Some(tag) = &e.tag {
25703 self.write(" ");
25704 self.write_keyword("TAG");
25705 self.write(" ");
25706 self.generate_expression(tag)?;
25707 }
25708
25709 Ok(())
25710 }
25711
25712 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
25714 match expr {
25715 Expression::Tuple(t) => {
25716 for (i, prop) in t.expressions.iter().enumerate() {
25717 if i > 0 {
25718 self.write(" ");
25719 }
25720 self.generate_expression(prop)?;
25721 }
25722 }
25723 _ => {
25724 self.generate_expression(expr)?;
25725 }
25726 }
25727 Ok(())
25728 }
25729
25730 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
25731 self.write_keyword("ALTER");
25733 if e.compound.is_some() {
25734 self.write_space();
25735 self.write_keyword("COMPOUND");
25736 }
25737 self.write_space();
25738 self.write_keyword("SORTKEY");
25739 self.write_space();
25740 if let Some(this) = &e.this {
25741 self.generate_expression(this)?;
25742 } else if !e.expressions.is_empty() {
25743 self.write("(");
25744 for (i, expr) in e.expressions.iter().enumerate() {
25745 if i > 0 {
25746 self.write(", ");
25747 }
25748 self.generate_expression(expr)?;
25749 }
25750 self.write(")");
25751 }
25752 Ok(())
25753 }
25754
25755 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
25756 self.write_keyword("ANALYZE");
25758 if !e.options.is_empty() {
25759 self.write_space();
25760 for (i, opt) in e.options.iter().enumerate() {
25761 if i > 0 {
25762 self.write_space();
25763 }
25764 if let Expression::Identifier(id) = opt {
25766 self.write_keyword(&id.name);
25767 } else {
25768 self.generate_expression(opt)?;
25769 }
25770 }
25771 }
25772 if let Some(kind) = &e.kind {
25773 self.write_space();
25774 self.write_keyword(kind);
25775 }
25776 if let Some(this) = &e.this {
25777 self.write_space();
25778 self.generate_expression(this)?;
25779 }
25780 if !e.columns.is_empty() {
25782 self.write("(");
25783 for (i, col) in e.columns.iter().enumerate() {
25784 if i > 0 {
25785 self.write(", ");
25786 }
25787 self.write(col);
25788 }
25789 self.write(")");
25790 }
25791 if let Some(partition) = &e.partition {
25792 self.write_space();
25793 self.generate_expression(partition)?;
25794 }
25795 if let Some(mode) = &e.mode {
25796 self.write_space();
25797 self.generate_expression(mode)?;
25798 }
25799 if let Some(expression) = &e.expression {
25800 self.write_space();
25801 self.generate_expression(expression)?;
25802 }
25803 if !e.properties.is_empty() {
25804 self.write_space();
25805 self.write_keyword(self.config.with_properties_prefix);
25806 self.write(" (");
25807 for (i, prop) in e.properties.iter().enumerate() {
25808 if i > 0 {
25809 self.write(", ");
25810 }
25811 self.generate_expression(prop)?;
25812 }
25813 self.write(")");
25814 }
25815 Ok(())
25816 }
25817
25818 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
25819 self.write_keyword("DELETE");
25821 if let Some(kind) = &e.kind {
25822 self.write_space();
25823 self.write_keyword(kind);
25824 }
25825 self.write_space();
25826 self.write_keyword("STATISTICS");
25827 Ok(())
25828 }
25829
25830 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
25831 if let Expression::Identifier(id) = e.this.as_ref() {
25834 self.write_keyword(&id.name);
25835 } else {
25836 self.generate_expression(&e.this)?;
25837 }
25838 self.write_space();
25839 self.write_keyword("HISTOGRAM ON");
25840 self.write_space();
25841 for (i, expr) in e.expressions.iter().enumerate() {
25842 if i > 0 {
25843 self.write(", ");
25844 }
25845 self.generate_expression(expr)?;
25846 }
25847 if let Some(expression) = &e.expression {
25848 self.write_space();
25849 self.generate_expression(expression)?;
25850 }
25851 if let Some(update_options) = &e.update_options {
25852 self.write_space();
25853 self.generate_expression(update_options)?;
25854 self.write_space();
25855 self.write_keyword("UPDATE");
25856 }
25857 Ok(())
25858 }
25859
25860 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
25861 self.write_keyword("LIST CHAINED ROWS");
25863 if let Some(expression) = &e.expression {
25864 self.write_space();
25865 self.write_keyword("INTO");
25866 self.write_space();
25867 self.generate_expression(expression)?;
25868 }
25869 Ok(())
25870 }
25871
25872 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
25873 self.write_keyword("SAMPLE");
25875 self.write_space();
25876 if let Some(sample) = &e.sample {
25877 self.generate_expression(sample)?;
25878 self.write_space();
25879 }
25880 self.write_keyword(&e.kind);
25881 Ok(())
25882 }
25883
25884 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
25885 self.write_keyword(&e.kind);
25887 if let Some(option) = &e.option {
25888 self.write_space();
25889 self.generate_expression(option)?;
25890 }
25891 self.write_space();
25892 self.write_keyword("STATISTICS");
25893 if let Some(this) = &e.this {
25894 self.write_space();
25895 self.generate_expression(this)?;
25896 }
25897 if !e.expressions.is_empty() {
25898 self.write_space();
25899 for (i, expr) in e.expressions.iter().enumerate() {
25900 if i > 0 {
25901 self.write(", ");
25902 }
25903 self.generate_expression(expr)?;
25904 }
25905 }
25906 Ok(())
25907 }
25908
25909 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
25910 self.write_keyword("VALIDATE");
25912 self.write_space();
25913 self.write_keyword(&e.kind);
25914 if let Some(this) = &e.this {
25915 self.write_space();
25916 if let Expression::Identifier(id) = this.as_ref() {
25918 self.write_keyword(&id.name);
25919 } else {
25920 self.generate_expression(this)?;
25921 }
25922 }
25923 if let Some(expression) = &e.expression {
25924 self.write_space();
25925 self.write_keyword("INTO");
25926 self.write_space();
25927 self.generate_expression(expression)?;
25928 }
25929 Ok(())
25930 }
25931
25932 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
25933 self.write_keyword("WITH");
25935 self.write_space();
25936 for (i, expr) in e.expressions.iter().enumerate() {
25937 if i > 0 {
25938 self.write(", ");
25939 }
25940 self.generate_expression(expr)?;
25941 }
25942 Ok(())
25943 }
25944
25945 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
25946 self.generate_expression(&e.this)?;
25949 self.write("(");
25950 for (i, arg) in e.expressions.iter().enumerate() {
25951 if i > 0 {
25952 self.write(", ");
25953 }
25954 self.generate_expression(arg)?;
25955 }
25956 self.write(")");
25957 Ok(())
25958 }
25959
25960 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
25961 self.generate_expression(&e.this)?;
25963 self.write("(");
25964 for (i, arg) in e.expressions.iter().enumerate() {
25965 if i > 0 {
25966 self.write(", ");
25967 }
25968 self.generate_expression(arg)?;
25969 }
25970 self.write(")");
25971 Ok(())
25972 }
25973
25974 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
25975 self.generate_expression(&e.this)?;
25977 self.write_space();
25978 self.write_keyword("APPLY");
25979 self.write("(");
25980 self.generate_expression(&e.expression)?;
25981 self.write(")");
25982 Ok(())
25983 }
25984
25985 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
25986 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
25988 self.write("(");
25989 self.generate_expression(&e.this)?;
25990 if let Some(percentile) = &e.percentile {
25991 self.write(", ");
25992 self.generate_expression(percentile)?;
25993 }
25994 self.write(")");
25995 Ok(())
25996 }
25997
25998 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
25999 self.write_keyword("APPROX_QUANTILE");
26001 self.write("(");
26002 self.generate_expression(&e.this)?;
26003 if let Some(quantile) = &e.quantile {
26004 self.write(", ");
26005 self.generate_expression(quantile)?;
26006 }
26007 if let Some(accuracy) = &e.accuracy {
26008 self.write(", ");
26009 self.generate_expression(accuracy)?;
26010 }
26011 if let Some(weight) = &e.weight {
26012 self.write(", ");
26013 self.generate_expression(weight)?;
26014 }
26015 self.write(")");
26016 Ok(())
26017 }
26018
26019 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
26020 self.write_keyword("APPROX_QUANTILES");
26022 self.write("(");
26023 self.generate_expression(&e.this)?;
26024 if let Some(expression) = &e.expression {
26025 self.write(", ");
26026 self.generate_expression(expression)?;
26027 }
26028 self.write(")");
26029 Ok(())
26030 }
26031
26032 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
26033 self.write_keyword("APPROX_TOP_K");
26035 self.write("(");
26036 self.generate_expression(&e.this)?;
26037 if let Some(expression) = &e.expression {
26038 self.write(", ");
26039 self.generate_expression(expression)?;
26040 }
26041 if let Some(counters) = &e.counters {
26042 self.write(", ");
26043 self.generate_expression(counters)?;
26044 }
26045 self.write(")");
26046 Ok(())
26047 }
26048
26049 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
26050 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
26052 self.write("(");
26053 self.generate_expression(&e.this)?;
26054 if let Some(expression) = &e.expression {
26055 self.write(", ");
26056 self.generate_expression(expression)?;
26057 }
26058 self.write(")");
26059 Ok(())
26060 }
26061
26062 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
26063 self.write_keyword("APPROX_TOP_K_COMBINE");
26065 self.write("(");
26066 self.generate_expression(&e.this)?;
26067 if let Some(expression) = &e.expression {
26068 self.write(", ");
26069 self.generate_expression(expression)?;
26070 }
26071 self.write(")");
26072 Ok(())
26073 }
26074
26075 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
26076 self.write_keyword("APPROX_TOP_K_ESTIMATE");
26078 self.write("(");
26079 self.generate_expression(&e.this)?;
26080 if let Some(expression) = &e.expression {
26081 self.write(", ");
26082 self.generate_expression(expression)?;
26083 }
26084 self.write(")");
26085 Ok(())
26086 }
26087
26088 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
26089 self.write_keyword("APPROX_TOP_SUM");
26091 self.write("(");
26092 self.generate_expression(&e.this)?;
26093 self.write(", ");
26094 self.generate_expression(&e.expression)?;
26095 if let Some(count) = &e.count {
26096 self.write(", ");
26097 self.generate_expression(count)?;
26098 }
26099 self.write(")");
26100 Ok(())
26101 }
26102
26103 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
26104 self.write_keyword("ARG_MAX");
26106 self.write("(");
26107 self.generate_expression(&e.this)?;
26108 self.write(", ");
26109 self.generate_expression(&e.expression)?;
26110 if let Some(count) = &e.count {
26111 self.write(", ");
26112 self.generate_expression(count)?;
26113 }
26114 self.write(")");
26115 Ok(())
26116 }
26117
26118 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
26119 self.write_keyword("ARG_MIN");
26121 self.write("(");
26122 self.generate_expression(&e.this)?;
26123 self.write(", ");
26124 self.generate_expression(&e.expression)?;
26125 if let Some(count) = &e.count {
26126 self.write(", ");
26127 self.generate_expression(count)?;
26128 }
26129 self.write(")");
26130 Ok(())
26131 }
26132
26133 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
26134 self.write_keyword("ARRAY_ALL");
26136 self.write("(");
26137 self.generate_expression(&e.this)?;
26138 self.write(", ");
26139 self.generate_expression(&e.expression)?;
26140 self.write(")");
26141 Ok(())
26142 }
26143
26144 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
26145 self.write_keyword("ARRAY_ANY");
26147 self.write("(");
26148 self.generate_expression(&e.this)?;
26149 self.write(", ");
26150 self.generate_expression(&e.expression)?;
26151 self.write(")");
26152 Ok(())
26153 }
26154
26155 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
26156 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
26158 self.write("(");
26159 for (i, expr) in e.expressions.iter().enumerate() {
26160 if i > 0 {
26161 self.write(", ");
26162 }
26163 self.generate_expression(expr)?;
26164 }
26165 self.write(")");
26166 Ok(())
26167 }
26168
26169 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
26170 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
26172 self.write("arraySum");
26173 } else {
26174 self.write_keyword("ARRAY_SUM");
26175 }
26176 self.write("(");
26177 self.generate_expression(&e.this)?;
26178 if let Some(expression) = &e.expression {
26179 self.write(", ");
26180 self.generate_expression(expression)?;
26181 }
26182 self.write(")");
26183 Ok(())
26184 }
26185
26186 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
26187 self.generate_expression(&e.this)?;
26189 self.write_space();
26190 self.write_keyword("AT");
26191 self.write_space();
26192 self.generate_expression(&e.expression)?;
26193 Ok(())
26194 }
26195
26196 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
26197 self.write_keyword("ATTACH");
26199 if e.exists {
26200 self.write_space();
26201 self.write_keyword("IF NOT EXISTS");
26202 }
26203 self.write_space();
26204 self.generate_expression(&e.this)?;
26205 if !e.expressions.is_empty() {
26206 self.write(" (");
26207 for (i, expr) in e.expressions.iter().enumerate() {
26208 if i > 0 {
26209 self.write(", ");
26210 }
26211 self.generate_expression(expr)?;
26212 }
26213 self.write(")");
26214 }
26215 Ok(())
26216 }
26217
26218 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
26219 self.generate_expression(&e.this)?;
26222 if let Some(expression) = &e.expression {
26223 self.write_space();
26224 self.generate_expression(expression)?;
26225 }
26226 Ok(())
26227 }
26228
26229 fn generate_auto_increment_keyword(
26233 &mut self,
26234 col: &crate::expressions::ColumnDef,
26235 ) -> Result<()> {
26236 use crate::dialects::DialectType;
26237 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
26238 self.write_keyword("IDENTITY");
26239 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26240 self.write("(");
26241 if let Some(ref start) = col.auto_increment_start {
26242 self.generate_expression(start)?;
26243 } else {
26244 self.write("0");
26245 }
26246 self.write(", ");
26247 if let Some(ref inc) = col.auto_increment_increment {
26248 self.generate_expression(inc)?;
26249 } else {
26250 self.write("1");
26251 }
26252 self.write(")");
26253 }
26254 } else if matches!(
26255 self.config.dialect,
26256 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
26257 ) {
26258 self.write_keyword("AUTOINCREMENT");
26259 if let Some(ref start) = col.auto_increment_start {
26260 self.write_space();
26261 self.write_keyword("START");
26262 self.write_space();
26263 self.generate_expression(start)?;
26264 }
26265 if let Some(ref inc) = col.auto_increment_increment {
26266 self.write_space();
26267 self.write_keyword("INCREMENT");
26268 self.write_space();
26269 self.generate_expression(inc)?;
26270 }
26271 if let Some(order) = col.auto_increment_order {
26272 self.write_space();
26273 if order {
26274 self.write_keyword("ORDER");
26275 } else {
26276 self.write_keyword("NOORDER");
26277 }
26278 }
26279 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
26280 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
26281 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26282 self.write(" (");
26283 let mut first = true;
26284 if let Some(ref start) = col.auto_increment_start {
26285 self.write_keyword("START WITH");
26286 self.write_space();
26287 self.generate_expression(start)?;
26288 first = false;
26289 }
26290 if let Some(ref inc) = col.auto_increment_increment {
26291 if !first {
26292 self.write_space();
26293 }
26294 self.write_keyword("INCREMENT BY");
26295 self.write_space();
26296 self.generate_expression(inc)?;
26297 }
26298 self.write(")");
26299 }
26300 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
26301 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26304 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
26305 } else {
26306 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
26307 }
26308 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26309 self.write(" (");
26310 let mut first = true;
26311 if let Some(ref start) = col.auto_increment_start {
26312 self.write_keyword("START WITH");
26313 self.write_space();
26314 self.generate_expression(start)?;
26315 first = false;
26316 }
26317 if let Some(ref inc) = col.auto_increment_increment {
26318 if !first {
26319 self.write_space();
26320 }
26321 self.write_keyword("INCREMENT BY");
26322 self.write_space();
26323 self.generate_expression(inc)?;
26324 }
26325 self.write(")");
26326 }
26327 } else if matches!(
26328 self.config.dialect,
26329 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26330 ) {
26331 self.write_keyword("IDENTITY");
26332 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26333 self.write("(");
26334 if let Some(ref start) = col.auto_increment_start {
26335 self.generate_expression(start)?;
26336 } else {
26337 self.write("0");
26338 }
26339 self.write(", ");
26340 if let Some(ref inc) = col.auto_increment_increment {
26341 self.generate_expression(inc)?;
26342 } else {
26343 self.write("1");
26344 }
26345 self.write(")");
26346 }
26347 } else {
26348 self.write_keyword("AUTO_INCREMENT");
26349 if let Some(ref start) = col.auto_increment_start {
26350 self.write_space();
26351 self.write_keyword("START");
26352 self.write_space();
26353 self.generate_expression(start)?;
26354 }
26355 if let Some(ref inc) = col.auto_increment_increment {
26356 self.write_space();
26357 self.write_keyword("INCREMENT");
26358 self.write_space();
26359 self.generate_expression(inc)?;
26360 }
26361 if let Some(order) = col.auto_increment_order {
26362 self.write_space();
26363 if order {
26364 self.write_keyword("ORDER");
26365 } else {
26366 self.write_keyword("NOORDER");
26367 }
26368 }
26369 }
26370 Ok(())
26371 }
26372
26373 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
26374 self.write_keyword("AUTO_INCREMENT");
26376 self.write("=");
26377 self.generate_expression(&e.this)?;
26378 Ok(())
26379 }
26380
26381 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
26382 self.write_keyword("AUTO_REFRESH");
26384 self.write("=");
26385 self.generate_expression(&e.this)?;
26386 Ok(())
26387 }
26388
26389 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
26390 self.write_keyword("BACKUP");
26392 self.write_space();
26393 self.generate_expression(&e.this)?;
26394 Ok(())
26395 }
26396
26397 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
26398 self.write_keyword("BASE64_DECODE_BINARY");
26400 self.write("(");
26401 self.generate_expression(&e.this)?;
26402 if let Some(alphabet) = &e.alphabet {
26403 self.write(", ");
26404 self.generate_expression(alphabet)?;
26405 }
26406 self.write(")");
26407 Ok(())
26408 }
26409
26410 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
26411 self.write_keyword("BASE64_DECODE_STRING");
26413 self.write("(");
26414 self.generate_expression(&e.this)?;
26415 if let Some(alphabet) = &e.alphabet {
26416 self.write(", ");
26417 self.generate_expression(alphabet)?;
26418 }
26419 self.write(")");
26420 Ok(())
26421 }
26422
26423 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
26424 self.write_keyword("BASE64_ENCODE");
26426 self.write("(");
26427 self.generate_expression(&e.this)?;
26428 if let Some(max_line_length) = &e.max_line_length {
26429 self.write(", ");
26430 self.generate_expression(max_line_length)?;
26431 }
26432 if let Some(alphabet) = &e.alphabet {
26433 self.write(", ");
26434 self.generate_expression(alphabet)?;
26435 }
26436 self.write(")");
26437 Ok(())
26438 }
26439
26440 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
26441 self.write_keyword("BLOCKCOMPRESSION");
26443 self.write("=");
26444 if let Some(autotemp) = &e.autotemp {
26445 self.write_keyword("AUTOTEMP");
26446 self.write("(");
26447 self.generate_expression(autotemp)?;
26448 self.write(")");
26449 }
26450 if let Some(always) = &e.always {
26451 self.generate_expression(always)?;
26452 }
26453 if let Some(default) = &e.default {
26454 self.generate_expression(default)?;
26455 }
26456 if let Some(manual) = &e.manual {
26457 self.generate_expression(manual)?;
26458 }
26459 if let Some(never) = &e.never {
26460 self.generate_expression(never)?;
26461 }
26462 Ok(())
26463 }
26464
26465 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
26466 self.write("((");
26468 self.generate_expression(&e.this)?;
26469 self.write(") ");
26470 self.write_keyword("AND");
26471 self.write(" (");
26472 self.generate_expression(&e.expression)?;
26473 self.write("))");
26474 Ok(())
26475 }
26476
26477 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
26478 self.write("((");
26480 self.generate_expression(&e.this)?;
26481 self.write(") ");
26482 self.write_keyword("OR");
26483 self.write(" (");
26484 self.generate_expression(&e.expression)?;
26485 self.write("))");
26486 Ok(())
26487 }
26488
26489 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
26490 self.write_keyword("BUILD");
26492 self.write_space();
26493 self.generate_expression(&e.this)?;
26494 Ok(())
26495 }
26496
26497 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
26498 self.generate_expression(&e.this)?;
26500 Ok(())
26501 }
26502
26503 fn generate_case_specific_column_constraint(
26504 &mut self,
26505 e: &CaseSpecificColumnConstraint,
26506 ) -> Result<()> {
26507 if e.not_.is_some() {
26509 self.write_keyword("NOT");
26510 self.write_space();
26511 }
26512 self.write_keyword("CASESPECIFIC");
26513 Ok(())
26514 }
26515
26516 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
26517 self.write_keyword("CAST");
26519 self.write("(");
26520 self.generate_expression(&e.this)?;
26521 if self.config.dialect == Some(DialectType::ClickHouse) {
26522 self.write(", ");
26524 } else {
26525 self.write_space();
26526 self.write_keyword("AS");
26527 self.write_space();
26528 }
26529 if let Some(to) = &e.to {
26530 self.generate_expression(to)?;
26531 }
26532 self.write(")");
26533 Ok(())
26534 }
26535
26536 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
26537 self.write_keyword("CHANGES");
26540 self.write(" (");
26541 if let Some(information) = &e.information {
26542 self.write_keyword("INFORMATION");
26543 self.write(" => ");
26544 self.generate_expression(information)?;
26545 }
26546 self.write(")");
26547 if let Some(at_before) = &e.at_before {
26549 self.write(" ");
26550 self.generate_expression(at_before)?;
26551 }
26552 if let Some(end) = &e.end {
26553 self.write(" ");
26554 self.generate_expression(end)?;
26555 }
26556 Ok(())
26557 }
26558
26559 fn generate_character_set_column_constraint(
26560 &mut self,
26561 e: &CharacterSetColumnConstraint,
26562 ) -> Result<()> {
26563 self.write_keyword("CHARACTER SET");
26565 self.write_space();
26566 self.generate_expression(&e.this)?;
26567 Ok(())
26568 }
26569
26570 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
26571 if e.default.is_some() {
26573 self.write_keyword("DEFAULT");
26574 self.write_space();
26575 }
26576 self.write_keyword("CHARACTER SET");
26577 self.write("=");
26578 self.generate_expression(&e.this)?;
26579 Ok(())
26580 }
26581
26582 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
26583 self.write_keyword("CHECK");
26585 self.write(" (");
26586 self.generate_expression(&e.this)?;
26587 self.write(")");
26588 if e.enforced.is_some() {
26589 self.write_space();
26590 self.write_keyword("ENFORCED");
26591 }
26592 Ok(())
26593 }
26594
26595 fn generate_assume_column_constraint(&mut self, e: &AssumeColumnConstraint) -> Result<()> {
26596 self.write_keyword("ASSUME");
26598 self.write(" (");
26599 self.generate_expression(&e.this)?;
26600 self.write(")");
26601 Ok(())
26602 }
26603
26604 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
26605 self.write_keyword("CHECK_JSON");
26607 self.write("(");
26608 self.generate_expression(&e.this)?;
26609 self.write(")");
26610 Ok(())
26611 }
26612
26613 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
26614 self.write_keyword("CHECK_XML");
26616 self.write("(");
26617 self.generate_expression(&e.this)?;
26618 self.write(")");
26619 Ok(())
26620 }
26621
26622 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
26623 self.write_keyword("CHECKSUM");
26625 self.write("=");
26626 if e.on.is_some() {
26627 self.write_keyword("ON");
26628 } else if e.default.is_some() {
26629 self.write_keyword("DEFAULT");
26630 } else {
26631 self.write_keyword("OFF");
26632 }
26633 Ok(())
26634 }
26635
26636 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
26637 if e.shallow.is_some() {
26639 self.write_keyword("SHALLOW");
26640 self.write_space();
26641 }
26642 if e.copy.is_some() {
26643 self.write_keyword("COPY");
26644 } else {
26645 self.write_keyword("CLONE");
26646 }
26647 self.write_space();
26648 self.generate_expression(&e.this)?;
26649 Ok(())
26650 }
26651
26652 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
26653 self.write_keyword("CLUSTER BY");
26655 self.write(" (");
26656 for (i, ord) in e.expressions.iter().enumerate() {
26657 if i > 0 {
26658 self.write(", ");
26659 }
26660 self.generate_ordered(ord)?;
26661 }
26662 self.write(")");
26663 Ok(())
26664 }
26665
26666 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
26667 self.write_keyword("CLUSTER BY");
26669 self.write_space();
26670 for (i, col) in e.columns.iter().enumerate() {
26671 if i > 0 {
26672 self.write(", ");
26673 }
26674 self.generate_identifier(col)?;
26675 }
26676 Ok(())
26677 }
26678
26679 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
26680 self.write_keyword("CLUSTERED BY");
26682 self.write(" (");
26683 for (i, expr) in e.expressions.iter().enumerate() {
26684 if i > 0 {
26685 self.write(", ");
26686 }
26687 self.generate_expression(expr)?;
26688 }
26689 self.write(")");
26690 if let Some(sorted_by) = &e.sorted_by {
26691 self.write_space();
26692 self.write_keyword("SORTED BY");
26693 self.write(" (");
26694 if let Expression::Tuple(t) = sorted_by.as_ref() {
26696 for (i, expr) in t.expressions.iter().enumerate() {
26697 if i > 0 {
26698 self.write(", ");
26699 }
26700 self.generate_expression(expr)?;
26701 }
26702 } else {
26703 self.generate_expression(sorted_by)?;
26704 }
26705 self.write(")");
26706 }
26707 if let Some(buckets) = &e.buckets {
26708 self.write_space();
26709 self.write_keyword("INTO");
26710 self.write_space();
26711 self.generate_expression(buckets)?;
26712 self.write_space();
26713 self.write_keyword("BUCKETS");
26714 }
26715 Ok(())
26716 }
26717
26718 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
26719 if e.default.is_some() {
26723 self.write_keyword("DEFAULT");
26724 self.write_space();
26725 }
26726 self.write_keyword("COLLATE");
26727 match self.config.dialect {
26729 Some(DialectType::BigQuery) => self.write_space(),
26730 _ => self.write("="),
26731 }
26732 self.generate_expression(&e.this)?;
26733 Ok(())
26734 }
26735
26736 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
26737 match e {
26739 ColumnConstraint::NotNull => {
26740 self.write_keyword("NOT NULL");
26741 }
26742 ColumnConstraint::Null => {
26743 self.write_keyword("NULL");
26744 }
26745 ColumnConstraint::Unique => {
26746 self.write_keyword("UNIQUE");
26747 }
26748 ColumnConstraint::PrimaryKey => {
26749 self.write_keyword("PRIMARY KEY");
26750 }
26751 ColumnConstraint::Default(expr) => {
26752 self.write_keyword("DEFAULT");
26753 self.write_space();
26754 self.generate_expression(expr)?;
26755 }
26756 ColumnConstraint::Check(expr) => {
26757 self.write_keyword("CHECK");
26758 self.write(" (");
26759 self.generate_expression(expr)?;
26760 self.write(")");
26761 }
26762 ColumnConstraint::References(fk_ref) => {
26763 if fk_ref.has_foreign_key_keywords {
26764 self.write_keyword("FOREIGN KEY");
26765 self.write_space();
26766 }
26767 self.write_keyword("REFERENCES");
26768 self.write_space();
26769 self.generate_table(&fk_ref.table)?;
26770 if !fk_ref.columns.is_empty() {
26771 self.write(" (");
26772 for (i, col) in fk_ref.columns.iter().enumerate() {
26773 if i > 0 {
26774 self.write(", ");
26775 }
26776 self.generate_identifier(col)?;
26777 }
26778 self.write(")");
26779 }
26780 }
26781 ColumnConstraint::GeneratedAsIdentity(gen) => {
26782 self.write_keyword("GENERATED");
26783 self.write_space();
26784 if gen.always {
26785 self.write_keyword("ALWAYS");
26786 } else {
26787 self.write_keyword("BY DEFAULT");
26788 if gen.on_null {
26789 self.write_space();
26790 self.write_keyword("ON NULL");
26791 }
26792 }
26793 self.write_space();
26794 self.write_keyword("AS IDENTITY");
26795 }
26796 ColumnConstraint::Collate(collation) => {
26797 self.write_keyword("COLLATE");
26798 self.write_space();
26799 self.generate_identifier(collation)?;
26800 }
26801 ColumnConstraint::Comment(comment) => {
26802 self.write_keyword("COMMENT");
26803 self.write(" '");
26804 self.write(comment);
26805 self.write("'");
26806 }
26807 ColumnConstraint::ComputedColumn(cc) => {
26808 self.generate_computed_column_inline(cc)?;
26809 }
26810 ColumnConstraint::GeneratedAsRow(gar) => {
26811 self.generate_generated_as_row_inline(gar)?;
26812 }
26813 ColumnConstraint::Tags(tags) => {
26814 self.write_keyword("TAG");
26815 self.write(" (");
26816 for (i, expr) in tags.expressions.iter().enumerate() {
26817 if i > 0 {
26818 self.write(", ");
26819 }
26820 self.generate_expression(expr)?;
26821 }
26822 self.write(")");
26823 }
26824 ColumnConstraint::Path(path_expr) => {
26825 self.write_keyword("PATH");
26826 self.write_space();
26827 self.generate_expression(path_expr)?;
26828 }
26829 }
26830 Ok(())
26831 }
26832
26833 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
26834 match e {
26836 ColumnPosition::First => {
26837 self.write_keyword("FIRST");
26838 }
26839 ColumnPosition::After(ident) => {
26840 self.write_keyword("AFTER");
26841 self.write_space();
26842 self.generate_identifier(ident)?;
26843 }
26844 }
26845 Ok(())
26846 }
26847
26848 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
26849 self.generate_expression(&e.this)?;
26851 self.write("(");
26852 self.generate_expression(&e.expression)?;
26853 self.write(")");
26854 Ok(())
26855 }
26856
26857 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
26858 if let Some(ref unpack) = e.unpack {
26861 if let Expression::Boolean(b) = unpack.as_ref() {
26862 if b.value {
26863 self.write("*");
26864 }
26865 }
26866 }
26867 self.write_keyword("COLUMNS");
26868 self.write("(");
26869 self.generate_expression(&e.this)?;
26870 self.write(")");
26871 Ok(())
26872 }
26873
26874 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
26875 self.generate_expression(&e.this)?;
26877 self.write("(");
26878 for (i, expr) in e.expressions.iter().enumerate() {
26879 if i > 0 {
26880 self.write(", ");
26881 }
26882 self.generate_expression(expr)?;
26883 }
26884 self.write(")");
26885 Ok(())
26886 }
26887
26888 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
26889 self.generate_expression(&e.this)?;
26891 self.write("(");
26892 for (i, param) in e.params.iter().enumerate() {
26893 if i > 0 {
26894 self.write(", ");
26895 }
26896 self.generate_expression(param)?;
26897 }
26898 self.write(")(");
26899 for (i, expr) in e.expressions.iter().enumerate() {
26900 if i > 0 {
26901 self.write(", ");
26902 }
26903 self.generate_expression(expr)?;
26904 }
26905 self.write(")");
26906 Ok(())
26907 }
26908
26909 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
26910 self.write_keyword("COMMIT");
26912
26913 if e.this.is_none()
26915 && matches!(
26916 self.config.dialect,
26917 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26918 )
26919 {
26920 self.write_space();
26921 self.write_keyword("TRANSACTION");
26922 }
26923
26924 if let Some(this) = &e.this {
26926 let is_transaction_marker = matches!(
26928 this.as_ref(),
26929 Expression::Identifier(id) if id.name == "TRANSACTION"
26930 );
26931
26932 self.write_space();
26933 self.write_keyword("TRANSACTION");
26934
26935 if !is_transaction_marker {
26937 self.write_space();
26938 self.generate_expression(this)?;
26939 }
26940 }
26941
26942 if let Some(durability) = &e.durability {
26944 self.write_space();
26945 self.write_keyword("WITH");
26946 self.write(" (");
26947 self.write_keyword("DELAYED_DURABILITY");
26948 self.write(" = ");
26949 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
26950 self.write_keyword("ON");
26951 } else {
26952 self.write_keyword("OFF");
26953 }
26954 self.write(")");
26955 }
26956
26957 if let Some(chain) = &e.chain {
26959 self.write_space();
26960 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
26961 self.write_keyword("AND NO CHAIN");
26962 } else {
26963 self.write_keyword("AND CHAIN");
26964 }
26965 }
26966 Ok(())
26967 }
26968
26969 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
26970 self.write("[");
26972 self.generate_expression(&e.this)?;
26973 self.write_space();
26974 self.write_keyword("FOR");
26975 self.write_space();
26976 self.generate_expression(&e.expression)?;
26977 if let Some(pos) = &e.position {
26979 self.write(", ");
26980 self.generate_expression(pos)?;
26981 }
26982 if let Some(iterator) = &e.iterator {
26983 self.write_space();
26984 self.write_keyword("IN");
26985 self.write_space();
26986 self.generate_expression(iterator)?;
26987 }
26988 if let Some(condition) = &e.condition {
26989 self.write_space();
26990 self.write_keyword("IF");
26991 self.write_space();
26992 self.generate_expression(condition)?;
26993 }
26994 self.write("]");
26995 Ok(())
26996 }
26997
26998 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
26999 self.write_keyword("COMPRESS");
27001 self.write("(");
27002 self.generate_expression(&e.this)?;
27003 if let Some(method) = &e.method {
27004 self.write(", '");
27005 self.write(method);
27006 self.write("'");
27007 }
27008 self.write(")");
27009 Ok(())
27010 }
27011
27012 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
27013 self.write_keyword("COMPRESS");
27015 if let Some(this) = &e.this {
27016 self.write_space();
27017 self.generate_expression(this)?;
27018 }
27019 Ok(())
27020 }
27021
27022 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
27023 self.write_keyword("AS");
27025 self.write_space();
27026 self.generate_expression(&e.this)?;
27027 if e.not_null.is_some() {
27028 self.write_space();
27029 self.write_keyword("PERSISTED NOT NULL");
27030 } else if e.persisted.is_some() {
27031 self.write_space();
27032 self.write_keyword("PERSISTED");
27033 }
27034 Ok(())
27035 }
27036
27037 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
27041 let computed_expr = if matches!(
27042 self.config.dialect,
27043 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27044 ) {
27045 match &*cc.expression {
27046 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
27047 {
27048 let wrapped = Expression::Cast(Box::new(Cast {
27049 this: y.this.clone(),
27050 to: DataType::Date,
27051 trailing_comments: Vec::new(),
27052 double_colon_syntax: false,
27053 format: None,
27054 default: None,
27055 inferred_type: None,
27056 }));
27057 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
27058 }
27059 Expression::Function(f)
27060 if f.name.eq_ignore_ascii_case("YEAR")
27061 && f.args.len() == 1
27062 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
27063 {
27064 let wrapped = Expression::Cast(Box::new(Cast {
27065 this: f.args[0].clone(),
27066 to: DataType::Date,
27067 trailing_comments: Vec::new(),
27068 double_colon_syntax: false,
27069 format: None,
27070 default: None,
27071 inferred_type: None,
27072 }));
27073 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
27074 }
27075 _ => *cc.expression.clone(),
27076 }
27077 } else {
27078 *cc.expression.clone()
27079 };
27080
27081 match cc.persistence_kind.as_deref() {
27082 Some("STORED") | Some("VIRTUAL") => {
27083 self.write_keyword("GENERATED ALWAYS AS");
27085 self.write(" (");
27086 self.generate_expression(&computed_expr)?;
27087 self.write(")");
27088 self.write_space();
27089 if cc.persisted {
27090 self.write_keyword("STORED");
27091 } else {
27092 self.write_keyword("VIRTUAL");
27093 }
27094 }
27095 Some("PERSISTED") => {
27096 self.write_keyword("AS");
27098 self.write(" (");
27099 self.generate_expression(&computed_expr)?;
27100 self.write(")");
27101 self.write_space();
27102 self.write_keyword("PERSISTED");
27103 if let Some(ref dt) = cc.data_type {
27105 self.write_space();
27106 self.generate_data_type(dt)?;
27107 }
27108 if cc.not_null {
27109 self.write_space();
27110 self.write_keyword("NOT NULL");
27111 }
27112 }
27113 _ => {
27114 if matches!(
27117 self.config.dialect,
27118 Some(DialectType::Spark)
27119 | Some(DialectType::Databricks)
27120 | Some(DialectType::Hive)
27121 ) {
27122 self.write_keyword("GENERATED ALWAYS AS");
27123 self.write(" (");
27124 self.generate_expression(&computed_expr)?;
27125 self.write(")");
27126 } else if matches!(
27127 self.config.dialect,
27128 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27129 ) {
27130 self.write_keyword("AS");
27131 let omit_parens = matches!(computed_expr, Expression::Year(_))
27132 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
27133 if omit_parens {
27134 self.write_space();
27135 self.generate_expression(&computed_expr)?;
27136 } else {
27137 self.write(" (");
27138 self.generate_expression(&computed_expr)?;
27139 self.write(")");
27140 }
27141 } else {
27142 self.write_keyword("AS");
27143 self.write(" (");
27144 self.generate_expression(&computed_expr)?;
27145 self.write(")");
27146 }
27147 }
27148 }
27149 Ok(())
27150 }
27151
27152 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
27155 self.write_keyword("GENERATED ALWAYS AS ROW ");
27156 if gar.start {
27157 self.write_keyword("START");
27158 } else {
27159 self.write_keyword("END");
27160 }
27161 if gar.hidden {
27162 self.write_space();
27163 self.write_keyword("HIDDEN");
27164 }
27165 Ok(())
27166 }
27167
27168 fn generate_system_versioning_content(
27170 &mut self,
27171 e: &WithSystemVersioningProperty,
27172 ) -> Result<()> {
27173 let mut parts = Vec::new();
27174
27175 if let Some(this) = &e.this {
27176 let mut s = String::from("HISTORY_TABLE=");
27177 let mut gen = Generator::with_arc_config(self.config.clone());
27178 gen.generate_expression(this)?;
27179 s.push_str(&gen.output);
27180 parts.push(s);
27181 }
27182
27183 if let Some(data_consistency) = &e.data_consistency {
27184 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
27185 let mut gen = Generator::with_arc_config(self.config.clone());
27186 gen.generate_expression(data_consistency)?;
27187 s.push_str(&gen.output);
27188 parts.push(s);
27189 }
27190
27191 if let Some(retention_period) = &e.retention_period {
27192 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
27193 let mut gen = Generator::with_arc_config(self.config.clone());
27194 gen.generate_expression(retention_period)?;
27195 s.push_str(&gen.output);
27196 parts.push(s);
27197 }
27198
27199 self.write_keyword("SYSTEM_VERSIONING");
27200 self.write("=");
27201
27202 if !parts.is_empty() {
27203 self.write_keyword("ON");
27204 self.write("(");
27205 self.write(&parts.join(", "));
27206 self.write(")");
27207 } else if e.on.is_some() {
27208 self.write_keyword("ON");
27209 } else {
27210 self.write_keyword("OFF");
27211 }
27212
27213 Ok(())
27214 }
27215
27216 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
27217 if e.else_.is_some() {
27220 self.write_keyword("ELSE");
27221 self.write_space();
27222 } else if let Some(expression) = &e.expression {
27223 self.write_keyword("WHEN");
27224 self.write_space();
27225 self.generate_expression(expression)?;
27226 self.write_space();
27227 self.write_keyword("THEN");
27228 self.write_space();
27229 }
27230
27231 if let Expression::Insert(insert) = e.this.as_ref() {
27234 self.write_keyword("INTO");
27235 self.write_space();
27236 self.generate_table(&insert.table)?;
27237
27238 if !insert.columns.is_empty() {
27240 self.write(" (");
27241 for (i, col) in insert.columns.iter().enumerate() {
27242 if i > 0 {
27243 self.write(", ");
27244 }
27245 self.generate_identifier(col)?;
27246 }
27247 self.write(")");
27248 }
27249
27250 if !insert.values.is_empty() {
27252 self.write_space();
27253 self.write_keyword("VALUES");
27254 for (row_idx, row) in insert.values.iter().enumerate() {
27255 if row_idx > 0 {
27256 self.write(", ");
27257 }
27258 self.write(" (");
27259 for (i, val) in row.iter().enumerate() {
27260 if i > 0 {
27261 self.write(", ");
27262 }
27263 self.generate_expression(val)?;
27264 }
27265 self.write(")");
27266 }
27267 }
27268 } else {
27269 self.generate_expression(&e.this)?;
27271 }
27272 Ok(())
27273 }
27274
27275 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
27276 self.write_keyword("CONSTRAINT");
27278 self.write_space();
27279 self.generate_expression(&e.this)?;
27280 if !e.expressions.is_empty() {
27281 self.write_space();
27282 for (i, expr) in e.expressions.iter().enumerate() {
27283 if i > 0 {
27284 self.write_space();
27285 }
27286 self.generate_expression(expr)?;
27287 }
27288 }
27289 Ok(())
27290 }
27291
27292 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
27293 self.write_keyword("CONVERT_TIMEZONE");
27295 self.write("(");
27296 let mut first = true;
27297 if let Some(source_tz) = &e.source_tz {
27298 self.generate_expression(source_tz)?;
27299 first = false;
27300 }
27301 if let Some(target_tz) = &e.target_tz {
27302 if !first {
27303 self.write(", ");
27304 }
27305 self.generate_expression(target_tz)?;
27306 first = false;
27307 }
27308 if let Some(timestamp) = &e.timestamp {
27309 if !first {
27310 self.write(", ");
27311 }
27312 self.generate_expression(timestamp)?;
27313 }
27314 self.write(")");
27315 Ok(())
27316 }
27317
27318 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
27319 self.write_keyword("CONVERT");
27321 self.write("(");
27322 self.generate_expression(&e.this)?;
27323 if let Some(dest) = &e.dest {
27324 self.write_space();
27325 self.write_keyword("USING");
27326 self.write_space();
27327 self.generate_expression(dest)?;
27328 }
27329 self.write(")");
27330 Ok(())
27331 }
27332
27333 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
27334 self.write_keyword("COPY");
27335 if e.is_into {
27336 self.write_space();
27337 self.write_keyword("INTO");
27338 }
27339 self.write_space();
27340
27341 if let Expression::Literal(lit) = &e.this {
27343 if let Literal::String(s) = lit.as_ref() {
27344 if s.starts_with('@') {
27345 self.write(s);
27346 } else {
27347 self.generate_expression(&e.this)?;
27348 }
27349 }
27350 } else {
27351 self.generate_expression(&e.this)?;
27352 }
27353
27354 if e.kind {
27356 if self.config.pretty {
27358 self.write_newline();
27359 } else {
27360 self.write_space();
27361 }
27362 self.write_keyword("FROM");
27363 self.write_space();
27364 } else if !e.files.is_empty() {
27365 if self.config.pretty {
27367 self.write_newline();
27368 } else {
27369 self.write_space();
27370 }
27371 self.write_keyword("TO");
27372 self.write_space();
27373 }
27374
27375 for (i, file) in e.files.iter().enumerate() {
27377 if i > 0 {
27378 self.write_space();
27379 }
27380 if let Expression::Literal(lit) = file {
27382 if let Literal::String(s) = lit.as_ref() {
27383 if s.starts_with('@') {
27384 self.write(s);
27385 } else {
27386 self.generate_expression(file)?;
27387 }
27388 }
27389 } else if let Expression::Identifier(id) = file {
27390 if id.quoted {
27392 self.write("`");
27393 self.write(&id.name);
27394 self.write("`");
27395 } else {
27396 self.generate_expression(file)?;
27397 }
27398 } else {
27399 self.generate_expression(file)?;
27400 }
27401 }
27402
27403 if !e.with_wrapped {
27405 if let Some(ref creds) = e.credentials {
27406 if let Some(ref storage) = creds.storage {
27407 if self.config.pretty {
27408 self.write_newline();
27409 } else {
27410 self.write_space();
27411 }
27412 self.write_keyword("STORAGE_INTEGRATION");
27413 self.write(" = ");
27414 self.write(storage);
27415 }
27416 if creds.credentials.is_empty() {
27417 if self.config.pretty {
27419 self.write_newline();
27420 } else {
27421 self.write_space();
27422 }
27423 self.write_keyword("CREDENTIALS");
27424 self.write(" = ()");
27425 } else {
27426 if self.config.pretty {
27427 self.write_newline();
27428 } else {
27429 self.write_space();
27430 }
27431 self.write_keyword("CREDENTIALS");
27432 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
27435 self.write(" '");
27437 self.write(&creds.credentials[0].1);
27438 self.write("'");
27439 } else {
27440 self.write(" = (");
27442 for (i, (k, v)) in creds.credentials.iter().enumerate() {
27443 if i > 0 {
27444 self.write_space();
27445 }
27446 self.write(k);
27447 self.write("='");
27448 self.write(v);
27449 self.write("'");
27450 }
27451 self.write(")");
27452 }
27453 }
27454 if let Some(ref encryption) = creds.encryption {
27455 self.write_space();
27456 self.write_keyword("ENCRYPTION");
27457 self.write(" = ");
27458 self.write(encryption);
27459 }
27460 }
27461 }
27462
27463 if !e.params.is_empty() {
27465 if e.with_wrapped {
27466 self.write_space();
27468 self.write_keyword("WITH");
27469 self.write(" (");
27470 for (i, param) in e.params.iter().enumerate() {
27471 if i > 0 {
27472 self.write(", ");
27473 }
27474 self.generate_copy_param_with_format(param)?;
27475 }
27476 self.write(")");
27477 } else {
27478 for param in &e.params {
27482 if self.config.pretty {
27483 self.write_newline();
27484 } else {
27485 self.write_space();
27486 }
27487 self.write(¶m.name);
27489 if let Some(ref value) = param.value {
27490 if param.eq {
27492 self.write(" = ");
27493 } else {
27494 self.write(" ");
27495 }
27496 if !param.values.is_empty() {
27497 self.write("(");
27498 for (i, v) in param.values.iter().enumerate() {
27499 if i > 0 {
27500 self.write_space();
27501 }
27502 self.generate_copy_nested_param(v)?;
27503 }
27504 self.write(")");
27505 } else {
27506 self.generate_copy_param_value(value)?;
27508 }
27509 } else if !param.values.is_empty() {
27510 if param.eq {
27512 self.write(" = (");
27513 } else {
27514 self.write(" (");
27515 }
27516 let is_key_value_pairs = param
27521 .values
27522 .first()
27523 .map_or(false, |v| matches!(v, Expression::Eq(_)));
27524 let sep = if is_key_value_pairs && param.eq {
27525 " "
27526 } else {
27527 ", "
27528 };
27529 for (i, v) in param.values.iter().enumerate() {
27530 if i > 0 {
27531 self.write(sep);
27532 }
27533 self.generate_copy_nested_param(v)?;
27534 }
27535 self.write(")");
27536 }
27537 }
27538 }
27539 }
27540
27541 Ok(())
27542 }
27543
27544 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
27547 self.write_keyword(¶m.name);
27548 if !param.values.is_empty() {
27549 self.write(" = (");
27551 for (i, v) in param.values.iter().enumerate() {
27552 if i > 0 {
27553 self.write(", ");
27554 }
27555 self.generate_copy_nested_param(v)?;
27556 }
27557 self.write(")");
27558 } else if let Some(ref value) = param.value {
27559 if param.eq {
27560 self.write(" = ");
27561 } else {
27562 self.write(" ");
27563 }
27564 self.generate_expression(value)?;
27565 }
27566 Ok(())
27567 }
27568
27569 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
27571 match expr {
27572 Expression::Eq(eq) => {
27573 match &eq.left {
27575 Expression::Column(c) => self.write(&c.name.name),
27576 _ => self.generate_expression(&eq.left)?,
27577 }
27578 self.write("=");
27579 match &eq.right {
27581 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27582 let Literal::String(s) = lit.as_ref() else {
27583 unreachable!()
27584 };
27585 self.write("'");
27586 self.write(s);
27587 self.write("'");
27588 }
27589 Expression::Tuple(t) => {
27590 self.write("(");
27592 if self.config.pretty {
27593 self.write_newline();
27594 self.indent_level += 1;
27595 for (i, item) in t.expressions.iter().enumerate() {
27596 if i > 0 {
27597 self.write(", ");
27598 }
27599 self.write_indent();
27600 self.generate_expression(item)?;
27601 }
27602 self.write_newline();
27603 self.indent_level -= 1;
27604 } else {
27605 for (i, item) in t.expressions.iter().enumerate() {
27606 if i > 0 {
27607 self.write(", ");
27608 }
27609 self.generate_expression(item)?;
27610 }
27611 }
27612 self.write(")");
27613 }
27614 _ => self.generate_expression(&eq.right)?,
27615 }
27616 Ok(())
27617 }
27618 Expression::Column(c) => {
27619 self.write(&c.name.name);
27621 Ok(())
27622 }
27623 _ => self.generate_expression(expr),
27624 }
27625 }
27626
27627 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
27630 match expr {
27631 Expression::Column(c) => {
27632 if c.name.quoted {
27634 self.write("\"");
27635 self.write(&c.name.name);
27636 self.write("\"");
27637 } else {
27638 self.write(&c.name.name);
27639 }
27640 Ok(())
27641 }
27642 Expression::Identifier(id) => {
27643 if id.quoted {
27645 self.write("\"");
27646 self.write(&id.name);
27647 self.write("\"");
27648 } else {
27649 self.write(&id.name);
27650 }
27651 Ok(())
27652 }
27653 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27654 let Literal::String(s) = lit.as_ref() else {
27655 unreachable!()
27656 };
27657 self.write("'");
27659 self.write(s);
27660 self.write("'");
27661 Ok(())
27662 }
27663 _ => self.generate_expression(expr),
27664 }
27665 }
27666
27667 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
27668 self.write_keyword(&e.name);
27669 if let Some(ref value) = e.value {
27670 if e.eq {
27671 self.write(" = ");
27672 } else {
27673 self.write(" ");
27674 }
27675 self.generate_expression(value)?;
27676 }
27677 if !e.values.is_empty() {
27678 if e.eq {
27679 self.write(" = ");
27680 } else {
27681 self.write(" ");
27682 }
27683 self.write("(");
27684 for (i, v) in e.values.iter().enumerate() {
27685 if i > 0 {
27686 self.write(", ");
27687 }
27688 self.generate_expression(v)?;
27689 }
27690 self.write(")");
27691 }
27692 Ok(())
27693 }
27694
27695 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
27696 self.write_keyword("CORR");
27698 self.write("(");
27699 self.generate_expression(&e.this)?;
27700 self.write(", ");
27701 self.generate_expression(&e.expression)?;
27702 self.write(")");
27703 Ok(())
27704 }
27705
27706 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
27707 self.write_keyword("COSINE_DISTANCE");
27709 self.write("(");
27710 self.generate_expression(&e.this)?;
27711 self.write(", ");
27712 self.generate_expression(&e.expression)?;
27713 self.write(")");
27714 Ok(())
27715 }
27716
27717 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
27718 self.write_keyword("COVAR_POP");
27720 self.write("(");
27721 self.generate_expression(&e.this)?;
27722 self.write(", ");
27723 self.generate_expression(&e.expression)?;
27724 self.write(")");
27725 Ok(())
27726 }
27727
27728 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
27729 self.write_keyword("COVAR_SAMP");
27731 self.write("(");
27732 self.generate_expression(&e.this)?;
27733 self.write(", ");
27734 self.generate_expression(&e.expression)?;
27735 self.write(")");
27736 Ok(())
27737 }
27738
27739 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
27740 self.write_keyword("CREDENTIALS");
27742 self.write(" (");
27743 for (i, (key, value)) in e.credentials.iter().enumerate() {
27744 if i > 0 {
27745 self.write(", ");
27746 }
27747 self.write(key);
27748 self.write("='");
27749 self.write(value);
27750 self.write("'");
27751 }
27752 self.write(")");
27753 Ok(())
27754 }
27755
27756 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
27757 self.write_keyword("CREDENTIALS");
27759 self.write("=(");
27760 for (i, expr) in e.expressions.iter().enumerate() {
27761 if i > 0 {
27762 self.write(", ");
27763 }
27764 self.generate_expression(expr)?;
27765 }
27766 self.write(")");
27767 Ok(())
27768 }
27769
27770 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
27771 use crate::dialects::DialectType;
27772
27773 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
27776 self.generate_expression(&e.this)?;
27777 self.write_space();
27778 self.write_keyword("AS");
27779 self.write_space();
27780 self.generate_identifier(&e.alias)?;
27781 return Ok(());
27782 }
27783 self.write(&e.alias.name);
27784
27785 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
27787
27788 if !e.columns.is_empty() && !skip_cte_columns {
27789 self.write("(");
27790 for (i, col) in e.columns.iter().enumerate() {
27791 if i > 0 {
27792 self.write(", ");
27793 }
27794 self.write(&col.name);
27795 }
27796 self.write(")");
27797 }
27798 if !e.key_expressions.is_empty() {
27800 self.write_space();
27801 self.write_keyword("USING KEY");
27802 self.write(" (");
27803 for (i, key) in e.key_expressions.iter().enumerate() {
27804 if i > 0 {
27805 self.write(", ");
27806 }
27807 self.write(&key.name);
27808 }
27809 self.write(")");
27810 }
27811 self.write_space();
27812 self.write_keyword("AS");
27813 self.write_space();
27814 if let Some(materialized) = e.materialized {
27815 if materialized {
27816 self.write_keyword("MATERIALIZED");
27817 } else {
27818 self.write_keyword("NOT MATERIALIZED");
27819 }
27820 self.write_space();
27821 }
27822 self.write("(");
27823 self.generate_expression(&e.this)?;
27824 self.write(")");
27825 Ok(())
27826 }
27827
27828 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
27829 if e.expressions.is_empty() {
27831 self.write_keyword("WITH CUBE");
27832 } else {
27833 self.write_keyword("CUBE");
27834 self.write("(");
27835 for (i, expr) in e.expressions.iter().enumerate() {
27836 if i > 0 {
27837 self.write(", ");
27838 }
27839 self.generate_expression(expr)?;
27840 }
27841 self.write(")");
27842 }
27843 Ok(())
27844 }
27845
27846 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
27847 self.write_keyword("CURRENT_DATETIME");
27849 if let Some(this) = &e.this {
27850 self.write("(");
27851 self.generate_expression(this)?;
27852 self.write(")");
27853 }
27854 Ok(())
27855 }
27856
27857 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
27858 self.write_keyword("CURRENT_SCHEMA");
27860 Ok(())
27861 }
27862
27863 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
27864 self.write_keyword("CURRENT_SCHEMAS");
27866 self.write("(");
27867 if !matches!(
27869 self.config.dialect,
27870 Some(crate::dialects::DialectType::Snowflake)
27871 ) {
27872 if let Some(this) = &e.this {
27873 self.generate_expression(this)?;
27874 }
27875 }
27876 self.write(")");
27877 Ok(())
27878 }
27879
27880 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
27881 self.write_keyword("CURRENT_USER");
27883 let needs_parens = e.this.is_some()
27885 || matches!(
27886 self.config.dialect,
27887 Some(DialectType::Snowflake)
27888 | Some(DialectType::Spark)
27889 | Some(DialectType::Hive)
27890 | Some(DialectType::DuckDB)
27891 | Some(DialectType::BigQuery)
27892 | Some(DialectType::MySQL)
27893 | Some(DialectType::Databricks)
27894 );
27895 if needs_parens {
27896 self.write("()");
27897 }
27898 Ok(())
27899 }
27900
27901 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
27902 if self.config.dialect == Some(DialectType::Solr) {
27904 self.generate_expression(&e.this)?;
27905 self.write(" ");
27906 self.write_keyword("OR");
27907 self.write(" ");
27908 self.generate_expression(&e.expression)?;
27909 } else if self.config.dialect == Some(DialectType::MySQL) {
27910 self.generate_mysql_concat_from_dpipe(e)?;
27911 } else {
27912 self.generate_expression(&e.this)?;
27914 self.write(" || ");
27915 self.generate_expression(&e.expression)?;
27916 }
27917 Ok(())
27918 }
27919
27920 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
27921 self.write_keyword("DATABLOCKSIZE");
27923 self.write("=");
27924 if let Some(size) = e.size {
27925 self.write(&size.to_string());
27926 if let Some(units) = &e.units {
27927 self.write_space();
27928 self.generate_expression(units)?;
27929 }
27930 } else if e.minimum.is_some() {
27931 self.write_keyword("MINIMUM");
27932 } else if e.maximum.is_some() {
27933 self.write_keyword("MAXIMUM");
27934 } else if e.default.is_some() {
27935 self.write_keyword("DEFAULT");
27936 }
27937 Ok(())
27938 }
27939
27940 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
27941 self.write_keyword("DATA_DELETION");
27943 self.write("=");
27944
27945 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
27946 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
27947
27948 if is_on {
27949 self.write_keyword("ON");
27950 if has_options {
27951 self.write("(");
27952 let mut first = true;
27953 if let Some(filter_column) = &e.filter_column {
27954 self.write_keyword("FILTER_COLUMN");
27955 self.write("=");
27956 self.generate_expression(filter_column)?;
27957 first = false;
27958 }
27959 if let Some(retention_period) = &e.retention_period {
27960 if !first {
27961 self.write(", ");
27962 }
27963 self.write_keyword("RETENTION_PERIOD");
27964 self.write("=");
27965 self.generate_expression(retention_period)?;
27966 }
27967 self.write(")");
27968 }
27969 } else {
27970 self.write_keyword("OFF");
27971 }
27972 Ok(())
27973 }
27974
27975 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
27979 use crate::dialects::DialectType;
27980 use crate::expressions::Literal;
27981
27982 match self.config.dialect {
27983 Some(DialectType::Exasol) => {
27985 self.write_keyword("TO_DATE");
27986 self.write("(");
27987 match &e.this {
27989 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27990 let Literal::String(s) = lit.as_ref() else {
27991 unreachable!()
27992 };
27993 self.write("'");
27994 self.write(s);
27995 self.write("'");
27996 }
27997 _ => {
27998 self.generate_expression(&e.this)?;
27999 }
28000 }
28001 self.write(")");
28002 }
28003 _ => {
28005 self.write_keyword("DATE");
28006 self.write("(");
28007 self.generate_expression(&e.this)?;
28008 self.write(")");
28009 }
28010 }
28011 Ok(())
28012 }
28013
28014 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
28015 self.write_keyword("DATE_BIN");
28017 self.write("(");
28018 self.generate_expression(&e.this)?;
28019 self.write(", ");
28020 self.generate_expression(&e.expression)?;
28021 if let Some(origin) = &e.origin {
28022 self.write(", ");
28023 self.generate_expression(origin)?;
28024 }
28025 self.write(")");
28026 Ok(())
28027 }
28028
28029 fn generate_date_format_column_constraint(
28030 &mut self,
28031 e: &DateFormatColumnConstraint,
28032 ) -> Result<()> {
28033 self.write_keyword("FORMAT");
28035 self.write_space();
28036 self.generate_expression(&e.this)?;
28037 Ok(())
28038 }
28039
28040 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
28041 self.write_keyword("DATE_FROM_PARTS");
28043 self.write("(");
28044 let mut first = true;
28045 if let Some(year) = &e.year {
28046 self.generate_expression(year)?;
28047 first = false;
28048 }
28049 if let Some(month) = &e.month {
28050 if !first {
28051 self.write(", ");
28052 }
28053 self.generate_expression(month)?;
28054 first = false;
28055 }
28056 if let Some(day) = &e.day {
28057 if !first {
28058 self.write(", ");
28059 }
28060 self.generate_expression(day)?;
28061 }
28062 self.write(")");
28063 Ok(())
28064 }
28065
28066 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
28067 self.write_keyword("DATETIME");
28069 self.write("(");
28070 self.generate_expression(&e.this)?;
28071 if let Some(expr) = &e.expression {
28072 self.write(", ");
28073 self.generate_expression(expr)?;
28074 }
28075 self.write(")");
28076 Ok(())
28077 }
28078
28079 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
28080 self.write_keyword("DATETIME_ADD");
28082 self.write("(");
28083 self.generate_expression(&e.this)?;
28084 self.write(", ");
28085 self.generate_expression(&e.expression)?;
28086 if let Some(unit) = &e.unit {
28087 self.write(", ");
28088 self.write_keyword(unit);
28089 }
28090 self.write(")");
28091 Ok(())
28092 }
28093
28094 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
28095 self.write_keyword("DATETIME_DIFF");
28097 self.write("(");
28098 self.generate_expression(&e.this)?;
28099 self.write(", ");
28100 self.generate_expression(&e.expression)?;
28101 if let Some(unit) = &e.unit {
28102 self.write(", ");
28103 self.write_keyword(unit);
28104 }
28105 self.write(")");
28106 Ok(())
28107 }
28108
28109 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
28110 self.write_keyword("DATETIME_SUB");
28112 self.write("(");
28113 self.generate_expression(&e.this)?;
28114 self.write(", ");
28115 self.generate_expression(&e.expression)?;
28116 if let Some(unit) = &e.unit {
28117 self.write(", ");
28118 self.write_keyword(unit);
28119 }
28120 self.write(")");
28121 Ok(())
28122 }
28123
28124 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
28125 self.write_keyword("DATETIME_TRUNC");
28127 self.write("(");
28128 self.generate_expression(&e.this)?;
28129 self.write(", ");
28130 self.write_keyword(&e.unit);
28131 if let Some(zone) = &e.zone {
28132 self.write(", ");
28133 self.generate_expression(zone)?;
28134 }
28135 self.write(")");
28136 Ok(())
28137 }
28138
28139 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
28140 self.write_keyword("DAYNAME");
28142 self.write("(");
28143 self.generate_expression(&e.this)?;
28144 self.write(")");
28145 Ok(())
28146 }
28147
28148 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
28149 self.write_keyword("DECLARE");
28151 self.write_space();
28152 if e.replace {
28153 self.write_keyword("OR");
28154 self.write_space();
28155 self.write_keyword("REPLACE");
28156 self.write_space();
28157 }
28158 for (i, expr) in e.expressions.iter().enumerate() {
28159 if i > 0 {
28160 self.write(", ");
28161 }
28162 self.generate_expression(expr)?;
28163 }
28164 Ok(())
28165 }
28166
28167 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
28168 use crate::dialects::DialectType;
28169
28170 self.generate_expression(&e.this)?;
28172 for name in &e.additional_names {
28174 self.write(", ");
28175 self.generate_expression(name)?;
28176 }
28177 if let Some(kind) = &e.kind {
28178 self.write_space();
28179 match self.config.dialect {
28183 Some(DialectType::BigQuery) => {
28184 self.write(kind);
28185 }
28186 Some(DialectType::TSQL) => {
28187 let is_complex_table = kind.starts_with("TABLE")
28191 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
28192 if is_complex_table {
28193 self.write(kind);
28194 } else if kind == "INT" {
28195 self.write("INTEGER");
28196 } else if kind.starts_with("TABLE") {
28197 let normalized = kind
28199 .replace(" INT ", " INTEGER ")
28200 .replace(" INT,", " INTEGER,")
28201 .replace(" INT)", " INTEGER)")
28202 .replace("(INT ", "(INTEGER ");
28203 self.write(&normalized);
28204 } else {
28205 self.write(kind);
28206 }
28207 }
28208 _ => {
28209 if e.has_as {
28210 self.write_keyword("AS");
28211 self.write_space();
28212 }
28213 self.write(kind);
28214 }
28215 }
28216 }
28217 if let Some(default) = &e.default {
28218 match self.config.dialect {
28220 Some(DialectType::BigQuery) => {
28221 self.write_space();
28222 self.write_keyword("DEFAULT");
28223 self.write_space();
28224 }
28225 _ => {
28226 self.write(" = ");
28227 }
28228 }
28229 self.generate_expression(default)?;
28230 }
28231 Ok(())
28232 }
28233
28234 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
28235 self.write_keyword("DECODE");
28237 self.write("(");
28238 for (i, expr) in e.expressions.iter().enumerate() {
28239 if i > 0 {
28240 self.write(", ");
28241 }
28242 self.generate_expression(expr)?;
28243 }
28244 self.write(")");
28245 Ok(())
28246 }
28247
28248 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
28249 self.write_keyword("DECOMPRESS");
28251 self.write("(");
28252 self.generate_expression(&e.this)?;
28253 self.write(", '");
28254 self.write(&e.method);
28255 self.write("')");
28256 Ok(())
28257 }
28258
28259 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
28260 self.write_keyword("DECOMPRESS");
28262 self.write("(");
28263 self.generate_expression(&e.this)?;
28264 self.write(", '");
28265 self.write(&e.method);
28266 self.write("')");
28267 Ok(())
28268 }
28269
28270 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
28271 self.write_keyword("DECRYPT");
28273 self.write("(");
28274 self.generate_expression(&e.this)?;
28275 if let Some(passphrase) = &e.passphrase {
28276 self.write(", ");
28277 self.generate_expression(passphrase)?;
28278 }
28279 if let Some(aad) = &e.aad {
28280 self.write(", ");
28281 self.generate_expression(aad)?;
28282 }
28283 if let Some(method) = &e.encryption_method {
28284 self.write(", ");
28285 self.generate_expression(method)?;
28286 }
28287 self.write(")");
28288 Ok(())
28289 }
28290
28291 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
28292 self.write_keyword("DECRYPT_RAW");
28294 self.write("(");
28295 self.generate_expression(&e.this)?;
28296 if let Some(key) = &e.key {
28297 self.write(", ");
28298 self.generate_expression(key)?;
28299 }
28300 if let Some(iv) = &e.iv {
28301 self.write(", ");
28302 self.generate_expression(iv)?;
28303 }
28304 if let Some(aad) = &e.aad {
28305 self.write(", ");
28306 self.generate_expression(aad)?;
28307 }
28308 if let Some(method) = &e.encryption_method {
28309 self.write(", ");
28310 self.generate_expression(method)?;
28311 }
28312 self.write(")");
28313 Ok(())
28314 }
28315
28316 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
28317 self.write_keyword("DEFINER");
28319 self.write(" = ");
28320 self.generate_expression(&e.this)?;
28321 Ok(())
28322 }
28323
28324 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
28325 self.write_keyword("DETACH");
28327 if e.exists {
28328 self.write_keyword(" DATABASE IF EXISTS");
28329 }
28330 self.write_space();
28331 self.generate_expression(&e.this)?;
28332 Ok(())
28333 }
28334
28335 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
28336 let property_name = match e.this.as_ref() {
28337 Expression::Identifier(id) => id.name.as_str(),
28338 Expression::Var(v) => v.this.as_str(),
28339 _ => "DICTIONARY",
28340 };
28341 self.write_keyword(property_name);
28342 self.write("(");
28343 self.write(&e.kind);
28344 if let Some(settings) = &e.settings {
28345 self.write("(");
28346 if let Expression::Tuple(t) = settings.as_ref() {
28347 if self.config.pretty && !t.expressions.is_empty() {
28348 self.write_newline();
28349 self.indent_level += 1;
28350 for (i, pair) in t.expressions.iter().enumerate() {
28351 if i > 0 {
28352 self.write(",");
28353 self.write_newline();
28354 }
28355 self.write_indent();
28356 if let Expression::Tuple(pair_tuple) = pair {
28357 if let Some(k) = pair_tuple.expressions.first() {
28358 self.generate_expression(k)?;
28359 }
28360 if let Some(v) = pair_tuple.expressions.get(1) {
28361 self.write(" ");
28362 self.generate_expression(v)?;
28363 }
28364 } else {
28365 self.generate_expression(pair)?;
28366 }
28367 }
28368 self.indent_level -= 1;
28369 self.write_newline();
28370 self.write_indent();
28371 } else {
28372 for (i, pair) in t.expressions.iter().enumerate() {
28373 if i > 0 {
28374 self.write(" ");
28376 }
28377 if let Expression::Tuple(pair_tuple) = pair {
28378 if let Some(k) = pair_tuple.expressions.first() {
28379 self.generate_expression(k)?;
28380 }
28381 if let Some(v) = pair_tuple.expressions.get(1) {
28382 self.write(" ");
28383 self.generate_expression(v)?;
28384 }
28385 } else {
28386 self.generate_expression(pair)?;
28387 }
28388 }
28389 }
28390 } else {
28391 self.generate_expression(settings)?;
28392 }
28393 self.write(")");
28394 } else {
28395 self.write("()");
28397 }
28398 self.write(")");
28399 Ok(())
28400 }
28401
28402 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
28403 let property_name = match e.this.as_ref() {
28404 Expression::Identifier(id) => id.name.as_str(),
28405 Expression::Var(v) => v.this.as_str(),
28406 _ => "RANGE",
28407 };
28408 self.write_keyword(property_name);
28409 self.write("(");
28410 if let Some(min) = &e.min {
28411 self.write_keyword("MIN");
28412 self.write_space();
28413 self.generate_expression(min)?;
28414 }
28415 if let Some(max) = &e.max {
28416 self.write_space();
28417 self.write_keyword("MAX");
28418 self.write_space();
28419 self.generate_expression(max)?;
28420 }
28421 self.write(")");
28422 Ok(())
28423 }
28424
28425 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
28426 if e.local.is_some() {
28428 self.write_keyword("LOCAL ");
28429 }
28430 self.write_keyword("DIRECTORY");
28431 self.write_space();
28432 self.generate_expression(&e.this)?;
28433 if let Some(row_format) = &e.row_format {
28434 self.write_space();
28435 self.generate_expression(row_format)?;
28436 }
28437 Ok(())
28438 }
28439
28440 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
28441 self.write_keyword("DISTKEY");
28443 self.write("(");
28444 self.generate_expression(&e.this)?;
28445 self.write(")");
28446 Ok(())
28447 }
28448
28449 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
28450 self.write_keyword("DISTSTYLE");
28452 self.write_space();
28453 self.generate_expression(&e.this)?;
28454 Ok(())
28455 }
28456
28457 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
28458 self.write_keyword("DISTRIBUTE BY");
28460 self.write_space();
28461 for (i, expr) in e.expressions.iter().enumerate() {
28462 if i > 0 {
28463 self.write(", ");
28464 }
28465 self.generate_expression(expr)?;
28466 }
28467 Ok(())
28468 }
28469
28470 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
28471 self.write_keyword("DISTRIBUTED BY");
28473 self.write_space();
28474 self.write(&e.kind);
28475 if !e.expressions.is_empty() {
28476 self.write(" (");
28477 for (i, expr) in e.expressions.iter().enumerate() {
28478 if i > 0 {
28479 self.write(", ");
28480 }
28481 self.generate_expression(expr)?;
28482 }
28483 self.write(")");
28484 }
28485 if let Some(buckets) = &e.buckets {
28486 self.write_space();
28487 self.write_keyword("BUCKETS");
28488 self.write_space();
28489 self.generate_expression(buckets)?;
28490 }
28491 if let Some(order) = &e.order {
28492 self.write_space();
28493 self.generate_expression(order)?;
28494 }
28495 Ok(())
28496 }
28497
28498 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
28499 self.write_keyword("DOT_PRODUCT");
28501 self.write("(");
28502 self.generate_expression(&e.this)?;
28503 self.write(", ");
28504 self.generate_expression(&e.expression)?;
28505 self.write(")");
28506 Ok(())
28507 }
28508
28509 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
28510 self.write_keyword("DROP");
28512 if e.exists {
28513 self.write_keyword(" IF EXISTS ");
28514 } else {
28515 self.write_space();
28516 }
28517 for (i, expr) in e.expressions.iter().enumerate() {
28518 if i > 0 {
28519 self.write(", ");
28520 }
28521 self.generate_expression(expr)?;
28522 }
28523 Ok(())
28524 }
28525
28526 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
28527 self.write_keyword("DUPLICATE KEY");
28529 self.write(" (");
28530 for (i, expr) in e.expressions.iter().enumerate() {
28531 if i > 0 {
28532 self.write(", ");
28533 }
28534 self.generate_expression(expr)?;
28535 }
28536 self.write(")");
28537 Ok(())
28538 }
28539
28540 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
28541 self.write_keyword("ELT");
28543 self.write("(");
28544 self.generate_expression(&e.this)?;
28545 for expr in &e.expressions {
28546 self.write(", ");
28547 self.generate_expression(expr)?;
28548 }
28549 self.write(")");
28550 Ok(())
28551 }
28552
28553 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
28554 self.write_keyword("ENCODE");
28556 self.write("(");
28557 self.generate_expression(&e.this)?;
28558 if let Some(charset) = &e.charset {
28559 self.write(", ");
28560 self.generate_expression(charset)?;
28561 }
28562 self.write(")");
28563 Ok(())
28564 }
28565
28566 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
28567 if e.key.is_some() {
28569 self.write_keyword("KEY ");
28570 }
28571 self.write_keyword("ENCODE");
28572 self.write_space();
28573 self.generate_expression(&e.this)?;
28574 if !e.properties.is_empty() {
28575 self.write(" (");
28576 for (i, prop) in e.properties.iter().enumerate() {
28577 if i > 0 {
28578 self.write(", ");
28579 }
28580 self.generate_expression(prop)?;
28581 }
28582 self.write(")");
28583 }
28584 Ok(())
28585 }
28586
28587 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
28588 self.write_keyword("ENCRYPT");
28590 self.write("(");
28591 self.generate_expression(&e.this)?;
28592 if let Some(passphrase) = &e.passphrase {
28593 self.write(", ");
28594 self.generate_expression(passphrase)?;
28595 }
28596 if let Some(aad) = &e.aad {
28597 self.write(", ");
28598 self.generate_expression(aad)?;
28599 }
28600 if let Some(method) = &e.encryption_method {
28601 self.write(", ");
28602 self.generate_expression(method)?;
28603 }
28604 self.write(")");
28605 Ok(())
28606 }
28607
28608 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
28609 self.write_keyword("ENCRYPT_RAW");
28611 self.write("(");
28612 self.generate_expression(&e.this)?;
28613 if let Some(key) = &e.key {
28614 self.write(", ");
28615 self.generate_expression(key)?;
28616 }
28617 if let Some(iv) = &e.iv {
28618 self.write(", ");
28619 self.generate_expression(iv)?;
28620 }
28621 if let Some(aad) = &e.aad {
28622 self.write(", ");
28623 self.generate_expression(aad)?;
28624 }
28625 if let Some(method) = &e.encryption_method {
28626 self.write(", ");
28627 self.generate_expression(method)?;
28628 }
28629 self.write(")");
28630 Ok(())
28631 }
28632
28633 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
28634 self.write_keyword("ENGINE");
28636 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
28637 self.write("=");
28638 } else {
28639 self.write(" = ");
28640 }
28641 self.generate_expression(&e.this)?;
28642 Ok(())
28643 }
28644
28645 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
28646 self.write_keyword("ENVIRONMENT");
28648 self.write(" (");
28649 for (i, expr) in e.expressions.iter().enumerate() {
28650 if i > 0 {
28651 self.write(", ");
28652 }
28653 self.generate_expression(expr)?;
28654 }
28655 self.write(")");
28656 Ok(())
28657 }
28658
28659 fn generate_ephemeral_column_constraint(
28660 &mut self,
28661 e: &EphemeralColumnConstraint,
28662 ) -> Result<()> {
28663 self.write_keyword("EPHEMERAL");
28665 if let Some(this) = &e.this {
28666 self.write_space();
28667 self.generate_expression(this)?;
28668 }
28669 Ok(())
28670 }
28671
28672 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
28673 self.write_keyword("EQUAL_NULL");
28675 self.write("(");
28676 self.generate_expression(&e.this)?;
28677 self.write(", ");
28678 self.generate_expression(&e.expression)?;
28679 self.write(")");
28680 Ok(())
28681 }
28682
28683 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
28684 use crate::dialects::DialectType;
28685
28686 match self.config.dialect {
28688 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
28689 self.generate_expression(&e.this)?;
28690 self.write(" <-> ");
28691 self.generate_expression(&e.expression)?;
28692 }
28693 _ => {
28694 self.write_keyword("EUCLIDEAN_DISTANCE");
28696 self.write("(");
28697 self.generate_expression(&e.this)?;
28698 self.write(", ");
28699 self.generate_expression(&e.expression)?;
28700 self.write(")");
28701 }
28702 }
28703 Ok(())
28704 }
28705
28706 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
28707 self.write_keyword("EXECUTE AS");
28709 self.write_space();
28710 self.generate_expression(&e.this)?;
28711 Ok(())
28712 }
28713
28714 fn generate_export(&mut self, e: &Export) -> Result<()> {
28715 self.write_keyword("EXPORT DATA");
28717 if let Some(connection) = &e.connection {
28718 self.write_space();
28719 self.write_keyword("WITH CONNECTION");
28720 self.write_space();
28721 self.generate_expression(connection)?;
28722 }
28723 if !e.options.is_empty() {
28724 self.write_space();
28725 self.generate_options_clause(&e.options)?;
28726 }
28727 self.write_space();
28728 self.write_keyword("AS");
28729 self.write_space();
28730 self.generate_expression(&e.this)?;
28731 Ok(())
28732 }
28733
28734 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
28735 self.write_keyword("EXTERNAL");
28737 if let Some(this) = &e.this {
28738 self.write_space();
28739 self.generate_expression(this)?;
28740 }
28741 Ok(())
28742 }
28743
28744 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
28745 if e.no.is_some() {
28747 self.write_keyword("NO ");
28748 }
28749 self.write_keyword("FALLBACK");
28750 if e.protection.is_some() {
28751 self.write_keyword(" PROTECTION");
28752 }
28753 Ok(())
28754 }
28755
28756 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
28757 self.write_keyword("FARM_FINGERPRINT");
28759 self.write("(");
28760 for (i, expr) in e.expressions.iter().enumerate() {
28761 if i > 0 {
28762 self.write(", ");
28763 }
28764 self.generate_expression(expr)?;
28765 }
28766 self.write(")");
28767 Ok(())
28768 }
28769
28770 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
28771 self.write_keyword("FEATURES_AT_TIME");
28773 self.write("(");
28774 self.generate_expression(&e.this)?;
28775 if let Some(time) = &e.time {
28776 self.write(", ");
28777 self.generate_expression(time)?;
28778 }
28779 if let Some(num_rows) = &e.num_rows {
28780 self.write(", ");
28781 self.generate_expression(num_rows)?;
28782 }
28783 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
28784 self.write(", ");
28785 self.generate_expression(ignore_nulls)?;
28786 }
28787 self.write(")");
28788 Ok(())
28789 }
28790
28791 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
28792 let use_limit = !e.percent
28794 && !e.with_ties
28795 && e.count.is_some()
28796 && matches!(
28797 self.config.dialect,
28798 Some(DialectType::Spark)
28799 | Some(DialectType::Hive)
28800 | Some(DialectType::DuckDB)
28801 | Some(DialectType::SQLite)
28802 | Some(DialectType::MySQL)
28803 | Some(DialectType::BigQuery)
28804 | Some(DialectType::Databricks)
28805 | Some(DialectType::StarRocks)
28806 | Some(DialectType::Doris)
28807 | Some(DialectType::Athena)
28808 | Some(DialectType::ClickHouse)
28809 );
28810
28811 if use_limit {
28812 self.write_keyword("LIMIT");
28813 self.write_space();
28814 self.generate_expression(e.count.as_ref().unwrap())?;
28815 return Ok(());
28816 }
28817
28818 self.write_keyword("FETCH");
28820 if !e.direction.is_empty() {
28821 self.write_space();
28822 self.write_keyword(&e.direction);
28823 }
28824 if let Some(count) = &e.count {
28825 self.write_space();
28826 self.generate_expression(count)?;
28827 }
28828 if e.percent {
28830 self.write_keyword(" PERCENT");
28831 }
28832 if e.rows {
28833 self.write_keyword(" ROWS");
28834 }
28835 if e.with_ties {
28836 self.write_keyword(" WITH TIES");
28837 } else if e.rows {
28838 self.write_keyword(" ONLY");
28839 } else {
28840 self.write_keyword(" ROWS ONLY");
28841 }
28842 Ok(())
28843 }
28844
28845 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
28846 if e.hive_format.is_some() {
28850 self.write_keyword("STORED AS");
28852 self.write_space();
28853 if let Some(this) = &e.this {
28854 if let Expression::Identifier(id) = this.as_ref() {
28856 self.write_keyword(&id.name.to_ascii_uppercase());
28857 } else {
28858 self.generate_expression(this)?;
28859 }
28860 }
28861 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
28862 self.write_keyword("STORED AS");
28864 self.write_space();
28865 if let Some(this) = &e.this {
28866 if let Expression::Identifier(id) = this.as_ref() {
28867 self.write_keyword(&id.name.to_ascii_uppercase());
28868 } else {
28869 self.generate_expression(this)?;
28870 }
28871 }
28872 } else if matches!(
28873 self.config.dialect,
28874 Some(DialectType::Spark) | Some(DialectType::Databricks)
28875 ) {
28876 self.write_keyword("USING");
28878 self.write_space();
28879 if let Some(this) = &e.this {
28880 self.generate_expression(this)?;
28881 }
28882 } else {
28883 self.write_keyword("FILE_FORMAT");
28885 self.write(" = ");
28886 if let Some(this) = &e.this {
28887 self.generate_expression(this)?;
28888 } else if !e.expressions.is_empty() {
28889 self.write("(");
28890 for (i, expr) in e.expressions.iter().enumerate() {
28891 if i > 0 {
28892 self.write(", ");
28893 }
28894 self.generate_expression(expr)?;
28895 }
28896 self.write(")");
28897 }
28898 }
28899 Ok(())
28900 }
28901
28902 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
28903 self.generate_expression(&e.this)?;
28905 self.write_space();
28906 self.write_keyword("FILTER");
28907 self.write("(");
28908 self.write_keyword("WHERE");
28909 self.write_space();
28910 self.generate_expression(&e.expression)?;
28911 self.write(")");
28912 Ok(())
28913 }
28914
28915 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
28916 self.write_keyword("FLOAT64");
28918 self.write("(");
28919 self.generate_expression(&e.this)?;
28920 if let Some(expr) = &e.expression {
28921 self.write(", ");
28922 self.generate_expression(expr)?;
28923 }
28924 self.write(")");
28925 Ok(())
28926 }
28927
28928 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
28929 self.write_keyword("FOR");
28931 self.write_space();
28932 self.generate_expression(&e.this)?;
28933 self.write_space();
28934 self.write_keyword("DO");
28935 self.write_space();
28936 self.generate_expression(&e.expression)?;
28937 Ok(())
28938 }
28939
28940 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
28941 self.write_keyword("FOREIGN KEY");
28943 if !e.expressions.is_empty() {
28944 self.write(" (");
28945 for (i, expr) in e.expressions.iter().enumerate() {
28946 if i > 0 {
28947 self.write(", ");
28948 }
28949 self.generate_expression(expr)?;
28950 }
28951 self.write(")");
28952 }
28953 if let Some(reference) = &e.reference {
28954 self.write_space();
28955 self.generate_expression(reference)?;
28956 }
28957 if let Some(delete) = &e.delete {
28958 self.write_space();
28959 self.write_keyword("ON DELETE");
28960 self.write_space();
28961 self.generate_expression(delete)?;
28962 }
28963 if let Some(update) = &e.update {
28964 self.write_space();
28965 self.write_keyword("ON UPDATE");
28966 self.write_space();
28967 self.generate_expression(update)?;
28968 }
28969 if !e.options.is_empty() {
28970 self.write_space();
28971 for (i, opt) in e.options.iter().enumerate() {
28972 if i > 0 {
28973 self.write_space();
28974 }
28975 self.generate_expression(opt)?;
28976 }
28977 }
28978 Ok(())
28979 }
28980
28981 fn generate_format(&mut self, e: &Format) -> Result<()> {
28982 self.write_keyword("FORMAT");
28984 self.write("(");
28985 self.generate_expression(&e.this)?;
28986 for expr in &e.expressions {
28987 self.write(", ");
28988 self.generate_expression(expr)?;
28989 }
28990 self.write(")");
28991 Ok(())
28992 }
28993
28994 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
28995 self.generate_expression(&e.this)?;
28997 self.write(" (");
28998 self.write_keyword("FORMAT");
28999 self.write(" '");
29000 self.write(&e.format);
29001 self.write("')");
29002 Ok(())
29003 }
29004
29005 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
29006 self.write_keyword("FREESPACE");
29008 self.write("=");
29009 self.generate_expression(&e.this)?;
29010 if e.percent.is_some() {
29011 self.write_keyword(" PERCENT");
29012 }
29013 Ok(())
29014 }
29015
29016 fn generate_from(&mut self, e: &From) -> Result<()> {
29017 self.write_keyword("FROM");
29019 self.write_space();
29020
29021 use crate::dialects::DialectType;
29025 let has_tablesample = e
29026 .expressions
29027 .iter()
29028 .any(|expr| matches!(expr, Expression::TableSample(_)));
29029 let is_cross_join_dialect = matches!(
29030 self.config.dialect,
29031 Some(DialectType::BigQuery)
29032 | Some(DialectType::Hive)
29033 | Some(DialectType::Spark)
29034 | Some(DialectType::Databricks)
29035 | Some(DialectType::SQLite)
29036 | Some(DialectType::ClickHouse)
29037 );
29038 let source_is_same_as_target2 = self.config.source_dialect.is_some()
29039 && self.config.source_dialect == self.config.dialect;
29040 let source_is_cross_join_dialect2 = matches!(
29041 self.config.source_dialect,
29042 Some(DialectType::BigQuery)
29043 | Some(DialectType::Hive)
29044 | Some(DialectType::Spark)
29045 | Some(DialectType::Databricks)
29046 | Some(DialectType::SQLite)
29047 | Some(DialectType::ClickHouse)
29048 );
29049 let use_cross_join = !has_tablesample
29050 && is_cross_join_dialect
29051 && (source_is_same_as_target2
29052 || source_is_cross_join_dialect2
29053 || self.config.source_dialect.is_none());
29054
29055 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
29057
29058 for (i, expr) in e.expressions.iter().enumerate() {
29059 if i > 0 {
29060 if use_cross_join {
29061 self.write(" CROSS JOIN ");
29062 } else {
29063 self.write(", ");
29064 }
29065 }
29066 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
29067 self.write("(");
29068 self.generate_expression(expr)?;
29069 self.write(")");
29070 } else {
29071 self.generate_expression(expr)?;
29072 }
29073 let leading = Self::extract_table_leading_comments(expr);
29076 for comment in &leading {
29077 self.write_space();
29078 self.write_formatted_comment(comment);
29079 }
29080 }
29081 Ok(())
29082 }
29083
29084 fn extract_table_leading_comments(expr: &Expression) -> Vec<String> {
29086 match expr {
29087 Expression::Table(t) => t.leading_comments.clone(),
29088 Expression::Pivot(p) => {
29089 if let Expression::Table(t) = &p.this {
29090 t.leading_comments.clone()
29091 } else {
29092 Vec::new()
29093 }
29094 }
29095 _ => Vec::new(),
29096 }
29097 }
29098
29099 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
29100 self.write_keyword("FROM_BASE");
29102 self.write("(");
29103 self.generate_expression(&e.this)?;
29104 self.write(", ");
29105 self.generate_expression(&e.expression)?;
29106 self.write(")");
29107 Ok(())
29108 }
29109
29110 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
29111 self.generate_expression(&e.this)?;
29113 if let Some(zone) = &e.zone {
29114 self.write_space();
29115 self.write_keyword("AT TIME ZONE");
29116 self.write_space();
29117 self.generate_expression(zone)?;
29118 self.write_space();
29119 self.write_keyword("AT TIME ZONE");
29120 self.write(" 'UTC'");
29121 }
29122 Ok(())
29123 }
29124
29125 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
29126 self.write_keyword("GAP_FILL");
29128 self.write("(");
29129 self.generate_expression(&e.this)?;
29130 if let Some(ts_column) = &e.ts_column {
29131 self.write(", ");
29132 self.generate_expression(ts_column)?;
29133 }
29134 if let Some(bucket_width) = &e.bucket_width {
29135 self.write(", ");
29136 self.generate_expression(bucket_width)?;
29137 }
29138 if let Some(partitioning_columns) = &e.partitioning_columns {
29139 self.write(", ");
29140 self.generate_expression(partitioning_columns)?;
29141 }
29142 if let Some(value_columns) = &e.value_columns {
29143 self.write(", ");
29144 self.generate_expression(value_columns)?;
29145 }
29146 self.write(")");
29147 Ok(())
29148 }
29149
29150 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
29151 self.write_keyword("GENERATE_DATE_ARRAY");
29153 self.write("(");
29154 let mut first = true;
29155 if let Some(start) = &e.start {
29156 self.generate_expression(start)?;
29157 first = false;
29158 }
29159 if let Some(end) = &e.end {
29160 if !first {
29161 self.write(", ");
29162 }
29163 self.generate_expression(end)?;
29164 first = false;
29165 }
29166 if let Some(step) = &e.step {
29167 if !first {
29168 self.write(", ");
29169 }
29170 self.generate_expression(step)?;
29171 }
29172 self.write(")");
29173 Ok(())
29174 }
29175
29176 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
29177 self.write_keyword("ML.GENERATE_EMBEDDING");
29179 self.write("(");
29180 self.generate_expression(&e.this)?;
29181 self.write(", ");
29182 self.generate_expression(&e.expression)?;
29183 if let Some(params) = &e.params_struct {
29184 self.write(", ");
29185 self.generate_expression(params)?;
29186 }
29187 self.write(")");
29188 Ok(())
29189 }
29190
29191 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
29192 let fn_name = match self.config.dialect {
29194 Some(DialectType::Presto)
29195 | Some(DialectType::Trino)
29196 | Some(DialectType::Athena)
29197 | Some(DialectType::Spark)
29198 | Some(DialectType::Databricks)
29199 | Some(DialectType::Hive) => "SEQUENCE",
29200 _ => "GENERATE_SERIES",
29201 };
29202 self.write_keyword(fn_name);
29203 self.write("(");
29204 let mut first = true;
29205 if let Some(start) = &e.start {
29206 self.generate_expression(start)?;
29207 first = false;
29208 }
29209 if let Some(end) = &e.end {
29210 if !first {
29211 self.write(", ");
29212 }
29213 self.generate_expression(end)?;
29214 first = false;
29215 }
29216 if let Some(step) = &e.step {
29217 if !first {
29218 self.write(", ");
29219 }
29220 if matches!(
29223 self.config.dialect,
29224 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
29225 ) {
29226 if let Some(converted) = self.convert_week_interval_to_day(step) {
29227 self.generate_expression(&converted)?;
29228 } else {
29229 self.generate_expression(step)?;
29230 }
29231 } else {
29232 self.generate_expression(step)?;
29233 }
29234 }
29235 self.write(")");
29236 Ok(())
29237 }
29238
29239 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
29242 use crate::expressions::*;
29243 if let Expression::Interval(ref iv) = expr {
29244 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
29246 unit: IntervalUnit::Week,
29247 ..
29248 }) = &iv.unit
29249 {
29250 let count = match &iv.this {
29252 Some(Expression::Literal(lit)) => match lit.as_ref() {
29253 Literal::String(s) | Literal::Number(s) => s.clone(),
29254 _ => return None,
29255 },
29256 _ => return None,
29257 };
29258 (true, count)
29259 } else if iv.unit.is_none() {
29260 if let Some(Expression::Literal(lit)) = &iv.this {
29262 if let Literal::String(s) = lit.as_ref() {
29263 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
29264 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
29265 (true, parts[0].to_string())
29266 } else {
29267 (false, String::new())
29268 }
29269 } else {
29270 (false, String::new())
29271 }
29272 } else {
29273 (false, String::new())
29274 }
29275 } else {
29276 (false, String::new())
29277 };
29278
29279 if is_week {
29280 let count_expr = Expression::Literal(Box::new(Literal::Number(count_str)));
29282 let day_interval = Expression::Interval(Box::new(Interval {
29283 this: Some(Expression::Literal(Box::new(Literal::String(
29284 "7".to_string(),
29285 )))),
29286 unit: Some(IntervalUnitSpec::Simple {
29287 unit: IntervalUnit::Day,
29288 use_plural: false,
29289 }),
29290 }));
29291 let mul = Expression::Mul(Box::new(BinaryOp {
29292 left: count_expr,
29293 right: day_interval,
29294 left_comments: vec![],
29295 operator_comments: vec![],
29296 trailing_comments: vec![],
29297 inferred_type: None,
29298 }));
29299 return Some(Expression::Paren(Box::new(Paren {
29300 this: mul,
29301 trailing_comments: vec![],
29302 })));
29303 }
29304 }
29305 None
29306 }
29307
29308 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
29309 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
29311 self.write("(");
29312 let mut first = true;
29313 if let Some(start) = &e.start {
29314 self.generate_expression(start)?;
29315 first = false;
29316 }
29317 if let Some(end) = &e.end {
29318 if !first {
29319 self.write(", ");
29320 }
29321 self.generate_expression(end)?;
29322 first = false;
29323 }
29324 if let Some(step) = &e.step {
29325 if !first {
29326 self.write(", ");
29327 }
29328 self.generate_expression(step)?;
29329 }
29330 self.write(")");
29331 Ok(())
29332 }
29333
29334 fn generate_generated_as_identity_column_constraint(
29335 &mut self,
29336 e: &GeneratedAsIdentityColumnConstraint,
29337 ) -> Result<()> {
29338 use crate::dialects::DialectType;
29339
29340 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
29342 self.write_keyword("AUTOINCREMENT");
29343 if let Some(start) = &e.start {
29344 self.write_keyword(" START ");
29345 self.generate_expression(start)?;
29346 }
29347 if let Some(increment) = &e.increment {
29348 self.write_keyword(" INCREMENT ");
29349 self.generate_expression(increment)?;
29350 }
29351 return Ok(());
29352 }
29353
29354 self.write_keyword("GENERATED");
29356 if let Some(this) = &e.this {
29357 if let Expression::Boolean(b) = this.as_ref() {
29359 if b.value {
29360 self.write_keyword(" ALWAYS");
29361 } else {
29362 self.write_keyword(" BY DEFAULT");
29363 if e.on_null.is_some() {
29364 self.write_keyword(" ON NULL");
29365 }
29366 }
29367 } else {
29368 self.write_keyword(" ALWAYS");
29369 }
29370 }
29371 self.write_keyword(" AS IDENTITY");
29372 let has_options = e.start.is_some()
29374 || e.increment.is_some()
29375 || e.minvalue.is_some()
29376 || e.maxvalue.is_some();
29377 if has_options {
29378 self.write(" (");
29379 let mut first = true;
29380 if let Some(start) = &e.start {
29381 self.write_keyword("START WITH ");
29382 self.generate_expression(start)?;
29383 first = false;
29384 }
29385 if let Some(increment) = &e.increment {
29386 if !first {
29387 self.write(" ");
29388 }
29389 self.write_keyword("INCREMENT BY ");
29390 self.generate_expression(increment)?;
29391 first = false;
29392 }
29393 if let Some(minvalue) = &e.minvalue {
29394 if !first {
29395 self.write(" ");
29396 }
29397 self.write_keyword("MINVALUE ");
29398 self.generate_expression(minvalue)?;
29399 first = false;
29400 }
29401 if let Some(maxvalue) = &e.maxvalue {
29402 if !first {
29403 self.write(" ");
29404 }
29405 self.write_keyword("MAXVALUE ");
29406 self.generate_expression(maxvalue)?;
29407 }
29408 self.write(")");
29409 }
29410 Ok(())
29411 }
29412
29413 fn generate_generated_as_row_column_constraint(
29414 &mut self,
29415 e: &GeneratedAsRowColumnConstraint,
29416 ) -> Result<()> {
29417 self.write_keyword("GENERATED ALWAYS AS ROW ");
29419 if e.start.is_some() {
29420 self.write_keyword("START");
29421 } else {
29422 self.write_keyword("END");
29423 }
29424 if e.hidden.is_some() {
29425 self.write_keyword(" HIDDEN");
29426 }
29427 Ok(())
29428 }
29429
29430 fn generate_get(&mut self, e: &Get) -> Result<()> {
29431 self.write_keyword("GET");
29433 self.write_space();
29434 self.generate_expression(&e.this)?;
29435 if let Some(target) = &e.target {
29436 self.write_space();
29437 self.generate_expression(target)?;
29438 }
29439 for prop in &e.properties {
29440 self.write_space();
29441 self.generate_expression(prop)?;
29442 }
29443 Ok(())
29444 }
29445
29446 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
29447 self.generate_expression(&e.this)?;
29449 self.write("[");
29450 self.generate_expression(&e.expression)?;
29451 self.write("]");
29452 Ok(())
29453 }
29454
29455 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
29456 self.write_keyword("GETBIT");
29458 self.write("(");
29459 self.generate_expression(&e.this)?;
29460 self.write(", ");
29461 self.generate_expression(&e.expression)?;
29462 self.write(")");
29463 Ok(())
29464 }
29465
29466 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
29467 if e.is_role {
29469 self.write_keyword("ROLE");
29470 self.write_space();
29471 } else if e.is_group {
29472 self.write_keyword("GROUP");
29473 self.write_space();
29474 } else if e.is_share {
29475 self.write_keyword("SHARE");
29476 self.write_space();
29477 }
29478 self.write(&e.name.name);
29479 Ok(())
29480 }
29481
29482 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
29483 self.generate_expression(&e.this)?;
29485 if !e.expressions.is_empty() {
29486 self.write("(");
29487 for (i, expr) in e.expressions.iter().enumerate() {
29488 if i > 0 {
29489 self.write(", ");
29490 }
29491 self.generate_expression(expr)?;
29492 }
29493 self.write(")");
29494 }
29495 Ok(())
29496 }
29497
29498 fn generate_group(&mut self, e: &Group) -> Result<()> {
29499 self.write_keyword("GROUP BY");
29501 match e.all {
29503 Some(true) => {
29504 self.write_space();
29505 self.write_keyword("ALL");
29506 }
29507 Some(false) => {
29508 self.write_space();
29509 self.write_keyword("DISTINCT");
29510 }
29511 None => {}
29512 }
29513 if !e.expressions.is_empty() {
29514 self.write_space();
29515 for (i, expr) in e.expressions.iter().enumerate() {
29516 if i > 0 {
29517 self.write(", ");
29518 }
29519 self.generate_expression(expr)?;
29520 }
29521 }
29522 if let Some(cube) = &e.cube {
29524 if !e.expressions.is_empty() {
29525 self.write(", ");
29526 } else {
29527 self.write_space();
29528 }
29529 self.generate_expression(cube)?;
29530 }
29531 if let Some(rollup) = &e.rollup {
29532 if !e.expressions.is_empty() || e.cube.is_some() {
29533 self.write(", ");
29534 } else {
29535 self.write_space();
29536 }
29537 self.generate_expression(rollup)?;
29538 }
29539 if let Some(grouping_sets) = &e.grouping_sets {
29540 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
29541 self.write(", ");
29542 } else {
29543 self.write_space();
29544 }
29545 self.generate_expression(grouping_sets)?;
29546 }
29547 if let Some(totals) = &e.totals {
29548 self.write_space();
29549 self.write_keyword("WITH TOTALS");
29550 self.generate_expression(totals)?;
29551 }
29552 Ok(())
29553 }
29554
29555 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
29556 self.write_keyword("GROUP BY");
29558 match e.all {
29560 Some(true) => {
29561 self.write_space();
29562 self.write_keyword("ALL");
29563 }
29564 Some(false) => {
29565 self.write_space();
29566 self.write_keyword("DISTINCT");
29567 }
29568 None => {}
29569 }
29570
29571 let mut trailing_cube = false;
29574 let mut trailing_rollup = false;
29575 let mut regular_expressions: Vec<&Expression> = Vec::new();
29576
29577 for expr in &e.expressions {
29578 match expr {
29579 Expression::Cube(c) if c.expressions.is_empty() => {
29580 trailing_cube = true;
29581 }
29582 Expression::Rollup(r) if r.expressions.is_empty() => {
29583 trailing_rollup = true;
29584 }
29585 _ => {
29586 regular_expressions.push(expr);
29587 }
29588 }
29589 }
29590
29591 if self.config.pretty {
29593 self.write_newline();
29594 self.indent_level += 1;
29595 for (i, expr) in regular_expressions.iter().enumerate() {
29596 if i > 0 {
29597 self.write(",");
29598 self.write_newline();
29599 }
29600 self.write_indent();
29601 self.generate_expression(expr)?;
29602 }
29603 self.indent_level -= 1;
29604 } else {
29605 self.write_space();
29606 for (i, expr) in regular_expressions.iter().enumerate() {
29607 if i > 0 {
29608 self.write(", ");
29609 }
29610 self.generate_expression(expr)?;
29611 }
29612 }
29613
29614 if trailing_cube {
29616 self.write_space();
29617 self.write_keyword("WITH CUBE");
29618 } else if trailing_rollup {
29619 self.write_space();
29620 self.write_keyword("WITH ROLLUP");
29621 }
29622
29623 if e.totals {
29625 self.write_space();
29626 self.write_keyword("WITH TOTALS");
29627 }
29628
29629 Ok(())
29630 }
29631
29632 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
29633 self.write_keyword("GROUPING");
29635 self.write("(");
29636 for (i, expr) in e.expressions.iter().enumerate() {
29637 if i > 0 {
29638 self.write(", ");
29639 }
29640 self.generate_expression(expr)?;
29641 }
29642 self.write(")");
29643 Ok(())
29644 }
29645
29646 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
29647 self.write_keyword("GROUPING_ID");
29649 self.write("(");
29650 for (i, expr) in e.expressions.iter().enumerate() {
29651 if i > 0 {
29652 self.write(", ");
29653 }
29654 self.generate_expression(expr)?;
29655 }
29656 self.write(")");
29657 Ok(())
29658 }
29659
29660 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
29661 self.write_keyword("GROUPING SETS");
29663 self.write(" (");
29664 for (i, expr) in e.expressions.iter().enumerate() {
29665 if i > 0 {
29666 self.write(", ");
29667 }
29668 self.generate_expression(expr)?;
29669 }
29670 self.write(")");
29671 Ok(())
29672 }
29673
29674 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
29675 self.write_keyword("HASH_AGG");
29677 self.write("(");
29678 self.generate_expression(&e.this)?;
29679 for expr in &e.expressions {
29680 self.write(", ");
29681 self.generate_expression(expr)?;
29682 }
29683 self.write(")");
29684 Ok(())
29685 }
29686
29687 fn generate_having(&mut self, e: &Having) -> Result<()> {
29688 self.write_keyword("HAVING");
29690 self.write_space();
29691 self.generate_expression(&e.this)?;
29692 Ok(())
29693 }
29694
29695 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
29696 self.generate_expression(&e.this)?;
29698 self.write_space();
29699 self.write_keyword("HAVING");
29700 self.write_space();
29701 if e.max.is_some() {
29702 self.write_keyword("MAX");
29703 } else {
29704 self.write_keyword("MIN");
29705 }
29706 self.write_space();
29707 self.generate_expression(&e.expression)?;
29708 Ok(())
29709 }
29710
29711 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
29712 use crate::dialects::DialectType;
29713 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
29715 if let Expression::Literal(ref lit) = *e.this {
29717 if let Literal::String(ref s) = lit.as_ref() {
29718 return self.generate_string_literal(s);
29719 }
29720 }
29721 }
29722 if matches!(
29724 self.config.dialect,
29725 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
29726 ) {
29727 self.write("$");
29728 if let Some(tag) = &e.tag {
29729 self.generate_expression(tag)?;
29730 }
29731 self.write("$");
29732 self.generate_expression(&e.this)?;
29733 self.write("$");
29734 if let Some(tag) = &e.tag {
29735 self.generate_expression(tag)?;
29736 }
29737 self.write("$");
29738 return Ok(());
29739 }
29740 self.write("$");
29742 if let Some(tag) = &e.tag {
29743 self.generate_expression(tag)?;
29744 }
29745 self.write("$");
29746 self.generate_expression(&e.this)?;
29747 self.write("$");
29748 if let Some(tag) = &e.tag {
29749 self.generate_expression(tag)?;
29750 }
29751 self.write("$");
29752 Ok(())
29753 }
29754
29755 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
29756 self.write_keyword("HEX_ENCODE");
29758 self.write("(");
29759 self.generate_expression(&e.this)?;
29760 self.write(")");
29761 Ok(())
29762 }
29763
29764 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
29765 match e.this.as_ref() {
29768 Expression::Identifier(id) => self.write(&id.name),
29769 other => self.generate_expression(other)?,
29770 }
29771 self.write(" (");
29772 self.write(&e.kind);
29773 self.write(" => ");
29774 self.generate_expression(&e.expression)?;
29775 self.write(")");
29776 Ok(())
29777 }
29778
29779 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
29780 self.write_keyword("HLL");
29782 self.write("(");
29783 self.generate_expression(&e.this)?;
29784 for expr in &e.expressions {
29785 self.write(", ");
29786 self.generate_expression(expr)?;
29787 }
29788 self.write(")");
29789 Ok(())
29790 }
29791
29792 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
29793 if e.input_.is_some() && e.output.is_some() {
29795 self.write_keyword("IN OUT");
29796 } else if e.input_.is_some() {
29797 self.write_keyword("IN");
29798 } else if e.output.is_some() {
29799 self.write_keyword("OUT");
29800 }
29801 Ok(())
29802 }
29803
29804 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
29805 self.write_keyword("INCLUDE");
29807 self.write_space();
29808 self.generate_expression(&e.this)?;
29809 if let Some(column_def) = &e.column_def {
29810 self.write_space();
29811 self.generate_expression(column_def)?;
29812 }
29813 if let Some(alias) = &e.alias {
29814 self.write_space();
29815 self.write_keyword("AS");
29816 self.write_space();
29817 self.write(alias);
29818 }
29819 Ok(())
29820 }
29821
29822 fn generate_index(&mut self, e: &Index) -> Result<()> {
29823 if e.unique {
29825 self.write_keyword("UNIQUE");
29826 self.write_space();
29827 }
29828 if e.primary.is_some() {
29829 self.write_keyword("PRIMARY");
29830 self.write_space();
29831 }
29832 if e.amp.is_some() {
29833 self.write_keyword("AMP");
29834 self.write_space();
29835 }
29836 if e.table.is_none() {
29837 self.write_keyword("INDEX");
29838 self.write_space();
29839 }
29840 if let Some(name) = &e.this {
29841 self.generate_expression(name)?;
29842 self.write_space();
29843 }
29844 if let Some(table) = &e.table {
29845 self.write_keyword("ON");
29846 self.write_space();
29847 self.generate_expression(table)?;
29848 }
29849 if !e.params.is_empty() {
29850 self.write("(");
29851 for (i, param) in e.params.iter().enumerate() {
29852 if i > 0 {
29853 self.write(", ");
29854 }
29855 self.generate_expression(param)?;
29856 }
29857 self.write(")");
29858 }
29859 Ok(())
29860 }
29861
29862 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
29863 if let Some(kind) = &e.kind {
29865 self.write(kind);
29866 self.write_space();
29867 }
29868 self.write_keyword("INDEX");
29869 if let Some(this) = &e.this {
29870 self.write_space();
29871 self.generate_expression(this)?;
29872 }
29873 if let Some(index_type) = &e.index_type {
29874 self.write_space();
29875 self.write_keyword("USING");
29876 self.write_space();
29877 self.generate_expression(index_type)?;
29878 }
29879 if !e.expressions.is_empty() {
29880 self.write(" (");
29881 for (i, expr) in e.expressions.iter().enumerate() {
29882 if i > 0 {
29883 self.write(", ");
29884 }
29885 self.generate_expression(expr)?;
29886 }
29887 self.write(")");
29888 }
29889 for opt in &e.options {
29890 self.write_space();
29891 self.generate_expression(opt)?;
29892 }
29893 Ok(())
29894 }
29895
29896 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
29897 if let Some(key_block_size) = &e.key_block_size {
29899 self.write_keyword("KEY_BLOCK_SIZE");
29900 self.write(" = ");
29901 self.generate_expression(key_block_size)?;
29902 } else if let Some(using) = &e.using {
29903 self.write_keyword("USING");
29904 self.write_space();
29905 self.generate_expression(using)?;
29906 } else if let Some(parser) = &e.parser {
29907 self.write_keyword("WITH PARSER");
29908 self.write_space();
29909 self.generate_expression(parser)?;
29910 } else if let Some(comment) = &e.comment {
29911 self.write_keyword("COMMENT");
29912 self.write_space();
29913 self.generate_expression(comment)?;
29914 } else if let Some(visible) = &e.visible {
29915 self.generate_expression(visible)?;
29916 } else if let Some(engine_attr) = &e.engine_attr {
29917 self.write_keyword("ENGINE_ATTRIBUTE");
29918 self.write(" = ");
29919 self.generate_expression(engine_attr)?;
29920 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
29921 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
29922 self.write(" = ");
29923 self.generate_expression(secondary_engine_attr)?;
29924 }
29925 Ok(())
29926 }
29927
29928 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
29929 if let Some(using) = &e.using {
29931 self.write_keyword("USING");
29932 self.write_space();
29933 self.generate_expression(using)?;
29934 }
29935 if !e.columns.is_empty() {
29936 self.write("(");
29937 for (i, col) in e.columns.iter().enumerate() {
29938 if i > 0 {
29939 self.write(", ");
29940 }
29941 self.generate_expression(col)?;
29942 }
29943 self.write(")");
29944 }
29945 if let Some(partition_by) = &e.partition_by {
29946 self.write_space();
29947 self.write_keyword("PARTITION BY");
29948 self.write_space();
29949 self.generate_expression(partition_by)?;
29950 }
29951 if let Some(where_) = &e.where_ {
29952 self.write_space();
29953 self.generate_expression(where_)?;
29954 }
29955 if let Some(include) = &e.include {
29956 self.write_space();
29957 self.write_keyword("INCLUDE");
29958 self.write(" (");
29959 self.generate_expression(include)?;
29960 self.write(")");
29961 }
29962 if let Some(with_storage) = &e.with_storage {
29963 self.write_space();
29964 self.write_keyword("WITH");
29965 self.write(" (");
29966 self.generate_expression(with_storage)?;
29967 self.write(")");
29968 }
29969 if let Some(tablespace) = &e.tablespace {
29970 self.write_space();
29971 self.write_keyword("USING INDEX TABLESPACE");
29972 self.write_space();
29973 self.generate_expression(tablespace)?;
29974 }
29975 Ok(())
29976 }
29977
29978 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
29979 if let Expression::Identifier(id) = &*e.this {
29983 self.write_keyword(&id.name);
29984 } else {
29985 self.generate_expression(&e.this)?;
29986 }
29987 self.write_space();
29988 self.write_keyword("INDEX");
29989 if let Some(target) = &e.target {
29990 self.write_space();
29991 self.write_keyword("FOR");
29992 self.write_space();
29993 if let Expression::Identifier(id) = &**target {
29994 self.write_keyword(&id.name);
29995 } else {
29996 self.generate_expression(target)?;
29997 }
29998 }
29999 self.write(" (");
30001 for (i, expr) in e.expressions.iter().enumerate() {
30002 if i > 0 {
30003 self.write(", ");
30004 }
30005 self.generate_expression(expr)?;
30006 }
30007 self.write(")");
30008 Ok(())
30009 }
30010
30011 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
30012 self.write_keyword("INHERITS");
30014 self.write(" (");
30015 for (i, expr) in e.expressions.iter().enumerate() {
30016 if i > 0 {
30017 self.write(", ");
30018 }
30019 self.generate_expression(expr)?;
30020 }
30021 self.write(")");
30022 Ok(())
30023 }
30024
30025 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
30026 self.write_keyword("INPUT");
30028 self.write("(");
30029 self.generate_expression(&e.this)?;
30030 self.write(")");
30031 Ok(())
30032 }
30033
30034 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
30035 if let Some(input_format) = &e.input_format {
30037 self.write_keyword("INPUTFORMAT");
30038 self.write_space();
30039 self.generate_expression(input_format)?;
30040 }
30041 if let Some(output_format) = &e.output_format {
30042 if e.input_format.is_some() {
30043 self.write(" ");
30044 }
30045 self.write_keyword("OUTPUTFORMAT");
30046 self.write_space();
30047 self.generate_expression(output_format)?;
30048 }
30049 Ok(())
30050 }
30051
30052 fn generate_install(&mut self, e: &Install) -> Result<()> {
30053 if e.force.is_some() {
30055 self.write_keyword("FORCE");
30056 self.write_space();
30057 }
30058 self.write_keyword("INSTALL");
30059 self.write_space();
30060 self.generate_expression(&e.this)?;
30061 if let Some(from) = &e.from_ {
30062 self.write_space();
30063 self.write_keyword("FROM");
30064 self.write_space();
30065 self.generate_expression(from)?;
30066 }
30067 Ok(())
30068 }
30069
30070 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
30071 self.write_keyword("INTERVAL");
30073 self.write_space();
30074 self.generate_expression(&e.expression)?;
30076 if let Some(unit) = &e.unit {
30077 self.write_space();
30078 self.write(unit);
30079 }
30080 Ok(())
30081 }
30082
30083 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
30084 self.write(&format!("{:?}", e.this).to_ascii_uppercase());
30086 self.write_space();
30087 self.write_keyword("TO");
30088 self.write_space();
30089 self.write(&format!("{:?}", e.expression).to_ascii_uppercase());
30090 Ok(())
30091 }
30092
30093 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
30094 self.write_keyword("INTO");
30096 if e.temporary {
30097 self.write_keyword(" TEMPORARY");
30098 }
30099 if e.unlogged.is_some() {
30100 self.write_keyword(" UNLOGGED");
30101 }
30102 if let Some(this) = &e.this {
30103 self.write_space();
30104 self.generate_expression(this)?;
30105 }
30106 if !e.expressions.is_empty() {
30107 self.write(" (");
30108 for (i, expr) in e.expressions.iter().enumerate() {
30109 if i > 0 {
30110 self.write(", ");
30111 }
30112 self.generate_expression(expr)?;
30113 }
30114 self.write(")");
30115 }
30116 Ok(())
30117 }
30118
30119 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
30120 self.generate_expression(&e.this)?;
30122 self.write_space();
30123 self.generate_expression(&e.expression)?;
30124 Ok(())
30125 }
30126
30127 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
30128 self.write_keyword("WITH");
30130 if e.no.is_some() {
30131 self.write_keyword(" NO");
30132 }
30133 if e.concurrent.is_some() {
30134 self.write_keyword(" CONCURRENT");
30135 }
30136 self.write_keyword(" ISOLATED LOADING");
30137 if let Some(target) = &e.target {
30138 self.write_space();
30139 self.generate_expression(target)?;
30140 }
30141 Ok(())
30142 }
30143
30144 fn generate_json(&mut self, e: &JSON) -> Result<()> {
30145 self.write_keyword("JSON");
30147 if let Some(this) = &e.this {
30148 self.write_space();
30149 self.generate_expression(this)?;
30150 }
30151 if let Some(with_) = &e.with_ {
30152 if let Expression::Boolean(b) = with_.as_ref() {
30154 if b.value {
30155 self.write_keyword(" WITH");
30156 } else {
30157 self.write_keyword(" WITHOUT");
30158 }
30159 }
30160 }
30161 if e.unique {
30162 self.write_keyword(" UNIQUE KEYS");
30163 }
30164 Ok(())
30165 }
30166
30167 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
30168 self.write_keyword("JSON_ARRAY");
30170 self.write("(");
30171 for (i, expr) in e.expressions.iter().enumerate() {
30172 if i > 0 {
30173 self.write(", ");
30174 }
30175 self.generate_expression(expr)?;
30176 }
30177 if let Some(null_handling) = &e.null_handling {
30178 self.write_space();
30179 self.generate_expression(null_handling)?;
30180 }
30181 if let Some(return_type) = &e.return_type {
30182 self.write_space();
30183 self.write_keyword("RETURNING");
30184 self.write_space();
30185 self.generate_expression(return_type)?;
30186 }
30187 if e.strict.is_some() {
30188 self.write_space();
30189 self.write_keyword("STRICT");
30190 }
30191 self.write(")");
30192 Ok(())
30193 }
30194
30195 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
30196 self.write_keyword("JSON_ARRAYAGG");
30198 self.write("(");
30199 self.generate_expression(&e.this)?;
30200 if let Some(order) = &e.order {
30201 self.write_space();
30202 if let Expression::OrderBy(ob) = order.as_ref() {
30204 self.write_keyword("ORDER BY");
30205 self.write_space();
30206 for (i, ord) in ob.expressions.iter().enumerate() {
30207 if i > 0 {
30208 self.write(", ");
30209 }
30210 self.generate_ordered(ord)?;
30211 }
30212 } else {
30213 self.generate_expression(order)?;
30215 }
30216 }
30217 if let Some(null_handling) = &e.null_handling {
30218 self.write_space();
30219 self.generate_expression(null_handling)?;
30220 }
30221 if let Some(return_type) = &e.return_type {
30222 self.write_space();
30223 self.write_keyword("RETURNING");
30224 self.write_space();
30225 self.generate_expression(return_type)?;
30226 }
30227 if e.strict.is_some() {
30228 self.write_space();
30229 self.write_keyword("STRICT");
30230 }
30231 self.write(")");
30232 Ok(())
30233 }
30234
30235 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
30236 self.write_keyword("JSON_OBJECTAGG");
30238 self.write("(");
30239 for (i, expr) in e.expressions.iter().enumerate() {
30240 if i > 0 {
30241 self.write(", ");
30242 }
30243 self.generate_expression(expr)?;
30244 }
30245 if let Some(null_handling) = &e.null_handling {
30246 self.write_space();
30247 self.generate_expression(null_handling)?;
30248 }
30249 if let Some(unique_keys) = &e.unique_keys {
30250 self.write_space();
30251 if let Expression::Boolean(b) = unique_keys.as_ref() {
30252 if b.value {
30253 self.write_keyword("WITH UNIQUE KEYS");
30254 } else {
30255 self.write_keyword("WITHOUT UNIQUE KEYS");
30256 }
30257 }
30258 }
30259 if let Some(return_type) = &e.return_type {
30260 self.write_space();
30261 self.write_keyword("RETURNING");
30262 self.write_space();
30263 self.generate_expression(return_type)?;
30264 }
30265 self.write(")");
30266 Ok(())
30267 }
30268
30269 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
30270 self.write_keyword("JSON_ARRAY_APPEND");
30272 self.write("(");
30273 self.generate_expression(&e.this)?;
30274 for expr in &e.expressions {
30275 self.write(", ");
30276 self.generate_expression(expr)?;
30277 }
30278 self.write(")");
30279 Ok(())
30280 }
30281
30282 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
30283 self.write_keyword("JSON_ARRAY_CONTAINS");
30285 self.write("(");
30286 self.generate_expression(&e.this)?;
30287 self.write(", ");
30288 self.generate_expression(&e.expression)?;
30289 self.write(")");
30290 Ok(())
30291 }
30292
30293 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
30294 self.write_keyword("JSON_ARRAY_INSERT");
30296 self.write("(");
30297 self.generate_expression(&e.this)?;
30298 for expr in &e.expressions {
30299 self.write(", ");
30300 self.generate_expression(expr)?;
30301 }
30302 self.write(")");
30303 Ok(())
30304 }
30305
30306 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
30307 self.write_keyword("JSONB_EXISTS");
30309 self.write("(");
30310 self.generate_expression(&e.this)?;
30311 if let Some(path) = &e.path {
30312 self.write(", ");
30313 self.generate_expression(path)?;
30314 }
30315 self.write(")");
30316 Ok(())
30317 }
30318
30319 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
30320 self.write_keyword("JSONB_EXTRACT_SCALAR");
30322 self.write("(");
30323 self.generate_expression(&e.this)?;
30324 self.write(", ");
30325 self.generate_expression(&e.expression)?;
30326 self.write(")");
30327 Ok(())
30328 }
30329
30330 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
30331 self.write_keyword("JSONB_OBJECT_AGG");
30333 self.write("(");
30334 self.generate_expression(&e.this)?;
30335 self.write(", ");
30336 self.generate_expression(&e.expression)?;
30337 self.write(")");
30338 Ok(())
30339 }
30340
30341 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
30342 if let Some(nested_schema) = &e.nested_schema {
30344 self.write_keyword("NESTED");
30345 if let Some(path) = &e.path {
30346 self.write_space();
30347 self.write_keyword("PATH");
30348 self.write_space();
30349 self.generate_expression(path)?;
30350 }
30351 self.write_space();
30352 self.generate_expression(nested_schema)?;
30353 } else {
30354 if let Some(this) = &e.this {
30355 self.generate_expression(this)?;
30356 }
30357 if let Some(kind) = &e.kind {
30358 self.write_space();
30359 self.write(kind);
30360 }
30361 if e.format_json {
30362 self.write_space();
30363 self.write_keyword("FORMAT JSON");
30364 }
30365 if let Some(path) = &e.path {
30366 self.write_space();
30367 self.write_keyword("PATH");
30368 self.write_space();
30369 self.generate_expression(path)?;
30370 }
30371 if e.ordinality.is_some() {
30372 self.write_keyword(" FOR ORDINALITY");
30373 }
30374 }
30375 Ok(())
30376 }
30377
30378 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
30379 self.write_keyword("JSON_EXISTS");
30381 self.write("(");
30382 self.generate_expression(&e.this)?;
30383 if let Some(path) = &e.path {
30384 self.write(", ");
30385 self.generate_expression(path)?;
30386 }
30387 if let Some(passing) = &e.passing {
30388 self.write_space();
30389 self.write_keyword("PASSING");
30390 self.write_space();
30391 self.generate_expression(passing)?;
30392 }
30393 if let Some(on_condition) = &e.on_condition {
30394 self.write_space();
30395 self.generate_expression(on_condition)?;
30396 }
30397 self.write(")");
30398 Ok(())
30399 }
30400
30401 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
30402 self.generate_expression(&e.this)?;
30403 self.write(".:");
30404 if Self::data_type_has_nested_expressions(&e.to) {
30408 let saved = std::mem::take(&mut self.output);
30410 self.generate_data_type(&e.to)?;
30411 let type_sql = std::mem::replace(&mut self.output, saved);
30412 self.write("\"");
30413 self.write(&type_sql);
30414 self.write("\"");
30415 } else {
30416 self.generate_data_type(&e.to)?;
30417 }
30418 Ok(())
30419 }
30420
30421 fn data_type_has_nested_expressions(dt: &DataType) -> bool {
30424 matches!(
30425 dt,
30426 DataType::Array { .. } | DataType::Map { .. } | DataType::Struct { .. }
30427 )
30428 }
30429
30430 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
30431 self.write_keyword("JSON_EXTRACT_ARRAY");
30433 self.write("(");
30434 self.generate_expression(&e.this)?;
30435 if let Some(expr) = &e.expression {
30436 self.write(", ");
30437 self.generate_expression(expr)?;
30438 }
30439 self.write(")");
30440 Ok(())
30441 }
30442
30443 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
30444 if let Some(option) = &e.option {
30446 self.generate_expression(option)?;
30447 self.write_space();
30448 }
30449 self.write_keyword("QUOTES");
30450 if e.scalar.is_some() {
30451 self.write_keyword(" SCALAR_ONLY");
30452 }
30453 Ok(())
30454 }
30455
30456 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
30457 self.write_keyword("JSON_EXTRACT_SCALAR");
30459 self.write("(");
30460 self.generate_expression(&e.this)?;
30461 self.write(", ");
30462 self.generate_expression(&e.expression)?;
30463 self.write(")");
30464 Ok(())
30465 }
30466
30467 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
30468 if e.variant_extract.is_some() {
30472 use crate::dialects::DialectType;
30473 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
30474 self.generate_expression(&e.this)?;
30478 self.write(":");
30479 match e.expression.as_ref() {
30480 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
30481 let Literal::String(s) = lit.as_ref() else {
30482 unreachable!()
30483 };
30484 self.write_databricks_json_path(s);
30485 }
30486 _ => {
30487 self.generate_expression(&e.expression)?;
30489 }
30490 }
30491 } else {
30492 self.write_keyword("GET_PATH");
30494 self.write("(");
30495 self.generate_expression(&e.this)?;
30496 self.write(", ");
30497 self.generate_expression(&e.expression)?;
30498 self.write(")");
30499 }
30500 } else {
30501 self.write_keyword("JSON_EXTRACT");
30502 self.write("(");
30503 self.generate_expression(&e.this)?;
30504 self.write(", ");
30505 self.generate_expression(&e.expression)?;
30506 for expr in &e.expressions {
30507 self.write(", ");
30508 self.generate_expression(expr)?;
30509 }
30510 self.write(")");
30511 }
30512 Ok(())
30513 }
30514
30515 fn write_databricks_json_path(&mut self, path: &str) {
30519 if path.starts_with("[\"") || path.starts_with("['") {
30522 self.write(path);
30523 return;
30524 }
30525 let mut first = true;
30529 for segment in path.split('.') {
30530 if !first {
30531 self.write(".");
30532 }
30533 first = false;
30534 if let Some(bracket_pos) = segment.find('[') {
30536 let key = &segment[..bracket_pos];
30537 let subscript = &segment[bracket_pos..];
30538 if key.is_empty() {
30539 self.write(segment);
30541 } else if Self::is_safe_json_path_key(key) {
30542 self.write(key);
30543 self.write(subscript);
30544 } else {
30545 self.write("[\"");
30546 self.write(key);
30547 self.write("\"]");
30548 self.write(subscript);
30549 }
30550 } else if Self::is_safe_json_path_key(segment) {
30551 self.write(segment);
30552 } else {
30553 self.write("[\"");
30554 self.write(segment);
30555 self.write("\"]");
30556 }
30557 }
30558 }
30559
30560 fn is_safe_json_path_key(key: &str) -> bool {
30563 if key.is_empty() {
30564 return false;
30565 }
30566 let mut chars = key.chars();
30567 let first = chars.next().unwrap();
30568 if first != '_' && !first.is_ascii_alphabetic() {
30569 return false;
30570 }
30571 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
30572 }
30573
30574 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
30575 if let Some(this) = &e.this {
30578 self.generate_expression(this)?;
30579 self.write_space();
30580 }
30581 self.write_keyword("FORMAT JSON");
30582 Ok(())
30583 }
30584
30585 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
30586 self.generate_expression(&e.this)?;
30588 self.write(": ");
30589 self.generate_expression(&e.expression)?;
30590 Ok(())
30591 }
30592
30593 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
30594 self.write_keyword("JSON_KEYS");
30596 self.write("(");
30597 self.generate_expression(&e.this)?;
30598 if let Some(expr) = &e.expression {
30599 self.write(", ");
30600 self.generate_expression(expr)?;
30601 }
30602 for expr in &e.expressions {
30603 self.write(", ");
30604 self.generate_expression(expr)?;
30605 }
30606 self.write(")");
30607 Ok(())
30608 }
30609
30610 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
30611 self.write_keyword("JSON_KEYS");
30613 self.write("(");
30614 self.generate_expression(&e.this)?;
30615 if let Some(expr) = &e.expression {
30616 self.write(", ");
30617 self.generate_expression(expr)?;
30618 }
30619 self.write(")");
30620 Ok(())
30621 }
30622
30623 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
30624 let mut path_str = String::new();
30627 for expr in &e.expressions {
30628 match expr {
30629 Expression::JSONPathRoot(_) => {
30630 path_str.push('$');
30631 }
30632 Expression::JSONPathKey(k) => {
30633 if let Expression::Literal(lit) = k.this.as_ref() {
30635 if let crate::expressions::Literal::String(s) = lit.as_ref() {
30636 path_str.push('.');
30637 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
30639 if needs_quoting {
30640 path_str.push('"');
30641 path_str.push_str(s);
30642 path_str.push('"');
30643 } else {
30644 path_str.push_str(s);
30645 }
30646 }
30647 }
30648 }
30649 Expression::JSONPathSubscript(s) => {
30650 if let Expression::Literal(lit) = s.this.as_ref() {
30652 if let crate::expressions::Literal::Number(n) = lit.as_ref() {
30653 path_str.push('[');
30654 path_str.push_str(n);
30655 path_str.push(']');
30656 }
30657 }
30658 }
30659 _ => {
30660 let mut temp_gen = Self::with_arc_config(self.config.clone());
30662 temp_gen.generate_expression(expr)?;
30663 path_str.push_str(&temp_gen.output);
30664 }
30665 }
30666 }
30667 self.write("'");
30669 self.write(&path_str);
30670 self.write("'");
30671 Ok(())
30672 }
30673
30674 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
30675 self.write("?(");
30677 self.generate_expression(&e.this)?;
30678 self.write(")");
30679 Ok(())
30680 }
30681
30682 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
30683 self.write(".");
30685 self.generate_expression(&e.this)?;
30686 Ok(())
30687 }
30688
30689 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
30690 self.write("..");
30692 if let Some(this) = &e.this {
30693 self.generate_expression(this)?;
30694 }
30695 Ok(())
30696 }
30697
30698 fn generate_json_path_root(&mut self) -> Result<()> {
30699 self.write("$");
30701 Ok(())
30702 }
30703
30704 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
30705 self.write("(");
30707 self.generate_expression(&e.this)?;
30708 self.write(")");
30709 Ok(())
30710 }
30711
30712 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
30713 self.generate_expression(&e.this)?;
30715 Ok(())
30716 }
30717
30718 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
30719 self.write("[");
30721 if let Some(start) = &e.start {
30722 self.generate_expression(start)?;
30723 }
30724 self.write(":");
30725 if let Some(end) = &e.end {
30726 self.generate_expression(end)?;
30727 }
30728 if let Some(step) = &e.step {
30729 self.write(":");
30730 self.generate_expression(step)?;
30731 }
30732 self.write("]");
30733 Ok(())
30734 }
30735
30736 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
30737 self.write("[");
30739 self.generate_expression(&e.this)?;
30740 self.write("]");
30741 Ok(())
30742 }
30743
30744 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
30745 self.write("[");
30747 for (i, expr) in e.expressions.iter().enumerate() {
30748 if i > 0 {
30749 self.write(", ");
30750 }
30751 self.generate_expression(expr)?;
30752 }
30753 self.write("]");
30754 Ok(())
30755 }
30756
30757 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
30758 self.write_keyword("JSON_REMOVE");
30760 self.write("(");
30761 self.generate_expression(&e.this)?;
30762 for expr in &e.expressions {
30763 self.write(", ");
30764 self.generate_expression(expr)?;
30765 }
30766 self.write(")");
30767 Ok(())
30768 }
30769
30770 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
30771 self.write_keyword("COLUMNS");
30774 self.write("(");
30775
30776 if self.config.pretty && !e.expressions.is_empty() {
30777 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
30779 for expr in &e.expressions {
30780 let mut temp_gen = Generator::with_arc_config(self.config.clone());
30781 temp_gen.generate_expression(expr)?;
30782 expr_strings.push(temp_gen.output);
30783 }
30784
30785 if self.too_wide(&expr_strings) {
30787 self.write_newline();
30789 self.indent_level += 1;
30790 for (i, expr_str) in expr_strings.iter().enumerate() {
30791 if i > 0 {
30792 self.write(",");
30793 self.write_newline();
30794 }
30795 self.write_indent();
30796 self.write(expr_str);
30797 }
30798 self.write_newline();
30799 self.indent_level -= 1;
30800 self.write_indent();
30801 } else {
30802 for (i, expr_str) in expr_strings.iter().enumerate() {
30804 if i > 0 {
30805 self.write(", ");
30806 }
30807 self.write(expr_str);
30808 }
30809 }
30810 } else {
30811 for (i, expr) in e.expressions.iter().enumerate() {
30813 if i > 0 {
30814 self.write(", ");
30815 }
30816 self.generate_expression(expr)?;
30817 }
30818 }
30819 self.write(")");
30820 Ok(())
30821 }
30822
30823 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
30824 self.write_keyword("JSON_SET");
30826 self.write("(");
30827 self.generate_expression(&e.this)?;
30828 for expr in &e.expressions {
30829 self.write(", ");
30830 self.generate_expression(expr)?;
30831 }
30832 self.write(")");
30833 Ok(())
30834 }
30835
30836 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
30837 self.write_keyword("JSON_STRIP_NULLS");
30839 self.write("(");
30840 self.generate_expression(&e.this)?;
30841 if let Some(expr) = &e.expression {
30842 self.write(", ");
30843 self.generate_expression(expr)?;
30844 }
30845 self.write(")");
30846 Ok(())
30847 }
30848
30849 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
30850 self.write_keyword("JSON_TABLE");
30852 self.write("(");
30853 self.generate_expression(&e.this)?;
30854 if let Some(path) = &e.path {
30855 self.write(", ");
30856 self.generate_expression(path)?;
30857 }
30858 if let Some(error_handling) = &e.error_handling {
30859 self.write_space();
30860 self.generate_expression(error_handling)?;
30861 }
30862 if let Some(empty_handling) = &e.empty_handling {
30863 self.write_space();
30864 self.generate_expression(empty_handling)?;
30865 }
30866 if let Some(schema) = &e.schema {
30867 self.write_space();
30868 self.generate_expression(schema)?;
30869 }
30870 self.write(")");
30871 Ok(())
30872 }
30873
30874 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
30875 self.write_keyword("JSON_TYPE");
30877 self.write("(");
30878 self.generate_expression(&e.this)?;
30879 self.write(")");
30880 Ok(())
30881 }
30882
30883 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
30884 self.write_keyword("JSON_VALUE");
30886 self.write("(");
30887 self.generate_expression(&e.this)?;
30888 if let Some(path) = &e.path {
30889 self.write(", ");
30890 self.generate_expression(path)?;
30891 }
30892 if let Some(returning) = &e.returning {
30893 self.write_space();
30894 self.write_keyword("RETURNING");
30895 self.write_space();
30896 self.generate_expression(returning)?;
30897 }
30898 if let Some(on_condition) = &e.on_condition {
30899 self.write_space();
30900 self.generate_expression(on_condition)?;
30901 }
30902 self.write(")");
30903 Ok(())
30904 }
30905
30906 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
30907 self.write_keyword("JSON_VALUE_ARRAY");
30909 self.write("(");
30910 self.generate_expression(&e.this)?;
30911 self.write(")");
30912 Ok(())
30913 }
30914
30915 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
30916 self.write_keyword("JAROWINKLER_SIMILARITY");
30918 self.write("(");
30919 self.generate_expression(&e.this)?;
30920 self.write(", ");
30921 self.generate_expression(&e.expression)?;
30922 self.write(")");
30923 Ok(())
30924 }
30925
30926 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
30927 self.generate_expression(&e.this)?;
30929 self.write("(");
30930 for (i, expr) in e.expressions.iter().enumerate() {
30931 if i > 0 {
30932 self.write(", ");
30933 }
30934 self.generate_expression(expr)?;
30935 }
30936 self.write(")");
30937 Ok(())
30938 }
30939
30940 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
30941 if e.no.is_some() {
30943 self.write_keyword("NO ");
30944 }
30945 if let Some(local) = &e.local {
30946 self.generate_expression(local)?;
30947 self.write_space();
30948 }
30949 if e.dual.is_some() {
30950 self.write_keyword("DUAL ");
30951 }
30952 if e.before.is_some() {
30953 self.write_keyword("BEFORE ");
30954 }
30955 if e.after.is_some() {
30956 self.write_keyword("AFTER ");
30957 }
30958 self.write_keyword("JOURNAL");
30959 Ok(())
30960 }
30961
30962 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
30963 self.write_keyword("LANGUAGE");
30965 self.write_space();
30966 self.generate_expression(&e.this)?;
30967 Ok(())
30968 }
30969
30970 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
30971 if e.view.is_some() {
30973 self.write_keyword("LATERAL VIEW");
30975 if e.outer.is_some() {
30976 self.write_space();
30977 self.write_keyword("OUTER");
30978 }
30979 self.write_space();
30980 self.generate_expression(&e.this)?;
30981 if let Some(alias) = &e.alias {
30982 self.write_space();
30983 self.write(alias);
30984 }
30985 } else {
30986 self.write_keyword("LATERAL");
30988 self.write_space();
30989 self.generate_expression(&e.this)?;
30990 if e.ordinality.is_some() {
30991 self.write_space();
30992 self.write_keyword("WITH ORDINALITY");
30993 }
30994 if let Some(alias) = &e.alias {
30995 self.write_space();
30996 self.write_keyword("AS");
30997 self.write_space();
30998 self.write(alias);
30999 if !e.column_aliases.is_empty() {
31000 self.write("(");
31001 for (i, col) in e.column_aliases.iter().enumerate() {
31002 if i > 0 {
31003 self.write(", ");
31004 }
31005 self.write(col);
31006 }
31007 self.write(")");
31008 }
31009 }
31010 }
31011 Ok(())
31012 }
31013
31014 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
31015 self.write_keyword("LIKE");
31017 self.write_space();
31018 self.generate_expression(&e.this)?;
31019 for expr in &e.expressions {
31020 self.write_space();
31021 self.generate_expression(expr)?;
31022 }
31023 Ok(())
31024 }
31025
31026 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
31027 self.write_keyword("LIMIT");
31028 self.write_space();
31029 self.write_limit_expr(&e.this)?;
31030 if e.percent {
31031 self.write_space();
31032 self.write_keyword("PERCENT");
31033 }
31034 for comment in &e.comments {
31036 self.write(" ");
31037 self.write_formatted_comment(comment);
31038 }
31039 Ok(())
31040 }
31041
31042 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
31043 if e.percent.is_some() {
31045 self.write_keyword(" PERCENT");
31046 }
31047 if e.rows.is_some() {
31048 self.write_keyword(" ROWS");
31049 }
31050 if e.with_ties.is_some() {
31051 self.write_keyword(" WITH TIES");
31052 } else if e.rows.is_some() {
31053 self.write_keyword(" ONLY");
31054 }
31055 Ok(())
31056 }
31057
31058 fn generate_list(&mut self, e: &List) -> Result<()> {
31059 use crate::dialects::DialectType;
31060 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
31061
31062 if e.expressions.len() == 1 {
31064 if let Expression::Select(_) = &e.expressions[0] {
31065 self.write_keyword("LIST");
31066 self.write("(");
31067 self.generate_expression(&e.expressions[0])?;
31068 self.write(")");
31069 return Ok(());
31070 }
31071 }
31072
31073 if is_materialize {
31075 self.write_keyword("LIST");
31076 self.write("[");
31077 for (i, expr) in e.expressions.iter().enumerate() {
31078 if i > 0 {
31079 self.write(", ");
31080 }
31081 self.generate_expression(expr)?;
31082 }
31083 self.write("]");
31084 } else {
31085 self.write_keyword("LIST");
31087 self.write("(");
31088 for (i, expr) in e.expressions.iter().enumerate() {
31089 if i > 0 {
31090 self.write(", ");
31091 }
31092 self.generate_expression(expr)?;
31093 }
31094 self.write(")");
31095 }
31096 Ok(())
31097 }
31098
31099 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
31100 if let Expression::Select(_) = &*e.this {
31102 self.write_keyword("MAP");
31103 self.write("(");
31104 self.generate_expression(&e.this)?;
31105 self.write(")");
31106 return Ok(());
31107 }
31108
31109 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
31110
31111 self.write_keyword("MAP");
31113 if is_duckdb {
31114 self.write(" {");
31115 } else {
31116 self.write("[");
31117 }
31118 if let Expression::Struct(s) = &*e.this {
31119 for (i, (_, expr)) in s.fields.iter().enumerate() {
31120 if i > 0 {
31121 self.write(", ");
31122 }
31123 if let Expression::PropertyEQ(op) = expr {
31124 self.generate_expression(&op.left)?;
31125 if is_duckdb {
31126 self.write(": ");
31127 } else {
31128 self.write(" => ");
31129 }
31130 self.generate_expression(&op.right)?;
31131 } else {
31132 self.generate_expression(expr)?;
31133 }
31134 }
31135 }
31136 if is_duckdb {
31137 self.write("}");
31138 } else {
31139 self.write("]");
31140 }
31141 Ok(())
31142 }
31143
31144 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
31145 self.write_keyword("LOCALTIME");
31147 if let Some(precision) = &e.this {
31148 self.write("(");
31149 self.generate_expression(precision)?;
31150 self.write(")");
31151 }
31152 Ok(())
31153 }
31154
31155 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
31156 self.write_keyword("LOCALTIMESTAMP");
31158 if let Some(precision) = &e.this {
31159 self.write("(");
31160 self.generate_expression(precision)?;
31161 self.write(")");
31162 }
31163 Ok(())
31164 }
31165
31166 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
31167 self.write_keyword("LOCATION");
31169 self.write_space();
31170 self.generate_expression(&e.this)?;
31171 Ok(())
31172 }
31173
31174 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
31175 if e.update.is_some() {
31177 if e.key.is_some() {
31178 self.write_keyword("FOR NO KEY UPDATE");
31179 } else {
31180 self.write_keyword("FOR UPDATE");
31181 }
31182 } else {
31183 if e.key.is_some() {
31184 self.write_keyword("FOR KEY SHARE");
31185 } else {
31186 self.write_keyword("FOR SHARE");
31187 }
31188 }
31189 if !e.expressions.is_empty() {
31190 self.write_keyword(" OF ");
31191 for (i, expr) in e.expressions.iter().enumerate() {
31192 if i > 0 {
31193 self.write(", ");
31194 }
31195 self.generate_expression(expr)?;
31196 }
31197 }
31198 if let Some(wait) = &e.wait {
31203 match wait.as_ref() {
31204 Expression::Boolean(b) => {
31205 if b.value {
31206 self.write_keyword(" NOWAIT");
31207 } else {
31208 self.write_keyword(" SKIP LOCKED");
31209 }
31210 }
31211 _ => {
31212 self.write_keyword(" WAIT ");
31214 self.generate_expression(wait)?;
31215 }
31216 }
31217 }
31218 Ok(())
31219 }
31220
31221 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
31222 self.write_keyword("LOCK");
31224 self.write_space();
31225 self.generate_expression(&e.this)?;
31226 Ok(())
31227 }
31228
31229 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
31230 self.write_keyword("LOCKING");
31232 self.write_space();
31233 self.write(&e.kind);
31234 if let Some(this) = &e.this {
31235 self.write_space();
31236 self.generate_expression(this)?;
31237 }
31238 if let Some(for_or_in) = &e.for_or_in {
31239 self.write_space();
31240 self.generate_expression(for_or_in)?;
31241 }
31242 if let Some(lock_type) = &e.lock_type {
31243 self.write_space();
31244 self.generate_expression(lock_type)?;
31245 }
31246 if e.override_.is_some() {
31247 self.write_keyword(" OVERRIDE");
31248 }
31249 Ok(())
31250 }
31251
31252 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
31253 self.generate_expression(&e.this)?;
31255 self.write_space();
31256 self.generate_expression(&e.expression)?;
31257 Ok(())
31258 }
31259
31260 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
31261 if e.no.is_some() {
31263 self.write_keyword("NO ");
31264 }
31265 self.write_keyword("LOG");
31266 Ok(())
31267 }
31268
31269 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
31270 self.write_keyword("MD5");
31272 self.write("(");
31273 self.generate_expression(&e.this)?;
31274 for expr in &e.expressions {
31275 self.write(", ");
31276 self.generate_expression(expr)?;
31277 }
31278 self.write(")");
31279 Ok(())
31280 }
31281
31282 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
31283 self.write_keyword("ML.FORECAST");
31285 self.write("(");
31286 self.generate_expression(&e.this)?;
31287 if let Some(expression) = &e.expression {
31288 self.write(", ");
31289 self.generate_expression(expression)?;
31290 }
31291 if let Some(params) = &e.params_struct {
31292 self.write(", ");
31293 self.generate_expression(params)?;
31294 }
31295 self.write(")");
31296 Ok(())
31297 }
31298
31299 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
31300 self.write_keyword("ML.TRANSLATE");
31302 self.write("(");
31303 self.generate_expression(&e.this)?;
31304 self.write(", ");
31305 self.generate_expression(&e.expression)?;
31306 if let Some(params) = &e.params_struct {
31307 self.write(", ");
31308 self.generate_expression(params)?;
31309 }
31310 self.write(")");
31311 Ok(())
31312 }
31313
31314 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
31315 self.write_keyword("MAKE_INTERVAL");
31317 self.write("(");
31318 let mut first = true;
31319 if let Some(year) = &e.year {
31320 self.write("years => ");
31321 self.generate_expression(year)?;
31322 first = false;
31323 }
31324 if let Some(month) = &e.month {
31325 if !first {
31326 self.write(", ");
31327 }
31328 self.write("months => ");
31329 self.generate_expression(month)?;
31330 first = false;
31331 }
31332 if let Some(week) = &e.week {
31333 if !first {
31334 self.write(", ");
31335 }
31336 self.write("weeks => ");
31337 self.generate_expression(week)?;
31338 first = false;
31339 }
31340 if let Some(day) = &e.day {
31341 if !first {
31342 self.write(", ");
31343 }
31344 self.write("days => ");
31345 self.generate_expression(day)?;
31346 first = false;
31347 }
31348 if let Some(hour) = &e.hour {
31349 if !first {
31350 self.write(", ");
31351 }
31352 self.write("hours => ");
31353 self.generate_expression(hour)?;
31354 first = false;
31355 }
31356 if let Some(minute) = &e.minute {
31357 if !first {
31358 self.write(", ");
31359 }
31360 self.write("mins => ");
31361 self.generate_expression(minute)?;
31362 first = false;
31363 }
31364 if let Some(second) = &e.second {
31365 if !first {
31366 self.write(", ");
31367 }
31368 self.write("secs => ");
31369 self.generate_expression(second)?;
31370 }
31371 self.write(")");
31372 Ok(())
31373 }
31374
31375 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
31376 self.write_keyword("MANHATTAN_DISTANCE");
31378 self.write("(");
31379 self.generate_expression(&e.this)?;
31380 self.write(", ");
31381 self.generate_expression(&e.expression)?;
31382 self.write(")");
31383 Ok(())
31384 }
31385
31386 fn generate_map(&mut self, e: &Map) -> Result<()> {
31387 self.write_keyword("MAP");
31389 self.write("(");
31390 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
31391 if i > 0 {
31392 self.write(", ");
31393 }
31394 self.generate_expression(key)?;
31395 self.write(", ");
31396 self.generate_expression(value)?;
31397 }
31398 self.write(")");
31399 Ok(())
31400 }
31401
31402 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
31403 self.write_keyword("MAP_CAT");
31405 self.write("(");
31406 self.generate_expression(&e.this)?;
31407 self.write(", ");
31408 self.generate_expression(&e.expression)?;
31409 self.write(")");
31410 Ok(())
31411 }
31412
31413 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
31414 self.write_keyword("MAP_DELETE");
31416 self.write("(");
31417 self.generate_expression(&e.this)?;
31418 for expr in &e.expressions {
31419 self.write(", ");
31420 self.generate_expression(expr)?;
31421 }
31422 self.write(")");
31423 Ok(())
31424 }
31425
31426 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
31427 self.write_keyword("MAP_INSERT");
31429 self.write("(");
31430 self.generate_expression(&e.this)?;
31431 if let Some(key) = &e.key {
31432 self.write(", ");
31433 self.generate_expression(key)?;
31434 }
31435 if let Some(value) = &e.value {
31436 self.write(", ");
31437 self.generate_expression(value)?;
31438 }
31439 if let Some(update_flag) = &e.update_flag {
31440 self.write(", ");
31441 self.generate_expression(update_flag)?;
31442 }
31443 self.write(")");
31444 Ok(())
31445 }
31446
31447 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
31448 self.write_keyword("MAP_PICK");
31450 self.write("(");
31451 self.generate_expression(&e.this)?;
31452 for expr in &e.expressions {
31453 self.write(", ");
31454 self.generate_expression(expr)?;
31455 }
31456 self.write(")");
31457 Ok(())
31458 }
31459
31460 fn generate_masking_policy_column_constraint(
31461 &mut self,
31462 e: &MaskingPolicyColumnConstraint,
31463 ) -> Result<()> {
31464 self.write_keyword("MASKING POLICY");
31466 self.write_space();
31467 self.generate_expression(&e.this)?;
31468 if !e.expressions.is_empty() {
31469 self.write_keyword(" USING");
31470 self.write(" (");
31471 for (i, expr) in e.expressions.iter().enumerate() {
31472 if i > 0 {
31473 self.write(", ");
31474 }
31475 self.generate_expression(expr)?;
31476 }
31477 self.write(")");
31478 }
31479 Ok(())
31480 }
31481
31482 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
31483 if matches!(
31484 self.config.dialect,
31485 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
31486 ) {
31487 if e.expressions.len() > 1 {
31488 self.write("(");
31489 }
31490 for (i, expr) in e.expressions.iter().enumerate() {
31491 if i > 0 {
31492 self.write_keyword(" OR ");
31493 }
31494 self.generate_expression(expr)?;
31495 self.write_space();
31496 self.write("@@");
31497 self.write_space();
31498 self.generate_expression(&e.this)?;
31499 }
31500 if e.expressions.len() > 1 {
31501 self.write(")");
31502 }
31503 return Ok(());
31504 }
31505
31506 self.write_keyword("MATCH");
31508 self.write("(");
31509 for (i, expr) in e.expressions.iter().enumerate() {
31510 if i > 0 {
31511 self.write(", ");
31512 }
31513 self.generate_expression(expr)?;
31514 }
31515 self.write(")");
31516 self.write_keyword(" AGAINST");
31517 self.write("(");
31518 self.generate_expression(&e.this)?;
31519 if let Some(modifier) = &e.modifier {
31520 self.write_space();
31521 self.generate_expression(modifier)?;
31522 }
31523 self.write(")");
31524 Ok(())
31525 }
31526
31527 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
31528 if let Some(window_frame) = &e.window_frame {
31530 self.write(&format!("{:?}", window_frame).to_ascii_uppercase());
31531 self.write_space();
31532 }
31533 self.generate_expression(&e.this)?;
31534 Ok(())
31535 }
31536
31537 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
31538 self.write_keyword("MATERIALIZED");
31540 if let Some(this) = &e.this {
31541 self.write_space();
31542 self.generate_expression(this)?;
31543 }
31544 Ok(())
31545 }
31546
31547 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
31548 if let Some(with_) = &e.with_ {
31551 if let Expression::With(with_clause) = with_.as_ref() {
31552 self.generate_with(with_clause)?;
31553 self.write_space();
31554 } else {
31555 self.generate_expression(with_)?;
31556 self.write_space();
31557 }
31558 }
31559 self.write_keyword("MERGE INTO");
31560 self.write_space();
31561 if matches!(self.config.dialect, Some(crate::DialectType::Oracle)) {
31562 if let Expression::Alias(alias) = e.this.as_ref() {
31563 self.generate_expression(&alias.this)?;
31564 self.write_space();
31565 self.generate_identifier(&alias.alias)?;
31566 } else {
31567 self.generate_expression(&e.this)?;
31568 }
31569 } else {
31570 self.generate_expression(&e.this)?;
31571 }
31572
31573 if self.config.pretty {
31575 self.write_newline();
31576 self.write_indent();
31577 } else {
31578 self.write_space();
31579 }
31580 self.write_keyword("USING");
31581 self.write_space();
31582 self.generate_expression(&e.using)?;
31583
31584 if let Some(on) = &e.on {
31586 if self.config.pretty {
31587 self.write_newline();
31588 self.write_indent();
31589 } else {
31590 self.write_space();
31591 }
31592 self.write_keyword("ON");
31593 self.write_space();
31594 self.generate_expression(on)?;
31595 }
31596 if let Some(using_cond) = &e.using_cond {
31598 self.write_space();
31599 self.write_keyword("USING");
31600 self.write_space();
31601 self.write("(");
31602 if let Expression::Tuple(tuple) = using_cond.as_ref() {
31604 for (i, col) in tuple.expressions.iter().enumerate() {
31605 if i > 0 {
31606 self.write(", ");
31607 }
31608 self.generate_expression(col)?;
31609 }
31610 } else {
31611 self.generate_expression(using_cond)?;
31612 }
31613 self.write(")");
31614 }
31615 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
31617 if matches!(
31618 self.config.dialect,
31619 Some(crate::DialectType::PostgreSQL)
31620 | Some(crate::DialectType::Redshift)
31621 | Some(crate::DialectType::Trino)
31622 | Some(crate::DialectType::Presto)
31623 | Some(crate::DialectType::Athena)
31624 ) {
31625 let mut names = Vec::new();
31626 match e.this.as_ref() {
31627 Expression::Alias(a) => {
31628 if let Expression::Table(t) = &a.this {
31630 names.push(t.name.name.clone());
31631 } else if let Expression::Identifier(id) = &a.this {
31632 names.push(id.name.clone());
31633 }
31634 names.push(a.alias.name.clone());
31635 }
31636 Expression::Table(t) => {
31637 names.push(t.name.name.clone());
31638 }
31639 Expression::Identifier(id) => {
31640 names.push(id.name.clone());
31641 }
31642 _ => {}
31643 }
31644 self.merge_strip_qualifiers = names;
31645 }
31646
31647 if let Some(whens) = &e.whens {
31649 if self.config.pretty {
31650 self.write_newline();
31651 self.write_indent();
31652 } else {
31653 self.write_space();
31654 }
31655 self.generate_expression(whens)?;
31656 }
31657
31658 self.merge_strip_qualifiers = saved_merge_strip;
31660
31661 if let Some(returning) = &e.returning {
31663 if self.config.pretty {
31664 self.write_newline();
31665 self.write_indent();
31666 } else {
31667 self.write_space();
31668 }
31669 self.generate_expression(returning)?;
31670 }
31671 Ok(())
31672 }
31673
31674 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
31675 if e.no.is_some() {
31677 self.write_keyword("NO MERGEBLOCKRATIO");
31678 } else if e.default.is_some() {
31679 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
31680 } else {
31681 self.write_keyword("MERGEBLOCKRATIO");
31682 self.write("=");
31683 if let Some(this) = &e.this {
31684 self.generate_expression(this)?;
31685 }
31686 if e.percent.is_some() {
31687 self.write_keyword(" PERCENT");
31688 }
31689 }
31690 Ok(())
31691 }
31692
31693 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
31694 self.write_keyword("TTL");
31696 let pretty_clickhouse = self.config.pretty
31697 && matches!(
31698 self.config.dialect,
31699 Some(crate::dialects::DialectType::ClickHouse)
31700 );
31701
31702 if pretty_clickhouse {
31703 self.write_newline();
31704 self.indent_level += 1;
31705 for (i, expr) in e.expressions.iter().enumerate() {
31706 if i > 0 {
31707 self.write(",");
31708 self.write_newline();
31709 }
31710 self.write_indent();
31711 self.generate_expression(expr)?;
31712 }
31713 self.indent_level -= 1;
31714 } else {
31715 self.write_space();
31716 for (i, expr) in e.expressions.iter().enumerate() {
31717 if i > 0 {
31718 self.write(", ");
31719 }
31720 self.generate_expression(expr)?;
31721 }
31722 }
31723
31724 if let Some(where_) = &e.where_ {
31725 if pretty_clickhouse {
31726 self.write_newline();
31727 if let Expression::Where(w) = where_.as_ref() {
31728 self.write_indent();
31729 self.write_keyword("WHERE");
31730 self.write_newline();
31731 self.indent_level += 1;
31732 self.write_indent();
31733 self.generate_expression(&w.this)?;
31734 self.indent_level -= 1;
31735 } else {
31736 self.write_indent();
31737 self.generate_expression(where_)?;
31738 }
31739 } else {
31740 self.write_space();
31741 self.generate_expression(where_)?;
31742 }
31743 }
31744 if let Some(group) = &e.group {
31745 if pretty_clickhouse {
31746 self.write_newline();
31747 if let Expression::Group(g) = group.as_ref() {
31748 self.write_indent();
31749 self.write_keyword("GROUP BY");
31750 self.write_newline();
31751 self.indent_level += 1;
31752 for (i, expr) in g.expressions.iter().enumerate() {
31753 if i > 0 {
31754 self.write(",");
31755 self.write_newline();
31756 }
31757 self.write_indent();
31758 self.generate_expression(expr)?;
31759 }
31760 self.indent_level -= 1;
31761 } else {
31762 self.write_indent();
31763 self.generate_expression(group)?;
31764 }
31765 } else {
31766 self.write_space();
31767 self.generate_expression(group)?;
31768 }
31769 }
31770 if let Some(aggregates) = &e.aggregates {
31771 if pretty_clickhouse {
31772 self.write_newline();
31773 self.write_indent();
31774 self.write_keyword("SET");
31775 self.write_newline();
31776 self.indent_level += 1;
31777 if let Expression::Tuple(t) = aggregates.as_ref() {
31778 for (i, agg) in t.expressions.iter().enumerate() {
31779 if i > 0 {
31780 self.write(",");
31781 self.write_newline();
31782 }
31783 self.write_indent();
31784 self.generate_expression(agg)?;
31785 }
31786 } else {
31787 self.write_indent();
31788 self.generate_expression(aggregates)?;
31789 }
31790 self.indent_level -= 1;
31791 } else {
31792 self.write_space();
31793 self.write_keyword("SET");
31794 self.write_space();
31795 if let Expression::Tuple(t) = aggregates.as_ref() {
31796 for (i, agg) in t.expressions.iter().enumerate() {
31797 if i > 0 {
31798 self.write(", ");
31799 }
31800 self.generate_expression(agg)?;
31801 }
31802 } else {
31803 self.generate_expression(aggregates)?;
31804 }
31805 }
31806 }
31807 Ok(())
31808 }
31809
31810 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
31811 self.generate_expression(&e.this)?;
31813 if e.delete.is_some() {
31814 self.write_keyword(" DELETE");
31815 }
31816 if let Some(recompress) = &e.recompress {
31817 self.write_keyword(" RECOMPRESS ");
31818 self.generate_expression(recompress)?;
31819 }
31820 if let Some(to_disk) = &e.to_disk {
31821 self.write_keyword(" TO DISK ");
31822 self.generate_expression(to_disk)?;
31823 }
31824 if let Some(to_volume) = &e.to_volume {
31825 self.write_keyword(" TO VOLUME ");
31826 self.generate_expression(to_volume)?;
31827 }
31828 Ok(())
31829 }
31830
31831 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
31832 self.write_keyword("MINHASH");
31834 self.write("(");
31835 self.generate_expression(&e.this)?;
31836 for expr in &e.expressions {
31837 self.write(", ");
31838 self.generate_expression(expr)?;
31839 }
31840 self.write(")");
31841 Ok(())
31842 }
31843
31844 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
31845 self.generate_expression(&e.this)?;
31847 self.write("!");
31848 self.generate_expression(&e.expression)?;
31849 Ok(())
31850 }
31851
31852 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
31853 self.write_keyword("MONTHNAME");
31855 self.write("(");
31856 self.generate_expression(&e.this)?;
31857 self.write(")");
31858 Ok(())
31859 }
31860
31861 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
31862 for comment in &e.leading_comments {
31864 self.write_formatted_comment(comment);
31865 if self.config.pretty {
31866 self.write_newline();
31867 self.write_indent();
31868 } else {
31869 self.write_space();
31870 }
31871 }
31872 self.write_keyword("INSERT");
31874 if e.overwrite {
31875 self.write_space();
31876 self.write_keyword("OVERWRITE");
31877 }
31878 self.write_space();
31879 self.write(&e.kind);
31880 if self.config.pretty {
31881 self.indent_level += 1;
31882 for expr in &e.expressions {
31883 self.write_newline();
31884 self.write_indent();
31885 self.generate_expression(expr)?;
31886 }
31887 self.indent_level -= 1;
31888 } else {
31889 for expr in &e.expressions {
31890 self.write_space();
31891 self.generate_expression(expr)?;
31892 }
31893 }
31894 if let Some(source) = &e.source {
31895 if self.config.pretty {
31896 self.write_newline();
31897 self.write_indent();
31898 } else {
31899 self.write_space();
31900 }
31901 self.generate_expression(source)?;
31902 }
31903 Ok(())
31904 }
31905
31906 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
31907 self.write_keyword("NEXT VALUE FOR");
31909 self.write_space();
31910 self.generate_expression(&e.this)?;
31911 if let Some(order) = &e.order {
31912 self.write_space();
31913 self.write_keyword("OVER");
31914 self.write(" (");
31915 self.generate_expression(order)?;
31916 self.write(")");
31917 }
31918 Ok(())
31919 }
31920
31921 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
31922 self.write_keyword("NORMAL");
31924 self.write("(");
31925 self.generate_expression(&e.this)?;
31926 if let Some(stddev) = &e.stddev {
31927 self.write(", ");
31928 self.generate_expression(stddev)?;
31929 }
31930 if let Some(gen) = &e.gen {
31931 self.write(", ");
31932 self.generate_expression(gen)?;
31933 }
31934 self.write(")");
31935 Ok(())
31936 }
31937
31938 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
31939 if e.is_casefold.is_some() {
31941 self.write_keyword("NORMALIZE_AND_CASEFOLD");
31942 } else {
31943 self.write_keyword("NORMALIZE");
31944 }
31945 self.write("(");
31946 self.generate_expression(&e.this)?;
31947 if let Some(form) = &e.form {
31948 self.write(", ");
31949 self.generate_expression(form)?;
31950 }
31951 self.write(")");
31952 Ok(())
31953 }
31954
31955 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
31956 if e.allow_null.is_none() {
31958 self.write_keyword("NOT ");
31959 }
31960 self.write_keyword("NULL");
31961 Ok(())
31962 }
31963
31964 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
31965 self.write_keyword("NULLIF");
31967 self.write("(");
31968 self.generate_expression(&e.this)?;
31969 self.write(", ");
31970 self.generate_expression(&e.expression)?;
31971 self.write(")");
31972 Ok(())
31973 }
31974
31975 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
31976 self.write_keyword("FORMAT");
31978 self.write("(");
31979 self.generate_expression(&e.this)?;
31980 self.write(", '");
31981 self.write(&e.format);
31982 self.write("'");
31983 if let Some(culture) = &e.culture {
31984 self.write(", ");
31985 self.generate_expression(culture)?;
31986 }
31987 self.write(")");
31988 Ok(())
31989 }
31990
31991 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
31992 self.write_keyword("OBJECT_AGG");
31994 self.write("(");
31995 self.generate_expression(&e.this)?;
31996 self.write(", ");
31997 self.generate_expression(&e.expression)?;
31998 self.write(")");
31999 Ok(())
32000 }
32001
32002 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
32003 self.generate_expression(&e.this)?;
32005 Ok(())
32006 }
32007
32008 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
32009 self.write_keyword("OBJECT_INSERT");
32011 self.write("(");
32012 self.generate_expression(&e.this)?;
32013 if let Some(key) = &e.key {
32014 self.write(", ");
32015 self.generate_expression(key)?;
32016 }
32017 if let Some(value) = &e.value {
32018 self.write(", ");
32019 self.generate_expression(value)?;
32020 }
32021 if let Some(update_flag) = &e.update_flag {
32022 self.write(", ");
32023 self.generate_expression(update_flag)?;
32024 }
32025 self.write(")");
32026 Ok(())
32027 }
32028
32029 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
32030 self.write_keyword("OFFSET");
32032 self.write_space();
32033 self.generate_expression(&e.this)?;
32034 if e.rows == Some(true)
32036 && matches!(
32037 self.config.dialect,
32038 Some(crate::dialects::DialectType::TSQL)
32039 | Some(crate::dialects::DialectType::Oracle)
32040 )
32041 {
32042 self.write_space();
32043 self.write_keyword("ROWS");
32044 }
32045 Ok(())
32046 }
32047
32048 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
32049 self.write_keyword("QUALIFY");
32051 self.write_space();
32052 self.generate_expression(&e.this)?;
32053 Ok(())
32054 }
32055
32056 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
32057 self.write_keyword("ON CLUSTER");
32059 self.write_space();
32060 self.generate_expression(&e.this)?;
32061 Ok(())
32062 }
32063
32064 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
32065 self.write_keyword("ON COMMIT");
32067 if e.delete.is_some() {
32068 self.write_keyword(" DELETE ROWS");
32069 } else {
32070 self.write_keyword(" PRESERVE ROWS");
32071 }
32072 Ok(())
32073 }
32074
32075 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
32076 if let Some(empty) = &e.empty {
32078 self.generate_expression(empty)?;
32079 self.write_keyword(" ON EMPTY");
32080 }
32081 if let Some(error) = &e.error {
32082 if e.empty.is_some() {
32083 self.write_space();
32084 }
32085 self.generate_expression(error)?;
32086 self.write_keyword(" ON ERROR");
32087 }
32088 if let Some(null) = &e.null {
32089 if e.empty.is_some() || e.error.is_some() {
32090 self.write_space();
32091 }
32092 self.generate_expression(null)?;
32093 self.write_keyword(" ON NULL");
32094 }
32095 Ok(())
32096 }
32097
32098 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
32099 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
32101 return Ok(());
32102 }
32103 if e.duplicate.is_some() {
32105 self.write_keyword("ON DUPLICATE KEY UPDATE");
32107 for (i, expr) in e.expressions.iter().enumerate() {
32108 if i > 0 {
32109 self.write(",");
32110 }
32111 self.write_space();
32112 self.generate_expression(expr)?;
32113 }
32114 return Ok(());
32115 } else {
32116 self.write_keyword("ON CONFLICT");
32117 }
32118 if let Some(constraint) = &e.constraint {
32119 self.write_keyword(" ON CONSTRAINT ");
32120 self.generate_expression(constraint)?;
32121 }
32122 if let Some(conflict_keys) = &e.conflict_keys {
32123 if let Expression::Tuple(t) = conflict_keys.as_ref() {
32125 self.write("(");
32126 for (i, expr) in t.expressions.iter().enumerate() {
32127 if i > 0 {
32128 self.write(", ");
32129 }
32130 self.generate_expression(expr)?;
32131 }
32132 self.write(")");
32133 } else {
32134 self.write("(");
32135 self.generate_expression(conflict_keys)?;
32136 self.write(")");
32137 }
32138 }
32139 if let Some(index_predicate) = &e.index_predicate {
32140 self.write_keyword(" WHERE ");
32141 self.generate_expression(index_predicate)?;
32142 }
32143 if let Some(action) = &e.action {
32144 if let Expression::Identifier(id) = action.as_ref() {
32146 if id.name.eq_ignore_ascii_case("NOTHING") {
32147 self.write_keyword(" DO NOTHING");
32148 } else {
32149 self.write_keyword(" DO ");
32150 self.generate_expression(action)?;
32151 }
32152 } else if let Expression::Tuple(t) = action.as_ref() {
32153 self.write_keyword(" DO UPDATE SET ");
32155 for (i, expr) in t.expressions.iter().enumerate() {
32156 if i > 0 {
32157 self.write(", ");
32158 }
32159 self.generate_expression(expr)?;
32160 }
32161 } else {
32162 self.write_keyword(" DO ");
32163 self.generate_expression(action)?;
32164 }
32165 }
32166 if let Some(where_) = &e.where_ {
32168 self.write_keyword(" WHERE ");
32169 self.generate_expression(where_)?;
32170 }
32171 Ok(())
32172 }
32173
32174 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
32175 self.write_keyword("ON");
32177 self.write_space();
32178 self.generate_expression(&e.this)?;
32179 Ok(())
32180 }
32181
32182 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
32183 self.generate_expression(&e.this)?;
32185 self.write_space();
32186 self.generate_expression(&e.expression)?;
32187 Ok(())
32188 }
32189
32190 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
32191 self.write_keyword("OPENJSON");
32193 self.write("(");
32194 self.generate_expression(&e.this)?;
32195 if let Some(path) = &e.path {
32196 self.write(", ");
32197 self.generate_expression(path)?;
32198 }
32199 self.write(")");
32200 if !e.expressions.is_empty() {
32201 self.write_keyword(" WITH");
32202 if self.config.pretty {
32203 self.write(" (\n");
32204 self.indent_level += 2;
32205 for (i, expr) in e.expressions.iter().enumerate() {
32206 if i > 0 {
32207 self.write(",\n");
32208 }
32209 self.write_indent();
32210 self.generate_expression(expr)?;
32211 }
32212 self.write("\n");
32213 self.indent_level -= 2;
32214 self.write(")");
32215 } else {
32216 self.write(" (");
32217 for (i, expr) in e.expressions.iter().enumerate() {
32218 if i > 0 {
32219 self.write(", ");
32220 }
32221 self.generate_expression(expr)?;
32222 }
32223 self.write(")");
32224 }
32225 }
32226 Ok(())
32227 }
32228
32229 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
32230 self.generate_expression(&e.this)?;
32232 self.write_space();
32233 if let Some(ref dt) = e.data_type {
32235 self.generate_data_type(dt)?;
32236 } else if !e.kind.is_empty() {
32237 self.write(&e.kind);
32238 }
32239 if let Some(path) = &e.path {
32240 self.write_space();
32241 self.generate_expression(path)?;
32242 }
32243 if e.as_json.is_some() {
32244 self.write_keyword(" AS JSON");
32245 }
32246 Ok(())
32247 }
32248
32249 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
32250 self.generate_expression(&e.this)?;
32252 self.write_space();
32253 if let Some(op) = &e.operator {
32254 self.write_keyword("OPERATOR");
32255 self.write("(");
32256 self.generate_expression(op)?;
32257 self.write(")");
32258 }
32259 for comment in &e.comments {
32261 self.write_space();
32262 self.write_formatted_comment(comment);
32263 }
32264 self.write_space();
32265 self.generate_expression(&e.expression)?;
32266 Ok(())
32267 }
32268
32269 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
32270 self.write_keyword("ORDER BY");
32272 let pretty_clickhouse_single_paren = self.config.pretty
32273 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
32274 && e.expressions.len() == 1
32275 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
32276 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
32277 && e.expressions.len() == 1
32278 && matches!(e.expressions[0].this, Expression::Tuple(_))
32279 && !e.expressions[0].desc
32280 && e.expressions[0].nulls_first.is_none();
32281
32282 if pretty_clickhouse_single_paren {
32283 self.write_space();
32284 if let Expression::Paren(p) = &e.expressions[0].this {
32285 self.write("(");
32286 self.write_newline();
32287 self.indent_level += 1;
32288 self.write_indent();
32289 self.generate_expression(&p.this)?;
32290 self.indent_level -= 1;
32291 self.write_newline();
32292 self.write(")");
32293 }
32294 return Ok(());
32295 }
32296
32297 if clickhouse_single_tuple {
32298 self.write_space();
32299 if let Expression::Tuple(t) = &e.expressions[0].this {
32300 self.write("(");
32301 for (i, expr) in t.expressions.iter().enumerate() {
32302 if i > 0 {
32303 self.write(", ");
32304 }
32305 self.generate_expression(expr)?;
32306 }
32307 self.write(")");
32308 }
32309 return Ok(());
32310 }
32311
32312 self.write_space();
32313 for (i, ordered) in e.expressions.iter().enumerate() {
32314 if i > 0 {
32315 self.write(", ");
32316 }
32317 self.generate_expression(&ordered.this)?;
32318 if ordered.desc {
32319 self.write_space();
32320 self.write_keyword("DESC");
32321 } else if ordered.explicit_asc {
32322 self.write_space();
32323 self.write_keyword("ASC");
32324 }
32325 if let Some(nulls_first) = ordered.nulls_first {
32326 let skip_nulls_last =
32328 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
32329 if !skip_nulls_last {
32330 self.write_space();
32331 self.write_keyword("NULLS");
32332 self.write_space();
32333 if nulls_first {
32334 self.write_keyword("FIRST");
32335 } else {
32336 self.write_keyword("LAST");
32337 }
32338 }
32339 }
32340 }
32341 Ok(())
32342 }
32343
32344 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
32345 self.write_keyword("OUTPUT");
32347 self.write("(");
32348 if self.config.pretty {
32349 self.indent_level += 1;
32350 self.write_newline();
32351 self.write_indent();
32352 self.generate_expression(&e.this)?;
32353 self.indent_level -= 1;
32354 self.write_newline();
32355 } else {
32356 self.generate_expression(&e.this)?;
32357 }
32358 self.write(")");
32359 Ok(())
32360 }
32361
32362 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
32363 self.write_keyword("TRUNCATE");
32365 if let Some(this) = &e.this {
32366 self.write_space();
32367 self.generate_expression(this)?;
32368 }
32369 if e.with_count.is_some() {
32370 self.write_keyword(" WITH COUNT");
32371 } else {
32372 self.write_keyword(" WITHOUT COUNT");
32373 }
32374 Ok(())
32375 }
32376
32377 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
32378 self.generate_expression(&e.this)?;
32380 self.write("(");
32381 for (i, expr) in e.expressions.iter().enumerate() {
32382 if i > 0 {
32383 self.write(", ");
32384 }
32385 self.generate_expression(expr)?;
32386 }
32387 self.write(")(");
32388 for (i, param) in e.params.iter().enumerate() {
32389 if i > 0 {
32390 self.write(", ");
32391 }
32392 self.generate_expression(param)?;
32393 }
32394 self.write(")");
32395 Ok(())
32396 }
32397
32398 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
32399 self.write_keyword("PARSE_DATETIME");
32401 self.write("(");
32402 if let Some(format) = &e.format {
32403 self.write("'");
32404 self.write(format);
32405 self.write("', ");
32406 }
32407 self.generate_expression(&e.this)?;
32408 if let Some(zone) = &e.zone {
32409 self.write(", ");
32410 self.generate_expression(zone)?;
32411 }
32412 self.write(")");
32413 Ok(())
32414 }
32415
32416 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
32417 self.write_keyword("PARSE_IP");
32419 self.write("(");
32420 self.generate_expression(&e.this)?;
32421 if let Some(type_) = &e.type_ {
32422 self.write(", ");
32423 self.generate_expression(type_)?;
32424 }
32425 if let Some(permissive) = &e.permissive {
32426 self.write(", ");
32427 self.generate_expression(permissive)?;
32428 }
32429 self.write(")");
32430 Ok(())
32431 }
32432
32433 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
32434 self.write_keyword("PARSE_JSON");
32436 self.write("(");
32437 self.generate_expression(&e.this)?;
32438 if let Some(expression) = &e.expression {
32439 self.write(", ");
32440 self.generate_expression(expression)?;
32441 }
32442 self.write(")");
32443 Ok(())
32444 }
32445
32446 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
32447 self.write_keyword("PARSE_TIME");
32449 self.write("(");
32450 self.write(&format!("'{}'", e.format));
32451 self.write(", ");
32452 self.generate_expression(&e.this)?;
32453 self.write(")");
32454 Ok(())
32455 }
32456
32457 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
32458 self.write_keyword("PARSE_URL");
32460 self.write("(");
32461 self.generate_expression(&e.this)?;
32462 if let Some(part) = &e.part_to_extract {
32463 self.write(", ");
32464 self.generate_expression(part)?;
32465 }
32466 if let Some(key) = &e.key {
32467 self.write(", ");
32468 self.generate_expression(key)?;
32469 }
32470 if let Some(permissive) = &e.permissive {
32471 self.write(", ");
32472 self.generate_expression(permissive)?;
32473 }
32474 self.write(")");
32475 Ok(())
32476 }
32477
32478 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
32479 if e.subpartition {
32481 self.write_keyword("SUBPARTITION");
32482 } else {
32483 self.write_keyword("PARTITION");
32484 }
32485 self.write("(");
32486 for (i, expr) in e.expressions.iter().enumerate() {
32487 if i > 0 {
32488 self.write(", ");
32489 }
32490 self.generate_expression(expr)?;
32491 }
32492 self.write(")");
32493 Ok(())
32494 }
32495
32496 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
32497 if let Some(this) = &e.this {
32499 if let Some(expression) = &e.expression {
32500 self.write_keyword("WITH");
32502 self.write(" (");
32503 self.write_keyword("MODULUS");
32504 self.write_space();
32505 self.generate_expression(this)?;
32506 self.write(", ");
32507 self.write_keyword("REMAINDER");
32508 self.write_space();
32509 self.generate_expression(expression)?;
32510 self.write(")");
32511 } else {
32512 self.write_keyword("IN");
32514 self.write(" (");
32515 self.generate_partition_bound_values(this)?;
32516 self.write(")");
32517 }
32518 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
32519 self.write_keyword("FROM");
32521 self.write(" (");
32522 self.generate_partition_bound_values(from)?;
32523 self.write(") ");
32524 self.write_keyword("TO");
32525 self.write(" (");
32526 self.generate_partition_bound_values(to)?;
32527 self.write(")");
32528 }
32529 Ok(())
32530 }
32531
32532 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
32535 if let Expression::Tuple(t) = expr {
32536 for (i, e) in t.expressions.iter().enumerate() {
32537 if i > 0 {
32538 self.write(", ");
32539 }
32540 self.generate_expression(e)?;
32541 }
32542 Ok(())
32543 } else {
32544 self.generate_expression(expr)
32545 }
32546 }
32547
32548 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
32549 self.write_keyword("PARTITION BY LIST");
32551 if let Some(partition_exprs) = &e.partition_expressions {
32552 self.write(" (");
32553 self.generate_doris_partition_expressions(partition_exprs)?;
32555 self.write(")");
32556 }
32557 if let Some(create_exprs) = &e.create_expressions {
32558 self.write(" (");
32559 self.generate_doris_partition_definitions(create_exprs)?;
32561 self.write(")");
32562 }
32563 Ok(())
32564 }
32565
32566 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
32567 self.write_keyword("PARTITION BY RANGE");
32569 if let Some(partition_exprs) = &e.partition_expressions {
32570 self.write(" (");
32571 self.generate_doris_partition_expressions(partition_exprs)?;
32573 self.write(")");
32574 }
32575 if let Some(create_exprs) = &e.create_expressions {
32576 self.write(" (");
32577 self.generate_doris_partition_definitions(create_exprs)?;
32579 self.write(")");
32580 }
32581 Ok(())
32582 }
32583
32584 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
32586 if let Expression::Tuple(t) = expr {
32587 for (i, e) in t.expressions.iter().enumerate() {
32588 if i > 0 {
32589 self.write(", ");
32590 }
32591 self.generate_expression(e)?;
32592 }
32593 } else {
32594 self.generate_expression(expr)?;
32595 }
32596 Ok(())
32597 }
32598
32599 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
32601 match expr {
32602 Expression::Tuple(t) => {
32603 for (i, part) in t.expressions.iter().enumerate() {
32605 if i > 0 {
32606 self.write(", ");
32607 }
32608 if let Expression::Partition(p) = part {
32610 for (j, inner) in p.expressions.iter().enumerate() {
32611 if j > 0 {
32612 self.write(", ");
32613 }
32614 self.generate_expression(inner)?;
32615 }
32616 } else {
32617 self.generate_expression(part)?;
32618 }
32619 }
32620 }
32621 Expression::PartitionByRangePropertyDynamic(_) => {
32622 self.generate_expression(expr)?;
32624 }
32625 _ => {
32626 self.generate_expression(expr)?;
32627 }
32628 }
32629 Ok(())
32630 }
32631
32632 fn generate_partition_by_range_property_dynamic(
32633 &mut self,
32634 e: &PartitionByRangePropertyDynamic,
32635 ) -> Result<()> {
32636 if e.use_start_end {
32637 if let Some(start) = &e.start {
32639 self.write_keyword("START");
32640 self.write(" (");
32641 self.generate_expression(start)?;
32642 self.write(")");
32643 }
32644 if let Some(end) = &e.end {
32645 self.write_space();
32646 self.write_keyword("END");
32647 self.write(" (");
32648 self.generate_expression(end)?;
32649 self.write(")");
32650 }
32651 if let Some(every) = &e.every {
32652 self.write_space();
32653 self.write_keyword("EVERY");
32654 self.write(" (");
32655 self.generate_doris_interval(every)?;
32657 self.write(")");
32658 }
32659 } else {
32660 if let Some(start) = &e.start {
32662 self.write_keyword("FROM");
32663 self.write(" (");
32664 self.generate_expression(start)?;
32665 self.write(")");
32666 }
32667 if let Some(end) = &e.end {
32668 self.write_space();
32669 self.write_keyword("TO");
32670 self.write(" (");
32671 self.generate_expression(end)?;
32672 self.write(")");
32673 }
32674 if let Some(every) = &e.every {
32675 self.write_space();
32676 self.generate_doris_interval(every)?;
32678 }
32679 }
32680 Ok(())
32681 }
32682
32683 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
32685 if let Expression::Interval(interval) = expr {
32686 self.write_keyword("INTERVAL");
32687 if let Some(ref value) = interval.this {
32688 self.write_space();
32689 match value {
32693 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()) => {
32694 if let Literal::String(s) = lit.as_ref() {
32695 self.write(s);
32696 }
32697 }
32698 _ => {
32699 self.generate_expression(value)?;
32700 }
32701 }
32702 }
32703 if let Some(ref unit_spec) = interval.unit {
32704 self.write_space();
32705 self.write_interval_unit_spec(unit_spec)?;
32706 }
32707 Ok(())
32708 } else {
32709 self.generate_expression(expr)
32710 }
32711 }
32712
32713 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
32714 self.write_keyword("TRUNCATE");
32716 self.write("(");
32717 self.generate_expression(&e.expression)?;
32718 self.write(", ");
32719 self.generate_expression(&e.this)?;
32720 self.write(")");
32721 Ok(())
32722 }
32723
32724 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
32725 self.write_keyword("PARTITION");
32727 self.write_space();
32728 self.generate_expression(&e.this)?;
32729 self.write_space();
32730 self.write_keyword("VALUES IN");
32731 self.write(" (");
32732 for (i, expr) in e.expressions.iter().enumerate() {
32733 if i > 0 {
32734 self.write(", ");
32735 }
32736 self.generate_expression(expr)?;
32737 }
32738 self.write(")");
32739 Ok(())
32740 }
32741
32742 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
32743 if e.expressions.is_empty() && e.expression.is_some() {
32746 self.generate_expression(&e.this)?;
32748 self.write_space();
32749 self.write_keyword("TO");
32750 self.write_space();
32751 self.generate_expression(e.expression.as_ref().unwrap())?;
32752 return Ok(());
32753 }
32754
32755 self.write_keyword("PARTITION");
32757 self.write_space();
32758 self.generate_expression(&e.this)?;
32759 self.write_space();
32760
32761 if e.expressions.len() == 1 {
32763 self.write_keyword("VALUES LESS THAN");
32765 self.write(" (");
32766 self.generate_expression(&e.expressions[0])?;
32767 self.write(")");
32768 } else if !e.expressions.is_empty() {
32769 self.write_keyword("VALUES");
32771 self.write(" [");
32772 for (i, expr) in e.expressions.iter().enumerate() {
32773 if i > 0 {
32774 self.write(", ");
32775 }
32776 if let Expression::Tuple(t) = expr {
32778 self.write("(");
32779 for (j, inner) in t.expressions.iter().enumerate() {
32780 if j > 0 {
32781 self.write(", ");
32782 }
32783 self.generate_expression(inner)?;
32784 }
32785 self.write(")");
32786 } else {
32787 self.write("(");
32788 self.generate_expression(expr)?;
32789 self.write(")");
32790 }
32791 }
32792 self.write(")");
32793 }
32794 Ok(())
32795 }
32796
32797 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
32798 self.write_keyword("BUCKET");
32800 self.write("(");
32801 self.generate_expression(&e.this)?;
32802 self.write(", ");
32803 self.generate_expression(&e.expression)?;
32804 self.write(")");
32805 Ok(())
32806 }
32807
32808 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
32809 self.write_keyword("PARTITION BY");
32811 self.write_space();
32812 for (i, expr) in e.expressions.iter().enumerate() {
32813 if i > 0 {
32814 self.write(", ");
32815 }
32816 self.generate_expression(expr)?;
32817 }
32818 Ok(())
32819 }
32820
32821 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
32822 if matches!(
32824 self.config.dialect,
32825 Some(crate::dialects::DialectType::Teradata)
32826 | Some(crate::dialects::DialectType::ClickHouse)
32827 ) {
32828 self.write_keyword("PARTITION BY");
32829 } else {
32830 self.write_keyword("PARTITIONED BY");
32831 }
32832 self.write_space();
32833 if self.config.pretty {
32835 if let Expression::Tuple(ref tuple) = *e.this {
32836 self.write("(");
32837 self.write_newline();
32838 self.indent_level += 1;
32839 for (i, expr) in tuple.expressions.iter().enumerate() {
32840 if i > 0 {
32841 self.write(",");
32842 self.write_newline();
32843 }
32844 self.write_indent();
32845 self.generate_expression(expr)?;
32846 }
32847 self.indent_level -= 1;
32848 self.write_newline();
32849 self.write(")");
32850 } else {
32851 self.generate_expression(&e.this)?;
32852 }
32853 } else {
32854 self.generate_expression(&e.this)?;
32855 }
32856 Ok(())
32857 }
32858
32859 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
32860 self.write_keyword("PARTITION OF");
32862 self.write_space();
32863 self.generate_expression(&e.this)?;
32864 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
32866 self.write_space();
32867 self.write_keyword("FOR VALUES");
32868 self.write_space();
32869 self.generate_expression(&e.expression)?;
32870 } else {
32871 self.write_space();
32872 self.write_keyword("DEFAULT");
32873 }
32874 Ok(())
32875 }
32876
32877 fn generate_period_for_system_time_constraint(
32878 &mut self,
32879 e: &PeriodForSystemTimeConstraint,
32880 ) -> Result<()> {
32881 self.write_keyword("PERIOD FOR SYSTEM_TIME");
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_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
32892 self.generate_expression(&e.this)?;
32895 self.write_space();
32896 self.write_keyword("AS");
32897 self.write_space();
32898 if self.config.unpivot_aliases_are_identifiers {
32900 match &e.alias {
32901 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
32902 let Literal::String(s) = lit.as_ref() else {
32903 unreachable!()
32904 };
32905 self.generate_identifier(&Identifier::new(s.clone()))?;
32907 }
32908 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
32909 let Literal::Number(n) = lit.as_ref() else {
32910 unreachable!()
32911 };
32912 let mut id = Identifier::new(n.clone());
32914 id.quoted = true;
32915 self.generate_identifier(&id)?;
32916 }
32917 other => {
32918 self.generate_expression(other)?;
32919 }
32920 }
32921 } else {
32922 self.generate_expression(&e.alias)?;
32923 }
32924 Ok(())
32925 }
32926
32927 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
32928 self.write_keyword("ANY");
32930 if let Some(this) = &e.this {
32931 self.write_space();
32932 self.generate_expression(this)?;
32933 }
32934 Ok(())
32935 }
32936
32937 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
32938 self.write_keyword("ML.PREDICT");
32940 self.write("(");
32941 self.write_keyword("MODEL");
32942 self.write_space();
32943 self.generate_expression(&e.this)?;
32944 self.write(", ");
32945 self.generate_expression(&e.expression)?;
32946 if let Some(params) = &e.params_struct {
32947 self.write(", ");
32948 self.generate_expression(params)?;
32949 }
32950 self.write(")");
32951 Ok(())
32952 }
32953
32954 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
32955 self.write_keyword("PREVIOUS_DAY");
32957 self.write("(");
32958 self.generate_expression(&e.this)?;
32959 self.write(", ");
32960 self.generate_expression(&e.expression)?;
32961 self.write(")");
32962 Ok(())
32963 }
32964
32965 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
32966 self.write_keyword("PRIMARY KEY");
32968 if let Some(name) = &e.this {
32969 self.write_space();
32970 self.generate_expression(name)?;
32971 }
32972 if !e.expressions.is_empty() {
32973 self.write(" (");
32974 for (i, expr) in e.expressions.iter().enumerate() {
32975 if i > 0 {
32976 self.write(", ");
32977 }
32978 self.generate_expression(expr)?;
32979 }
32980 self.write(")");
32981 }
32982 if let Some(include) = &e.include {
32983 self.write_space();
32984 self.generate_expression(include)?;
32985 }
32986 if !e.options.is_empty() {
32987 self.write_space();
32988 for (i, opt) in e.options.iter().enumerate() {
32989 if i > 0 {
32990 self.write_space();
32991 }
32992 self.generate_expression(opt)?;
32993 }
32994 }
32995 Ok(())
32996 }
32997
32998 fn generate_primary_key_column_constraint(
32999 &mut self,
33000 _e: &PrimaryKeyColumnConstraint,
33001 ) -> Result<()> {
33002 self.write_keyword("PRIMARY KEY");
33004 Ok(())
33005 }
33006
33007 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
33008 self.write_keyword("PATH");
33010 self.write_space();
33011 self.generate_expression(&e.this)?;
33012 Ok(())
33013 }
33014
33015 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
33016 self.write_keyword("PROJECTION");
33018 self.write_space();
33019 self.generate_expression(&e.this)?;
33020 self.write(" (");
33021 self.generate_expression(&e.expression)?;
33022 self.write(")");
33023 Ok(())
33024 }
33025
33026 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
33027 for (i, prop) in e.expressions.iter().enumerate() {
33029 if i > 0 {
33030 self.write(", ");
33031 }
33032 self.generate_expression(prop)?;
33033 }
33034 Ok(())
33035 }
33036
33037 fn generate_property(&mut self, e: &Property) -> Result<()> {
33038 self.generate_expression(&e.this)?;
33040 if let Some(value) = &e.value {
33041 self.write("=");
33042 self.generate_expression(value)?;
33043 }
33044 Ok(())
33045 }
33046
33047 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
33048 self.write_keyword("OPTIONS");
33049 if e.entries.is_empty() {
33050 self.write(" ()");
33051 return Ok(());
33052 }
33053
33054 if self.config.pretty {
33055 self.write(" (");
33056 self.write_newline();
33057 self.indent_level += 1;
33058 for (i, entry) in e.entries.iter().enumerate() {
33059 if i > 0 {
33060 self.write(",");
33061 self.write_newline();
33062 }
33063 self.write_indent();
33064 self.generate_identifier(&entry.key)?;
33065 self.write("=");
33066 self.generate_expression(&entry.value)?;
33067 }
33068 self.indent_level -= 1;
33069 self.write_newline();
33070 self.write(")");
33071 } else {
33072 self.write(" (");
33073 for (i, entry) in e.entries.iter().enumerate() {
33074 if i > 0 {
33075 self.write(", ");
33076 }
33077 self.generate_identifier(&entry.key)?;
33078 self.write("=");
33079 self.generate_expression(&entry.value)?;
33080 }
33081 self.write(")");
33082 }
33083 Ok(())
33084 }
33085
33086 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
33088 self.write_keyword("OPTIONS");
33089 self.write(" (");
33090 for (i, opt) in options.iter().enumerate() {
33091 if i > 0 {
33092 self.write(", ");
33093 }
33094 self.generate_option_expression(opt)?;
33095 }
33096 self.write(")");
33097 Ok(())
33098 }
33099
33100 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
33102 self.write_keyword("PROPERTIES");
33103 self.write(" (");
33104 for (i, prop) in properties.iter().enumerate() {
33105 if i > 0 {
33106 self.write(", ");
33107 }
33108 self.generate_option_expression(prop)?;
33109 }
33110 self.write(")");
33111 Ok(())
33112 }
33113
33114 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
33116 self.write_keyword("ENVIRONMENT");
33117 self.write(" (");
33118 for (i, env_item) in environment.iter().enumerate() {
33119 if i > 0 {
33120 self.write(", ");
33121 }
33122 self.generate_environment_expression(env_item)?;
33123 }
33124 self.write(")");
33125 Ok(())
33126 }
33127
33128 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
33130 match expr {
33131 Expression::Eq(eq) => {
33132 self.generate_expression(&eq.left)?;
33134 self.write(" = ");
33135 self.generate_expression(&eq.right)?;
33136 Ok(())
33137 }
33138 _ => self.generate_expression(expr),
33139 }
33140 }
33141
33142 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
33144 self.write_keyword("TBLPROPERTIES");
33145 if self.config.pretty {
33146 self.write(" (");
33147 self.write_newline();
33148 self.indent_level += 1;
33149 for (i, opt) in options.iter().enumerate() {
33150 if i > 0 {
33151 self.write(",");
33152 self.write_newline();
33153 }
33154 self.write_indent();
33155 self.generate_option_expression(opt)?;
33156 }
33157 self.indent_level -= 1;
33158 self.write_newline();
33159 self.write(")");
33160 } else {
33161 self.write(" (");
33162 for (i, opt) in options.iter().enumerate() {
33163 if i > 0 {
33164 self.write(", ");
33165 }
33166 self.generate_option_expression(opt)?;
33167 }
33168 self.write(")");
33169 }
33170 Ok(())
33171 }
33172
33173 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
33175 match expr {
33176 Expression::Eq(eq) => {
33177 self.generate_expression(&eq.left)?;
33179 self.write("=");
33180 self.generate_expression(&eq.right)?;
33181 Ok(())
33182 }
33183 _ => self.generate_expression(expr),
33184 }
33185 }
33186
33187 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
33188 self.generate_expression(&e.this)?;
33190 Ok(())
33191 }
33192
33193 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
33194 self.write_keyword("PUT");
33196 self.write_space();
33197
33198 if e.source_quoted {
33200 self.write("'");
33201 self.write(&e.source);
33202 self.write("'");
33203 } else {
33204 self.write(&e.source);
33205 }
33206
33207 self.write_space();
33208
33209 if let Expression::Literal(lit) = &e.target {
33211 if let Literal::String(s) = lit.as_ref() {
33212 self.write(s);
33213 }
33214 } else {
33215 self.generate_expression(&e.target)?;
33216 }
33217
33218 for param in &e.params {
33220 self.write_space();
33221 self.write(¶m.name);
33222 if let Some(ref value) = param.value {
33223 self.write("=");
33224 self.generate_expression(value)?;
33225 }
33226 }
33227
33228 Ok(())
33229 }
33230
33231 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
33232 self.write_keyword("QUANTILE");
33234 self.write("(");
33235 self.generate_expression(&e.this)?;
33236 if let Some(quantile) = &e.quantile {
33237 self.write(", ");
33238 self.generate_expression(quantile)?;
33239 }
33240 self.write(")");
33241 Ok(())
33242 }
33243
33244 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
33245 if matches!(
33247 self.config.dialect,
33248 Some(crate::dialects::DialectType::Teradata)
33249 ) {
33250 self.write_keyword("SET");
33251 self.write_space();
33252 }
33253 self.write_keyword("QUERY_BAND");
33254 self.write(" = ");
33255 self.generate_expression(&e.this)?;
33256 if e.update.is_some() {
33257 self.write_space();
33258 self.write_keyword("UPDATE");
33259 }
33260 if let Some(scope) = &e.scope {
33261 self.write_space();
33262 self.write_keyword("FOR");
33263 self.write_space();
33264 self.generate_expression(scope)?;
33265 }
33266 Ok(())
33267 }
33268
33269 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
33270 self.generate_expression(&e.this)?;
33272 if let Some(expression) = &e.expression {
33273 self.write(" = ");
33274 self.generate_expression(expression)?;
33275 }
33276 Ok(())
33277 }
33278
33279 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
33280 self.write_keyword("TRANSFORM");
33282 self.write("(");
33283 for (i, expr) in e.expressions.iter().enumerate() {
33284 if i > 0 {
33285 self.write(", ");
33286 }
33287 self.generate_expression(expr)?;
33288 }
33289 self.write(")");
33290 if let Some(row_format_before) = &e.row_format_before {
33291 self.write_space();
33292 self.generate_expression(row_format_before)?;
33293 }
33294 if let Some(record_writer) = &e.record_writer {
33295 self.write_space();
33296 self.write_keyword("RECORDWRITER");
33297 self.write_space();
33298 self.generate_expression(record_writer)?;
33299 }
33300 if let Some(command_script) = &e.command_script {
33301 self.write_space();
33302 self.write_keyword("USING");
33303 self.write_space();
33304 self.generate_expression(command_script)?;
33305 }
33306 if let Some(schema) = &e.schema {
33307 self.write_space();
33308 self.write_keyword("AS");
33309 self.write_space();
33310 self.generate_expression(schema)?;
33311 }
33312 if let Some(row_format_after) = &e.row_format_after {
33313 self.write_space();
33314 self.generate_expression(row_format_after)?;
33315 }
33316 if let Some(record_reader) = &e.record_reader {
33317 self.write_space();
33318 self.write_keyword("RECORDREADER");
33319 self.write_space();
33320 self.generate_expression(record_reader)?;
33321 }
33322 Ok(())
33323 }
33324
33325 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
33326 self.write_keyword("RANDN");
33328 self.write("(");
33329 if let Some(this) = &e.this {
33330 self.generate_expression(this)?;
33331 }
33332 self.write(")");
33333 Ok(())
33334 }
33335
33336 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
33337 self.write_keyword("RANDSTR");
33339 self.write("(");
33340 self.generate_expression(&e.this)?;
33341 if let Some(generator) = &e.generator {
33342 self.write(", ");
33343 self.generate_expression(generator)?;
33344 }
33345 self.write(")");
33346 Ok(())
33347 }
33348
33349 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
33350 self.write_keyword("RANGE_BUCKET");
33352 self.write("(");
33353 self.generate_expression(&e.this)?;
33354 self.write(", ");
33355 self.generate_expression(&e.expression)?;
33356 self.write(")");
33357 Ok(())
33358 }
33359
33360 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
33361 self.write_keyword("RANGE_N");
33363 self.write("(");
33364 self.generate_expression(&e.this)?;
33365 self.write_space();
33366 self.write_keyword("BETWEEN");
33367 self.write_space();
33368 for (i, expr) in e.expressions.iter().enumerate() {
33369 if i > 0 {
33370 self.write(", ");
33371 }
33372 self.generate_expression(expr)?;
33373 }
33374 if let Some(each) = &e.each {
33375 self.write_space();
33376 self.write_keyword("EACH");
33377 self.write_space();
33378 self.generate_expression(each)?;
33379 }
33380 self.write(")");
33381 Ok(())
33382 }
33383
33384 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
33385 self.write_keyword("READ_CSV");
33387 self.write("(");
33388 self.generate_expression(&e.this)?;
33389 for expr in &e.expressions {
33390 self.write(", ");
33391 self.generate_expression(expr)?;
33392 }
33393 self.write(")");
33394 Ok(())
33395 }
33396
33397 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
33398 self.write_keyword("READ_PARQUET");
33400 self.write("(");
33401 for (i, expr) in e.expressions.iter().enumerate() {
33402 if i > 0 {
33403 self.write(", ");
33404 }
33405 self.generate_expression(expr)?;
33406 }
33407 self.write(")");
33408 Ok(())
33409 }
33410
33411 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
33412 if e.kind == "CYCLE" {
33415 self.write_keyword("CYCLE");
33416 } else {
33417 self.write_keyword("SEARCH");
33418 self.write_space();
33419 self.write(&e.kind);
33420 self.write_space();
33421 self.write_keyword("FIRST BY");
33422 }
33423 self.write_space();
33424 self.generate_expression(&e.this)?;
33425 self.write_space();
33426 self.write_keyword("SET");
33427 self.write_space();
33428 self.generate_expression(&e.expression)?;
33429 if let Some(using) = &e.using {
33430 self.write_space();
33431 self.write_keyword("USING");
33432 self.write_space();
33433 self.generate_expression(using)?;
33434 }
33435 Ok(())
33436 }
33437
33438 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
33439 self.write_keyword("REDUCE");
33441 self.write("(");
33442 self.generate_expression(&e.this)?;
33443 if let Some(initial) = &e.initial {
33444 self.write(", ");
33445 self.generate_expression(initial)?;
33446 }
33447 if let Some(merge) = &e.merge {
33448 self.write(", ");
33449 self.generate_expression(merge)?;
33450 }
33451 if let Some(finish) = &e.finish {
33452 self.write(", ");
33453 self.generate_expression(finish)?;
33454 }
33455 self.write(")");
33456 Ok(())
33457 }
33458
33459 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
33460 self.write_keyword("REFERENCES");
33462 self.write_space();
33463 self.generate_expression(&e.this)?;
33464 if !e.expressions.is_empty() {
33465 self.write(" (");
33466 for (i, expr) in e.expressions.iter().enumerate() {
33467 if i > 0 {
33468 self.write(", ");
33469 }
33470 self.generate_expression(expr)?;
33471 }
33472 self.write(")");
33473 }
33474 for opt in &e.options {
33475 self.write_space();
33476 self.generate_expression(opt)?;
33477 }
33478 Ok(())
33479 }
33480
33481 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
33482 self.write_keyword("REFRESH");
33484 if !e.kind.is_empty() {
33485 self.write_space();
33486 self.write_keyword(&e.kind);
33487 }
33488 self.write_space();
33489 self.generate_expression(&e.this)?;
33490 Ok(())
33491 }
33492
33493 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
33494 self.write_keyword("REFRESH");
33496 self.write_space();
33497 self.write_keyword(&e.method);
33498
33499 if let Some(ref kind) = e.kind {
33500 self.write_space();
33501 self.write_keyword("ON");
33502 self.write_space();
33503 self.write_keyword(kind);
33504
33505 if let Some(ref every) = e.every {
33507 self.write_space();
33508 self.write_keyword("EVERY");
33509 self.write_space();
33510 self.generate_expression(every)?;
33511 if let Some(ref unit) = e.unit {
33512 self.write_space();
33513 self.write_keyword(unit);
33514 }
33515 }
33516
33517 if let Some(ref starts) = e.starts {
33519 self.write_space();
33520 self.write_keyword("STARTS");
33521 self.write_space();
33522 self.generate_expression(starts)?;
33523 }
33524 }
33525 Ok(())
33526 }
33527
33528 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
33529 self.write_keyword("REGEXP_COUNT");
33531 self.write("(");
33532 self.generate_expression(&e.this)?;
33533 self.write(", ");
33534 self.generate_expression(&e.expression)?;
33535 if let Some(position) = &e.position {
33536 self.write(", ");
33537 self.generate_expression(position)?;
33538 }
33539 if let Some(parameters) = &e.parameters {
33540 self.write(", ");
33541 self.generate_expression(parameters)?;
33542 }
33543 self.write(")");
33544 Ok(())
33545 }
33546
33547 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
33548 self.write_keyword("REGEXP_EXTRACT_ALL");
33550 self.write("(");
33551 self.generate_expression(&e.this)?;
33552 self.write(", ");
33553 self.generate_expression(&e.expression)?;
33554 if let Some(group) = &e.group {
33555 self.write(", ");
33556 self.generate_expression(group)?;
33557 }
33558 self.write(")");
33559 Ok(())
33560 }
33561
33562 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
33563 self.write_keyword("REGEXP_FULL_MATCH");
33565 self.write("(");
33566 self.generate_expression(&e.this)?;
33567 self.write(", ");
33568 self.generate_expression(&e.expression)?;
33569 self.write(")");
33570 Ok(())
33571 }
33572
33573 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
33574 use crate::dialects::DialectType;
33575 if matches!(
33577 self.config.dialect,
33578 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
33579 ) && e.flag.is_none()
33580 {
33581 self.generate_expression(&e.this)?;
33582 self.write(" ~* ");
33583 self.generate_expression(&e.expression)?;
33584 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33585 self.write_keyword("REGEXP_LIKE");
33587 self.write("(");
33588 self.generate_expression(&e.this)?;
33589 self.write(", ");
33590 self.generate_expression(&e.expression)?;
33591 self.write(", ");
33592 if let Some(flag) = &e.flag {
33593 self.generate_expression(flag)?;
33594 } else {
33595 self.write("'i'");
33596 }
33597 self.write(")");
33598 } else {
33599 self.generate_expression(&e.this)?;
33601 self.write_space();
33602 self.write_keyword("REGEXP_ILIKE");
33603 self.write_space();
33604 self.generate_expression(&e.expression)?;
33605 if let Some(flag) = &e.flag {
33606 self.write(", ");
33607 self.generate_expression(flag)?;
33608 }
33609 }
33610 Ok(())
33611 }
33612
33613 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
33614 self.write_keyword("REGEXP_INSTR");
33616 self.write("(");
33617 self.generate_expression(&e.this)?;
33618 self.write(", ");
33619 self.generate_expression(&e.expression)?;
33620 if let Some(position) = &e.position {
33621 self.write(", ");
33622 self.generate_expression(position)?;
33623 }
33624 if let Some(occurrence) = &e.occurrence {
33625 self.write(", ");
33626 self.generate_expression(occurrence)?;
33627 }
33628 if let Some(option) = &e.option {
33629 self.write(", ");
33630 self.generate_expression(option)?;
33631 }
33632 if let Some(parameters) = &e.parameters {
33633 self.write(", ");
33634 self.generate_expression(parameters)?;
33635 }
33636 if let Some(group) = &e.group {
33637 self.write(", ");
33638 self.generate_expression(group)?;
33639 }
33640 self.write(")");
33641 Ok(())
33642 }
33643
33644 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
33645 self.write_keyword("REGEXP_SPLIT");
33647 self.write("(");
33648 self.generate_expression(&e.this)?;
33649 self.write(", ");
33650 self.generate_expression(&e.expression)?;
33651 if let Some(limit) = &e.limit {
33652 self.write(", ");
33653 self.generate_expression(limit)?;
33654 }
33655 self.write(")");
33656 Ok(())
33657 }
33658
33659 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
33660 self.write_keyword("REGR_AVGX");
33662 self.write("(");
33663 self.generate_expression(&e.this)?;
33664 self.write(", ");
33665 self.generate_expression(&e.expression)?;
33666 self.write(")");
33667 Ok(())
33668 }
33669
33670 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
33671 self.write_keyword("REGR_AVGY");
33673 self.write("(");
33674 self.generate_expression(&e.this)?;
33675 self.write(", ");
33676 self.generate_expression(&e.expression)?;
33677 self.write(")");
33678 Ok(())
33679 }
33680
33681 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
33682 self.write_keyword("REGR_COUNT");
33684 self.write("(");
33685 self.generate_expression(&e.this)?;
33686 self.write(", ");
33687 self.generate_expression(&e.expression)?;
33688 self.write(")");
33689 Ok(())
33690 }
33691
33692 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
33693 self.write_keyword("REGR_INTERCEPT");
33695 self.write("(");
33696 self.generate_expression(&e.this)?;
33697 self.write(", ");
33698 self.generate_expression(&e.expression)?;
33699 self.write(")");
33700 Ok(())
33701 }
33702
33703 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
33704 self.write_keyword("REGR_R2");
33706 self.write("(");
33707 self.generate_expression(&e.this)?;
33708 self.write(", ");
33709 self.generate_expression(&e.expression)?;
33710 self.write(")");
33711 Ok(())
33712 }
33713
33714 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
33715 self.write_keyword("REGR_SLOPE");
33717 self.write("(");
33718 self.generate_expression(&e.this)?;
33719 self.write(", ");
33720 self.generate_expression(&e.expression)?;
33721 self.write(")");
33722 Ok(())
33723 }
33724
33725 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
33726 self.write_keyword("REGR_SXX");
33728 self.write("(");
33729 self.generate_expression(&e.this)?;
33730 self.write(", ");
33731 self.generate_expression(&e.expression)?;
33732 self.write(")");
33733 Ok(())
33734 }
33735
33736 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
33737 self.write_keyword("REGR_SXY");
33739 self.write("(");
33740 self.generate_expression(&e.this)?;
33741 self.write(", ");
33742 self.generate_expression(&e.expression)?;
33743 self.write(")");
33744 Ok(())
33745 }
33746
33747 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
33748 self.write_keyword("REGR_SYY");
33750 self.write("(");
33751 self.generate_expression(&e.this)?;
33752 self.write(", ");
33753 self.generate_expression(&e.expression)?;
33754 self.write(")");
33755 Ok(())
33756 }
33757
33758 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
33759 self.write_keyword("REGR_VALX");
33761 self.write("(");
33762 self.generate_expression(&e.this)?;
33763 self.write(", ");
33764 self.generate_expression(&e.expression)?;
33765 self.write(")");
33766 Ok(())
33767 }
33768
33769 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
33770 self.write_keyword("REGR_VALY");
33772 self.write("(");
33773 self.generate_expression(&e.this)?;
33774 self.write(", ");
33775 self.generate_expression(&e.expression)?;
33776 self.write(")");
33777 Ok(())
33778 }
33779
33780 fn generate_remote_with_connection_model_property(
33781 &mut self,
33782 e: &RemoteWithConnectionModelProperty,
33783 ) -> Result<()> {
33784 self.write_keyword("REMOTE WITH CONNECTION");
33786 self.write_space();
33787 self.generate_expression(&e.this)?;
33788 Ok(())
33789 }
33790
33791 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
33792 self.write_keyword("RENAME COLUMN");
33794 if e.exists {
33795 self.write_space();
33796 self.write_keyword("IF EXISTS");
33797 }
33798 self.write_space();
33799 self.generate_expression(&e.this)?;
33800 if let Some(to) = &e.to {
33801 self.write_space();
33802 self.write_keyword("TO");
33803 self.write_space();
33804 self.generate_expression(to)?;
33805 }
33806 Ok(())
33807 }
33808
33809 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
33810 self.write_keyword("REPLACE PARTITION");
33812 self.write_space();
33813 self.generate_expression(&e.expression)?;
33814 if let Some(source) = &e.source {
33815 self.write_space();
33816 self.write_keyword("FROM");
33817 self.write_space();
33818 self.generate_expression(source)?;
33819 }
33820 Ok(())
33821 }
33822
33823 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
33824 let keyword = match self.config.dialect {
33827 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
33828 _ => "RETURNING",
33829 };
33830 self.write_keyword(keyword);
33831 self.write_space();
33832 for (i, expr) in e.expressions.iter().enumerate() {
33833 if i > 0 {
33834 self.write(", ");
33835 }
33836 self.generate_expression(expr)?;
33837 }
33838 if let Some(into) = &e.into {
33839 self.write_space();
33840 self.write_keyword("INTO");
33841 self.write_space();
33842 self.generate_expression(into)?;
33843 }
33844 Ok(())
33845 }
33846
33847 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
33848 self.write_space();
33850 self.write_keyword("OUTPUT");
33851 self.write_space();
33852 for (i, expr) in output.columns.iter().enumerate() {
33853 if i > 0 {
33854 self.write(", ");
33855 }
33856 self.generate_expression(expr)?;
33857 }
33858 if let Some(into_table) = &output.into_table {
33859 self.write_space();
33860 self.write_keyword("INTO");
33861 self.write_space();
33862 self.generate_expression(into_table)?;
33863 }
33864 Ok(())
33865 }
33866
33867 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
33868 self.write_keyword("RETURNS");
33870 if e.is_table.is_some() {
33871 self.write_space();
33872 self.write_keyword("TABLE");
33873 }
33874 if let Some(table) = &e.table {
33875 self.write_space();
33876 self.generate_expression(table)?;
33877 } else if let Some(this) = &e.this {
33878 self.write_space();
33879 self.generate_expression(this)?;
33880 }
33881 if e.null.is_some() {
33882 self.write_space();
33883 self.write_keyword("NULL ON NULL INPUT");
33884 }
33885 Ok(())
33886 }
33887
33888 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
33889 self.write_keyword("ROLLBACK");
33891
33892 if e.this.is_none()
33894 && matches!(
33895 self.config.dialect,
33896 Some(DialectType::TSQL) | Some(DialectType::Fabric)
33897 )
33898 {
33899 self.write_space();
33900 self.write_keyword("TRANSACTION");
33901 }
33902
33903 if let Some(this) = &e.this {
33905 let is_transaction_marker = matches!(
33907 this.as_ref(),
33908 Expression::Identifier(id) if id.name == "TRANSACTION"
33909 );
33910
33911 self.write_space();
33912 self.write_keyword("TRANSACTION");
33913
33914 if !is_transaction_marker {
33916 self.write_space();
33917 self.generate_expression(this)?;
33918 }
33919 }
33920
33921 if let Some(savepoint) = &e.savepoint {
33923 self.write_space();
33924 self.write_keyword("TO");
33925 self.write_space();
33926 self.generate_expression(savepoint)?;
33927 }
33928 Ok(())
33929 }
33930
33931 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
33932 if e.expressions.is_empty() {
33934 self.write_keyword("WITH ROLLUP");
33935 } else {
33936 self.write_keyword("ROLLUP");
33937 self.write("(");
33938 for (i, expr) in e.expressions.iter().enumerate() {
33939 if i > 0 {
33940 self.write(", ");
33941 }
33942 self.generate_expression(expr)?;
33943 }
33944 self.write(")");
33945 }
33946 Ok(())
33947 }
33948
33949 fn generate_row_format_delimited_property(
33950 &mut self,
33951 e: &RowFormatDelimitedProperty,
33952 ) -> Result<()> {
33953 self.write_keyword("ROW FORMAT DELIMITED");
33955 if let Some(fields) = &e.fields {
33956 self.write_space();
33957 self.write_keyword("FIELDS TERMINATED BY");
33958 self.write_space();
33959 self.generate_expression(fields)?;
33960 }
33961 if let Some(escaped) = &e.escaped {
33962 self.write_space();
33963 self.write_keyword("ESCAPED BY");
33964 self.write_space();
33965 self.generate_expression(escaped)?;
33966 }
33967 if let Some(items) = &e.collection_items {
33968 self.write_space();
33969 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
33970 self.write_space();
33971 self.generate_expression(items)?;
33972 }
33973 if let Some(keys) = &e.map_keys {
33974 self.write_space();
33975 self.write_keyword("MAP KEYS TERMINATED BY");
33976 self.write_space();
33977 self.generate_expression(keys)?;
33978 }
33979 if let Some(lines) = &e.lines {
33980 self.write_space();
33981 self.write_keyword("LINES TERMINATED BY");
33982 self.write_space();
33983 self.generate_expression(lines)?;
33984 }
33985 if let Some(null) = &e.null {
33986 self.write_space();
33987 self.write_keyword("NULL DEFINED AS");
33988 self.write_space();
33989 self.generate_expression(null)?;
33990 }
33991 if let Some(serde) = &e.serde {
33992 self.write_space();
33993 self.generate_expression(serde)?;
33994 }
33995 Ok(())
33996 }
33997
33998 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
33999 self.write_keyword("ROW FORMAT");
34001 self.write_space();
34002 self.generate_expression(&e.this)?;
34003 Ok(())
34004 }
34005
34006 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
34007 self.write_keyword("ROW FORMAT SERDE");
34009 self.write_space();
34010 self.generate_expression(&e.this)?;
34011 if let Some(props) = &e.serde_properties {
34012 self.write_space();
34013 self.generate_expression(props)?;
34015 }
34016 Ok(())
34017 }
34018
34019 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
34020 self.write_keyword("SHA2");
34022 self.write("(");
34023 self.generate_expression(&e.this)?;
34024 if let Some(length) = e.length {
34025 self.write(", ");
34026 self.write(&length.to_string());
34027 }
34028 self.write(")");
34029 Ok(())
34030 }
34031
34032 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
34033 self.write_keyword("SHA2_DIGEST");
34035 self.write("(");
34036 self.generate_expression(&e.this)?;
34037 if let Some(length) = e.length {
34038 self.write(", ");
34039 self.write(&length.to_string());
34040 }
34041 self.write(")");
34042 Ok(())
34043 }
34044
34045 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
34046 let name = if matches!(
34047 self.config.dialect,
34048 Some(crate::dialects::DialectType::Spark)
34049 | Some(crate::dialects::DialectType::Databricks)
34050 ) {
34051 "TRY_ADD"
34052 } else {
34053 "SAFE_ADD"
34054 };
34055 self.write_keyword(name);
34056 self.write("(");
34057 self.generate_expression(&e.this)?;
34058 self.write(", ");
34059 self.generate_expression(&e.expression)?;
34060 self.write(")");
34061 Ok(())
34062 }
34063
34064 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
34065 self.write_keyword("SAFE_DIVIDE");
34067 self.write("(");
34068 self.generate_expression(&e.this)?;
34069 self.write(", ");
34070 self.generate_expression(&e.expression)?;
34071 self.write(")");
34072 Ok(())
34073 }
34074
34075 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
34076 let name = if matches!(
34077 self.config.dialect,
34078 Some(crate::dialects::DialectType::Spark)
34079 | Some(crate::dialects::DialectType::Databricks)
34080 ) {
34081 "TRY_MULTIPLY"
34082 } else {
34083 "SAFE_MULTIPLY"
34084 };
34085 self.write_keyword(name);
34086 self.write("(");
34087 self.generate_expression(&e.this)?;
34088 self.write(", ");
34089 self.generate_expression(&e.expression)?;
34090 self.write(")");
34091 Ok(())
34092 }
34093
34094 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
34095 let name = if matches!(
34096 self.config.dialect,
34097 Some(crate::dialects::DialectType::Spark)
34098 | Some(crate::dialects::DialectType::Databricks)
34099 ) {
34100 "TRY_SUBTRACT"
34101 } else {
34102 "SAFE_SUBTRACT"
34103 };
34104 self.write_keyword(name);
34105 self.write("(");
34106 self.generate_expression(&e.this)?;
34107 self.write(", ");
34108 self.generate_expression(&e.expression)?;
34109 self.write(")");
34110 Ok(())
34111 }
34112
34113 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
34116 if matches!(sample.method, SampleMethod::Bucket) {
34118 self.write(" (");
34119 self.write_keyword("BUCKET");
34120 self.write_space();
34121 if let Some(ref num) = sample.bucket_numerator {
34122 self.generate_expression(num)?;
34123 }
34124 self.write_space();
34125 self.write_keyword("OUT OF");
34126 self.write_space();
34127 if let Some(ref denom) = sample.bucket_denominator {
34128 self.generate_expression(denom)?;
34129 }
34130 if let Some(ref field) = sample.bucket_field {
34131 self.write_space();
34132 self.write_keyword("ON");
34133 self.write_space();
34134 self.generate_expression(field)?;
34135 }
34136 self.write(")");
34137 return Ok(());
34138 }
34139
34140 let is_snowflake = matches!(
34142 self.config.dialect,
34143 Some(crate::dialects::DialectType::Snowflake)
34144 );
34145 let is_postgres = matches!(
34146 self.config.dialect,
34147 Some(crate::dialects::DialectType::PostgreSQL)
34148 | Some(crate::dialects::DialectType::Redshift)
34149 );
34150 let is_databricks = matches!(
34152 self.config.dialect,
34153 Some(crate::dialects::DialectType::Databricks)
34154 );
34155 let is_spark = matches!(
34156 self.config.dialect,
34157 Some(crate::dialects::DialectType::Spark)
34158 );
34159 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
34160 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
34162 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
34163 self.write_space();
34164 if !sample.explicit_method && (is_snowflake || force_method) {
34165 self.write_keyword("BERNOULLI");
34167 } else {
34168 match sample.method {
34169 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
34170 SampleMethod::System => self.write_keyword("SYSTEM"),
34171 SampleMethod::Block => self.write_keyword("BLOCK"),
34172 SampleMethod::Row => self.write_keyword("ROW"),
34173 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
34174 SampleMethod::Percent => self.write_keyword("SYSTEM"),
34175 SampleMethod::Bucket => {} }
34177 }
34178 }
34179
34180 let emit_size_no_parens = !self.config.tablesample_requires_parens;
34182 if emit_size_no_parens {
34183 self.write_space();
34184 match &sample.size {
34185 Expression::Tuple(tuple) => {
34186 for (i, expr) in tuple.expressions.iter().enumerate() {
34187 if i > 0 {
34188 self.write(", ");
34189 }
34190 self.generate_expression(expr)?;
34191 }
34192 }
34193 expr => self.generate_expression(expr)?,
34194 }
34195 } else {
34196 self.write(" (");
34197 self.generate_expression(&sample.size)?;
34198 }
34199
34200 let is_rows_method = matches!(
34202 sample.method,
34203 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
34204 );
34205 let is_percent = matches!(
34206 sample.method,
34207 SampleMethod::Percent
34208 | SampleMethod::System
34209 | SampleMethod::Bernoulli
34210 | SampleMethod::Block
34211 );
34212
34213 let is_presto = matches!(
34217 self.config.dialect,
34218 Some(crate::dialects::DialectType::Presto)
34219 | Some(crate::dialects::DialectType::Trino)
34220 | Some(crate::dialects::DialectType::Athena)
34221 );
34222 let should_output_unit = if is_databricks || is_spark {
34223 is_percent || is_rows_method || sample.unit_after_size
34225 } else if is_snowflake || is_postgres || is_presto {
34226 sample.unit_after_size
34227 } else {
34228 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
34229 };
34230
34231 if should_output_unit {
34232 self.write_space();
34233 if sample.is_percent {
34234 self.write_keyword("PERCENT");
34235 } else if is_rows_method && !sample.unit_after_size {
34236 self.write_keyword("ROWS");
34237 } else if sample.unit_after_size {
34238 match sample.method {
34239 SampleMethod::Percent
34240 | SampleMethod::System
34241 | SampleMethod::Bernoulli
34242 | SampleMethod::Block => {
34243 self.write_keyword("PERCENT");
34244 }
34245 SampleMethod::Row | SampleMethod::Reservoir => {
34246 self.write_keyword("ROWS");
34247 }
34248 _ => self.write_keyword("ROWS"),
34249 }
34250 } else {
34251 self.write_keyword("PERCENT");
34252 }
34253 }
34254
34255 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34256 if let Some(ref offset) = sample.offset {
34257 self.write_space();
34258 self.write_keyword("OFFSET");
34259 self.write_space();
34260 self.generate_expression(offset)?;
34261 }
34262 }
34263 if !emit_size_no_parens {
34264 self.write(")");
34265 }
34266
34267 Ok(())
34268 }
34269
34270 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
34271 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34273 self.write_keyword("SAMPLE BY");
34274 } else {
34275 self.write_keyword("SAMPLE");
34276 }
34277 self.write_space();
34278 self.generate_expression(&e.this)?;
34279 Ok(())
34280 }
34281
34282 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
34283 if let Some(this) = &e.this {
34285 self.generate_expression(this)?;
34286 }
34287 if !e.expressions.is_empty() {
34288 if e.this.is_some() {
34290 self.write_space();
34291 }
34292 self.write("(");
34293 for (i, expr) in e.expressions.iter().enumerate() {
34294 if i > 0 {
34295 self.write(", ");
34296 }
34297 self.generate_expression(expr)?;
34298 }
34299 self.write(")");
34300 }
34301 Ok(())
34302 }
34303
34304 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
34305 self.write_keyword("COMMENT");
34307 self.write_space();
34308 self.generate_expression(&e.this)?;
34309 Ok(())
34310 }
34311
34312 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
34313 if let Some(this) = &e.this {
34315 self.generate_expression(this)?;
34316 self.write("::");
34317 }
34318 self.generate_expression(&e.expression)?;
34319 Ok(())
34320 }
34321
34322 fn generate_search(&mut self, e: &Search) -> Result<()> {
34323 self.write_keyword("SEARCH");
34325 self.write("(");
34326 self.generate_expression(&e.this)?;
34327 self.write(", ");
34328 self.generate_expression(&e.expression)?;
34329 if let Some(json_scope) = &e.json_scope {
34330 self.write(", ");
34331 self.generate_expression(json_scope)?;
34332 }
34333 if let Some(analyzer) = &e.analyzer {
34334 self.write(", ");
34335 self.generate_expression(analyzer)?;
34336 }
34337 if let Some(analyzer_options) = &e.analyzer_options {
34338 self.write(", ");
34339 self.generate_expression(analyzer_options)?;
34340 }
34341 if let Some(search_mode) = &e.search_mode {
34342 self.write(", ");
34343 self.generate_expression(search_mode)?;
34344 }
34345 self.write(")");
34346 Ok(())
34347 }
34348
34349 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
34350 self.write_keyword("SEARCH_IP");
34352 self.write("(");
34353 self.generate_expression(&e.this)?;
34354 self.write(", ");
34355 self.generate_expression(&e.expression)?;
34356 self.write(")");
34357 Ok(())
34358 }
34359
34360 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
34361 self.write_keyword("SECURITY");
34363 self.write_space();
34364 self.generate_expression(&e.this)?;
34365 Ok(())
34366 }
34367
34368 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
34369 self.write("SEMANTIC_VIEW(");
34371
34372 if self.config.pretty {
34373 self.write_newline();
34375 self.indent_level += 1;
34376 self.write_indent();
34377 self.generate_expression(&e.this)?;
34378
34379 if let Some(metrics) = &e.metrics {
34380 self.write_newline();
34381 self.write_indent();
34382 self.write_keyword("METRICS");
34383 self.write_space();
34384 self.generate_semantic_view_tuple(metrics)?;
34385 }
34386 if let Some(dimensions) = &e.dimensions {
34387 self.write_newline();
34388 self.write_indent();
34389 self.write_keyword("DIMENSIONS");
34390 self.write_space();
34391 self.generate_semantic_view_tuple(dimensions)?;
34392 }
34393 if let Some(facts) = &e.facts {
34394 self.write_newline();
34395 self.write_indent();
34396 self.write_keyword("FACTS");
34397 self.write_space();
34398 self.generate_semantic_view_tuple(facts)?;
34399 }
34400 if let Some(where_) = &e.where_ {
34401 self.write_newline();
34402 self.write_indent();
34403 self.write_keyword("WHERE");
34404 self.write_space();
34405 self.generate_expression(where_)?;
34406 }
34407 self.write_newline();
34408 self.indent_level -= 1;
34409 self.write_indent();
34410 } else {
34411 self.generate_expression(&e.this)?;
34413 if let Some(metrics) = &e.metrics {
34414 self.write_space();
34415 self.write_keyword("METRICS");
34416 self.write_space();
34417 self.generate_semantic_view_tuple(metrics)?;
34418 }
34419 if let Some(dimensions) = &e.dimensions {
34420 self.write_space();
34421 self.write_keyword("DIMENSIONS");
34422 self.write_space();
34423 self.generate_semantic_view_tuple(dimensions)?;
34424 }
34425 if let Some(facts) = &e.facts {
34426 self.write_space();
34427 self.write_keyword("FACTS");
34428 self.write_space();
34429 self.generate_semantic_view_tuple(facts)?;
34430 }
34431 if let Some(where_) = &e.where_ {
34432 self.write_space();
34433 self.write_keyword("WHERE");
34434 self.write_space();
34435 self.generate_expression(where_)?;
34436 }
34437 }
34438 self.write(")");
34439 Ok(())
34440 }
34441
34442 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
34444 if let Expression::Tuple(t) = expr {
34445 for (i, e) in t.expressions.iter().enumerate() {
34446 if i > 0 {
34447 self.write(", ");
34448 }
34449 self.generate_expression(e)?;
34450 }
34451 } else {
34452 self.generate_expression(expr)?;
34453 }
34454 Ok(())
34455 }
34456
34457 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
34458 if let Some(start) = &e.start {
34460 self.write_keyword("START WITH");
34461 self.write_space();
34462 self.generate_expression(start)?;
34463 }
34464 if let Some(increment) = &e.increment {
34465 self.write_space();
34466 self.write_keyword("INCREMENT BY");
34467 self.write_space();
34468 self.generate_expression(increment)?;
34469 }
34470 if let Some(minvalue) = &e.minvalue {
34471 self.write_space();
34472 self.write_keyword("MINVALUE");
34473 self.write_space();
34474 self.generate_expression(minvalue)?;
34475 }
34476 if let Some(maxvalue) = &e.maxvalue {
34477 self.write_space();
34478 self.write_keyword("MAXVALUE");
34479 self.write_space();
34480 self.generate_expression(maxvalue)?;
34481 }
34482 if let Some(cache) = &e.cache {
34483 self.write_space();
34484 self.write_keyword("CACHE");
34485 self.write_space();
34486 self.generate_expression(cache)?;
34487 }
34488 if let Some(owned) = &e.owned {
34489 self.write_space();
34490 self.write_keyword("OWNED BY");
34491 self.write_space();
34492 self.generate_expression(owned)?;
34493 }
34494 for opt in &e.options {
34495 self.write_space();
34496 self.generate_expression(opt)?;
34497 }
34498 Ok(())
34499 }
34500
34501 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
34502 if e.with_.is_some() {
34504 self.write_keyword("WITH");
34505 self.write_space();
34506 }
34507 self.write_keyword("SERDEPROPERTIES");
34508 self.write(" (");
34509 for (i, expr) in e.expressions.iter().enumerate() {
34510 if i > 0 {
34511 self.write(", ");
34512 }
34513 match expr {
34515 Expression::Eq(eq) => {
34516 self.generate_expression(&eq.left)?;
34517 self.write("=");
34518 self.generate_expression(&eq.right)?;
34519 }
34520 _ => self.generate_expression(expr)?,
34521 }
34522 }
34523 self.write(")");
34524 Ok(())
34525 }
34526
34527 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
34528 self.write("@@");
34530 if let Some(kind) = &e.kind {
34531 self.write(kind);
34532 self.write(".");
34533 }
34534 self.generate_expression(&e.this)?;
34535 Ok(())
34536 }
34537
34538 fn generate_set(&mut self, e: &Set) -> Result<()> {
34539 if e.unset.is_some() {
34541 self.write_keyword("UNSET");
34542 } else {
34543 self.write_keyword("SET");
34544 }
34545 if e.tag.is_some() {
34546 self.write_space();
34547 self.write_keyword("TAG");
34548 }
34549 if !e.expressions.is_empty() {
34550 self.write_space();
34551 for (i, expr) in e.expressions.iter().enumerate() {
34552 if i > 0 {
34553 self.write(", ");
34554 }
34555 self.generate_expression(expr)?;
34556 }
34557 }
34558 Ok(())
34559 }
34560
34561 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
34562 self.write_keyword("SET");
34564 self.write_space();
34565 self.generate_expression(&e.this)?;
34566 Ok(())
34567 }
34568
34569 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
34570 if let Some(kind) = &e.kind {
34572 self.write_keyword(kind);
34573 self.write_space();
34574 }
34575 self.generate_expression(&e.name)?;
34576 self.write(" = ");
34577 self.generate_expression(&e.value)?;
34578 Ok(())
34579 }
34580
34581 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
34582 if let Some(with_) = &e.with_ {
34584 self.generate_expression(with_)?;
34585 self.write_space();
34586 }
34587 self.generate_expression(&e.this)?;
34588 self.write_space();
34589 if let Some(kind) = &e.kind {
34591 self.write_keyword(kind);
34592 }
34593 if e.distinct {
34594 self.write_space();
34595 self.write_keyword("DISTINCT");
34596 } else {
34597 self.write_space();
34598 self.write_keyword("ALL");
34599 }
34600 if e.by_name.is_some() {
34601 self.write_space();
34602 self.write_keyword("BY NAME");
34603 }
34604 self.write_space();
34605 self.generate_expression(&e.expression)?;
34606 Ok(())
34607 }
34608
34609 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
34610 if e.multi.is_some() {
34612 self.write_keyword("MULTISET");
34613 } else {
34614 self.write_keyword("SET");
34615 }
34616 Ok(())
34617 }
34618
34619 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
34620 self.write_keyword("SETTINGS");
34622 if self.config.pretty && e.expressions.len() > 1 {
34623 self.indent_level += 1;
34625 for (i, expr) in e.expressions.iter().enumerate() {
34626 if i > 0 {
34627 self.write(",");
34628 }
34629 self.write_newline();
34630 self.write_indent();
34631 self.generate_expression(expr)?;
34632 }
34633 self.indent_level -= 1;
34634 } else {
34635 self.write_space();
34636 for (i, expr) in e.expressions.iter().enumerate() {
34637 if i > 0 {
34638 self.write(", ");
34639 }
34640 self.generate_expression(expr)?;
34641 }
34642 }
34643 Ok(())
34644 }
34645
34646 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
34647 self.write_keyword("SHARING");
34649 if let Some(this) = &e.this {
34650 self.write(" = ");
34651 self.generate_expression(this)?;
34652 }
34653 Ok(())
34654 }
34655
34656 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
34657 if let Some(begin) = &e.this {
34659 self.generate_expression(begin)?;
34660 }
34661 self.write(":");
34662 if let Some(end) = &e.expression {
34663 self.generate_expression(end)?;
34664 }
34665 if let Some(step) = &e.step {
34666 self.write(":");
34667 self.generate_expression(step)?;
34668 }
34669 Ok(())
34670 }
34671
34672 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
34673 self.write_keyword("SORT_ARRAY");
34675 self.write("(");
34676 self.generate_expression(&e.this)?;
34677 if let Some(asc) = &e.asc {
34678 self.write(", ");
34679 self.generate_expression(asc)?;
34680 }
34681 self.write(")");
34682 Ok(())
34683 }
34684
34685 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
34686 self.write_keyword("SORT BY");
34688 self.write_space();
34689 for (i, expr) in e.expressions.iter().enumerate() {
34690 if i > 0 {
34691 self.write(", ");
34692 }
34693 self.generate_ordered(expr)?;
34694 }
34695 Ok(())
34696 }
34697
34698 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
34699 if e.compound.is_some() {
34701 self.write_keyword("COMPOUND");
34702 self.write_space();
34703 }
34704 self.write_keyword("SORTKEY");
34705 self.write("(");
34706 if let Expression::Tuple(t) = e.this.as_ref() {
34708 for (i, expr) in t.expressions.iter().enumerate() {
34709 if i > 0 {
34710 self.write(", ");
34711 }
34712 self.generate_expression(expr)?;
34713 }
34714 } else {
34715 self.generate_expression(&e.this)?;
34716 }
34717 self.write(")");
34718 Ok(())
34719 }
34720
34721 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
34722 self.write_keyword("SPLIT_PART");
34724 self.write("(");
34725 self.generate_expression(&e.this)?;
34726 if let Some(delimiter) = &e.delimiter {
34727 self.write(", ");
34728 self.generate_expression(delimiter)?;
34729 }
34730 if let Some(part_index) = &e.part_index {
34731 self.write(", ");
34732 self.generate_expression(part_index)?;
34733 }
34734 self.write(")");
34735 Ok(())
34736 }
34737
34738 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
34739 self.generate_expression(&e.this)?;
34741 Ok(())
34742 }
34743
34744 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
34745 self.write_keyword("SQL SECURITY");
34747 self.write_space();
34748 self.generate_expression(&e.this)?;
34749 Ok(())
34750 }
34751
34752 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
34753 self.write_keyword("ST_DISTANCE");
34755 self.write("(");
34756 self.generate_expression(&e.this)?;
34757 self.write(", ");
34758 self.generate_expression(&e.expression)?;
34759 if let Some(use_spheroid) = &e.use_spheroid {
34760 self.write(", ");
34761 self.generate_expression(use_spheroid)?;
34762 }
34763 self.write(")");
34764 Ok(())
34765 }
34766
34767 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
34768 self.write_keyword("ST_POINT");
34770 self.write("(");
34771 self.generate_expression(&e.this)?;
34772 self.write(", ");
34773 self.generate_expression(&e.expression)?;
34774 self.write(")");
34775 Ok(())
34776 }
34777
34778 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
34779 self.generate_expression(&e.this)?;
34781 Ok(())
34782 }
34783
34784 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
34785 self.write_keyword("STANDARD_HASH");
34787 self.write("(");
34788 self.generate_expression(&e.this)?;
34789 if let Some(expression) = &e.expression {
34790 self.write(", ");
34791 self.generate_expression(expression)?;
34792 }
34793 self.write(")");
34794 Ok(())
34795 }
34796
34797 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
34798 self.write_keyword("STORED BY");
34800 self.write_space();
34801 self.generate_expression(&e.this)?;
34802 Ok(())
34803 }
34804
34805 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
34806 use crate::dialects::DialectType;
34809 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
34810 self.write_keyword("CHARINDEX");
34812 self.write("(");
34813 if let Some(substr) = &e.substr {
34814 self.generate_expression(substr)?;
34815 self.write(", ");
34816 }
34817 self.generate_expression(&e.this)?;
34818 if let Some(position) = &e.position {
34819 self.write(", ");
34820 self.generate_expression(position)?;
34821 }
34822 self.write(")");
34823 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34824 self.write_keyword("POSITION");
34825 self.write("(");
34826 self.generate_expression(&e.this)?;
34827 if let Some(substr) = &e.substr {
34828 self.write(", ");
34829 self.generate_expression(substr)?;
34830 }
34831 if let Some(position) = &e.position {
34832 self.write(", ");
34833 self.generate_expression(position)?;
34834 }
34835 if let Some(occurrence) = &e.occurrence {
34836 self.write(", ");
34837 self.generate_expression(occurrence)?;
34838 }
34839 self.write(")");
34840 } else if matches!(
34841 self.config.dialect,
34842 Some(DialectType::SQLite)
34843 | Some(DialectType::Oracle)
34844 | Some(DialectType::BigQuery)
34845 | Some(DialectType::Teradata)
34846 ) {
34847 self.write_keyword("INSTR");
34848 self.write("(");
34849 self.generate_expression(&e.this)?;
34850 if let Some(substr) = &e.substr {
34851 self.write(", ");
34852 self.generate_expression(substr)?;
34853 }
34854 if let Some(position) = &e.position {
34855 self.write(", ");
34856 self.generate_expression(position)?;
34857 } else if e.occurrence.is_some() {
34858 self.write(", 1");
34861 }
34862 if let Some(occurrence) = &e.occurrence {
34863 self.write(", ");
34864 self.generate_expression(occurrence)?;
34865 }
34866 self.write(")");
34867 } else if matches!(
34868 self.config.dialect,
34869 Some(DialectType::MySQL)
34870 | Some(DialectType::SingleStore)
34871 | Some(DialectType::Doris)
34872 | Some(DialectType::StarRocks)
34873 | Some(DialectType::Hive)
34874 | Some(DialectType::Spark)
34875 | Some(DialectType::Databricks)
34876 ) {
34877 self.write_keyword("LOCATE");
34879 self.write("(");
34880 if let Some(substr) = &e.substr {
34881 self.generate_expression(substr)?;
34882 self.write(", ");
34883 }
34884 self.generate_expression(&e.this)?;
34885 if let Some(position) = &e.position {
34886 self.write(", ");
34887 self.generate_expression(position)?;
34888 }
34889 self.write(")");
34890 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
34891 self.write_keyword("CHARINDEX");
34893 self.write("(");
34894 if let Some(substr) = &e.substr {
34895 self.generate_expression(substr)?;
34896 self.write(", ");
34897 }
34898 self.generate_expression(&e.this)?;
34899 if let Some(position) = &e.position {
34900 self.write(", ");
34901 self.generate_expression(position)?;
34902 }
34903 self.write(")");
34904 } else if matches!(
34905 self.config.dialect,
34906 Some(DialectType::PostgreSQL)
34907 | Some(DialectType::Materialize)
34908 | Some(DialectType::RisingWave)
34909 | Some(DialectType::Redshift)
34910 ) {
34911 self.write_keyword("POSITION");
34913 self.write("(");
34914 if let Some(substr) = &e.substr {
34915 self.generate_expression(substr)?;
34916 self.write(" IN ");
34917 }
34918 self.generate_expression(&e.this)?;
34919 self.write(")");
34920 } else {
34921 self.write_keyword("STRPOS");
34922 self.write("(");
34923 self.generate_expression(&e.this)?;
34924 if let Some(substr) = &e.substr {
34925 self.write(", ");
34926 self.generate_expression(substr)?;
34927 }
34928 if let Some(position) = &e.position {
34929 self.write(", ");
34930 self.generate_expression(position)?;
34931 }
34932 if let Some(occurrence) = &e.occurrence {
34933 self.write(", ");
34934 self.generate_expression(occurrence)?;
34935 }
34936 self.write(")");
34937 }
34938 Ok(())
34939 }
34940
34941 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
34942 match self.config.dialect {
34943 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
34944 self.write_keyword("TO_DATE");
34946 self.write("(");
34947 self.generate_expression(&e.this)?;
34948 if let Some(format) = &e.format {
34949 self.write(", '");
34950 self.write(&Self::strftime_to_java_format(format));
34951 self.write("'");
34952 }
34953 self.write(")");
34954 }
34955 Some(DialectType::DuckDB) => {
34956 self.write_keyword("CAST");
34958 self.write("(");
34959 self.write_keyword("STRPTIME");
34960 self.write("(");
34961 self.generate_expression(&e.this)?;
34962 if let Some(format) = &e.format {
34963 self.write(", '");
34964 self.write(format);
34965 self.write("'");
34966 }
34967 self.write(")");
34968 self.write_keyword(" AS ");
34969 self.write_keyword("DATE");
34970 self.write(")");
34971 }
34972 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
34973 self.write_keyword("TO_DATE");
34975 self.write("(");
34976 self.generate_expression(&e.this)?;
34977 if let Some(format) = &e.format {
34978 self.write(", '");
34979 self.write(&Self::strftime_to_postgres_format(format));
34980 self.write("'");
34981 }
34982 self.write(")");
34983 }
34984 Some(DialectType::BigQuery) => {
34985 self.write_keyword("PARSE_DATE");
34987 self.write("(");
34988 if let Some(format) = &e.format {
34989 self.write("'");
34990 self.write(format);
34991 self.write("'");
34992 self.write(", ");
34993 }
34994 self.generate_expression(&e.this)?;
34995 self.write(")");
34996 }
34997 Some(DialectType::Teradata) => {
34998 self.write_keyword("CAST");
35000 self.write("(");
35001 self.generate_expression(&e.this)?;
35002 self.write_keyword(" AS ");
35003 self.write_keyword("DATE");
35004 if let Some(format) = &e.format {
35005 self.write_keyword(" FORMAT ");
35006 self.write("'");
35007 self.write(&Self::strftime_to_teradata_format(format));
35008 self.write("'");
35009 }
35010 self.write(")");
35011 }
35012 _ => {
35013 self.write_keyword("STR_TO_DATE");
35015 self.write("(");
35016 self.generate_expression(&e.this)?;
35017 if let Some(format) = &e.format {
35018 self.write(", '");
35019 self.write(format);
35020 self.write("'");
35021 }
35022 self.write(")");
35023 }
35024 }
35025 Ok(())
35026 }
35027
35028 fn strftime_to_teradata_format(fmt: &str) -> String {
35030 let mut result = String::with_capacity(fmt.len() * 2);
35031 let bytes = fmt.as_bytes();
35032 let len = bytes.len();
35033 let mut i = 0;
35034 while i < len {
35035 if bytes[i] == b'%' && i + 1 < len {
35036 let replacement = match bytes[i + 1] {
35037 b'Y' => "YYYY",
35038 b'y' => "YY",
35039 b'm' => "MM",
35040 b'B' => "MMMM",
35041 b'b' => "MMM",
35042 b'd' => "DD",
35043 b'j' => "DDD",
35044 b'H' => "HH",
35045 b'M' => "MI",
35046 b'S' => "SS",
35047 b'f' => "SSSSSS",
35048 b'A' => "EEEE",
35049 b'a' => "EEE",
35050 _ => {
35051 result.push('%');
35052 i += 1;
35053 continue;
35054 }
35055 };
35056 result.push_str(replacement);
35057 i += 2;
35058 } else {
35059 result.push(bytes[i] as char);
35060 i += 1;
35061 }
35062 }
35063 result
35064 }
35065
35066 pub fn strftime_to_java_format_static(fmt: &str) -> String {
35069 Self::strftime_to_java_format(fmt)
35070 }
35071
35072 fn strftime_to_java_format(fmt: &str) -> String {
35074 let mut result = String::with_capacity(fmt.len() * 2);
35075 let bytes = fmt.as_bytes();
35076 let len = bytes.len();
35077 let mut i = 0;
35078 while i < len {
35079 if bytes[i] == b'%' && i + 1 < len {
35080 if bytes[i + 1] == b'-' && i + 2 < len {
35082 let replacement = match bytes[i + 2] {
35083 b'd' => "d",
35084 b'm' => "M",
35085 b'H' => "H",
35086 b'M' => "m",
35087 b'S' => "s",
35088 _ => {
35089 result.push('%');
35090 i += 1;
35091 continue;
35092 }
35093 };
35094 result.push_str(replacement);
35095 i += 3;
35096 } else {
35097 let replacement = match bytes[i + 1] {
35098 b'Y' => "yyyy",
35099 b'y' => "yy",
35100 b'm' => "MM",
35101 b'B' => "MMMM",
35102 b'b' => "MMM",
35103 b'd' => "dd",
35104 b'j' => "DDD",
35105 b'H' => "HH",
35106 b'M' => "mm",
35107 b'S' => "ss",
35108 b'f' => "SSSSSS",
35109 b'A' => "EEEE",
35110 b'a' => "EEE",
35111 _ => {
35112 result.push('%');
35113 i += 1;
35114 continue;
35115 }
35116 };
35117 result.push_str(replacement);
35118 i += 2;
35119 }
35120 } else {
35121 result.push(bytes[i] as char);
35122 i += 1;
35123 }
35124 }
35125 result
35126 }
35127
35128 fn strftime_to_tsql_format(fmt: &str) -> String {
35131 let mut result = String::with_capacity(fmt.len() * 2);
35132 let bytes = fmt.as_bytes();
35133 let len = bytes.len();
35134 let mut i = 0;
35135 while i < len {
35136 if bytes[i] == b'%' && i + 1 < len {
35137 if bytes[i + 1] == b'-' && i + 2 < len {
35139 let replacement = match bytes[i + 2] {
35140 b'd' => "d",
35141 b'm' => "M",
35142 b'H' => "H",
35143 b'M' => "m",
35144 b'S' => "s",
35145 _ => {
35146 result.push('%');
35147 i += 1;
35148 continue;
35149 }
35150 };
35151 result.push_str(replacement);
35152 i += 3;
35153 } else {
35154 let replacement = match bytes[i + 1] {
35155 b'Y' => "yyyy",
35156 b'y' => "yy",
35157 b'm' => "MM",
35158 b'B' => "MMMM",
35159 b'b' => "MMM",
35160 b'd' => "dd",
35161 b'j' => "DDD",
35162 b'H' => "HH",
35163 b'M' => "mm",
35164 b'S' => "ss",
35165 b'f' => "ffffff",
35166 b'A' => "dddd",
35167 b'a' => "ddd",
35168 _ => {
35169 result.push('%');
35170 i += 1;
35171 continue;
35172 }
35173 };
35174 result.push_str(replacement);
35175 i += 2;
35176 }
35177 } else {
35178 result.push(bytes[i] as char);
35179 i += 1;
35180 }
35181 }
35182 result
35183 }
35184
35185 fn decompose_json_path(path: &str) -> Vec<String> {
35188 let mut parts = Vec::new();
35189 let path = if path.starts_with("$.") {
35191 &path[2..]
35192 } else if path.starts_with('$') {
35193 &path[1..]
35194 } else {
35195 path
35196 };
35197 if path.is_empty() {
35198 return parts;
35199 }
35200 let mut current = String::new();
35201 let chars: Vec<char> = path.chars().collect();
35202 let mut i = 0;
35203 while i < chars.len() {
35204 match chars[i] {
35205 '.' => {
35206 if !current.is_empty() {
35207 parts.push(current.clone());
35208 current.clear();
35209 }
35210 i += 1;
35211 }
35212 '[' => {
35213 if !current.is_empty() {
35214 parts.push(current.clone());
35215 current.clear();
35216 }
35217 i += 1;
35218 let mut bracket_content = String::new();
35220 while i < chars.len() && chars[i] != ']' {
35221 if chars[i] == '"' || chars[i] == '\'' {
35223 let quote = chars[i];
35224 i += 1;
35225 while i < chars.len() && chars[i] != quote {
35226 bracket_content.push(chars[i]);
35227 i += 1;
35228 }
35229 if i < chars.len() {
35230 i += 1;
35231 } } else {
35233 bracket_content.push(chars[i]);
35234 i += 1;
35235 }
35236 }
35237 if i < chars.len() {
35238 i += 1;
35239 } if bracket_content != "*" {
35242 parts.push(bracket_content);
35243 }
35244 }
35245 _ => {
35246 current.push(chars[i]);
35247 i += 1;
35248 }
35249 }
35250 }
35251 if !current.is_empty() {
35252 parts.push(current);
35253 }
35254 parts
35255 }
35256
35257 fn strftime_to_postgres_format(fmt: &str) -> String {
35259 let mut result = String::with_capacity(fmt.len() * 2);
35260 let bytes = fmt.as_bytes();
35261 let len = bytes.len();
35262 let mut i = 0;
35263 while i < len {
35264 if bytes[i] == b'%' && i + 1 < len {
35265 if bytes[i + 1] == b'-' && i + 2 < len {
35267 let replacement = match bytes[i + 2] {
35268 b'd' => "FMDD",
35269 b'm' => "FMMM",
35270 b'H' => "FMHH24",
35271 b'M' => "FMMI",
35272 b'S' => "FMSS",
35273 _ => {
35274 result.push('%');
35275 i += 1;
35276 continue;
35277 }
35278 };
35279 result.push_str(replacement);
35280 i += 3;
35281 } else {
35282 let replacement = match bytes[i + 1] {
35283 b'Y' => "YYYY",
35284 b'y' => "YY",
35285 b'm' => "MM",
35286 b'B' => "Month",
35287 b'b' => "Mon",
35288 b'd' => "DD",
35289 b'j' => "DDD",
35290 b'H' => "HH24",
35291 b'M' => "MI",
35292 b'S' => "SS",
35293 b'f' => "US",
35294 b'A' => "Day",
35295 b'a' => "Dy",
35296 _ => {
35297 result.push('%');
35298 i += 1;
35299 continue;
35300 }
35301 };
35302 result.push_str(replacement);
35303 i += 2;
35304 }
35305 } else {
35306 result.push(bytes[i] as char);
35307 i += 1;
35308 }
35309 }
35310 result
35311 }
35312
35313 fn strftime_to_snowflake_format(fmt: &str) -> String {
35315 let mut result = String::with_capacity(fmt.len() * 2);
35316 let bytes = fmt.as_bytes();
35317 let len = bytes.len();
35318 let mut i = 0;
35319 while i < len {
35320 if bytes[i] == b'%' && i + 1 < len {
35321 if bytes[i + 1] == b'-' && i + 2 < len {
35323 let replacement = match bytes[i + 2] {
35324 b'd' => "dd",
35325 b'm' => "mm",
35326 _ => {
35327 result.push('%');
35328 i += 1;
35329 continue;
35330 }
35331 };
35332 result.push_str(replacement);
35333 i += 3;
35334 } else {
35335 let replacement = match bytes[i + 1] {
35336 b'Y' => "yyyy",
35337 b'y' => "yy",
35338 b'm' => "mm",
35339 b'd' => "DD",
35340 b'H' => "hh24",
35341 b'M' => "mi",
35342 b'S' => "ss",
35343 b'f' => "ff",
35344 _ => {
35345 result.push('%');
35346 i += 1;
35347 continue;
35348 }
35349 };
35350 result.push_str(replacement);
35351 i += 2;
35352 }
35353 } else {
35354 result.push(bytes[i] as char);
35355 i += 1;
35356 }
35357 }
35358 result
35359 }
35360
35361 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
35362 self.write_keyword("STR_TO_MAP");
35364 self.write("(");
35365 self.generate_expression(&e.this)?;
35366 let needs_defaults = matches!(
35368 self.config.dialect,
35369 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
35370 );
35371 if let Some(pair_delim) = &e.pair_delim {
35372 self.write(", ");
35373 self.generate_expression(pair_delim)?;
35374 } else if needs_defaults {
35375 self.write(", ','");
35376 }
35377 if let Some(key_value_delim) = &e.key_value_delim {
35378 self.write(", ");
35379 self.generate_expression(key_value_delim)?;
35380 } else if needs_defaults {
35381 self.write(", ':'");
35382 }
35383 self.write(")");
35384 Ok(())
35385 }
35386
35387 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
35388 let is_strftime = e.format.contains('%');
35390 let to_strftime = |f: &str| -> String {
35392 if is_strftime {
35393 f.to_string()
35394 } else {
35395 Self::snowflake_format_to_strftime(f)
35396 }
35397 };
35398 let to_java = |f: &str| -> String {
35400 if is_strftime {
35401 Self::strftime_to_java_format(f)
35402 } else {
35403 Self::snowflake_format_to_spark(f)
35404 }
35405 };
35406 let to_pg = |f: &str| -> String {
35408 if is_strftime {
35409 Self::strftime_to_postgres_format(f)
35410 } else {
35411 Self::convert_strptime_to_postgres_format(f)
35412 }
35413 };
35414
35415 match self.config.dialect {
35416 Some(DialectType::Exasol) => {
35417 self.write_keyword("TO_DATE");
35418 self.write("(");
35419 self.generate_expression(&e.this)?;
35420 self.write(", '");
35421 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
35422 self.write("'");
35423 self.write(")");
35424 }
35425 Some(DialectType::BigQuery) => {
35426 let fmt = to_strftime(&e.format);
35428 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
35430 self.write_keyword("PARSE_TIMESTAMP");
35431 self.write("('");
35432 self.write(&fmt);
35433 self.write("', ");
35434 self.generate_expression(&e.this)?;
35435 self.write(")");
35436 }
35437 Some(DialectType::Hive) => {
35438 let java_fmt = to_java(&e.format);
35441 if java_fmt == "yyyy-MM-dd HH:mm:ss"
35442 || java_fmt == "yyyy-MM-dd"
35443 || e.format == "yyyy-MM-dd HH:mm:ss"
35444 || e.format == "yyyy-MM-dd"
35445 {
35446 self.write_keyword("CAST");
35447 self.write("(");
35448 self.generate_expression(&e.this)?;
35449 self.write(" ");
35450 self.write_keyword("AS TIMESTAMP");
35451 self.write(")");
35452 } else {
35453 self.write_keyword("CAST");
35455 self.write("(");
35456 self.write_keyword("FROM_UNIXTIME");
35457 self.write("(");
35458 self.write_keyword("UNIX_TIMESTAMP");
35459 self.write("(");
35460 self.generate_expression(&e.this)?;
35461 self.write(", '");
35462 self.write(&java_fmt);
35463 self.write("')");
35464 self.write(") ");
35465 self.write_keyword("AS TIMESTAMP");
35466 self.write(")");
35467 }
35468 }
35469 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35470 let java_fmt = to_java(&e.format);
35472 self.write_keyword("TO_TIMESTAMP");
35473 self.write("(");
35474 self.generate_expression(&e.this)?;
35475 self.write(", '");
35476 self.write(&java_fmt);
35477 self.write("')");
35478 }
35479 Some(DialectType::MySQL) => {
35480 let mut fmt = to_strftime(&e.format);
35482 fmt = fmt.replace("%-d", "%e");
35484 fmt = fmt.replace("%-m", "%c");
35485 fmt = fmt.replace("%H:%M:%S", "%T");
35486 self.write_keyword("STR_TO_DATE");
35487 self.write("(");
35488 self.generate_expression(&e.this)?;
35489 self.write(", '");
35490 self.write(&fmt);
35491 self.write("')");
35492 }
35493 Some(DialectType::Drill) => {
35494 let java_fmt = to_java(&e.format);
35496 let java_fmt = java_fmt.replace('T', "''T''");
35498 self.write_keyword("TO_TIMESTAMP");
35499 self.write("(");
35500 self.generate_expression(&e.this)?;
35501 self.write(", '");
35502 self.write(&java_fmt);
35503 self.write("')");
35504 }
35505 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
35506 let mut fmt = to_strftime(&e.format);
35508 fmt = fmt.replace("%-d", "%e");
35510 fmt = fmt.replace("%-m", "%c");
35511 fmt = fmt.replace("%H:%M:%S", "%T");
35512 self.write_keyword("DATE_PARSE");
35513 self.write("(");
35514 self.generate_expression(&e.this)?;
35515 self.write(", '");
35516 self.write(&fmt);
35517 self.write("')");
35518 }
35519 Some(DialectType::DuckDB) => {
35520 let fmt = to_strftime(&e.format);
35522 self.write_keyword("STRPTIME");
35523 self.write("(");
35524 self.generate_expression(&e.this)?;
35525 self.write(", '");
35526 self.write(&fmt);
35527 self.write("')");
35528 }
35529 Some(DialectType::PostgreSQL)
35530 | Some(DialectType::Redshift)
35531 | Some(DialectType::Materialize) => {
35532 let pg_fmt = to_pg(&e.format);
35534 self.write_keyword("TO_TIMESTAMP");
35535 self.write("(");
35536 self.generate_expression(&e.this)?;
35537 self.write(", '");
35538 self.write(&pg_fmt);
35539 self.write("')");
35540 }
35541 Some(DialectType::Oracle) => {
35542 let pg_fmt = to_pg(&e.format);
35544 self.write_keyword("TO_TIMESTAMP");
35545 self.write("(");
35546 self.generate_expression(&e.this)?;
35547 self.write(", '");
35548 self.write(&pg_fmt);
35549 self.write("')");
35550 }
35551 Some(DialectType::Snowflake) => {
35552 self.write_keyword("TO_TIMESTAMP");
35554 self.write("(");
35555 self.generate_expression(&e.this)?;
35556 self.write(", '");
35557 self.write(&e.format);
35558 self.write("')");
35559 }
35560 _ => {
35561 self.write_keyword("STR_TO_TIME");
35563 self.write("(");
35564 self.generate_expression(&e.this)?;
35565 self.write(", '");
35566 self.write(&e.format);
35567 self.write("'");
35568 self.write(")");
35569 }
35570 }
35571 Ok(())
35572 }
35573
35574 fn snowflake_format_to_strftime(format: &str) -> String {
35576 let mut result = String::new();
35577 let chars: Vec<char> = format.chars().collect();
35578 let mut i = 0;
35579 while i < chars.len() {
35580 let remaining = &format[i..];
35581 if remaining.starts_with("yyyy") {
35582 result.push_str("%Y");
35583 i += 4;
35584 } else if remaining.starts_with("yy") {
35585 result.push_str("%y");
35586 i += 2;
35587 } else if remaining.starts_with("mmmm") {
35588 result.push_str("%B"); i += 4;
35590 } else if remaining.starts_with("mon") {
35591 result.push_str("%b"); i += 3;
35593 } else if remaining.starts_with("mm") {
35594 result.push_str("%m");
35595 i += 2;
35596 } else if remaining.starts_with("DD") {
35597 result.push_str("%d");
35598 i += 2;
35599 } else if remaining.starts_with("dy") {
35600 result.push_str("%a"); i += 2;
35602 } else if remaining.starts_with("hh24") {
35603 result.push_str("%H");
35604 i += 4;
35605 } else if remaining.starts_with("hh12") {
35606 result.push_str("%I");
35607 i += 4;
35608 } else if remaining.starts_with("hh") {
35609 result.push_str("%H");
35610 i += 2;
35611 } else if remaining.starts_with("mi") {
35612 result.push_str("%M");
35613 i += 2;
35614 } else if remaining.starts_with("ss") {
35615 result.push_str("%S");
35616 i += 2;
35617 } else if remaining.starts_with("ff") {
35618 result.push_str("%f");
35620 i += 2;
35621 while i < chars.len() && chars[i].is_ascii_digit() {
35623 i += 1;
35624 }
35625 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
35626 result.push_str("%p");
35627 i += 2;
35628 } else if remaining.starts_with("tz") {
35629 result.push_str("%Z");
35630 i += 2;
35631 } else {
35632 result.push(chars[i]);
35633 i += 1;
35634 }
35635 }
35636 result
35637 }
35638
35639 fn snowflake_format_to_spark(format: &str) -> String {
35641 let mut result = String::new();
35642 let chars: Vec<char> = format.chars().collect();
35643 let mut i = 0;
35644 while i < chars.len() {
35645 let remaining = &format[i..];
35646 if remaining.starts_with("yyyy") {
35647 result.push_str("yyyy");
35648 i += 4;
35649 } else if remaining.starts_with("yy") {
35650 result.push_str("yy");
35651 i += 2;
35652 } else if remaining.starts_with("mmmm") {
35653 result.push_str("MMMM"); i += 4;
35655 } else if remaining.starts_with("mon") {
35656 result.push_str("MMM"); i += 3;
35658 } else if remaining.starts_with("mm") {
35659 result.push_str("MM");
35660 i += 2;
35661 } else if remaining.starts_with("DD") {
35662 result.push_str("dd");
35663 i += 2;
35664 } else if remaining.starts_with("dy") {
35665 result.push_str("EEE"); i += 2;
35667 } else if remaining.starts_with("hh24") {
35668 result.push_str("HH");
35669 i += 4;
35670 } else if remaining.starts_with("hh12") {
35671 result.push_str("hh");
35672 i += 4;
35673 } else if remaining.starts_with("hh") {
35674 result.push_str("HH");
35675 i += 2;
35676 } else if remaining.starts_with("mi") {
35677 result.push_str("mm");
35678 i += 2;
35679 } else if remaining.starts_with("ss") {
35680 result.push_str("ss");
35681 i += 2;
35682 } else if remaining.starts_with("ff") {
35683 result.push_str("SSS"); i += 2;
35685 while i < chars.len() && chars[i].is_ascii_digit() {
35687 i += 1;
35688 }
35689 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
35690 result.push_str("a");
35691 i += 2;
35692 } else if remaining.starts_with("tz") {
35693 result.push_str("z");
35694 i += 2;
35695 } else {
35696 result.push(chars[i]);
35697 i += 1;
35698 }
35699 }
35700 result
35701 }
35702
35703 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
35704 match self.config.dialect {
35705 Some(DialectType::DuckDB) => {
35706 self.write_keyword("EPOCH");
35708 self.write("(");
35709 self.write_keyword("STRPTIME");
35710 self.write("(");
35711 if let Some(this) = &e.this {
35712 self.generate_expression(this)?;
35713 }
35714 if let Some(format) = &e.format {
35715 self.write(", '");
35716 self.write(format);
35717 self.write("'");
35718 }
35719 self.write("))");
35720 }
35721 Some(DialectType::Hive) => {
35722 self.write_keyword("UNIX_TIMESTAMP");
35724 self.write("(");
35725 if let Some(this) = &e.this {
35726 self.generate_expression(this)?;
35727 }
35728 if let Some(format) = &e.format {
35729 let java_fmt = Self::strftime_to_java_format(format);
35730 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
35731 self.write(", '");
35732 self.write(&java_fmt);
35733 self.write("'");
35734 }
35735 }
35736 self.write(")");
35737 }
35738 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35739 self.write_keyword("UNIX_TIMESTAMP");
35741 self.write("(");
35742 if let Some(this) = &e.this {
35743 self.generate_expression(this)?;
35744 }
35745 if let Some(format) = &e.format {
35746 self.write(", '");
35747 self.write(format);
35748 self.write("'");
35749 }
35750 self.write(")");
35751 }
35752 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35753 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
35756 let java_fmt = Self::strftime_to_java_format(c_fmt);
35757 self.write_keyword("TO_UNIXTIME");
35758 self.write("(");
35759 self.write_keyword("COALESCE");
35760 self.write("(");
35761 self.write_keyword("TRY");
35762 self.write("(");
35763 self.write_keyword("DATE_PARSE");
35764 self.write("(");
35765 self.write_keyword("CAST");
35766 self.write("(");
35767 if let Some(this) = &e.this {
35768 self.generate_expression(this)?;
35769 }
35770 self.write(" ");
35771 self.write_keyword("AS VARCHAR");
35772 self.write("), '");
35773 self.write(c_fmt);
35774 self.write("')), ");
35775 self.write_keyword("PARSE_DATETIME");
35776 self.write("(");
35777 self.write_keyword("DATE_FORMAT");
35778 self.write("(");
35779 self.write_keyword("CAST");
35780 self.write("(");
35781 if let Some(this) = &e.this {
35782 self.generate_expression(this)?;
35783 }
35784 self.write(" ");
35785 self.write_keyword("AS TIMESTAMP");
35786 self.write("), '");
35787 self.write(c_fmt);
35788 self.write("'), '");
35789 self.write(&java_fmt);
35790 self.write("')))");
35791 }
35792 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35793 self.write_keyword("UNIX_TIMESTAMP");
35795 self.write("(");
35796 if let Some(this) = &e.this {
35797 self.generate_expression(this)?;
35798 }
35799 if let Some(format) = &e.format {
35800 let java_fmt = Self::strftime_to_java_format(format);
35801 self.write(", '");
35802 self.write(&java_fmt);
35803 self.write("'");
35804 }
35805 self.write(")");
35806 }
35807 _ => {
35808 self.write_keyword("STR_TO_UNIX");
35810 self.write("(");
35811 if let Some(this) = &e.this {
35812 self.generate_expression(this)?;
35813 }
35814 if let Some(format) = &e.format {
35815 self.write(", '");
35816 self.write(format);
35817 self.write("'");
35818 }
35819 self.write(")");
35820 }
35821 }
35822 Ok(())
35823 }
35824
35825 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
35826 self.write_keyword("STRING_TO_ARRAY");
35828 self.write("(");
35829 self.generate_expression(&e.this)?;
35830 if let Some(expression) = &e.expression {
35831 self.write(", ");
35832 self.generate_expression(expression)?;
35833 }
35834 if let Some(null_val) = &e.null {
35835 self.write(", ");
35836 self.generate_expression(null_val)?;
35837 }
35838 self.write(")");
35839 Ok(())
35840 }
35841
35842 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
35843 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35844 self.write_keyword("OBJECT_CONSTRUCT");
35846 self.write("(");
35847 for (i, (name, expr)) in e.fields.iter().enumerate() {
35848 if i > 0 {
35849 self.write(", ");
35850 }
35851 if let Some(name) = name {
35852 self.write("'");
35853 self.write(name);
35854 self.write("'");
35855 self.write(", ");
35856 } else {
35857 self.write("'_");
35858 self.write(&i.to_string());
35859 self.write("'");
35860 self.write(", ");
35861 }
35862 self.generate_expression(expr)?;
35863 }
35864 self.write(")");
35865 } else if self.config.struct_curly_brace_notation {
35866 self.write("{");
35868 for (i, (name, expr)) in e.fields.iter().enumerate() {
35869 if i > 0 {
35870 self.write(", ");
35871 }
35872 if let Some(name) = name {
35873 self.write("'");
35875 self.write(name);
35876 self.write("'");
35877 self.write(": ");
35878 } else {
35879 self.write("'_");
35881 self.write(&i.to_string());
35882 self.write("'");
35883 self.write(": ");
35884 }
35885 self.generate_expression(expr)?;
35886 }
35887 self.write("}");
35888 } else {
35889 let value_as_name = matches!(
35893 self.config.dialect,
35894 Some(DialectType::BigQuery)
35895 | Some(DialectType::Spark)
35896 | Some(DialectType::Databricks)
35897 | Some(DialectType::Hive)
35898 );
35899 self.write_keyword("STRUCT");
35900 self.write("(");
35901 for (i, (name, expr)) in e.fields.iter().enumerate() {
35902 if i > 0 {
35903 self.write(", ");
35904 }
35905 if let Some(name) = name {
35906 if value_as_name {
35907 self.generate_expression(expr)?;
35909 self.write_space();
35910 self.write_keyword("AS");
35911 self.write_space();
35912 let needs_quoting = name.contains(' ') || name.contains('-');
35914 if needs_quoting {
35915 if matches!(
35916 self.config.dialect,
35917 Some(DialectType::Spark)
35918 | Some(DialectType::Databricks)
35919 | Some(DialectType::Hive)
35920 ) {
35921 self.write("`");
35922 self.write(name);
35923 self.write("`");
35924 } else {
35925 self.write(name);
35926 }
35927 } else {
35928 self.write(name);
35929 }
35930 } else {
35931 self.write(name);
35933 self.write_space();
35934 self.write_keyword("AS");
35935 self.write_space();
35936 self.generate_expression(expr)?;
35937 }
35938 } else {
35939 self.generate_expression(expr)?;
35940 }
35941 }
35942 self.write(")");
35943 }
35944 Ok(())
35945 }
35946
35947 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
35948 self.write_keyword("STUFF");
35950 self.write("(");
35951 self.generate_expression(&e.this)?;
35952 if let Some(start) = &e.start {
35953 self.write(", ");
35954 self.generate_expression(start)?;
35955 }
35956 if let Some(length) = e.length {
35957 self.write(", ");
35958 self.write(&length.to_string());
35959 }
35960 self.write(", ");
35961 self.generate_expression(&e.expression)?;
35962 self.write(")");
35963 Ok(())
35964 }
35965
35966 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
35967 self.write_keyword("SUBSTRING_INDEX");
35969 self.write("(");
35970 self.generate_expression(&e.this)?;
35971 if let Some(delimiter) = &e.delimiter {
35972 self.write(", ");
35973 self.generate_expression(delimiter)?;
35974 }
35975 if let Some(count) = &e.count {
35976 self.write(", ");
35977 self.generate_expression(count)?;
35978 }
35979 self.write(")");
35980 Ok(())
35981 }
35982
35983 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
35984 self.write_keyword("SUMMARIZE");
35986 if e.table.is_some() {
35987 self.write_space();
35988 self.write_keyword("TABLE");
35989 }
35990 self.write_space();
35991 self.generate_expression(&e.this)?;
35992 Ok(())
35993 }
35994
35995 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
35996 self.write_keyword("SYSTIMESTAMP");
35998 Ok(())
35999 }
36000
36001 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
36002 if let Some(this) = &e.this {
36004 self.generate_expression(this)?;
36005 }
36006 if !e.columns.is_empty() {
36007 self.write("(");
36008 for (i, col) in e.columns.iter().enumerate() {
36009 if i > 0 {
36010 self.write(", ");
36011 }
36012 self.generate_expression(col)?;
36013 }
36014 self.write(")");
36015 }
36016 Ok(())
36017 }
36018
36019 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
36020 self.write_keyword("TABLE");
36022 self.write("(");
36023 self.generate_expression(&e.this)?;
36024 self.write(")");
36025 if let Some(alias) = &e.alias {
36026 self.write_space();
36027 self.write_keyword("AS");
36028 self.write_space();
36029 self.write(alias);
36030 }
36031 Ok(())
36032 }
36033
36034 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
36035 self.write_keyword("ROWS FROM");
36037 self.write(" (");
36038 for (i, expr) in e.expressions.iter().enumerate() {
36039 if i > 0 {
36040 self.write(", ");
36041 }
36042 match expr {
36046 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
36047 self.generate_expression(&tuple.expressions[0])?;
36049 self.write_space();
36050 self.write_keyword("AS");
36051 self.write_space();
36052 self.generate_expression(&tuple.expressions[1])?;
36053 }
36054 _ => {
36055 self.generate_expression(expr)?;
36056 }
36057 }
36058 }
36059 self.write(")");
36060 if e.ordinality {
36061 self.write_space();
36062 self.write_keyword("WITH ORDINALITY");
36063 }
36064 if let Some(alias) = &e.alias {
36065 self.write_space();
36066 self.write_keyword("AS");
36067 self.write_space();
36068 self.generate_expression(alias)?;
36069 }
36070 Ok(())
36071 }
36072
36073 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
36074 use crate::dialects::DialectType;
36075
36076 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
36078 if self.config.alias_post_tablesample {
36080 if let Expression::Subquery(ref s) = **this {
36082 if let Some(ref alias) = s.alias {
36083 let mut subquery_no_alias = (**s).clone();
36085 subquery_no_alias.alias = None;
36086 subquery_no_alias.column_aliases = Vec::new();
36087 self.generate_expression(&Expression::Subquery(Box::new(
36088 subquery_no_alias,
36089 )))?;
36090 self.write_space();
36091 self.write_keyword(self.config.tablesample_keywords);
36092 self.generate_sample_body(sample)?;
36093 if let Some(ref seed) = sample.seed {
36094 self.write_space();
36095 let use_seed = sample.use_seed_keyword
36096 && !matches!(
36097 self.config.dialect,
36098 Some(crate::dialects::DialectType::Databricks)
36099 | Some(crate::dialects::DialectType::Spark)
36100 );
36101 if use_seed {
36102 self.write_keyword("SEED");
36103 } else {
36104 self.write_keyword("REPEATABLE");
36105 }
36106 self.write(" (");
36107 self.generate_expression(seed)?;
36108 self.write(")");
36109 }
36110 self.write_space();
36111 self.write_keyword("AS");
36112 self.write_space();
36113 self.generate_identifier(alias)?;
36114 return Ok(());
36115 }
36116 } else if let Expression::Alias(ref a) = **this {
36117 self.generate_expression(&a.this)?;
36119 self.write_space();
36120 self.write_keyword(self.config.tablesample_keywords);
36121 self.generate_sample_body(sample)?;
36122 if let Some(ref seed) = sample.seed {
36123 self.write_space();
36124 let use_seed = sample.use_seed_keyword
36125 && !matches!(
36126 self.config.dialect,
36127 Some(crate::dialects::DialectType::Databricks)
36128 | Some(crate::dialects::DialectType::Spark)
36129 );
36130 if use_seed {
36131 self.write_keyword("SEED");
36132 } else {
36133 self.write_keyword("REPEATABLE");
36134 }
36135 self.write(" (");
36136 self.generate_expression(seed)?;
36137 self.write(")");
36138 }
36139 self.write_space();
36141 self.write_keyword("AS");
36142 self.write_space();
36143 self.generate_identifier(&a.alias)?;
36144 return Ok(());
36145 }
36146 }
36147 self.generate_expression(this)?;
36149 self.write_space();
36150 self.write_keyword(self.config.tablesample_keywords);
36151 self.generate_sample_body(sample)?;
36152 if let Some(ref seed) = sample.seed {
36154 self.write_space();
36155 let use_seed = sample.use_seed_keyword
36157 && !matches!(
36158 self.config.dialect,
36159 Some(crate::dialects::DialectType::Databricks)
36160 | Some(crate::dialects::DialectType::Spark)
36161 );
36162 if use_seed {
36163 self.write_keyword("SEED");
36164 } else {
36165 self.write_keyword("REPEATABLE");
36166 }
36167 self.write(" (");
36168 self.generate_expression(seed)?;
36169 self.write(")");
36170 }
36171 return Ok(());
36172 }
36173
36174 self.write_keyword(self.config.tablesample_keywords);
36176 if let Some(method) = &e.method {
36177 self.write_space();
36178 self.write_keyword(method);
36179 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
36180 self.write_space();
36182 self.write_keyword("BERNOULLI");
36183 }
36184 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
36185 self.write_space();
36186 self.write_keyword("BUCKET");
36187 self.write_space();
36188 self.generate_expression(numerator)?;
36189 self.write_space();
36190 self.write_keyword("OUT OF");
36191 self.write_space();
36192 self.generate_expression(denominator)?;
36193 if let Some(field) = &e.bucket_field {
36194 self.write_space();
36195 self.write_keyword("ON");
36196 self.write_space();
36197 self.generate_expression(field)?;
36198 }
36199 } else if !e.expressions.is_empty() {
36200 self.write(" (");
36201 for (i, expr) in e.expressions.iter().enumerate() {
36202 if i > 0 {
36203 self.write(", ");
36204 }
36205 self.generate_expression(expr)?;
36206 }
36207 self.write(")");
36208 } else if let Some(percent) = &e.percent {
36209 self.write(" (");
36210 self.generate_expression(percent)?;
36211 self.write_space();
36212 self.write_keyword("PERCENT");
36213 self.write(")");
36214 }
36215 Ok(())
36216 }
36217
36218 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
36219 if let Some(prefix) = &e.prefix {
36221 self.generate_expression(prefix)?;
36222 }
36223 if let Some(this) = &e.this {
36224 self.generate_expression(this)?;
36225 }
36226 if let Some(postfix) = &e.postfix {
36227 self.generate_expression(postfix)?;
36228 }
36229 Ok(())
36230 }
36231
36232 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
36233 self.write_keyword("TAG");
36235 self.write(" (");
36236 for (i, expr) in e.expressions.iter().enumerate() {
36237 if i > 0 {
36238 self.write(", ");
36239 }
36240 self.generate_expression(expr)?;
36241 }
36242 self.write(")");
36243 Ok(())
36244 }
36245
36246 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
36247 if let Some(this) = &e.this {
36249 self.generate_expression(this)?;
36250 self.write_space();
36251 }
36252 self.write_keyword("TEMPORARY");
36253 Ok(())
36254 }
36255
36256 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
36259 self.write_keyword("TIME");
36261 self.write("(");
36262 self.generate_expression(&e.this)?;
36263 self.write(")");
36264 Ok(())
36265 }
36266
36267 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
36268 self.write_keyword("TIME_ADD");
36270 self.write("(");
36271 self.generate_expression(&e.this)?;
36272 self.write(", ");
36273 self.generate_expression(&e.expression)?;
36274 if let Some(unit) = &e.unit {
36275 self.write(", ");
36276 self.write_keyword(unit);
36277 }
36278 self.write(")");
36279 Ok(())
36280 }
36281
36282 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
36283 self.write_keyword("TIME_DIFF");
36285 self.write("(");
36286 self.generate_expression(&e.this)?;
36287 self.write(", ");
36288 self.generate_expression(&e.expression)?;
36289 if let Some(unit) = &e.unit {
36290 self.write(", ");
36291 self.write_keyword(unit);
36292 }
36293 self.write(")");
36294 Ok(())
36295 }
36296
36297 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
36298 self.write_keyword("TIME_FROM_PARTS");
36300 self.write("(");
36301 let mut first = true;
36302 if let Some(hour) = &e.hour {
36303 self.generate_expression(hour)?;
36304 first = false;
36305 }
36306 if let Some(minute) = &e.min {
36307 if !first {
36308 self.write(", ");
36309 }
36310 self.generate_expression(minute)?;
36311 first = false;
36312 }
36313 if let Some(second) = &e.sec {
36314 if !first {
36315 self.write(", ");
36316 }
36317 self.generate_expression(second)?;
36318 first = false;
36319 }
36320 if let Some(ns) = &e.nano {
36321 if !first {
36322 self.write(", ");
36323 }
36324 self.generate_expression(ns)?;
36325 }
36326 self.write(")");
36327 Ok(())
36328 }
36329
36330 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
36331 self.write_keyword("TIME_SLICE");
36333 self.write("(");
36334 self.generate_expression(&e.this)?;
36335 self.write(", ");
36336 self.generate_expression(&e.expression)?;
36337 self.write(", ");
36338 self.write_keyword(&e.unit);
36339 self.write(")");
36340 Ok(())
36341 }
36342
36343 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
36344 self.write_keyword("TIME_STR_TO_TIME");
36346 self.write("(");
36347 self.generate_expression(&e.this)?;
36348 self.write(")");
36349 Ok(())
36350 }
36351
36352 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
36353 self.write_keyword("TIME_SUB");
36355 self.write("(");
36356 self.generate_expression(&e.this)?;
36357 self.write(", ");
36358 self.generate_expression(&e.expression)?;
36359 if let Some(unit) = &e.unit {
36360 self.write(", ");
36361 self.write_keyword(unit);
36362 }
36363 self.write(")");
36364 Ok(())
36365 }
36366
36367 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
36368 match self.config.dialect {
36369 Some(DialectType::Exasol) => {
36370 self.write_keyword("TO_CHAR");
36372 self.write("(");
36373 self.generate_expression(&e.this)?;
36374 self.write(", '");
36375 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
36376 self.write("'");
36377 self.write(")");
36378 }
36379 Some(DialectType::PostgreSQL)
36380 | Some(DialectType::Redshift)
36381 | Some(DialectType::Materialize) => {
36382 self.write_keyword("TO_CHAR");
36384 self.write("(");
36385 self.generate_expression(&e.this)?;
36386 self.write(", '");
36387 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
36388 self.write("'");
36389 self.write(")");
36390 }
36391 Some(DialectType::Oracle) => {
36392 self.write_keyword("TO_CHAR");
36394 self.write("(");
36395 self.generate_expression(&e.this)?;
36396 self.write(", '");
36397 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
36398 self.write("'");
36399 self.write(")");
36400 }
36401 Some(DialectType::Drill) => {
36402 self.write_keyword("TO_CHAR");
36404 self.write("(");
36405 self.generate_expression(&e.this)?;
36406 self.write(", '");
36407 self.write(&Self::strftime_to_java_format(&e.format));
36408 self.write("'");
36409 self.write(")");
36410 }
36411 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
36412 self.write_keyword("FORMAT");
36414 self.write("(");
36415 self.generate_expression(&e.this)?;
36416 self.write(", '");
36417 self.write(&Self::strftime_to_tsql_format(&e.format));
36418 self.write("'");
36419 self.write(")");
36420 }
36421 Some(DialectType::DuckDB) => {
36422 self.write_keyword("STRFTIME");
36424 self.write("(");
36425 self.generate_expression(&e.this)?;
36426 self.write(", '");
36427 self.write(&e.format);
36428 self.write("'");
36429 self.write(")");
36430 }
36431 Some(DialectType::BigQuery) => {
36432 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
36435 self.write_keyword("FORMAT_DATE");
36436 self.write("('");
36437 self.write(&fmt);
36438 self.write("', ");
36439 self.generate_expression(&e.this)?;
36440 self.write(")");
36441 }
36442 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36443 self.write_keyword("DATE_FORMAT");
36445 self.write("(");
36446 self.generate_expression(&e.this)?;
36447 self.write(", '");
36448 self.write(&Self::strftime_to_java_format(&e.format));
36449 self.write("'");
36450 self.write(")");
36451 }
36452 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
36453 self.write_keyword("DATE_FORMAT");
36455 self.write("(");
36456 self.generate_expression(&e.this)?;
36457 self.write(", '");
36458 self.write(&e.format);
36459 self.write("'");
36460 self.write(")");
36461 }
36462 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
36463 self.write_keyword("DATE_FORMAT");
36465 self.write("(");
36466 self.generate_expression(&e.this)?;
36467 self.write(", '");
36468 self.write(&e.format);
36469 self.write("'");
36470 self.write(")");
36471 }
36472 _ => {
36473 self.write_keyword("TIME_TO_STR");
36475 self.write("(");
36476 self.generate_expression(&e.this)?;
36477 self.write(", '");
36478 self.write(&e.format);
36479 self.write("'");
36480 self.write(")");
36481 }
36482 }
36483 Ok(())
36484 }
36485
36486 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
36487 match self.config.dialect {
36488 Some(DialectType::DuckDB) => {
36489 self.write_keyword("EPOCH");
36491 self.write("(");
36492 self.generate_expression(&e.this)?;
36493 self.write(")");
36494 }
36495 Some(DialectType::Hive)
36496 | Some(DialectType::Spark)
36497 | Some(DialectType::Databricks)
36498 | Some(DialectType::Doris)
36499 | Some(DialectType::StarRocks)
36500 | Some(DialectType::Drill) => {
36501 self.write_keyword("UNIX_TIMESTAMP");
36503 self.write("(");
36504 self.generate_expression(&e.this)?;
36505 self.write(")");
36506 }
36507 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36508 self.write_keyword("TO_UNIXTIME");
36510 self.write("(");
36511 self.generate_expression(&e.this)?;
36512 self.write(")");
36513 }
36514 _ => {
36515 self.write_keyword("TIME_TO_UNIX");
36517 self.write("(");
36518 self.generate_expression(&e.this)?;
36519 self.write(")");
36520 }
36521 }
36522 Ok(())
36523 }
36524
36525 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
36526 match self.config.dialect {
36527 Some(DialectType::Hive) => {
36528 self.write_keyword("TO_DATE");
36530 self.write("(");
36531 self.generate_expression(&e.this)?;
36532 self.write(")");
36533 }
36534 _ => {
36535 self.write_keyword("TIME_STR_TO_DATE");
36537 self.write("(");
36538 self.generate_expression(&e.this)?;
36539 self.write(")");
36540 }
36541 }
36542 Ok(())
36543 }
36544
36545 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
36546 self.write_keyword("TIME_TRUNC");
36548 self.write("(");
36549 self.generate_expression(&e.this)?;
36550 self.write(", ");
36551 self.write_keyword(&e.unit);
36552 self.write(")");
36553 Ok(())
36554 }
36555
36556 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
36557 if let Some(unit) = &e.unit {
36559 self.write_keyword(unit);
36560 }
36561 Ok(())
36562 }
36563
36564 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
36568 use crate::dialects::DialectType;
36569 use crate::expressions::Literal;
36570
36571 match self.config.dialect {
36572 Some(DialectType::Exasol) => {
36574 self.write_keyword("TO_TIMESTAMP");
36575 self.write("(");
36576 if let Some(this) = &e.this {
36578 match this.as_ref() {
36579 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
36580 let Literal::String(s) = lit.as_ref() else {
36581 unreachable!()
36582 };
36583 self.write("'");
36584 self.write(s);
36585 self.write("'");
36586 }
36587 _ => {
36588 self.generate_expression(this)?;
36589 }
36590 }
36591 }
36592 self.write(")");
36593 }
36594 _ => {
36596 self.write_keyword("TIMESTAMP");
36597 self.write("(");
36598 if let Some(this) = &e.this {
36599 self.generate_expression(this)?;
36600 }
36601 if let Some(zone) = &e.zone {
36602 self.write(", ");
36603 self.generate_expression(zone)?;
36604 }
36605 self.write(")");
36606 }
36607 }
36608 Ok(())
36609 }
36610
36611 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
36612 self.write_keyword("TIMESTAMP_ADD");
36614 self.write("(");
36615 self.generate_expression(&e.this)?;
36616 self.write(", ");
36617 self.generate_expression(&e.expression)?;
36618 if let Some(unit) = &e.unit {
36619 self.write(", ");
36620 self.write_keyword(unit);
36621 }
36622 self.write(")");
36623 Ok(())
36624 }
36625
36626 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
36627 self.write_keyword("TIMESTAMP_DIFF");
36629 self.write("(");
36630 self.generate_expression(&e.this)?;
36631 self.write(", ");
36632 self.generate_expression(&e.expression)?;
36633 if let Some(unit) = &e.unit {
36634 self.write(", ");
36635 self.write_keyword(unit);
36636 }
36637 self.write(")");
36638 Ok(())
36639 }
36640
36641 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
36642 self.write_keyword("TIMESTAMP_FROM_PARTS");
36644 self.write("(");
36645 if let Some(this) = &e.this {
36646 self.generate_expression(this)?;
36647 }
36648 if let Some(expression) = &e.expression {
36649 self.write(", ");
36650 self.generate_expression(expression)?;
36651 }
36652 if let Some(zone) = &e.zone {
36653 self.write(", ");
36654 self.generate_expression(zone)?;
36655 }
36656 if let Some(milli) = &e.milli {
36657 self.write(", ");
36658 self.generate_expression(milli)?;
36659 }
36660 self.write(")");
36661 Ok(())
36662 }
36663
36664 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
36665 self.write_keyword("TIMESTAMP_SUB");
36667 self.write("(");
36668 self.generate_expression(&e.this)?;
36669 self.write(", ");
36670 self.write_keyword("INTERVAL");
36671 self.write_space();
36672 self.generate_expression(&e.expression)?;
36673 if let Some(unit) = &e.unit {
36674 self.write_space();
36675 self.write_keyword(unit);
36676 }
36677 self.write(")");
36678 Ok(())
36679 }
36680
36681 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
36682 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
36684 self.write("(");
36685 if let Some(zone) = &e.zone {
36686 self.generate_expression(zone)?;
36687 }
36688 self.write(")");
36689 Ok(())
36690 }
36691
36692 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
36693 self.write_keyword("TO_BINARY");
36695 self.write("(");
36696 self.generate_expression(&e.this)?;
36697 if let Some(format) = &e.format {
36698 self.write(", '");
36699 self.write(format);
36700 self.write("'");
36701 }
36702 self.write(")");
36703 Ok(())
36704 }
36705
36706 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
36707 self.write_keyword("TO_BOOLEAN");
36709 self.write("(");
36710 self.generate_expression(&e.this)?;
36711 self.write(")");
36712 Ok(())
36713 }
36714
36715 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
36716 self.write_keyword("TO_CHAR");
36718 self.write("(");
36719 self.generate_expression(&e.this)?;
36720 if let Some(format) = &e.format {
36721 self.write(", '");
36722 self.write(format);
36723 self.write("'");
36724 }
36725 if let Some(nlsparam) = &e.nlsparam {
36726 self.write(", ");
36727 self.generate_expression(nlsparam)?;
36728 }
36729 self.write(")");
36730 Ok(())
36731 }
36732
36733 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
36734 self.write_keyword("TO_DECFLOAT");
36736 self.write("(");
36737 self.generate_expression(&e.this)?;
36738 if let Some(format) = &e.format {
36739 self.write(", '");
36740 self.write(format);
36741 self.write("'");
36742 }
36743 self.write(")");
36744 Ok(())
36745 }
36746
36747 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
36748 self.write_keyword("TO_DOUBLE");
36750 self.write("(");
36751 self.generate_expression(&e.this)?;
36752 if let Some(format) = &e.format {
36753 self.write(", '");
36754 self.write(format);
36755 self.write("'");
36756 }
36757 self.write(")");
36758 Ok(())
36759 }
36760
36761 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
36762 self.write_keyword("TO_FILE");
36764 self.write("(");
36765 self.generate_expression(&e.this)?;
36766 if let Some(path) = &e.path {
36767 self.write(", ");
36768 self.generate_expression(path)?;
36769 }
36770 self.write(")");
36771 Ok(())
36772 }
36773
36774 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
36775 let is_safe = e.safe.is_some();
36778 if is_safe {
36779 self.write_keyword("TRY_TO_NUMBER");
36780 } else {
36781 self.write_keyword("TO_NUMBER");
36782 }
36783 self.write("(");
36784 self.generate_expression(&e.this)?;
36785 let precision_is_snowflake_default = e.precision.is_none()
36786 || matches!(
36787 e.precision.as_deref(),
36788 Some(Expression::Literal(lit))
36789 if matches!(lit.as_ref(), Literal::Number(n) if n == "0")
36790 );
36791 let is_snowflake_default_precision =
36792 matches!(self.config.dialect, Some(DialectType::Snowflake))
36793 && e.nlsparam.is_none()
36794 && e.scale.is_none()
36795 && matches!(
36796 e.format.as_deref(),
36797 Some(Expression::Literal(lit))
36798 if matches!(lit.as_ref(), Literal::Number(n) if n == "38")
36799 )
36800 && precision_is_snowflake_default;
36801
36802 if !is_snowflake_default_precision {
36803 if let Some(format) = &e.format {
36804 self.write(", ");
36805 self.generate_expression(format)?;
36806 }
36807 if let Some(nlsparam) = &e.nlsparam {
36808 self.write(", ");
36809 self.generate_expression(nlsparam)?;
36810 }
36811 if let Some(precision) = &e.precision {
36812 self.write(", ");
36813 self.generate_expression(precision)?;
36814 }
36815 if let Some(scale) = &e.scale {
36816 self.write(", ");
36817 self.generate_expression(scale)?;
36818 }
36819 }
36820 self.write(")");
36821 Ok(())
36822 }
36823
36824 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
36825 self.write_keyword("TO_TABLE");
36827 self.write_space();
36828 self.generate_expression(&e.this)?;
36829 Ok(())
36830 }
36831
36832 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
36833 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
36835 Expression::Identifier(id) => id.name.clone(),
36836 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
36837 let Literal::String(s) = lit.as_ref() else {
36838 unreachable!()
36839 };
36840 s.clone()
36841 }
36842 _ => String::new(),
36843 });
36844
36845 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
36846 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
36847 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
36848 matches!(m.as_ref(), Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)))
36849 });
36850
36851 let use_start_transaction = matches!(
36853 self.config.dialect,
36854 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
36855 );
36856 let strip_transaction = matches!(
36858 self.config.dialect,
36859 Some(DialectType::Snowflake)
36860 | Some(DialectType::PostgreSQL)
36861 | Some(DialectType::Redshift)
36862 | Some(DialectType::MySQL)
36863 | Some(DialectType::Hive)
36864 | Some(DialectType::Spark)
36865 | Some(DialectType::Databricks)
36866 | Some(DialectType::DuckDB)
36867 | Some(DialectType::Oracle)
36868 | Some(DialectType::Doris)
36869 | Some(DialectType::StarRocks)
36870 | Some(DialectType::Materialize)
36871 | Some(DialectType::ClickHouse)
36872 );
36873
36874 if is_start || use_start_transaction {
36875 self.write_keyword("START TRANSACTION");
36877 if let Some(modes) = &e.modes {
36878 self.write_space();
36879 self.generate_expression(modes)?;
36880 }
36881 } else {
36882 self.write_keyword("BEGIN");
36884
36885 let is_kind = e.this.as_ref().map_or(false, |t| {
36887 if let Expression::Identifier(id) = t.as_ref() {
36888 id.name.eq_ignore_ascii_case("DEFERRED")
36889 || id.name.eq_ignore_ascii_case("IMMEDIATE")
36890 || id.name.eq_ignore_ascii_case("EXCLUSIVE")
36891 } else {
36892 false
36893 }
36894 });
36895
36896 if is_kind {
36898 if let Some(this) = &e.this {
36899 self.write_space();
36900 if let Expression::Identifier(id) = this.as_ref() {
36901 self.write_keyword(&id.name);
36902 }
36903 }
36904 }
36905
36906 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
36908 self.write_space();
36909 self.write_keyword("TRANSACTION");
36910 }
36911
36912 if !is_kind {
36914 if let Some(this) = &e.this {
36915 self.write_space();
36916 self.generate_expression(this)?;
36917 }
36918 }
36919
36920 if has_with_mark {
36922 self.write_space();
36923 self.write_keyword("WITH MARK");
36924 if let Some(Expression::Literal(lit)) = e.mark.as_deref() {
36925 if let Literal::String(desc) = lit.as_ref() {
36926 if !desc.is_empty() {
36927 self.write_space();
36928 self.write(&format!("'{}'", desc));
36929 }
36930 }
36931 }
36932 }
36933
36934 if let Some(modes) = &e.modes {
36936 self.write_space();
36937 self.generate_expression(modes)?;
36938 }
36939 }
36940 Ok(())
36941 }
36942
36943 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
36944 self.write_keyword("TRANSFORM");
36946 self.write("(");
36947 self.generate_expression(&e.this)?;
36948 self.write(", ");
36949 self.generate_expression(&e.expression)?;
36950 self.write(")");
36951 Ok(())
36952 }
36953
36954 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
36955 self.write_keyword("TRANSFORM");
36957 self.write("(");
36958 if self.config.pretty && !e.expressions.is_empty() {
36959 self.indent_level += 1;
36960 for (i, expr) in e.expressions.iter().enumerate() {
36961 if i > 0 {
36962 self.write(",");
36963 }
36964 self.write_newline();
36965 self.write_indent();
36966 self.generate_expression(expr)?;
36967 }
36968 self.indent_level -= 1;
36969 self.write_newline();
36970 self.write(")");
36971 } else {
36972 for (i, expr) in e.expressions.iter().enumerate() {
36973 if i > 0 {
36974 self.write(", ");
36975 }
36976 self.generate_expression(expr)?;
36977 }
36978 self.write(")");
36979 }
36980 Ok(())
36981 }
36982
36983 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
36984 use crate::dialects::DialectType;
36985 if let Some(this) = &e.this {
36987 self.generate_expression(this)?;
36988 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
36989 self.write_space();
36990 }
36991 }
36992 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
36993 self.write_keyword("TRANSIENT");
36994 }
36995 Ok(())
36996 }
36997
36998 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
36999 self.write_keyword("TRANSLATE");
37001 self.write("(");
37002 self.generate_expression(&e.this)?;
37003 if let Some(from) = &e.from_ {
37004 self.write(", ");
37005 self.generate_expression(from)?;
37006 }
37007 if let Some(to) = &e.to {
37008 self.write(", ");
37009 self.generate_expression(to)?;
37010 }
37011 self.write(")");
37012 Ok(())
37013 }
37014
37015 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
37016 self.write_keyword("TRANSLATE");
37018 self.write("(");
37019 self.generate_expression(&e.this)?;
37020 self.write_space();
37021 self.write_keyword("USING");
37022 self.write_space();
37023 self.generate_expression(&e.expression)?;
37024 if e.with_error.is_some() {
37025 self.write_space();
37026 self.write_keyword("WITH ERROR");
37027 }
37028 self.write(")");
37029 Ok(())
37030 }
37031
37032 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
37033 self.write_keyword("TRUNCATE TABLE");
37035 self.write_space();
37036 for (i, expr) in e.expressions.iter().enumerate() {
37037 if i > 0 {
37038 self.write(", ");
37039 }
37040 self.generate_expression(expr)?;
37041 }
37042 Ok(())
37043 }
37044
37045 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
37046 self.write_keyword("TRY_BASE64_DECODE_BINARY");
37048 self.write("(");
37049 self.generate_expression(&e.this)?;
37050 if let Some(alphabet) = &e.alphabet {
37051 self.write(", ");
37052 self.generate_expression(alphabet)?;
37053 }
37054 self.write(")");
37055 Ok(())
37056 }
37057
37058 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
37059 self.write_keyword("TRY_BASE64_DECODE_STRING");
37061 self.write("(");
37062 self.generate_expression(&e.this)?;
37063 if let Some(alphabet) = &e.alphabet {
37064 self.write(", ");
37065 self.generate_expression(alphabet)?;
37066 }
37067 self.write(")");
37068 Ok(())
37069 }
37070
37071 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
37072 self.write_keyword("TRY_TO_DECFLOAT");
37074 self.write("(");
37075 self.generate_expression(&e.this)?;
37076 if let Some(format) = &e.format {
37077 self.write(", '");
37078 self.write(format);
37079 self.write("'");
37080 }
37081 self.write(")");
37082 Ok(())
37083 }
37084
37085 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
37086 self.write_keyword("TS_OR_DS_ADD");
37088 self.write("(");
37089 self.generate_expression(&e.this)?;
37090 self.write(", ");
37091 self.generate_expression(&e.expression)?;
37092 if let Some(unit) = &e.unit {
37093 self.write(", ");
37094 self.write_keyword(unit);
37095 }
37096 if let Some(return_type) = &e.return_type {
37097 self.write(", ");
37098 self.generate_expression(return_type)?;
37099 }
37100 self.write(")");
37101 Ok(())
37102 }
37103
37104 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
37105 self.write_keyword("TS_OR_DS_DIFF");
37107 self.write("(");
37108 self.generate_expression(&e.this)?;
37109 self.write(", ");
37110 self.generate_expression(&e.expression)?;
37111 if let Some(unit) = &e.unit {
37112 self.write(", ");
37113 self.write_keyword(unit);
37114 }
37115 self.write(")");
37116 Ok(())
37117 }
37118
37119 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
37120 let default_time_format = "%Y-%m-%d %H:%M:%S";
37121 let default_date_format = "%Y-%m-%d";
37122 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
37123 f != default_time_format && f != default_date_format
37124 });
37125
37126 if has_non_default_format {
37127 let fmt = e.format.as_ref().unwrap();
37129 match self.config.dialect {
37130 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
37131 let str_to_time = crate::expressions::StrToTime {
37134 this: Box::new((*e.this).clone()),
37135 format: fmt.clone(),
37136 zone: None,
37137 safe: None,
37138 target_type: None,
37139 };
37140 self.generate_str_to_time(&str_to_time)?;
37141 }
37142 Some(DialectType::Hive)
37143 | Some(DialectType::Spark)
37144 | Some(DialectType::Databricks) => {
37145 self.write_keyword("TO_DATE");
37147 self.write("(");
37148 self.generate_expression(&e.this)?;
37149 self.write(", '");
37150 self.write(&Self::strftime_to_java_format(fmt));
37151 self.write("')");
37152 }
37153 Some(DialectType::Snowflake) => {
37154 self.write_keyword("TO_DATE");
37156 self.write("(");
37157 self.generate_expression(&e.this)?;
37158 self.write(", '");
37159 self.write(&Self::strftime_to_snowflake_format(fmt));
37160 self.write("')");
37161 }
37162 Some(DialectType::Doris) => {
37163 self.write_keyword("TO_DATE");
37165 self.write("(");
37166 self.generate_expression(&e.this)?;
37167 self.write(")");
37168 }
37169 _ => {
37170 self.write_keyword("CAST");
37172 self.write("(");
37173 let str_to_time = crate::expressions::StrToTime {
37174 this: Box::new((*e.this).clone()),
37175 format: fmt.clone(),
37176 zone: None,
37177 safe: None,
37178 target_type: None,
37179 };
37180 self.generate_str_to_time(&str_to_time)?;
37181 self.write_keyword(" AS ");
37182 self.write_keyword("DATE");
37183 self.write(")");
37184 }
37185 }
37186 } else {
37187 match self.config.dialect {
37189 Some(DialectType::MySQL)
37190 | Some(DialectType::SQLite)
37191 | Some(DialectType::StarRocks) => {
37192 self.write_keyword("DATE");
37194 self.write("(");
37195 self.generate_expression(&e.this)?;
37196 self.write(")");
37197 }
37198 Some(DialectType::Hive)
37199 | Some(DialectType::Spark)
37200 | Some(DialectType::Databricks)
37201 | Some(DialectType::Snowflake)
37202 | Some(DialectType::Doris) => {
37203 self.write_keyword("TO_DATE");
37205 self.write("(");
37206 self.generate_expression(&e.this)?;
37207 self.write(")");
37208 }
37209 Some(DialectType::Presto)
37210 | Some(DialectType::Trino)
37211 | Some(DialectType::Athena) => {
37212 self.write_keyword("CAST");
37214 self.write("(");
37215 self.write_keyword("CAST");
37216 self.write("(");
37217 self.generate_expression(&e.this)?;
37218 self.write_keyword(" AS ");
37219 self.write_keyword("TIMESTAMP");
37220 self.write(")");
37221 self.write_keyword(" AS ");
37222 self.write_keyword("DATE");
37223 self.write(")");
37224 }
37225 Some(DialectType::ClickHouse) => {
37226 self.write_keyword("CAST");
37228 self.write("(");
37229 self.generate_expression(&e.this)?;
37230 self.write_keyword(" AS ");
37231 self.write("Nullable(DATE)");
37232 self.write(")");
37233 }
37234 _ => {
37235 self.write_keyword("CAST");
37237 self.write("(");
37238 self.generate_expression(&e.this)?;
37239 self.write_keyword(" AS ");
37240 self.write_keyword("DATE");
37241 self.write(")");
37242 }
37243 }
37244 }
37245 Ok(())
37246 }
37247
37248 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
37249 self.write_keyword("TS_OR_DS_TO_TIME");
37251 self.write("(");
37252 self.generate_expression(&e.this)?;
37253 if let Some(format) = &e.format {
37254 self.write(", '");
37255 self.write(format);
37256 self.write("'");
37257 }
37258 self.write(")");
37259 Ok(())
37260 }
37261
37262 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
37263 self.write_keyword("UNHEX");
37265 self.write("(");
37266 self.generate_expression(&e.this)?;
37267 if let Some(expression) = &e.expression {
37268 self.write(", ");
37269 self.generate_expression(expression)?;
37270 }
37271 self.write(")");
37272 Ok(())
37273 }
37274
37275 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
37276 self.write("U&");
37278 self.generate_expression(&e.this)?;
37279 if let Some(escape) = &e.escape {
37280 self.write_space();
37281 self.write_keyword("UESCAPE");
37282 self.write_space();
37283 self.generate_expression(escape)?;
37284 }
37285 Ok(())
37286 }
37287
37288 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
37289 self.write_keyword("UNIFORM");
37291 self.write("(");
37292 self.generate_expression(&e.this)?;
37293 self.write(", ");
37294 self.generate_expression(&e.expression)?;
37295 if let Some(gen) = &e.gen {
37296 self.write(", ");
37297 self.generate_expression(gen)?;
37298 }
37299 if let Some(seed) = &e.seed {
37300 self.write(", ");
37301 self.generate_expression(seed)?;
37302 }
37303 self.write(")");
37304 Ok(())
37305 }
37306
37307 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
37308 self.write_keyword("UNIQUE");
37310 if e.nulls.is_some() {
37312 self.write(" NULLS NOT DISTINCT");
37313 }
37314 if let Some(this) = &e.this {
37315 self.write_space();
37316 self.generate_expression(this)?;
37317 }
37318 if let Some(index_type) = &e.index_type {
37319 self.write(" USING ");
37320 self.generate_expression(index_type)?;
37321 }
37322 if let Some(on_conflict) = &e.on_conflict {
37323 self.write_space();
37324 self.generate_expression(on_conflict)?;
37325 }
37326 for opt in &e.options {
37327 self.write_space();
37328 self.generate_expression(opt)?;
37329 }
37330 Ok(())
37331 }
37332
37333 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
37334 self.write_keyword("UNIQUE KEY");
37336 self.write(" (");
37337 for (i, expr) in e.expressions.iter().enumerate() {
37338 if i > 0 {
37339 self.write(", ");
37340 }
37341 self.generate_expression(expr)?;
37342 }
37343 self.write(")");
37344 Ok(())
37345 }
37346
37347 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
37348 self.write_keyword("ROLLUP");
37350 self.write(" (");
37351 for (i, index) in e.expressions.iter().enumerate() {
37352 if i > 0 {
37353 self.write(", ");
37354 }
37355 self.generate_identifier(&index.name)?;
37356 self.write("(");
37357 for (j, col) in index.expressions.iter().enumerate() {
37358 if j > 0 {
37359 self.write(", ");
37360 }
37361 self.generate_identifier(col)?;
37362 }
37363 self.write(")");
37364 }
37365 self.write(")");
37366 Ok(())
37367 }
37368
37369 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
37370 match self.config.dialect {
37371 Some(DialectType::DuckDB) => {
37372 self.write_keyword("STRFTIME");
37374 self.write("(");
37375 self.write_keyword("TO_TIMESTAMP");
37376 self.write("(");
37377 self.generate_expression(&e.this)?;
37378 self.write("), '");
37379 if let Some(format) = &e.format {
37380 self.write(format);
37381 }
37382 self.write("')");
37383 }
37384 Some(DialectType::Hive) => {
37385 self.write_keyword("FROM_UNIXTIME");
37387 self.write("(");
37388 self.generate_expression(&e.this)?;
37389 if let Some(format) = &e.format {
37390 if format != "yyyy-MM-dd HH:mm:ss" {
37391 self.write(", '");
37392 self.write(format);
37393 self.write("'");
37394 }
37395 }
37396 self.write(")");
37397 }
37398 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37399 self.write_keyword("DATE_FORMAT");
37401 self.write("(");
37402 self.write_keyword("FROM_UNIXTIME");
37403 self.write("(");
37404 self.generate_expression(&e.this)?;
37405 self.write("), '");
37406 if let Some(format) = &e.format {
37407 self.write(format);
37408 }
37409 self.write("')");
37410 }
37411 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
37412 self.write_keyword("FROM_UNIXTIME");
37414 self.write("(");
37415 self.generate_expression(&e.this)?;
37416 if let Some(format) = &e.format {
37417 self.write(", '");
37418 self.write(format);
37419 self.write("'");
37420 }
37421 self.write(")");
37422 }
37423 _ => {
37424 self.write_keyword("UNIX_TO_STR");
37426 self.write("(");
37427 self.generate_expression(&e.this)?;
37428 if let Some(format) = &e.format {
37429 self.write(", '");
37430 self.write(format);
37431 self.write("'");
37432 }
37433 self.write(")");
37434 }
37435 }
37436 Ok(())
37437 }
37438
37439 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
37440 use crate::dialects::DialectType;
37441 let scale = e.scale.unwrap_or(0); match self.config.dialect {
37444 Some(DialectType::Snowflake) => {
37445 self.write_keyword("TO_TIMESTAMP");
37447 self.write("(");
37448 self.generate_expression(&e.this)?;
37449 if let Some(s) = e.scale {
37450 if s > 0 {
37451 self.write(", ");
37452 self.write(&s.to_string());
37453 }
37454 }
37455 self.write(")");
37456 }
37457 Some(DialectType::BigQuery) => {
37458 match scale {
37461 0 => {
37462 self.write_keyword("TIMESTAMP_SECONDS");
37463 self.write("(");
37464 self.generate_expression(&e.this)?;
37465 self.write(")");
37466 }
37467 3 => {
37468 self.write_keyword("TIMESTAMP_MILLIS");
37469 self.write("(");
37470 self.generate_expression(&e.this)?;
37471 self.write(")");
37472 }
37473 6 => {
37474 self.write_keyword("TIMESTAMP_MICROS");
37475 self.write("(");
37476 self.generate_expression(&e.this)?;
37477 self.write(")");
37478 }
37479 _ => {
37480 self.write_keyword("TIMESTAMP_SECONDS");
37482 self.write("(CAST(");
37483 self.generate_expression(&e.this)?;
37484 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
37485 }
37486 }
37487 }
37488 Some(DialectType::Spark) => {
37489 match scale {
37494 0 => {
37495 self.write_keyword("CAST");
37496 self.write("(");
37497 self.write_keyword("FROM_UNIXTIME");
37498 self.write("(");
37499 self.generate_expression(&e.this)?;
37500 self.write(") ");
37501 self.write_keyword("AS TIMESTAMP");
37502 self.write(")");
37503 }
37504 3 => {
37505 self.write_keyword("TIMESTAMP_MILLIS");
37506 self.write("(");
37507 self.generate_expression(&e.this)?;
37508 self.write(")");
37509 }
37510 6 => {
37511 self.write_keyword("TIMESTAMP_MICROS");
37512 self.write("(");
37513 self.generate_expression(&e.this)?;
37514 self.write(")");
37515 }
37516 _ => {
37517 self.write_keyword("TIMESTAMP_SECONDS");
37518 self.write("(");
37519 self.generate_expression(&e.this)?;
37520 self.write(&format!(" / POWER(10, {}))", scale));
37521 }
37522 }
37523 }
37524 Some(DialectType::Databricks) => {
37525 match scale {
37529 0 => {
37530 self.write_keyword("CAST");
37531 self.write("(");
37532 self.write_keyword("FROM_UNIXTIME");
37533 self.write("(");
37534 self.generate_expression(&e.this)?;
37535 self.write(") ");
37536 self.write_keyword("AS TIMESTAMP");
37537 self.write(")");
37538 }
37539 3 => {
37540 self.write_keyword("TIMESTAMP_MILLIS");
37541 self.write("(");
37542 self.generate_expression(&e.this)?;
37543 self.write(")");
37544 }
37545 6 => {
37546 self.write_keyword("TIMESTAMP_MICROS");
37547 self.write("(");
37548 self.generate_expression(&e.this)?;
37549 self.write(")");
37550 }
37551 _ => {
37552 self.write_keyword("TIMESTAMP_SECONDS");
37553 self.write("(");
37554 self.generate_expression(&e.this)?;
37555 self.write(&format!(" / POWER(10, {}))", scale));
37556 }
37557 }
37558 }
37559 Some(DialectType::Hive) => {
37560 if scale == 0 {
37562 self.write_keyword("FROM_UNIXTIME");
37563 self.write("(");
37564 self.generate_expression(&e.this)?;
37565 self.write(")");
37566 } else {
37567 self.write_keyword("FROM_UNIXTIME");
37568 self.write("(");
37569 self.generate_expression(&e.this)?;
37570 self.write(&format!(" / POWER(10, {})", scale));
37571 self.write(")");
37572 }
37573 }
37574 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37575 if scale == 0 {
37578 self.write_keyword("FROM_UNIXTIME");
37579 self.write("(");
37580 self.generate_expression(&e.this)?;
37581 self.write(")");
37582 } else {
37583 self.write_keyword("FROM_UNIXTIME");
37584 self.write("(CAST(");
37585 self.generate_expression(&e.this)?;
37586 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
37587 }
37588 }
37589 Some(DialectType::DuckDB) => {
37590 match scale {
37594 0 => {
37595 self.write_keyword("TO_TIMESTAMP");
37596 self.write("(");
37597 self.generate_expression(&e.this)?;
37598 self.write(")");
37599 }
37600 3 => {
37601 self.write_keyword("EPOCH_MS");
37602 self.write("(");
37603 self.generate_expression(&e.this)?;
37604 self.write(")");
37605 }
37606 6 => {
37607 self.write_keyword("MAKE_TIMESTAMP");
37608 self.write("(");
37609 self.generate_expression(&e.this)?;
37610 self.write(")");
37611 }
37612 _ => {
37613 self.write_keyword("TO_TIMESTAMP");
37614 self.write("(");
37615 self.generate_expression(&e.this)?;
37616 self.write(&format!(" / POWER(10, {}))", scale));
37617 self.write_keyword(" AT TIME ZONE");
37618 self.write(" 'UTC'");
37619 }
37620 }
37621 }
37622 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
37623 self.write_keyword("FROM_UNIXTIME");
37625 self.write("(");
37626 self.generate_expression(&e.this)?;
37627 self.write(")");
37628 }
37629 Some(DialectType::Oracle) => {
37630 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
37632 self.generate_expression(&e.this)?;
37633 self.write(" / 86400)");
37634 }
37635 Some(DialectType::Redshift) => {
37636 self.write("(TIMESTAMP 'epoch' + ");
37639 if scale == 0 {
37640 self.generate_expression(&e.this)?;
37641 } else {
37642 self.write("(");
37643 self.generate_expression(&e.this)?;
37644 self.write(&format!(" / POWER(10, {}))", scale));
37645 }
37646 self.write(" * INTERVAL '1 SECOND')");
37647 }
37648 Some(DialectType::Exasol) => {
37649 self.write_keyword("FROM_POSIX_TIME");
37651 self.write("(");
37652 self.generate_expression(&e.this)?;
37653 self.write(")");
37654 }
37655 _ => {
37656 self.write_keyword("TO_TIMESTAMP");
37658 self.write("(");
37659 self.generate_expression(&e.this)?;
37660 if let Some(s) = e.scale {
37661 self.write(", ");
37662 self.write(&s.to_string());
37663 }
37664 self.write(")");
37665 }
37666 }
37667 Ok(())
37668 }
37669
37670 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
37671 if !matches!(&*e.this, Expression::Null(_)) {
37673 self.write_keyword("NAME");
37674 self.write_space();
37675 self.generate_expression(&e.this)?;
37676 }
37677 if !e.expressions.is_empty() {
37678 self.write_space();
37679 self.write_keyword("VALUE");
37680 self.write_space();
37681 for (i, expr) in e.expressions.iter().enumerate() {
37682 if i > 0 {
37683 self.write(", ");
37684 }
37685 self.generate_expression(expr)?;
37686 }
37687 }
37688 Ok(())
37689 }
37690
37691 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
37692 if e.wrapped.is_some() {
37694 self.write("(");
37695 }
37696 self.generate_expression(&e.this)?;
37697 if e.wrapped.is_some() {
37698 self.write(")");
37699 }
37700 self.write("(");
37701 for (i, expr) in e.expressions.iter().enumerate() {
37702 if i > 0 {
37703 self.write(", ");
37704 }
37705 self.generate_expression(expr)?;
37706 }
37707 self.write(")");
37708 Ok(())
37709 }
37710
37711 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
37712 self.write_keyword("USING TEMPLATE");
37714 self.write_space();
37715 self.generate_expression(&e.this)?;
37716 Ok(())
37717 }
37718
37719 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
37720 self.write_keyword("UTC_TIME");
37722 Ok(())
37723 }
37724
37725 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
37726 if matches!(
37727 self.config.dialect,
37728 Some(crate::dialects::DialectType::ClickHouse)
37729 ) {
37730 self.write_keyword("CURRENT_TIMESTAMP");
37731 self.write("('UTC')");
37732 } else {
37733 self.write_keyword("UTC_TIMESTAMP");
37734 }
37735 Ok(())
37736 }
37737
37738 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
37739 use crate::dialects::DialectType;
37740 let func_name = match self.config.dialect {
37742 Some(DialectType::Snowflake) => "UUID_STRING",
37743 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
37744 Some(DialectType::BigQuery) => "GENERATE_UUID",
37745 _ => {
37746 if let Some(name) = &e.name {
37747 name.as_str()
37748 } else {
37749 "UUID"
37750 }
37751 }
37752 };
37753 self.write_keyword(func_name);
37754 self.write("(");
37755 if let Some(this) = &e.this {
37756 self.generate_expression(this)?;
37757 }
37758 self.write(")");
37759 Ok(())
37760 }
37761
37762 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
37763 self.write_keyword("MAP");
37765 self.write("(");
37766 let mut first = true;
37767 for (k, v) in e.keys.iter().zip(e.values.iter()) {
37768 if !first {
37769 self.write(", ");
37770 }
37771 self.generate_expression(k)?;
37772 self.write(", ");
37773 self.generate_expression(v)?;
37774 first = false;
37775 }
37776 self.write(")");
37777 Ok(())
37778 }
37779
37780 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
37781 self.write_keyword("VECTOR_SEARCH");
37783 self.write("(");
37784 self.generate_expression(&e.this)?;
37785 if let Some(col) = &e.column_to_search {
37786 self.write(", ");
37787 self.generate_expression(col)?;
37788 }
37789 if let Some(query_table) = &e.query_table {
37790 self.write(", ");
37791 self.generate_expression(query_table)?;
37792 }
37793 if let Some(query_col) = &e.query_column_to_search {
37794 self.write(", ");
37795 self.generate_expression(query_col)?;
37796 }
37797 if let Some(top_k) = &e.top_k {
37798 self.write(", ");
37799 self.generate_expression(top_k)?;
37800 }
37801 if let Some(dist_type) = &e.distance_type {
37802 self.write(", ");
37803 self.generate_expression(dist_type)?;
37804 }
37805 self.write(")");
37806 Ok(())
37807 }
37808
37809 fn generate_version(&mut self, e: &Version) -> Result<()> {
37810 use crate::dialects::DialectType;
37816 let skip_for = matches!(
37817 self.config.dialect,
37818 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
37819 );
37820 if !skip_for {
37821 self.write_keyword("FOR");
37822 self.write_space();
37823 }
37824 match e.this.as_ref() {
37826 Expression::Identifier(ident) => {
37827 self.write_keyword(&ident.name);
37828 }
37829 _ => {
37830 self.generate_expression(&e.this)?;
37831 }
37832 }
37833 self.write_space();
37834 self.write_keyword(&e.kind);
37835 if let Some(expression) = &e.expression {
37836 self.write_space();
37837 self.generate_expression(expression)?;
37838 }
37839 Ok(())
37840 }
37841
37842 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
37843 self.generate_expression(&e.this)?;
37845 Ok(())
37846 }
37847
37848 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
37849 if e.this.is_some() {
37851 self.write_keyword("NOT VOLATILE");
37852 } else {
37853 self.write_keyword("VOLATILE");
37854 }
37855 Ok(())
37856 }
37857
37858 fn generate_watermark_column_constraint(
37859 &mut self,
37860 e: &WatermarkColumnConstraint,
37861 ) -> Result<()> {
37862 self.write_keyword("WATERMARK FOR");
37864 self.write_space();
37865 self.generate_expression(&e.this)?;
37866 self.write_space();
37867 self.write_keyword("AS");
37868 self.write_space();
37869 self.generate_expression(&e.expression)?;
37870 Ok(())
37871 }
37872
37873 fn generate_week(&mut self, e: &Week) -> Result<()> {
37874 self.write_keyword("WEEK");
37876 self.write("(");
37877 self.generate_expression(&e.this)?;
37878 if let Some(mode) = &e.mode {
37879 self.write(", ");
37880 self.generate_expression(mode)?;
37881 }
37882 self.write(")");
37883 Ok(())
37884 }
37885
37886 fn generate_when(&mut self, e: &When) -> Result<()> {
37887 self.write_keyword("WHEN");
37891 self.write_space();
37892
37893 if let Some(matched) = &e.matched {
37895 match matched.as_ref() {
37897 Expression::Boolean(b) if b.value => {
37898 self.write_keyword("MATCHED");
37899 }
37900 _ => {
37901 self.write_keyword("NOT MATCHED");
37902 }
37903 }
37904 } else {
37905 self.write_keyword("NOT MATCHED");
37906 }
37907
37908 if self.config.matched_by_source {
37913 if let Some(source) = &e.source {
37914 if let Expression::Boolean(b) = source.as_ref() {
37915 if b.value {
37916 self.write_space();
37918 self.write_keyword("BY SOURCE");
37919 }
37920 } else {
37922 self.write_space();
37924 self.write_keyword("BY SOURCE");
37925 }
37926 }
37927 }
37928
37929 if let Some(condition) = &e.condition {
37931 self.write_space();
37932 self.write_keyword("AND");
37933 self.write_space();
37934 self.generate_expression(condition)?;
37935 }
37936
37937 self.write_space();
37938 self.write_keyword("THEN");
37939 self.write_space();
37940
37941 self.generate_merge_action(&e.then)?;
37944
37945 Ok(())
37946 }
37947
37948 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
37949 match action {
37950 Expression::Tuple(tuple) => {
37951 let elements = &tuple.expressions;
37952 if elements.is_empty() {
37953 return self.generate_expression(action);
37954 }
37955 match &elements[0] {
37957 Expression::Var(v) if v.this == "INSERT" => {
37958 self.write_keyword("INSERT");
37959 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
37961 self.write(" *");
37962 if let Some(Expression::Where(w)) = elements.get(2) {
37963 self.write_space();
37964 self.generate_where(w)?;
37965 }
37966 } else {
37967 let mut values_idx = 1;
37968 if elements.len() > 1 {
37970 if let Expression::Tuple(cols) = &elements[1] {
37971 if elements.len() > 2 {
37973 self.write(" (");
37975 for (i, col) in cols.expressions.iter().enumerate() {
37976 if i > 0 {
37977 self.write(", ");
37978 }
37979 if !self.merge_strip_qualifiers.is_empty() {
37981 let stripped = self.strip_merge_qualifier(col);
37982 self.generate_expression(&stripped)?;
37983 } else {
37984 self.generate_expression(col)?;
37985 }
37986 }
37987 self.write(")");
37988 values_idx = 2;
37989 } else {
37990 values_idx = 1;
37992 }
37993 }
37994 }
37995 let mut next_idx = values_idx;
37996 if values_idx < elements.len()
37998 && !matches!(&elements[values_idx], Expression::Where(_))
37999 {
38000 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
38002 if !is_row {
38003 self.write_space();
38004 self.write_keyword("VALUES");
38005 }
38006 self.write(" ");
38007 if let Expression::Tuple(vals) = &elements[values_idx] {
38008 self.write("(");
38009 for (i, val) in vals.expressions.iter().enumerate() {
38010 if i > 0 {
38011 self.write(", ");
38012 }
38013 self.generate_expression(val)?;
38014 }
38015 self.write(")");
38016 } else {
38017 self.generate_expression(&elements[values_idx])?;
38018 }
38019 next_idx += 1;
38020 }
38021 if let Some(Expression::Where(w)) = elements.get(next_idx) {
38022 self.write_space();
38023 self.generate_where(w)?;
38024 }
38025 } }
38027 Expression::Var(v) if v.this == "UPDATE" => {
38028 self.write_keyword("UPDATE");
38029 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
38031 self.write(" *");
38032 if let Some(Expression::Where(w)) = elements.get(2) {
38033 self.write_space();
38034 self.generate_where(w)?;
38035 }
38036 } else if elements.len() > 1 {
38037 self.write_space();
38038 self.write_keyword("SET");
38039 if self.config.pretty {
38041 self.write_newline();
38042 self.indent_level += 1;
38043 self.write_indent();
38044 } else {
38045 self.write_space();
38046 }
38047 if let Expression::Tuple(assignments) = &elements[1] {
38048 for (i, assignment) in assignments.expressions.iter().enumerate() {
38049 if i > 0 {
38050 if self.config.pretty {
38051 self.write(",");
38052 self.write_newline();
38053 self.write_indent();
38054 } else {
38055 self.write(", ");
38056 }
38057 }
38058 if !self.merge_strip_qualifiers.is_empty() {
38060 self.generate_merge_set_assignment(assignment)?;
38061 } else {
38062 self.generate_expression(assignment)?;
38063 }
38064 }
38065 } else {
38066 self.generate_expression(&elements[1])?;
38067 }
38068 if self.config.pretty {
38069 self.indent_level -= 1;
38070 }
38071 if let Some(Expression::Where(w)) = elements.get(2) {
38072 self.write_space();
38073 self.generate_where(w)?;
38074 }
38075 }
38076 }
38077 Expression::Var(v) if v.this == "DELETE" => {
38078 self.write_keyword("DELETE");
38079 if let Some(Expression::Where(w)) = elements.get(1) {
38080 self.write_space();
38081 self.generate_where(w)?;
38082 }
38083 }
38084 _ => {
38085 self.generate_expression(action)?;
38087 }
38088 }
38089 }
38090 Expression::Var(v)
38091 if v.this == "INSERT"
38092 || v.this == "UPDATE"
38093 || v.this == "DELETE"
38094 || v.this == "DO NOTHING" =>
38095 {
38096 self.write_keyword(&v.this);
38097 }
38098 _ => {
38099 self.generate_expression(action)?;
38100 }
38101 }
38102 Ok(())
38103 }
38104
38105 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
38107 match assignment {
38108 Expression::Eq(eq) => {
38109 let stripped_left = self.strip_merge_qualifier(&eq.left);
38111 self.generate_expression(&stripped_left)?;
38112 self.write(" = ");
38113 self.generate_expression(&eq.right)?;
38114 Ok(())
38115 }
38116 other => self.generate_expression(other),
38117 }
38118 }
38119
38120 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
38122 match expr {
38123 Expression::Column(col) => {
38124 if let Some(ref table_ident) = col.table {
38125 if self
38126 .merge_strip_qualifiers
38127 .iter()
38128 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
38129 {
38130 let mut col = col.clone();
38132 col.table = None;
38133 return Expression::Column(col);
38134 }
38135 }
38136 expr.clone()
38137 }
38138 Expression::Dot(dot) => {
38139 if let Expression::Identifier(id) = &dot.this {
38141 if self
38142 .merge_strip_qualifiers
38143 .iter()
38144 .any(|n| n.eq_ignore_ascii_case(&id.name))
38145 {
38146 return Expression::Identifier(dot.field.clone());
38147 }
38148 }
38149 expr.clone()
38150 }
38151 _ => expr.clone(),
38152 }
38153 }
38154
38155 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
38156 for (i, expr) in e.expressions.iter().enumerate() {
38158 if i > 0 {
38159 if self.config.pretty {
38161 self.write_newline();
38162 self.write_indent();
38163 } else {
38164 self.write_space();
38165 }
38166 }
38167 self.generate_expression(expr)?;
38168 }
38169 Ok(())
38170 }
38171
38172 fn generate_where(&mut self, e: &Where) -> Result<()> {
38173 self.write_keyword("WHERE");
38175 self.write_space();
38176 self.generate_expression(&e.this)?;
38177 Ok(())
38178 }
38179
38180 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
38181 self.write_keyword("WIDTH_BUCKET");
38183 self.write("(");
38184 self.generate_expression(&e.this)?;
38185 if let Some(min_value) = &e.min_value {
38186 self.write(", ");
38187 self.generate_expression(min_value)?;
38188 }
38189 if let Some(max_value) = &e.max_value {
38190 self.write(", ");
38191 self.generate_expression(max_value)?;
38192 }
38193 if let Some(num_buckets) = &e.num_buckets {
38194 self.write(", ");
38195 self.generate_expression(num_buckets)?;
38196 }
38197 self.write(")");
38198 Ok(())
38199 }
38200
38201 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
38202 self.generate_window_spec(e)
38204 }
38205
38206 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
38207 let mut has_content = false;
38209
38210 if !e.partition_by.is_empty() {
38212 self.write_keyword("PARTITION BY");
38213 self.write_space();
38214 for (i, expr) in e.partition_by.iter().enumerate() {
38215 if i > 0 {
38216 self.write(", ");
38217 }
38218 self.generate_expression(expr)?;
38219 }
38220 has_content = true;
38221 }
38222
38223 if !e.order_by.is_empty() {
38225 if has_content {
38226 self.write_space();
38227 }
38228 self.write_keyword("ORDER BY");
38229 self.write_space();
38230 for (i, ordered) in e.order_by.iter().enumerate() {
38231 if i > 0 {
38232 self.write(", ");
38233 }
38234 self.generate_expression(&ordered.this)?;
38235 if ordered.desc {
38236 self.write_space();
38237 self.write_keyword("DESC");
38238 } else if ordered.explicit_asc {
38239 self.write_space();
38240 self.write_keyword("ASC");
38241 }
38242 if let Some(nulls_first) = ordered.nulls_first {
38243 self.write_space();
38244 self.write_keyword("NULLS");
38245 self.write_space();
38246 if nulls_first {
38247 self.write_keyword("FIRST");
38248 } else {
38249 self.write_keyword("LAST");
38250 }
38251 }
38252 }
38253 has_content = true;
38254 }
38255
38256 if let Some(frame) = &e.frame {
38258 if has_content {
38259 self.write_space();
38260 }
38261 self.generate_window_frame(frame)?;
38262 }
38263
38264 Ok(())
38265 }
38266
38267 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
38268 self.write_keyword("WITH");
38270 self.write_space();
38271 if e.no.is_some() {
38272 self.write_keyword("NO");
38273 self.write_space();
38274 }
38275 self.write_keyword("DATA");
38276
38277 if let Some(statistics) = &e.statistics {
38279 self.write_space();
38280 self.write_keyword("AND");
38281 self.write_space();
38282 match statistics.as_ref() {
38284 Expression::Boolean(b) if !b.value => {
38285 self.write_keyword("NO");
38286 self.write_space();
38287 }
38288 _ => {}
38289 }
38290 self.write_keyword("STATISTICS");
38291 }
38292 Ok(())
38293 }
38294
38295 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
38296 self.write_keyword("WITH FILL");
38298
38299 if let Some(from_) = &e.from_ {
38300 self.write_space();
38301 self.write_keyword("FROM");
38302 self.write_space();
38303 self.generate_expression(from_)?;
38304 }
38305
38306 if let Some(to) = &e.to {
38307 self.write_space();
38308 self.write_keyword("TO");
38309 self.write_space();
38310 self.generate_expression(to)?;
38311 }
38312
38313 if let Some(step) = &e.step {
38314 self.write_space();
38315 self.write_keyword("STEP");
38316 self.write_space();
38317 self.generate_expression(step)?;
38318 }
38319
38320 if let Some(staleness) = &e.staleness {
38321 self.write_space();
38322 self.write_keyword("STALENESS");
38323 self.write_space();
38324 self.generate_expression(staleness)?;
38325 }
38326
38327 if let Some(interpolate) = &e.interpolate {
38328 self.write_space();
38329 self.write_keyword("INTERPOLATE");
38330 self.write(" (");
38331 self.generate_interpolate_item(interpolate)?;
38333 self.write(")");
38334 }
38335
38336 Ok(())
38337 }
38338
38339 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
38341 match expr {
38342 Expression::Alias(alias) => {
38343 self.generate_identifier(&alias.alias)?;
38345 self.write_space();
38346 self.write_keyword("AS");
38347 self.write_space();
38348 self.generate_expression(&alias.this)?;
38349 }
38350 Expression::Tuple(tuple) => {
38351 for (i, item) in tuple.expressions.iter().enumerate() {
38352 if i > 0 {
38353 self.write(", ");
38354 }
38355 self.generate_interpolate_item(item)?;
38356 }
38357 }
38358 other => {
38359 self.generate_expression(other)?;
38360 }
38361 }
38362 Ok(())
38363 }
38364
38365 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
38366 self.write_keyword("WITH JOURNAL TABLE");
38368 self.write("=");
38369 self.generate_expression(&e.this)?;
38370 Ok(())
38371 }
38372
38373 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
38374 self.generate_expression(&e.this)?;
38376 self.write_space();
38377 self.write_keyword("WITH");
38378 self.write_space();
38379 self.write_keyword(&e.op);
38380 Ok(())
38381 }
38382
38383 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
38384 self.write_keyword("WITH");
38386 self.write_space();
38387 for (i, expr) in e.expressions.iter().enumerate() {
38388 if i > 0 {
38389 self.write(", ");
38390 }
38391 self.generate_expression(expr)?;
38392 }
38393 Ok(())
38394 }
38395
38396 fn generate_with_schema_binding_property(
38397 &mut self,
38398 e: &WithSchemaBindingProperty,
38399 ) -> Result<()> {
38400 self.write_keyword("WITH");
38402 self.write_space();
38403 self.generate_expression(&e.this)?;
38404 Ok(())
38405 }
38406
38407 fn generate_with_system_versioning_property(
38408 &mut self,
38409 e: &WithSystemVersioningProperty,
38410 ) -> Result<()> {
38411 let mut parts = Vec::new();
38417
38418 if let Some(this) = &e.this {
38419 let mut s = String::from("HISTORY_TABLE=");
38421 let mut gen = Generator::new();
38422 gen.generate_expression(this)?;
38423 s.push_str(&gen.output);
38424 parts.push(s);
38425 }
38426
38427 if let Some(data_consistency) = &e.data_consistency {
38428 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
38429 let mut gen = Generator::new();
38430 gen.generate_expression(data_consistency)?;
38431 s.push_str(&gen.output);
38432 parts.push(s);
38433 }
38434
38435 if let Some(retention_period) = &e.retention_period {
38436 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
38437 let mut gen = Generator::new();
38438 gen.generate_expression(retention_period)?;
38439 s.push_str(&gen.output);
38440 parts.push(s);
38441 }
38442
38443 self.write_keyword("SYSTEM_VERSIONING");
38444 self.write("=");
38445
38446 if !parts.is_empty() {
38447 self.write_keyword("ON");
38448 self.write("(");
38449 self.write(&parts.join(", "));
38450 self.write(")");
38451 } else if e.on.is_some() {
38452 self.write_keyword("ON");
38453 } else {
38454 self.write_keyword("OFF");
38455 }
38456
38457 if e.with_.is_some() {
38459 let inner = self.output.clone();
38460 self.output.clear();
38461 self.write("WITH(");
38462 self.write(&inner);
38463 self.write(")");
38464 }
38465
38466 Ok(())
38467 }
38468
38469 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
38470 self.write_keyword("WITH");
38472 self.write(" (");
38473 for (i, expr) in e.expressions.iter().enumerate() {
38474 if i > 0 {
38475 self.write(", ");
38476 }
38477 self.generate_expression(expr)?;
38478 }
38479 self.write(")");
38480 Ok(())
38481 }
38482
38483 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
38484 self.write_keyword("XMLELEMENT");
38487 self.write("(");
38488
38489 if e.evalname.is_some() {
38490 self.write_keyword("EVALNAME");
38491 } else {
38492 self.write_keyword("NAME");
38493 }
38494 self.write_space();
38495 self.generate_expression(&e.this)?;
38496
38497 for expr in &e.expressions {
38498 self.write(", ");
38499 self.generate_expression(expr)?;
38500 }
38501 self.write(")");
38502 Ok(())
38503 }
38504
38505 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
38506 self.write_keyword("XMLGET");
38508 self.write("(");
38509 self.generate_expression(&e.this)?;
38510 self.write(", ");
38511 self.generate_expression(&e.expression)?;
38512 if let Some(instance) = &e.instance {
38513 self.write(", ");
38514 self.generate_expression(instance)?;
38515 }
38516 self.write(")");
38517 Ok(())
38518 }
38519
38520 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
38521 self.generate_expression(&e.this)?;
38523 if let Some(expression) = &e.expression {
38524 self.write("(");
38525 self.generate_expression(expression)?;
38526 self.write(")");
38527 }
38528 Ok(())
38529 }
38530
38531 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
38532 self.write_keyword("XMLTABLE");
38534 self.write("(");
38535
38536 if self.config.pretty {
38537 self.indent_level += 1;
38538 self.write_newline();
38539 self.write_indent();
38540 self.generate_expression(&e.this)?;
38541
38542 if let Some(passing) = &e.passing {
38543 self.write_newline();
38544 self.write_indent();
38545 self.write_keyword("PASSING");
38546 if let Expression::Tuple(tuple) = passing.as_ref() {
38547 for expr in &tuple.expressions {
38548 self.write_newline();
38549 self.indent_level += 1;
38550 self.write_indent();
38551 self.generate_expression(expr)?;
38552 self.indent_level -= 1;
38553 }
38554 } else {
38555 self.write_newline();
38556 self.indent_level += 1;
38557 self.write_indent();
38558 self.generate_expression(passing)?;
38559 self.indent_level -= 1;
38560 }
38561 }
38562
38563 if e.by_ref.is_some() {
38564 self.write_newline();
38565 self.write_indent();
38566 self.write_keyword("RETURNING SEQUENCE BY REF");
38567 }
38568
38569 if !e.columns.is_empty() {
38570 self.write_newline();
38571 self.write_indent();
38572 self.write_keyword("COLUMNS");
38573 for (i, col) in e.columns.iter().enumerate() {
38574 self.write_newline();
38575 self.indent_level += 1;
38576 self.write_indent();
38577 self.generate_expression(col)?;
38578 self.indent_level -= 1;
38579 if i < e.columns.len() - 1 {
38580 self.write(",");
38581 }
38582 }
38583 }
38584
38585 self.indent_level -= 1;
38586 self.write_newline();
38587 self.write_indent();
38588 self.write(")");
38589 return Ok(());
38590 }
38591
38592 if let Some(namespaces) = &e.namespaces {
38594 self.write_keyword("XMLNAMESPACES");
38595 self.write("(");
38596 if let Expression::Tuple(tuple) = namespaces.as_ref() {
38598 for (i, expr) in tuple.expressions.iter().enumerate() {
38599 if i > 0 {
38600 self.write(", ");
38601 }
38602 if !matches!(expr, Expression::Alias(_)) {
38605 self.write_keyword("DEFAULT");
38606 self.write_space();
38607 }
38608 self.generate_expression(expr)?;
38609 }
38610 } else {
38611 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
38613 self.write_keyword("DEFAULT");
38614 self.write_space();
38615 }
38616 self.generate_expression(namespaces)?;
38617 }
38618 self.write("), ");
38619 }
38620
38621 self.generate_expression(&e.this)?;
38623
38624 if let Some(passing) = &e.passing {
38626 self.write_space();
38627 self.write_keyword("PASSING");
38628 self.write_space();
38629 if let Expression::Tuple(tuple) = passing.as_ref() {
38631 for (i, expr) in tuple.expressions.iter().enumerate() {
38632 if i > 0 {
38633 self.write(", ");
38634 }
38635 self.generate_expression(expr)?;
38636 }
38637 } else {
38638 self.generate_expression(passing)?;
38639 }
38640 }
38641
38642 if e.by_ref.is_some() {
38644 self.write_space();
38645 self.write_keyword("RETURNING SEQUENCE BY REF");
38646 }
38647
38648 if !e.columns.is_empty() {
38650 self.write_space();
38651 self.write_keyword("COLUMNS");
38652 self.write_space();
38653 for (i, col) in e.columns.iter().enumerate() {
38654 if i > 0 {
38655 self.write(", ");
38656 }
38657 self.generate_expression(col)?;
38658 }
38659 }
38660
38661 self.write(")");
38662 Ok(())
38663 }
38664
38665 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
38666 if let Some(this) = &e.this {
38669 self.generate_expression(this)?;
38670 if let Some(expression) = &e.expression {
38671 self.write_space();
38672 self.write_keyword("XOR");
38673 self.write_space();
38674 self.generate_expression(expression)?;
38675 }
38676 }
38677
38678 for (i, expr) in e.expressions.iter().enumerate() {
38680 if i > 0 || e.this.is_some() {
38681 self.write_space();
38682 self.write_keyword("XOR");
38683 self.write_space();
38684 }
38685 self.generate_expression(expr)?;
38686 }
38687 Ok(())
38688 }
38689
38690 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
38691 self.write_keyword("ZIPF");
38693 self.write("(");
38694 self.generate_expression(&e.this)?;
38695 if let Some(elementcount) = &e.elementcount {
38696 self.write(", ");
38697 self.generate_expression(elementcount)?;
38698 }
38699 if let Some(gen) = &e.gen {
38700 self.write(", ");
38701 self.generate_expression(gen)?;
38702 }
38703 self.write(")");
38704 Ok(())
38705 }
38706}
38707
38708impl Default for Generator {
38709 fn default() -> Self {
38710 Self::new()
38711 }
38712}
38713
38714#[cfg(test)]
38715mod tests {
38716 use super::*;
38717 use crate::parser::Parser;
38718
38719 fn roundtrip(sql: &str) -> String {
38720 let ast = Parser::parse_sql(sql).unwrap();
38721 Generator::sql(&ast[0]).unwrap()
38722 }
38723
38724 #[test]
38725 fn test_simple_select() {
38726 let result = roundtrip("SELECT 1");
38727 assert_eq!(result, "SELECT 1");
38728 }
38729
38730 #[test]
38731 fn test_select_from() {
38732 let result = roundtrip("SELECT a, b FROM t");
38733 assert_eq!(result, "SELECT a, b FROM t");
38734 }
38735
38736 #[test]
38737 fn test_select_where() {
38738 let result = roundtrip("SELECT * FROM t WHERE x = 1");
38739 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
38740 }
38741
38742 #[test]
38743 fn test_select_join() {
38744 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
38745 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
38746 }
38747
38748 #[test]
38749 fn test_insert() {
38750 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
38751 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
38752 }
38753
38754 #[test]
38755 fn test_pretty_print() {
38756 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
38757 let result = Generator::pretty_sql(&ast[0]).unwrap();
38758 assert!(result.contains('\n'));
38759 }
38760
38761 #[test]
38762 fn test_window_function() {
38763 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
38764 assert_eq!(
38765 result,
38766 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
38767 );
38768 }
38769
38770 #[test]
38771 fn test_window_function_with_frame() {
38772 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
38773 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
38774 }
38775
38776 #[test]
38777 fn test_aggregate_with_filter() {
38778 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
38779 assert_eq!(
38780 result,
38781 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
38782 );
38783 }
38784
38785 #[test]
38786 fn test_subscript() {
38787 let result = roundtrip("SELECT arr[0]");
38788 assert_eq!(result, "SELECT arr[0]");
38789 }
38790
38791 #[test]
38793 fn test_create_table() {
38794 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
38795 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
38796 }
38797
38798 #[test]
38799 fn test_create_table_with_constraints() {
38800 let result = roundtrip(
38801 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
38802 );
38803 assert_eq!(
38804 result,
38805 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
38806 );
38807 }
38808
38809 #[test]
38810 fn test_create_table_if_not_exists() {
38811 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
38812 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
38813 }
38814
38815 #[test]
38816 fn test_drop_table() {
38817 let result = roundtrip("DROP TABLE users");
38818 assert_eq!(result, "DROP TABLE users");
38819 }
38820
38821 #[test]
38822 fn test_drop_table_if_exists_cascade() {
38823 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
38824 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
38825 }
38826
38827 #[test]
38828 fn test_alter_table_add_column() {
38829 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
38830 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
38831 }
38832
38833 #[test]
38834 fn test_alter_table_drop_column() {
38835 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
38836 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
38837 }
38838
38839 #[test]
38840 fn test_create_index() {
38841 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
38842 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
38843 }
38844
38845 #[test]
38846 fn test_create_unique_index() {
38847 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
38848 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
38849 }
38850
38851 #[test]
38852 fn test_drop_index() {
38853 let result = roundtrip("DROP INDEX idx_name");
38854 assert_eq!(result, "DROP INDEX idx_name");
38855 }
38856
38857 #[test]
38858 fn test_create_view() {
38859 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
38860 assert_eq!(
38861 result,
38862 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
38863 );
38864 }
38865
38866 #[test]
38867 fn test_drop_view() {
38868 let result = roundtrip("DROP VIEW active_users");
38869 assert_eq!(result, "DROP VIEW active_users");
38870 }
38871
38872 #[test]
38873 fn test_truncate() {
38874 let result = roundtrip("TRUNCATE TABLE users");
38875 assert_eq!(result, "TRUNCATE TABLE users");
38876 }
38877
38878 #[test]
38879 fn test_string_literal_escaping_default() {
38880 let result = roundtrip("SELECT 'hello'");
38882 assert_eq!(result, "SELECT 'hello'");
38883
38884 let result = roundtrip("SELECT 'it''s a test'");
38886 assert_eq!(result, "SELECT 'it''s a test'");
38887 }
38888
38889 #[test]
38890 fn test_not_in_style_prefix_default_generic() {
38891 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
38892 assert_eq!(
38893 result,
38894 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
38895 );
38896 }
38897
38898 #[test]
38899 fn test_not_in_style_infix_generic_override() {
38900 let ast =
38901 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
38902 .unwrap();
38903 let config = GeneratorConfig {
38904 not_in_style: NotInStyle::Infix,
38905 ..Default::default()
38906 };
38907 let mut gen = Generator::with_config(config);
38908 let result = gen.generate(&ast[0]).unwrap();
38909 assert_eq!(
38910 result,
38911 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
38912 );
38913 }
38914
38915 #[test]
38916 fn test_string_literal_escaping_mysql() {
38917 use crate::dialects::DialectType;
38918
38919 let config = GeneratorConfig {
38920 dialect: Some(DialectType::MySQL),
38921 ..Default::default()
38922 };
38923
38924 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38925 let mut gen = Generator::with_config(config.clone());
38926 let result = gen.generate(&ast[0]).unwrap();
38927 assert_eq!(result, "SELECT 'hello'");
38928
38929 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38931 let mut gen = Generator::with_config(config.clone());
38932 let result = gen.generate(&ast[0]).unwrap();
38933 assert_eq!(result, "SELECT 'it''s'");
38934 }
38935
38936 #[test]
38937 fn test_string_literal_escaping_postgres() {
38938 use crate::dialects::DialectType;
38939
38940 let config = GeneratorConfig {
38941 dialect: Some(DialectType::PostgreSQL),
38942 ..Default::default()
38943 };
38944
38945 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38946 let mut gen = Generator::with_config(config.clone());
38947 let result = gen.generate(&ast[0]).unwrap();
38948 assert_eq!(result, "SELECT 'hello'");
38949
38950 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38952 let mut gen = Generator::with_config(config.clone());
38953 let result = gen.generate(&ast[0]).unwrap();
38954 assert_eq!(result, "SELECT 'it''s'");
38955 }
38956
38957 #[test]
38958 fn test_string_literal_escaping_bigquery() {
38959 use crate::dialects::DialectType;
38960
38961 let config = GeneratorConfig {
38962 dialect: Some(DialectType::BigQuery),
38963 ..Default::default()
38964 };
38965
38966 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38967 let mut gen = Generator::with_config(config.clone());
38968 let result = gen.generate(&ast[0]).unwrap();
38969 assert_eq!(result, "SELECT 'hello'");
38970
38971 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38973 let mut gen = Generator::with_config(config.clone());
38974 let result = gen.generate(&ast[0]).unwrap();
38975 assert_eq!(result, "SELECT 'it\\'s'");
38976 }
38977
38978 #[test]
38979 fn test_generate_deep_and_chain_without_stack_growth() {
38980 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
38981 Expression::column("c0"),
38982 Expression::number(0),
38983 )));
38984
38985 for i in 1..2500 {
38986 let predicate = Expression::Eq(Box::new(BinaryOp::new(
38987 Expression::column(format!("c{i}")),
38988 Expression::number(i as i64),
38989 )));
38990 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
38991 }
38992
38993 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
38994 assert!(sql.contains("c2499 = 2499"), "{}", sql);
38995 }
38996
38997 #[test]
38998 fn test_generate_deep_or_chain_without_stack_growth() {
38999 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
39000 Expression::column("c0"),
39001 Expression::number(0),
39002 )));
39003
39004 for i in 1..2500 {
39005 let predicate = Expression::Eq(Box::new(BinaryOp::new(
39006 Expression::column(format!("c{i}")),
39007 Expression::number(i as i64),
39008 )));
39009 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
39010 }
39011
39012 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
39013 assert!(sql.contains("c2499 = 2499"), "{}", sql);
39014 }
39015}