1use std::borrow::Cow;
14use std::sync::Arc;
15
16use crate::error::Result;
17use crate::expressions::*;
18use crate::guard::{enforce_generate_ast, ComplexityGuardOptions};
19use crate::DialectType;
20use serde::{Deserialize, Serialize};
21
22pub struct Generator {
47 config: Arc<GeneratorConfig>,
48 output: String,
49 unsupported_messages: Vec<String>,
50 indent_level: usize,
51 athena_hive_context: bool,
54 sqlite_inline_pk_columns: std::collections::HashSet<String>,
56 merge_strip_qualifiers: Vec<String>,
58 clickhouse_nullable_depth: i32,
63}
64
65#[derive(Debug, Clone, Copy, PartialEq, Default)]
71pub enum NormalizeFunctions {
72 #[default]
74 Upper,
75 Lower,
77 None,
79}
80
81#[derive(Debug, Clone, Copy, PartialEq, Default)]
83pub enum LimitFetchStyle {
84 #[default]
86 Limit,
87 Top,
89 FetchFirst,
91}
92
93#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
95pub enum NotInStyle {
96 #[default]
98 Prefix,
99 Infix,
101}
102
103#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
105#[serde(rename_all = "lowercase")]
106pub enum UnsupportedLevel {
107 Ignore,
109 #[default]
111 Warn,
112 Raise,
114 Immediate,
116}
117
118#[derive(Debug, Clone, Copy, PartialEq, Eq)]
119enum ConnectorOperator {
120 And,
121 Or,
122}
123
124impl ConnectorOperator {
125 fn keyword(self) -> &'static str {
126 match self {
127 Self::And => "AND",
128 Self::Or => "OR",
129 }
130 }
131}
132
133#[derive(Debug, Clone, Copy, PartialEq)]
135pub struct IdentifierQuoteStyle {
136 pub start: char,
138 pub end: char,
140}
141
142impl Default for IdentifierQuoteStyle {
143 fn default() -> Self {
144 Self {
145 start: '"',
146 end: '"',
147 }
148 }
149}
150
151impl IdentifierQuoteStyle {
152 pub const DOUBLE_QUOTE: Self = Self {
154 start: '"',
155 end: '"',
156 };
157 pub const BACKTICK: Self = Self {
159 start: '`',
160 end: '`',
161 };
162 pub const BRACKET: Self = Self {
164 start: '[',
165 end: ']',
166 };
167}
168
169#[derive(Debug, Clone)]
191pub struct GeneratorConfig {
192 pub pretty: bool,
195 pub indent: &'static str,
197 pub max_text_width: usize,
199 pub identifier_quote: char,
201 pub identifier_quote_style: IdentifierQuoteStyle,
203 pub uppercase_keywords: bool,
205 pub normalize_identifiers: bool,
207 pub dialect: Option<crate::dialects::DialectType>,
209 pub source_dialect: Option<crate::dialects::DialectType>,
211 pub unsupported_level: UnsupportedLevel,
213 pub max_unsupported: usize,
215 pub complexity_guard: ComplexityGuardOptions,
217 pub normalize_functions: NormalizeFunctions,
219 pub string_escape: char,
221 pub case_sensitive_identifiers: bool,
223 pub identifiers_can_start_with_digit: bool,
225 pub always_quote_identifiers: bool,
228 pub not_in_style: NotInStyle,
230
231 pub null_ordering_supported: bool,
235 pub ignore_nulls_in_func: bool,
238 pub nvl2_supported: bool,
240
241 pub limit_fetch_style: LimitFetchStyle,
244 pub limit_is_top: bool,
246 pub limit_only_literals: bool,
248
249 pub single_string_interval: bool,
252 pub interval_allows_plural_form: bool,
254
255 pub cte_recursive_keyword_required: bool,
258
259 pub values_as_table: bool,
262 pub wrap_derived_values: bool,
264
265 pub tablesample_seed_keyword: &'static str,
268 pub tablesample_requires_parens: bool,
270 pub tablesample_size_is_rows: bool,
272 pub tablesample_keywords: &'static str,
274 pub tablesample_with_method: bool,
276 pub alias_post_tablesample: bool,
278
279 pub aggregate_filter_supported: bool,
282 pub multi_arg_distinct: bool,
284 pub quantified_no_paren_space: bool,
286 pub supports_median: bool,
288
289 pub supports_select_into: bool,
292 pub locking_reads_supported: bool,
294
295 pub rename_table_with_db: bool,
298 pub semi_anti_join_with_side: bool,
300 pub supports_table_alias_columns: bool,
302 pub join_hints: bool,
304 pub table_hints: bool,
306 pub query_hints: bool,
308 pub query_hint_sep: &'static str,
310 pub supports_column_join_marks: bool,
312
313 pub index_using_no_space: bool,
317 pub supports_unlogged_tables: bool,
319 pub supports_create_table_like: bool,
321 pub like_property_inside_schema: bool,
323 pub alter_table_include_column_keyword: bool,
325 pub supports_table_copy: bool,
327 pub alter_set_type: &'static str,
329 pub alter_set_wrapped: bool,
331
332 pub tz_to_with_time_zone: bool,
335 pub supports_convert_timezone: bool,
337
338 pub json_type_required_for_extraction: bool,
341 pub json_path_bracketed_key_supported: bool,
343 pub json_path_single_quote_escape: bool,
345 pub quote_json_path: bool,
347 pub json_key_value_pair_sep: &'static str,
349
350 pub copy_params_are_wrapped: bool,
353 pub copy_params_eq_required: bool,
355 pub copy_has_into_keyword: bool,
357
358 pub supports_window_exclude: bool,
361 pub unnest_with_ordinality: bool,
363 pub lowercase_window_frame_keywords: bool,
366 pub normalize_window_frame_between: bool,
369
370 pub array_concat_is_var_len: bool,
373 pub array_size_dim_required: Option<bool>,
376 pub can_implement_array_any: bool,
378 pub array_size_name: &'static str,
380
381 pub supports_between_flags: bool,
384
385 pub is_bool_allowed: bool,
388 pub ensure_bools: bool,
390
391 pub extract_allows_quotes: bool,
394 pub normalize_extract_date_parts: bool,
396
397 pub try_supported: bool,
400 pub supports_uescape: bool,
402 pub supports_to_number: bool,
404 pub supports_single_arg_concat: bool,
406 pub last_day_supports_date_part: bool,
408 pub supports_exploding_projections: bool,
410 pub supports_unix_seconds: bool,
412 pub supports_like_quantifiers: bool,
414 pub supports_decode_case: bool,
416 pub set_op_modifiers: bool,
418 pub update_statement_supports_from: bool,
420
421 pub collate_is_func: bool,
424
425 pub duplicate_key_update_with_set: bool,
428 pub insert_overwrite: &'static str,
430
431 pub returning_end: bool,
434
435 pub matched_by_source: bool,
438
439 pub create_function_return_as: bool,
442 pub parameter_default_equals: bool,
444
445 pub computed_column_with_type: bool,
448
449 pub unpivot_aliases_are_identifiers: bool,
452
453 pub star_except: &'static str,
456
457 pub hex_func: &'static str,
460
461 pub with_properties_prefix: &'static str,
464
465 pub pad_fill_pattern_is_required: bool,
468
469 pub index_on: &'static str,
472
473 pub groupings_sep: &'static str,
476
477 pub struct_delimiter: (&'static str, &'static str),
480 pub struct_curly_brace_notation: bool,
482 pub array_bracket_only: bool,
484 pub struct_field_sep: &'static str,
486
487 pub except_intersect_support_all_clause: bool,
490
491 pub parameter_token: &'static str,
494 pub named_placeholder_token: &'static str,
496
497 pub data_type_specifiers_allowed: bool,
500
501 pub schema_comment_with_eq: bool,
505}
506
507impl Default for GeneratorConfig {
508 fn default() -> Self {
509 Self {
510 pretty: false,
512 indent: " ",
513 max_text_width: 80,
514 identifier_quote: '"',
515 identifier_quote_style: IdentifierQuoteStyle::DOUBLE_QUOTE,
516 uppercase_keywords: true,
517 normalize_identifiers: false,
518 dialect: None,
519 source_dialect: None,
520 unsupported_level: UnsupportedLevel::Warn,
521 max_unsupported: 3,
522 complexity_guard: ComplexityGuardOptions::default(),
523 normalize_functions: NormalizeFunctions::Upper,
524 string_escape: '\'',
525 case_sensitive_identifiers: false,
526 identifiers_can_start_with_digit: false,
527 always_quote_identifiers: false,
528 not_in_style: NotInStyle::Prefix,
529
530 null_ordering_supported: true,
532 ignore_nulls_in_func: false,
533 nvl2_supported: true,
534
535 limit_fetch_style: LimitFetchStyle::Limit,
537 limit_is_top: false,
538 limit_only_literals: false,
539
540 single_string_interval: false,
542 interval_allows_plural_form: true,
543
544 cte_recursive_keyword_required: true,
546
547 values_as_table: true,
549 wrap_derived_values: true,
550
551 tablesample_seed_keyword: "SEED",
553 tablesample_requires_parens: true,
554 tablesample_size_is_rows: true,
555 tablesample_keywords: "TABLESAMPLE",
556 tablesample_with_method: true,
557 alias_post_tablesample: false,
558
559 aggregate_filter_supported: true,
561 multi_arg_distinct: true,
562 quantified_no_paren_space: false,
563 supports_median: true,
564
565 supports_select_into: false,
567 locking_reads_supported: true,
568
569 rename_table_with_db: true,
571 semi_anti_join_with_side: true,
572 supports_table_alias_columns: true,
573 join_hints: true,
574 table_hints: true,
575 query_hints: true,
576 query_hint_sep: ", ",
577 supports_column_join_marks: false,
578
579 index_using_no_space: false,
581 supports_unlogged_tables: false,
582 supports_create_table_like: true,
583 like_property_inside_schema: false,
584 alter_table_include_column_keyword: true,
585 supports_table_copy: true,
586 alter_set_type: "SET DATA TYPE",
587 alter_set_wrapped: false,
588
589 tz_to_with_time_zone: false,
591 supports_convert_timezone: false,
592
593 json_type_required_for_extraction: false,
595 json_path_bracketed_key_supported: true,
596 json_path_single_quote_escape: false,
597 quote_json_path: true,
598 json_key_value_pair_sep: ":",
599
600 copy_params_are_wrapped: true,
602 copy_params_eq_required: false,
603 copy_has_into_keyword: true,
604
605 supports_window_exclude: false,
607 unnest_with_ordinality: true,
608 lowercase_window_frame_keywords: false,
609 normalize_window_frame_between: false,
610
611 array_concat_is_var_len: true,
613 array_size_dim_required: None,
614 can_implement_array_any: false,
615 array_size_name: "ARRAY_LENGTH",
616
617 supports_between_flags: false,
619
620 is_bool_allowed: true,
622 ensure_bools: false,
623
624 extract_allows_quotes: true,
626 normalize_extract_date_parts: false,
627
628 try_supported: true,
630 supports_uescape: true,
631 supports_to_number: true,
632 supports_single_arg_concat: true,
633 last_day_supports_date_part: true,
634 supports_exploding_projections: true,
635 supports_unix_seconds: false,
636 supports_like_quantifiers: true,
637 supports_decode_case: true,
638 set_op_modifiers: true,
639 update_statement_supports_from: true,
640
641 collate_is_func: false,
643
644 duplicate_key_update_with_set: true,
646 insert_overwrite: " OVERWRITE TABLE",
647
648 returning_end: true,
650
651 matched_by_source: true,
653
654 create_function_return_as: true,
656 parameter_default_equals: false,
657
658 computed_column_with_type: true,
660
661 unpivot_aliases_are_identifiers: true,
663
664 star_except: "EXCEPT",
666
667 hex_func: "HEX",
669
670 with_properties_prefix: "WITH",
672
673 pad_fill_pattern_is_required: false,
675
676 index_on: "ON",
678
679 groupings_sep: ",",
681
682 struct_delimiter: ("<", ">"),
684 struct_curly_brace_notation: false,
685 array_bracket_only: false,
686 struct_field_sep: " ",
687
688 except_intersect_support_all_clause: true,
690
691 parameter_token: "@",
693 named_placeholder_token: ":",
694
695 data_type_specifiers_allowed: false,
697
698 schema_comment_with_eq: true,
700 }
701 }
702}
703
704mod reserved_keywords {
707 use std::collections::HashSet;
708 use std::sync::LazyLock;
709
710 pub static SQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
712 [
713 "all",
714 "alter",
715 "and",
716 "any",
717 "array",
718 "as",
719 "asc",
720 "at",
721 "authorization",
722 "begin",
723 "between",
724 "both",
725 "by",
726 "case",
727 "cast",
728 "check",
729 "collate",
730 "column",
731 "commit",
732 "constraint",
733 "create",
734 "cross",
735 "cube",
736 "current",
737 "current_date",
738 "current_time",
739 "current_timestamp",
740 "current_user",
741 "default",
742 "delete",
743 "desc",
744 "distinct",
745 "drop",
746 "else",
747 "end",
748 "escape",
749 "except",
750 "execute",
751 "exists",
752 "external",
753 "false",
754 "fetch",
755 "filter",
756 "for",
757 "foreign",
758 "from",
759 "full",
760 "function",
761 "grant",
762 "group",
763 "grouping",
764 "having",
765 "if",
766 "in",
767 "index",
768 "inner",
769 "insert",
770 "intersect",
771 "interval",
772 "into",
773 "is",
774 "join",
775 "key",
776 "leading",
777 "left",
778 "like",
779 "limit",
780 "local",
781 "localtime",
782 "localtimestamp",
783 "match",
784 "merge",
785 "natural",
786 "no",
787 "not",
788 "null",
789 "of",
790 "offset",
791 "on",
792 "only",
793 "or",
794 "order",
795 "outer",
796 "over",
797 "partition",
798 "primary",
799 "procedure",
800 "range",
801 "references",
802 "right",
803 "rollback",
804 "rollup",
805 "row",
806 "rows",
807 "select",
808 "session_user",
809 "set",
810 "some",
811 "table",
812 "tablesample",
813 "then",
814 "to",
815 "trailing",
816 "true",
817 "truncate",
818 "union",
819 "unique",
820 "unknown",
821 "update",
822 "user",
823 "using",
824 "values",
825 "view",
826 "when",
827 "where",
828 "window",
829 "with",
830 ]
831 .into_iter()
832 .collect()
833 });
834
835 pub static BIGQUERY_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
838 let mut set = SQL_RESERVED.clone();
839 set.extend([
840 "assert_rows_modified",
841 "at",
842 "contains",
843 "cube",
844 "current",
845 "define",
846 "enum",
847 "escape",
848 "exclude",
849 "following",
850 "for",
851 "groups",
852 "hash",
853 "ignore",
854 "lateral",
855 "lookup",
856 "new",
857 "no",
858 "nulls",
859 "of",
860 "over",
861 "preceding",
862 "proto",
863 "qualify",
864 "recursive",
865 "respect",
866 "struct",
867 "tablesample",
868 "treat",
869 "unbounded",
870 "unnest",
871 "window",
872 "within",
873 ]);
874 set.remove("grant");
876 set.remove("key");
877 set.remove("index");
878 set.remove("offset");
879 set.remove("values");
880 set.remove("table");
881 set
882 });
883
884 pub static MYSQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
886 let mut set = SQL_RESERVED.clone();
887 set.extend([
888 "accessible",
889 "add",
890 "analyze",
891 "asensitive",
892 "before",
893 "bigint",
894 "binary",
895 "blob",
896 "call",
897 "cascade",
898 "change",
899 "char",
900 "character",
901 "condition",
902 "continue",
903 "convert",
904 "current_date",
905 "current_time",
906 "current_timestamp",
907 "current_user",
908 "cursor",
909 "database",
910 "databases",
911 "day_hour",
912 "day_microsecond",
913 "day_minute",
914 "day_second",
915 "dec",
916 "decimal",
917 "declare",
918 "delayed",
919 "describe",
920 "deterministic",
921 "distinctrow",
922 "div",
923 "double",
924 "dual",
925 "each",
926 "elseif",
927 "enclosed",
928 "escaped",
929 "exit",
930 "explain",
931 "float",
932 "float4",
933 "float8",
934 "force",
935 "get",
936 "high_priority",
937 "hour_microsecond",
938 "hour_minute",
939 "hour_second",
940 "ignore",
941 "infile",
942 "inout",
943 "insensitive",
944 "int",
945 "int1",
946 "int2",
947 "int3",
948 "int4",
949 "int8",
950 "integer",
951 "iterate",
952 "keys",
953 "kill",
954 "leave",
955 "linear",
956 "lines",
957 "load",
958 "lock",
959 "long",
960 "longblob",
961 "longtext",
962 "loop",
963 "low_priority",
964 "master_ssl_verify_server_cert",
965 "maxvalue",
966 "mediumblob",
967 "mediumint",
968 "mediumtext",
969 "middleint",
970 "minute_microsecond",
971 "minute_second",
972 "mod",
973 "modifies",
974 "no_write_to_binlog",
975 "numeric",
976 "optimize",
977 "option",
978 "optionally",
979 "out",
980 "outfile",
981 "precision",
982 "purge",
983 "read",
984 "reads",
985 "real",
986 "regexp",
987 "release",
988 "rename",
989 "repeat",
990 "replace",
991 "require",
992 "resignal",
993 "restrict",
994 "return",
995 "revoke",
996 "rlike",
997 "schema",
998 "schemas",
999 "second_microsecond",
1000 "sensitive",
1001 "separator",
1002 "show",
1003 "signal",
1004 "smallint",
1005 "spatial",
1006 "specific",
1007 "sql",
1008 "sql_big_result",
1009 "sql_calc_found_rows",
1010 "sql_small_result",
1011 "sqlexception",
1012 "sqlstate",
1013 "sqlwarning",
1014 "ssl",
1015 "starting",
1016 "straight_join",
1017 "terminated",
1018 "text",
1019 "tinyblob",
1020 "tinyint",
1021 "tinytext",
1022 "trigger",
1023 "undo",
1024 "unlock",
1025 "unsigned",
1026 "usage",
1027 "utc_date",
1028 "utc_time",
1029 "utc_timestamp",
1030 "varbinary",
1031 "varchar",
1032 "varcharacter",
1033 "varying",
1034 "while",
1035 "write",
1036 "xor",
1037 "year_month",
1038 "zerofill",
1039 ]);
1040 set.remove("table");
1041 set
1042 });
1043
1044 pub static DORIS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1047 let mut set = MYSQL_RESERVED.clone();
1048 set.extend([
1049 "aggregate",
1050 "anti",
1051 "array",
1052 "backend",
1053 "backup",
1054 "begin",
1055 "bitmap",
1056 "boolean",
1057 "broker",
1058 "buckets",
1059 "cached",
1060 "cancel",
1061 "cast",
1062 "catalog",
1063 "charset",
1064 "cluster",
1065 "collation",
1066 "columns",
1067 "comment",
1068 "commit",
1069 "config",
1070 "connection",
1071 "count",
1072 "current",
1073 "data",
1074 "date",
1075 "datetime",
1076 "day",
1077 "deferred",
1078 "distributed",
1079 "dynamic",
1080 "enable",
1081 "end",
1082 "events",
1083 "export",
1084 "external",
1085 "fields",
1086 "first",
1087 "follower",
1088 "format",
1089 "free",
1090 "frontend",
1091 "full",
1092 "functions",
1093 "global",
1094 "grants",
1095 "hash",
1096 "help",
1097 "hour",
1098 "install",
1099 "intermediate",
1100 "json",
1101 "label",
1102 "last",
1103 "less",
1104 "level",
1105 "link",
1106 "local",
1107 "location",
1108 "max",
1109 "merge",
1110 "min",
1111 "minute",
1112 "modify",
1113 "month",
1114 "name",
1115 "names",
1116 "negative",
1117 "nulls",
1118 "observer",
1119 "offset",
1120 "only",
1121 "open",
1122 "overwrite",
1123 "password",
1124 "path",
1125 "plan",
1126 "plugin",
1127 "plugins",
1128 "policy",
1129 "process",
1130 "properties",
1131 "property",
1132 "query",
1133 "quota",
1134 "recover",
1135 "refresh",
1136 "repair",
1137 "replica",
1138 "repository",
1139 "resource",
1140 "restore",
1141 "resume",
1142 "role",
1143 "roles",
1144 "rollback",
1145 "rollup",
1146 "routine",
1147 "sample",
1148 "second",
1149 "semi",
1150 "session",
1151 "signed",
1152 "snapshot",
1153 "start",
1154 "stats",
1155 "status",
1156 "stop",
1157 "stream",
1158 "string",
1159 "sum",
1160 "tables",
1161 "tablet",
1162 "temporary",
1163 "text",
1164 "timestamp",
1165 "transaction",
1166 "trash",
1167 "trim",
1168 "truncate",
1169 "type",
1170 "user",
1171 "value",
1172 "variables",
1173 "verbose",
1174 "version",
1175 "view",
1176 "warnings",
1177 "week",
1178 "work",
1179 "year",
1180 ]);
1181 set
1182 });
1183
1184 pub static POSTGRES_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1186 let mut set = SQL_RESERVED.clone();
1187 set.extend([
1188 "analyse",
1189 "analyze",
1190 "asymmetric",
1191 "binary",
1192 "collation",
1193 "concurrently",
1194 "current_catalog",
1195 "current_role",
1196 "current_schema",
1197 "deferrable",
1198 "do",
1199 "freeze",
1200 "ilike",
1201 "initially",
1202 "isnull",
1203 "lateral",
1204 "notnull",
1205 "placing",
1206 "returning",
1207 "similar",
1208 "symmetric",
1209 "variadic",
1210 "verbose",
1211 ]);
1212 set.remove("default");
1214 set.remove("interval");
1215 set.remove("match");
1216 set.remove("offset");
1217 set.remove("table");
1218 set
1219 });
1220
1221 pub static REDSHIFT_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1225 [
1226 "aes128",
1227 "aes256",
1228 "all",
1229 "allowoverwrite",
1230 "analyse",
1231 "analyze",
1232 "and",
1233 "any",
1234 "array",
1235 "as",
1236 "asc",
1237 "authorization",
1238 "az64",
1239 "backup",
1240 "between",
1241 "binary",
1242 "blanksasnull",
1243 "both",
1244 "bytedict",
1245 "bzip2",
1246 "case",
1247 "cast",
1248 "check",
1249 "collate",
1250 "column",
1251 "constraint",
1252 "create",
1253 "credentials",
1254 "cross",
1255 "current_date",
1256 "current_time",
1257 "current_timestamp",
1258 "current_user",
1259 "current_user_id",
1260 "default",
1261 "deferrable",
1262 "deflate",
1263 "defrag",
1264 "delta",
1265 "delta32k",
1266 "desc",
1267 "disable",
1268 "distinct",
1269 "do",
1270 "else",
1271 "emptyasnull",
1272 "enable",
1273 "encode",
1274 "encrypt",
1275 "encryption",
1276 "end",
1277 "except",
1278 "explicit",
1279 "false",
1280 "for",
1281 "foreign",
1282 "freeze",
1283 "from",
1284 "full",
1285 "globaldict256",
1286 "globaldict64k",
1287 "grant",
1288 "group",
1289 "gzip",
1290 "having",
1291 "identity",
1292 "ignore",
1293 "ilike",
1294 "in",
1295 "initially",
1296 "inner",
1297 "intersect",
1298 "interval",
1299 "into",
1300 "is",
1301 "isnull",
1302 "join",
1303 "leading",
1304 "left",
1305 "like",
1306 "limit",
1307 "localtime",
1308 "localtimestamp",
1309 "lun",
1310 "luns",
1311 "lzo",
1312 "lzop",
1313 "minus",
1314 "mostly16",
1315 "mostly32",
1316 "mostly8",
1317 "natural",
1318 "new",
1319 "not",
1320 "notnull",
1321 "null",
1322 "nulls",
1323 "off",
1324 "offline",
1325 "offset",
1326 "oid",
1327 "old",
1328 "on",
1329 "only",
1330 "open",
1331 "or",
1332 "order",
1333 "outer",
1334 "overlaps",
1335 "parallel",
1336 "partition",
1337 "percent",
1338 "permissions",
1339 "pivot",
1340 "placing",
1341 "primary",
1342 "raw",
1343 "readratio",
1344 "recover",
1345 "references",
1346 "rejectlog",
1347 "resort",
1348 "respect",
1349 "restore",
1350 "right",
1351 "select",
1352 "session_user",
1353 "similar",
1354 "snapshot",
1355 "some",
1356 "sysdate",
1357 "system",
1358 "table",
1359 "tag",
1360 "tdes",
1361 "text255",
1362 "text32k",
1363 "then",
1364 "timestamp",
1365 "to",
1366 "top",
1367 "trailing",
1368 "true",
1369 "truncatecolumns",
1370 "type",
1371 "union",
1372 "unique",
1373 "unnest",
1374 "unpivot",
1375 "user",
1376 "using",
1377 "verbose",
1378 "wallet",
1379 "when",
1380 "where",
1381 "with",
1382 "without",
1383 ]
1384 .into_iter()
1385 .collect()
1386 });
1387
1388 pub static DUCKDB_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1390 let mut set = POSTGRES_RESERVED.clone();
1391 set.extend([
1392 "anti",
1393 "asof",
1394 "columns",
1395 "describe",
1396 "groups",
1397 "macro",
1398 "pivot",
1399 "pivot_longer",
1400 "pivot_wider",
1401 "qualify",
1402 "replace",
1403 "respect",
1404 "semi",
1405 "show",
1406 "table",
1407 "unpivot",
1408 ]);
1409 set.remove("at");
1410 set.remove("key");
1411 set.remove("range");
1412 set.remove("row");
1413 set.remove("values");
1414 set
1415 });
1416
1417 pub static PRESTO_TRINO_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1419 let mut set = SQL_RESERVED.clone();
1420 set.extend([
1421 "alter",
1422 "and",
1423 "as",
1424 "between",
1425 "by",
1426 "case",
1427 "cast",
1428 "constraint",
1429 "create",
1430 "cross",
1431 "cube",
1432 "current_catalog",
1433 "current_date",
1434 "current_path",
1435 "current_role",
1436 "current_schema",
1437 "current_time",
1438 "current_timestamp",
1439 "current_user",
1440 "deallocate",
1441 "delete",
1442 "describe",
1443 "distinct",
1444 "drop",
1445 "else",
1446 "end",
1447 "escape",
1448 "except",
1449 "execute",
1450 "exists",
1451 "extract",
1452 "false",
1453 "for",
1454 "from",
1455 "full",
1456 "group",
1457 "grouping",
1458 "having",
1459 "in",
1460 "inner",
1461 "insert",
1462 "intersect",
1463 "into",
1464 "is",
1465 "join",
1466 "json_array",
1467 "json_exists",
1468 "json_object",
1469 "json_query",
1470 "json_table",
1471 "json_value",
1472 "left",
1473 "like",
1474 "listagg",
1475 "localtime",
1476 "localtimestamp",
1477 "natural",
1478 "normalize",
1479 "not",
1480 "null",
1481 "on",
1482 "or",
1483 "order",
1484 "outer",
1485 "prepare",
1486 "recursive",
1487 "right",
1488 "rollup",
1489 "select",
1490 "skip",
1491 "table",
1492 "then",
1493 "trim",
1494 "true",
1495 "uescape",
1496 "union",
1497 "unnest",
1498 "using",
1499 "values",
1500 "when",
1501 "where",
1502 "with",
1503 ]);
1504 set.remove("key");
1506 set
1507 });
1508
1509 pub static STARROCKS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1512 [
1513 "add",
1514 "all",
1515 "alter",
1516 "analyze",
1517 "and",
1518 "array",
1519 "as",
1520 "asc",
1521 "between",
1522 "bigint",
1523 "bitmap",
1524 "both",
1525 "by",
1526 "case",
1527 "char",
1528 "character",
1529 "check",
1530 "collate",
1531 "column",
1532 "compaction",
1533 "convert",
1534 "create",
1535 "cross",
1536 "cube",
1537 "current_date",
1538 "current_role",
1539 "current_time",
1540 "current_timestamp",
1541 "current_user",
1542 "database",
1543 "databases",
1544 "decimal",
1545 "decimalv2",
1546 "decimal32",
1547 "decimal64",
1548 "decimal128",
1549 "default",
1550 "deferred",
1551 "delete",
1552 "dense_rank",
1553 "desc",
1554 "describe",
1555 "distinct",
1556 "double",
1557 "drop",
1558 "dual",
1559 "else",
1560 "except",
1561 "exists",
1562 "explain",
1563 "false",
1564 "first_value",
1565 "float",
1566 "for",
1567 "force",
1568 "from",
1569 "full",
1570 "function",
1571 "grant",
1572 "group",
1573 "grouping",
1574 "grouping_id",
1575 "groups",
1576 "having",
1577 "hll",
1578 "host",
1579 "if",
1580 "ignore",
1581 "immediate",
1582 "in",
1583 "index",
1584 "infile",
1585 "inner",
1586 "insert",
1587 "int",
1588 "integer",
1589 "intersect",
1590 "into",
1591 "is",
1592 "join",
1593 "json",
1594 "key",
1595 "keys",
1596 "kill",
1597 "lag",
1598 "largeint",
1599 "last_value",
1600 "lateral",
1601 "lead",
1602 "left",
1603 "like",
1604 "limit",
1605 "load",
1606 "localtime",
1607 "localtimestamp",
1608 "maxvalue",
1609 "minus",
1610 "mod",
1611 "not",
1612 "ntile",
1613 "null",
1614 "on",
1615 "or",
1616 "order",
1617 "outer",
1618 "outfile",
1619 "over",
1620 "partition",
1621 "percentile",
1622 "primary",
1623 "procedure",
1624 "qualify",
1625 "range",
1626 "rank",
1627 "read",
1628 "regexp",
1629 "release",
1630 "rename",
1631 "replace",
1632 "revoke",
1633 "right",
1634 "rlike",
1635 "row",
1636 "row_number",
1637 "rows",
1638 "schema",
1639 "schemas",
1640 "select",
1641 "set",
1642 "set_var",
1643 "show",
1644 "smallint",
1645 "system",
1646 "table",
1647 "terminated",
1648 "text",
1649 "then",
1650 "tinyint",
1651 "to",
1652 "true",
1653 "union",
1654 "unique",
1655 "unsigned",
1656 "update",
1657 "use",
1658 "using",
1659 "values",
1660 "varchar",
1661 "when",
1662 "where",
1663 "with",
1664 ]
1665 .into_iter()
1666 .collect()
1667 });
1668
1669 pub static SINGLESTORE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1672 let mut set = MYSQL_RESERVED.clone();
1673 set.extend([
1674 "abs",
1677 "account",
1678 "acos",
1679 "adddate",
1680 "addtime",
1681 "admin",
1682 "aes_decrypt",
1683 "aes_encrypt",
1684 "aggregate",
1685 "aggregates",
1686 "aggregator",
1687 "anti_join",
1688 "any_value",
1689 "approx_count_distinct",
1690 "approx_percentile",
1691 "arrange",
1692 "arrangement",
1693 "asin",
1694 "atan",
1695 "atan2",
1696 "attach",
1697 "autostats",
1698 "avro",
1699 "background",
1700 "backup",
1701 "batch",
1702 "batches",
1703 "boot_strapping",
1704 "ceil",
1705 "ceiling",
1706 "coercibility",
1707 "columnar",
1708 "columnstore",
1709 "compile",
1710 "concurrent",
1711 "connection_id",
1712 "cos",
1713 "cot",
1714 "current_security_groups",
1715 "current_security_roles",
1716 "dayname",
1717 "dayofmonth",
1718 "dayofweek",
1719 "dayofyear",
1720 "degrees",
1721 "dot_product",
1722 "dump",
1723 "durability",
1724 "earliest",
1725 "echo",
1726 "election",
1727 "euclidean_distance",
1728 "exp",
1729 "extractor",
1730 "extractors",
1731 "floor",
1732 "foreground",
1733 "found_rows",
1734 "from_base64",
1735 "from_days",
1736 "from_unixtime",
1737 "fs",
1738 "fulltext",
1739 "gc",
1740 "gcs",
1741 "geography",
1742 "geography_area",
1743 "geography_contains",
1744 "geography_distance",
1745 "geography_intersects",
1746 "geography_latitude",
1747 "geography_length",
1748 "geography_longitude",
1749 "geographypoint",
1750 "geography_point",
1751 "geography_within_distance",
1752 "geometry",
1753 "geometry_area",
1754 "geometry_contains",
1755 "geometry_distance",
1756 "geometry_filter",
1757 "geometry_intersects",
1758 "geometry_length",
1759 "geometrypoint",
1760 "geometry_point",
1761 "geometry_within_distance",
1762 "geometry_x",
1763 "geometry_y",
1764 "greatest",
1765 "groups",
1766 "group_concat",
1767 "gzip",
1768 "hdfs",
1769 "hex",
1770 "highlight",
1771 "ifnull",
1772 "ilike",
1773 "inet_aton",
1774 "inet_ntoa",
1775 "inet6_aton",
1776 "inet6_ntoa",
1777 "initcap",
1778 "instr",
1779 "interpreter_mode",
1780 "isnull",
1781 "json",
1782 "json_agg",
1783 "json_array_contains_double",
1784 "json_array_contains_json",
1785 "json_array_contains_string",
1786 "json_delete_key",
1787 "json_extract_double",
1788 "json_extract_json",
1789 "json_extract_string",
1790 "json_extract_bigint",
1791 "json_get_type",
1792 "json_length",
1793 "json_set_double",
1794 "json_set_json",
1795 "json_set_string",
1796 "kafka",
1797 "lag",
1798 "last_day",
1799 "last_insert_id",
1800 "latest",
1801 "lcase",
1802 "lead",
1803 "leaf",
1804 "least",
1805 "leaves",
1806 "length",
1807 "license",
1808 "links",
1809 "llvm",
1810 "ln",
1811 "load",
1812 "locate",
1813 "log",
1814 "log10",
1815 "log2",
1816 "lpad",
1817 "lz4",
1818 "management",
1819 "match",
1820 "mbc",
1821 "md5",
1822 "median",
1823 "memsql",
1824 "memsql_deserialize",
1825 "memsql_serialize",
1826 "metadata",
1827 "microsecond",
1828 "minute",
1829 "model",
1830 "monthname",
1831 "months_between",
1832 "mpl",
1833 "namespace",
1834 "node",
1835 "noparam",
1836 "now",
1837 "nth_value",
1838 "ntile",
1839 "nullcols",
1840 "nullif",
1841 "object",
1842 "octet_length",
1843 "offsets",
1844 "online",
1845 "optimizer",
1846 "orphan",
1847 "parquet",
1848 "partitions",
1849 "pause",
1850 "percentile_cont",
1851 "percentile_disc",
1852 "periodic",
1853 "persisted",
1854 "pi",
1855 "pipeline",
1856 "pipelines",
1857 "plancache",
1858 "plugins",
1859 "pool",
1860 "pools",
1861 "pow",
1862 "power",
1863 "process",
1864 "processlist",
1865 "profile",
1866 "profiles",
1867 "quarter",
1868 "queries",
1869 "query",
1870 "radians",
1871 "rand",
1872 "record",
1873 "reduce",
1874 "redundancy",
1875 "regexp_match",
1876 "regexp_substr",
1877 "remote",
1878 "replication",
1879 "resource",
1880 "resource_pool",
1881 "restore",
1882 "retry",
1883 "role",
1884 "roles",
1885 "round",
1886 "rpad",
1887 "rtrim",
1888 "running",
1889 "s3",
1890 "scalar",
1891 "sec_to_time",
1892 "second",
1893 "security_lists_intersect",
1894 "semi_join",
1895 "sha",
1896 "sha1",
1897 "sha2",
1898 "shard",
1899 "sharded",
1900 "sharded_id",
1901 "sigmoid",
1902 "sign",
1903 "sin",
1904 "skip",
1905 "sleep",
1906 "snapshot",
1907 "soname",
1908 "sparse",
1909 "spatial_check_index",
1910 "split",
1911 "sqrt",
1912 "standalone",
1913 "std",
1914 "stddev",
1915 "stddev_pop",
1916 "stddev_samp",
1917 "stop",
1918 "str_to_date",
1919 "subdate",
1920 "substr",
1921 "substring_index",
1922 "success",
1923 "synchronize",
1924 "table_checksum",
1925 "tan",
1926 "task",
1927 "timediff",
1928 "time_bucket",
1929 "time_format",
1930 "time_to_sec",
1931 "timestampadd",
1932 "timestampdiff",
1933 "to_base64",
1934 "to_char",
1935 "to_date",
1936 "to_days",
1937 "to_json",
1938 "to_number",
1939 "to_seconds",
1940 "to_timestamp",
1941 "tracelogs",
1942 "transform",
1943 "trim",
1944 "trunc",
1945 "truncate",
1946 "ucase",
1947 "unhex",
1948 "unix_timestamp",
1949 "utc_date",
1950 "utc_time",
1951 "utc_timestamp",
1952 "vacuum",
1953 "variance",
1954 "var_pop",
1955 "var_samp",
1956 "vector_sub",
1957 "voting",
1958 "week",
1959 "weekday",
1960 "weekofyear",
1961 "workload",
1962 "year",
1963 ]);
1964 set.remove("all");
1966 set
1967 });
1968
1969 pub static SQLITE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1973 [
1975 "abort",
1976 "action",
1977 "add",
1978 "after",
1979 "all",
1980 "alter",
1981 "always",
1982 "analyze",
1983 "and",
1984 "as",
1985 "asc",
1986 "attach",
1987 "autoincrement",
1988 "before",
1989 "begin",
1990 "between",
1991 "by",
1992 "cascade",
1993 "case",
1994 "cast",
1995 "check",
1996 "collate",
1997 "column",
1998 "commit",
1999 "conflict",
2000 "constraint",
2001 "create",
2002 "cross",
2003 "current",
2004 "current_date",
2005 "current_time",
2006 "current_timestamp",
2007 "database",
2008 "default",
2009 "deferrable",
2010 "deferred",
2011 "delete",
2012 "desc",
2013 "detach",
2014 "distinct",
2015 "do",
2016 "drop",
2017 "each",
2018 "else",
2019 "end",
2020 "escape",
2021 "except",
2022 "exclude",
2023 "exclusive",
2024 "exists",
2025 "explain",
2026 "fail",
2027 "filter",
2028 "first",
2029 "following",
2030 "for",
2031 "foreign",
2032 "from",
2033 "full",
2034 "generated",
2035 "glob",
2036 "group",
2037 "groups",
2038 "having",
2039 "if",
2040 "ignore",
2041 "immediate",
2042 "in",
2043 "index",
2044 "indexed",
2045 "initially",
2046 "inner",
2047 "insert",
2048 "instead",
2049 "intersect",
2050 "into",
2051 "is",
2052 "isnull",
2053 "join",
2054 "key",
2055 "last",
2056 "left",
2057 "like",
2058 "limit",
2059 "natural",
2060 "no",
2061 "not",
2062 "nothing",
2063 "notnull",
2064 "null",
2065 "nulls",
2066 "of",
2067 "offset",
2068 "on",
2069 "or",
2070 "order",
2071 "others",
2072 "outer",
2073 "partition",
2074 "plan",
2075 "pragma",
2076 "preceding",
2077 "primary",
2078 "query",
2079 "raise",
2080 "range",
2081 "recursive",
2082 "references",
2083 "regexp",
2084 "reindex",
2085 "release",
2086 "rename",
2087 "replace",
2088 "restrict",
2089 "returning",
2090 "right",
2091 "rollback",
2092 "row",
2093 "rows",
2094 "savepoint",
2095 "select",
2096 "set",
2097 "table",
2098 "temp",
2099 "temporary",
2100 "then",
2101 "ties",
2102 "to",
2103 "transaction",
2104 "trigger",
2105 "unbounded",
2106 "union",
2107 "unique",
2108 "update",
2109 "using",
2110 "vacuum",
2111 "values",
2112 "view",
2113 "virtual",
2114 "when",
2115 "where",
2116 "window",
2117 "with",
2118 "without",
2119 ]
2120 .into_iter()
2121 .collect()
2122 });
2123}
2124
2125impl Generator {
2126 pub fn new() -> Self {
2132 Self::with_config(GeneratorConfig::default())
2133 }
2134
2135 pub fn with_config(config: GeneratorConfig) -> Self {
2140 Self::with_arc_config(Arc::new(config))
2141 }
2142
2143 pub(crate) fn with_arc_config(config: Arc<GeneratorConfig>) -> Self {
2148 Self {
2149 config,
2150 output: String::new(),
2151 unsupported_messages: Vec::new(),
2152 indent_level: 0,
2153 athena_hive_context: false,
2154 sqlite_inline_pk_columns: std::collections::HashSet::new(),
2155 merge_strip_qualifiers: Vec::new(),
2156 clickhouse_nullable_depth: 0,
2157 }
2158 }
2159
2160 fn add_column_aliases_to_query(expr: Expression) -> Expression {
2164 match expr {
2165 Expression::Select(mut select) => {
2166 select.expressions = select
2168 .expressions
2169 .into_iter()
2170 .map(|e| Self::add_alias_to_expression(e))
2171 .collect();
2172
2173 if let Some(ref mut from) = select.from {
2175 from.expressions = from
2176 .expressions
2177 .iter()
2178 .cloned()
2179 .map(|e| Self::add_column_aliases_to_query(e))
2180 .collect();
2181 }
2182
2183 Expression::Select(select)
2184 }
2185 Expression::Subquery(mut sq) => {
2186 sq.this = Self::add_column_aliases_to_query(sq.this);
2187 Expression::Subquery(sq)
2188 }
2189 Expression::Paren(mut p) => {
2190 p.this = Self::add_column_aliases_to_query(p.this);
2191 Expression::Paren(p)
2192 }
2193 other => other,
2195 }
2196 }
2197
2198 fn add_alias_to_expression(expr: Expression) -> Expression {
2201 use crate::expressions::Alias;
2202
2203 match &expr {
2204 Expression::Alias(_) => expr,
2206
2207 Expression::Column(col) => Expression::Alias(Box::new(Alias {
2209 this: expr.clone(),
2210 alias: col.name.clone(),
2211 column_aliases: Vec::new(),
2212 alias_explicit_as: false,
2213 alias_keyword: None,
2214 pre_alias_comments: Vec::new(),
2215 trailing_comments: Vec::new(),
2216 inferred_type: None,
2217 })),
2218
2219 Expression::Identifier(ident) => Expression::Alias(Box::new(Alias {
2221 this: expr.clone(),
2222 alias: ident.clone(),
2223 column_aliases: Vec::new(),
2224 alias_explicit_as: false,
2225 alias_keyword: None,
2226 pre_alias_comments: Vec::new(),
2227 trailing_comments: Vec::new(),
2228 inferred_type: None,
2229 })),
2230
2231 Expression::Subquery(sq) => {
2233 let processed = Self::add_column_aliases_to_query(Expression::Subquery(sq.clone()));
2234 if sq.alias.is_some() {
2236 processed
2237 } else {
2238 processed
2240 }
2241 }
2242
2243 Expression::Star(_) => expr,
2245
2246 _ => expr,
2249 }
2250 }
2251
2252 fn try_evaluate_constant(expr: &Expression) -> Option<i64> {
2256 match expr {
2257 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
2258 let Literal::Number(n) = lit.as_ref() else {
2259 unreachable!()
2260 };
2261 n.parse::<i64>().ok()
2262 }
2263 Expression::Add(op) => {
2264 let left = Self::try_evaluate_constant(&op.left)?;
2265 let right = Self::try_evaluate_constant(&op.right)?;
2266 Some(left + right)
2267 }
2268 Expression::Sub(op) => {
2269 let left = Self::try_evaluate_constant(&op.left)?;
2270 let right = Self::try_evaluate_constant(&op.right)?;
2271 Some(left - right)
2272 }
2273 Expression::Mul(op) => {
2274 let left = Self::try_evaluate_constant(&op.left)?;
2275 let right = Self::try_evaluate_constant(&op.right)?;
2276 Some(left * right)
2277 }
2278 Expression::Div(op) => {
2279 let left = Self::try_evaluate_constant(&op.left)?;
2280 let right = Self::try_evaluate_constant(&op.right)?;
2281 if right != 0 {
2282 Some(left / right)
2283 } else {
2284 None
2285 }
2286 }
2287 Expression::Paren(p) => Self::try_evaluate_constant(&p.this),
2288 _ => None,
2289 }
2290 }
2291
2292 fn is_reserved_keyword(&self, name: &str) -> bool {
2294 use crate::dialects::DialectType;
2295 let mut buf = [0u8; 128];
2296 let lower_ref: &str = if name.len() <= 128 {
2297 for (i, b) in name.bytes().enumerate() {
2298 buf[i] = b.to_ascii_lowercase();
2299 }
2300 std::str::from_utf8(&buf[..name.len()]).unwrap_or(name)
2302 } else {
2303 return false;
2304 };
2305
2306 match self.config.dialect {
2307 Some(DialectType::BigQuery) => reserved_keywords::BIGQUERY_RESERVED.contains(lower_ref),
2308 Some(DialectType::MySQL) | Some(DialectType::TiDB) => {
2309 reserved_keywords::MYSQL_RESERVED.contains(lower_ref)
2310 }
2311 Some(DialectType::Doris) => reserved_keywords::DORIS_RESERVED.contains(lower_ref),
2312 Some(DialectType::SingleStore) => {
2313 reserved_keywords::SINGLESTORE_RESERVED.contains(lower_ref)
2314 }
2315 Some(DialectType::StarRocks) => {
2316 reserved_keywords::STARROCKS_RESERVED.contains(lower_ref)
2317 }
2318 Some(DialectType::PostgreSQL)
2319 | Some(DialectType::CockroachDB)
2320 | Some(DialectType::Materialize)
2321 | Some(DialectType::RisingWave) => {
2322 reserved_keywords::POSTGRES_RESERVED.contains(lower_ref)
2323 }
2324 Some(DialectType::Redshift) => reserved_keywords::REDSHIFT_RESERVED.contains(lower_ref),
2325 Some(DialectType::Snowflake) => false,
2328 Some(DialectType::ClickHouse) => false,
2330 Some(DialectType::DuckDB) => reserved_keywords::DUCKDB_RESERVED.contains(lower_ref),
2331 Some(DialectType::Teradata) => false,
2333 Some(DialectType::TSQL)
2335 | Some(DialectType::Fabric)
2336 | Some(DialectType::Oracle)
2337 | Some(DialectType::Spark)
2338 | Some(DialectType::Databricks)
2339 | Some(DialectType::Hive)
2340 | Some(DialectType::Solr) => false,
2341 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
2342 reserved_keywords::PRESTO_TRINO_RESERVED.contains(lower_ref)
2343 }
2344 Some(DialectType::SQLite) => reserved_keywords::SQLITE_RESERVED.contains(lower_ref),
2345 Some(DialectType::Generic) | None => false,
2347 _ => reserved_keywords::SQL_RESERVED.contains(lower_ref),
2349 }
2350 }
2351
2352 fn normalize_func_name<'a>(&self, name: &'a str) -> Cow<'a, str> {
2354 match self.config.normalize_functions {
2355 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
2356 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
2357 NormalizeFunctions::None => Cow::Borrowed(name),
2358 }
2359 }
2360
2361 pub fn generate(&mut self, expr: &Expression) -> Result<String> {
2370 self.output.clear();
2371 self.unsupported_messages.clear();
2372 enforce_generate_ast(expr, &self.config.complexity_guard)?;
2373 self.generate_expression(expr)?;
2374 if self.config.unsupported_level == UnsupportedLevel::Raise
2375 && !self.unsupported_messages.is_empty()
2376 {
2377 return Err(crate::error::Error::generate(
2378 self.format_unsupported_messages(),
2379 ));
2380 }
2381 Ok(std::mem::take(&mut self.output))
2382 }
2383
2384 pub fn unsupported_messages(&self) -> &[String] {
2386 &self.unsupported_messages
2387 }
2388
2389 fn unsupported(&mut self, message: impl Into<String>) -> Result<()> {
2390 let message = message.into();
2391 if self.config.unsupported_level == UnsupportedLevel::Immediate {
2392 return Err(crate::error::Error::generate(message));
2393 }
2394 self.unsupported_messages.push(message);
2395 Ok(())
2396 }
2397
2398 fn write_unsupported_comment(&mut self, message: &str) -> Result<()> {
2399 self.unsupported(message.to_string())?;
2400 self.write("/* ");
2401 self.write(message);
2402 self.write(" */");
2403 Ok(())
2404 }
2405
2406 fn format_unsupported_messages(&self) -> String {
2407 let limit = self.config.max_unsupported.max(1);
2408 if self.unsupported_messages.len() <= limit {
2409 return self.unsupported_messages.join("; ");
2410 }
2411
2412 let mut messages = self
2413 .unsupported_messages
2414 .iter()
2415 .take(limit)
2416 .cloned()
2417 .collect::<Vec<_>>();
2418 messages.push(format!(
2419 "... and {} more",
2420 self.unsupported_messages.len() - limit
2421 ));
2422 messages.join("; ")
2423 }
2424
2425 pub fn sql(expr: &Expression) -> Result<String> {
2431 let mut gen = Generator::new();
2432 gen.generate(expr)
2433 }
2434
2435 pub fn pretty_sql(expr: &Expression) -> Result<String> {
2440 let config = GeneratorConfig {
2441 pretty: true,
2442 ..Default::default()
2443 };
2444 let mut gen = Generator::with_config(config);
2445 let mut sql = gen.generate(expr)?;
2446 if !sql.ends_with(';') {
2448 sql.push(';');
2449 }
2450 Ok(sql)
2451 }
2452
2453 fn generate_expression(&mut self, expr: &Expression) -> Result<()> {
2454 #[cfg(feature = "stacker")]
2455 {
2456 let red_zone = if cfg!(debug_assertions) {
2457 4 * 1024 * 1024
2458 } else {
2459 1024 * 1024
2460 };
2461 stacker::maybe_grow(red_zone, 8 * 1024 * 1024, || {
2462 self.generate_expression_inner(expr)
2463 })
2464 }
2465 #[cfg(not(feature = "stacker"))]
2466 {
2467 self.generate_expression_inner(expr)
2468 }
2469 }
2470
2471 fn generate_expression_inner(&mut self, expr: &Expression) -> Result<()> {
2472 match expr {
2473 Expression::Select(select) => self.generate_select(select),
2474 Expression::Union(union) => self.generate_union(union),
2475 Expression::Intersect(intersect) => self.generate_intersect(intersect),
2476 Expression::Except(except) => self.generate_except(except),
2477 Expression::Insert(insert) => self.generate_insert(insert),
2478 Expression::Update(update) => self.generate_update(update),
2479 Expression::Delete(delete) => self.generate_delete(delete),
2480 Expression::Literal(lit) => self.generate_literal(lit),
2481 Expression::Boolean(b) => self.generate_boolean(b),
2482 Expression::Null(_) => {
2483 self.write_keyword("NULL");
2484 Ok(())
2485 }
2486 Expression::Identifier(id) => self.generate_identifier(id),
2487 Expression::Column(col) => self.generate_column(col),
2488 Expression::Pseudocolumn(pc) => self.generate_pseudocolumn(pc),
2489 Expression::Connect(c) => self.generate_connect_expr(c),
2490 Expression::Prior(p) => self.generate_prior(p),
2491 Expression::ConnectByRoot(cbr) => self.generate_connect_by_root(cbr),
2492 Expression::MatchRecognize(mr) => self.generate_match_recognize(mr),
2493 Expression::Table(table) => self.generate_table(table),
2494 Expression::StageReference(sr) => self.generate_stage_reference(sr),
2495 Expression::HistoricalData(hd) => self.generate_historical_data(hd),
2496 Expression::JoinedTable(jt) => self.generate_joined_table(jt),
2497 Expression::Star(star) => self.generate_star(star),
2498 Expression::BracedWildcard(expr) => self.generate_braced_wildcard(expr),
2499 Expression::Alias(alias) => self.generate_alias(alias),
2500 Expression::Cast(cast) => self.generate_cast(cast),
2501 Expression::Collation(coll) => self.generate_collation(coll),
2502 Expression::Case(case) => self.generate_case(case),
2503 Expression::Function(func) => self.generate_function(func),
2504 Expression::FunctionEmits(fe) => self.generate_function_emits(fe),
2505 Expression::AggregateFunction(func) => self.generate_aggregate_function(func),
2506 Expression::WindowFunction(wf) => self.generate_window_function(wf),
2507 Expression::WithinGroup(wg) => self.generate_within_group(wg),
2508 Expression::Interval(interval) => self.generate_interval(interval),
2509
2510 Expression::ConcatWs(f) => self.generate_concat_ws(f),
2512 Expression::Substring(f) => self.generate_substring(f),
2513 Expression::Upper(f) => self.generate_unary_func("UPPER", f),
2514 Expression::Lower(f) => self.generate_unary_func("LOWER", f),
2515 Expression::Length(f) => self.generate_unary_func("LENGTH", f),
2516 Expression::Trim(f) => self.generate_trim(f),
2517 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
2518 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
2519 Expression::Replace(f) => self.generate_replace(f),
2520 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
2521 Expression::Left(f) => self.generate_left_right("LEFT", f),
2522 Expression::Right(f) => self.generate_left_right("RIGHT", f),
2523 Expression::Repeat(f) => self.generate_repeat(f),
2524 Expression::Lpad(f) => self.generate_pad("LPAD", f),
2525 Expression::Rpad(f) => self.generate_pad("RPAD", f),
2526 Expression::Split(f) => self.generate_split(f),
2527 Expression::RegexpLike(f) => self.generate_regexp_like(f),
2528 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
2529 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
2530 Expression::Overlay(f) => self.generate_overlay(f),
2531
2532 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
2534 Expression::Round(f) => self.generate_round(f),
2535 Expression::Floor(f) => self.generate_floor(f),
2536 Expression::Ceil(f) => self.generate_ceil(f),
2537 Expression::Power(f) => self.generate_power(f),
2538 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
2539 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
2540 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
2541 Expression::Log(f) => self.generate_log(f),
2542 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
2543 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
2544 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
2545 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
2546
2547 Expression::CurrentDate(_) => {
2549 self.write_keyword("CURRENT_DATE");
2550 Ok(())
2551 }
2552 Expression::CurrentTime(f) => self.generate_current_time(f),
2553 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
2554 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
2555 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
2556 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
2557 Expression::DateDiff(f) => self.generate_datediff(f),
2558 Expression::DateTrunc(f) => self.generate_date_trunc(f),
2559 Expression::Extract(f) => self.generate_extract(f),
2560 Expression::ToDate(f) => self.generate_to_date(f),
2561 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
2562
2563 Expression::Coalesce(f) => {
2565 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
2567 self.generate_vararg_func(func_name, &f.expressions)
2568 }
2569 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
2570 Expression::IfFunc(f) => self.generate_if_func(f),
2571 Expression::IfNull(f) => self.generate_ifnull(f),
2572 Expression::Nvl(f) => self.generate_nvl(f),
2573 Expression::Nvl2(f) => self.generate_nvl2(f),
2574
2575 Expression::TryCast(cast) => self.generate_try_cast(cast),
2577 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
2578
2579 Expression::Count(f) => self.generate_count(f),
2581 Expression::Sum(f) => self.generate_agg_func("SUM", f),
2582 Expression::Avg(f) => self.generate_agg_func("AVG", f),
2583 Expression::Min(f) => self.generate_agg_func("MIN", f),
2584 Expression::Max(f) => self.generate_agg_func("MAX", f),
2585 Expression::GroupConcat(f) => self.generate_group_concat(f),
2586 Expression::StringAgg(f) => self.generate_string_agg(f),
2587 Expression::ListAgg(f) => self.generate_listagg(f),
2588 Expression::ArrayAgg(f) => {
2589 let override_name = f
2592 .name
2593 .as_ref()
2594 .filter(|n| !n.eq_ignore_ascii_case("ARRAY_AGG"))
2595 .map(|n| n.to_ascii_uppercase());
2596 match override_name {
2597 Some(name) => self.generate_agg_func(&name, f),
2598 None => self.generate_agg_func("ARRAY_AGG", f),
2599 }
2600 }
2601 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
2602 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
2603 Expression::SumIf(f) => self.generate_sum_if(f),
2604 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
2605 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
2606 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
2607 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
2608 Expression::VarPop(f) => {
2609 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
2610 "VARIANCE_POP"
2611 } else {
2612 "VAR_POP"
2613 };
2614 self.generate_agg_func(name, f)
2615 }
2616 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
2617 Expression::Skewness(f) => {
2618 let name = match self.config.dialect {
2619 Some(DialectType::Snowflake) => "SKEW",
2620 _ => "SKEWNESS",
2621 };
2622 self.generate_agg_func(name, f)
2623 }
2624 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
2625 Expression::Mode(f) => self.generate_agg_func("MODE", f),
2626 Expression::First(f) => self.generate_agg_func_with_ignore_nulls_bool("FIRST", f),
2627 Expression::Last(f) => self.generate_agg_func_with_ignore_nulls_bool("LAST", f),
2628 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
2629 Expression::ApproxDistinct(f) => {
2630 match self.config.dialect {
2631 Some(DialectType::Hive)
2632 | Some(DialectType::Spark)
2633 | Some(DialectType::Databricks)
2634 | Some(DialectType::BigQuery) => {
2635 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2637 }
2638 Some(DialectType::Redshift) => {
2639 self.write_keyword("APPROXIMATE COUNT");
2641 self.write("(");
2642 self.write_keyword("DISTINCT");
2643 self.write(" ");
2644 self.generate_expression(&f.this)?;
2645 self.write(")");
2646 Ok(())
2647 }
2648 _ => self.generate_agg_func("APPROX_DISTINCT", f),
2649 }
2650 }
2651 Expression::ApproxCountDistinct(f) => {
2652 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2653 }
2654 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
2655 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
2656 Expression::LogicalAnd(f) => {
2657 let name = match self.config.dialect {
2658 Some(DialectType::Snowflake) => "BOOLAND_AGG",
2659 Some(DialectType::Spark)
2660 | Some(DialectType::Databricks)
2661 | Some(DialectType::PostgreSQL)
2662 | Some(DialectType::DuckDB)
2663 | Some(DialectType::Redshift) => "BOOL_AND",
2664 Some(DialectType::Oracle)
2665 | Some(DialectType::SQLite)
2666 | Some(DialectType::MySQL) => "MIN",
2667 _ => "BOOL_AND",
2668 };
2669 self.generate_agg_func(name, f)
2670 }
2671 Expression::LogicalOr(f) => {
2672 let name = match self.config.dialect {
2673 Some(DialectType::Snowflake) => "BOOLOR_AGG",
2674 Some(DialectType::Spark)
2675 | Some(DialectType::Databricks)
2676 | Some(DialectType::PostgreSQL)
2677 | Some(DialectType::DuckDB)
2678 | Some(DialectType::Redshift) => "BOOL_OR",
2679 Some(DialectType::Oracle)
2680 | Some(DialectType::SQLite)
2681 | Some(DialectType::MySQL) => "MAX",
2682 _ => "BOOL_OR",
2683 };
2684 self.generate_agg_func(name, f)
2685 }
2686
2687 Expression::RowNumber(_) => {
2689 if self.config.dialect == Some(DialectType::ClickHouse) {
2690 self.write("row_number");
2691 } else {
2692 self.write_keyword("ROW_NUMBER");
2693 }
2694 self.write("()");
2695 Ok(())
2696 }
2697 Expression::Rank(r) => {
2698 self.write_keyword("RANK");
2699 self.write("(");
2700 if !r.args.is_empty() {
2702 for (i, arg) in r.args.iter().enumerate() {
2703 if i > 0 {
2704 self.write(", ");
2705 }
2706 self.generate_expression(arg)?;
2707 }
2708 } else if let Some(order_by) = &r.order_by {
2709 self.write_keyword(" ORDER BY ");
2711 for (i, ob) in order_by.iter().enumerate() {
2712 if i > 0 {
2713 self.write(", ");
2714 }
2715 self.generate_ordered(ob)?;
2716 }
2717 }
2718 self.write(")");
2719 Ok(())
2720 }
2721 Expression::DenseRank(dr) => {
2722 self.write_keyword("DENSE_RANK");
2723 self.write("(");
2724 for (i, arg) in dr.args.iter().enumerate() {
2726 if i > 0 {
2727 self.write(", ");
2728 }
2729 self.generate_expression(arg)?;
2730 }
2731 self.write(")");
2732 Ok(())
2733 }
2734 Expression::NTile(f) => self.generate_ntile(f),
2735 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
2736 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
2737 Expression::FirstValue(f) => {
2738 self.generate_value_func_with_ignore_nulls_bool("FIRST_VALUE", f)
2739 }
2740 Expression::LastValue(f) => {
2741 self.generate_value_func_with_ignore_nulls_bool("LAST_VALUE", f)
2742 }
2743 Expression::NthValue(f) => self.generate_nth_value(f),
2744 Expression::PercentRank(pr) => {
2745 self.write_keyword("PERCENT_RANK");
2746 self.write("(");
2747 if !pr.args.is_empty() {
2749 for (i, arg) in pr.args.iter().enumerate() {
2750 if i > 0 {
2751 self.write(", ");
2752 }
2753 self.generate_expression(arg)?;
2754 }
2755 } else if let Some(order_by) = &pr.order_by {
2756 self.write_keyword(" ORDER BY ");
2758 for (i, ob) in order_by.iter().enumerate() {
2759 if i > 0 {
2760 self.write(", ");
2761 }
2762 self.generate_ordered(ob)?;
2763 }
2764 }
2765 self.write(")");
2766 Ok(())
2767 }
2768 Expression::CumeDist(cd) => {
2769 self.write_keyword("CUME_DIST");
2770 self.write("(");
2771 if !cd.args.is_empty() {
2773 for (i, arg) in cd.args.iter().enumerate() {
2774 if i > 0 {
2775 self.write(", ");
2776 }
2777 self.generate_expression(arg)?;
2778 }
2779 } else if let Some(order_by) = &cd.order_by {
2780 self.write_keyword(" ORDER BY ");
2782 for (i, ob) in order_by.iter().enumerate() {
2783 if i > 0 {
2784 self.write(", ");
2785 }
2786 self.generate_ordered(ob)?;
2787 }
2788 }
2789 self.write(")");
2790 Ok(())
2791 }
2792 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
2793 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
2794
2795 Expression::Contains(f) => {
2797 self.generate_binary_func("CONTAINS", &f.this, &f.expression)
2798 }
2799 Expression::StartsWith(f) => {
2800 let name = match self.config.dialect {
2801 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
2802 _ => "STARTS_WITH",
2803 };
2804 self.generate_binary_func(name, &f.this, &f.expression)
2805 }
2806 Expression::EndsWith(f) => {
2807 let name = match self.config.dialect {
2808 Some(DialectType::Snowflake) => "ENDSWITH",
2809 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
2810 Some(DialectType::ClickHouse) => "endsWith",
2811 _ => "ENDS_WITH",
2812 };
2813 self.generate_binary_func(name, &f.this, &f.expression)
2814 }
2815 Expression::Position(f) => self.generate_position(f),
2816 Expression::Initcap(f) => match self.config.dialect {
2817 Some(DialectType::Presto)
2818 | Some(DialectType::Trino)
2819 | Some(DialectType::Athena) => {
2820 self.write_keyword("REGEXP_REPLACE");
2821 self.write("(");
2822 self.generate_expression(&f.this)?;
2823 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
2824 Ok(())
2825 }
2826 _ => self.generate_simple_func("INITCAP", &f.this),
2827 },
2828 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
2829 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
2830 Expression::CharFunc(f) => self.generate_char_func(f),
2831 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
2832 Expression::Levenshtein(f) => {
2833 self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression)
2834 }
2835
2836 Expression::ModFunc(f) => self.generate_mod_func(f),
2838 Expression::Random(_) => {
2839 self.write_keyword("RANDOM");
2840 self.write("()");
2841 Ok(())
2842 }
2843 Expression::Rand(f) => self.generate_rand(f),
2844 Expression::TruncFunc(f) => self.generate_truncate_func(f),
2845 Expression::Pi(_) => {
2846 self.write_keyword("PI");
2847 self.write("()");
2848 Ok(())
2849 }
2850 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
2851 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
2852 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
2853 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
2854 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
2855 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
2856 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
2857 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
2858 Expression::Atan2(f) => {
2859 let name = f.original_name.as_deref().unwrap_or("ATAN2");
2860 self.generate_binary_func(name, &f.this, &f.expression)
2861 }
2862
2863 Expression::Decode(f) => self.generate_decode(f),
2865
2866 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
2868 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
2869 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
2870 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
2871 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
2872 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
2873 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
2874 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
2875 Expression::DayOfWeek(f) => {
2876 let name = match self.config.dialect {
2877 Some(DialectType::Presto)
2878 | Some(DialectType::Trino)
2879 | Some(DialectType::Athena) => "DAY_OF_WEEK",
2880 Some(DialectType::DuckDB) => "ISODOW",
2881 _ => "DAYOFWEEK",
2882 };
2883 self.generate_simple_func(name, &f.this)
2884 }
2885 Expression::DayOfMonth(f) => {
2886 let name = match self.config.dialect {
2887 Some(DialectType::Presto)
2888 | Some(DialectType::Trino)
2889 | Some(DialectType::Athena) => "DAY_OF_MONTH",
2890 _ => "DAYOFMONTH",
2891 };
2892 self.generate_simple_func(name, &f.this)
2893 }
2894 Expression::DayOfYear(f) => {
2895 let name = match self.config.dialect {
2896 Some(DialectType::Presto)
2897 | Some(DialectType::Trino)
2898 | Some(DialectType::Athena) => "DAY_OF_YEAR",
2899 _ => "DAYOFYEAR",
2900 };
2901 self.generate_simple_func(name, &f.this)
2902 }
2903 Expression::WeekOfYear(f) => {
2904 let name = match self.config.dialect {
2906 Some(DialectType::Hive)
2907 | Some(DialectType::DuckDB)
2908 | Some(DialectType::Spark)
2909 | Some(DialectType::Databricks)
2910 | Some(DialectType::MySQL) => "WEEKOFYEAR",
2911 _ => "WEEK_OF_YEAR",
2912 };
2913 self.generate_simple_func(name, &f.this)
2914 }
2915 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
2916 Expression::AddMonths(f) => {
2917 self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression)
2918 }
2919 Expression::MonthsBetween(f) => {
2920 self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression)
2921 }
2922 Expression::LastDay(f) => self.generate_last_day(f),
2923 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
2924 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
2925 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
2926 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
2927 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
2928 Expression::MakeDate(f) => self.generate_make_date(f),
2929 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
2930 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
2931
2932 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
2934 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
2935 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
2936 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
2937 Expression::ArrayContains(f) => {
2938 self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression)
2939 }
2940 Expression::ArrayPosition(f) => {
2941 self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression)
2942 }
2943 Expression::ArrayAppend(f) => {
2944 self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression)
2945 }
2946 Expression::ArrayPrepend(f) => {
2947 self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression)
2948 }
2949 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
2950 Expression::ArraySort(f) => self.generate_array_sort(f),
2951 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
2952 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
2953 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
2954 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
2955 Expression::Unnest(f) => self.generate_unnest(f),
2956 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
2957 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
2958 Expression::ArrayFilter(f) => self.generate_array_filter(f),
2959 Expression::ArrayTransform(f) => self.generate_array_transform(f),
2960 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
2961 Expression::ArrayCompact(f) => {
2962 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
2963 self.write("LIST_FILTER(");
2965 self.generate_expression(&f.this)?;
2966 self.write(", _u -> NOT _u IS NULL)");
2967 Ok(())
2968 } else {
2969 self.generate_simple_func("ARRAY_COMPACT", &f.this)
2970 }
2971 }
2972 Expression::ArrayIntersect(f) => {
2973 let func_name = f.original_name.as_deref().unwrap_or("ARRAY_INTERSECT");
2974 self.generate_vararg_func(func_name, &f.expressions)
2975 }
2976 Expression::ArrayUnion(f) => {
2977 self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression)
2978 }
2979 Expression::ArrayExcept(f) => {
2980 self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression)
2981 }
2982 Expression::ArrayRemove(f) => {
2983 self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression)
2984 }
2985 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
2986 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
2987 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
2988
2989 Expression::StructFunc(f) => self.generate_struct_constructor(f),
2991 Expression::StructExtract(f) => self.generate_struct_extract(f),
2992 Expression::NamedStruct(f) => self.generate_named_struct(f),
2993
2994 Expression::MapFunc(f) => self.generate_map_constructor(f),
2996 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
2997 Expression::MapFromArrays(f) => {
2998 self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression)
2999 }
3000 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
3001 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
3002 Expression::MapContainsKey(f) => {
3003 self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression)
3004 }
3005 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
3006 Expression::ElementAt(f) => {
3007 self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression)
3008 }
3009 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
3010 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
3011
3012 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
3014 Expression::JsonExtractScalar(f) => {
3015 self.generate_json_extract("JSON_EXTRACT_SCALAR", f)
3016 }
3017 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
3018 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
3019 Expression::JsonObject(f) => self.generate_json_object(f),
3020 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
3021 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
3022 Expression::JsonArrayLength(f) => {
3023 self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this)
3024 }
3025 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
3026 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
3027 Expression::ParseJson(f) => {
3028 let name = match self.config.dialect {
3029 Some(DialectType::Presto)
3030 | Some(DialectType::Trino)
3031 | Some(DialectType::Athena) => "JSON_PARSE",
3032 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
3033 self.write_keyword("CAST");
3035 self.write("(");
3036 self.generate_expression(&f.this)?;
3037 self.write_keyword(" AS ");
3038 self.write_keyword("JSON");
3039 self.write(")");
3040 return Ok(());
3041 }
3042 Some(DialectType::Hive)
3043 | Some(DialectType::Spark)
3044 | Some(DialectType::MySQL)
3045 | Some(DialectType::SingleStore)
3046 | Some(DialectType::TiDB)
3047 | Some(DialectType::TSQL) => {
3048 self.generate_expression(&f.this)?;
3050 return Ok(());
3051 }
3052 Some(DialectType::DuckDB) => "JSON",
3053 _ => "PARSE_JSON",
3054 };
3055 self.generate_simple_func(name, &f.this)
3056 }
3057 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
3058 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
3059 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
3060 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
3061 Expression::JsonMergePatch(f) => {
3062 self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression)
3063 }
3064 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
3065 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
3066
3067 Expression::Convert(f) => self.generate_convert(f),
3069 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
3070
3071 Expression::Lambda(f) => self.generate_lambda(f),
3073 Expression::Parameter(f) => self.generate_parameter(f),
3074 Expression::Placeholder(f) => self.generate_placeholder(f),
3075 Expression::NamedArgument(f) => self.generate_named_argument(f),
3076 Expression::TableArgument(f) => self.generate_table_argument(f),
3077 Expression::SqlComment(f) => self.generate_sql_comment(f),
3078
3079 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
3081 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
3082 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
3083 Expression::SimilarTo(f) => self.generate_similar_to(f),
3084 Expression::Any(f) => self.generate_quantified("ANY", f),
3085 Expression::All(f) => self.generate_quantified("ALL", f),
3086 Expression::Overlaps(f) => self.generate_overlaps(f),
3087
3088 Expression::BitwiseLeftShift(op) => {
3090 if matches!(
3091 self.config.dialect,
3092 Some(DialectType::Presto) | Some(DialectType::Trino)
3093 ) {
3094 self.write_keyword("BITWISE_LEFT_SHIFT");
3095 self.write("(");
3096 self.generate_expression(&op.left)?;
3097 self.write(", ");
3098 self.generate_expression(&op.right)?;
3099 self.write(")");
3100 Ok(())
3101 } else if matches!(
3102 self.config.dialect,
3103 Some(DialectType::Spark) | Some(DialectType::Databricks)
3104 ) {
3105 self.write_keyword("SHIFTLEFT");
3106 self.write("(");
3107 self.generate_expression(&op.left)?;
3108 self.write(", ");
3109 self.generate_expression(&op.right)?;
3110 self.write(")");
3111 Ok(())
3112 } else {
3113 self.generate_binary_op(op, "<<")
3114 }
3115 }
3116 Expression::BitwiseRightShift(op) => {
3117 if matches!(
3118 self.config.dialect,
3119 Some(DialectType::Presto) | Some(DialectType::Trino)
3120 ) {
3121 self.write_keyword("BITWISE_RIGHT_SHIFT");
3122 self.write("(");
3123 self.generate_expression(&op.left)?;
3124 self.write(", ");
3125 self.generate_expression(&op.right)?;
3126 self.write(")");
3127 Ok(())
3128 } else if matches!(
3129 self.config.dialect,
3130 Some(DialectType::Spark) | Some(DialectType::Databricks)
3131 ) {
3132 self.write_keyword("SHIFTRIGHT");
3133 self.write("(");
3134 self.generate_expression(&op.left)?;
3135 self.write(", ");
3136 self.generate_expression(&op.right)?;
3137 self.write(")");
3138 Ok(())
3139 } else {
3140 self.generate_binary_op(op, ">>")
3141 }
3142 }
3143 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
3144 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
3145 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
3146
3147 Expression::Subscript(s) => self.generate_subscript(s),
3149 Expression::Dot(d) => self.generate_dot_access(d),
3150 Expression::MethodCall(m) => self.generate_method_call(m),
3151 Expression::ArraySlice(s) => self.generate_array_slice(s),
3152
3153 Expression::And(op) => self.generate_connector_op(op, ConnectorOperator::And),
3154 Expression::Or(op) => self.generate_connector_op(op, ConnectorOperator::Or),
3155 Expression::Add(op) => self.generate_binary_op(op, "+"),
3156 Expression::Sub(op) => self.generate_binary_op(op, "-"),
3157 Expression::Mul(op) => self.generate_binary_op(op, "*"),
3158 Expression::Div(op) => self.generate_binary_op(op, "/"),
3159 Expression::IntDiv(f) => {
3160 use crate::dialects::DialectType;
3161 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
3162 self.generate_expression(&f.this)?;
3164 self.write(" // ");
3165 self.generate_expression(&f.expression)?;
3166 Ok(())
3167 } else if matches!(
3168 self.config.dialect,
3169 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
3170 ) {
3171 self.generate_expression(&f.this)?;
3173 self.write(" ");
3174 self.write_keyword("DIV");
3175 self.write(" ");
3176 self.generate_expression(&f.expression)?;
3177 Ok(())
3178 } else {
3179 self.write_keyword("DIV");
3181 self.write("(");
3182 self.generate_expression(&f.this)?;
3183 self.write(", ");
3184 self.generate_expression(&f.expression)?;
3185 self.write(")");
3186 Ok(())
3187 }
3188 }
3189 Expression::Mod(op) => {
3190 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
3191 self.generate_binary_op(op, "MOD")
3192 } else {
3193 self.generate_binary_op(op, "%")
3194 }
3195 }
3196 Expression::Eq(op) => self.generate_binary_op(op, "="),
3197 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
3198 Expression::Lt(op) => self.generate_binary_op(op, "<"),
3199 Expression::Lte(op) => self.generate_binary_op(op, "<="),
3200 Expression::Gt(op) => self.generate_binary_op(op, ">"),
3201 Expression::Gte(op) => self.generate_binary_op(op, ">="),
3202 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
3203 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
3204 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
3205 Expression::Concat(op) => {
3206 if self.config.dialect == Some(DialectType::Solr) {
3208 self.generate_binary_op(op, "OR")
3209 } else if self.config.dialect == Some(DialectType::MySQL) {
3210 self.generate_mysql_concat_from_concat(op)
3211 } else {
3212 self.generate_binary_op(op, "||")
3213 }
3214 }
3215 Expression::BitwiseAnd(op) => {
3216 if matches!(
3218 self.config.dialect,
3219 Some(DialectType::Presto) | Some(DialectType::Trino)
3220 ) {
3221 self.write_keyword("BITWISE_AND");
3222 self.write("(");
3223 self.generate_expression(&op.left)?;
3224 self.write(", ");
3225 self.generate_expression(&op.right)?;
3226 self.write(")");
3227 Ok(())
3228 } else {
3229 self.generate_binary_op(op, "&")
3230 }
3231 }
3232 Expression::BitwiseOr(op) => {
3233 if matches!(
3235 self.config.dialect,
3236 Some(DialectType::Presto) | Some(DialectType::Trino)
3237 ) {
3238 self.write_keyword("BITWISE_OR");
3239 self.write("(");
3240 self.generate_expression(&op.left)?;
3241 self.write(", ");
3242 self.generate_expression(&op.right)?;
3243 self.write(")");
3244 Ok(())
3245 } else {
3246 self.generate_binary_op(op, "|")
3247 }
3248 }
3249 Expression::BitwiseXor(op) => {
3250 if matches!(
3252 self.config.dialect,
3253 Some(DialectType::Presto) | Some(DialectType::Trino)
3254 ) {
3255 self.write_keyword("BITWISE_XOR");
3256 self.write("(");
3257 self.generate_expression(&op.left)?;
3258 self.write(", ");
3259 self.generate_expression(&op.right)?;
3260 self.write(")");
3261 Ok(())
3262 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
3263 self.generate_binary_op(op, "#")
3264 } else {
3265 self.generate_binary_op(op, "^")
3266 }
3267 }
3268 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
3269 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
3270 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
3271 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
3272 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
3273 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
3274 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
3275 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
3276 Expression::JSONBContains(f) => {
3277 self.generate_expression(&f.this)?;
3279 self.write_space();
3280 self.write(f.original_name.as_deref().unwrap_or("?"));
3281 self.write_space();
3282 self.generate_expression(&f.expression)
3283 }
3284 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
3285 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
3286 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
3287 Expression::Not(op) => match &op.this {
3288 Expression::Like(like) => self.generate_like_op_negated(like, "LIKE"),
3289 Expression::ILike(like) => self.generate_like_op_negated(like, "ILIKE"),
3290 _ => self.generate_unary_op(op, "NOT"),
3291 },
3292 Expression::Neg(op) => self.generate_unary_op(op, "-"),
3293 Expression::BitwiseNot(op) => {
3294 if matches!(
3296 self.config.dialect,
3297 Some(DialectType::Presto) | Some(DialectType::Trino)
3298 ) {
3299 self.write_keyword("BITWISE_NOT");
3300 self.write("(");
3301 self.generate_expression(&op.this)?;
3302 self.write(")");
3303 Ok(())
3304 } else {
3305 self.generate_unary_op(op, "~")
3306 }
3307 }
3308 Expression::In(in_expr) => self.generate_in(in_expr),
3309 Expression::Between(between) => self.generate_between(between),
3310 Expression::IsNull(is_null) => self.generate_is_null(is_null),
3311 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
3312 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
3313 Expression::IsJson(is_json) => self.generate_is_json(is_json),
3314 Expression::Is(is_expr) => self.generate_is(is_expr),
3315 Expression::Exists(exists) => self.generate_exists(exists),
3316 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
3317 Expression::Subquery(subquery) => self.generate_subquery(subquery),
3318 Expression::Paren(paren) => {
3319 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
3321
3322 if !skip_parens {
3323 self.write("(");
3324 if self.config.pretty {
3325 self.write_newline();
3326 self.indent_level += 1;
3327 self.write_indent();
3328 }
3329 }
3330 self.generate_expression(&paren.this)?;
3331 if !skip_parens {
3332 if self.config.pretty {
3333 self.write_newline();
3334 self.indent_level -= 1;
3335 self.write_indent();
3336 }
3337 self.write(")");
3338 }
3339 for comment in &paren.trailing_comments {
3341 self.write(" ");
3342 self.write_formatted_comment(comment);
3343 }
3344 Ok(())
3345 }
3346 Expression::Array(arr) => self.generate_array(arr),
3347 Expression::Tuple(tuple) => self.generate_tuple(tuple),
3348 Expression::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
3349 Expression::Ordered(ordered) => self.generate_ordered(ordered),
3350 Expression::DataType(dt) => self.generate_data_type(dt),
3351 Expression::Raw(raw) => {
3352 self.write(&raw.sql);
3353 Ok(())
3354 }
3355 Expression::CreateTask(task) => self.generate_create_task(task),
3356 Expression::TryCatch(try_catch) => self.generate_try_catch(try_catch),
3357 Expression::Command(cmd) => {
3358 self.write(&cmd.this);
3359 if matches!(self.config.dialect, Some(DialectType::ClickHouse))
3360 && cmd
3361 .this
3362 .trim_start()
3363 .get(..7)
3364 .is_some_and(|prefix| prefix.eq_ignore_ascii_case("EXPLAIN"))
3365 {
3366 for _ in 0..Self::missing_closing_parens_outside_quotes(&cmd.this) {
3367 self.write(")");
3368 }
3369 }
3370 Ok(())
3371 }
3372 Expression::Kill(kill) => {
3373 self.write_keyword("KILL");
3374 if let Some(kind) = &kill.kind {
3375 self.write_space();
3376 self.write_keyword(kind);
3377 }
3378 self.write_space();
3379 self.generate_expression(&kill.this)?;
3380 Ok(())
3381 }
3382 Expression::Prepare(prepare) => self.generate_prepare(prepare),
3383 Expression::Execute(exec) => {
3384 self.write_keyword("EXECUTE");
3385 self.write_space();
3386 self.generate_expression(&exec.this)?;
3387 if exec.prepared {
3388 if !exec.arguments.is_empty() {
3389 self.write("(");
3390 for (i, argument) in exec.arguments.iter().enumerate() {
3391 if i > 0 {
3392 self.write(", ");
3393 }
3394 self.generate_expression(argument)?;
3395 }
3396 self.write(")");
3397 }
3398 return Ok(());
3399 }
3400 for (i, param) in exec.parameters.iter().enumerate() {
3401 if i == 0 {
3402 self.write_space();
3403 } else {
3404 self.write(", ");
3405 }
3406 self.write(¶m.name);
3407 if !param.positional {
3409 self.write(" = ");
3410 self.generate_expression(¶m.value)?;
3411 }
3412 if param.output {
3413 self.write_space();
3414 self.write_keyword("OUTPUT");
3415 }
3416 }
3417 if let Some(ref suffix) = exec.suffix {
3418 self.write_space();
3419 self.write(suffix);
3420 }
3421 Ok(())
3422 }
3423 Expression::Annotated(annotated) => {
3424 self.generate_expression(&annotated.this)?;
3425 for comment in &annotated.trailing_comments {
3426 self.write(" ");
3427 self.write_formatted_comment(comment);
3428 }
3429 Ok(())
3430 }
3431
3432 Expression::CreateTable(ct) => self.generate_create_table(ct),
3434 Expression::DropTable(dt) => self.generate_drop_table(dt),
3435 Expression::Undrop(u) => self.generate_undrop(u),
3436 Expression::AlterTable(at) => self.generate_alter_table(at),
3437 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3438 Expression::DropIndex(di) => self.generate_drop_index(di),
3439 Expression::CreateView(cv) => self.generate_create_view(cv),
3440 Expression::DropView(dv) => self.generate_drop_view(dv),
3441 Expression::AlterView(av) => self.generate_alter_view(av),
3442 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3443 Expression::Truncate(tr) => self.generate_truncate(tr),
3444 Expression::Use(u) => self.generate_use(u),
3445 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3447 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3448 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3449 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3450 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3451 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3452 Expression::DropFunction(df) => self.generate_drop_function(df),
3453 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3454 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3455 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3456 Expression::CreateSynonym(cs) => {
3457 self.write_keyword("CREATE SYNONYM");
3458 self.write_space();
3459 self.generate_table(&cs.name)?;
3460 self.write_space();
3461 self.write_keyword("FOR");
3462 self.write_space();
3463 self.generate_table(&cs.target)?;
3464 Ok(())
3465 }
3466 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3467 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3468 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3469 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3470 Expression::CreateType(ct) => self.generate_create_type(ct),
3471 Expression::DropType(dt) => self.generate_drop_type(dt),
3472 Expression::Describe(d) => self.generate_describe(d),
3473 Expression::Show(s) => self.generate_show(s),
3474
3475 Expression::Cache(c) => self.generate_cache(c),
3477 Expression::Uncache(u) => self.generate_uncache(u),
3478 Expression::LoadData(l) => self.generate_load_data(l),
3479 Expression::Pragma(p) => self.generate_pragma(p),
3480 Expression::Grant(g) => self.generate_grant(g),
3481 Expression::Revoke(r) => self.generate_revoke(r),
3482 Expression::Comment(c) => self.generate_comment(c),
3483 Expression::SetStatement(s) => self.generate_set_statement(s),
3484
3485 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3487 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3488
3489 Expression::Values(values) => self.generate_values(values),
3491
3492 Expression::AIAgg(e) => self.generate_ai_agg(e),
3494 Expression::AIClassify(e) => self.generate_ai_classify(e),
3495 Expression::AddPartition(e) => self.generate_add_partition(e),
3496 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3497 Expression::Aliases(e) => self.generate_aliases(e),
3498 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3499 Expression::AlterColumn(e) => self.generate_alter_column(e),
3500 Expression::AlterSession(e) => self.generate_alter_session(e),
3501 Expression::AlterSet(e) => self.generate_alter_set(e),
3502 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3503 Expression::Analyze(e) => self.generate_analyze(e),
3504 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3505 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3506 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3507 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3508 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3509 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3510 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3511 Expression::Anonymous(e) => self.generate_anonymous(e),
3512 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3513 Expression::Apply(e) => self.generate_apply(e),
3514 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3515 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3516 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3517 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3518 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3519 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3520 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3521 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3522 Expression::ArgMax(e) => self.generate_arg_max(e),
3523 Expression::ArgMin(e) => self.generate_arg_min(e),
3524 Expression::ArrayAll(e) => self.generate_array_all(e),
3525 Expression::ArrayAny(e) => self.generate_array_any(e),
3526 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3527 Expression::ArraySum(e) => self.generate_array_sum(e),
3528 Expression::AtIndex(e) => self.generate_at_index(e),
3529 Expression::Attach(e) => self.generate_attach(e),
3530 Expression::AttachOption(e) => self.generate_attach_option(e),
3531 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3532 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3533 Expression::BackupProperty(e) => self.generate_backup_property(e),
3534 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3535 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3536 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3537 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3538 Expression::Booland(e) => self.generate_booland(e),
3539 Expression::Boolor(e) => self.generate_boolor(e),
3540 Expression::BuildProperty(e) => self.generate_build_property(e),
3541 Expression::ByteString(e) => self.generate_byte_string(e),
3542 Expression::CaseSpecificColumnConstraint(e) => {
3543 self.generate_case_specific_column_constraint(e)
3544 }
3545 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3546 Expression::Changes(e) => self.generate_changes(e),
3547 Expression::CharacterSetColumnConstraint(e) => {
3548 self.generate_character_set_column_constraint(e)
3549 }
3550 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3551 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3552 Expression::AssumeColumnConstraint(e) => self.generate_assume_column_constraint(e),
3553 Expression::CheckJson(e) => self.generate_check_json(e),
3554 Expression::CheckXml(e) => self.generate_check_xml(e),
3555 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3556 Expression::Clone(e) => self.generate_clone(e),
3557 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3558 Expression::ClusterByColumnsProperty(e) => self.generate_cluster_by_columns_property(e),
3559 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3560 Expression::CollateProperty(e) => self.generate_collate_property(e),
3561 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3562 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3563 Expression::ColumnPosition(e) => self.generate_column_position(e),
3564 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3565 Expression::Columns(e) => self.generate_columns(e),
3566 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3567 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3568 Expression::Commit(e) => self.generate_commit(e),
3569 Expression::Comprehension(e) => self.generate_comprehension(e),
3570 Expression::Compress(e) => self.generate_compress(e),
3571 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3572 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3573 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3574 Expression::Constraint(e) => self.generate_constraint(e),
3575 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3576 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3577 Expression::Copy(e) => self.generate_copy(e),
3578 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3579 Expression::Corr(e) => self.generate_corr(e),
3580 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3581 Expression::CovarPop(e) => self.generate_covar_pop(e),
3582 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3583 Expression::Credentials(e) => self.generate_credentials(e),
3584 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3585 Expression::Cte(e) => self.generate_cte(e),
3586 Expression::Cube(e) => self.generate_cube(e),
3587 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3588 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3589 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3590 Expression::CurrentUser(e) => self.generate_current_user(e),
3591 Expression::DPipe(e) => self.generate_d_pipe(e),
3592 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3593 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3594 Expression::Date(e) => self.generate_date_func(e),
3595 Expression::DateBin(e) => self.generate_date_bin(e),
3596 Expression::DateFormatColumnConstraint(e) => {
3597 self.generate_date_format_column_constraint(e)
3598 }
3599 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3600 Expression::Datetime(e) => self.generate_datetime(e),
3601 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3602 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3603 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3604 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3605 Expression::Dayname(e) => self.generate_dayname(e),
3606 Expression::Declare(e) => self.generate_declare(e),
3607 Expression::DeclareItem(e) => self.generate_declare_item(e),
3608 Expression::DecodeCase(e) => self.generate_decode_case(e),
3609 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3610 Expression::DecompressString(e) => self.generate_decompress_string(e),
3611 Expression::Decrypt(e) => self.generate_decrypt(e),
3612 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3613 Expression::DefaultColumnConstraint(e) => {
3614 self.write_keyword("DEFAULT");
3615 self.write_space();
3616 self.generate_expression(&e.this)?;
3617 if let Some(ref col) = e.for_column {
3618 self.write_space();
3619 self.write_keyword("FOR");
3620 self.write_space();
3621 self.generate_identifier(col)?;
3622 }
3623 Ok(())
3624 }
3625 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3626 Expression::Detach(e) => self.generate_detach(e),
3627 Expression::DictProperty(e) => self.generate_dict_property(e),
3628 Expression::DictRange(e) => self.generate_dict_range(e),
3629 Expression::Directory(e) => self.generate_directory(e),
3630 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3631 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3632 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3633 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3634 Expression::DotProduct(e) => self.generate_dot_product(e),
3635 Expression::DropPartition(e) => self.generate_drop_partition(e),
3636 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3637 Expression::Elt(e) => self.generate_elt(e),
3638 Expression::Encode(e) => self.generate_encode(e),
3639 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3640 Expression::Encrypt(e) => self.generate_encrypt(e),
3641 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3642 Expression::EngineProperty(e) => self.generate_engine_property(e),
3643 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3644 Expression::EphemeralColumnConstraint(e) => {
3645 self.generate_ephemeral_column_constraint(e)
3646 }
3647 Expression::EqualNull(e) => self.generate_equal_null(e),
3648 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3649 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3650 Expression::Export(e) => self.generate_export(e),
3651 Expression::ExternalProperty(e) => self.generate_external_property(e),
3652 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3653 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3654 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3655 Expression::Fetch(e) => self.generate_fetch(e),
3656 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3657 Expression::Filter(e) => self.generate_filter(e),
3658 Expression::Float64(e) => self.generate_float64(e),
3659 Expression::ForIn(e) => self.generate_for_in(e),
3660 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3661 Expression::Format(e) => self.generate_format(e),
3662 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3663 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3664 Expression::From(e) => self.generate_from(e),
3665 Expression::FromBase(e) => self.generate_from_base(e),
3666 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3667 Expression::GapFill(e) => self.generate_gap_fill(e),
3668 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3669 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3670 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3671 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3672 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3673 self.generate_generated_as_identity_column_constraint(e)
3674 }
3675 Expression::GeneratedAsRowColumnConstraint(e) => {
3676 self.generate_generated_as_row_column_constraint(e)
3677 }
3678 Expression::Get(e) => self.generate_get(e),
3679 Expression::GetExtract(e) => self.generate_get_extract(e),
3680 Expression::Getbit(e) => self.generate_getbit(e),
3681 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3682 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3683 Expression::Group(e) => self.generate_group(e),
3684 Expression::GroupBy(e) => self.generate_group_by(e),
3685 Expression::Grouping(e) => self.generate_grouping(e),
3686 Expression::GroupingId(e) => self.generate_grouping_id(e),
3687 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3688 Expression::HashAgg(e) => self.generate_hash_agg(e),
3689 Expression::Having(e) => self.generate_having(e),
3690 Expression::HavingMax(e) => self.generate_having_max(e),
3691 Expression::Heredoc(e) => self.generate_heredoc(e),
3692 Expression::HexEncode(e) => self.generate_hex_encode(e),
3693 Expression::Hll(e) => self.generate_hll(e),
3694 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3695 Expression::IncludeProperty(e) => self.generate_include_property(e),
3696 Expression::Index(e) => self.generate_index(e),
3697 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3698 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3699 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3700 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3701 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3702 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3703 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3704 Expression::Install(e) => self.generate_install(e),
3705 Expression::IntervalOp(e) => self.generate_interval_op(e),
3706 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3707 Expression::IntoClause(e) => self.generate_into_clause(e),
3708 Expression::Introducer(e) => self.generate_introducer(e),
3709 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3710 Expression::JSON(e) => self.generate_json(e),
3711 Expression::JSONArray(e) => self.generate_json_array(e),
3712 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3713 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3714 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3715 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3716 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3717 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3718 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3719 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3720 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3721 Expression::JSONExists(e) => self.generate_json_exists(e),
3722 Expression::JSONCast(e) => self.generate_json_cast(e),
3723 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3724 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3725 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3726 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3727 Expression::JSONFormat(e) => self.generate_json_format(e),
3728 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3729 Expression::JSONKeys(e) => self.generate_json_keys(e),
3730 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3731 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3732 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3733 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3734 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3735 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3736 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3737 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3738 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3739 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3740 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3741 Expression::JSONRemove(e) => self.generate_json_remove(e),
3742 Expression::JSONSchema(e) => self.generate_json_schema(e),
3743 Expression::JSONSet(e) => self.generate_json_set(e),
3744 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3745 Expression::JSONTable(e) => self.generate_json_table(e),
3746 Expression::JSONType(e) => self.generate_json_type(e),
3747 Expression::JSONValue(e) => self.generate_json_value(e),
3748 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3749 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3750 Expression::JoinHint(e) => self.generate_join_hint(e),
3751 Expression::JournalProperty(e) => self.generate_journal_property(e),
3752 Expression::LanguageProperty(e) => self.generate_language_property(e),
3753 Expression::Lateral(e) => self.generate_lateral(e),
3754 Expression::LikeProperty(e) => self.generate_like_property(e),
3755 Expression::Limit(e) => self.generate_limit(e),
3756 Expression::LimitOptions(e) => self.generate_limit_options(e),
3757 Expression::List(e) => self.generate_list(e),
3758 Expression::ToMap(e) => self.generate_tomap(e),
3759 Expression::Localtime(e) => self.generate_localtime(e),
3760 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3761 Expression::LocationProperty(e) => self.generate_location_property(e),
3762 Expression::Lock(e) => self.generate_lock(e),
3763 Expression::LockProperty(e) => self.generate_lock_property(e),
3764 Expression::LockingProperty(e) => self.generate_locking_property(e),
3765 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3766 Expression::LogProperty(e) => self.generate_log_property(e),
3767 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3768 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3769 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3770 Expression::MakeInterval(e) => self.generate_make_interval(e),
3771 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3772 Expression::Map(e) => self.generate_map(e),
3773 Expression::MapCat(e) => self.generate_map_cat(e),
3774 Expression::MapDelete(e) => self.generate_map_delete(e),
3775 Expression::MapInsert(e) => self.generate_map_insert(e),
3776 Expression::MapPick(e) => self.generate_map_pick(e),
3777 Expression::MaskingPolicyColumnConstraint(e) => {
3778 self.generate_masking_policy_column_constraint(e)
3779 }
3780 Expression::MatchAgainst(e) => self.generate_match_against(e),
3781 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3782 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3783 Expression::Merge(e) => self.generate_merge(e),
3784 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3785 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3786 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3787 Expression::Minhash(e) => self.generate_minhash(e),
3788 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3789 Expression::Monthname(e) => self.generate_monthname(e),
3790 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3791 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3792 Expression::Normal(e) => self.generate_normal(e),
3793 Expression::Normalize(e) => self.generate_normalize(e),
3794 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3795 Expression::Nullif(e) => self.generate_nullif(e),
3796 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3797 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3798 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3799 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3800 Expression::Offset(e) => self.generate_offset(e),
3801 Expression::Qualify(e) => self.generate_qualify(e),
3802 Expression::OnCluster(e) => self.generate_on_cluster(e),
3803 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3804 Expression::OnCondition(e) => self.generate_on_condition(e),
3805 Expression::OnConflict(e) => self.generate_on_conflict(e),
3806 Expression::OnProperty(e) => self.generate_on_property(e),
3807 Expression::Opclass(e) => self.generate_opclass(e),
3808 Expression::OpenJSON(e) => self.generate_open_json(e),
3809 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3810 Expression::Operator(e) => self.generate_operator(e),
3811 Expression::OrderBy(e) => self.generate_order_by(e),
3812 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3813 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3814 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3815 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3816 Expression::ParseIp(e) => self.generate_parse_ip(e),
3817 Expression::ParseJSON(e) => self.generate_parse_json(e),
3818 Expression::ParseTime(e) => self.generate_parse_time(e),
3819 Expression::ParseUrl(e) => self.generate_parse_url(e),
3820 Expression::Partition(e) => self.generate_partition_expr(e),
3821 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3822 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3823 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3824 Expression::PartitionByRangePropertyDynamic(e) => {
3825 self.generate_partition_by_range_property_dynamic(e)
3826 }
3827 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3828 Expression::PartitionList(e) => self.generate_partition_list(e),
3829 Expression::PartitionRange(e) => self.generate_partition_range(e),
3830 Expression::PartitionByProperty(e) => self.generate_partition_by_property(e),
3831 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3832 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3833 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3834 Expression::PeriodForSystemTimeConstraint(e) => {
3835 self.generate_period_for_system_time_constraint(e)
3836 }
3837 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3838 Expression::PivotAny(e) => self.generate_pivot_any(e),
3839 Expression::Predict(e) => self.generate_predict(e),
3840 Expression::PreviousDay(e) => self.generate_previous_day(e),
3841 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3842 Expression::PrimaryKeyColumnConstraint(e) => {
3843 self.generate_primary_key_column_constraint(e)
3844 }
3845 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3846 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3847 Expression::OptionsProperty(e) => self.generate_options_property(e),
3848 Expression::Properties(e) => self.generate_properties(e),
3849 Expression::Property(e) => self.generate_property(e),
3850 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3851 Expression::Put(e) => self.generate_put(e),
3852 Expression::Quantile(e) => self.generate_quantile(e),
3853 Expression::QueryBand(e) => self.generate_query_band(e),
3854 Expression::QueryOption(e) => self.generate_query_option(e),
3855 Expression::QueryTransform(e) => self.generate_query_transform(e),
3856 Expression::Randn(e) => self.generate_randn(e),
3857 Expression::Randstr(e) => self.generate_randstr(e),
3858 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3859 Expression::RangeN(e) => self.generate_range_n(e),
3860 Expression::ReadCSV(e) => self.generate_read_csv(e),
3861 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3862 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3863 Expression::Reduce(e) => self.generate_reduce(e),
3864 Expression::Reference(e) => self.generate_reference(e),
3865 Expression::Refresh(e) => self.generate_refresh(e),
3866 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3867 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3868 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3869 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3870 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3871 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3872 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3873 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3874 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3875 Expression::RegrCount(e) => self.generate_regr_count(e),
3876 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3877 Expression::RegrR2(e) => self.generate_regr_r2(e),
3878 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3879 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3880 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3881 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3882 Expression::RegrValx(e) => self.generate_regr_valx(e),
3883 Expression::RegrValy(e) => self.generate_regr_valy(e),
3884 Expression::RemoteWithConnectionModelProperty(e) => {
3885 self.generate_remote_with_connection_model_property(e)
3886 }
3887 Expression::RenameColumn(e) => self.generate_rename_column(e),
3888 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3889 Expression::Returning(e) => self.generate_returning(e),
3890 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3891 Expression::Rollback(e) => self.generate_rollback(e),
3892 Expression::Rollup(e) => self.generate_rollup(e),
3893 Expression::RowFormatDelimitedProperty(e) => {
3894 self.generate_row_format_delimited_property(e)
3895 }
3896 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3897 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3898 Expression::SHA2(e) => self.generate_sha2(e),
3899 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3900 Expression::SafeAdd(e) => self.generate_safe_add(e),
3901 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3902 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3903 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3904 Expression::SampleProperty(e) => self.generate_sample_property(e),
3905 Expression::Schema(e) => self.generate_schema(e),
3906 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3907 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3908 Expression::Search(e) => self.generate_search(e),
3909 Expression::SearchIp(e) => self.generate_search_ip(e),
3910 Expression::SecurityProperty(e) => self.generate_security_property(e),
3911 Expression::SemanticView(e) => self.generate_semantic_view(e),
3912 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3913 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3914 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3915 Expression::Set(e) => self.generate_set(e),
3916 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3917 Expression::SetItem(e) => self.generate_set_item(e),
3918 Expression::SetOperation(e) => self.generate_set_operation(e),
3919 Expression::SetProperty(e) => self.generate_set_property(e),
3920 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3921 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3922 Expression::Slice(e) => self.generate_slice(e),
3923 Expression::SortArray(e) => self.generate_sort_array(e),
3924 Expression::SortBy(e) => self.generate_sort_by(e),
3925 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3926 Expression::SplitPart(e) => self.generate_split_part(e),
3927 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3928 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3929 Expression::StDistance(e) => self.generate_st_distance(e),
3930 Expression::StPoint(e) => self.generate_st_point(e),
3931 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3932 Expression::StandardHash(e) => self.generate_standard_hash(e),
3933 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3934 Expression::StrPosition(e) => self.generate_str_position(e),
3935 Expression::StrToDate(e) => self.generate_str_to_date(e),
3936 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3937 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3938 Expression::StrToMap(e) => self.generate_str_to_map(e),
3939 Expression::StrToTime(e) => self.generate_str_to_time(e),
3940 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3941 Expression::StringToArray(e) => self.generate_string_to_array(e),
3942 Expression::Struct(e) => self.generate_struct(e),
3943 Expression::Stuff(e) => self.generate_stuff(e),
3944 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3945 Expression::Summarize(e) => self.generate_summarize(e),
3946 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3947 Expression::TableAlias(e) => self.generate_table_alias(e),
3948 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3949 Expression::RowsFrom(e) => self.generate_rows_from(e),
3950 Expression::TableSample(e) => self.generate_table_sample(e),
3951 Expression::Tag(e) => self.generate_tag(e),
3952 Expression::Tags(e) => self.generate_tags(e),
3953 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3954 Expression::Time(e) => self.generate_time_func(e),
3955 Expression::TimeAdd(e) => self.generate_time_add(e),
3956 Expression::TimeDiff(e) => self.generate_time_diff(e),
3957 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3958 Expression::TimeSlice(e) => self.generate_time_slice(e),
3959 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3960 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3961 Expression::TimeSub(e) => self.generate_time_sub(e),
3962 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3963 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3964 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3965 Expression::TimeUnit(e) => self.generate_time_unit(e),
3966 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3967 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3968 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3969 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3970 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3971 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3972 Expression::ToBinary(e) => self.generate_to_binary(e),
3973 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3974 Expression::ToChar(e) => self.generate_to_char(e),
3975 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3976 Expression::ToDouble(e) => self.generate_to_double(e),
3977 Expression::ToFile(e) => self.generate_to_file(e),
3978 Expression::ToNumber(e) => self.generate_to_number(e),
3979 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3980 Expression::Transaction(e) => self.generate_transaction(e),
3981 Expression::Transform(e) => self.generate_transform(e),
3982 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3983 Expression::TransientProperty(e) => self.generate_transient_property(e),
3984 Expression::Translate(e) => self.generate_translate(e),
3985 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
3986 Expression::TruncateTable(e) => self.generate_truncate_table(e),
3987 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
3988 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
3989 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
3990 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
3991 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
3992 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
3993 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
3994 Expression::Unhex(e) => self.generate_unhex(e),
3995 Expression::UnicodeString(e) => self.generate_unicode_string(e),
3996 Expression::Uniform(e) => self.generate_uniform(e),
3997 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
3998 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
3999 Expression::RollupProperty(e) => self.generate_rollup_property(e),
4000 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
4001 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
4002 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
4003 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
4004 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
4005 Expression::UtcTime(e) => self.generate_utc_time(e),
4006 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
4007 Expression::Uuid(e) => self.generate_uuid(e),
4008 Expression::Var(v) => {
4009 if matches!(self.config.dialect, Some(DialectType::MySQL))
4010 && v.this.len() > 2
4011 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
4012 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
4013 {
4014 return self.generate_identifier(&Identifier {
4015 name: v.this.clone(),
4016 quoted: true,
4017 trailing_comments: Vec::new(),
4018 span: None,
4019 });
4020 }
4021 self.write(&v.this);
4022 Ok(())
4023 }
4024 Expression::Variadic(e) => {
4025 self.write_keyword("VARIADIC");
4026 self.write_space();
4027 self.generate_expression(&e.this)?;
4028 Ok(())
4029 }
4030 Expression::VarMap(e) => self.generate_var_map(e),
4031 Expression::VectorSearch(e) => self.generate_vector_search(e),
4032 Expression::Version(e) => self.generate_version(e),
4033 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
4034 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
4035 Expression::WatermarkColumnConstraint(e) => {
4036 self.generate_watermark_column_constraint(e)
4037 }
4038 Expression::Week(e) => self.generate_week(e),
4039 Expression::When(e) => self.generate_when(e),
4040 Expression::Whens(e) => self.generate_whens(e),
4041 Expression::Where(e) => self.generate_where(e),
4042 Expression::WidthBucket(e) => self.generate_width_bucket(e),
4043 Expression::Window(e) => self.generate_window(e),
4044 Expression::WindowSpec(e) => self.generate_window_spec(e),
4045 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
4046 Expression::WithFill(e) => self.generate_with_fill(e),
4047 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
4048 Expression::WithOperator(e) => self.generate_with_operator(e),
4049 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
4050 Expression::WithSchemaBindingProperty(e) => {
4051 self.generate_with_schema_binding_property(e)
4052 }
4053 Expression::WithSystemVersioningProperty(e) => {
4054 self.generate_with_system_versioning_property(e)
4055 }
4056 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
4057 Expression::XMLElement(e) => self.generate_xml_element(e),
4058 Expression::XMLGet(e) => self.generate_xml_get(e),
4059 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
4060 Expression::XMLTable(e) => self.generate_xml_table(e),
4061 Expression::Xor(e) => self.generate_xor(e),
4062 Expression::Zipf(e) => self.generate_zipf(e),
4063 _ => self.write_unsupported_comment("unsupported expression"),
4064 }
4065 }
4066
4067 fn generate_select(&mut self, select: &Select) -> Result<()> {
4068 use crate::dialects::DialectType;
4069
4070 if let Some(exclude) = &select.exclude {
4074 if !exclude.is_empty() && !matches!(self.config.dialect, Some(DialectType::Redshift)) {
4075 let mut inner_select = select.clone();
4077 inner_select.exclude = None;
4078 let inner_expr = Expression::Select(Box::new(inner_select));
4079
4080 let subquery = crate::expressions::Subquery {
4082 this: inner_expr,
4083 alias: None,
4084 column_aliases: Vec::new(),
4085 alias_explicit_as: false,
4086 alias_keyword: None,
4087 order_by: None,
4088 limit: None,
4089 offset: None,
4090 distribute_by: None,
4091 sort_by: None,
4092 cluster_by: None,
4093 lateral: false,
4094 modifiers_inside: false,
4095 trailing_comments: Vec::new(),
4096 inferred_type: None,
4097 };
4098
4099 let star = Expression::Star(crate::expressions::Star {
4101 table: None,
4102 except: Some(
4103 exclude
4104 .iter()
4105 .map(|e| match e {
4106 Expression::Column(col) => col.name.clone(),
4107 Expression::Identifier(id) => id.clone(),
4108 _ => crate::expressions::Identifier::new("unknown".to_string()),
4109 })
4110 .collect(),
4111 ),
4112 replace: None,
4113 rename: None,
4114 trailing_comments: Vec::new(),
4115 span: None,
4116 });
4117
4118 let outer_select = Select {
4119 expressions: vec![star],
4120 from: Some(crate::expressions::From {
4121 expressions: vec![Expression::Subquery(Box::new(subquery))],
4122 }),
4123 ..Select::new()
4124 };
4125
4126 return self.generate_select(&outer_select);
4127 }
4128 }
4129
4130 for comment in &select.leading_comments {
4132 self.write_formatted_comment(comment);
4133 self.write(" ");
4134 }
4135
4136 if let Some(with) = &select.with {
4138 self.generate_with(with)?;
4139 if self.config.pretty {
4140 self.write_newline();
4141 self.write_indent();
4142 } else {
4143 self.write_space();
4144 }
4145 }
4146
4147 for comment in &select.post_select_comments {
4150 self.write_formatted_comment(comment);
4151 self.write(" ");
4152 }
4153
4154 self.write_keyword("SELECT");
4155
4156 if let Some(hint) = &select.hint {
4158 self.generate_hint(hint)?;
4159 }
4160
4161 let use_top_from_limit = matches!(
4165 self.config.dialect,
4166 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4167 ) && select.top.is_none()
4168 && select.limit.is_some()
4169 && select.offset.is_none(); let is_top_dialect = matches!(
4174 self.config.dialect,
4175 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
4176 );
4177 let keep_top_verbatim = !is_top_dialect
4178 && select.limit.is_none()
4179 && select
4180 .top
4181 .as_ref()
4182 .map_or(false, |top| top.percent || top.with_ties);
4183
4184 if select.distinct && (is_top_dialect || select.top.is_some()) {
4185 self.write_space();
4186 self.write_keyword("DISTINCT");
4187 }
4188
4189 if is_top_dialect || keep_top_verbatim {
4190 if let Some(top) = &select.top {
4191 self.write_space();
4192 self.write_keyword("TOP");
4193 if top.parenthesized {
4194 if matches!(&top.this, Expression::Subquery(_) | Expression::Paren(_)) {
4195 self.write_space();
4196 self.generate_expression(&top.this)?;
4197 } else {
4198 self.write(" (");
4199 self.generate_expression(&top.this)?;
4200 self.write(")");
4201 }
4202 } else {
4203 self.write_space();
4204 self.generate_expression(&top.this)?;
4205 }
4206 if top.percent {
4207 self.write_space();
4208 self.write_keyword("PERCENT");
4209 }
4210 if top.with_ties {
4211 self.write_space();
4212 self.write_keyword("WITH TIES");
4213 }
4214 } else if use_top_from_limit {
4215 if let Some(limit) = &select.limit {
4217 self.write_space();
4218 self.write_keyword("TOP");
4219 let is_simple_literal = matches!(&limit.this, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)));
4221 if is_simple_literal {
4222 self.write_space();
4223 self.generate_expression(&limit.this)?;
4224 } else {
4225 self.write(" (");
4226 self.generate_expression(&limit.this)?;
4227 self.write(")");
4228 }
4229 }
4230 }
4231 }
4232
4233 if select.distinct && !is_top_dialect && select.top.is_none() {
4234 self.write_space();
4235 self.write_keyword("DISTINCT");
4236 }
4237
4238 if let Some(distinct_on) = &select.distinct_on {
4240 self.write_space();
4241 self.write_keyword("ON");
4242 self.write(" (");
4243 for (i, expr) in distinct_on.iter().enumerate() {
4244 if i > 0 {
4245 self.write(", ");
4246 }
4247 self.generate_expression(expr)?;
4248 }
4249 self.write(")");
4250 }
4251
4252 for modifier in &select.operation_modifiers {
4254 self.write_space();
4255 self.write_keyword(modifier);
4256 }
4257
4258 if let Some(kind) = &select.kind {
4260 self.write_space();
4261 self.write_keyword("AS");
4262 self.write_space();
4263 self.write_keyword(kind);
4264 }
4265
4266 if !select.expressions.is_empty() {
4268 if self.config.pretty {
4269 self.write_newline();
4270 self.indent_level += 1;
4271 } else {
4272 self.write_space();
4273 }
4274 }
4275
4276 for (i, expr) in select.expressions.iter().enumerate() {
4277 if i > 0 {
4278 self.write(",");
4279 if self.config.pretty {
4280 self.write_newline();
4281 } else {
4282 self.write_space();
4283 }
4284 }
4285 if self.config.pretty {
4286 self.write_indent();
4287 }
4288 self.generate_expression(expr)?;
4289 }
4290
4291 if self.config.pretty && !select.expressions.is_empty() {
4292 self.indent_level -= 1;
4293 }
4294
4295 if let Some(exclude) = &select.exclude {
4300 if !exclude.is_empty() && matches!(self.config.dialect, Some(DialectType::Redshift)) {
4301 self.write_space();
4302 self.write_keyword("EXCLUDE");
4303 self.write(" (");
4304 for (i, col) in exclude.iter().enumerate() {
4305 if i > 0 {
4306 self.write(", ");
4307 }
4308 self.generate_expression(col)?;
4309 }
4310 self.write(")");
4311 }
4312 }
4313
4314 if let Some(into) = &select.into {
4317 if self.config.pretty {
4318 self.write_newline();
4319 self.write_indent();
4320 } else {
4321 self.write_space();
4322 }
4323 if into.bulk_collect {
4324 self.write_keyword("BULK COLLECT INTO");
4325 } else {
4326 self.write_keyword("INTO");
4327 }
4328 if into.temporary {
4329 self.write_space();
4330 self.write_keyword("TEMPORARY");
4331 }
4332 if into.unlogged {
4333 self.write_space();
4334 self.write_keyword("UNLOGGED");
4335 }
4336 self.write_space();
4337 if !into.expressions.is_empty() {
4339 for (i, expr) in into.expressions.iter().enumerate() {
4340 if i > 0 {
4341 self.write(", ");
4342 }
4343 self.generate_expression(expr)?;
4344 }
4345 } else {
4346 self.generate_expression(&into.this)?;
4347 }
4348 }
4349
4350 if let Some(from) = &select.from {
4352 if self.config.pretty {
4353 self.write_newline();
4354 self.write_indent();
4355 } else {
4356 self.write_space();
4357 }
4358 self.write_keyword("FROM");
4359 self.write_space();
4360
4361 let has_tablesample = from
4366 .expressions
4367 .iter()
4368 .any(|e| matches!(e, Expression::TableSample(_)));
4369 let is_cross_join_dialect = matches!(
4370 self.config.dialect,
4371 Some(DialectType::BigQuery)
4372 | Some(DialectType::Hive)
4373 | Some(DialectType::Spark)
4374 | Some(DialectType::Databricks)
4375 | Some(DialectType::SQLite)
4376 | Some(DialectType::ClickHouse)
4377 );
4378 let source_is_same_as_target = self.config.source_dialect.is_some()
4381 && self.config.source_dialect == self.config.dialect;
4382 let source_is_cross_join_dialect = matches!(
4383 self.config.source_dialect,
4384 Some(DialectType::BigQuery)
4385 | Some(DialectType::Hive)
4386 | Some(DialectType::Spark)
4387 | Some(DialectType::Databricks)
4388 | Some(DialectType::SQLite)
4389 | Some(DialectType::ClickHouse)
4390 );
4391 let use_cross_join = !has_tablesample
4392 && is_cross_join_dialect
4393 && (source_is_same_as_target
4394 || source_is_cross_join_dialect
4395 || self.config.source_dialect.is_none());
4396
4397 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4399
4400 for (i, expr) in from.expressions.iter().enumerate() {
4401 if i > 0 {
4402 if use_cross_join {
4403 self.write(" CROSS JOIN ");
4404 } else {
4405 self.write(", ");
4406 }
4407 }
4408 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4409 self.write("(");
4410 self.generate_expression(expr)?;
4411 self.write(")");
4412 } else {
4413 self.generate_expression(expr)?;
4414 }
4415 let leading = Self::extract_table_leading_comments(expr);
4418 for comment in &leading {
4419 self.write_space();
4420 self.write_formatted_comment(comment);
4421 }
4422 }
4423 }
4424
4425 if self.config.pretty {
4429 self.generate_joins_with_nesting(&select.joins)?;
4430 } else {
4431 for join in &select.joins {
4432 self.generate_join(join)?;
4433 }
4434 for join in select.joins.iter().rev() {
4436 if join.deferred_condition {
4437 self.generate_join_condition(join)?;
4438 }
4439 }
4440 }
4441
4442 for (lv_idx, lateral_view) in select.lateral_views.iter().enumerate() {
4444 self.generate_lateral_view(lateral_view, lv_idx)?;
4445 }
4446
4447 if let Some(prewhere) = &select.prewhere {
4449 self.write_clause_condition("PREWHERE", prewhere)?;
4450 }
4451
4452 if let Some(where_clause) = &select.where_clause {
4454 self.write_clause_condition("WHERE", &where_clause.this)?;
4455 }
4456
4457 if let Some(connect) = &select.connect {
4459 self.generate_connect(connect)?;
4460 }
4461
4462 if let Some(group_by) = &select.group_by {
4464 if self.config.pretty {
4465 for comment in &group_by.comments {
4467 self.write_newline();
4468 self.write_indent();
4469 self.write_formatted_comment(comment);
4470 }
4471 self.write_newline();
4472 self.write_indent();
4473 } else {
4474 self.write_space();
4475 for comment in &group_by.comments {
4477 self.write_formatted_comment(comment);
4478 self.write_space();
4479 }
4480 }
4481 let clickhouse_bare_modifiers =
4482 matches!(self.config.dialect, Some(DialectType::ClickHouse))
4483 && group_by.all.is_none()
4484 && (group_by.totals || !group_by.expressions.is_empty())
4485 && group_by.expressions.iter().all(|expr| match expr {
4486 Expression::Cube(c) => c.expressions.is_empty(),
4487 Expression::Rollup(r) => r.expressions.is_empty(),
4488 _ => false,
4489 });
4490
4491 if clickhouse_bare_modifiers {
4492 let trailing_cube = group_by
4493 .expressions
4494 .iter()
4495 .any(|expr| matches!(expr, Expression::Cube(c) if c.expressions.is_empty()));
4496 let trailing_rollup = group_by
4497 .expressions
4498 .iter()
4499 .any(|expr| matches!(expr, Expression::Rollup(r) if r.expressions.is_empty()));
4500
4501 if trailing_cube {
4502 self.write_keyword("WITH CUBE");
4503 } else if trailing_rollup {
4504 self.write_keyword("WITH ROLLUP");
4505 }
4506
4507 if group_by.totals {
4508 if trailing_cube || trailing_rollup {
4509 self.write_space();
4510 }
4511 self.write_keyword("WITH TOTALS");
4512 }
4513 } else {
4514 self.write_keyword("GROUP BY");
4515 match group_by.all {
4517 Some(true) => {
4518 self.write_space();
4519 self.write_keyword("ALL");
4520 }
4521 Some(false) => {
4522 self.write_space();
4523 self.write_keyword("DISTINCT");
4524 }
4525 None => {}
4526 }
4527 if !group_by.expressions.is_empty() {
4528 let mut trailing_cube = false;
4531 let mut trailing_rollup = false;
4532 let mut plain_expressions: Vec<&Expression> = Vec::new();
4533 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4534 let mut cube_expressions: Vec<&Expression> = Vec::new();
4535 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4536
4537 for expr in &group_by.expressions {
4538 match expr {
4539 Expression::Cube(c) if c.expressions.is_empty() => {
4540 trailing_cube = true;
4541 }
4542 Expression::Rollup(r) if r.expressions.is_empty() => {
4543 trailing_rollup = true;
4544 }
4545 Expression::Function(f) if f.name == "CUBE" => {
4546 cube_expressions.push(expr);
4547 }
4548 Expression::Function(f) if f.name == "ROLLUP" => {
4549 rollup_expressions.push(expr);
4550 }
4551 Expression::Function(f) if f.name == "GROUPING SETS" => {
4552 grouping_sets_expressions.push(expr);
4553 }
4554 _ => {
4555 plain_expressions.push(expr);
4556 }
4557 }
4558 }
4559
4560 let mut regular_expressions: Vec<&Expression> = Vec::new();
4562 regular_expressions.extend(plain_expressions);
4563 regular_expressions.extend(grouping_sets_expressions);
4564 regular_expressions.extend(cube_expressions);
4565 regular_expressions.extend(rollup_expressions);
4566
4567 if self.config.pretty {
4568 self.write_newline();
4569 self.indent_level += 1;
4570 self.write_indent();
4571 } else {
4572 self.write_space();
4573 }
4574
4575 for (i, expr) in regular_expressions.iter().enumerate() {
4576 if i > 0 {
4577 if self.config.pretty {
4578 self.write(",");
4579 self.write_newline();
4580 self.write_indent();
4581 } else {
4582 self.write(", ");
4583 }
4584 }
4585 self.generate_expression(expr)?;
4586 }
4587
4588 if self.config.pretty {
4589 self.indent_level -= 1;
4590 }
4591
4592 if trailing_cube {
4594 self.write_space();
4595 self.write_keyword("WITH CUBE");
4596 } else if trailing_rollup {
4597 self.write_space();
4598 self.write_keyword("WITH ROLLUP");
4599 }
4600 }
4601
4602 if group_by.totals {
4604 self.write_space();
4605 self.write_keyword("WITH TOTALS");
4606 }
4607 }
4608 }
4609
4610 if let Some(having) = &select.having {
4612 if self.config.pretty {
4613 for comment in &having.comments {
4615 self.write_newline();
4616 self.write_indent();
4617 self.write_formatted_comment(comment);
4618 }
4619 } else {
4620 for comment in &having.comments {
4621 self.write_space();
4622 self.write_formatted_comment(comment);
4623 }
4624 }
4625 self.write_clause_condition("HAVING", &having.this)?;
4626 }
4627
4628 if select.qualify_after_window {
4630 if let Some(windows) = &select.windows {
4632 self.write_window_clause(windows)?;
4633 }
4634 if let Some(qualify) = &select.qualify {
4635 self.write_clause_condition("QUALIFY", &qualify.this)?;
4636 }
4637 } else {
4638 if let Some(qualify) = &select.qualify {
4640 self.write_clause_condition("QUALIFY", &qualify.this)?;
4641 }
4642 if let Some(windows) = &select.windows {
4643 self.write_window_clause(windows)?;
4644 }
4645 }
4646
4647 if let Some(distribute_by) = &select.distribute_by {
4649 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4650 }
4651
4652 if let Some(cluster_by) = &select.cluster_by {
4654 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4655 }
4656
4657 if let Some(sort_by) = &select.sort_by {
4659 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4660 }
4661
4662 if let Some(order_by) = &select.order_by {
4664 if self.config.pretty {
4665 for comment in &order_by.comments {
4667 self.write_newline();
4668 self.write_indent();
4669 self.write_formatted_comment(comment);
4670 }
4671 } else {
4672 for comment in &order_by.comments {
4673 self.write_space();
4674 self.write_formatted_comment(comment);
4675 }
4676 }
4677 let keyword = if order_by.siblings {
4678 "ORDER SIBLINGS BY"
4679 } else {
4680 "ORDER BY"
4681 };
4682 self.write_order_clause(keyword, &order_by.expressions)?;
4683 }
4684
4685 if select.order_by.is_none()
4687 && select.fetch.is_some()
4688 && matches!(
4689 self.config.dialect,
4690 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4691 )
4692 {
4693 if self.config.pretty {
4694 self.write_newline();
4695 self.write_indent();
4696 } else {
4697 self.write_space();
4698 }
4699 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4700 }
4701
4702 let is_presto_like = matches!(
4707 self.config.dialect,
4708 Some(DialectType::Presto) | Some(DialectType::Trino)
4709 );
4710
4711 if is_presto_like && select.offset.is_some() {
4712 if let Some(offset) = &select.offset {
4714 if self.config.pretty {
4715 self.write_newline();
4716 self.write_indent();
4717 } else {
4718 self.write_space();
4719 }
4720 self.write_keyword("OFFSET");
4721 self.write_space();
4722 self.write_limit_expr(&offset.this)?;
4723 if offset.rows == Some(true) {
4724 self.write_space();
4725 self.write_keyword("ROWS");
4726 }
4727 }
4728 if let Some(limit) = &select.limit {
4729 if self.config.pretty {
4730 self.write_newline();
4731 self.write_indent();
4732 } else {
4733 self.write_space();
4734 }
4735 self.write_keyword("LIMIT");
4736 self.write_space();
4737 self.write_limit_expr(&limit.this)?;
4738 if limit.percent {
4739 self.write_space();
4740 self.write_keyword("PERCENT");
4741 }
4742 for comment in &limit.comments {
4744 self.write(" ");
4745 self.write_formatted_comment(comment);
4746 }
4747 }
4748 } else {
4749 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
4751 !fetch.percent
4752 && !fetch.with_ties
4753 && fetch.count.is_some()
4754 && matches!(
4755 self.config.dialect,
4756 Some(DialectType::Spark)
4757 | Some(DialectType::Hive)
4758 | Some(DialectType::DuckDB)
4759 | Some(DialectType::SQLite)
4760 | Some(DialectType::MySQL)
4761 | Some(DialectType::BigQuery)
4762 | Some(DialectType::Databricks)
4763 | Some(DialectType::StarRocks)
4764 | Some(DialectType::Doris)
4765 | Some(DialectType::Athena)
4766 | Some(DialectType::ClickHouse)
4767 | Some(DialectType::Redshift)
4768 )
4769 });
4770
4771 if let Some(limit) = &select.limit {
4773 if !matches!(
4775 self.config.dialect,
4776 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4777 ) {
4778 if self.config.pretty {
4779 self.write_newline();
4780 self.write_indent();
4781 } else {
4782 self.write_space();
4783 }
4784 self.write_keyword("LIMIT");
4785 self.write_space();
4786 self.write_limit_expr(&limit.this)?;
4787 if limit.percent {
4788 self.write_space();
4789 self.write_keyword("PERCENT");
4790 }
4791 for comment in &limit.comments {
4793 self.write(" ");
4794 self.write_formatted_comment(comment);
4795 }
4796 }
4797 }
4798
4799 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
4801 if let Some(top) = &select.top {
4802 if !top.percent && !top.with_ties {
4803 if self.config.pretty {
4804 self.write_newline();
4805 self.write_indent();
4806 } else {
4807 self.write_space();
4808 }
4809 self.write_keyword("LIMIT");
4810 self.write_space();
4811 self.generate_expression(&top.this)?;
4812 }
4813 }
4814 }
4815
4816 if fetch_as_limit && select.offset.is_some() {
4819 if let Some(fetch) = &select.fetch {
4820 if self.config.pretty {
4821 self.write_newline();
4822 self.write_indent();
4823 } else {
4824 self.write_space();
4825 }
4826 self.write_keyword("LIMIT");
4827 self.write_space();
4828 self.generate_expression(fetch.count.as_ref().unwrap())?;
4829 }
4830 }
4831
4832 if let Some(offset) = &select.offset {
4836 if self.config.pretty {
4837 self.write_newline();
4838 self.write_indent();
4839 } else {
4840 self.write_space();
4841 }
4842 if matches!(
4843 self.config.dialect,
4844 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4845 ) {
4846 self.write_keyword("OFFSET");
4848 self.write_space();
4849 self.write_limit_expr(&offset.this)?;
4850 self.write_space();
4851 self.write_keyword("ROWS");
4852 if let Some(limit) = &select.limit {
4854 self.write_space();
4855 self.write_keyword("FETCH NEXT");
4856 self.write_space();
4857 self.write_limit_expr(&limit.this)?;
4858 self.write_space();
4859 self.write_keyword("ROWS ONLY");
4860 }
4861 } else {
4862 self.write_keyword("OFFSET");
4863 self.write_space();
4864 self.write_limit_expr(&offset.this)?;
4865 if offset.rows == Some(true) {
4867 self.write_space();
4868 self.write_keyword("ROWS");
4869 }
4870 }
4871 }
4872 }
4873
4874 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4876 if let Some(limit_by) = &select.limit_by {
4877 if !limit_by.is_empty() {
4878 self.write_space();
4879 self.write_keyword("BY");
4880 self.write_space();
4881 for (i, expr) in limit_by.iter().enumerate() {
4882 if i > 0 {
4883 self.write(", ");
4884 }
4885 self.generate_expression(expr)?;
4886 }
4887 }
4888 }
4889 }
4890
4891 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4893 if let Some(settings) = &select.settings {
4894 if self.config.pretty {
4895 self.write_newline();
4896 self.write_indent();
4897 } else {
4898 self.write_space();
4899 }
4900 self.write_keyword("SETTINGS");
4901 self.write_space();
4902 for (i, expr) in settings.iter().enumerate() {
4903 if i > 0 {
4904 self.write(", ");
4905 }
4906 self.generate_expression(expr)?;
4907 }
4908 }
4909
4910 if let Some(format_expr) = &select.format {
4911 if self.config.pretty {
4912 self.write_newline();
4913 self.write_indent();
4914 } else {
4915 self.write_space();
4916 }
4917 self.write_keyword("FORMAT");
4918 self.write_space();
4919 self.generate_expression(format_expr)?;
4920 }
4921 }
4922
4923 if let Some(fetch) = &select.fetch {
4925 let fetch_already_as_limit = select.offset.is_some()
4927 && !fetch.percent
4928 && !fetch.with_ties
4929 && fetch.count.is_some()
4930 && matches!(
4931 self.config.dialect,
4932 Some(DialectType::Spark)
4933 | Some(DialectType::Hive)
4934 | Some(DialectType::DuckDB)
4935 | Some(DialectType::SQLite)
4936 | Some(DialectType::MySQL)
4937 | Some(DialectType::BigQuery)
4938 | Some(DialectType::Databricks)
4939 | Some(DialectType::StarRocks)
4940 | Some(DialectType::Doris)
4941 | Some(DialectType::Athena)
4942 | Some(DialectType::ClickHouse)
4943 | Some(DialectType::Redshift)
4944 );
4945
4946 if fetch_already_as_limit {
4947 } else {
4949 if self.config.pretty {
4950 self.write_newline();
4951 self.write_indent();
4952 } else {
4953 self.write_space();
4954 }
4955
4956 let use_limit = !fetch.percent
4958 && !fetch.with_ties
4959 && fetch.count.is_some()
4960 && matches!(
4961 self.config.dialect,
4962 Some(DialectType::Spark)
4963 | Some(DialectType::Hive)
4964 | Some(DialectType::DuckDB)
4965 | Some(DialectType::SQLite)
4966 | Some(DialectType::MySQL)
4967 | Some(DialectType::BigQuery)
4968 | Some(DialectType::Databricks)
4969 | Some(DialectType::StarRocks)
4970 | Some(DialectType::Doris)
4971 | Some(DialectType::Athena)
4972 | Some(DialectType::ClickHouse)
4973 | Some(DialectType::Redshift)
4974 );
4975
4976 if use_limit {
4977 self.write_keyword("LIMIT");
4978 self.write_space();
4979 self.generate_expression(fetch.count.as_ref().unwrap())?;
4980 } else {
4981 self.write_keyword("FETCH");
4982 self.write_space();
4983 self.write_keyword(&fetch.direction);
4984 if let Some(ref count) = fetch.count {
4985 self.write_space();
4986 self.generate_expression(count)?;
4987 }
4988 if fetch.percent {
4989 self.write_space();
4990 self.write_keyword("PERCENT");
4991 }
4992 if fetch.rows {
4993 self.write_space();
4994 self.write_keyword("ROWS");
4995 }
4996 if fetch.with_ties {
4997 self.write_space();
4998 self.write_keyword("WITH TIES");
4999 } else {
5000 self.write_space();
5001 self.write_keyword("ONLY");
5002 }
5003 }
5004 } }
5006
5007 if let Some(sample) = &select.sample {
5009 use crate::dialects::DialectType;
5010 if self.config.pretty {
5011 self.write_newline();
5012 } else {
5013 self.write_space();
5014 }
5015
5016 if sample.is_using_sample {
5017 self.write_keyword("USING SAMPLE");
5019 self.generate_sample_body(sample)?;
5020 } else {
5021 self.write_keyword("TABLESAMPLE");
5022
5023 let snowflake_bernoulli =
5025 matches!(self.config.dialect, Some(DialectType::Snowflake))
5026 && !sample.explicit_method;
5027 if snowflake_bernoulli {
5028 self.write_space();
5029 self.write_keyword("BERNOULLI");
5030 }
5031
5032 if matches!(sample.method, SampleMethod::Bucket) {
5034 self.write_space();
5035 self.write("(");
5036 self.write_keyword("BUCKET");
5037 self.write_space();
5038 if let Some(ref num) = sample.bucket_numerator {
5039 self.generate_expression(num)?;
5040 }
5041 self.write_space();
5042 self.write_keyword("OUT OF");
5043 self.write_space();
5044 if let Some(ref denom) = sample.bucket_denominator {
5045 self.generate_expression(denom)?;
5046 }
5047 if let Some(ref field) = sample.bucket_field {
5048 self.write_space();
5049 self.write_keyword("ON");
5050 self.write_space();
5051 self.generate_expression(field)?;
5052 }
5053 self.write(")");
5054 } else if sample.unit_after_size {
5055 if sample.explicit_method && sample.method_before_size {
5057 self.write_space();
5058 match sample.method {
5059 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5060 SampleMethod::System => self.write_keyword("SYSTEM"),
5061 SampleMethod::Block => self.write_keyword("BLOCK"),
5062 SampleMethod::Row => self.write_keyword("ROW"),
5063 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5064 _ => {}
5065 }
5066 }
5067 self.write(" (");
5068 self.generate_expression(&sample.size)?;
5069 self.write_space();
5070 match sample.method {
5071 SampleMethod::Percent => self.write_keyword("PERCENT"),
5072 SampleMethod::Row => self.write_keyword("ROWS"),
5073 SampleMethod::Reservoir => self.write_keyword("ROWS"),
5074 _ => {
5075 self.write_keyword("PERCENT");
5076 }
5077 }
5078 self.write(")");
5079 } else {
5080 self.write_space();
5082 match sample.method {
5083 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5084 SampleMethod::System => self.write_keyword("SYSTEM"),
5085 SampleMethod::Block => self.write_keyword("BLOCK"),
5086 SampleMethod::Row => self.write_keyword("ROW"),
5087 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
5088 SampleMethod::Bucket => {}
5089 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5090 }
5091 self.write(" (");
5092 self.generate_expression(&sample.size)?;
5093 if matches!(sample.method, SampleMethod::Percent) {
5094 self.write_space();
5095 self.write_keyword("PERCENT");
5096 }
5097 self.write(")");
5098 }
5099 }
5100
5101 if let Some(seed) = &sample.seed {
5102 self.write_space();
5103 let use_seed = sample.use_seed_keyword
5105 && !matches!(
5106 self.config.dialect,
5107 Some(crate::dialects::DialectType::Databricks)
5108 | Some(crate::dialects::DialectType::Spark)
5109 );
5110 if use_seed {
5111 self.write_keyword("SEED");
5112 } else {
5113 self.write_keyword("REPEATABLE");
5114 }
5115 self.write(" (");
5116 self.generate_expression(seed)?;
5117 self.write(")");
5118 }
5119 }
5120
5121 if self.config.locking_reads_supported {
5124 for lock in &select.locks {
5125 if self.config.pretty {
5126 self.write_newline();
5127 self.write_indent();
5128 } else {
5129 self.write_space();
5130 }
5131 self.generate_lock(lock)?;
5132 }
5133 }
5134
5135 if !select.for_xml.is_empty() {
5137 if self.config.pretty {
5138 self.write_newline();
5139 self.write_indent();
5140 } else {
5141 self.write_space();
5142 }
5143 self.write_keyword("FOR XML");
5144 for (i, opt) in select.for_xml.iter().enumerate() {
5145 if self.config.pretty {
5146 if i > 0 {
5147 self.write(",");
5148 }
5149 self.write_newline();
5150 self.write_indent();
5151 self.write(" "); } else {
5153 if i > 0 {
5154 self.write(",");
5155 }
5156 self.write_space();
5157 }
5158 self.generate_for_xml_option(opt)?;
5159 }
5160 }
5161
5162 if !select.for_json.is_empty()
5164 && matches!(
5165 self.config.dialect,
5166 None | Some(DialectType::TSQL) | Some(DialectType::Fabric)
5167 )
5168 {
5169 if self.config.pretty {
5170 self.write_newline();
5171 self.write_indent();
5172 } else {
5173 self.write_space();
5174 }
5175 self.write_keyword("FOR JSON");
5176 for (i, opt) in select.for_json.iter().enumerate() {
5177 if self.config.pretty {
5178 if i > 0 {
5179 self.write(",");
5180 }
5181 self.write_newline();
5182 self.write_indent();
5183 self.write(" "); } else {
5185 if i > 0 {
5186 self.write(",");
5187 }
5188 self.write_space();
5189 }
5190 self.generate_for_xml_option(opt)?;
5191 }
5192 }
5193
5194 if let Some(ref option) = select.option {
5196 if matches!(
5197 self.config.dialect,
5198 Some(crate::dialects::DialectType::TSQL)
5199 | Some(crate::dialects::DialectType::Fabric)
5200 ) {
5201 self.write_space();
5202 self.write(option);
5203 }
5204 }
5205
5206 Ok(())
5207 }
5208
5209 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
5211 match opt {
5212 Expression::QueryOption(qo) => {
5213 if let Expression::Var(var) = &*qo.this {
5215 self.write(&var.this);
5216 } else {
5217 self.generate_expression(&qo.this)?;
5218 }
5219 if let Some(expr) = &qo.expression {
5221 self.write("(");
5222 self.generate_expression(expr)?;
5223 self.write(")");
5224 }
5225 }
5226 _ => {
5227 self.generate_expression(opt)?;
5228 }
5229 }
5230 Ok(())
5231 }
5232
5233 fn generate_with(&mut self, with: &With) -> Result<()> {
5234 use crate::dialects::DialectType;
5235
5236 for comment in &with.leading_comments {
5238 self.write_formatted_comment(comment);
5239 self.write(" ");
5240 }
5241 self.write_keyword("WITH");
5242 if with.recursive && self.config.cte_recursive_keyword_required {
5243 self.write_space();
5244 self.write_keyword("RECURSIVE");
5245 }
5246 self.write_space();
5247
5248 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
5250
5251 for (i, cte) in with.ctes.iter().enumerate() {
5252 if i > 0 {
5253 self.write(",");
5254 if self.config.pretty {
5255 self.write_space();
5256 } else {
5257 self.write(" ");
5258 }
5259 }
5260 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
5261 self.generate_expression(&cte.this)?;
5262 self.write_space();
5263 self.write_keyword("AS");
5264 self.write_space();
5265 self.generate_identifier(&cte.alias)?;
5266 continue;
5267 }
5268 self.generate_identifier(&cte.alias)?;
5269 for comment in &cte.comments {
5271 self.write_space();
5272 self.write_formatted_comment(comment);
5273 }
5274 if !cte.columns.is_empty() && !skip_cte_columns {
5275 self.write("(");
5276 for (j, col) in cte.columns.iter().enumerate() {
5277 if j > 0 {
5278 self.write(", ");
5279 }
5280 self.generate_identifier(col)?;
5281 }
5282 self.write(")");
5283 }
5284 if !cte.key_expressions.is_empty() {
5286 self.write_space();
5287 self.write_keyword("USING KEY");
5288 self.write(" (");
5289 for (i, key) in cte.key_expressions.iter().enumerate() {
5290 if i > 0 {
5291 self.write(", ");
5292 }
5293 self.generate_identifier(key)?;
5294 }
5295 self.write(")");
5296 }
5297 self.write_space();
5298 self.write_keyword("AS");
5299 if let Some(materialized) = cte.materialized {
5301 self.write_space();
5302 if materialized {
5303 self.write_keyword("MATERIALIZED");
5304 } else {
5305 self.write_keyword("NOT MATERIALIZED");
5306 }
5307 }
5308 self.write(" (");
5309 if self.config.pretty {
5310 self.write_newline();
5311 self.indent_level += 1;
5312 self.write_indent();
5313 }
5314 let wrap_values_in_select = matches!(
5317 self.config.dialect,
5318 Some(DialectType::Spark) | Some(DialectType::Databricks)
5319 ) && matches!(&cte.this, Expression::Values(_));
5320
5321 if wrap_values_in_select {
5322 self.write_keyword("SELECT");
5323 self.write(" * ");
5324 self.write_keyword("FROM");
5325 self.write_space();
5326 }
5327 self.generate_expression(&cte.this)?;
5328 if self.config.pretty {
5329 self.write_newline();
5330 self.indent_level -= 1;
5331 self.write_indent();
5332 }
5333 self.write(")");
5334 }
5335
5336 if let Some(search) = &with.search {
5338 self.write_space();
5339 self.generate_expression(search)?;
5340 }
5341
5342 Ok(())
5343 }
5344
5345 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
5349 let mut i = 0;
5350 while i < joins.len() {
5351 if joins[i].deferred_condition {
5352 let parent_group = joins[i].nesting_group;
5353
5354 self.generate_join_without_condition(&joins[i])?;
5357
5358 let child_start = i + 1;
5360 let mut child_end = child_start;
5361 while child_end < joins.len()
5362 && !joins[child_end].deferred_condition
5363 && joins[child_end].nesting_group == parent_group
5364 {
5365 child_end += 1;
5366 }
5367
5368 if child_start < child_end {
5370 self.indent_level += 1;
5371 for j in child_start..child_end {
5372 self.generate_join(&joins[j])?;
5373 }
5374 self.indent_level -= 1;
5375 }
5376
5377 self.generate_join_condition(&joins[i])?;
5379
5380 i = child_end;
5381 } else {
5382 self.generate_join(&joins[i])?;
5384 i += 1;
5385 }
5386 }
5387 Ok(())
5388 }
5389
5390 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5393 let mut join_copy = join.clone();
5396 join_copy.on = None;
5397 join_copy.using = Vec::new();
5398 join_copy.deferred_condition = false;
5399 self.generate_join(&join_copy)
5400 }
5401
5402 fn generate_join(&mut self, join: &Join) -> Result<()> {
5403 if join.kind == JoinKind::Implicit {
5405 self.write(",");
5406 if self.config.pretty {
5407 self.write_newline();
5408 self.write_indent();
5409 } else {
5410 self.write_space();
5411 }
5412 self.generate_expression(&join.this)?;
5413 return Ok(());
5414 }
5415
5416 if self.config.pretty {
5417 self.write_newline();
5418 self.write_indent();
5419 } else {
5420 self.write_space();
5421 }
5422
5423 let hint_str = if self.config.join_hints {
5426 join.join_hint
5427 .as_ref()
5428 .map(|h| format!(" {}", h))
5429 .unwrap_or_default()
5430 } else {
5431 String::new()
5432 };
5433
5434 let clickhouse_join_keyword =
5435 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5436 if let Some(hint) = &join.join_hint {
5437 let mut global = false;
5438 let mut strictness: Option<&'static str> = None;
5439 for part in hint.split_whitespace() {
5440 if part.eq_ignore_ascii_case("GLOBAL") {
5441 global = true;
5442 } else if part.eq_ignore_ascii_case("ALL") {
5443 strictness = Some("ALL");
5444 } else if part.eq_ignore_ascii_case("ANY") {
5445 strictness = Some("ANY");
5446 } else if part.eq_ignore_ascii_case("ASOF") {
5447 strictness = Some("ASOF");
5448 } else if part.eq_ignore_ascii_case("SEMI") {
5449 strictness = Some("SEMI");
5450 } else if part.eq_ignore_ascii_case("ANTI") {
5451 strictness = Some("ANTI");
5452 }
5453 }
5454
5455 if global || strictness.is_some() {
5456 let join_type = match join.kind {
5457 JoinKind::Left => {
5458 if join.use_outer_keyword {
5459 "LEFT OUTER"
5460 } else if join.use_inner_keyword {
5461 "LEFT INNER"
5462 } else {
5463 "LEFT"
5464 }
5465 }
5466 JoinKind::Right => {
5467 if join.use_outer_keyword {
5468 "RIGHT OUTER"
5469 } else if join.use_inner_keyword {
5470 "RIGHT INNER"
5471 } else {
5472 "RIGHT"
5473 }
5474 }
5475 JoinKind::Full => {
5476 if join.use_outer_keyword {
5477 "FULL OUTER"
5478 } else {
5479 "FULL"
5480 }
5481 }
5482 JoinKind::Inner => {
5483 if join.use_inner_keyword {
5484 "INNER"
5485 } else {
5486 ""
5487 }
5488 }
5489 _ => "",
5490 };
5491
5492 let mut parts = Vec::new();
5493 if global {
5494 parts.push("GLOBAL");
5495 }
5496 if !join_type.is_empty() {
5497 parts.push(join_type);
5498 }
5499 if let Some(strict) = strictness {
5500 parts.push(strict);
5501 }
5502 parts.push("JOIN");
5503 Some(parts.join(" "))
5504 } else {
5505 None
5506 }
5507 } else {
5508 None
5509 }
5510 } else {
5511 None
5512 };
5513
5514 if !join.comments.is_empty() {
5518 if self.config.pretty {
5519 let trimmed = self.output.trim_end().len();
5524 self.output.truncate(trimmed);
5525 for comment in &join.comments {
5526 self.write_newline();
5527 self.write_indent();
5528 self.write_formatted_comment(comment);
5529 }
5530 self.write_newline();
5531 self.write_indent();
5532 } else {
5533 for comment in &join.comments {
5534 self.write_formatted_comment(comment);
5535 self.write_space();
5536 }
5537 }
5538 }
5539
5540 let directed_str = if join.directed { " DIRECTED" } else { "" };
5541
5542 if let Some(keyword) = clickhouse_join_keyword {
5543 self.write_keyword(&keyword);
5544 } else {
5545 match join.kind {
5546 JoinKind::Inner => {
5547 if join.use_inner_keyword {
5548 if hint_str.is_empty() && directed_str.is_empty() {
5549 self.write_keyword("INNER JOIN");
5550 } else {
5551 self.write_keyword("INNER");
5552 if !hint_str.is_empty() {
5553 self.write_keyword(&hint_str);
5554 }
5555 if !directed_str.is_empty() {
5556 self.write_keyword(directed_str);
5557 }
5558 self.write_keyword(" JOIN");
5559 }
5560 } else {
5561 if !hint_str.is_empty() {
5562 self.write_keyword(hint_str.trim());
5563 self.write_keyword(" ");
5564 }
5565 if !directed_str.is_empty() {
5566 self.write_keyword("DIRECTED ");
5567 }
5568 self.write_keyword("JOIN");
5569 }
5570 }
5571 JoinKind::Left => {
5572 if join.use_outer_keyword {
5573 if hint_str.is_empty() && directed_str.is_empty() {
5574 self.write_keyword("LEFT OUTER JOIN");
5575 } else {
5576 self.write_keyword("LEFT OUTER");
5577 if !hint_str.is_empty() {
5578 self.write_keyword(&hint_str);
5579 }
5580 if !directed_str.is_empty() {
5581 self.write_keyword(directed_str);
5582 }
5583 self.write_keyword(" JOIN");
5584 }
5585 } else if join.use_inner_keyword {
5586 if hint_str.is_empty() && directed_str.is_empty() {
5587 self.write_keyword("LEFT INNER JOIN");
5588 } else {
5589 self.write_keyword("LEFT INNER");
5590 if !hint_str.is_empty() {
5591 self.write_keyword(&hint_str);
5592 }
5593 if !directed_str.is_empty() {
5594 self.write_keyword(directed_str);
5595 }
5596 self.write_keyword(" JOIN");
5597 }
5598 } else {
5599 if hint_str.is_empty() && directed_str.is_empty() {
5600 self.write_keyword("LEFT JOIN");
5601 } else {
5602 self.write_keyword("LEFT");
5603 if !hint_str.is_empty() {
5604 self.write_keyword(&hint_str);
5605 }
5606 if !directed_str.is_empty() {
5607 self.write_keyword(directed_str);
5608 }
5609 self.write_keyword(" JOIN");
5610 }
5611 }
5612 }
5613 JoinKind::Right => {
5614 if join.use_outer_keyword {
5615 if hint_str.is_empty() && directed_str.is_empty() {
5616 self.write_keyword("RIGHT OUTER JOIN");
5617 } else {
5618 self.write_keyword("RIGHT OUTER");
5619 if !hint_str.is_empty() {
5620 self.write_keyword(&hint_str);
5621 }
5622 if !directed_str.is_empty() {
5623 self.write_keyword(directed_str);
5624 }
5625 self.write_keyword(" JOIN");
5626 }
5627 } else if join.use_inner_keyword {
5628 if hint_str.is_empty() && directed_str.is_empty() {
5629 self.write_keyword("RIGHT INNER JOIN");
5630 } else {
5631 self.write_keyword("RIGHT INNER");
5632 if !hint_str.is_empty() {
5633 self.write_keyword(&hint_str);
5634 }
5635 if !directed_str.is_empty() {
5636 self.write_keyword(directed_str);
5637 }
5638 self.write_keyword(" JOIN");
5639 }
5640 } else {
5641 if hint_str.is_empty() && directed_str.is_empty() {
5642 self.write_keyword("RIGHT JOIN");
5643 } else {
5644 self.write_keyword("RIGHT");
5645 if !hint_str.is_empty() {
5646 self.write_keyword(&hint_str);
5647 }
5648 if !directed_str.is_empty() {
5649 self.write_keyword(directed_str);
5650 }
5651 self.write_keyword(" JOIN");
5652 }
5653 }
5654 }
5655 JoinKind::Full => {
5656 if join.use_outer_keyword {
5657 if hint_str.is_empty() && directed_str.is_empty() {
5658 self.write_keyword("FULL OUTER JOIN");
5659 } else {
5660 self.write_keyword("FULL OUTER");
5661 if !hint_str.is_empty() {
5662 self.write_keyword(&hint_str);
5663 }
5664 if !directed_str.is_empty() {
5665 self.write_keyword(directed_str);
5666 }
5667 self.write_keyword(" JOIN");
5668 }
5669 } else {
5670 if hint_str.is_empty() && directed_str.is_empty() {
5671 self.write_keyword("FULL JOIN");
5672 } else {
5673 self.write_keyword("FULL");
5674 if !hint_str.is_empty() {
5675 self.write_keyword(&hint_str);
5676 }
5677 if !directed_str.is_empty() {
5678 self.write_keyword(directed_str);
5679 }
5680 self.write_keyword(" JOIN");
5681 }
5682 }
5683 }
5684 JoinKind::Outer => {
5685 if directed_str.is_empty() {
5686 self.write_keyword("OUTER JOIN");
5687 } else {
5688 self.write_keyword("OUTER");
5689 self.write_keyword(directed_str);
5690 self.write_keyword(" JOIN");
5691 }
5692 }
5693 JoinKind::Cross => {
5694 if directed_str.is_empty() {
5695 self.write_keyword("CROSS JOIN");
5696 } else {
5697 self.write_keyword("CROSS");
5698 self.write_keyword(directed_str);
5699 self.write_keyword(" JOIN");
5700 }
5701 }
5702 JoinKind::Natural => {
5703 if join.use_inner_keyword {
5704 if directed_str.is_empty() {
5705 self.write_keyword("NATURAL INNER JOIN");
5706 } else {
5707 self.write_keyword("NATURAL INNER");
5708 self.write_keyword(directed_str);
5709 self.write_keyword(" JOIN");
5710 }
5711 } else {
5712 if directed_str.is_empty() {
5713 self.write_keyword("NATURAL JOIN");
5714 } else {
5715 self.write_keyword("NATURAL");
5716 self.write_keyword(directed_str);
5717 self.write_keyword(" JOIN");
5718 }
5719 }
5720 }
5721 JoinKind::NaturalLeft => {
5722 if join.use_outer_keyword {
5723 if directed_str.is_empty() {
5724 self.write_keyword("NATURAL LEFT OUTER JOIN");
5725 } else {
5726 self.write_keyword("NATURAL LEFT OUTER");
5727 self.write_keyword(directed_str);
5728 self.write_keyword(" JOIN");
5729 }
5730 } else {
5731 if directed_str.is_empty() {
5732 self.write_keyword("NATURAL LEFT JOIN");
5733 } else {
5734 self.write_keyword("NATURAL LEFT");
5735 self.write_keyword(directed_str);
5736 self.write_keyword(" JOIN");
5737 }
5738 }
5739 }
5740 JoinKind::NaturalRight => {
5741 if join.use_outer_keyword {
5742 if directed_str.is_empty() {
5743 self.write_keyword("NATURAL RIGHT OUTER JOIN");
5744 } else {
5745 self.write_keyword("NATURAL RIGHT OUTER");
5746 self.write_keyword(directed_str);
5747 self.write_keyword(" JOIN");
5748 }
5749 } else {
5750 if directed_str.is_empty() {
5751 self.write_keyword("NATURAL RIGHT JOIN");
5752 } else {
5753 self.write_keyword("NATURAL RIGHT");
5754 self.write_keyword(directed_str);
5755 self.write_keyword(" JOIN");
5756 }
5757 }
5758 }
5759 JoinKind::NaturalFull => {
5760 if join.use_outer_keyword {
5761 if directed_str.is_empty() {
5762 self.write_keyword("NATURAL FULL OUTER JOIN");
5763 } else {
5764 self.write_keyword("NATURAL FULL OUTER");
5765 self.write_keyword(directed_str);
5766 self.write_keyword(" JOIN");
5767 }
5768 } else {
5769 if directed_str.is_empty() {
5770 self.write_keyword("NATURAL FULL JOIN");
5771 } else {
5772 self.write_keyword("NATURAL FULL");
5773 self.write_keyword(directed_str);
5774 self.write_keyword(" JOIN");
5775 }
5776 }
5777 }
5778 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
5779 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
5780 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
5781 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
5782 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
5783 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
5784 JoinKind::CrossApply => {
5785 if matches!(
5787 self.config.dialect,
5788 Some(DialectType::TSQL) | Some(DialectType::Fabric) | None
5789 ) {
5790 self.write_keyword("CROSS APPLY");
5791 } else {
5792 self.write_keyword("INNER JOIN LATERAL");
5793 }
5794 }
5795 JoinKind::OuterApply => {
5796 if matches!(
5798 self.config.dialect,
5799 Some(DialectType::TSQL) | Some(DialectType::Fabric) | None
5800 ) {
5801 self.write_keyword("OUTER APPLY");
5802 } else {
5803 self.write_keyword("LEFT JOIN LATERAL");
5804 }
5805 }
5806 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
5807 JoinKind::AsOfLeft => {
5808 if join.use_outer_keyword {
5809 self.write_keyword("ASOF LEFT OUTER JOIN");
5810 } else {
5811 self.write_keyword("ASOF LEFT JOIN");
5812 }
5813 }
5814 JoinKind::AsOfRight => {
5815 if join.use_outer_keyword {
5816 self.write_keyword("ASOF RIGHT OUTER JOIN");
5817 } else {
5818 self.write_keyword("ASOF RIGHT JOIN");
5819 }
5820 }
5821 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
5822 JoinKind::LeftLateral => {
5823 if join.use_outer_keyword {
5824 self.write_keyword("LEFT OUTER LATERAL JOIN");
5825 } else {
5826 self.write_keyword("LEFT LATERAL JOIN");
5827 }
5828 }
5829 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
5830 JoinKind::Implicit => {
5831 use crate::dialects::DialectType;
5835 let is_cj_dialect = matches!(
5836 self.config.dialect,
5837 Some(DialectType::BigQuery)
5838 | Some(DialectType::Hive)
5839 | Some(DialectType::Spark)
5840 | Some(DialectType::Databricks)
5841 );
5842 let source_is_same = self.config.source_dialect.is_some()
5843 && self.config.source_dialect == self.config.dialect;
5844 let source_is_cj = matches!(
5845 self.config.source_dialect,
5846 Some(DialectType::BigQuery)
5847 | Some(DialectType::Hive)
5848 | Some(DialectType::Spark)
5849 | Some(DialectType::Databricks)
5850 );
5851 if is_cj_dialect
5852 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
5853 {
5854 self.write_keyword("CROSS JOIN");
5855 } else {
5856 self.output.truncate(self.output.trim_end().len());
5860 self.write(",");
5861 }
5862 }
5863 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
5864 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
5865 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
5866 JoinKind::Positional => self.write_keyword("POSITIONAL JOIN"),
5867 }
5868 }
5869
5870 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
5872 match &join.this {
5873 Expression::Tuple(t) if t.expressions.is_empty() => {}
5874 Expression::Tuple(t) => {
5875 self.write_space();
5876 for (i, item) in t.expressions.iter().enumerate() {
5877 if i > 0 {
5878 self.write(", ");
5879 }
5880 self.generate_expression(item)?;
5881 }
5882 }
5883 other => {
5884 self.write_space();
5885 self.generate_expression(other)?;
5886 }
5887 }
5888 } else {
5889 self.write_space();
5890 self.generate_expression(&join.this)?;
5891 }
5892
5893 if !join.deferred_condition {
5895 if let Some(match_cond) = &join.match_condition {
5897 self.write_space();
5898 self.write_keyword("MATCH_CONDITION");
5899 self.write(" (");
5900 self.generate_expression(match_cond)?;
5901 self.write(")");
5902 }
5903
5904 if let Some(on) = &join.on {
5905 if self.config.pretty {
5906 self.write_newline();
5907 self.indent_level += 1;
5908 self.write_indent();
5909 self.write_keyword("ON");
5910 self.write_space();
5911 self.generate_join_on_condition(on)?;
5912 self.indent_level -= 1;
5913 } else {
5914 self.write_space();
5915 self.write_keyword("ON");
5916 self.write_space();
5917 self.generate_expression(on)?;
5918 }
5919 }
5920
5921 if !join.using.is_empty() {
5922 if self.config.pretty {
5923 self.write_newline();
5924 self.indent_level += 1;
5925 self.write_indent();
5926 self.write_keyword("USING");
5927 self.write(" (");
5928 for (i, col) in join.using.iter().enumerate() {
5929 if i > 0 {
5930 self.write(", ");
5931 }
5932 self.generate_identifier(col)?;
5933 }
5934 self.write(")");
5935 self.indent_level -= 1;
5936 } else {
5937 self.write_space();
5938 self.write_keyword("USING");
5939 self.write(" (");
5940 for (i, col) in join.using.iter().enumerate() {
5941 if i > 0 {
5942 self.write(", ");
5943 }
5944 self.generate_identifier(col)?;
5945 }
5946 self.write(")");
5947 }
5948 }
5949 }
5950
5951 for pivot in &join.pivots {
5953 self.write_space();
5954 self.generate_expression(pivot)?;
5955 }
5956
5957 Ok(())
5958 }
5959
5960 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
5962 if let Some(match_cond) = &join.match_condition {
5964 self.write_space();
5965 self.write_keyword("MATCH_CONDITION");
5966 self.write(" (");
5967 self.generate_expression(match_cond)?;
5968 self.write(")");
5969 }
5970
5971 if let Some(on) = &join.on {
5972 if self.config.pretty {
5973 self.write_newline();
5974 self.indent_level += 1;
5975 self.write_indent();
5976 self.write_keyword("ON");
5977 self.write_space();
5978 self.generate_join_on_condition(on)?;
5980 self.indent_level -= 1;
5981 } else {
5982 self.write_space();
5983 self.write_keyword("ON");
5984 self.write_space();
5985 self.generate_expression(on)?;
5986 }
5987 }
5988
5989 if !join.using.is_empty() {
5990 if self.config.pretty {
5991 self.write_newline();
5992 self.indent_level += 1;
5993 self.write_indent();
5994 self.write_keyword("USING");
5995 self.write(" (");
5996 for (i, col) in join.using.iter().enumerate() {
5997 if i > 0 {
5998 self.write(", ");
5999 }
6000 self.generate_identifier(col)?;
6001 }
6002 self.write(")");
6003 self.indent_level -= 1;
6004 } else {
6005 self.write_space();
6006 self.write_keyword("USING");
6007 self.write(" (");
6008 for (i, col) in join.using.iter().enumerate() {
6009 if i > 0 {
6010 self.write(", ");
6011 }
6012 self.generate_identifier(col)?;
6013 }
6014 self.write(")");
6015 }
6016 }
6017
6018 for pivot in &join.pivots {
6020 self.write_space();
6021 self.generate_expression(pivot)?;
6022 }
6023
6024 Ok(())
6025 }
6026
6027 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
6029 if let Expression::And(and_op) = expr {
6030 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
6031 self.generate_expression(conditions[0])?;
6032 for condition in conditions.iter().skip(1) {
6033 self.write_newline();
6034 self.write_indent();
6035 self.write_keyword("AND");
6036 self.write_space();
6037 self.generate_expression(condition)?;
6038 }
6039 return Ok(());
6040 }
6041 }
6042
6043 self.generate_expression(expr)
6044 }
6045
6046 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
6047 self.write("(");
6049 self.generate_expression(&jt.left)?;
6050
6051 for join in &jt.joins {
6053 self.generate_join(join)?;
6054 }
6055
6056 for (lv_idx, lv) in jt.lateral_views.iter().enumerate() {
6058 self.generate_lateral_view(lv, lv_idx)?;
6059 }
6060
6061 self.write(")");
6062
6063 if let Some(alias) = &jt.alias {
6065 self.write_space();
6066 self.write_keyword("AS");
6067 self.write_space();
6068 self.generate_identifier(alias)?;
6069 }
6070
6071 Ok(())
6072 }
6073
6074 fn generate_lateral_view(&mut self, lv: &LateralView, lv_index: usize) -> Result<()> {
6075 use crate::dialects::DialectType;
6076
6077 if self.config.pretty {
6078 self.write_newline();
6079 self.write_indent();
6080 } else {
6081 self.write_space();
6082 }
6083
6084 let use_lateral_join = matches!(
6087 self.config.dialect,
6088 Some(DialectType::PostgreSQL)
6089 | Some(DialectType::DuckDB)
6090 | Some(DialectType::Snowflake)
6091 | Some(DialectType::TSQL)
6092 | Some(DialectType::Presto)
6093 | Some(DialectType::Trino)
6094 | Some(DialectType::Athena)
6095 );
6096
6097 let use_unnest = matches!(
6099 self.config.dialect,
6100 Some(DialectType::DuckDB)
6101 | Some(DialectType::Presto)
6102 | Some(DialectType::Trino)
6103 | Some(DialectType::Athena)
6104 );
6105
6106 let (is_posexplode, is_inline, func_args) = match &lv.this {
6108 Expression::Explode(uf) => {
6109 (false, false, vec![uf.this.clone()])
6111 }
6112 Expression::Unnest(uf) => {
6113 let mut args = vec![uf.this.clone()];
6114 args.extend(uf.expressions.clone());
6115 (false, false, args)
6116 }
6117 Expression::Function(func) => {
6118 if func.name.eq_ignore_ascii_case("POSEXPLODE")
6119 || func.name.eq_ignore_ascii_case("POSEXPLODE_OUTER")
6120 {
6121 (true, false, func.args.clone())
6122 } else if func.name.eq_ignore_ascii_case("INLINE") {
6123 (false, true, func.args.clone())
6124 } else if func.name.eq_ignore_ascii_case("EXPLODE")
6125 || func.name.eq_ignore_ascii_case("EXPLODE_OUTER")
6126 {
6127 (false, false, func.args.clone())
6128 } else {
6129 (false, false, vec![])
6130 }
6131 }
6132 _ => (false, false, vec![]),
6133 };
6134
6135 if use_lateral_join {
6136 if lv.outer {
6138 self.write_keyword("LEFT JOIN LATERAL");
6139 } else {
6140 self.write_keyword("CROSS JOIN");
6141 }
6142 self.write_space();
6143
6144 if use_unnest && !func_args.is_empty() {
6145 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6148 func_args
6150 .iter()
6151 .map(|a| {
6152 if let Expression::Function(ref f) = a {
6153 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() == 1 {
6154 return Expression::ArrayFunc(Box::new(
6155 crate::expressions::ArrayConstructor {
6156 expressions: f.args.clone(),
6157 bracket_notation: true,
6158 use_list_keyword: false,
6159 },
6160 ));
6161 }
6162 }
6163 a.clone()
6164 })
6165 .collect::<Vec<_>>()
6166 } else if matches!(
6167 self.config.dialect,
6168 Some(DialectType::Presto)
6169 | Some(DialectType::Trino)
6170 | Some(DialectType::Athena)
6171 ) {
6172 func_args
6174 .iter()
6175 .map(|a| {
6176 if let Expression::Function(ref f) = a {
6177 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() >= 1 {
6178 return Expression::ArrayFunc(Box::new(
6179 crate::expressions::ArrayConstructor {
6180 expressions: f.args.clone(),
6181 bracket_notation: true,
6182 use_list_keyword: false,
6183 },
6184 ));
6185 }
6186 }
6187 a.clone()
6188 })
6189 .collect::<Vec<_>>()
6190 } else {
6191 func_args
6192 };
6193
6194 if is_posexplode {
6196 self.write_keyword("LATERAL");
6197 self.write(" (");
6198 self.write_keyword("SELECT");
6199 self.write_space();
6200
6201 let pos_alias = if !lv.column_aliases.is_empty() {
6204 lv.column_aliases[0].clone()
6205 } else {
6206 Identifier::new("pos")
6207 };
6208 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
6209 lv.column_aliases[1..].to_vec()
6210 } else {
6211 vec![Identifier::new("col")]
6212 };
6213
6214 self.generate_identifier(&pos_alias)?;
6216 self.write(" - 1");
6217 self.write_space();
6218 self.write_keyword("AS");
6219 self.write_space();
6220 self.generate_identifier(&pos_alias)?;
6221
6222 for data_col in &data_aliases {
6224 self.write(", ");
6225 self.generate_identifier(data_col)?;
6226 }
6227
6228 self.write_space();
6229 self.write_keyword("FROM");
6230 self.write_space();
6231 self.write_keyword("UNNEST");
6232 self.write("(");
6233 for (i, arg) in unnest_args.iter().enumerate() {
6234 if i > 0 {
6235 self.write(", ");
6236 }
6237 self.generate_expression(arg)?;
6238 }
6239 self.write(")");
6240 self.write_space();
6241 self.write_keyword("WITH ORDINALITY");
6242 self.write_space();
6243 self.write_keyword("AS");
6244 self.write_space();
6245
6246 let table_alias_ident = lv
6248 .table_alias
6249 .clone()
6250 .unwrap_or_else(|| Identifier::new("t"));
6251 self.generate_identifier(&table_alias_ident)?;
6252 self.write("(");
6253 for (i, data_col) in data_aliases.iter().enumerate() {
6254 if i > 0 {
6255 self.write(", ");
6256 }
6257 self.generate_identifier(data_col)?;
6258 }
6259 self.write(", ");
6260 self.generate_identifier(&pos_alias)?;
6261 self.write("))");
6262 } else if is_inline && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6263 self.write_keyword("LATERAL");
6265 self.write(" (");
6266 self.write_keyword("SELECT");
6267 self.write_space();
6268 self.write_keyword("UNNEST");
6269 self.write("(");
6270 for (i, arg) in unnest_args.iter().enumerate() {
6271 if i > 0 {
6272 self.write(", ");
6273 }
6274 self.generate_expression(arg)?;
6275 }
6276 self.write(", ");
6277 self.write_keyword("max_depth");
6278 self.write(" => 2))");
6279
6280 if let Some(alias) = &lv.table_alias {
6282 self.write_space();
6283 self.write_keyword("AS");
6284 self.write_space();
6285 self.generate_identifier(alias)?;
6286 if !lv.column_aliases.is_empty() {
6287 self.write("(");
6288 for (i, col) in lv.column_aliases.iter().enumerate() {
6289 if i > 0 {
6290 self.write(", ");
6291 }
6292 self.generate_identifier(col)?;
6293 }
6294 self.write(")");
6295 }
6296 } else if !lv.column_aliases.is_empty() {
6297 self.write_space();
6299 self.write_keyword("AS");
6300 self.write_space();
6301 self.write(&format!("_u_{}", lv_index));
6302 self.write("(");
6303 for (i, col) in lv.column_aliases.iter().enumerate() {
6304 if i > 0 {
6305 self.write(", ");
6306 }
6307 self.generate_identifier(col)?;
6308 }
6309 self.write(")");
6310 }
6311 } else {
6312 self.write_keyword("UNNEST");
6313 self.write("(");
6314 for (i, arg) in unnest_args.iter().enumerate() {
6315 if i > 0 {
6316 self.write(", ");
6317 }
6318 self.generate_expression(arg)?;
6319 }
6320 self.write(")");
6321
6322 if let Some(alias) = &lv.table_alias {
6324 self.write_space();
6325 self.write_keyword("AS");
6326 self.write_space();
6327 self.generate_identifier(alias)?;
6328 if !lv.column_aliases.is_empty() {
6329 self.write("(");
6330 for (i, col) in lv.column_aliases.iter().enumerate() {
6331 if i > 0 {
6332 self.write(", ");
6333 }
6334 self.generate_identifier(col)?;
6335 }
6336 self.write(")");
6337 }
6338 } else if !lv.column_aliases.is_empty() {
6339 self.write_space();
6340 self.write_keyword("AS");
6341 self.write(" t(");
6342 for (i, col) in lv.column_aliases.iter().enumerate() {
6343 if i > 0 {
6344 self.write(", ");
6345 }
6346 self.generate_identifier(col)?;
6347 }
6348 self.write(")");
6349 }
6350 }
6351 } else {
6352 if !lv.outer {
6354 self.write_keyword("LATERAL");
6355 self.write_space();
6356 }
6357 self.generate_expression(&lv.this)?;
6358
6359 if let Some(alias) = &lv.table_alias {
6361 self.write_space();
6362 self.write_keyword("AS");
6363 self.write_space();
6364 self.generate_identifier(alias)?;
6365 if !lv.column_aliases.is_empty() {
6366 self.write("(");
6367 for (i, col) in lv.column_aliases.iter().enumerate() {
6368 if i > 0 {
6369 self.write(", ");
6370 }
6371 self.generate_identifier(col)?;
6372 }
6373 self.write(")");
6374 }
6375 } else if !lv.column_aliases.is_empty() {
6376 self.write_space();
6377 self.write_keyword("AS");
6378 self.write(" t(");
6379 for (i, col) in lv.column_aliases.iter().enumerate() {
6380 if i > 0 {
6381 self.write(", ");
6382 }
6383 self.generate_identifier(col)?;
6384 }
6385 self.write(")");
6386 }
6387 }
6388
6389 if lv.outer {
6391 self.write_space();
6392 self.write_keyword("ON TRUE");
6393 }
6394 } else {
6395 self.write_keyword("LATERAL VIEW");
6397 if lv.outer {
6398 self.write_space();
6399 self.write_keyword("OUTER");
6400 }
6401 if self.config.pretty {
6402 self.write_newline();
6403 self.write_indent();
6404 } else {
6405 self.write_space();
6406 }
6407 self.generate_expression(&lv.this)?;
6408
6409 if let Some(alias) = &lv.table_alias {
6411 self.write_space();
6412 self.generate_identifier(alias)?;
6413 }
6414
6415 if !lv.column_aliases.is_empty() {
6417 self.write_space();
6418 self.write_keyword("AS");
6419 self.write_space();
6420 for (i, col) in lv.column_aliases.iter().enumerate() {
6421 if i > 0 {
6422 self.write(", ");
6423 }
6424 self.generate_identifier(col)?;
6425 }
6426 }
6427 }
6428
6429 Ok(())
6430 }
6431
6432 fn should_wrap_set_operation_modifiers(
6433 &self,
6434 order_by: &Option<OrderBy>,
6435 limit: &Option<Box<Expression>>,
6436 offset: &Option<Box<Expression>>,
6437 ) -> bool {
6438 let has_row_limit = limit.is_some() || offset.is_some();
6439 let has_emulated_null_ordering = order_by.as_ref().map_or(false, |order_by| {
6440 order_by
6441 .expressions
6442 .iter()
6443 .any(|ordered| ordered.nulls_first.is_some())
6444 });
6445
6446 (has_row_limit || has_emulated_null_ordering)
6447 && matches!(
6448 self.config.dialect,
6449 Some(DialectType::TSQL) | Some(DialectType::Fabric)
6450 )
6451 }
6452
6453 fn generate_tsql_wrapped_set_operation(
6454 &mut self,
6455 inner: Expression,
6456 with: Option<With>,
6457 order_by: Option<OrderBy>,
6458 limit: Option<Box<Expression>>,
6459 offset: Option<Box<Expression>>,
6460 ) -> Result<()> {
6461 let subquery = Subquery {
6462 this: inner,
6463 alias: Some(Identifier::new("_l_0".to_string())),
6464 column_aliases: Vec::new(),
6465 alias_explicit_as: true,
6466 alias_keyword: None,
6467 order_by: None,
6468 limit: None,
6469 offset: None,
6470 lateral: false,
6471 modifiers_inside: false,
6472 trailing_comments: Vec::new(),
6473 distribute_by: None,
6474 sort_by: None,
6475 cluster_by: None,
6476 inferred_type: None,
6477 };
6478
6479 let mut outer_select = Select {
6480 expressions: vec![Expression::Star(Star {
6481 table: None,
6482 except: None,
6483 replace: None,
6484 rename: None,
6485 trailing_comments: Vec::new(),
6486 span: None,
6487 })],
6488 from: Some(From {
6489 expressions: vec![Expression::Subquery(Box::new(subquery))],
6490 }),
6491 with,
6492 order_by,
6493 limit: limit.map(|limit| Limit {
6494 this: *limit,
6495 percent: false,
6496 comments: Vec::new(),
6497 }),
6498 offset: offset.map(|offset| Offset {
6499 this: *offset,
6500 rows: Some(true),
6501 }),
6502 ..Select::new()
6503 };
6504
6505 if outer_select.offset.is_some() && outer_select.order_by.is_none() {
6506 outer_select.order_by = Some(Self::dummy_tsql_order_by());
6507 }
6508
6509 self.generate_select(&outer_select)
6510 }
6511
6512 fn dummy_tsql_order_by() -> OrderBy {
6513 let null_select = Expression::Select(Box::new(Select {
6514 expressions: vec![Expression::Null(Null)],
6515 ..Select::new()
6516 }));
6517
6518 OrderBy {
6519 expressions: vec![Ordered {
6520 this: Expression::Subquery(Box::new(Subquery {
6521 this: null_select,
6522 alias: None,
6523 column_aliases: Vec::new(),
6524 alias_explicit_as: false,
6525 alias_keyword: None,
6526 order_by: None,
6527 limit: None,
6528 offset: None,
6529 lateral: false,
6530 modifiers_inside: false,
6531 trailing_comments: Vec::new(),
6532 distribute_by: None,
6533 sort_by: None,
6534 cluster_by: None,
6535 inferred_type: None,
6536 })),
6537 desc: false,
6538 nulls_first: None,
6539 explicit_asc: false,
6540 with_fill: None,
6541 }],
6542 siblings: false,
6543 comments: Vec::new(),
6544 }
6545 }
6546
6547 fn generate_union(&mut self, outermost: &Union) -> Result<()> {
6548 if self.should_wrap_set_operation_modifiers(
6549 &outermost.order_by,
6550 &outermost.limit,
6551 &outermost.offset,
6552 ) {
6553 let mut inner = outermost.clone();
6554 let with = inner.with.take();
6555 let order_by = inner.order_by.take();
6556 let limit = inner.limit.take();
6557 let offset = inner.offset.take();
6558
6559 return self.generate_tsql_wrapped_set_operation(
6560 Expression::Union(Box::new(inner)),
6561 with,
6562 order_by,
6563 limit,
6564 offset,
6565 );
6566 }
6567
6568 let mut chain: Vec<&Union> = vec![outermost];
6573 let mut leftmost: &Expression = &outermost.left;
6574 while let Expression::Union(inner) = leftmost {
6575 chain.push(inner);
6576 leftmost = &inner.left;
6577 }
6578 if let Some(with) = &outermost.with {
6583 self.generate_with(with)?;
6584 self.write_space();
6585 }
6586
6587 self.generate_expression(leftmost)?;
6589
6590 for union in chain.iter().rev() {
6592 self.generate_union_step(union)?;
6593 }
6594 Ok(())
6595 }
6596
6597 fn generate_union_step(&mut self, union: &Union) -> Result<()> {
6599 if self.config.pretty {
6600 self.write_newline();
6601 self.write_indent();
6602 } else {
6603 self.write_space();
6604 }
6605
6606 if let Some(side) = &union.side {
6608 self.write_keyword(side);
6609 self.write_space();
6610 }
6611 if let Some(kind) = &union.kind {
6612 self.write_keyword(kind);
6613 self.write_space();
6614 }
6615
6616 self.write_keyword("UNION");
6617 if union.all {
6618 self.write_space();
6619 self.write_keyword("ALL");
6620 } else if union.distinct {
6621 self.write_space();
6622 self.write_keyword("DISTINCT");
6623 }
6624
6625 if union.corresponding || union.by_name {
6628 self.write_space();
6629 self.write_keyword("BY NAME");
6630 }
6631 if !union.on_columns.is_empty() {
6632 self.write_space();
6633 self.write_keyword("ON");
6634 self.write(" (");
6635 for (i, col) in union.on_columns.iter().enumerate() {
6636 if i > 0 {
6637 self.write(", ");
6638 }
6639 self.generate_expression(col)?;
6640 }
6641 self.write(")");
6642 }
6643
6644 if self.config.pretty {
6645 self.write_newline();
6646 self.write_indent();
6647 } else {
6648 self.write_space();
6649 }
6650 self.generate_expression(&union.right)?;
6651 if let Some(order_by) = &union.order_by {
6653 if self.config.pretty {
6654 self.write_newline();
6655 } else {
6656 self.write_space();
6657 }
6658 self.write_keyword("ORDER BY");
6659 self.write_space();
6660 for (i, ordered) in order_by.expressions.iter().enumerate() {
6661 if i > 0 {
6662 self.write(", ");
6663 }
6664 self.generate_ordered(ordered)?;
6665 }
6666 }
6667 if let Some(limit) = &union.limit {
6668 if self.config.pretty {
6669 self.write_newline();
6670 } else {
6671 self.write_space();
6672 }
6673 self.write_keyword("LIMIT");
6674 self.write_space();
6675 self.generate_expression(limit)?;
6676 }
6677 if let Some(offset) = &union.offset {
6678 if self.config.pretty {
6679 self.write_newline();
6680 } else {
6681 self.write_space();
6682 }
6683 self.write_keyword("OFFSET");
6684 self.write_space();
6685 self.generate_expression(offset)?;
6686 }
6687 if let Some(distribute_by) = &union.distribute_by {
6689 self.write_space();
6690 self.write_keyword("DISTRIBUTE BY");
6691 self.write_space();
6692 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6693 if i > 0 {
6694 self.write(", ");
6695 }
6696 self.generate_expression(expr)?;
6697 }
6698 }
6699 if let Some(sort_by) = &union.sort_by {
6701 self.write_space();
6702 self.write_keyword("SORT BY");
6703 self.write_space();
6704 for (i, ord) in sort_by.expressions.iter().enumerate() {
6705 if i > 0 {
6706 self.write(", ");
6707 }
6708 self.generate_ordered(ord)?;
6709 }
6710 }
6711 if let Some(cluster_by) = &union.cluster_by {
6713 self.write_space();
6714 self.write_keyword("CLUSTER BY");
6715 self.write_space();
6716 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6717 if i > 0 {
6718 self.write(", ");
6719 }
6720 self.generate_ordered(ord)?;
6721 }
6722 }
6723 Ok(())
6724 }
6725
6726 fn generate_intersect(&mut self, outermost: &Intersect) -> Result<()> {
6727 if self.should_wrap_set_operation_modifiers(
6728 &outermost.order_by,
6729 &outermost.limit,
6730 &outermost.offset,
6731 ) {
6732 let mut inner = outermost.clone();
6733 let with = inner.with.take();
6734 let order_by = inner.order_by.take();
6735 let limit = inner.limit.take();
6736 let offset = inner.offset.take();
6737
6738 return self.generate_tsql_wrapped_set_operation(
6739 Expression::Intersect(Box::new(inner)),
6740 with,
6741 order_by,
6742 limit,
6743 offset,
6744 );
6745 }
6746
6747 let mut chain: Vec<&Intersect> = vec![outermost];
6749 let mut leftmost: &Expression = &outermost.left;
6750 while let Expression::Intersect(inner) = leftmost {
6751 chain.push(inner);
6752 leftmost = &inner.left;
6753 }
6754
6755 if let Some(with) = &outermost.with {
6756 self.generate_with(with)?;
6757 self.write_space();
6758 }
6759
6760 self.generate_expression(leftmost)?;
6761
6762 for intersect in chain.iter().rev() {
6763 self.generate_intersect_step(intersect)?;
6764 }
6765 Ok(())
6766 }
6767
6768 fn generate_intersect_step(&mut self, intersect: &Intersect) -> Result<()> {
6770 if self.config.pretty {
6771 self.write_newline();
6772 self.write_indent();
6773 } else {
6774 self.write_space();
6775 }
6776
6777 if let Some(side) = &intersect.side {
6779 self.write_keyword(side);
6780 self.write_space();
6781 }
6782 if let Some(kind) = &intersect.kind {
6783 self.write_keyword(kind);
6784 self.write_space();
6785 }
6786
6787 self.write_keyword("INTERSECT");
6788 if intersect.all {
6789 self.write_space();
6790 self.write_keyword("ALL");
6791 } else if intersect.distinct {
6792 self.write_space();
6793 self.write_keyword("DISTINCT");
6794 }
6795
6796 if intersect.corresponding || intersect.by_name {
6799 self.write_space();
6800 self.write_keyword("BY NAME");
6801 }
6802 if !intersect.on_columns.is_empty() {
6803 self.write_space();
6804 self.write_keyword("ON");
6805 self.write(" (");
6806 for (i, col) in intersect.on_columns.iter().enumerate() {
6807 if i > 0 {
6808 self.write(", ");
6809 }
6810 self.generate_expression(col)?;
6811 }
6812 self.write(")");
6813 }
6814
6815 if self.config.pretty {
6816 self.write_newline();
6817 self.write_indent();
6818 } else {
6819 self.write_space();
6820 }
6821 self.generate_expression(&intersect.right)?;
6822 if let Some(order_by) = &intersect.order_by {
6824 if self.config.pretty {
6825 self.write_newline();
6826 } else {
6827 self.write_space();
6828 }
6829 self.write_keyword("ORDER BY");
6830 self.write_space();
6831 for (i, ordered) in order_by.expressions.iter().enumerate() {
6832 if i > 0 {
6833 self.write(", ");
6834 }
6835 self.generate_ordered(ordered)?;
6836 }
6837 }
6838 if let Some(limit) = &intersect.limit {
6839 if self.config.pretty {
6840 self.write_newline();
6841 } else {
6842 self.write_space();
6843 }
6844 self.write_keyword("LIMIT");
6845 self.write_space();
6846 self.generate_expression(limit)?;
6847 }
6848 if let Some(offset) = &intersect.offset {
6849 if self.config.pretty {
6850 self.write_newline();
6851 } else {
6852 self.write_space();
6853 }
6854 self.write_keyword("OFFSET");
6855 self.write_space();
6856 self.generate_expression(offset)?;
6857 }
6858 if let Some(distribute_by) = &intersect.distribute_by {
6860 self.write_space();
6861 self.write_keyword("DISTRIBUTE BY");
6862 self.write_space();
6863 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6864 if i > 0 {
6865 self.write(", ");
6866 }
6867 self.generate_expression(expr)?;
6868 }
6869 }
6870 if let Some(sort_by) = &intersect.sort_by {
6872 self.write_space();
6873 self.write_keyword("SORT BY");
6874 self.write_space();
6875 for (i, ord) in sort_by.expressions.iter().enumerate() {
6876 if i > 0 {
6877 self.write(", ");
6878 }
6879 self.generate_ordered(ord)?;
6880 }
6881 }
6882 if let Some(cluster_by) = &intersect.cluster_by {
6884 self.write_space();
6885 self.write_keyword("CLUSTER BY");
6886 self.write_space();
6887 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6888 if i > 0 {
6889 self.write(", ");
6890 }
6891 self.generate_ordered(ord)?;
6892 }
6893 }
6894 Ok(())
6895 }
6896
6897 fn generate_except(&mut self, outermost: &Except) -> Result<()> {
6898 if self.should_wrap_set_operation_modifiers(
6899 &outermost.order_by,
6900 &outermost.limit,
6901 &outermost.offset,
6902 ) {
6903 let mut inner = outermost.clone();
6904 let with = inner.with.take();
6905 let order_by = inner.order_by.take();
6906 let limit = inner.limit.take();
6907 let offset = inner.offset.take();
6908
6909 return self.generate_tsql_wrapped_set_operation(
6910 Expression::Except(Box::new(inner)),
6911 with,
6912 order_by,
6913 limit,
6914 offset,
6915 );
6916 }
6917
6918 let mut chain: Vec<&Except> = vec![outermost];
6920 let mut leftmost: &Expression = &outermost.left;
6921 while let Expression::Except(inner) = leftmost {
6922 chain.push(inner);
6923 leftmost = &inner.left;
6924 }
6925
6926 if let Some(with) = &outermost.with {
6927 self.generate_with(with)?;
6928 self.write_space();
6929 }
6930
6931 self.generate_expression(leftmost)?;
6932
6933 for except in chain.iter().rev() {
6934 self.generate_except_step(except)?;
6935 }
6936 Ok(())
6937 }
6938
6939 fn generate_except_step(&mut self, except: &Except) -> Result<()> {
6941 use crate::dialects::DialectType;
6942
6943 if self.config.pretty {
6944 self.write_newline();
6945 self.write_indent();
6946 } else {
6947 self.write_space();
6948 }
6949
6950 if let Some(side) = &except.side {
6952 self.write_keyword(side);
6953 self.write_space();
6954 }
6955 if let Some(kind) = &except.kind {
6956 self.write_keyword(kind);
6957 self.write_space();
6958 }
6959
6960 match self.config.dialect {
6962 Some(DialectType::Oracle) if !except.all => {
6963 self.write_keyword("MINUS");
6964 }
6965 Some(DialectType::ClickHouse) => {
6966 self.write_keyword("EXCEPT");
6967 let preserve_all = self.config.source_dialect.is_none()
6968 || matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
6969 if except.all && preserve_all {
6970 self.write_space();
6971 self.write_keyword("ALL");
6972 }
6973 if except.distinct {
6974 self.write_space();
6975 self.write_keyword("DISTINCT");
6976 }
6977 }
6978 Some(DialectType::BigQuery) => {
6979 self.write_keyword("EXCEPT");
6981 if except.all {
6982 self.write_space();
6983 self.write_keyword("ALL");
6984 } else {
6985 self.write_space();
6986 self.write_keyword("DISTINCT");
6987 }
6988 }
6989 _ => {
6990 self.write_keyword("EXCEPT");
6991 if except.all {
6992 self.write_space();
6993 self.write_keyword("ALL");
6994 } else if except.distinct {
6995 self.write_space();
6996 self.write_keyword("DISTINCT");
6997 }
6998 }
6999 }
7000
7001 if except.corresponding || except.by_name {
7004 self.write_space();
7005 self.write_keyword("BY NAME");
7006 }
7007 if !except.on_columns.is_empty() {
7008 self.write_space();
7009 self.write_keyword("ON");
7010 self.write(" (");
7011 for (i, col) in except.on_columns.iter().enumerate() {
7012 if i > 0 {
7013 self.write(", ");
7014 }
7015 self.generate_expression(col)?;
7016 }
7017 self.write(")");
7018 }
7019
7020 if self.config.pretty {
7021 self.write_newline();
7022 self.write_indent();
7023 } else {
7024 self.write_space();
7025 }
7026 self.generate_expression(&except.right)?;
7027 if let Some(order_by) = &except.order_by {
7029 if self.config.pretty {
7030 self.write_newline();
7031 } else {
7032 self.write_space();
7033 }
7034 self.write_keyword("ORDER BY");
7035 self.write_space();
7036 for (i, ordered) in order_by.expressions.iter().enumerate() {
7037 if i > 0 {
7038 self.write(", ");
7039 }
7040 self.generate_ordered(ordered)?;
7041 }
7042 }
7043 if let Some(limit) = &except.limit {
7044 if self.config.pretty {
7045 self.write_newline();
7046 } else {
7047 self.write_space();
7048 }
7049 self.write_keyword("LIMIT");
7050 self.write_space();
7051 self.generate_expression(limit)?;
7052 }
7053 if let Some(offset) = &except.offset {
7054 if self.config.pretty {
7055 self.write_newline();
7056 } else {
7057 self.write_space();
7058 }
7059 self.write_keyword("OFFSET");
7060 self.write_space();
7061 self.generate_expression(offset)?;
7062 }
7063 if let Some(distribute_by) = &except.distribute_by {
7065 self.write_space();
7066 self.write_keyword("DISTRIBUTE BY");
7067 self.write_space();
7068 for (i, expr) in distribute_by.expressions.iter().enumerate() {
7069 if i > 0 {
7070 self.write(", ");
7071 }
7072 self.generate_expression(expr)?;
7073 }
7074 }
7075 if let Some(sort_by) = &except.sort_by {
7077 self.write_space();
7078 self.write_keyword("SORT BY");
7079 self.write_space();
7080 for (i, ord) in sort_by.expressions.iter().enumerate() {
7081 if i > 0 {
7082 self.write(", ");
7083 }
7084 self.generate_ordered(ord)?;
7085 }
7086 }
7087 if let Some(cluster_by) = &except.cluster_by {
7089 self.write_space();
7090 self.write_keyword("CLUSTER BY");
7091 self.write_space();
7092 for (i, ord) in cluster_by.expressions.iter().enumerate() {
7093 if i > 0 {
7094 self.write(", ");
7095 }
7096 self.generate_ordered(ord)?;
7097 }
7098 }
7099 Ok(())
7100 }
7101
7102 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
7103 let prepend_query_cte = if insert.with.is_none() {
7105 use crate::dialects::DialectType;
7106 let should_prepend = matches!(
7107 self.config.dialect,
7108 Some(DialectType::TSQL)
7109 | Some(DialectType::Fabric)
7110 | Some(DialectType::Spark)
7111 | Some(DialectType::Databricks)
7112 | Some(DialectType::Hive)
7113 );
7114 if should_prepend {
7115 if let Some(Expression::Select(select)) = &insert.query {
7116 select.with.clone()
7117 } else {
7118 None
7119 }
7120 } else {
7121 None
7122 }
7123 } else {
7124 None
7125 };
7126
7127 if let Some(with) = &insert.with {
7129 self.generate_with(with)?;
7130 self.write_space();
7131 } else if let Some(with) = &prepend_query_cte {
7132 self.generate_with(with)?;
7133 self.write_space();
7134 }
7135
7136 for comment in &insert.leading_comments {
7138 self.write_formatted_comment(comment);
7139 self.write(" ");
7140 }
7141
7142 if let Some(dir) = &insert.directory {
7144 self.write_keyword("INSERT OVERWRITE");
7145 if dir.local {
7146 self.write_space();
7147 self.write_keyword("LOCAL");
7148 }
7149 self.write_space();
7150 self.write_keyword("DIRECTORY");
7151 self.write_space();
7152 self.write("'");
7153 self.write(&dir.path);
7154 self.write("'");
7155
7156 if let Some(row_format) = &dir.row_format {
7158 self.write_space();
7159 self.write_keyword("ROW FORMAT");
7160 if row_format.delimited {
7161 self.write_space();
7162 self.write_keyword("DELIMITED");
7163 }
7164 if let Some(val) = &row_format.fields_terminated_by {
7165 self.write_space();
7166 self.write_keyword("FIELDS TERMINATED BY");
7167 self.write_space();
7168 self.generate_string_literal(val)?;
7169 }
7170 if let Some(val) = &row_format.collection_items_terminated_by {
7171 self.write_space();
7172 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
7173 self.write_space();
7174 self.write("'");
7175 self.write(val);
7176 self.write("'");
7177 }
7178 if let Some(val) = &row_format.map_keys_terminated_by {
7179 self.write_space();
7180 self.write_keyword("MAP KEYS TERMINATED BY");
7181 self.write_space();
7182 self.write("'");
7183 self.write(val);
7184 self.write("'");
7185 }
7186 if let Some(val) = &row_format.lines_terminated_by {
7187 self.write_space();
7188 self.write_keyword("LINES TERMINATED BY");
7189 self.write_space();
7190 self.write("'");
7191 self.write(val);
7192 self.write("'");
7193 }
7194 if let Some(val) = &row_format.null_defined_as {
7195 self.write_space();
7196 self.write_keyword("NULL DEFINED AS");
7197 self.write_space();
7198 self.write("'");
7199 self.write(val);
7200 self.write("'");
7201 }
7202 }
7203
7204 if let Some(format) = &dir.stored_as {
7206 self.write_space();
7207 self.write_keyword("STORED AS");
7208 self.write_space();
7209 self.write_keyword(format);
7210 }
7211
7212 if let Some(query) = &insert.query {
7214 self.write_space();
7215 self.generate_expression(query)?;
7216 }
7217
7218 return Ok(());
7219 }
7220
7221 if insert.is_replace {
7222 self.write_keyword("REPLACE INTO");
7224 } else if insert.overwrite {
7225 self.write_keyword("INSERT");
7227 if let Some(ref hint) = insert.hint {
7229 self.generate_hint(hint)?;
7230 }
7231 self.write(&self.config.insert_overwrite.to_ascii_uppercase());
7232 } else if let Some(ref action) = insert.conflict_action {
7233 self.write_keyword("INSERT OR");
7235 self.write_space();
7236 self.write_keyword(action);
7237 self.write_space();
7238 self.write_keyword("INTO");
7239 } else if insert.ignore {
7240 self.write_keyword("INSERT IGNORE INTO");
7242 } else {
7243 self.write_keyword("INSERT");
7244 if let Some(ref hint) = insert.hint {
7246 self.generate_hint(hint)?;
7247 }
7248 self.write_space();
7249 self.write_keyword("INTO");
7250 }
7251 if let Some(ref func) = insert.function_target {
7253 self.write_space();
7254 self.write_keyword("FUNCTION");
7255 self.write_space();
7256 self.generate_expression(func)?;
7257 } else {
7258 self.write_space();
7259 self.generate_table(&insert.table)?;
7260 }
7261
7262 if let Some(ref alias) = insert.alias {
7264 self.write_space();
7265 if insert.alias_explicit_as {
7266 self.write_keyword("AS");
7267 self.write_space();
7268 }
7269 self.generate_identifier(alias)?;
7270 }
7271
7272 if insert.if_exists {
7274 self.write_space();
7275 self.write_keyword("IF EXISTS");
7276 }
7277
7278 if let Some(ref replace_where) = insert.replace_where {
7280 if self.config.pretty {
7281 self.write_newline();
7282 self.write_indent();
7283 } else {
7284 self.write_space();
7285 }
7286 self.write_keyword("REPLACE WHERE");
7287 self.write_space();
7288 self.generate_expression(replace_where)?;
7289 }
7290
7291 if !insert.partition.is_empty() {
7293 self.write_space();
7294 self.write_keyword("PARTITION");
7295 self.write("(");
7296 for (i, (col, val)) in insert.partition.iter().enumerate() {
7297 if i > 0 {
7298 self.write(", ");
7299 }
7300 self.generate_identifier(col)?;
7301 if let Some(v) = val {
7302 self.write(" = ");
7303 self.generate_expression(v)?;
7304 }
7305 }
7306 self.write(")");
7307 }
7308
7309 if let Some(ref partition_by) = insert.partition_by {
7311 self.write_space();
7312 self.write_keyword("PARTITION BY");
7313 self.write_space();
7314 self.generate_expression(partition_by)?;
7315 }
7316
7317 if !insert.settings.is_empty() {
7319 self.write_space();
7320 self.write_keyword("SETTINGS");
7321 self.write_space();
7322 for (i, setting) in insert.settings.iter().enumerate() {
7323 if i > 0 {
7324 self.write(", ");
7325 }
7326 self.generate_expression(setting)?;
7327 }
7328 }
7329
7330 if !insert.columns.is_empty() {
7331 if insert.alias.is_some() && insert.alias_explicit_as {
7332 self.write("(");
7334 } else {
7335 self.write(" (");
7337 }
7338 for (i, col) in insert.columns.iter().enumerate() {
7339 if i > 0 {
7340 self.write(", ");
7341 }
7342 self.generate_identifier(col)?;
7343 }
7344 self.write(")");
7345 }
7346
7347 if let Some(ref output) = insert.output {
7349 self.generate_output_clause(output)?;
7350 }
7351
7352 if insert.by_name {
7354 self.write_space();
7355 self.write_keyword("BY NAME");
7356 }
7357
7358 if insert.default_values {
7359 self.write_space();
7360 self.write_keyword("DEFAULT VALUES");
7361 } else if let Some(query) = &insert.query {
7362 if self.config.pretty {
7363 self.write_newline();
7364 } else {
7365 self.write_space();
7366 }
7367 if prepend_query_cte.is_some() {
7369 if let Expression::Select(select) = query {
7370 let mut select_no_with = select.clone();
7371 select_no_with.with = None;
7372 self.generate_select(&select_no_with)?;
7373 } else {
7374 self.generate_expression(query)?;
7375 }
7376 } else {
7377 self.generate_expression(query)?;
7378 }
7379 } else if !insert.values.is_empty() {
7380 if self.config.pretty {
7381 self.write_newline();
7383 self.write_keyword("VALUES");
7384 self.write_newline();
7385 self.indent_level += 1;
7386 for (i, row) in insert.values.iter().enumerate() {
7387 if i > 0 {
7388 self.write(",");
7389 self.write_newline();
7390 }
7391 self.write_indent();
7392 self.write("(");
7393 for (j, val) in row.iter().enumerate() {
7394 if j > 0 {
7395 self.write(", ");
7396 }
7397 self.generate_expression(val)?;
7398 }
7399 self.write(")");
7400 }
7401 self.indent_level -= 1;
7402 } else {
7403 self.write_space();
7405 self.write_keyword("VALUES");
7406 for (i, row) in insert.values.iter().enumerate() {
7407 if i > 0 {
7408 self.write(",");
7409 }
7410 self.write(" (");
7411 for (j, val) in row.iter().enumerate() {
7412 if j > 0 {
7413 self.write(", ");
7414 }
7415 self.generate_expression(val)?;
7416 }
7417 self.write(")");
7418 }
7419 }
7420 }
7421
7422 if let Some(ref source) = insert.source {
7424 self.write_space();
7425 self.write_keyword("TABLE");
7426 self.write_space();
7427 self.generate_expression(source)?;
7428 }
7429
7430 if let Some(alias) = &insert.source_alias {
7432 self.write_space();
7433 self.write_keyword("AS");
7434 self.write_space();
7435 self.generate_identifier(alias)?;
7436 }
7437
7438 if let Some(on_conflict) = &insert.on_conflict {
7440 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
7441 self.write_space();
7442 self.generate_expression(on_conflict)?;
7443 }
7444 }
7445
7446 if !insert.returning.is_empty() {
7448 self.write_space();
7449 self.write_keyword("RETURNING");
7450 self.write_space();
7451 for (i, expr) in insert.returning.iter().enumerate() {
7452 if i > 0 {
7453 self.write(", ");
7454 }
7455 self.generate_expression(expr)?;
7456 }
7457 }
7458
7459 Ok(())
7460 }
7461
7462 fn generate_update(&mut self, update: &Update) -> Result<()> {
7463 for comment in &update.leading_comments {
7465 self.write_formatted_comment(comment);
7466 self.write(" ");
7467 }
7468
7469 if let Some(ref with) = update.with {
7471 self.generate_with(with)?;
7472 self.write_space();
7473 }
7474
7475 self.write_keyword("UPDATE");
7476 if let Some(hint) = &update.hint {
7477 self.generate_hint(hint)?;
7478 }
7479 self.write_space();
7480 self.generate_table(&update.table)?;
7481
7482 let mysql_like_update_from = matches!(
7483 self.config.dialect,
7484 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
7485 ) && update.from_clause.is_some();
7486
7487 let mut set_pairs = update.set.clone();
7488
7489 let mut pre_set_joins = update.table_joins.clone();
7491 if mysql_like_update_from {
7492 let target_name = update
7493 .table
7494 .alias
7495 .as_ref()
7496 .map(|a| a.name.clone())
7497 .unwrap_or_else(|| update.table.name.name.clone());
7498
7499 for (col, _) in &mut set_pairs {
7500 if !col.name.contains('.') {
7501 col.name = format!("{}.{}", target_name, col.name);
7502 }
7503 }
7504
7505 if let Some(from_clause) = &update.from_clause {
7506 for table_expr in &from_clause.expressions {
7507 pre_set_joins.push(crate::expressions::Join {
7508 this: table_expr.clone(),
7509 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7510 value: true,
7511 })),
7512 using: Vec::new(),
7513 kind: crate::expressions::JoinKind::Inner,
7514 use_inner_keyword: false,
7515 use_outer_keyword: false,
7516 deferred_condition: false,
7517 join_hint: None,
7518 match_condition: None,
7519 pivots: Vec::new(),
7520 comments: Vec::new(),
7521 nesting_group: 0,
7522 directed: false,
7523 });
7524 }
7525 }
7526 for join in &update.from_joins {
7527 let mut join = join.clone();
7528 if join.on.is_none() && join.using.is_empty() {
7529 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7530 value: true,
7531 }));
7532 }
7533 pre_set_joins.push(join);
7534 }
7535 }
7536
7537 for extra_table in &update.extra_tables {
7539 self.write(", ");
7540 self.generate_table(extra_table)?;
7541 }
7542
7543 for join in &pre_set_joins {
7545 self.generate_join(join)?;
7547 }
7548
7549 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
7551 if teradata_from_before_set && !mysql_like_update_from {
7552 if let Some(ref from_clause) = update.from_clause {
7553 self.write_space();
7554 self.write_keyword("FROM");
7555 self.write_space();
7556 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7557 if i > 0 {
7558 self.write(", ");
7559 }
7560 self.generate_expression(table_expr)?;
7561 }
7562 }
7563 for join in &update.from_joins {
7564 self.generate_join(join)?;
7565 }
7566 }
7567
7568 self.write_space();
7569 self.write_keyword("SET");
7570 self.write_space();
7571
7572 for (i, (col, val)) in set_pairs.iter().enumerate() {
7573 if i > 0 {
7574 self.write(", ");
7575 }
7576 self.generate_identifier(col)?;
7577 self.write(" = ");
7578 self.generate_expression(val)?;
7579 }
7580
7581 if let Some(ref output) = update.output {
7583 self.generate_output_clause(output)?;
7584 }
7585
7586 if !mysql_like_update_from && !teradata_from_before_set {
7588 if let Some(ref from_clause) = update.from_clause {
7589 self.write_space();
7590 self.write_keyword("FROM");
7591 self.write_space();
7592 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7594 if i > 0 {
7595 self.write(", ");
7596 }
7597 self.generate_expression(table_expr)?;
7598 }
7599 }
7600 }
7601
7602 if !mysql_like_update_from && !teradata_from_before_set {
7603 for join in &update.from_joins {
7605 self.generate_join(join)?;
7606 }
7607 }
7608
7609 if let Some(where_clause) = &update.where_clause {
7610 self.write_space();
7611 self.write_keyword("WHERE");
7612 self.write_space();
7613 self.generate_expression(&where_clause.this)?;
7614 }
7615
7616 if !update.returning.is_empty() {
7618 self.write_space();
7619 self.write_keyword("RETURNING");
7620 self.write_space();
7621 for (i, expr) in update.returning.iter().enumerate() {
7622 if i > 0 {
7623 self.write(", ");
7624 }
7625 self.generate_expression(expr)?;
7626 }
7627 }
7628
7629 if let Some(ref order_by) = update.order_by {
7631 self.write_space();
7632 self.generate_order_by(order_by)?;
7633 }
7634
7635 if let Some(ref limit) = update.limit {
7637 self.write_space();
7638 self.write_keyword("LIMIT");
7639 self.write_space();
7640 self.generate_expression(limit)?;
7641 }
7642
7643 Ok(())
7644 }
7645
7646 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
7647 if let Some(with) = &delete.with {
7649 self.generate_with(with)?;
7650 self.write_space();
7651 }
7652
7653 for comment in &delete.leading_comments {
7655 self.write_formatted_comment(comment);
7656 self.write(" ");
7657 }
7658
7659 if !delete.tables.is_empty() && !delete.tables_from_using {
7661 self.write_keyword("DELETE");
7663 if let Some(hint) = &delete.hint {
7664 self.generate_hint(hint)?;
7665 }
7666 self.write_space();
7667 for (i, tbl) in delete.tables.iter().enumerate() {
7668 if i > 0 {
7669 self.write(", ");
7670 }
7671 self.generate_table(tbl)?;
7672 }
7673 if let Some(ref output) = delete.output {
7675 self.generate_output_clause(output)?;
7676 }
7677 self.write_space();
7678 self.write_keyword("FROM");
7679 self.write_space();
7680 self.generate_table(&delete.table)?;
7681 } else if !delete.tables.is_empty() && delete.tables_from_using {
7682 self.write_keyword("DELETE");
7684 if let Some(hint) = &delete.hint {
7685 self.generate_hint(hint)?;
7686 }
7687 self.write_space();
7688 self.write_keyword("FROM");
7689 self.write_space();
7690 for (i, tbl) in delete.tables.iter().enumerate() {
7691 if i > 0 {
7692 self.write(", ");
7693 }
7694 self.generate_table(tbl)?;
7695 }
7696 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
7697 self.write_keyword("DELETE");
7699 if let Some(hint) = &delete.hint {
7700 self.generate_hint(hint)?;
7701 }
7702 self.write_space();
7703 self.generate_table(&delete.table)?;
7704 } else {
7705 self.write_keyword("DELETE");
7706 if let Some(hint) = &delete.hint {
7707 self.generate_hint(hint)?;
7708 }
7709 self.write_space();
7710 self.write_keyword("FROM");
7711 self.write_space();
7712 self.generate_table(&delete.table)?;
7713 }
7714
7715 if let Some(ref on_cluster) = delete.on_cluster {
7717 self.write_space();
7718 self.generate_on_cluster(on_cluster)?;
7719 }
7720
7721 if let Some(ref idx) = delete.force_index {
7723 self.write_space();
7724 self.write_keyword("FORCE INDEX");
7725 self.write(" (");
7726 self.write(idx);
7727 self.write(")");
7728 }
7729
7730 if let Some(ref alias) = delete.alias {
7732 self.write_space();
7733 if delete.alias_explicit_as
7734 || matches!(self.config.dialect, Some(DialectType::BigQuery))
7735 {
7736 self.write_keyword("AS");
7737 self.write_space();
7738 }
7739 self.generate_identifier(alias)?;
7740 }
7741
7742 if !delete.tables_from_using {
7744 for join in &delete.joins {
7745 self.generate_join(join)?;
7746 }
7747 }
7748
7749 if !delete.using.is_empty() {
7751 self.write_space();
7752 self.write_keyword("USING");
7753 for (i, table) in delete.using.iter().enumerate() {
7754 if i > 0 {
7755 self.write(",");
7756 }
7757 self.write_space();
7758 if !table.hints.is_empty() && table.name.is_empty() {
7760 self.generate_expression(&table.hints[0])?;
7762 if let Some(ref alias) = table.alias {
7763 self.write_space();
7764 if table.alias_explicit_as {
7765 self.write_keyword("AS");
7766 self.write_space();
7767 }
7768 self.generate_identifier(alias)?;
7769 if !table.column_aliases.is_empty() {
7770 self.write("(");
7771 for (j, col_alias) in table.column_aliases.iter().enumerate() {
7772 if j > 0 {
7773 self.write(", ");
7774 }
7775 self.generate_identifier(col_alias)?;
7776 }
7777 self.write(")");
7778 }
7779 }
7780 } else {
7781 self.generate_table(table)?;
7782 }
7783 }
7784 }
7785
7786 if delete.tables_from_using {
7788 for join in &delete.joins {
7789 self.generate_join(join)?;
7790 }
7791 }
7792
7793 let output_already_emitted =
7795 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
7796 if !output_already_emitted {
7797 if let Some(ref output) = delete.output {
7798 self.generate_output_clause(output)?;
7799 }
7800 }
7801
7802 if let Some(where_clause) = &delete.where_clause {
7803 self.write_space();
7804 self.write_keyword("WHERE");
7805 self.write_space();
7806 self.generate_expression(&where_clause.this)?;
7807 }
7808
7809 if let Some(ref order_by) = delete.order_by {
7811 self.write_space();
7812 self.generate_order_by(order_by)?;
7813 }
7814
7815 if let Some(ref limit) = delete.limit {
7817 self.write_space();
7818 self.write_keyword("LIMIT");
7819 self.write_space();
7820 self.generate_expression(limit)?;
7821 }
7822
7823 if !delete.returning.is_empty() {
7825 self.write_space();
7826 self.write_keyword("RETURNING");
7827 self.write_space();
7828 for (i, expr) in delete.returning.iter().enumerate() {
7829 if i > 0 {
7830 self.write(", ");
7831 }
7832 self.generate_expression(expr)?;
7833 }
7834 }
7835
7836 Ok(())
7837 }
7838
7839 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
7842 let saved_athena_hive_context = self.athena_hive_context;
7846 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
7847 if matches!(
7848 self.config.dialect,
7849 Some(crate::dialects::DialectType::Athena)
7850 ) {
7851 let is_external = ct
7855 .table_modifier
7856 .as_ref()
7857 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
7858 .unwrap_or(false);
7859 let has_as_select = ct.as_select.is_some();
7860 self.athena_hive_context = is_external || !has_as_select;
7861 }
7862
7863 if matches!(
7865 self.config.dialect,
7866 Some(crate::dialects::DialectType::TSQL)
7867 ) {
7868 if let Some(ref query) = ct.as_select {
7869 if let Some(with_cte) = &ct.with_cte {
7871 self.generate_with(with_cte)?;
7872 self.write_space();
7873 }
7874
7875 self.write_keyword("SELECT");
7877 self.write(" * ");
7878 self.write_keyword("INTO");
7879 self.write_space();
7880
7881 if ct.temporary {
7883 self.write("#");
7884 }
7885 self.generate_table(&ct.name)?;
7886
7887 self.write_space();
7888 self.write_keyword("FROM");
7889 self.write(" (");
7890 let aliased_query = Self::add_column_aliases_to_query(query.clone());
7892 self.generate_expression(&aliased_query)?;
7893 self.write(") ");
7894 self.write_keyword("AS");
7895 self.write(" temp");
7896 return Ok(());
7897 }
7898 }
7899
7900 if let Some(with_cte) = &ct.with_cte {
7902 self.generate_with(with_cte)?;
7903 self.write_space();
7904 }
7905
7906 for comment in &ct.leading_comments {
7908 self.write_formatted_comment(comment);
7909 self.write(" ");
7910 }
7911 self.write_keyword("CREATE");
7912
7913 if ct.or_replace {
7914 self.write_space();
7915 self.write_keyword("OR REPLACE");
7916 }
7917
7918 if ct.temporary {
7919 self.write_space();
7920 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
7922 self.write_keyword("GLOBAL TEMPORARY");
7923 } else {
7924 self.write_keyword("TEMPORARY");
7925 }
7926 }
7927
7928 let is_dictionary = ct
7930 .table_modifier
7931 .as_ref()
7932 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
7933 .unwrap_or(false);
7934 if let Some(ref modifier) = ct.table_modifier {
7935 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
7937 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
7938 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
7940 || modifier.eq_ignore_ascii_case("SET")
7941 || modifier.eq_ignore_ascii_case("MULTISET")
7942 || modifier.to_ascii_uppercase().contains("VOLATILE")
7943 || modifier.to_ascii_uppercase().starts_with("SET ")
7944 || modifier.to_ascii_uppercase().starts_with("MULTISET ");
7945 let skip_teradata =
7946 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
7947 if !skip_transient && !skip_teradata {
7948 self.write_space();
7949 self.write_keyword(modifier);
7950 }
7951 }
7952
7953 if !is_dictionary {
7954 self.write_space();
7955 self.write_keyword("TABLE");
7956 }
7957
7958 if ct.if_not_exists {
7959 self.write_space();
7960 self.write_keyword("IF NOT EXISTS");
7961 }
7962
7963 self.write_space();
7964 self.generate_table(&ct.name)?;
7965
7966 if let Some(ref uuid) = ct.uuid {
7968 self.write_space();
7969 self.write_keyword("UUID");
7970 self.write(" '");
7971 self.write(uuid);
7972 self.write("'");
7973 }
7974
7975 if let Some(ref on_cluster) = ct.on_cluster {
7977 self.write_space();
7978 self.generate_on_cluster(on_cluster)?;
7979 }
7980
7981 if matches!(
7983 self.config.dialect,
7984 Some(crate::dialects::DialectType::Teradata)
7985 ) && !ct.teradata_post_name_options.is_empty()
7986 {
7987 for opt in &ct.teradata_post_name_options {
7988 self.write(", ");
7989 self.write(opt);
7990 }
7991 }
7992
7993 if ct.copy_grants {
7995 self.write_space();
7996 self.write_keyword("COPY GRANTS");
7997 }
7998
7999 if let Some(ref using_template) = ct.using_template {
8001 self.write_space();
8002 self.write_keyword("USING TEMPLATE");
8003 self.write_space();
8004 self.generate_expression(using_template)?;
8005 return Ok(());
8006 }
8007
8008 if is_clickhouse {
8012 if let Some(ref clone_source) = ct.clone_source {
8013 if ct.columns.is_empty() && ct.constraints.is_empty() {
8014 self.write_space();
8015 self.write_keyword("AS");
8016 self.write_space();
8017 self.generate_table(clone_source)?;
8018 }
8019 }
8020 }
8021
8022 if !is_clickhouse {
8024 if let Some(ref clone_source) = ct.clone_source {
8025 self.write_space();
8026 if ct.is_copy && self.config.supports_table_copy {
8027 self.write_keyword("COPY");
8029 } else if ct.shallow_clone {
8030 self.write_keyword("SHALLOW CLONE");
8031 } else if ct.deep_clone {
8032 self.write_keyword("DEEP CLONE");
8033 } else {
8034 self.write_keyword("CLONE");
8035 }
8036 self.write_space();
8037 self.generate_table(clone_source)?;
8038 if let Some(ref at_clause) = ct.clone_at_clause {
8040 self.write_space();
8041 self.generate_expression(at_clause)?;
8042 }
8043 return Ok(());
8044 }
8045 }
8046
8047 if let Some(ref partition_of) = ct.partition_of {
8051 self.write_space();
8052
8053 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
8055 self.write_keyword("PARTITION OF");
8057 self.write_space();
8058 self.generate_expression(&pop.this)?;
8059
8060 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
8062 self.write(" (");
8063 let mut first = true;
8064 for col in &ct.columns {
8065 if !first {
8066 self.write(", ");
8067 }
8068 first = false;
8069 self.generate_column_def(col)?;
8070 }
8071 for constraint in &ct.constraints {
8072 if !first {
8073 self.write(", ");
8074 }
8075 first = false;
8076 self.generate_table_constraint(constraint)?;
8077 }
8078 self.write(")");
8079 }
8080
8081 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
8083 self.write_space();
8084 self.write_keyword("FOR VALUES");
8085 self.write_space();
8086 self.generate_expression(&pop.expression)?;
8087 } else {
8088 self.write_space();
8089 self.write_keyword("DEFAULT");
8090 }
8091 } else {
8092 self.generate_expression(partition_of)?;
8094
8095 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
8097 self.write(" (");
8098 let mut first = true;
8099 for col in &ct.columns {
8100 if !first {
8101 self.write(", ");
8102 }
8103 first = false;
8104 self.generate_column_def(col)?;
8105 }
8106 for constraint in &ct.constraints {
8107 if !first {
8108 self.write(", ");
8109 }
8110 first = false;
8111 self.generate_table_constraint(constraint)?;
8112 }
8113 self.write(")");
8114 }
8115 }
8116
8117 for prop in &ct.properties {
8119 self.write_space();
8120 self.generate_expression(prop)?;
8121 }
8122
8123 return Ok(());
8124 }
8125
8126 self.sqlite_inline_pk_columns.clear();
8129 if matches!(
8130 self.config.dialect,
8131 Some(crate::dialects::DialectType::SQLite)
8132 ) {
8133 for constraint in &ct.constraints {
8134 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8135 if columns.len() == 1 && name.is_none() {
8137 let pk_col_name = columns[0].name.to_ascii_lowercase();
8138 if ct
8140 .columns
8141 .iter()
8142 .any(|c| c.name.name.to_ascii_lowercase() == pk_col_name)
8143 {
8144 self.sqlite_inline_pk_columns.insert(pk_col_name);
8145 }
8146 }
8147 }
8148 }
8149 }
8150
8151 if !ct.columns.is_empty() {
8153 if self.config.pretty {
8154 self.write(" (");
8156 self.write_newline();
8157 self.indent_level += 1;
8158 for (i, col) in ct.columns.iter().enumerate() {
8159 if i > 0 {
8160 self.write(",");
8161 self.write_newline();
8162 }
8163 self.write_indent();
8164 self.generate_column_def(col)?;
8165 }
8166 for constraint in &ct.constraints {
8168 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8170 if columns.len() == 1
8171 && name.is_none()
8172 && self
8173 .sqlite_inline_pk_columns
8174 .contains(&columns[0].name.to_ascii_lowercase())
8175 {
8176 continue;
8177 }
8178 }
8179 self.write(",");
8180 self.write_newline();
8181 self.write_indent();
8182 self.generate_table_constraint(constraint)?;
8183 }
8184 self.indent_level -= 1;
8185 self.write_newline();
8186 self.write(")");
8187 } else {
8188 self.write(" (");
8189 for (i, col) in ct.columns.iter().enumerate() {
8190 if i > 0 {
8191 self.write(", ");
8192 }
8193 self.generate_column_def(col)?;
8194 }
8195 let mut first_constraint = true;
8197 for constraint in &ct.constraints {
8198 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8200 if columns.len() == 1
8201 && name.is_none()
8202 && self
8203 .sqlite_inline_pk_columns
8204 .contains(&columns[0].name.to_ascii_lowercase())
8205 {
8206 continue;
8207 }
8208 }
8209 if first_constraint {
8210 self.write(", ");
8211 first_constraint = false;
8212 } else {
8213 self.write(", ");
8214 }
8215 self.generate_table_constraint(constraint)?;
8216 }
8217 self.write(")");
8218 }
8219 } else if !ct.constraints.is_empty() {
8220 let has_like_only = ct
8222 .constraints
8223 .iter()
8224 .all(|c| matches!(c, TableConstraint::Like { .. }));
8225 let has_tags_only = ct
8226 .constraints
8227 .iter()
8228 .all(|c| matches!(c, TableConstraint::Tags(_)));
8229 let is_pg_like = matches!(
8233 self.config.dialect,
8234 Some(crate::dialects::DialectType::PostgreSQL)
8235 | Some(crate::dialects::DialectType::CockroachDB)
8236 | Some(crate::dialects::DialectType::Materialize)
8237 | Some(crate::dialects::DialectType::RisingWave)
8238 | Some(crate::dialects::DialectType::Redshift)
8239 | Some(crate::dialects::DialectType::Presto)
8240 | Some(crate::dialects::DialectType::Trino)
8241 | Some(crate::dialects::DialectType::Athena)
8242 );
8243 let use_parens = if has_like_only {
8244 is_pg_like
8245 } else {
8246 !has_tags_only
8247 };
8248 if self.config.pretty && use_parens {
8249 self.write(" (");
8250 self.write_newline();
8251 self.indent_level += 1;
8252 for (i, constraint) in ct.constraints.iter().enumerate() {
8253 if i > 0 {
8254 self.write(",");
8255 self.write_newline();
8256 }
8257 self.write_indent();
8258 self.generate_table_constraint(constraint)?;
8259 }
8260 self.indent_level -= 1;
8261 self.write_newline();
8262 self.write(")");
8263 } else {
8264 if use_parens {
8265 self.write(" (");
8266 } else {
8267 self.write_space();
8268 }
8269 for (i, constraint) in ct.constraints.iter().enumerate() {
8270 if i > 0 {
8271 self.write(", ");
8272 }
8273 self.generate_table_constraint(constraint)?;
8274 }
8275 if use_parens {
8276 self.write(")");
8277 }
8278 }
8279 }
8280
8281 if is_clickhouse && (!ct.columns.is_empty() || !ct.constraints.is_empty()) {
8282 if let Some(ref clone_source) = ct.clone_source {
8283 self.write_space();
8284 self.write_keyword("AS");
8285 self.write_space();
8286 self.generate_table(clone_source)?;
8287 }
8288 }
8289
8290 if let Some(ref on_prop) = ct.on_property {
8292 self.write(" ");
8293 self.write_keyword("ON");
8294 self.write(" ");
8295 self.generate_expression(&on_prop.this)?;
8296 }
8297
8298 if !ct.with_partition_columns.is_empty() {
8300 if self.config.pretty {
8301 self.write_newline();
8302 } else {
8303 self.write_space();
8304 }
8305 self.write_keyword("WITH PARTITION COLUMNS");
8306 self.write(" (");
8307 if self.config.pretty {
8308 self.write_newline();
8309 self.indent_level += 1;
8310 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8311 if i > 0 {
8312 self.write(",");
8313 self.write_newline();
8314 }
8315 self.write_indent();
8316 self.generate_column_def(col)?;
8317 }
8318 self.indent_level -= 1;
8319 self.write_newline();
8320 } else {
8321 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8322 if i > 0 {
8323 self.write(", ");
8324 }
8325 self.generate_column_def(col)?;
8326 }
8327 }
8328 self.write(")");
8329 }
8330
8331 if let Some(ref conn) = ct.with_connection {
8333 if self.config.pretty {
8334 self.write_newline();
8335 } else {
8336 self.write_space();
8337 }
8338 self.write_keyword("WITH CONNECTION");
8339 self.write_space();
8340 self.generate_table(conn)?;
8341 }
8342
8343 if !is_clickhouse {
8346 for prop in &ct.properties {
8347 if let Expression::SchemaCommentProperty(_) = prop {
8348 if self.config.pretty {
8349 self.write_newline();
8350 } else {
8351 self.write_space();
8352 }
8353 self.generate_expression(prop)?;
8354 }
8355 }
8356 }
8357
8358 if !ct.with_properties.is_empty() {
8360 let is_snowflake_special_table = matches!(
8362 self.config.dialect,
8363 Some(crate::dialects::DialectType::Snowflake)
8364 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
8365 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
8366 if is_snowflake_special_table {
8367 for (key, value) in &ct.with_properties {
8368 self.write_space();
8369 self.write(key);
8370 self.write("=");
8371 self.write(value);
8372 }
8373 } else if self.config.pretty {
8374 self.write_newline();
8375 self.write_keyword("WITH");
8376 self.write(" (");
8377 self.write_newline();
8378 self.indent_level += 1;
8379 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8380 if i > 0 {
8381 self.write(",");
8382 self.write_newline();
8383 }
8384 self.write_indent();
8385 self.write(key);
8386 self.write("=");
8387 self.write(value);
8388 }
8389 self.indent_level -= 1;
8390 self.write_newline();
8391 self.write(")");
8392 } else {
8393 self.write_space();
8394 self.write_keyword("WITH");
8395 self.write(" (");
8396 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8397 if i > 0 {
8398 self.write(", ");
8399 }
8400 self.write(key);
8401 self.write("=");
8402 self.write(value);
8403 }
8404 self.write(")");
8405 }
8406 }
8407
8408 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
8409 if is_clickhouse && ct.as_select.is_some() {
8410 let mut pre = Vec::new();
8411 let mut post = Vec::new();
8412 for prop in &ct.properties {
8413 if matches!(prop, Expression::SchemaCommentProperty(_)) {
8414 post.push(prop);
8415 } else {
8416 pre.push(prop);
8417 }
8418 }
8419 (pre, post)
8420 } else {
8421 (ct.properties.iter().collect(), Vec::new())
8422 };
8423
8424 for prop in pre_as_properties {
8426 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
8428 continue;
8429 }
8430 if self.config.pretty {
8431 self.write_newline();
8432 } else {
8433 self.write_space();
8434 }
8435 if let Expression::Properties(props) = prop {
8439 let is_hive_dialect = matches!(
8440 self.config.dialect,
8441 Some(crate::dialects::DialectType::Hive)
8442 | Some(crate::dialects::DialectType::Spark)
8443 | Some(crate::dialects::DialectType::Databricks)
8444 | Some(crate::dialects::DialectType::Athena)
8445 );
8446 let is_doris_starrocks = matches!(
8447 self.config.dialect,
8448 Some(crate::dialects::DialectType::Doris)
8449 | Some(crate::dialects::DialectType::StarRocks)
8450 );
8451 if is_hive_dialect {
8452 self.generate_tblproperties_clause(&props.expressions)?;
8453 } else if is_doris_starrocks {
8454 self.generate_properties_clause(&props.expressions)?;
8455 } else {
8456 self.generate_options_clause(&props.expressions)?;
8457 }
8458 } else {
8459 self.generate_expression(prop)?;
8460 }
8461 }
8462
8463 for prop in &ct.post_table_properties {
8465 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
8466 self.write(" WITH(");
8467 self.generate_system_versioning_content(svp)?;
8468 self.write(")");
8469 } else if let Expression::Properties(props) = prop {
8470 let is_doris_starrocks = matches!(
8472 self.config.dialect,
8473 Some(crate::dialects::DialectType::Doris)
8474 | Some(crate::dialects::DialectType::StarRocks)
8475 );
8476 self.write_space();
8477 if is_doris_starrocks {
8478 self.generate_properties_clause(&props.expressions)?;
8479 } else {
8480 self.generate_options_clause(&props.expressions)?;
8481 }
8482 } else {
8483 self.write_space();
8484 self.generate_expression(prop)?;
8485 }
8486 }
8487
8488 if let Some(ref rollup) = ct.rollup {
8491 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
8492 self.write_space();
8493 self.generate_rollup_property(rollup)?;
8494 }
8495 }
8496
8497 let is_mysql_compatible = matches!(
8501 self.config.dialect,
8502 Some(DialectType::MySQL)
8503 | Some(DialectType::SingleStore)
8504 | Some(DialectType::Doris)
8505 | Some(DialectType::StarRocks)
8506 | None
8507 );
8508 let is_hive_compatible = matches!(
8509 self.config.dialect,
8510 Some(DialectType::Hive)
8511 | Some(DialectType::Spark)
8512 | Some(DialectType::Databricks)
8513 | Some(DialectType::Athena)
8514 );
8515 let mysql_pretty_options =
8516 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
8517 for (key, value) in &ct.mysql_table_options {
8518 let should_output = if is_mysql_compatible {
8520 true
8521 } else if is_hive_compatible && key == "COMMENT" {
8522 true } else {
8524 false
8525 };
8526 if should_output {
8527 if mysql_pretty_options {
8528 self.write_newline();
8529 self.write_indent();
8530 } else {
8531 self.write_space();
8532 }
8533 self.write_keyword(key);
8534 if key == "COMMENT" && !self.config.schema_comment_with_eq {
8536 self.write_space();
8537 } else {
8538 self.write("=");
8539 }
8540 self.write(value);
8541 }
8542 }
8543
8544 if ct.temporary
8546 && matches!(
8547 self.config.dialect,
8548 Some(DialectType::Spark) | Some(DialectType::Databricks)
8549 )
8550 && ct.as_select.is_none()
8551 {
8552 self.write_space();
8553 self.write_keyword("USING PARQUET");
8554 }
8555
8556 if !ct.inherits.is_empty() {
8558 self.write_space();
8559 self.write_keyword("INHERITS");
8560 self.write(" (");
8561 for (i, parent) in ct.inherits.iter().enumerate() {
8562 if i > 0 {
8563 self.write(", ");
8564 }
8565 self.generate_table(parent)?;
8566 }
8567 self.write(")");
8568 }
8569
8570 if let Some(ref query) = ct.as_select {
8572 self.write_space();
8573 self.write_keyword("AS");
8574 self.write_space();
8575 let source_is_clickhouse =
8576 matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
8577 let wrap_as_select =
8578 ct.as_select_parenthesized && !(is_clickhouse && source_is_clickhouse);
8579 if wrap_as_select {
8580 self.write("(");
8581 }
8582 self.generate_expression(query)?;
8583 if wrap_as_select {
8584 self.write(")");
8585 }
8586
8587 if let Some(with_data) = ct.with_data {
8589 self.write_space();
8590 self.write_keyword("WITH");
8591 if !with_data {
8592 self.write_space();
8593 self.write_keyword("NO");
8594 }
8595 self.write_space();
8596 self.write_keyword("DATA");
8597 }
8598
8599 if let Some(with_statistics) = ct.with_statistics {
8601 self.write_space();
8602 self.write_keyword("AND");
8603 if !with_statistics {
8604 self.write_space();
8605 self.write_keyword("NO");
8606 }
8607 self.write_space();
8608 self.write_keyword("STATISTICS");
8609 }
8610
8611 for index in &ct.teradata_indexes {
8613 self.write_space();
8614 match index.kind {
8615 TeradataIndexKind::NoPrimary => {
8616 self.write_keyword("NO PRIMARY INDEX");
8617 }
8618 TeradataIndexKind::Primary => {
8619 self.write_keyword("PRIMARY INDEX");
8620 }
8621 TeradataIndexKind::PrimaryAmp => {
8622 self.write_keyword("PRIMARY AMP INDEX");
8623 }
8624 TeradataIndexKind::Unique => {
8625 self.write_keyword("UNIQUE INDEX");
8626 }
8627 TeradataIndexKind::UniquePrimary => {
8628 self.write_keyword("UNIQUE PRIMARY INDEX");
8629 }
8630 TeradataIndexKind::Secondary => {
8631 self.write_keyword("INDEX");
8632 }
8633 }
8634 if let Some(ref name) = index.name {
8636 self.write_space();
8637 self.write(name);
8638 }
8639 if !index.columns.is_empty() {
8641 self.write(" (");
8642 for (i, col) in index.columns.iter().enumerate() {
8643 if i > 0 {
8644 self.write(", ");
8645 }
8646 self.write(col);
8647 }
8648 self.write(")");
8649 }
8650 }
8651
8652 if let Some(ref on_commit) = ct.on_commit {
8654 self.write_space();
8655 self.write_keyword("ON COMMIT");
8656 self.write_space();
8657 match on_commit {
8658 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8659 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8660 }
8661 }
8662
8663 if !post_as_properties.is_empty() {
8664 for prop in post_as_properties {
8665 self.write_space();
8666 self.generate_expression(prop)?;
8667 }
8668 }
8669
8670 self.athena_hive_context = saved_athena_hive_context;
8672 return Ok(());
8673 }
8674
8675 if let Some(ref on_commit) = ct.on_commit {
8677 self.write_space();
8678 self.write_keyword("ON COMMIT");
8679 self.write_space();
8680 match on_commit {
8681 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8682 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8683 }
8684 }
8685
8686 self.athena_hive_context = saved_athena_hive_context;
8688
8689 Ok(())
8690 }
8691
8692 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
8695 self.generate_identifier(&col.name)?;
8697 if !matches!(col.data_type, DataType::Unknown) {
8699 self.write_space();
8700 self.generate_data_type(&col.data_type)?;
8701 }
8702 for constraint in &col.constraints {
8704 if let ColumnConstraint::Path(path_expr) = constraint {
8705 self.write_space();
8706 self.write_keyword("PATH");
8707 self.write_space();
8708 self.generate_expression(path_expr)?;
8709 }
8710 }
8711 Ok(())
8712 }
8713
8714 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
8715 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8717 && col
8718 .constraints
8719 .iter()
8720 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8721 let omit_computed_type = !self.config.computed_column_with_type
8723 && col
8724 .constraints
8725 .iter()
8726 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8727
8728 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
8731
8732 let has_no_type = col.no_type
8735 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8736 && col.constraints.is_empty());
8737
8738 self.generate_identifier(&col.name)?;
8739
8740 let serial_expansion = if matches!(
8742 self.config.dialect,
8743 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
8744 ) {
8745 if let DataType::Custom { ref name } = col.data_type {
8746 if name.eq_ignore_ascii_case("SERIAL") {
8747 Some("INT")
8748 } else if name.eq_ignore_ascii_case("BIGSERIAL") {
8749 Some("BIGINT")
8750 } else if name.eq_ignore_ascii_case("SMALLSERIAL") {
8751 Some("SMALLINT")
8752 } else {
8753 None
8754 }
8755 } else {
8756 None
8757 }
8758 } else {
8759 None
8760 };
8761
8762 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
8763 {
8764 self.write_space();
8765 let saved_nullable_depth = self.clickhouse_nullable_depth;
8768 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
8769 self.clickhouse_nullable_depth = -1;
8770 }
8771 if let Some(int_type) = serial_expansion {
8772 self.write_keyword(int_type);
8774 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8775 let unsigned_type = match &col.data_type {
8777 DataType::Int { .. } => Some("UINTEGER"),
8778 DataType::BigInt { .. } => Some("UBIGINT"),
8779 DataType::SmallInt { .. } => Some("USMALLINT"),
8780 DataType::TinyInt { .. } => Some("UTINYINT"),
8781 _ => None,
8782 };
8783 if let Some(utype) = unsigned_type {
8784 self.write_keyword(utype);
8785 } else {
8786 self.generate_data_type(&col.data_type)?;
8787 }
8788 } else {
8789 self.generate_data_type(&col.data_type)?;
8790 }
8791 self.clickhouse_nullable_depth = saved_nullable_depth;
8792 }
8793
8794 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8797 self.write_space();
8798 self.write_keyword("UNSIGNED");
8799 }
8800 if col.zerofill {
8801 self.write_space();
8802 self.write_keyword("ZEROFILL");
8803 }
8804
8805 if let Some(ref charset) = col.character_set {
8809 self.write_space();
8810 self.write_keyword("CHARACTER SET");
8811 self.write_space();
8812 self.write(charset);
8813 }
8814
8815 if col.uppercase {
8816 self.write_space();
8817 self.write_keyword("UPPERCASE");
8818 }
8819
8820 if let Some(casespecific) = col.casespecific {
8821 self.write_space();
8822 if casespecific {
8823 self.write_keyword("CASESPECIFIC");
8824 } else {
8825 self.write_keyword("NOT CASESPECIFIC");
8826 }
8827 }
8828
8829 if let Some(ref format) = col.format {
8830 self.write_space();
8831 self.write_keyword("FORMAT");
8832 self.write(" '");
8833 self.write(format);
8834 self.write("'");
8835 }
8836
8837 if let Some(ref title) = col.title {
8838 self.write_space();
8839 self.write_keyword("TITLE");
8840 self.write(" '");
8841 self.write(title);
8842 self.write("'");
8843 }
8844
8845 if let Some(length) = col.inline_length {
8846 self.write_space();
8847 self.write_keyword("INLINE LENGTH");
8848 self.write(" ");
8849 self.write(&length.to_string());
8850 }
8851
8852 if let Some(ref compress) = col.compress {
8853 self.write_space();
8854 self.write_keyword("COMPRESS");
8855 if !compress.is_empty() {
8856 if compress.len() == 1 {
8858 if let Expression::Literal(lit) = &compress[0] {
8859 if let Literal::String(_) = lit.as_ref() {
8860 self.write_space();
8861 self.generate_expression(&compress[0])?;
8862 }
8863 } else {
8864 self.write(" (");
8865 self.generate_expression(&compress[0])?;
8866 self.write(")");
8867 }
8868 } else {
8869 self.write(" (");
8870 for (i, val) in compress.iter().enumerate() {
8871 if i > 0 {
8872 self.write(", ");
8873 }
8874 self.generate_expression(val)?;
8875 }
8876 self.write(")");
8877 }
8878 }
8879 }
8880
8881 if !col.constraint_order.is_empty() {
8884 let mut references_idx = 0;
8887 let mut check_idx = 0;
8888 let mut generated_idx = 0;
8889 let mut collate_idx = 0;
8890 let mut comment_idx = 0;
8891 let defer_not_null_after_identity = false;
8894 let mut pending_not_null_after_identity = false;
8895
8896 for constraint_type in &col.constraint_order {
8897 match constraint_type {
8898 ConstraintType::PrimaryKey => {
8899 if col.primary_key
8901 && !matches!(self.config.dialect, Some(DialectType::Materialize))
8902 {
8903 if let Some(ref cname) = col.primary_key_constraint_name {
8904 self.write_space();
8905 self.write_keyword("CONSTRAINT");
8906 self.write_space();
8907 self.write(cname);
8908 }
8909 self.write_space();
8910 self.write_keyword("PRIMARY KEY");
8911 if let Some(ref order) = col.primary_key_order {
8912 self.write_space();
8913 match order {
8914 SortOrder::Asc => self.write_keyword("ASC"),
8915 SortOrder::Desc => self.write_keyword("DESC"),
8916 }
8917 }
8918 }
8919 }
8920 ConstraintType::Unique => {
8921 if col.unique {
8922 if let Some(ref cname) = col.unique_constraint_name {
8923 self.write_space();
8924 self.write_keyword("CONSTRAINT");
8925 self.write_space();
8926 self.write(cname);
8927 }
8928 self.write_space();
8929 self.write_keyword("UNIQUE");
8930 if col.unique_nulls_not_distinct {
8932 self.write(" NULLS NOT DISTINCT");
8933 }
8934 }
8935 }
8936 ConstraintType::NotNull => {
8937 if col.nullable == Some(false) {
8938 if defer_not_null_after_identity {
8939 pending_not_null_after_identity = true;
8940 continue;
8941 }
8942 if let Some(ref cname) = col.not_null_constraint_name {
8943 self.write_space();
8944 self.write_keyword("CONSTRAINT");
8945 self.write_space();
8946 self.write(cname);
8947 }
8948 self.write_space();
8949 self.write_keyword("NOT NULL");
8950 }
8951 }
8952 ConstraintType::Null => {
8953 if col.nullable == Some(true) {
8954 self.write_space();
8955 self.write_keyword("NULL");
8956 }
8957 }
8958 ConstraintType::Default => {
8959 if let Some(ref default) = col.default {
8960 self.write_space();
8961 self.write_keyword("DEFAULT");
8962 self.write_space();
8963 self.generate_expression(default)?;
8964 }
8965 }
8966 ConstraintType::AutoIncrement => {
8967 if col.auto_increment {
8968 if matches!(
8970 self.config.dialect,
8971 Some(crate::dialects::DialectType::DuckDB)
8972 ) {
8973 } else if matches!(
8975 self.config.dialect,
8976 Some(crate::dialects::DialectType::Materialize)
8977 ) {
8978 if !matches!(col.nullable, Some(false)) {
8980 self.write_space();
8981 self.write_keyword("NOT NULL");
8982 }
8983 } else if matches!(
8984 self.config.dialect,
8985 Some(crate::dialects::DialectType::PostgreSQL)
8986 ) {
8987 self.write_space();
8989 self.generate_auto_increment_keyword(col)?;
8990 } else if matches!(
8991 self.config.dialect,
8992 Some(crate::dialects::DialectType::SQLite)
8993 ) && !col.primary_key
8994 && self
8995 .sqlite_inline_pk_columns
8996 .contains(&col.name.name.to_ascii_lowercase())
8997 {
8998 } else {
9001 self.write_space();
9002 self.generate_auto_increment_keyword(col)?;
9003 if pending_not_null_after_identity {
9004 self.write_space();
9005 self.write_keyword("NOT NULL");
9006 pending_not_null_after_identity = false;
9007 }
9008 }
9009 } }
9011 ConstraintType::References => {
9012 while references_idx < col.constraints.len() {
9014 if let ColumnConstraint::References(fk_ref) =
9015 &col.constraints[references_idx]
9016 {
9017 if let Some(ref name) = fk_ref.constraint_name {
9019 self.write_space();
9020 self.write_keyword("CONSTRAINT");
9021 self.write_space();
9022 self.write(name);
9023 }
9024 self.write_space();
9025 if fk_ref.has_foreign_key_keywords {
9026 self.write_keyword("FOREIGN KEY");
9027 self.write_space();
9028 }
9029 self.write_keyword("REFERENCES");
9030 self.write_space();
9031 self.generate_table(&fk_ref.table)?;
9032 if !fk_ref.columns.is_empty() {
9033 self.write(" (");
9034 for (i, c) in fk_ref.columns.iter().enumerate() {
9035 if i > 0 {
9036 self.write(", ");
9037 }
9038 self.generate_identifier(c)?;
9039 }
9040 self.write(")");
9041 }
9042 self.generate_referential_actions(fk_ref)?;
9043 references_idx += 1;
9044 break;
9045 }
9046 references_idx += 1;
9047 }
9048 }
9049 ConstraintType::Check => {
9050 while check_idx < col.constraints.len() {
9052 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
9053 if check_idx == 0 {
9055 if let Some(ref cname) = col.check_constraint_name {
9056 self.write_space();
9057 self.write_keyword("CONSTRAINT");
9058 self.write_space();
9059 self.write(cname);
9060 }
9061 }
9062 self.write_space();
9063 self.write_keyword("CHECK");
9064 self.write(" (");
9065 self.generate_expression(expr)?;
9066 self.write(")");
9067 check_idx += 1;
9068 break;
9069 }
9070 check_idx += 1;
9071 }
9072 }
9073 ConstraintType::GeneratedAsIdentity => {
9074 while generated_idx < col.constraints.len() {
9076 if let ColumnConstraint::GeneratedAsIdentity(gen) =
9077 &col.constraints[generated_idx]
9078 {
9079 self.write_space();
9080 if matches!(
9082 self.config.dialect,
9083 Some(crate::dialects::DialectType::Redshift)
9084 ) {
9085 self.write_keyword("IDENTITY");
9086 self.write("(");
9087 if let Some(ref start) = gen.start {
9088 self.generate_expression(start)?;
9089 } else {
9090 self.write("0");
9091 }
9092 self.write(", ");
9093 if let Some(ref incr) = gen.increment {
9094 self.generate_expression(incr)?;
9095 } else {
9096 self.write("1");
9097 }
9098 self.write(")");
9099 } else {
9100 self.write_keyword("GENERATED");
9101 if gen.always {
9102 self.write_space();
9103 self.write_keyword("ALWAYS");
9104 } else {
9105 self.write_space();
9106 self.write_keyword("BY DEFAULT");
9107 if gen.on_null {
9108 self.write_space();
9109 self.write_keyword("ON NULL");
9110 }
9111 }
9112 self.write_space();
9113 self.write_keyword("AS IDENTITY");
9114
9115 let has_options = gen.start.is_some()
9116 || gen.increment.is_some()
9117 || gen.minvalue.is_some()
9118 || gen.maxvalue.is_some()
9119 || gen.cycle.is_some();
9120 if has_options {
9121 self.write(" (");
9122 let mut first = true;
9123 if let Some(ref start) = gen.start {
9124 if !first {
9125 self.write(" ");
9126 }
9127 first = false;
9128 self.write_keyword("START WITH");
9129 self.write_space();
9130 self.generate_expression(start)?;
9131 }
9132 if let Some(ref incr) = gen.increment {
9133 if !first {
9134 self.write(" ");
9135 }
9136 first = false;
9137 self.write_keyword("INCREMENT BY");
9138 self.write_space();
9139 self.generate_expression(incr)?;
9140 }
9141 if let Some(ref minv) = gen.minvalue {
9142 if !first {
9143 self.write(" ");
9144 }
9145 first = false;
9146 self.write_keyword("MINVALUE");
9147 self.write_space();
9148 self.generate_expression(minv)?;
9149 }
9150 if let Some(ref maxv) = gen.maxvalue {
9151 if !first {
9152 self.write(" ");
9153 }
9154 first = false;
9155 self.write_keyword("MAXVALUE");
9156 self.write_space();
9157 self.generate_expression(maxv)?;
9158 }
9159 if let Some(cycle) = gen.cycle {
9160 if !first {
9161 self.write(" ");
9162 }
9163 if cycle {
9164 self.write_keyword("CYCLE");
9165 } else {
9166 self.write_keyword("NO CYCLE");
9167 }
9168 }
9169 self.write(")");
9170 }
9171 }
9172 generated_idx += 1;
9173 break;
9174 }
9175 generated_idx += 1;
9176 }
9177 }
9178 ConstraintType::Collate => {
9179 while collate_idx < col.constraints.len() {
9181 if let ColumnConstraint::Collate(collation) =
9182 &col.constraints[collate_idx]
9183 {
9184 self.write_space();
9185 self.write_keyword("COLLATE");
9186 self.write_space();
9187 self.generate_identifier(collation)?;
9188 collate_idx += 1;
9189 break;
9190 }
9191 collate_idx += 1;
9192 }
9193 }
9194 ConstraintType::Comment => {
9195 while comment_idx < col.constraints.len() {
9197 if let ColumnConstraint::Comment(comment) =
9198 &col.constraints[comment_idx]
9199 {
9200 self.write_space();
9201 self.write_keyword("COMMENT");
9202 self.write_space();
9203 self.generate_string_literal(comment)?;
9204 comment_idx += 1;
9205 break;
9206 }
9207 comment_idx += 1;
9208 }
9209 }
9210 ConstraintType::Tags => {
9211 for constraint in &col.constraints {
9213 if let ColumnConstraint::Tags(tags) = constraint {
9214 self.write_space();
9215 self.write_keyword("TAG");
9216 self.write(" (");
9217 for (i, expr) in tags.expressions.iter().enumerate() {
9218 if i > 0 {
9219 self.write(", ");
9220 }
9221 self.generate_expression(expr)?;
9222 }
9223 self.write(")");
9224 break;
9225 }
9226 }
9227 }
9228 ConstraintType::ComputedColumn => {
9229 for constraint in &col.constraints {
9231 if let ColumnConstraint::ComputedColumn(cc) = constraint {
9232 self.write_space();
9233 self.generate_computed_column_inline(cc)?;
9234 break;
9235 }
9236 }
9237 }
9238 ConstraintType::GeneratedAsRow => {
9239 for constraint in &col.constraints {
9241 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
9242 self.write_space();
9243 self.generate_generated_as_row_inline(gar)?;
9244 break;
9245 }
9246 }
9247 }
9248 ConstraintType::OnUpdate => {
9249 if let Some(ref expr) = col.on_update {
9250 self.write_space();
9251 self.write_keyword("ON UPDATE");
9252 self.write_space();
9253 self.generate_expression(expr)?;
9254 }
9255 }
9256 ConstraintType::Encode => {
9257 if let Some(ref encoding) = col.encoding {
9258 self.write_space();
9259 self.write_keyword("ENCODE");
9260 self.write_space();
9261 self.write(encoding);
9262 }
9263 }
9264 ConstraintType::Path => {
9265 for constraint in &col.constraints {
9267 if let ColumnConstraint::Path(path_expr) = constraint {
9268 self.write_space();
9269 self.write_keyword("PATH");
9270 self.write_space();
9271 self.generate_expression(path_expr)?;
9272 break;
9273 }
9274 }
9275 }
9276 }
9277 }
9278 if pending_not_null_after_identity {
9279 self.write_space();
9280 self.write_keyword("NOT NULL");
9281 }
9282 } else {
9283 if col.primary_key {
9285 self.write_space();
9286 self.write_keyword("PRIMARY KEY");
9287 if let Some(ref order) = col.primary_key_order {
9288 self.write_space();
9289 match order {
9290 SortOrder::Asc => self.write_keyword("ASC"),
9291 SortOrder::Desc => self.write_keyword("DESC"),
9292 }
9293 }
9294 }
9295
9296 if col.unique {
9297 self.write_space();
9298 self.write_keyword("UNIQUE");
9299 if col.unique_nulls_not_distinct {
9301 self.write(" NULLS NOT DISTINCT");
9302 }
9303 }
9304
9305 match col.nullable {
9306 Some(false) => {
9307 self.write_space();
9308 self.write_keyword("NOT NULL");
9309 }
9310 Some(true) => {
9311 self.write_space();
9312 self.write_keyword("NULL");
9313 }
9314 None => {}
9315 }
9316
9317 if let Some(ref default) = col.default {
9318 self.write_space();
9319 self.write_keyword("DEFAULT");
9320 self.write_space();
9321 self.generate_expression(default)?;
9322 }
9323
9324 if col.auto_increment {
9325 self.write_space();
9326 self.generate_auto_increment_keyword(col)?;
9327 }
9328
9329 for constraint in &col.constraints {
9331 match constraint {
9332 ColumnConstraint::References(fk_ref) => {
9333 self.write_space();
9334 if fk_ref.has_foreign_key_keywords {
9335 self.write_keyword("FOREIGN KEY");
9336 self.write_space();
9337 }
9338 self.write_keyword("REFERENCES");
9339 self.write_space();
9340 self.generate_table(&fk_ref.table)?;
9341 if !fk_ref.columns.is_empty() {
9342 self.write(" (");
9343 for (i, c) in fk_ref.columns.iter().enumerate() {
9344 if i > 0 {
9345 self.write(", ");
9346 }
9347 self.generate_identifier(c)?;
9348 }
9349 self.write(")");
9350 }
9351 self.generate_referential_actions(fk_ref)?;
9352 }
9353 ColumnConstraint::Check(expr) => {
9354 self.write_space();
9355 self.write_keyword("CHECK");
9356 self.write(" (");
9357 self.generate_expression(expr)?;
9358 self.write(")");
9359 }
9360 ColumnConstraint::GeneratedAsIdentity(gen) => {
9361 self.write_space();
9362 if matches!(
9364 self.config.dialect,
9365 Some(crate::dialects::DialectType::Redshift)
9366 ) {
9367 self.write_keyword("IDENTITY");
9368 self.write("(");
9369 if let Some(ref start) = gen.start {
9370 self.generate_expression(start)?;
9371 } else {
9372 self.write("0");
9373 }
9374 self.write(", ");
9375 if let Some(ref incr) = gen.increment {
9376 self.generate_expression(incr)?;
9377 } else {
9378 self.write("1");
9379 }
9380 self.write(")");
9381 } else {
9382 self.write_keyword("GENERATED");
9383 if gen.always {
9384 self.write_space();
9385 self.write_keyword("ALWAYS");
9386 } else {
9387 self.write_space();
9388 self.write_keyword("BY DEFAULT");
9389 if gen.on_null {
9390 self.write_space();
9391 self.write_keyword("ON NULL");
9392 }
9393 }
9394 self.write_space();
9395 self.write_keyword("AS IDENTITY");
9396
9397 let has_options = gen.start.is_some()
9398 || gen.increment.is_some()
9399 || gen.minvalue.is_some()
9400 || gen.maxvalue.is_some()
9401 || gen.cycle.is_some();
9402 if has_options {
9403 self.write(" (");
9404 let mut first = true;
9405 if let Some(ref start) = gen.start {
9406 if !first {
9407 self.write(" ");
9408 }
9409 first = false;
9410 self.write_keyword("START WITH");
9411 self.write_space();
9412 self.generate_expression(start)?;
9413 }
9414 if let Some(ref incr) = gen.increment {
9415 if !first {
9416 self.write(" ");
9417 }
9418 first = false;
9419 self.write_keyword("INCREMENT BY");
9420 self.write_space();
9421 self.generate_expression(incr)?;
9422 }
9423 if let Some(ref minv) = gen.minvalue {
9424 if !first {
9425 self.write(" ");
9426 }
9427 first = false;
9428 self.write_keyword("MINVALUE");
9429 self.write_space();
9430 self.generate_expression(minv)?;
9431 }
9432 if let Some(ref maxv) = gen.maxvalue {
9433 if !first {
9434 self.write(" ");
9435 }
9436 first = false;
9437 self.write_keyword("MAXVALUE");
9438 self.write_space();
9439 self.generate_expression(maxv)?;
9440 }
9441 if let Some(cycle) = gen.cycle {
9442 if !first {
9443 self.write(" ");
9444 }
9445 if cycle {
9446 self.write_keyword("CYCLE");
9447 } else {
9448 self.write_keyword("NO CYCLE");
9449 }
9450 }
9451 self.write(")");
9452 }
9453 }
9454 }
9455 ColumnConstraint::Collate(collation) => {
9456 self.write_space();
9457 self.write_keyword("COLLATE");
9458 self.write_space();
9459 self.generate_identifier(collation)?;
9460 }
9461 ColumnConstraint::Comment(comment) => {
9462 self.write_space();
9463 self.write_keyword("COMMENT");
9464 self.write_space();
9465 self.generate_string_literal(comment)?;
9466 }
9467 ColumnConstraint::Path(path_expr) => {
9468 self.write_space();
9469 self.write_keyword("PATH");
9470 self.write_space();
9471 self.generate_expression(path_expr)?;
9472 }
9473 _ => {} }
9475 }
9476
9477 if let Some(ref encoding) = col.encoding {
9479 self.write_space();
9480 self.write_keyword("ENCODE");
9481 self.write_space();
9482 self.write(encoding);
9483 }
9484 }
9485
9486 if let Some(ref codec) = col.codec {
9488 self.write_space();
9489 self.write_keyword("CODEC");
9490 self.write("(");
9491 self.write(codec);
9492 self.write(")");
9493 }
9494
9495 if let Some(visible) = col.visible {
9496 self.write_space();
9497 if visible {
9498 self.write_keyword("VISIBLE");
9499 } else {
9500 self.write_keyword("INVISIBLE");
9501 }
9502 }
9503
9504 if let Some(ref ephemeral) = col.ephemeral {
9506 self.write_space();
9507 self.write_keyword("EPHEMERAL");
9508 if let Some(ref expr) = ephemeral {
9509 self.write_space();
9510 self.generate_expression(expr)?;
9511 }
9512 }
9513
9514 if let Some(ref mat_expr) = col.materialized_expr {
9516 self.write_space();
9517 self.write_keyword("MATERIALIZED");
9518 self.write_space();
9519 self.generate_expression(mat_expr)?;
9520 }
9521
9522 if let Some(ref alias_expr) = col.alias_expr {
9524 self.write_space();
9525 self.write_keyword("ALIAS");
9526 self.write_space();
9527 self.generate_expression(alias_expr)?;
9528 }
9529
9530 if let Some(ref ttl_expr) = col.ttl_expr {
9532 self.write_space();
9533 self.write_keyword("TTL");
9534 self.write_space();
9535 self.generate_expression(ttl_expr)?;
9536 }
9537
9538 if col.not_for_replication
9540 && matches!(
9541 self.config.dialect,
9542 Some(crate::dialects::DialectType::TSQL)
9543 | Some(crate::dialects::DialectType::Fabric)
9544 )
9545 {
9546 self.write_space();
9547 self.write_keyword("NOT FOR REPLICATION");
9548 }
9549
9550 if !col.options.is_empty() {
9552 self.write_space();
9553 self.generate_options_clause(&col.options)?;
9554 }
9555
9556 if !col.primary_key
9559 && self
9560 .sqlite_inline_pk_columns
9561 .contains(&col.name.name.to_ascii_lowercase())
9562 {
9563 self.write_space();
9564 self.write_keyword("PRIMARY KEY");
9565 if matches!(self.config.dialect, Some(DialectType::SQLite)) && col.auto_increment {
9566 self.write_space();
9567 self.generate_auto_increment_keyword(col)?;
9568 }
9569 }
9570
9571 if serial_expansion.is_some() {
9574 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
9575 self.write_space();
9576 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
9577 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
9578 self.write_space();
9579 self.write_keyword("NOT NULL");
9580 }
9581 }
9582
9583 Ok(())
9584 }
9585
9586 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
9587 match constraint {
9588 TableConstraint::PrimaryKey {
9589 name,
9590 columns,
9591 include_columns,
9592 modifiers,
9593 has_constraint_keyword,
9594 } => {
9595 if let Some(ref n) = name {
9596 if *has_constraint_keyword {
9597 self.write_keyword("CONSTRAINT");
9598 self.write_space();
9599 self.generate_identifier(n)?;
9600 self.write_space();
9601 }
9602 }
9603 self.write_keyword("PRIMARY KEY");
9604 if let Some(ref clustered) = modifiers.clustered {
9606 self.write_space();
9607 self.write_keyword(clustered);
9608 }
9609 if let Some(ref n) = name {
9611 if !*has_constraint_keyword {
9612 self.write_space();
9613 self.generate_identifier(n)?;
9614 }
9615 }
9616 self.write(" (");
9617 for (i, col) in columns.iter().enumerate() {
9618 if i > 0 {
9619 self.write(", ");
9620 }
9621 self.generate_identifier(col)?;
9622 }
9623 self.write(")");
9624 if !include_columns.is_empty() {
9625 self.write_space();
9626 self.write_keyword("INCLUDE");
9627 self.write(" (");
9628 for (i, col) in include_columns.iter().enumerate() {
9629 if i > 0 {
9630 self.write(", ");
9631 }
9632 self.generate_identifier(col)?;
9633 }
9634 self.write(")");
9635 }
9636 self.generate_constraint_modifiers(modifiers);
9637 }
9638 TableConstraint::Unique {
9639 name,
9640 columns,
9641 columns_parenthesized,
9642 modifiers,
9643 has_constraint_keyword,
9644 nulls_not_distinct,
9645 } => {
9646 if let Some(ref n) = name {
9647 if *has_constraint_keyword {
9648 self.write_keyword("CONSTRAINT");
9649 self.write_space();
9650 self.generate_identifier(n)?;
9651 self.write_space();
9652 }
9653 }
9654 self.write_keyword("UNIQUE");
9655 if let Some(ref clustered) = modifiers.clustered {
9657 self.write_space();
9658 self.write_keyword(clustered);
9659 }
9660 if *nulls_not_distinct {
9662 self.write(" NULLS NOT DISTINCT");
9663 }
9664 if let Some(ref n) = name {
9666 if !*has_constraint_keyword {
9667 self.write_space();
9668 self.generate_identifier(n)?;
9669 }
9670 }
9671 if *columns_parenthesized {
9672 self.write(" (");
9673 for (i, col) in columns.iter().enumerate() {
9674 if i > 0 {
9675 self.write(", ");
9676 }
9677 self.generate_identifier(col)?;
9678 }
9679 self.write(")");
9680 } else {
9681 for col in columns.iter() {
9683 self.write_space();
9684 self.generate_identifier(col)?;
9685 }
9686 }
9687 self.generate_constraint_modifiers(modifiers);
9688 }
9689 TableConstraint::ForeignKey {
9690 name,
9691 columns,
9692 references,
9693 on_delete,
9694 on_update,
9695 modifiers,
9696 } => {
9697 if let Some(ref n) = name {
9698 self.write_keyword("CONSTRAINT");
9699 self.write_space();
9700 self.generate_identifier(n)?;
9701 self.write_space();
9702 }
9703 self.write_keyword("FOREIGN KEY");
9704 self.write(" (");
9705 for (i, col) in columns.iter().enumerate() {
9706 if i > 0 {
9707 self.write(", ");
9708 }
9709 self.generate_identifier(col)?;
9710 }
9711 self.write(")");
9712 if let Some(ref refs) = references {
9713 self.write(" ");
9714 self.write_keyword("REFERENCES");
9715 self.write_space();
9716 self.generate_table(&refs.table)?;
9717 if !refs.columns.is_empty() {
9718 if self.config.pretty {
9719 self.write(" (");
9720 self.write_newline();
9721 self.indent_level += 1;
9722 for (i, col) in refs.columns.iter().enumerate() {
9723 if i > 0 {
9724 self.write(",");
9725 self.write_newline();
9726 }
9727 self.write_indent();
9728 self.generate_identifier(col)?;
9729 }
9730 self.indent_level -= 1;
9731 self.write_newline();
9732 self.write_indent();
9733 self.write(")");
9734 } else {
9735 self.write(" (");
9736 for (i, col) in refs.columns.iter().enumerate() {
9737 if i > 0 {
9738 self.write(", ");
9739 }
9740 self.generate_identifier(col)?;
9741 }
9742 self.write(")");
9743 }
9744 }
9745 self.generate_referential_actions(refs)?;
9746 } else {
9747 if let Some(ref action) = on_delete {
9749 self.write_space();
9750 self.write_keyword("ON DELETE");
9751 self.write_space();
9752 self.generate_referential_action(action);
9753 }
9754 if let Some(ref action) = on_update {
9755 self.write_space();
9756 self.write_keyword("ON UPDATE");
9757 self.write_space();
9758 self.generate_referential_action(action);
9759 }
9760 }
9761 self.generate_constraint_modifiers(modifiers);
9762 }
9763 TableConstraint::Check {
9764 name,
9765 expression,
9766 modifiers,
9767 } => {
9768 if let Some(ref n) = name {
9769 self.write_keyword("CONSTRAINT");
9770 self.write_space();
9771 self.generate_identifier(n)?;
9772 self.write_space();
9773 }
9774 self.write_keyword("CHECK");
9775 self.write(" (");
9776 self.generate_expression(expression)?;
9777 self.write(")");
9778 self.generate_constraint_modifiers(modifiers);
9779 }
9780 TableConstraint::Assume { name, expression } => {
9781 if let Some(ref n) = name {
9782 self.write_keyword("CONSTRAINT");
9783 self.write_space();
9784 self.generate_identifier(n)?;
9785 self.write_space();
9786 }
9787 self.write_keyword("ASSUME");
9788 self.write(" (");
9789 self.generate_expression(expression)?;
9790 self.write(")");
9791 }
9792 TableConstraint::Default {
9793 name,
9794 expression,
9795 column,
9796 } => {
9797 if let Some(ref n) = name {
9798 self.write_keyword("CONSTRAINT");
9799 self.write_space();
9800 self.generate_identifier(n)?;
9801 self.write_space();
9802 }
9803 self.write_keyword("DEFAULT");
9804 self.write_space();
9805 self.generate_expression(expression)?;
9806 self.write_space();
9807 self.write_keyword("FOR");
9808 self.write_space();
9809 self.generate_identifier(column)?;
9810 }
9811 TableConstraint::Index {
9812 name,
9813 columns,
9814 kind,
9815 modifiers,
9816 use_key_keyword,
9817 expression,
9818 index_type,
9819 granularity,
9820 } => {
9821 if expression.is_some() {
9823 self.write_keyword("INDEX");
9824 if let Some(ref n) = name {
9825 self.write_space();
9826 self.generate_identifier(n)?;
9827 }
9828 if let Some(ref expr) = expression {
9829 self.write_space();
9830 self.generate_expression(expr)?;
9831 }
9832 if let Some(ref idx_type) = index_type {
9833 self.write_space();
9834 self.write_keyword("TYPE");
9835 self.write_space();
9836 self.generate_expression(idx_type)?;
9837 }
9838 if let Some(ref gran) = granularity {
9839 self.write_space();
9840 self.write_keyword("GRANULARITY");
9841 self.write_space();
9842 self.generate_expression(gran)?;
9843 }
9844 } else {
9845 use crate::dialects::DialectType;
9849 let index_keyword = if *use_key_keyword
9850 && !matches!(self.config.dialect, Some(DialectType::MySQL))
9851 {
9852 "KEY"
9853 } else {
9854 "INDEX"
9855 };
9856
9857 if let Some(ref k) = kind {
9859 self.write_keyword(k);
9860 if k != "UNIQUE" {
9862 self.write_space();
9863 self.write_keyword(index_keyword);
9864 }
9865 } else {
9866 self.write_keyword(index_keyword);
9867 }
9868
9869 if modifiers.using_before_columns && name.is_none() {
9871 if let Some(ref using) = modifiers.using {
9872 self.write_space();
9873 self.write_keyword("USING");
9874 self.write_space();
9875 self.write_keyword(using);
9876 }
9877 }
9878
9879 if let Some(ref n) = name {
9881 self.write_space();
9882 self.generate_identifier(n)?;
9883 }
9884
9885 if modifiers.using_before_columns && name.is_some() {
9887 if let Some(ref using) = modifiers.using {
9888 self.write_space();
9889 self.write_keyword("USING");
9890 self.write_space();
9891 self.write_keyword(using);
9892 }
9893 }
9894
9895 self.write(" (");
9897 for (i, col) in columns.iter().enumerate() {
9898 if i > 0 {
9899 self.write(", ");
9900 }
9901 self.generate_identifier(col)?;
9902 }
9903 self.write(")");
9904
9905 if !modifiers.using_before_columns {
9907 if let Some(ref using) = modifiers.using {
9908 self.write_space();
9909 self.write_keyword("USING");
9910 self.write_space();
9911 self.write_keyword(using);
9912 }
9913 }
9914
9915 self.generate_constraint_modifiers_without_using(modifiers);
9917 }
9918 }
9919 TableConstraint::Projection { name, expression } => {
9920 self.write_keyword("PROJECTION");
9922 self.write_space();
9923 self.generate_identifier(name)?;
9924 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
9925 if let Expression::Raw(raw) = expression {
9926 if raw
9927 .sql
9928 .trim_start()
9929 .to_ascii_uppercase()
9930 .starts_with("INDEX ")
9931 {
9932 self.write_space();
9933 self.write(raw.sql.trim());
9934 return Ok(());
9935 }
9936 }
9937 }
9938 self.write(" (");
9939 self.generate_expression(expression)?;
9940 self.write(")");
9941 }
9942 TableConstraint::Like { source, options } => {
9943 self.write_keyword("LIKE");
9944 self.write_space();
9945 self.generate_table(source)?;
9946 for (action, prop) in options {
9947 self.write_space();
9948 match action {
9949 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
9950 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
9951 }
9952 self.write_space();
9953 self.write_keyword(prop);
9954 }
9955 }
9956 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
9957 self.write_keyword("PERIOD FOR SYSTEM_TIME");
9958 self.write(" (");
9959 self.generate_identifier(start_col)?;
9960 self.write(", ");
9961 self.generate_identifier(end_col)?;
9962 self.write(")");
9963 }
9964 TableConstraint::Exclude {
9965 name,
9966 using,
9967 elements,
9968 include_columns,
9969 where_clause,
9970 with_params,
9971 using_index_tablespace,
9972 modifiers: _,
9973 } => {
9974 if let Some(ref n) = name {
9975 self.write_keyword("CONSTRAINT");
9976 self.write_space();
9977 self.generate_identifier(n)?;
9978 self.write_space();
9979 }
9980 self.write_keyword("EXCLUDE");
9981 if let Some(ref method) = using {
9982 self.write_space();
9983 self.write_keyword("USING");
9984 self.write_space();
9985 self.write(method);
9986 self.write("(");
9987 } else {
9988 self.write(" (");
9989 }
9990 for (i, elem) in elements.iter().enumerate() {
9991 if i > 0 {
9992 self.write(", ");
9993 }
9994 self.write(&elem.expression);
9995 self.write_space();
9996 self.write_keyword("WITH");
9997 self.write_space();
9998 self.write(&elem.operator);
9999 }
10000 self.write(")");
10001 if !include_columns.is_empty() {
10002 self.write_space();
10003 self.write_keyword("INCLUDE");
10004 self.write(" (");
10005 for (i, col) in include_columns.iter().enumerate() {
10006 if i > 0 {
10007 self.write(", ");
10008 }
10009 self.generate_identifier(col)?;
10010 }
10011 self.write(")");
10012 }
10013 if !with_params.is_empty() {
10014 self.write_space();
10015 self.write_keyword("WITH");
10016 self.write(" (");
10017 for (i, (key, val)) in with_params.iter().enumerate() {
10018 if i > 0 {
10019 self.write(", ");
10020 }
10021 self.write(key);
10022 self.write("=");
10023 self.write(val);
10024 }
10025 self.write(")");
10026 }
10027 if let Some(ref tablespace) = using_index_tablespace {
10028 self.write_space();
10029 self.write_keyword("USING INDEX TABLESPACE");
10030 self.write_space();
10031 self.write(tablespace);
10032 }
10033 if let Some(ref where_expr) = where_clause {
10034 self.write_space();
10035 self.write_keyword("WHERE");
10036 self.write(" (");
10037 self.generate_expression(where_expr)?;
10038 self.write(")");
10039 }
10040 }
10041 TableConstraint::Tags(tags) => {
10042 self.write_keyword("TAG");
10043 self.write(" (");
10044 for (i, expr) in tags.expressions.iter().enumerate() {
10045 if i > 0 {
10046 self.write(", ");
10047 }
10048 self.generate_expression(expr)?;
10049 }
10050 self.write(")");
10051 }
10052 TableConstraint::InitiallyDeferred { deferred } => {
10053 self.write_keyword("INITIALLY");
10054 self.write_space();
10055 if *deferred {
10056 self.write_keyword("DEFERRED");
10057 } else {
10058 self.write_keyword("IMMEDIATE");
10059 }
10060 }
10061 }
10062 Ok(())
10063 }
10064
10065 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
10066 if let Some(using) = &modifiers.using {
10068 self.write_space();
10069 self.write_keyword("USING");
10070 self.write_space();
10071 self.write_keyword(using);
10072 }
10073 if let Some(enforced) = modifiers.enforced {
10075 self.write_space();
10076 if enforced {
10077 self.write_keyword("ENFORCED");
10078 } else {
10079 self.write_keyword("NOT ENFORCED");
10080 }
10081 }
10082 if let Some(deferrable) = modifiers.deferrable {
10084 self.write_space();
10085 if deferrable {
10086 self.write_keyword("DEFERRABLE");
10087 } else {
10088 self.write_keyword("NOT DEFERRABLE");
10089 }
10090 }
10091 if let Some(initially_deferred) = modifiers.initially_deferred {
10093 self.write_space();
10094 if initially_deferred {
10095 self.write_keyword("INITIALLY DEFERRED");
10096 } else {
10097 self.write_keyword("INITIALLY IMMEDIATE");
10098 }
10099 }
10100 if modifiers.norely {
10102 self.write_space();
10103 self.write_keyword("NORELY");
10104 }
10105 if modifiers.rely {
10107 self.write_space();
10108 self.write_keyword("RELY");
10109 }
10110 if modifiers.not_valid {
10112 self.write_space();
10113 self.write_keyword("NOT VALID");
10114 }
10115 if let Some(on_conflict) = &modifiers.on_conflict {
10117 self.write_space();
10118 self.write_keyword("ON CONFLICT");
10119 self.write_space();
10120 self.write_keyword(on_conflict);
10121 }
10122 if !modifiers.with_options.is_empty() {
10124 self.write_space();
10125 self.write_keyword("WITH");
10126 self.write(" (");
10127 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
10128 if i > 0 {
10129 self.write(", ");
10130 }
10131 self.write(key);
10132 self.write("=");
10133 self.write(value);
10134 }
10135 self.write(")");
10136 }
10137 if let Some(ref fg) = modifiers.on_filegroup {
10139 self.write_space();
10140 self.write_keyword("ON");
10141 self.write_space();
10142 let _ = self.generate_identifier(fg);
10143 }
10144 }
10145
10146 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
10148 if let Some(enforced) = modifiers.enforced {
10150 self.write_space();
10151 if enforced {
10152 self.write_keyword("ENFORCED");
10153 } else {
10154 self.write_keyword("NOT ENFORCED");
10155 }
10156 }
10157 if let Some(deferrable) = modifiers.deferrable {
10159 self.write_space();
10160 if deferrable {
10161 self.write_keyword("DEFERRABLE");
10162 } else {
10163 self.write_keyword("NOT DEFERRABLE");
10164 }
10165 }
10166 if let Some(initially_deferred) = modifiers.initially_deferred {
10168 self.write_space();
10169 if initially_deferred {
10170 self.write_keyword("INITIALLY DEFERRED");
10171 } else {
10172 self.write_keyword("INITIALLY IMMEDIATE");
10173 }
10174 }
10175 if modifiers.norely {
10177 self.write_space();
10178 self.write_keyword("NORELY");
10179 }
10180 if modifiers.rely {
10182 self.write_space();
10183 self.write_keyword("RELY");
10184 }
10185 if modifiers.not_valid {
10187 self.write_space();
10188 self.write_keyword("NOT VALID");
10189 }
10190 if let Some(on_conflict) = &modifiers.on_conflict {
10192 self.write_space();
10193 self.write_keyword("ON CONFLICT");
10194 self.write_space();
10195 self.write_keyword(on_conflict);
10196 }
10197 self.generate_index_specific_modifiers(modifiers);
10199 }
10200
10201 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
10203 if let Some(ref comment) = modifiers.comment {
10204 self.write_space();
10205 self.write_keyword("COMMENT");
10206 self.write(" '");
10207 self.write(comment);
10208 self.write("'");
10209 }
10210 if let Some(visible) = modifiers.visible {
10211 self.write_space();
10212 if visible {
10213 self.write_keyword("VISIBLE");
10214 } else {
10215 self.write_keyword("INVISIBLE");
10216 }
10217 }
10218 if let Some(ref attr) = modifiers.engine_attribute {
10219 self.write_space();
10220 self.write_keyword("ENGINE_ATTRIBUTE");
10221 self.write(" = '");
10222 self.write(attr);
10223 self.write("'");
10224 }
10225 if let Some(ref parser) = modifiers.with_parser {
10226 self.write_space();
10227 self.write_keyword("WITH PARSER");
10228 self.write_space();
10229 self.write(parser);
10230 }
10231 }
10232
10233 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
10234 if !fk_ref.match_after_actions {
10236 if let Some(ref match_type) = fk_ref.match_type {
10237 self.write_space();
10238 self.write_keyword("MATCH");
10239 self.write_space();
10240 match match_type {
10241 MatchType::Full => self.write_keyword("FULL"),
10242 MatchType::Partial => self.write_keyword("PARTIAL"),
10243 MatchType::Simple => self.write_keyword("SIMPLE"),
10244 }
10245 }
10246 }
10247
10248 if fk_ref.on_update_first {
10250 if let Some(ref action) = fk_ref.on_update {
10251 self.write_space();
10252 self.write_keyword("ON UPDATE");
10253 self.write_space();
10254 self.generate_referential_action(action);
10255 }
10256 if let Some(ref action) = fk_ref.on_delete {
10257 self.write_space();
10258 self.write_keyword("ON DELETE");
10259 self.write_space();
10260 self.generate_referential_action(action);
10261 }
10262 } else {
10263 if let Some(ref action) = fk_ref.on_delete {
10264 self.write_space();
10265 self.write_keyword("ON DELETE");
10266 self.write_space();
10267 self.generate_referential_action(action);
10268 }
10269 if let Some(ref action) = fk_ref.on_update {
10270 self.write_space();
10271 self.write_keyword("ON UPDATE");
10272 self.write_space();
10273 self.generate_referential_action(action);
10274 }
10275 }
10276
10277 if fk_ref.match_after_actions {
10279 if let Some(ref match_type) = fk_ref.match_type {
10280 self.write_space();
10281 self.write_keyword("MATCH");
10282 self.write_space();
10283 match match_type {
10284 MatchType::Full => self.write_keyword("FULL"),
10285 MatchType::Partial => self.write_keyword("PARTIAL"),
10286 MatchType::Simple => self.write_keyword("SIMPLE"),
10287 }
10288 }
10289 }
10290
10291 if let Some(deferrable) = fk_ref.deferrable {
10293 self.write_space();
10294 if deferrable {
10295 self.write_keyword("DEFERRABLE");
10296 } else {
10297 self.write_keyword("NOT DEFERRABLE");
10298 }
10299 }
10300
10301 Ok(())
10302 }
10303
10304 fn generate_referential_action(&mut self, action: &ReferentialAction) {
10305 match action {
10306 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
10307 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
10308 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
10309 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
10310 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
10311 }
10312 }
10313
10314 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
10315 if let Some(ref object_id_args) = dt.object_id_args {
10317 if matches!(
10318 self.config.dialect,
10319 Some(crate::dialects::DialectType::TSQL)
10320 | Some(crate::dialects::DialectType::Fabric)
10321 ) {
10322 self.write_keyword("IF NOT OBJECT_ID");
10323 self.write("(");
10324 self.write(object_id_args);
10325 self.write(")");
10326 self.write_space();
10327 self.write_keyword("IS NULL BEGIN DROP TABLE");
10328 self.write_space();
10329 for (i, table) in dt.names.iter().enumerate() {
10330 if i > 0 {
10331 self.write(", ");
10332 }
10333 self.generate_table(table)?;
10334 }
10335 self.write("; ");
10336 self.write_keyword("END");
10337 return Ok(());
10338 }
10339 }
10340
10341 let saved_athena_hive_context = self.athena_hive_context;
10343 if matches!(
10344 self.config.dialect,
10345 Some(crate::dialects::DialectType::Athena)
10346 ) {
10347 self.athena_hive_context = true;
10348 }
10349
10350 for comment in &dt.leading_comments {
10352 self.write_formatted_comment(comment);
10353 self.write_space();
10354 }
10355 if dt.iceberg {
10356 self.write_keyword("DROP ICEBERG TABLE");
10357 } else {
10358 self.write_keyword("DROP TABLE");
10359 }
10360
10361 if dt.if_exists {
10362 self.write_space();
10363 self.write_keyword("IF EXISTS");
10364 }
10365
10366 self.write_space();
10367 for (i, table) in dt.names.iter().enumerate() {
10368 if i > 0 {
10369 self.write(", ");
10370 }
10371 self.generate_table(table)?;
10372 }
10373
10374 if dt.cascade_constraints {
10375 self.write_space();
10376 self.write_keyword("CASCADE CONSTRAINTS");
10377 } else if dt.cascade {
10378 self.write_space();
10379 self.write_keyword("CASCADE");
10380 }
10381
10382 if dt.restrict {
10383 self.write_space();
10384 self.write_keyword("RESTRICT");
10385 }
10386
10387 if dt.purge {
10388 self.write_space();
10389 self.write_keyword("PURGE");
10390 }
10391
10392 if dt.sync {
10393 self.write_space();
10394 self.write_keyword("SYNC");
10395 }
10396
10397 self.athena_hive_context = saved_athena_hive_context;
10399
10400 Ok(())
10401 }
10402
10403 fn generate_undrop(&mut self, u: &Undrop) -> Result<()> {
10404 self.write_keyword("UNDROP");
10405 self.write_space();
10406 self.write_keyword(&u.kind);
10407 if u.if_exists {
10408 self.write_space();
10409 self.write_keyword("IF EXISTS");
10410 }
10411 self.write_space();
10412 self.generate_table(&u.name)?;
10413 if let Some(rename_to) = &u.rename_to {
10414 self.write_space();
10415 self.write_keyword("RENAME TO");
10416 self.write_space();
10417 self.generate_table(rename_to)?;
10418 }
10419 Ok(())
10420 }
10421
10422 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
10423 let saved_athena_hive_context = self.athena_hive_context;
10425 if matches!(
10426 self.config.dialect,
10427 Some(crate::dialects::DialectType::Athena)
10428 ) {
10429 self.athena_hive_context = true;
10430 }
10431
10432 self.write_keyword("ALTER");
10433 if let Some(ref modifier) = at.table_modifier {
10435 if !matches!(
10436 self.config.dialect,
10437 Some(crate::dialects::DialectType::DuckDB)
10438 ) {
10439 self.write_space();
10440 self.write_keyword(modifier);
10441 }
10442 }
10443 self.write(" ");
10444 self.write_keyword("TABLE");
10445 if at.if_exists {
10446 self.write_space();
10447 self.write_keyword("IF EXISTS");
10448 }
10449 self.write_space();
10450 self.generate_table(&at.name)?;
10451
10452 if let Some(ref on_cluster) = at.on_cluster {
10454 self.write_space();
10455 self.generate_on_cluster(on_cluster)?;
10456 }
10457
10458 if let Some(ref partition) = at.partition {
10460 self.write_space();
10461 self.write_keyword("PARTITION");
10462 self.write("(");
10463 for (i, (key, value)) in partition.iter().enumerate() {
10464 if i > 0 {
10465 self.write(", ");
10466 }
10467 self.generate_identifier(key)?;
10468 self.write(" = ");
10469 self.generate_expression(value)?;
10470 }
10471 self.write(")");
10472 }
10473
10474 if let Some(ref with_check) = at.with_check {
10476 self.write_space();
10477 self.write_keyword(with_check);
10478 }
10479
10480 if self.config.pretty {
10481 self.write_newline();
10483 self.indent_level += 1;
10484 for (i, action) in at.actions.iter().enumerate() {
10485 let is_continuation = i > 0
10487 && matches!(
10488 (&at.actions[i - 1], action),
10489 (
10490 AlterTableAction::AddColumn { .. },
10491 AlterTableAction::AddColumn { .. }
10492 ) | (
10493 AlterTableAction::AddConstraint(_),
10494 AlterTableAction::AddConstraint(_)
10495 )
10496 );
10497 if i > 0 {
10498 self.write(",");
10499 self.write_newline();
10500 }
10501 self.write_indent();
10502 self.generate_alter_action_with_continuation(action, is_continuation)?;
10503 }
10504 self.indent_level -= 1;
10505 } else {
10506 for (i, action) in at.actions.iter().enumerate() {
10507 let is_continuation = i > 0
10509 && matches!(
10510 (&at.actions[i - 1], action),
10511 (
10512 AlterTableAction::AddColumn { .. },
10513 AlterTableAction::AddColumn { .. }
10514 ) | (
10515 AlterTableAction::AddConstraint(_),
10516 AlterTableAction::AddConstraint(_)
10517 )
10518 );
10519 if i > 0 {
10520 self.write(",");
10521 }
10522 self.write_space();
10523 self.generate_alter_action_with_continuation(action, is_continuation)?;
10524 }
10525 }
10526
10527 if let Some(ref algorithm) = at.algorithm {
10529 self.write(", ");
10530 self.write_keyword("ALGORITHM");
10531 self.write("=");
10532 self.write_keyword(algorithm);
10533 }
10534 if let Some(ref lock) = at.lock {
10535 self.write(", ");
10536 self.write_keyword("LOCK");
10537 self.write("=");
10538 self.write_keyword(lock);
10539 }
10540
10541 self.athena_hive_context = saved_athena_hive_context;
10543
10544 Ok(())
10545 }
10546
10547 fn generate_alter_action_with_continuation(
10548 &mut self,
10549 action: &AlterTableAction,
10550 is_continuation: bool,
10551 ) -> Result<()> {
10552 match action {
10553 AlterTableAction::AddColumn {
10554 column,
10555 if_not_exists,
10556 position,
10557 } => {
10558 use crate::dialects::DialectType;
10559 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
10563 let is_tsql_like = matches!(
10564 self.config.dialect,
10565 Some(DialectType::TSQL) | Some(DialectType::Fabric)
10566 );
10567 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
10569
10570 if is_continuation && (is_snowflake || is_tsql_like) {
10571 } else if is_snowflake {
10573 self.write_keyword("ADD");
10574 self.write_space();
10575 } else if is_athena {
10576 self.write_keyword("ADD COLUMNS");
10578 self.write(" (");
10579 } else if self.config.alter_table_include_column_keyword {
10580 self.write_keyword("ADD COLUMN");
10581 self.write_space();
10582 } else {
10583 self.write_keyword("ADD");
10585 self.write_space();
10586 }
10587
10588 if *if_not_exists {
10589 self.write_keyword("IF NOT EXISTS");
10590 self.write_space();
10591 }
10592 self.generate_column_def(column)?;
10593
10594 if is_athena {
10596 self.write(")");
10597 }
10598
10599 if let Some(pos) = position {
10601 self.write_space();
10602 match pos {
10603 ColumnPosition::First => self.write_keyword("FIRST"),
10604 ColumnPosition::After(col_name) => {
10605 self.write_keyword("AFTER");
10606 self.write_space();
10607 self.generate_identifier(col_name)?;
10608 }
10609 }
10610 }
10611 }
10612 AlterTableAction::DropColumn {
10613 name,
10614 if_exists,
10615 cascade,
10616 } => {
10617 self.write_keyword("DROP COLUMN");
10618 if *if_exists {
10619 self.write_space();
10620 self.write_keyword("IF EXISTS");
10621 }
10622 self.write_space();
10623 self.generate_identifier(name)?;
10624 if *cascade {
10625 self.write_space();
10626 self.write_keyword("CASCADE");
10627 }
10628 }
10629 AlterTableAction::DropColumns { names } => {
10630 self.write_keyword("DROP COLUMNS");
10631 self.write(" (");
10632 for (i, name) in names.iter().enumerate() {
10633 if i > 0 {
10634 self.write(", ");
10635 }
10636 self.generate_identifier(name)?;
10637 }
10638 self.write(")");
10639 }
10640 AlterTableAction::RenameColumn {
10641 old_name,
10642 new_name,
10643 if_exists,
10644 } => {
10645 self.write_keyword("RENAME COLUMN");
10646 if *if_exists {
10647 self.write_space();
10648 self.write_keyword("IF EXISTS");
10649 }
10650 self.write_space();
10651 self.generate_identifier(old_name)?;
10652 self.write_space();
10653 self.write_keyword("TO");
10654 self.write_space();
10655 self.generate_identifier(new_name)?;
10656 }
10657 AlterTableAction::AlterColumn {
10658 name,
10659 action,
10660 use_modify_keyword,
10661 } => {
10662 use crate::dialects::DialectType;
10663 let use_modify = *use_modify_keyword
10666 || (matches!(self.config.dialect, Some(DialectType::MySQL))
10667 && matches!(action, AlterColumnAction::SetDataType { .. }));
10668 if use_modify {
10669 self.write_keyword("MODIFY COLUMN");
10670 self.write_space();
10671 self.generate_identifier(name)?;
10672 if let AlterColumnAction::SetDataType {
10674 data_type,
10675 using: _,
10676 collate,
10677 } = action
10678 {
10679 self.write_space();
10680 self.generate_data_type(data_type)?;
10681 if let Some(collate_name) = collate {
10683 self.write_space();
10684 self.write_keyword("COLLATE");
10685 self.write_space();
10686 self.write(&format!("'{}'", collate_name));
10688 }
10689 } else {
10690 self.write_space();
10691 self.generate_alter_column_action(action)?;
10692 }
10693 } else if matches!(self.config.dialect, Some(DialectType::Hive))
10694 && matches!(action, AlterColumnAction::SetDataType { .. })
10695 {
10696 self.write_keyword("CHANGE COLUMN");
10698 self.write_space();
10699 self.generate_identifier(name)?;
10700 self.write_space();
10701 self.generate_identifier(name)?;
10702 if let AlterColumnAction::SetDataType { data_type, .. } = action {
10703 self.write_space();
10704 self.generate_data_type(data_type)?;
10705 }
10706 } else {
10707 self.write_keyword("ALTER COLUMN");
10708 self.write_space();
10709 self.generate_identifier(name)?;
10710 self.write_space();
10711 self.generate_alter_column_action(action)?;
10712 }
10713 }
10714 AlterTableAction::RenameTable(new_name) => {
10715 let mysql_like = matches!(
10717 self.config.dialect,
10718 Some(DialectType::MySQL)
10719 | Some(DialectType::Doris)
10720 | Some(DialectType::StarRocks)
10721 | Some(DialectType::SingleStore)
10722 );
10723 if mysql_like {
10724 self.write_keyword("RENAME");
10725 } else {
10726 self.write_keyword("RENAME TO");
10727 }
10728 self.write_space();
10729 let rename_table_with_db = !matches!(
10731 self.config.dialect,
10732 Some(DialectType::Doris)
10733 | Some(DialectType::DuckDB)
10734 | Some(DialectType::BigQuery)
10735 | Some(DialectType::PostgreSQL)
10736 );
10737 if !rename_table_with_db {
10738 let mut stripped = new_name.clone();
10739 stripped.schema = None;
10740 stripped.catalog = None;
10741 self.generate_table(&stripped)?;
10742 } else {
10743 self.generate_table(new_name)?;
10744 }
10745 }
10746 AlterTableAction::AddConstraint(constraint) => {
10747 if !is_continuation {
10750 self.write_keyword("ADD");
10751 self.write_space();
10752 }
10753 self.generate_table_constraint(constraint)?;
10754 }
10755 AlterTableAction::DropConstraint { name, if_exists } => {
10756 self.write_keyword("DROP CONSTRAINT");
10757 if *if_exists {
10758 self.write_space();
10759 self.write_keyword("IF EXISTS");
10760 }
10761 self.write_space();
10762 self.generate_identifier(name)?;
10763 }
10764 AlterTableAction::DropForeignKey { name } => {
10765 self.write_keyword("DROP FOREIGN KEY");
10766 self.write_space();
10767 self.generate_identifier(name)?;
10768 }
10769 AlterTableAction::DropPartition {
10770 partitions,
10771 if_exists,
10772 } => {
10773 self.write_keyword("DROP");
10774 if *if_exists {
10775 self.write_space();
10776 self.write_keyword("IF EXISTS");
10777 }
10778 for (i, partition) in partitions.iter().enumerate() {
10779 if i > 0 {
10780 self.write(",");
10781 }
10782 self.write_space();
10783 self.write_keyword("PARTITION");
10784 if partition.len() == 1 && partition[0].0.name == "__expr__" {
10786 self.write_space();
10788 self.generate_expression(&partition[0].1)?;
10789 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
10790 self.write_space();
10792 self.write_keyword("ALL");
10793 } else if partition.len() == 1 && partition[0].0.name == "ID" {
10794 self.write_space();
10796 self.write_keyword("ID");
10797 self.write_space();
10798 self.generate_expression(&partition[0].1)?;
10799 } else {
10800 self.write("(");
10802 for (j, (key, value)) in partition.iter().enumerate() {
10803 if j > 0 {
10804 self.write(", ");
10805 }
10806 self.generate_identifier(key)?;
10807 self.write(" = ");
10808 self.generate_expression(value)?;
10809 }
10810 self.write(")");
10811 }
10812 }
10813 }
10814 AlterTableAction::Delete { where_clause } => {
10815 self.write_keyword("DELETE");
10816 self.write_space();
10817 self.write_keyword("WHERE");
10818 self.write_space();
10819 self.generate_expression(where_clause)?;
10820 }
10821 AlterTableAction::SwapWith(target) => {
10822 self.write_keyword("SWAP WITH");
10823 self.write_space();
10824 self.generate_table(target)?;
10825 }
10826 AlterTableAction::SetProperty { properties } => {
10827 use crate::dialects::DialectType;
10828 self.write_keyword("SET");
10829 let is_trino_presto = matches!(
10831 self.config.dialect,
10832 Some(DialectType::Trino) | Some(DialectType::Presto)
10833 );
10834 if is_trino_presto {
10835 self.write_space();
10836 self.write_keyword("PROPERTIES");
10837 }
10838 let eq = if is_trino_presto { " = " } else { "=" };
10839 for (i, (key, value)) in properties.iter().enumerate() {
10840 if i > 0 {
10841 self.write(",");
10842 }
10843 self.write_space();
10844 if key.contains(' ') {
10846 self.generate_string_literal(key)?;
10847 } else {
10848 self.write(key);
10849 }
10850 self.write(eq);
10851 self.generate_expression(value)?;
10852 }
10853 }
10854 AlterTableAction::UnsetProperty { properties } => {
10855 self.write_keyword("UNSET");
10856 for (i, name) in properties.iter().enumerate() {
10857 if i > 0 {
10858 self.write(",");
10859 }
10860 self.write_space();
10861 self.write(name);
10862 }
10863 }
10864 AlterTableAction::ClusterBy { expressions } => {
10865 self.write_keyword("CLUSTER BY");
10866 self.write(" (");
10867 for (i, expr) in expressions.iter().enumerate() {
10868 if i > 0 {
10869 self.write(", ");
10870 }
10871 self.generate_expression(expr)?;
10872 }
10873 self.write(")");
10874 }
10875 AlterTableAction::SetTag { expressions } => {
10876 self.write_keyword("SET TAG");
10877 for (i, (key, value)) in expressions.iter().enumerate() {
10878 if i > 0 {
10879 self.write(",");
10880 }
10881 self.write_space();
10882 self.write(key);
10883 self.write(" = ");
10884 self.generate_expression(value)?;
10885 }
10886 }
10887 AlterTableAction::UnsetTag { names } => {
10888 self.write_keyword("UNSET TAG");
10889 for (i, name) in names.iter().enumerate() {
10890 if i > 0 {
10891 self.write(",");
10892 }
10893 self.write_space();
10894 self.write(name);
10895 }
10896 }
10897 AlterTableAction::SetOptions { expressions } => {
10898 self.write_keyword("SET");
10899 self.write(" (");
10900 for (i, expr) in expressions.iter().enumerate() {
10901 if i > 0 {
10902 self.write(", ");
10903 }
10904 self.generate_expression(expr)?;
10905 }
10906 self.write(")");
10907 }
10908 AlterTableAction::AlterIndex { name, visible } => {
10909 self.write_keyword("ALTER INDEX");
10910 self.write_space();
10911 self.generate_identifier(name)?;
10912 self.write_space();
10913 if *visible {
10914 self.write_keyword("VISIBLE");
10915 } else {
10916 self.write_keyword("INVISIBLE");
10917 }
10918 }
10919 AlterTableAction::SetAttribute { attribute } => {
10920 self.write_keyword("SET");
10921 self.write_space();
10922 self.write_keyword(attribute);
10923 }
10924 AlterTableAction::SetStageFileFormat { options } => {
10925 self.write_keyword("SET");
10926 self.write_space();
10927 self.write_keyword("STAGE_FILE_FORMAT");
10928 self.write(" = (");
10929 if let Some(opts) = options {
10930 self.generate_space_separated_properties(opts)?;
10931 }
10932 self.write(")");
10933 }
10934 AlterTableAction::SetStageCopyOptions { options } => {
10935 self.write_keyword("SET");
10936 self.write_space();
10937 self.write_keyword("STAGE_COPY_OPTIONS");
10938 self.write(" = (");
10939 if let Some(opts) = options {
10940 self.generate_space_separated_properties(opts)?;
10941 }
10942 self.write(")");
10943 }
10944 AlterTableAction::AddColumns { columns, cascade } => {
10945 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
10948 if is_oracle {
10949 self.write_keyword("ADD");
10950 } else {
10951 self.write_keyword("ADD COLUMNS");
10952 }
10953 self.write(" (");
10954 for (i, col) in columns.iter().enumerate() {
10955 if i > 0 {
10956 self.write(", ");
10957 }
10958 self.generate_column_def(col)?;
10959 }
10960 self.write(")");
10961 if *cascade {
10962 self.write_space();
10963 self.write_keyword("CASCADE");
10964 }
10965 }
10966 AlterTableAction::ChangeColumn {
10967 old_name,
10968 new_name,
10969 data_type,
10970 comment,
10971 cascade,
10972 } => {
10973 use crate::dialects::DialectType;
10974 let is_spark = matches!(
10975 self.config.dialect,
10976 Some(DialectType::Spark) | Some(DialectType::Databricks)
10977 );
10978 let is_rename = old_name.name != new_name.name;
10979
10980 if is_spark {
10981 if is_rename {
10982 self.write_keyword("RENAME COLUMN");
10984 self.write_space();
10985 self.generate_identifier(old_name)?;
10986 self.write_space();
10987 self.write_keyword("TO");
10988 self.write_space();
10989 self.generate_identifier(new_name)?;
10990 } else if comment.is_some() {
10991 self.write_keyword("ALTER COLUMN");
10993 self.write_space();
10994 self.generate_identifier(old_name)?;
10995 self.write_space();
10996 self.write_keyword("COMMENT");
10997 self.write_space();
10998 self.write("'");
10999 self.write(comment.as_ref().unwrap());
11000 self.write("'");
11001 } else if data_type.is_some() {
11002 self.write_keyword("ALTER COLUMN");
11004 self.write_space();
11005 self.generate_identifier(old_name)?;
11006 self.write_space();
11007 self.write_keyword("TYPE");
11008 self.write_space();
11009 self.generate_data_type(data_type.as_ref().unwrap())?;
11010 } else {
11011 self.write_keyword("CHANGE COLUMN");
11013 self.write_space();
11014 self.generate_identifier(old_name)?;
11015 self.write_space();
11016 self.generate_identifier(new_name)?;
11017 }
11018 } else {
11019 if data_type.is_some() {
11021 self.write_keyword("CHANGE COLUMN");
11022 } else {
11023 self.write_keyword("CHANGE");
11024 }
11025 self.write_space();
11026 self.generate_identifier(old_name)?;
11027 self.write_space();
11028 self.generate_identifier(new_name)?;
11029 if let Some(ref dt) = data_type {
11030 self.write_space();
11031 self.generate_data_type(dt)?;
11032 }
11033 if let Some(ref c) = comment {
11034 self.write_space();
11035 self.write_keyword("COMMENT");
11036 self.write_space();
11037 self.write("'");
11038 self.write(c);
11039 self.write("'");
11040 }
11041 if *cascade {
11042 self.write_space();
11043 self.write_keyword("CASCADE");
11044 }
11045 }
11046 }
11047 AlterTableAction::AddPartition {
11048 partition,
11049 if_not_exists,
11050 location,
11051 } => {
11052 self.write_keyword("ADD");
11053 self.write_space();
11054 if *if_not_exists {
11055 self.write_keyword("IF NOT EXISTS");
11056 self.write_space();
11057 }
11058 self.generate_expression(partition)?;
11059 if let Some(ref loc) = location {
11060 self.write_space();
11061 self.write_keyword("LOCATION");
11062 self.write_space();
11063 self.generate_expression(loc)?;
11064 }
11065 }
11066 AlterTableAction::AlterSortKey {
11067 this,
11068 expressions,
11069 compound,
11070 } => {
11071 self.write_keyword("ALTER");
11073 if *compound {
11074 self.write_space();
11075 self.write_keyword("COMPOUND");
11076 }
11077 self.write_space();
11078 self.write_keyword("SORTKEY");
11079 self.write_space();
11080 if let Some(style) = this {
11081 self.write_keyword(style);
11082 } else if !expressions.is_empty() {
11083 self.write("(");
11084 for (i, expr) in expressions.iter().enumerate() {
11085 if i > 0 {
11086 self.write(", ");
11087 }
11088 self.generate_expression(expr)?;
11089 }
11090 self.write(")");
11091 }
11092 }
11093 AlterTableAction::AlterDistStyle { style, distkey } => {
11094 self.write_keyword("ALTER");
11096 self.write_space();
11097 self.write_keyword("DISTSTYLE");
11098 self.write_space();
11099 self.write_keyword(style);
11100 if let Some(col) = distkey {
11101 self.write_space();
11102 self.write_keyword("DISTKEY");
11103 self.write_space();
11104 self.generate_identifier(col)?;
11105 }
11106 }
11107 AlterTableAction::SetTableProperties { properties } => {
11108 self.write_keyword("SET TABLE PROPERTIES");
11110 self.write(" (");
11111 for (i, (key, value)) in properties.iter().enumerate() {
11112 if i > 0 {
11113 self.write(", ");
11114 }
11115 self.generate_expression(key)?;
11116 self.write(" = ");
11117 self.generate_expression(value)?;
11118 }
11119 self.write(")");
11120 }
11121 AlterTableAction::SetLocation { location } => {
11122 self.write_keyword("SET LOCATION");
11124 self.write_space();
11125 self.write("'");
11126 self.write(location);
11127 self.write("'");
11128 }
11129 AlterTableAction::SetFileFormat { format } => {
11130 self.write_keyword("SET FILE FORMAT");
11132 self.write_space();
11133 self.write_keyword(format);
11134 }
11135 AlterTableAction::ReplacePartition { partition, source } => {
11136 self.write_keyword("REPLACE PARTITION");
11138 self.write_space();
11139 self.generate_expression(partition)?;
11140 if let Some(src) = source {
11141 self.write_space();
11142 self.write_keyword("FROM");
11143 self.write_space();
11144 self.generate_expression(src)?;
11145 }
11146 }
11147 AlterTableAction::Raw { sql } => {
11148 self.write(sql);
11149 }
11150 }
11151 Ok(())
11152 }
11153
11154 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
11155 match action {
11156 AlterColumnAction::SetDataType {
11157 data_type,
11158 using,
11159 collate,
11160 } => {
11161 use crate::dialects::DialectType;
11162 let is_no_prefix = matches!(
11167 self.config.dialect,
11168 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
11169 );
11170 let is_type_only = matches!(
11171 self.config.dialect,
11172 Some(DialectType::Redshift)
11173 | Some(DialectType::Spark)
11174 | Some(DialectType::Databricks)
11175 );
11176 if is_type_only {
11177 self.write_keyword("TYPE");
11178 self.write_space();
11179 } else if !is_no_prefix {
11180 self.write_keyword("SET DATA TYPE");
11181 self.write_space();
11182 }
11183 self.generate_data_type(data_type)?;
11184 if let Some(ref collation) = collate {
11185 self.write_space();
11186 self.write_keyword("COLLATE");
11187 self.write_space();
11188 self.write(collation);
11189 }
11190 if let Some(ref using_expr) = using {
11191 self.write_space();
11192 self.write_keyword("USING");
11193 self.write_space();
11194 self.generate_expression(using_expr)?;
11195 }
11196 }
11197 AlterColumnAction::SetDefault(expr) => {
11198 self.write_keyword("SET DEFAULT");
11199 self.write_space();
11200 self.generate_expression(expr)?;
11201 }
11202 AlterColumnAction::DropDefault => {
11203 self.write_keyword("DROP DEFAULT");
11204 }
11205 AlterColumnAction::SetNotNull => {
11206 self.write_keyword("SET NOT NULL");
11207 }
11208 AlterColumnAction::DropNotNull => {
11209 self.write_keyword("DROP NOT NULL");
11210 }
11211 AlterColumnAction::Comment(comment) => {
11212 self.write_keyword("COMMENT");
11213 self.write_space();
11214 self.generate_string_literal(comment)?;
11215 }
11216 AlterColumnAction::SetVisible => {
11217 self.write_keyword("SET VISIBLE");
11218 }
11219 AlterColumnAction::SetInvisible => {
11220 self.write_keyword("SET INVISIBLE");
11221 }
11222 }
11223 Ok(())
11224 }
11225
11226 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
11227 self.write_keyword("CREATE");
11228
11229 if ci.unique {
11230 self.write_space();
11231 self.write_keyword("UNIQUE");
11232 }
11233
11234 if let Some(ref clustered) = ci.clustered {
11236 self.write_space();
11237 self.write_keyword(clustered);
11238 }
11239
11240 self.write_space();
11241 self.write_keyword("INDEX");
11242
11243 if ci.concurrently {
11245 self.write_space();
11246 self.write_keyword("CONCURRENTLY");
11247 }
11248
11249 if ci.if_not_exists {
11250 self.write_space();
11251 self.write_keyword("IF NOT EXISTS");
11252 }
11253
11254 if !ci.name.name.is_empty() {
11256 self.write_space();
11257 self.generate_identifier(&ci.name)?;
11258 }
11259 self.write_space();
11260 self.write_keyword("ON");
11261 if matches!(self.config.dialect, Some(DialectType::Hive)) {
11263 self.write_space();
11264 self.write_keyword("TABLE");
11265 }
11266 self.write_space();
11267 self.generate_table(&ci.table)?;
11268
11269 if !ci.columns.is_empty() || ci.using.is_some() {
11272 let space_before_paren = false;
11273
11274 if let Some(ref using) = ci.using {
11275 self.write_space();
11276 self.write_keyword("USING");
11277 self.write_space();
11278 self.write(using);
11279 if space_before_paren {
11280 self.write(" (");
11281 } else {
11282 self.write("(");
11283 }
11284 } else {
11285 if space_before_paren {
11286 self.write(" (");
11287 } else {
11288 self.write("(");
11289 }
11290 }
11291 for (i, col) in ci.columns.iter().enumerate() {
11292 if i > 0 {
11293 self.write(", ");
11294 }
11295 self.generate_identifier(&col.column)?;
11296 if let Some(ref opclass) = col.opclass {
11297 self.write_space();
11298 self.write(opclass);
11299 }
11300 if col.desc {
11301 self.write_space();
11302 self.write_keyword("DESC");
11303 } else if col.asc {
11304 self.write_space();
11305 self.write_keyword("ASC");
11306 }
11307 if let Some(nulls_first) = col.nulls_first {
11308 self.write_space();
11309 self.write_keyword("NULLS");
11310 self.write_space();
11311 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
11312 }
11313 }
11314 self.write(")");
11315 }
11316
11317 if !ci.include_columns.is_empty() {
11319 self.write_space();
11320 self.write_keyword("INCLUDE");
11321 self.write(" (");
11322 for (i, col) in ci.include_columns.iter().enumerate() {
11323 if i > 0 {
11324 self.write(", ");
11325 }
11326 self.generate_identifier(col)?;
11327 }
11328 self.write(")");
11329 }
11330
11331 if !ci.with_options.is_empty() {
11333 self.write_space();
11334 self.write_keyword("WITH");
11335 self.write(" (");
11336 for (i, (key, value)) in ci.with_options.iter().enumerate() {
11337 if i > 0 {
11338 self.write(", ");
11339 }
11340 self.write(key);
11341 self.write("=");
11342 self.write(value);
11343 }
11344 self.write(")");
11345 }
11346
11347 if let Some(ref where_clause) = ci.where_clause {
11349 self.write_space();
11350 self.write_keyword("WHERE");
11351 self.write_space();
11352 self.generate_expression(where_clause)?;
11353 }
11354
11355 if let Some(ref on_fg) = ci.on_filegroup {
11357 self.write_space();
11358 self.write_keyword("ON");
11359 self.write_space();
11360 self.write(on_fg);
11361 }
11362
11363 Ok(())
11364 }
11365
11366 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
11367 self.write_keyword("DROP INDEX");
11368
11369 if di.concurrently {
11370 self.write_space();
11371 self.write_keyword("CONCURRENTLY");
11372 }
11373
11374 if di.if_exists {
11375 self.write_space();
11376 self.write_keyword("IF EXISTS");
11377 }
11378
11379 self.write_space();
11380 self.generate_table(&di.name)?;
11381
11382 if let Some(ref table) = di.table {
11383 self.write_space();
11384 self.write_keyword("ON");
11385 self.write_space();
11386 self.generate_table(table)?;
11387 }
11388
11389 Ok(())
11390 }
11391
11392 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
11393 self.write_keyword("CREATE");
11394
11395 if let Some(ref algorithm) = cv.algorithm {
11397 self.write_space();
11398 self.write_keyword("ALGORITHM");
11399 self.write("=");
11400 self.write_keyword(algorithm);
11401 }
11402
11403 if let Some(ref definer) = cv.definer {
11405 self.write_space();
11406 self.write_keyword("DEFINER");
11407 self.write("=");
11408 self.write(definer);
11409 }
11410
11411 if cv.security_sql_style && !cv.security_after_name {
11413 if let Some(ref security) = cv.security {
11414 self.write_space();
11415 self.write_keyword("SQL SECURITY");
11416 self.write_space();
11417 match security {
11418 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11419 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11420 FunctionSecurity::None => self.write_keyword("NONE"),
11421 }
11422 }
11423 }
11424
11425 if cv.or_alter {
11426 self.write_space();
11427 self.write_keyword("OR ALTER");
11428 } else if cv.or_replace {
11429 self.write_space();
11430 self.write_keyword("OR REPLACE");
11431 }
11432
11433 if cv.temporary {
11434 self.write_space();
11435 self.write_keyword("TEMPORARY");
11436 }
11437
11438 if cv.materialized {
11439 self.write_space();
11440 self.write_keyword("MATERIALIZED");
11441 }
11442
11443 if cv.secure {
11445 self.write_space();
11446 self.write_keyword("SECURE");
11447 }
11448
11449 self.write_space();
11450 self.write_keyword("VIEW");
11451
11452 if cv.if_not_exists {
11453 self.write_space();
11454 self.write_keyword("IF NOT EXISTS");
11455 }
11456
11457 self.write_space();
11458 self.generate_table(&cv.name)?;
11459
11460 if let Some(ref on_cluster) = cv.on_cluster {
11462 self.write_space();
11463 self.generate_on_cluster(on_cluster)?;
11464 }
11465
11466 if let Some(ref to_table) = cv.to_table {
11468 self.write_space();
11469 self.write_keyword("TO");
11470 self.write_space();
11471 self.generate_table(to_table)?;
11472 }
11473
11474 if !cv.materialized {
11477 if let Some(ref schema) = cv.schema {
11479 self.write(" (");
11480 for (i, expr) in schema.expressions.iter().enumerate() {
11481 if i > 0 {
11482 self.write(", ");
11483 }
11484 self.generate_expression(expr)?;
11485 }
11486 self.write(")");
11487 } else if !cv.columns.is_empty() {
11488 self.write(" (");
11489 for (i, col) in cv.columns.iter().enumerate() {
11490 if i > 0 {
11491 self.write(", ");
11492 }
11493 self.generate_identifier(&col.name)?;
11494 if !col.options.is_empty() {
11496 self.write_space();
11497 self.generate_options_clause(&col.options)?;
11498 }
11499 if let Some(ref comment) = col.comment {
11500 self.write_space();
11501 self.write_keyword("COMMENT");
11502 self.write_space();
11503 self.generate_string_literal(comment)?;
11504 }
11505 }
11506 self.write(")");
11507 }
11508
11509 if !cv.security_sql_style || cv.security_after_name {
11512 if let Some(ref security) = cv.security {
11513 self.write_space();
11514 if cv.security_sql_style {
11515 self.write_keyword("SQL SECURITY");
11516 } else {
11517 self.write_keyword("SECURITY");
11518 }
11519 self.write_space();
11520 match security {
11521 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11522 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11523 FunctionSecurity::None => self.write_keyword("NONE"),
11524 }
11525 }
11526 }
11527
11528 if cv.copy_grants {
11530 self.write_space();
11531 self.write_keyword("COPY GRANTS");
11532 }
11533 } else {
11534 if cv.copy_grants {
11536 self.write_space();
11537 self.write_keyword("COPY GRANTS");
11538 }
11539
11540 if let Some(ref schema) = cv.schema {
11542 self.write(" (");
11543 for (i, expr) in schema.expressions.iter().enumerate() {
11544 if i > 0 {
11545 self.write(", ");
11546 }
11547 self.generate_expression(expr)?;
11548 }
11549 self.write(")");
11550 } else if !cv.columns.is_empty() {
11551 self.write(" (");
11553 for (i, col) in cv.columns.iter().enumerate() {
11554 if i > 0 {
11555 self.write(", ");
11556 }
11557 self.generate_identifier(&col.name)?;
11558 if !col.options.is_empty() {
11560 self.write_space();
11561 self.generate_options_clause(&col.options)?;
11562 }
11563 if let Some(ref comment) = col.comment {
11564 self.write_space();
11565 self.write_keyword("COMMENT");
11566 self.write_space();
11567 self.generate_string_literal(comment)?;
11568 }
11569 }
11570 self.write(")");
11571 }
11572
11573 if let Some(ref unique_key) = cv.unique_key {
11575 self.write_space();
11576 self.write_keyword("KEY");
11577 self.write(" (");
11578 for (i, expr) in unique_key.expressions.iter().enumerate() {
11579 if i > 0 {
11580 self.write(", ");
11581 }
11582 self.generate_expression(expr)?;
11583 }
11584 self.write(")");
11585 }
11586 }
11587
11588 if let Some(ref row_access_policy) = cv.row_access_policy {
11589 self.write_space();
11590 self.write_keyword("WITH");
11591 self.write_space();
11592 self.write(row_access_policy);
11593 }
11594
11595 if let Some(ref comment) = cv.comment {
11597 self.write_space();
11598 self.write_keyword("COMMENT");
11599 self.write("=");
11600 self.generate_string_literal(comment)?;
11601 }
11602
11603 if !cv.tags.is_empty() {
11605 self.write_space();
11606 self.write_keyword("TAG");
11607 self.write(" (");
11608 for (i, (name, value)) in cv.tags.iter().enumerate() {
11609 if i > 0 {
11610 self.write(", ");
11611 }
11612 self.write(name);
11613 self.write("='");
11614 self.write(value);
11615 self.write("'");
11616 }
11617 self.write(")");
11618 }
11619
11620 if !cv.options.is_empty() {
11622 self.write_space();
11623 self.generate_options_clause(&cv.options)?;
11624 }
11625
11626 if let Some(ref build) = cv.build {
11628 self.write_space();
11629 self.write_keyword("BUILD");
11630 self.write_space();
11631 self.write_keyword(build);
11632 }
11633
11634 if let Some(ref refresh) = cv.refresh {
11636 self.write_space();
11637 self.generate_refresh_trigger_property(refresh)?;
11638 }
11639
11640 if let Some(auto_refresh) = cv.auto_refresh {
11642 self.write_space();
11643 self.write_keyword("AUTO REFRESH");
11644 self.write_space();
11645 if auto_refresh {
11646 self.write_keyword("YES");
11647 } else {
11648 self.write_keyword("NO");
11649 }
11650 }
11651
11652 for prop in &cv.table_properties {
11654 self.write_space();
11655 self.generate_expression(prop)?;
11656 }
11657
11658 if let Some(ref population) = cv.clickhouse_population {
11660 self.write_space();
11661 self.write_keyword(population);
11662 }
11663
11664 if !matches!(&cv.query, Expression::Null(_)) {
11666 self.write_space();
11667 self.write_keyword("AS");
11668 self.write_space();
11669
11670 if let Some(ref mode) = cv.locking_mode {
11672 self.write_keyword("LOCKING");
11673 self.write_space();
11674 self.write_keyword(mode);
11675 if let Some(ref access) = cv.locking_access {
11676 self.write_space();
11677 self.write_keyword("FOR");
11678 self.write_space();
11679 self.write_keyword(access);
11680 }
11681 self.write_space();
11682 }
11683
11684 if cv.query_parenthesized {
11685 self.write("(");
11686 }
11687 self.generate_expression(&cv.query)?;
11688 if cv.query_parenthesized {
11689 self.write(")");
11690 }
11691 }
11692
11693 if cv.no_schema_binding {
11695 self.write_space();
11696 self.write_keyword("WITH NO SCHEMA BINDING");
11697 }
11698
11699 Ok(())
11700 }
11701
11702 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
11703 self.write_keyword("DROP");
11704
11705 if dv.materialized {
11706 self.write_space();
11707 self.write_keyword("MATERIALIZED");
11708 }
11709
11710 self.write_space();
11711 self.write_keyword("VIEW");
11712
11713 if dv.if_exists {
11714 self.write_space();
11715 self.write_keyword("IF EXISTS");
11716 }
11717
11718 self.write_space();
11719 self.generate_table(&dv.name)?;
11720
11721 Ok(())
11722 }
11723
11724 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
11725 match tr.target {
11726 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
11727 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
11728 }
11729 if tr.if_exists {
11730 self.write_space();
11731 self.write_keyword("IF EXISTS");
11732 }
11733 self.write_space();
11734 self.generate_table(&tr.table)?;
11735
11736 if let Some(ref on_cluster) = tr.on_cluster {
11738 self.write_space();
11739 self.generate_on_cluster(on_cluster)?;
11740 }
11741
11742 if !tr.extra_tables.is_empty() {
11744 let skip_first = if let Some(first) = tr.extra_tables.first() {
11746 first.table.name == tr.table.name && first.star
11747 } else {
11748 false
11749 };
11750
11751 let strip_star = matches!(
11753 self.config.dialect,
11754 Some(crate::dialects::DialectType::PostgreSQL)
11755 | Some(crate::dialects::DialectType::Redshift)
11756 );
11757 if skip_first && !strip_star {
11758 self.write("*");
11759 }
11760
11761 for (i, entry) in tr.extra_tables.iter().enumerate() {
11763 if i == 0 && skip_first {
11764 continue; }
11766 self.write(", ");
11767 self.generate_table(&entry.table)?;
11768 if entry.star && !strip_star {
11769 self.write("*");
11770 }
11771 }
11772 }
11773
11774 if let Some(identity) = &tr.identity {
11776 self.write_space();
11777 match identity {
11778 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
11779 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
11780 }
11781 }
11782
11783 if tr.cascade {
11784 self.write_space();
11785 self.write_keyword("CASCADE");
11786 }
11787
11788 if tr.restrict {
11789 self.write_space();
11790 self.write_keyword("RESTRICT");
11791 }
11792
11793 if let Some(ref partition) = tr.partition {
11795 self.write_space();
11796 self.generate_expression(partition)?;
11797 }
11798
11799 Ok(())
11800 }
11801
11802 fn generate_use(&mut self, u: &Use) -> Result<()> {
11803 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
11805 self.write_keyword("DATABASE");
11806 self.write_space();
11807 self.generate_identifier(&u.this)?;
11808 return Ok(());
11809 }
11810
11811 self.write_keyword("USE");
11812
11813 if let Some(kind) = &u.kind {
11814 self.write_space();
11815 match kind {
11816 UseKind::Database => self.write_keyword("DATABASE"),
11817 UseKind::Schema => self.write_keyword("SCHEMA"),
11818 UseKind::Role => self.write_keyword("ROLE"),
11819 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
11820 UseKind::Catalog => self.write_keyword("CATALOG"),
11821 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
11822 }
11823 }
11824
11825 self.write_space();
11826 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
11829 self.write(&u.this.name);
11830 } else {
11831 self.generate_identifier(&u.this)?;
11832 }
11833 Ok(())
11834 }
11835
11836 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
11837 self.write_keyword("CACHE");
11838 if c.lazy {
11839 self.write_space();
11840 self.write_keyword("LAZY");
11841 }
11842 self.write_space();
11843 self.write_keyword("TABLE");
11844 self.write_space();
11845 self.generate_identifier(&c.table)?;
11846
11847 if !c.options.is_empty() {
11849 self.write_space();
11850 self.write_keyword("OPTIONS");
11851 self.write("(");
11852 for (i, (key, value)) in c.options.iter().enumerate() {
11853 if i > 0 {
11854 self.write(", ");
11855 }
11856 self.generate_expression(key)?;
11857 self.write(" = ");
11858 self.generate_expression(value)?;
11859 }
11860 self.write(")");
11861 }
11862
11863 if let Some(query) = &c.query {
11865 self.write_space();
11866 self.write_keyword("AS");
11867 self.write_space();
11868 self.generate_expression(query)?;
11869 }
11870
11871 Ok(())
11872 }
11873
11874 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
11875 self.write_keyword("UNCACHE TABLE");
11876 if u.if_exists {
11877 self.write_space();
11878 self.write_keyword("IF EXISTS");
11879 }
11880 self.write_space();
11881 self.generate_identifier(&u.table)?;
11882 Ok(())
11883 }
11884
11885 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
11886 self.write_keyword("LOAD DATA");
11887 if l.local {
11888 self.write_space();
11889 self.write_keyword("LOCAL");
11890 }
11891 self.write_space();
11892 self.write_keyword("INPATH");
11893 self.write_space();
11894 self.write("'");
11895 self.write(&l.inpath);
11896 self.write("'");
11897
11898 if l.overwrite {
11899 self.write_space();
11900 self.write_keyword("OVERWRITE");
11901 }
11902
11903 self.write_space();
11904 self.write_keyword("INTO TABLE");
11905 self.write_space();
11906 self.generate_expression(&l.table)?;
11907
11908 if !l.partition.is_empty() {
11910 self.write_space();
11911 self.write_keyword("PARTITION");
11912 self.write("(");
11913 for (i, (col, val)) in l.partition.iter().enumerate() {
11914 if i > 0 {
11915 self.write(", ");
11916 }
11917 self.generate_identifier(col)?;
11918 self.write(" = ");
11919 self.generate_expression(val)?;
11920 }
11921 self.write(")");
11922 }
11923
11924 if let Some(fmt) = &l.input_format {
11926 self.write_space();
11927 self.write_keyword("INPUTFORMAT");
11928 self.write_space();
11929 self.write("'");
11930 self.write(fmt);
11931 self.write("'");
11932 }
11933
11934 if let Some(serde) = &l.serde {
11936 self.write_space();
11937 self.write_keyword("SERDE");
11938 self.write_space();
11939 self.write("'");
11940 self.write(serde);
11941 self.write("'");
11942 }
11943
11944 Ok(())
11945 }
11946
11947 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
11948 self.write_keyword("PRAGMA");
11949 self.write_space();
11950
11951 if let Some(schema) = &p.schema {
11953 self.generate_identifier(schema)?;
11954 self.write(".");
11955 }
11956
11957 self.generate_identifier(&p.name)?;
11959
11960 if p.use_assignment_syntax {
11962 self.write(" = ");
11963 if let Some(value) = &p.value {
11964 self.generate_expression(value)?;
11965 } else if let Some(arg) = p.args.first() {
11966 self.generate_expression(arg)?;
11967 }
11968 } else if !p.args.is_empty() {
11969 self.write("(");
11970 for (i, arg) in p.args.iter().enumerate() {
11971 if i > 0 {
11972 self.write(", ");
11973 }
11974 self.generate_expression(arg)?;
11975 }
11976 self.write(")");
11977 }
11978
11979 Ok(())
11980 }
11981
11982 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
11983 self.write_keyword("GRANT");
11984 self.write_space();
11985
11986 for (i, privilege) in g.privileges.iter().enumerate() {
11988 if i > 0 {
11989 self.write(", ");
11990 }
11991 self.write_keyword(&privilege.name);
11992 if !privilege.columns.is_empty() {
11994 self.write("(");
11995 for (j, col) in privilege.columns.iter().enumerate() {
11996 if j > 0 {
11997 self.write(", ");
11998 }
11999 self.write(col);
12000 }
12001 self.write(")");
12002 }
12003 }
12004
12005 self.write_space();
12006 self.write_keyword("ON");
12007 self.write_space();
12008
12009 if let Some(kind) = &g.kind {
12011 self.write_keyword(kind);
12012 self.write_space();
12013 }
12014
12015 {
12017 use crate::dialects::DialectType;
12018 let should_upper = matches!(
12019 self.config.dialect,
12020 Some(DialectType::PostgreSQL)
12021 | Some(DialectType::CockroachDB)
12022 | Some(DialectType::Materialize)
12023 | Some(DialectType::RisingWave)
12024 ) && (g.kind.as_deref() == Some("FUNCTION")
12025 || g.kind.as_deref() == Some("PROCEDURE"));
12026 if should_upper {
12027 use crate::expressions::Identifier;
12028 let upper_id = Identifier {
12029 name: g.securable.name.to_ascii_uppercase(),
12030 quoted: g.securable.quoted,
12031 ..g.securable.clone()
12032 };
12033 self.generate_identifier(&upper_id)?;
12034 } else {
12035 self.generate_identifier(&g.securable)?;
12036 }
12037 }
12038
12039 if !g.function_params.is_empty() {
12041 self.write("(");
12042 for (i, param) in g.function_params.iter().enumerate() {
12043 if i > 0 {
12044 self.write(", ");
12045 }
12046 self.write(param);
12047 }
12048 self.write(")");
12049 }
12050
12051 self.write_space();
12052 self.write_keyword("TO");
12053 self.write_space();
12054
12055 for (i, principal) in g.principals.iter().enumerate() {
12057 if i > 0 {
12058 self.write(", ");
12059 }
12060 if principal.is_role {
12061 self.write_keyword("ROLE");
12062 self.write_space();
12063 } else if principal.is_group {
12064 self.write_keyword("GROUP");
12065 self.write_space();
12066 } else if principal.is_share {
12067 self.write_keyword("SHARE");
12068 self.write_space();
12069 }
12070 self.generate_identifier(&principal.name)?;
12071 }
12072
12073 if g.grant_option {
12075 self.write_space();
12076 self.write_keyword("WITH GRANT OPTION");
12077 }
12078
12079 if let Some(ref principal) = g.as_principal {
12081 self.write_space();
12082 self.write_keyword("AS");
12083 self.write_space();
12084 self.generate_identifier(principal)?;
12085 }
12086
12087 Ok(())
12088 }
12089
12090 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
12091 self.write_keyword("REVOKE");
12092 self.write_space();
12093
12094 if r.grant_option {
12096 self.write_keyword("GRANT OPTION FOR");
12097 self.write_space();
12098 }
12099
12100 for (i, privilege) in r.privileges.iter().enumerate() {
12102 if i > 0 {
12103 self.write(", ");
12104 }
12105 self.write_keyword(&privilege.name);
12106 if !privilege.columns.is_empty() {
12108 self.write("(");
12109 for (j, col) in privilege.columns.iter().enumerate() {
12110 if j > 0 {
12111 self.write(", ");
12112 }
12113 self.write(col);
12114 }
12115 self.write(")");
12116 }
12117 }
12118
12119 self.write_space();
12120 self.write_keyword("ON");
12121 self.write_space();
12122
12123 if let Some(kind) = &r.kind {
12125 self.write_keyword(kind);
12126 self.write_space();
12127 }
12128
12129 {
12131 use crate::dialects::DialectType;
12132 let should_upper = matches!(
12133 self.config.dialect,
12134 Some(DialectType::PostgreSQL)
12135 | Some(DialectType::CockroachDB)
12136 | Some(DialectType::Materialize)
12137 | Some(DialectType::RisingWave)
12138 ) && (r.kind.as_deref() == Some("FUNCTION")
12139 || r.kind.as_deref() == Some("PROCEDURE"));
12140 if should_upper {
12141 use crate::expressions::Identifier;
12142 let upper_id = Identifier {
12143 name: r.securable.name.to_ascii_uppercase(),
12144 quoted: r.securable.quoted,
12145 ..r.securable.clone()
12146 };
12147 self.generate_identifier(&upper_id)?;
12148 } else {
12149 self.generate_identifier(&r.securable)?;
12150 }
12151 }
12152
12153 if !r.function_params.is_empty() {
12155 self.write("(");
12156 for (i, param) in r.function_params.iter().enumerate() {
12157 if i > 0 {
12158 self.write(", ");
12159 }
12160 self.write(param);
12161 }
12162 self.write(")");
12163 }
12164
12165 self.write_space();
12166 self.write_keyword("FROM");
12167 self.write_space();
12168
12169 for (i, principal) in r.principals.iter().enumerate() {
12171 if i > 0 {
12172 self.write(", ");
12173 }
12174 if principal.is_role {
12175 self.write_keyword("ROLE");
12176 self.write_space();
12177 } else if principal.is_group {
12178 self.write_keyword("GROUP");
12179 self.write_space();
12180 } else if principal.is_share {
12181 self.write_keyword("SHARE");
12182 self.write_space();
12183 }
12184 self.generate_identifier(&principal.name)?;
12185 }
12186
12187 if r.cascade {
12189 self.write_space();
12190 self.write_keyword("CASCADE");
12191 } else if r.restrict {
12192 self.write_space();
12193 self.write_keyword("RESTRICT");
12194 }
12195
12196 Ok(())
12197 }
12198
12199 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
12200 self.write_keyword("COMMENT");
12201
12202 if c.exists {
12204 self.write_space();
12205 self.write_keyword("IF EXISTS");
12206 }
12207
12208 self.write_space();
12209 self.write_keyword("ON");
12210
12211 if c.materialized {
12213 self.write_space();
12214 self.write_keyword("MATERIALIZED");
12215 }
12216
12217 self.write_space();
12218 self.write_keyword(&c.kind);
12219 self.write_space();
12220
12221 self.generate_expression(&c.this)?;
12223
12224 self.write_space();
12225 self.write_keyword("IS");
12226 self.write_space();
12227
12228 self.generate_expression(&c.expression)?;
12230
12231 Ok(())
12232 }
12233
12234 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
12235 self.write_keyword("SET");
12236
12237 for (i, item) in s.items.iter().enumerate() {
12238 if i > 0 {
12239 self.write(",");
12240 }
12241 self.write_space();
12242
12243 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
12245 if let Some(ref kind) = item.kind {
12246 if has_variable_kind {
12250 if matches!(
12251 self.config.dialect,
12252 Some(DialectType::Spark | DialectType::Databricks | DialectType::DuckDB)
12253 ) {
12254 self.write_keyword("VARIABLE");
12255 self.write_space();
12256 }
12257 } else {
12258 self.write_keyword(kind);
12259 self.write_space();
12260 }
12261 }
12262
12263 let name_str = match &item.name {
12265 Expression::Identifier(id) => Some(id.name.as_str()),
12266 _ => None,
12267 };
12268
12269 let is_transaction = name_str == Some("TRANSACTION");
12270 let is_character_set = name_str == Some("CHARACTER SET");
12271 let is_names = name_str == Some("NAMES");
12272 let is_collate = name_str == Some("COLLATE");
12273 let is_identity_insert = name_str == Some("IDENTITY_INSERT");
12274 let is_value_only =
12275 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
12276
12277 if is_transaction {
12278 self.write_keyword("TRANSACTION");
12280 if let Expression::Identifier(id) = &item.value {
12281 if !id.name.is_empty() {
12282 self.write_space();
12283 self.write(&id.name);
12284 }
12285 }
12286 } else if is_character_set {
12287 self.write_keyword("CHARACTER SET");
12289 self.write_space();
12290 self.generate_set_value(&item.value)?;
12291 } else if is_names {
12292 self.write_keyword("NAMES");
12294 self.write_space();
12295 self.generate_set_value(&item.value)?;
12296 } else if is_collate {
12297 self.write_keyword("COLLATE");
12299 self.write_space();
12300 self.generate_set_value(&item.value)?;
12301 } else if is_identity_insert {
12302 self.write_keyword("IDENTITY_INSERT");
12304 self.write_space();
12305 self.generate_identity_insert_value(&item.value)?;
12306 } else if has_variable_kind {
12307 if let Some(ns) = name_str {
12310 self.write(ns);
12311 } else {
12312 self.generate_expression(&item.name)?;
12313 }
12314 self.write(" = ");
12315 self.generate_set_value(&item.value)?;
12316 } else if is_value_only {
12317 self.generate_expression(&item.name)?;
12319 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
12320 self.generate_expression(&item.name)?;
12322 self.write_space();
12323 self.generate_set_value(&item.value)?;
12324 } else {
12325 match &item.name {
12328 Expression::Identifier(id) => {
12329 self.write(&id.name);
12330 }
12331 _ => {
12332 self.generate_expression(&item.name)?;
12333 }
12334 }
12335 self.write(" = ");
12336 self.generate_set_value(&item.value)?;
12337 }
12338 }
12339
12340 Ok(())
12341 }
12342
12343 fn generate_identity_insert_value(&mut self, value: &Expression) -> Result<()> {
12344 if let Expression::Tuple(tuple) = value {
12345 if tuple.expressions.len() == 2 {
12346 self.generate_expression(&tuple.expressions[0])?;
12347 self.write_space();
12348 self.generate_set_value(&tuple.expressions[1])?;
12349 return Ok(());
12350 }
12351 }
12352
12353 self.generate_set_value(value)
12354 }
12355
12356 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
12359 if let Expression::Identifier(id) = value {
12360 match id.name.as_str() {
12361 "DEFAULT" | "ON" | "OFF" => {
12362 self.write_keyword(&id.name);
12363 return Ok(());
12364 }
12365 _ => {}
12366 }
12367 }
12368 self.generate_expression(value)
12369 }
12370
12371 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
12374 self.write_keyword("ALTER");
12375 if let Some(ref algorithm) = av.algorithm {
12377 self.write_space();
12378 self.write_keyword("ALGORITHM");
12379 self.write(" = ");
12380 self.write_keyword(algorithm);
12381 }
12382 if let Some(ref definer) = av.definer {
12383 self.write_space();
12384 self.write_keyword("DEFINER");
12385 self.write(" = ");
12386 self.write(definer);
12387 }
12388 if let Some(ref sql_security) = av.sql_security {
12389 self.write_space();
12390 self.write_keyword("SQL SECURITY");
12391 self.write(" = ");
12392 self.write_keyword(sql_security);
12393 }
12394 self.write_space();
12395 self.write_keyword("VIEW");
12396 self.write_space();
12397 self.generate_table(&av.name)?;
12398
12399 if !av.columns.is_empty() {
12401 self.write(" (");
12402 for (i, col) in av.columns.iter().enumerate() {
12403 if i > 0 {
12404 self.write(", ");
12405 }
12406 self.generate_identifier(&col.name)?;
12407 if let Some(ref comment) = col.comment {
12408 self.write_space();
12409 self.write_keyword("COMMENT");
12410 self.write(" ");
12411 self.generate_string_literal(comment)?;
12412 }
12413 }
12414 self.write(")");
12415 }
12416
12417 if let Some(ref opt) = av.with_option {
12419 self.write_space();
12420 self.write_keyword("WITH");
12421 self.write_space();
12422 self.write_keyword(opt);
12423 }
12424
12425 for action in &av.actions {
12426 self.write_space();
12427 match action {
12428 AlterViewAction::Rename(new_name) => {
12429 self.write_keyword("RENAME TO");
12430 self.write_space();
12431 self.generate_table(new_name)?;
12432 }
12433 AlterViewAction::OwnerTo(owner) => {
12434 self.write_keyword("OWNER TO");
12435 self.write_space();
12436 self.generate_identifier(owner)?;
12437 }
12438 AlterViewAction::SetSchema(schema) => {
12439 self.write_keyword("SET SCHEMA");
12440 self.write_space();
12441 self.generate_identifier(schema)?;
12442 }
12443 AlterViewAction::SetAuthorization(auth) => {
12444 self.write_keyword("SET AUTHORIZATION");
12445 self.write_space();
12446 self.write(auth);
12447 }
12448 AlterViewAction::AlterColumn { name, action } => {
12449 self.write_keyword("ALTER COLUMN");
12450 self.write_space();
12451 self.generate_identifier(name)?;
12452 self.write_space();
12453 self.generate_alter_column_action(action)?;
12454 }
12455 AlterViewAction::AsSelect(query) => {
12456 self.write_keyword("AS");
12457 self.write_space();
12458 self.generate_expression(query)?;
12459 }
12460 AlterViewAction::SetTblproperties(props) => {
12461 self.write_keyword("SET TBLPROPERTIES");
12462 self.write(" (");
12463 for (i, (key, value)) in props.iter().enumerate() {
12464 if i > 0 {
12465 self.write(", ");
12466 }
12467 self.generate_string_literal(key)?;
12468 self.write("=");
12469 self.generate_string_literal(value)?;
12470 }
12471 self.write(")");
12472 }
12473 AlterViewAction::UnsetTblproperties(keys) => {
12474 self.write_keyword("UNSET TBLPROPERTIES");
12475 self.write(" (");
12476 for (i, key) in keys.iter().enumerate() {
12477 if i > 0 {
12478 self.write(", ");
12479 }
12480 self.generate_string_literal(key)?;
12481 }
12482 self.write(")");
12483 }
12484 }
12485 }
12486
12487 Ok(())
12488 }
12489
12490 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
12491 self.write_keyword("ALTER INDEX");
12492 self.write_space();
12493 self.generate_identifier(&ai.name)?;
12494
12495 if let Some(table) = &ai.table {
12496 self.write_space();
12497 self.write_keyword("ON");
12498 self.write_space();
12499 self.generate_table(table)?;
12500 }
12501
12502 for action in &ai.actions {
12503 self.write_space();
12504 match action {
12505 AlterIndexAction::Rename(new_name) => {
12506 self.write_keyword("RENAME TO");
12507 self.write_space();
12508 self.generate_identifier(new_name)?;
12509 }
12510 AlterIndexAction::SetTablespace(tablespace) => {
12511 self.write_keyword("SET TABLESPACE");
12512 self.write_space();
12513 self.generate_identifier(tablespace)?;
12514 }
12515 AlterIndexAction::Visible(visible) => {
12516 if *visible {
12517 self.write_keyword("VISIBLE");
12518 } else {
12519 self.write_keyword("INVISIBLE");
12520 }
12521 }
12522 }
12523 }
12524
12525 Ok(())
12526 }
12527
12528 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
12529 for comment in &cs.leading_comments {
12531 self.write_formatted_comment(comment);
12532 self.write_space();
12533 }
12534
12535 let saved_athena_hive_context = self.athena_hive_context;
12537 if matches!(
12538 self.config.dialect,
12539 Some(crate::dialects::DialectType::Athena)
12540 ) {
12541 self.athena_hive_context = true;
12542 }
12543
12544 self.write_keyword("CREATE SCHEMA");
12545
12546 if cs.if_not_exists {
12547 self.write_space();
12548 self.write_keyword("IF NOT EXISTS");
12549 }
12550
12551 self.write_space();
12552 for (i, part) in cs.name.iter().enumerate() {
12553 if i > 0 {
12554 self.write(".");
12555 }
12556 self.generate_identifier(part)?;
12557 }
12558
12559 if let Some(ref clone_parts) = cs.clone_from {
12560 self.write_keyword(" CLONE ");
12561 for (i, part) in clone_parts.iter().enumerate() {
12562 if i > 0 {
12563 self.write(".");
12564 }
12565 self.generate_identifier(part)?;
12566 }
12567 }
12568
12569 if let Some(ref at_clause) = cs.at_clause {
12570 self.write_space();
12571 self.generate_expression(at_clause)?;
12572 }
12573
12574 if let Some(auth) = &cs.authorization {
12575 self.write_space();
12576 self.write_keyword("AUTHORIZATION");
12577 self.write_space();
12578 self.generate_identifier(auth)?;
12579 }
12580
12581 let with_properties: Vec<_> = cs
12584 .properties
12585 .iter()
12586 .filter(|p| matches!(p, Expression::Property(_)))
12587 .collect();
12588 let other_properties: Vec<_> = cs
12589 .properties
12590 .iter()
12591 .filter(|p| !matches!(p, Expression::Property(_)))
12592 .collect();
12593
12594 if !with_properties.is_empty() {
12596 self.write_space();
12597 self.write_keyword("WITH");
12598 self.write(" (");
12599 for (i, prop) in with_properties.iter().enumerate() {
12600 if i > 0 {
12601 self.write(", ");
12602 }
12603 self.generate_expression(prop)?;
12604 }
12605 self.write(")");
12606 }
12607
12608 for prop in other_properties {
12610 self.write_space();
12611 self.generate_expression(prop)?;
12612 }
12613
12614 self.athena_hive_context = saved_athena_hive_context;
12616
12617 Ok(())
12618 }
12619
12620 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
12621 self.write_keyword("DROP SCHEMA");
12622
12623 if ds.if_exists {
12624 self.write_space();
12625 self.write_keyword("IF EXISTS");
12626 }
12627
12628 self.write_space();
12629 self.generate_identifier(&ds.name)?;
12630
12631 if ds.cascade {
12632 self.write_space();
12633 self.write_keyword("CASCADE");
12634 }
12635
12636 Ok(())
12637 }
12638
12639 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
12640 self.write_keyword("DROP NAMESPACE");
12641
12642 if dn.if_exists {
12643 self.write_space();
12644 self.write_keyword("IF EXISTS");
12645 }
12646
12647 self.write_space();
12648 self.generate_identifier(&dn.name)?;
12649
12650 if dn.cascade {
12651 self.write_space();
12652 self.write_keyword("CASCADE");
12653 }
12654
12655 Ok(())
12656 }
12657
12658 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
12659 self.write_keyword("CREATE DATABASE");
12660
12661 if cd.if_not_exists {
12662 self.write_space();
12663 self.write_keyword("IF NOT EXISTS");
12664 }
12665
12666 self.write_space();
12667 self.generate_identifier(&cd.name)?;
12668
12669 if let Some(ref clone_src) = cd.clone_from {
12670 self.write_keyword(" CLONE ");
12671 self.generate_identifier(clone_src)?;
12672 }
12673
12674 if let Some(ref at_clause) = cd.at_clause {
12676 self.write_space();
12677 self.generate_expression(at_clause)?;
12678 }
12679
12680 for option in &cd.options {
12681 self.write_space();
12682 match option {
12683 DatabaseOption::CharacterSet(charset) => {
12684 self.write_keyword("CHARACTER SET");
12685 self.write(" = ");
12686 self.write(&format!("'{}'", charset));
12687 }
12688 DatabaseOption::Collate(collate) => {
12689 self.write_keyword("COLLATE");
12690 self.write(" = ");
12691 self.write(&format!("'{}'", collate));
12692 }
12693 DatabaseOption::Owner(owner) => {
12694 self.write_keyword("OWNER");
12695 self.write(" = ");
12696 self.generate_identifier(owner)?;
12697 }
12698 DatabaseOption::Template(template) => {
12699 self.write_keyword("TEMPLATE");
12700 self.write(" = ");
12701 self.generate_identifier(template)?;
12702 }
12703 DatabaseOption::Encoding(encoding) => {
12704 self.write_keyword("ENCODING");
12705 self.write(" = ");
12706 self.write(&format!("'{}'", encoding));
12707 }
12708 DatabaseOption::Location(location) => {
12709 self.write_keyword("LOCATION");
12710 self.write(" = ");
12711 self.write(&format!("'{}'", location));
12712 }
12713 }
12714 }
12715
12716 Ok(())
12717 }
12718
12719 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
12720 self.write_keyword("DROP DATABASE");
12721
12722 if dd.if_exists {
12723 self.write_space();
12724 self.write_keyword("IF EXISTS");
12725 }
12726
12727 self.write_space();
12728 self.generate_identifier(&dd.name)?;
12729
12730 if dd.sync {
12731 self.write_space();
12732 self.write_keyword("SYNC");
12733 }
12734
12735 Ok(())
12736 }
12737
12738 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
12739 self.write_keyword("CREATE");
12740
12741 if cf.or_alter {
12742 self.write_space();
12743 self.write_keyword("OR ALTER");
12744 } else if cf.or_replace {
12745 self.write_space();
12746 self.write_keyword("OR REPLACE");
12747 }
12748
12749 if cf.temporary {
12750 self.write_space();
12751 self.write_keyword("TEMPORARY");
12752 }
12753
12754 self.write_space();
12755 if cf.is_table_function {
12756 self.write_keyword("TABLE FUNCTION");
12757 } else {
12758 self.write_keyword("FUNCTION");
12759 }
12760
12761 if cf.if_not_exists {
12762 self.write_space();
12763 self.write_keyword("IF NOT EXISTS");
12764 }
12765
12766 self.write_space();
12767 self.generate_table(&cf.name)?;
12768 if cf.has_parens {
12769 let func_multiline = self.config.pretty
12770 && matches!(
12771 self.config.dialect,
12772 Some(crate::dialects::DialectType::TSQL)
12773 | Some(crate::dialects::DialectType::Fabric)
12774 )
12775 && !cf.parameters.is_empty();
12776 if func_multiline {
12777 self.write("(\n");
12778 self.indent_level += 2;
12779 self.write_indent();
12780 self.generate_function_parameters(&cf.parameters)?;
12781 self.write("\n");
12782 self.indent_level -= 2;
12783 self.write(")");
12784 } else {
12785 self.write("(");
12786 self.generate_function_parameters(&cf.parameters)?;
12787 self.write(")");
12788 }
12789 }
12790
12791 let use_multiline = self.config.pretty
12794 && matches!(
12795 self.config.dialect,
12796 Some(crate::dialects::DialectType::BigQuery)
12797 | Some(crate::dialects::DialectType::TSQL)
12798 | Some(crate::dialects::DialectType::Fabric)
12799 );
12800
12801 if cf.language_first {
12802 if let Some(lang) = &cf.language {
12804 if use_multiline {
12805 self.write_newline();
12806 } else {
12807 self.write_space();
12808 }
12809 self.write_keyword("LANGUAGE");
12810 self.write_space();
12811 self.write(lang);
12812 }
12813
12814 if let Some(sql_data) = &cf.sql_data_access {
12816 self.write_space();
12817 match sql_data {
12818 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12819 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12820 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12821 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12822 }
12823 }
12824
12825 if let Some(ref rtb) = cf.returns_table_body {
12826 if use_multiline {
12827 self.write_newline();
12828 } else {
12829 self.write_space();
12830 }
12831 self.write_keyword("RETURNS");
12832 self.write_space();
12833 self.write(rtb);
12834 } else if let Some(return_type) = &cf.return_type {
12835 if use_multiline {
12836 self.write_newline();
12837 } else {
12838 self.write_space();
12839 }
12840 self.write_keyword("RETURNS");
12841 self.write_space();
12842 self.generate_function_return_type(return_type)?;
12843 }
12844 } else {
12845 let is_duckdb = matches!(
12848 self.config.dialect,
12849 Some(crate::dialects::DialectType::DuckDB)
12850 );
12851 if let Some(ref rtb) = cf.returns_table_body {
12852 if !(is_duckdb && rtb.is_empty()) {
12853 if use_multiline {
12854 self.write_newline();
12855 } else {
12856 self.write_space();
12857 }
12858 self.write_keyword("RETURNS");
12859 self.write_space();
12860 self.write(rtb);
12861 }
12862 } else if let Some(return_type) = &cf.return_type {
12863 if !is_duckdb {
12865 let is_table_return = matches!(return_type, crate::expressions::DataType::Custom { ref name } if name.eq_ignore_ascii_case("TABLE"));
12866 if use_multiline {
12867 self.write_newline();
12868 } else {
12869 self.write_space();
12870 }
12871 self.write_keyword("RETURNS");
12872 self.write_space();
12873 if is_table_return {
12874 self.write_keyword("TABLE");
12875 } else {
12876 self.generate_function_return_type(return_type)?;
12877 }
12878 }
12879 }
12880 }
12881
12882 if !cf.property_order.is_empty() {
12884 let is_bigquery = matches!(
12886 self.config.dialect,
12887 Some(crate::dialects::DialectType::BigQuery)
12888 );
12889 let is_postgres = matches!(
12890 self.config.dialect,
12891 Some(crate::dialects::DialectType::PostgreSQL)
12892 );
12893 let property_order = if is_bigquery {
12894 let mut reordered = Vec::new();
12896 let mut has_as = false;
12897 let mut has_options = false;
12898 for prop in &cf.property_order {
12899 match prop {
12900 FunctionPropertyKind::As => has_as = true,
12901 FunctionPropertyKind::Options => has_options = true,
12902 _ => {}
12903 }
12904 }
12905 if has_as && has_options {
12906 for prop in &cf.property_order {
12908 if *prop != FunctionPropertyKind::As
12909 && *prop != FunctionPropertyKind::Options
12910 {
12911 reordered.push(*prop);
12912 }
12913 }
12914 reordered.push(FunctionPropertyKind::Options);
12915 reordered.push(FunctionPropertyKind::As);
12916 reordered
12917 } else {
12918 cf.property_order.clone()
12919 }
12920 } else if is_postgres
12921 && cf.property_order.contains(&FunctionPropertyKind::As)
12922 && cf.property_order.contains(&FunctionPropertyKind::NullInput)
12923 {
12924 let mut reordered: Vec<_> = cf
12925 .property_order
12926 .iter()
12927 .copied()
12928 .filter(|prop| *prop != FunctionPropertyKind::As)
12929 .collect();
12930 reordered.push(FunctionPropertyKind::As);
12931 reordered
12932 } else {
12933 cf.property_order.clone()
12934 };
12935
12936 for prop in &property_order {
12937 match prop {
12938 FunctionPropertyKind::Set => {
12939 self.generate_function_set_options(cf)?;
12940 }
12941 FunctionPropertyKind::As => {
12942 self.generate_function_body(cf)?;
12943 }
12944 FunctionPropertyKind::Using => {
12945 self.generate_function_using_resources(cf)?;
12946 }
12947 FunctionPropertyKind::Language => {
12948 if !cf.language_first {
12949 if let Some(lang) = &cf.language {
12951 let use_multiline = self.config.pretty
12953 && matches!(
12954 self.config.dialect,
12955 Some(crate::dialects::DialectType::BigQuery)
12956 );
12957 if use_multiline {
12958 self.write_newline();
12959 } else {
12960 self.write_space();
12961 }
12962 self.write_keyword("LANGUAGE");
12963 self.write_space();
12964 self.write(lang);
12965 }
12966 }
12967 }
12968 FunctionPropertyKind::Determinism => {
12969 self.generate_function_determinism(cf)?;
12970 }
12971 FunctionPropertyKind::NullInput => {
12972 self.generate_function_null_input(cf)?;
12973 }
12974 FunctionPropertyKind::Security => {
12975 self.generate_function_security(cf)?;
12976 }
12977 FunctionPropertyKind::SqlDataAccess => {
12978 if !cf.language_first {
12979 self.generate_function_sql_data_access(cf)?;
12981 }
12982 }
12983 FunctionPropertyKind::Options => {
12984 if !cf.options.is_empty() {
12985 self.write_space();
12986 self.generate_options_clause(&cf.options)?;
12987 }
12988 }
12989 FunctionPropertyKind::Environment => {
12990 if !cf.environment.is_empty() {
12991 self.write_space();
12992 self.generate_environment_clause(&cf.environment)?;
12993 }
12994 }
12995 FunctionPropertyKind::Handler => {
12996 if let Some(ref h) = cf.handler {
12997 self.write_space();
12998 self.write_keyword("HANDLER");
12999 if cf.handler_uses_eq {
13000 self.write(" = ");
13001 } else {
13002 self.write_space();
13003 }
13004 self.write("'");
13005 self.write(h);
13006 self.write("'");
13007 }
13008 }
13009 FunctionPropertyKind::RuntimeVersion => {
13010 if let Some(ref runtime_version) = cf.runtime_version {
13011 self.write_space();
13012 self.write_keyword("RUNTIME_VERSION");
13013 self.write("='");
13014 self.write(runtime_version);
13015 self.write("'");
13016 }
13017 }
13018 FunctionPropertyKind::Packages => {
13019 if let Some(ref packages) = cf.packages {
13020 self.write_space();
13021 self.write_keyword("PACKAGES");
13022 self.write("=(");
13023 for (i, package) in packages.iter().enumerate() {
13024 if i > 0 {
13025 self.write(", ");
13026 }
13027 self.write("'");
13028 self.write(package);
13029 self.write("'");
13030 }
13031 self.write(")");
13032 }
13033 }
13034 FunctionPropertyKind::ParameterStyle => {
13035 if let Some(ref ps) = cf.parameter_style {
13036 self.write_space();
13037 self.write_keyword("PARAMETER STYLE");
13038 self.write_space();
13039 self.write_keyword(ps);
13040 }
13041 }
13042 }
13043 }
13044
13045 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
13047 {
13048 self.write_space();
13049 self.generate_options_clause(&cf.options)?;
13050 }
13051
13052 if !cf.environment.is_empty()
13054 && !cf
13055 .property_order
13056 .contains(&FunctionPropertyKind::Environment)
13057 {
13058 self.write_space();
13059 self.generate_environment_clause(&cf.environment)?;
13060 }
13061 } else {
13062 if matches!(
13065 self.config.dialect,
13066 Some(crate::dialects::DialectType::BigQuery)
13067 ) {
13068 self.generate_function_determinism(cf)?;
13069 }
13070
13071 let use_multiline = self.config.pretty
13073 && matches!(
13074 self.config.dialect,
13075 Some(crate::dialects::DialectType::BigQuery)
13076 );
13077
13078 if !cf.language_first {
13079 if let Some(lang) = &cf.language {
13080 if use_multiline {
13081 self.write_newline();
13082 } else {
13083 self.write_space();
13084 }
13085 self.write_keyword("LANGUAGE");
13086 self.write_space();
13087 self.write(lang);
13088 }
13089
13090 self.generate_function_sql_data_access(cf)?;
13092 }
13093
13094 if !matches!(
13096 self.config.dialect,
13097 Some(crate::dialects::DialectType::BigQuery)
13098 ) {
13099 self.generate_function_determinism(cf)?;
13100 }
13101
13102 self.generate_function_null_input(cf)?;
13103 self.generate_function_security(cf)?;
13104 self.generate_function_set_options(cf)?;
13105
13106 if !cf.options.is_empty() {
13108 self.write_space();
13109 self.generate_options_clause(&cf.options)?;
13110 }
13111
13112 if !cf.environment.is_empty() {
13114 self.write_space();
13115 self.generate_environment_clause(&cf.environment)?;
13116 }
13117
13118 if let Some(ref h) = cf.handler {
13119 self.write_space();
13120 self.write_keyword("HANDLER");
13121 if cf.handler_uses_eq {
13122 self.write(" = ");
13123 } else {
13124 self.write_space();
13125 }
13126 self.write("'");
13127 self.write(h);
13128 self.write("'");
13129 }
13130
13131 if let Some(ref runtime_version) = cf.runtime_version {
13132 self.write_space();
13133 self.write_keyword("RUNTIME_VERSION");
13134 self.write("='");
13135 self.write(runtime_version);
13136 self.write("'");
13137 }
13138
13139 if let Some(ref packages) = cf.packages {
13140 self.write_space();
13141 self.write_keyword("PACKAGES");
13142 self.write("=(");
13143 for (i, package) in packages.iter().enumerate() {
13144 if i > 0 {
13145 self.write(", ");
13146 }
13147 self.write("'");
13148 self.write(package);
13149 self.write("'");
13150 }
13151 self.write(")");
13152 }
13153
13154 self.generate_function_body(cf)?;
13155 self.generate_function_using_resources(cf)?;
13156 }
13157
13158 Ok(())
13159 }
13160
13161 fn generate_function_return_type(&mut self, return_type: &DataType) -> Result<()> {
13162 if matches!(
13163 self.config.dialect,
13164 Some(crate::dialects::DialectType::PostgreSQL)
13165 ) {
13166 if let DataType::Custom { name } = return_type {
13167 if name.eq_ignore_ascii_case("integer") {
13168 self.write_keyword("INT");
13169 return Ok(());
13170 }
13171 }
13172 }
13173
13174 self.generate_data_type(return_type)
13175 }
13176
13177 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
13179 for opt in &cf.set_options {
13180 self.write_space();
13181 self.write_keyword("SET");
13182 self.write_space();
13183 self.write(&opt.name);
13184 match &opt.value {
13185 FunctionSetValue::Value { value, use_to } => {
13186 if *use_to {
13187 self.write(" TO ");
13188 } else {
13189 self.write(" = ");
13190 }
13191 self.write(value);
13192 }
13193 FunctionSetValue::FromCurrent => {
13194 self.write_space();
13195 self.write_keyword("FROM CURRENT");
13196 }
13197 }
13198 }
13199 Ok(())
13200 }
13201
13202 fn generate_function_using_resources(&mut self, cf: &CreateFunction) -> Result<()> {
13203 if cf.using_resources.is_empty() {
13204 return Ok(());
13205 }
13206
13207 self.write_space();
13208 self.write_keyword("USING");
13209 for resource in &cf.using_resources {
13210 self.write_space();
13211 self.write_keyword(&resource.kind);
13212 self.write_space();
13213 self.generate_string_literal(&resource.uri)?;
13214 }
13215 Ok(())
13216 }
13217
13218 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
13220 if let Some(body) = &cf.body {
13221 self.write_space();
13223 let use_multiline = self.config.pretty
13225 && matches!(
13226 self.config.dialect,
13227 Some(crate::dialects::DialectType::BigQuery)
13228 );
13229 match body {
13230 FunctionBody::Block(block) => {
13231 self.write_keyword("AS");
13232 if matches!(
13233 self.config.dialect,
13234 Some(crate::dialects::DialectType::TSQL)
13235 ) {
13236 self.write(" BEGIN ");
13237 self.write(block);
13238 self.write(" END");
13239 } else if matches!(
13240 self.config.dialect,
13241 Some(crate::dialects::DialectType::PostgreSQL)
13242 ) {
13243 self.write(" $$");
13244 self.write(block);
13245 self.write("$$");
13246 } else {
13247 let escaped = self.escape_block_for_single_quote(block);
13249 if use_multiline {
13251 self.write_newline();
13252 } else {
13253 self.write(" ");
13254 }
13255 self.write("'");
13256 self.write(&escaped);
13257 self.write("'");
13258 }
13259 }
13260 FunctionBody::StringLiteral(s) => {
13261 self.write_keyword("AS");
13262 if use_multiline {
13264 self.write_newline();
13265 } else {
13266 self.write(" ");
13267 }
13268 self.write("'");
13269 self.write(s);
13270 self.write("'");
13271 }
13272 FunctionBody::Expression(expr) => {
13273 self.write_keyword("AS");
13274 self.write_space();
13275 self.generate_expression(expr)?;
13276 }
13277 FunctionBody::External(name) => {
13278 self.write_keyword("EXTERNAL NAME");
13279 self.write(" '");
13280 self.write(name);
13281 self.write("'");
13282 }
13283 FunctionBody::Return(expr) => {
13284 if matches!(
13285 self.config.dialect,
13286 Some(crate::dialects::DialectType::DuckDB)
13287 ) {
13288 self.write_keyword("AS");
13290 self.write_space();
13291 let is_table_return = cf.returns_table_body.is_some()
13293 || matches!(&cf.return_type, Some(crate::expressions::DataType::Custom { ref name }) if name.eq_ignore_ascii_case("TABLE"));
13294 if is_table_return {
13295 self.write_keyword("TABLE");
13296 self.write_space();
13297 }
13298 self.generate_expression(expr)?;
13299 } else {
13300 if self.config.create_function_return_as {
13301 self.write_keyword("AS");
13302 if self.config.pretty
13304 && matches!(
13305 self.config.dialect,
13306 Some(crate::dialects::DialectType::TSQL)
13307 | Some(crate::dialects::DialectType::Fabric)
13308 )
13309 {
13310 self.write_newline();
13311 } else {
13312 self.write_space();
13313 }
13314 }
13315 self.write_keyword("RETURN");
13316 self.write_space();
13317 self.generate_expression(expr)?;
13318 }
13319 }
13320 FunctionBody::Statements(stmts) => {
13321 self.write_keyword("AS");
13322 self.write(" BEGIN ");
13323 for (i, stmt) in stmts.iter().enumerate() {
13324 if i > 0 {
13325 self.write(" ");
13326 }
13327 self.generate_expression(stmt)?;
13328 self.write(";");
13329 }
13330 self.write(" END");
13331 }
13332 FunctionBody::RawBlock(text) => {
13333 self.write_newline();
13334 self.write(text);
13335 }
13336 FunctionBody::DollarQuoted { content, tag } => {
13337 self.write_keyword("AS");
13338 self.write(" ");
13339 let supports_dollar_quoting = matches!(
13341 self.config.dialect,
13342 Some(crate::dialects::DialectType::PostgreSQL)
13343 | Some(crate::dialects::DialectType::Databricks)
13344 | Some(crate::dialects::DialectType::Redshift)
13345 | Some(crate::dialects::DialectType::DuckDB)
13346 );
13347 if supports_dollar_quoting {
13348 self.write("$");
13350 if let Some(t) = tag {
13351 self.write(t);
13352 }
13353 self.write("$");
13354 self.write(content);
13355 self.write("$");
13356 if let Some(t) = tag {
13357 self.write(t);
13358 }
13359 self.write("$");
13360 } else {
13361 let escaped = self.escape_block_for_single_quote(content);
13363 self.write("'");
13364 self.write(&escaped);
13365 self.write("'");
13366 }
13367 }
13368 }
13369 }
13370 Ok(())
13371 }
13372
13373 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
13375 if let Some(det) = cf.deterministic {
13376 self.write_space();
13377 if matches!(
13378 self.config.dialect,
13379 Some(crate::dialects::DialectType::BigQuery)
13380 ) {
13381 if det {
13383 self.write_keyword("DETERMINISTIC");
13384 } else {
13385 self.write_keyword("NOT DETERMINISTIC");
13386 }
13387 } else {
13388 if det {
13390 self.write_keyword("IMMUTABLE");
13391 } else {
13392 self.write_keyword("VOLATILE");
13393 }
13394 }
13395 }
13396 Ok(())
13397 }
13398
13399 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
13401 if let Some(returns_null) = cf.returns_null_on_null_input {
13402 self.write_space();
13403 if returns_null {
13404 if cf.strict {
13405 self.write_keyword("STRICT");
13406 } else {
13407 self.write_keyword("RETURNS NULL ON NULL INPUT");
13408 }
13409 } else {
13410 self.write_keyword("CALLED ON NULL INPUT");
13411 }
13412 }
13413 Ok(())
13414 }
13415
13416 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
13418 if let Some(security) = &cf.security {
13419 self.write_space();
13420 if matches!(
13422 self.config.dialect,
13423 Some(crate::dialects::DialectType::MySQL)
13424 ) {
13425 self.write_keyword("SQL SECURITY");
13426 } else {
13427 self.write_keyword("SECURITY");
13428 }
13429 self.write_space();
13430 match security {
13431 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13432 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13433 FunctionSecurity::None => self.write_keyword("NONE"),
13434 }
13435 }
13436 Ok(())
13437 }
13438
13439 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
13441 if let Some(sql_data) = &cf.sql_data_access {
13442 self.write_space();
13443 match sql_data {
13444 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
13445 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
13446 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
13447 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
13448 }
13449 }
13450 Ok(())
13451 }
13452
13453 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
13454 for (i, param) in params.iter().enumerate() {
13455 if i > 0 {
13456 self.write(", ");
13457 }
13458
13459 if let Some(mode) = ¶m.mode {
13460 if let Some(text) = ¶m.mode_text {
13461 self.write(text);
13462 } else {
13463 match mode {
13464 ParameterMode::In => self.write_keyword("IN"),
13465 ParameterMode::Out => self.write_keyword("OUT"),
13466 ParameterMode::InOut => self.write_keyword("INOUT"),
13467 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
13468 }
13469 }
13470 self.write_space();
13471 }
13472
13473 if let Some(name) = ¶m.name {
13474 self.generate_identifier(name)?;
13475 let skip_type =
13477 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
13478 if !skip_type {
13479 self.write_space();
13480 self.generate_data_type(¶m.data_type)?;
13481 }
13482 } else {
13483 self.generate_data_type(¶m.data_type)?;
13484 }
13485
13486 if let Some(default) = ¶m.default {
13487 if self.config.parameter_default_equals {
13488 self.write(" = ");
13489 } else {
13490 self.write(" DEFAULT ");
13491 }
13492 self.generate_expression(default)?;
13493 }
13494 }
13495
13496 Ok(())
13497 }
13498
13499 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
13500 self.write_keyword("DROP FUNCTION");
13501
13502 if df.if_exists {
13503 self.write_space();
13504 self.write_keyword("IF EXISTS");
13505 }
13506
13507 self.write_space();
13508 self.generate_table(&df.name)?;
13509
13510 if let Some(params) = &df.parameters {
13511 self.write(" (");
13512 for (i, dt) in params.iter().enumerate() {
13513 if i > 0 {
13514 self.write(", ");
13515 }
13516 self.generate_data_type(dt)?;
13517 }
13518 self.write(")");
13519 }
13520
13521 if df.cascade {
13522 self.write_space();
13523 self.write_keyword("CASCADE");
13524 }
13525
13526 Ok(())
13527 }
13528
13529 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
13530 self.write_keyword("CREATE");
13531
13532 if cp.or_alter {
13533 self.write_space();
13534 self.write_keyword("OR ALTER");
13535 } else if cp.or_replace {
13536 self.write_space();
13537 self.write_keyword("OR REPLACE");
13538 }
13539
13540 self.write_space();
13541 if cp.use_proc_keyword {
13542 self.write_keyword("PROC");
13543 } else {
13544 self.write_keyword("PROCEDURE");
13545 }
13546
13547 if cp.if_not_exists {
13548 self.write_space();
13549 self.write_keyword("IF NOT EXISTS");
13550 }
13551
13552 self.write_space();
13553 self.generate_table(&cp.name)?;
13554 if cp.has_parens {
13555 self.write("(");
13556 self.generate_function_parameters(&cp.parameters)?;
13557 self.write(")");
13558 } else if !cp.parameters.is_empty() {
13559 self.write_space();
13561 self.generate_function_parameters(&cp.parameters)?;
13562 }
13563
13564 if let Some(return_type) = &cp.return_type {
13566 self.write_space();
13567 self.write_keyword("RETURNS");
13568 self.write_space();
13569 self.generate_data_type(return_type)?;
13570 }
13571
13572 if let Some(execute_as) = &cp.execute_as {
13574 self.write_space();
13575 self.write_keyword("EXECUTE AS");
13576 self.write_space();
13577 self.write_keyword(execute_as);
13578 }
13579
13580 if let Some(lang) = &cp.language {
13581 self.write_space();
13582 self.write_keyword("LANGUAGE");
13583 self.write_space();
13584 self.write(lang);
13585 }
13586
13587 if let Some(security) = &cp.security {
13588 self.write_space();
13589 self.write_keyword("SECURITY");
13590 self.write_space();
13591 match security {
13592 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13593 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13594 FunctionSecurity::None => self.write_keyword("NONE"),
13595 }
13596 }
13597
13598 if !cp.with_options.is_empty() {
13600 self.write_space();
13601 self.write_keyword("WITH");
13602 self.write_space();
13603 for (i, opt) in cp.with_options.iter().enumerate() {
13604 if i > 0 {
13605 self.write(", ");
13606 }
13607 self.write(opt);
13608 }
13609 }
13610
13611 if let Some(body) = &cp.body {
13612 self.write_space();
13613 match body {
13614 FunctionBody::Block(block) => {
13615 self.write_keyword("AS");
13616 if matches!(
13617 self.config.dialect,
13618 Some(crate::dialects::DialectType::TSQL)
13619 ) {
13620 self.write(" BEGIN ");
13621 self.write(block);
13622 self.write(" END");
13623 } else if matches!(
13624 self.config.dialect,
13625 Some(crate::dialects::DialectType::PostgreSQL)
13626 ) {
13627 self.write(" $$");
13628 self.write(block);
13629 self.write("$$");
13630 } else {
13631 let escaped = self.escape_block_for_single_quote(block);
13633 self.write(" '");
13634 self.write(&escaped);
13635 self.write("'");
13636 }
13637 }
13638 FunctionBody::StringLiteral(s) => {
13639 self.write_keyword("AS");
13640 self.write(" '");
13641 self.write(s);
13642 self.write("'");
13643 }
13644 FunctionBody::Expression(expr) => {
13645 self.write_keyword("AS");
13646 self.write_space();
13647 self.generate_expression(expr)?;
13648 }
13649 FunctionBody::External(name) => {
13650 self.write_keyword("EXTERNAL NAME");
13651 self.write(" '");
13652 self.write(name);
13653 self.write("'");
13654 }
13655 FunctionBody::Return(expr) => {
13656 self.write_keyword("RETURN");
13657 self.write_space();
13658 self.generate_expression(expr)?;
13659 }
13660 FunctionBody::Statements(stmts) => {
13661 self.write_keyword("AS");
13662 self.write(" BEGIN ");
13663 for (i, stmt) in stmts.iter().enumerate() {
13664 if i > 0 {
13665 self.write(" ");
13666 }
13667 self.generate_expression(stmt)?;
13668 self.write(";");
13669 }
13670 self.write(" END");
13671 }
13672 FunctionBody::RawBlock(text) => {
13673 self.write_newline();
13674 self.write(text);
13675 }
13676 FunctionBody::DollarQuoted { content, tag } => {
13677 self.write_keyword("AS");
13678 self.write(" ");
13679 let supports_dollar_quoting = matches!(
13681 self.config.dialect,
13682 Some(crate::dialects::DialectType::PostgreSQL)
13683 | Some(crate::dialects::DialectType::Databricks)
13684 | Some(crate::dialects::DialectType::Redshift)
13685 | Some(crate::dialects::DialectType::DuckDB)
13686 );
13687 if supports_dollar_quoting {
13688 self.write("$");
13690 if let Some(t) = tag {
13691 self.write(t);
13692 }
13693 self.write("$");
13694 self.write(content);
13695 self.write("$");
13696 if let Some(t) = tag {
13697 self.write(t);
13698 }
13699 self.write("$");
13700 } else {
13701 let escaped = self.escape_block_for_single_quote(content);
13703 self.write("'");
13704 self.write(&escaped);
13705 self.write("'");
13706 }
13707 }
13708 }
13709 }
13710
13711 Ok(())
13712 }
13713
13714 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
13715 self.write_keyword("DROP PROCEDURE");
13716
13717 if dp.if_exists {
13718 self.write_space();
13719 self.write_keyword("IF EXISTS");
13720 }
13721
13722 self.write_space();
13723 self.generate_table(&dp.name)?;
13724
13725 if let Some(params) = &dp.parameters {
13726 self.write(" (");
13727 for (i, dt) in params.iter().enumerate() {
13728 if i > 0 {
13729 self.write(", ");
13730 }
13731 self.generate_data_type(dt)?;
13732 }
13733 self.write(")");
13734 }
13735
13736 if dp.cascade {
13737 self.write_space();
13738 self.write_keyword("CASCADE");
13739 }
13740
13741 Ok(())
13742 }
13743
13744 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
13745 self.write_keyword("CREATE");
13746
13747 if cs.or_replace {
13748 self.write_space();
13749 self.write_keyword("OR REPLACE");
13750 }
13751
13752 if cs.temporary {
13753 self.write_space();
13754 self.write_keyword("TEMPORARY");
13755 }
13756
13757 self.write_space();
13758 self.write_keyword("SEQUENCE");
13759
13760 if cs.if_not_exists {
13761 self.write_space();
13762 self.write_keyword("IF NOT EXISTS");
13763 }
13764
13765 self.write_space();
13766 self.generate_table(&cs.name)?;
13767
13768 if let Some(as_type) = &cs.as_type {
13770 self.write_space();
13771 self.write_keyword("AS");
13772 self.write_space();
13773 self.generate_data_type(as_type)?;
13774 }
13775
13776 if let Some(comment) = &cs.comment {
13778 self.write_space();
13779 self.write_keyword("COMMENT");
13780 self.write("=");
13781 self.generate_string_literal(comment)?;
13782 }
13783
13784 if !cs.property_order.is_empty() {
13786 for prop in &cs.property_order {
13787 match prop {
13788 SeqPropKind::Start => {
13789 if let Some(start) = cs.start {
13790 self.write_space();
13791 self.write_keyword("START WITH");
13792 self.write(&format!(" {}", start));
13793 }
13794 }
13795 SeqPropKind::Increment => {
13796 if let Some(inc) = cs.increment {
13797 self.write_space();
13798 self.write_keyword("INCREMENT BY");
13799 self.write(&format!(" {}", inc));
13800 }
13801 }
13802 SeqPropKind::Minvalue => {
13803 if let Some(min) = &cs.minvalue {
13804 self.write_space();
13805 match min {
13806 SequenceBound::Value(v) => {
13807 self.write_keyword("MINVALUE");
13808 self.write(&format!(" {}", v));
13809 }
13810 SequenceBound::None => {
13811 self.write_keyword("NO MINVALUE");
13812 }
13813 }
13814 }
13815 }
13816 SeqPropKind::Maxvalue => {
13817 if let Some(max) = &cs.maxvalue {
13818 self.write_space();
13819 match max {
13820 SequenceBound::Value(v) => {
13821 self.write_keyword("MAXVALUE");
13822 self.write(&format!(" {}", v));
13823 }
13824 SequenceBound::None => {
13825 self.write_keyword("NO MAXVALUE");
13826 }
13827 }
13828 }
13829 }
13830 SeqPropKind::Cache => {
13831 if let Some(cache) = cs.cache {
13832 self.write_space();
13833 self.write_keyword("CACHE");
13834 self.write(&format!(" {}", cache));
13835 }
13836 }
13837 SeqPropKind::NoCache => {
13838 self.write_space();
13839 self.write_keyword("NO CACHE");
13840 }
13841 SeqPropKind::NoCacheWord => {
13842 self.write_space();
13843 self.write_keyword("NOCACHE");
13844 }
13845 SeqPropKind::Cycle => {
13846 self.write_space();
13847 self.write_keyword("CYCLE");
13848 }
13849 SeqPropKind::NoCycle => {
13850 self.write_space();
13851 self.write_keyword("NO CYCLE");
13852 }
13853 SeqPropKind::NoCycleWord => {
13854 self.write_space();
13855 self.write_keyword("NOCYCLE");
13856 }
13857 SeqPropKind::OwnedBy => {
13858 if !cs.owned_by_none {
13860 if let Some(owned) = &cs.owned_by {
13861 self.write_space();
13862 self.write_keyword("OWNED BY");
13863 self.write_space();
13864 self.generate_table(owned)?;
13865 }
13866 }
13867 }
13868 SeqPropKind::Order => {
13869 self.write_space();
13870 self.write_keyword("ORDER");
13871 }
13872 SeqPropKind::NoOrder => {
13873 self.write_space();
13874 self.write_keyword("NOORDER");
13875 }
13876 SeqPropKind::Comment => {
13877 }
13879 SeqPropKind::Sharing => {
13880 if let Some(val) = &cs.sharing {
13881 self.write_space();
13882 self.write(&format!("SHARING={}", val));
13883 }
13884 }
13885 SeqPropKind::Keep => {
13886 self.write_space();
13887 self.write_keyword("KEEP");
13888 }
13889 SeqPropKind::NoKeep => {
13890 self.write_space();
13891 self.write_keyword("NOKEEP");
13892 }
13893 SeqPropKind::Scale => {
13894 self.write_space();
13895 self.write_keyword("SCALE");
13896 if let Some(modifier) = &cs.scale_modifier {
13897 if !modifier.is_empty() {
13898 self.write_space();
13899 self.write_keyword(modifier);
13900 }
13901 }
13902 }
13903 SeqPropKind::NoScale => {
13904 self.write_space();
13905 self.write_keyword("NOSCALE");
13906 }
13907 SeqPropKind::Shard => {
13908 self.write_space();
13909 self.write_keyword("SHARD");
13910 if let Some(modifier) = &cs.shard_modifier {
13911 if !modifier.is_empty() {
13912 self.write_space();
13913 self.write_keyword(modifier);
13914 }
13915 }
13916 }
13917 SeqPropKind::NoShard => {
13918 self.write_space();
13919 self.write_keyword("NOSHARD");
13920 }
13921 SeqPropKind::Session => {
13922 self.write_space();
13923 self.write_keyword("SESSION");
13924 }
13925 SeqPropKind::Global => {
13926 self.write_space();
13927 self.write_keyword("GLOBAL");
13928 }
13929 SeqPropKind::NoMinvalueWord => {
13930 self.write_space();
13931 self.write_keyword("NOMINVALUE");
13932 }
13933 SeqPropKind::NoMaxvalueWord => {
13934 self.write_space();
13935 self.write_keyword("NOMAXVALUE");
13936 }
13937 }
13938 }
13939 } else {
13940 if let Some(inc) = cs.increment {
13942 self.write_space();
13943 self.write_keyword("INCREMENT BY");
13944 self.write(&format!(" {}", inc));
13945 }
13946
13947 if let Some(min) = &cs.minvalue {
13948 self.write_space();
13949 match min {
13950 SequenceBound::Value(v) => {
13951 self.write_keyword("MINVALUE");
13952 self.write(&format!(" {}", v));
13953 }
13954 SequenceBound::None => {
13955 self.write_keyword("NO MINVALUE");
13956 }
13957 }
13958 }
13959
13960 if let Some(max) = &cs.maxvalue {
13961 self.write_space();
13962 match max {
13963 SequenceBound::Value(v) => {
13964 self.write_keyword("MAXVALUE");
13965 self.write(&format!(" {}", v));
13966 }
13967 SequenceBound::None => {
13968 self.write_keyword("NO MAXVALUE");
13969 }
13970 }
13971 }
13972
13973 if let Some(start) = cs.start {
13974 self.write_space();
13975 self.write_keyword("START WITH");
13976 self.write(&format!(" {}", start));
13977 }
13978
13979 if let Some(cache) = cs.cache {
13980 self.write_space();
13981 self.write_keyword("CACHE");
13982 self.write(&format!(" {}", cache));
13983 }
13984
13985 if cs.cycle {
13986 self.write_space();
13987 self.write_keyword("CYCLE");
13988 }
13989
13990 if let Some(owned) = &cs.owned_by {
13991 self.write_space();
13992 self.write_keyword("OWNED BY");
13993 self.write_space();
13994 self.generate_table(owned)?;
13995 }
13996 }
13997
13998 Ok(())
13999 }
14000
14001 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
14002 self.write_keyword("DROP SEQUENCE");
14003
14004 if ds.if_exists {
14005 self.write_space();
14006 self.write_keyword("IF EXISTS");
14007 }
14008
14009 self.write_space();
14010 self.generate_table(&ds.name)?;
14011
14012 if ds.cascade {
14013 self.write_space();
14014 self.write_keyword("CASCADE");
14015 }
14016
14017 Ok(())
14018 }
14019
14020 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
14021 self.write_keyword("ALTER SEQUENCE");
14022
14023 if als.if_exists {
14024 self.write_space();
14025 self.write_keyword("IF EXISTS");
14026 }
14027
14028 self.write_space();
14029 self.generate_table(&als.name)?;
14030
14031 if let Some(inc) = als.increment {
14032 self.write_space();
14033 self.write_keyword("INCREMENT BY");
14034 self.write(&format!(" {}", inc));
14035 }
14036
14037 if let Some(min) = &als.minvalue {
14038 self.write_space();
14039 match min {
14040 SequenceBound::Value(v) => {
14041 self.write_keyword("MINVALUE");
14042 self.write(&format!(" {}", v));
14043 }
14044 SequenceBound::None => {
14045 self.write_keyword("NO MINVALUE");
14046 }
14047 }
14048 }
14049
14050 if let Some(max) = &als.maxvalue {
14051 self.write_space();
14052 match max {
14053 SequenceBound::Value(v) => {
14054 self.write_keyword("MAXVALUE");
14055 self.write(&format!(" {}", v));
14056 }
14057 SequenceBound::None => {
14058 self.write_keyword("NO MAXVALUE");
14059 }
14060 }
14061 }
14062
14063 if let Some(start) = als.start {
14064 self.write_space();
14065 self.write_keyword("START WITH");
14066 self.write(&format!(" {}", start));
14067 }
14068
14069 if let Some(restart) = &als.restart {
14070 self.write_space();
14071 self.write_keyword("RESTART");
14072 if let Some(val) = restart {
14073 self.write_keyword(" WITH");
14074 self.write(&format!(" {}", val));
14075 }
14076 }
14077
14078 if let Some(cache) = als.cache {
14079 self.write_space();
14080 self.write_keyword("CACHE");
14081 self.write(&format!(" {}", cache));
14082 }
14083
14084 if let Some(cycle) = als.cycle {
14085 self.write_space();
14086 if cycle {
14087 self.write_keyword("CYCLE");
14088 } else {
14089 self.write_keyword("NO CYCLE");
14090 }
14091 }
14092
14093 if let Some(owned) = &als.owned_by {
14094 self.write_space();
14095 self.write_keyword("OWNED BY");
14096 self.write_space();
14097 if let Some(table) = owned {
14098 self.generate_table(table)?;
14099 } else {
14100 self.write_keyword("NONE");
14101 }
14102 }
14103
14104 Ok(())
14105 }
14106
14107 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
14108 self.write_keyword("CREATE");
14109
14110 if ct.or_alter {
14111 self.write_space();
14112 self.write_keyword("OR ALTER");
14113 } else if ct.or_replace {
14114 self.write_space();
14115 self.write_keyword("OR REPLACE");
14116 }
14117
14118 if ct.constraint {
14119 self.write_space();
14120 self.write_keyword("CONSTRAINT");
14121 }
14122
14123 self.write_space();
14124 self.write_keyword("TRIGGER");
14125 self.write_space();
14126 self.generate_identifier(&ct.name)?;
14127
14128 self.write_space();
14129 match ct.timing {
14130 TriggerTiming::Before => self.write_keyword("BEFORE"),
14131 TriggerTiming::After => self.write_keyword("AFTER"),
14132 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
14133 }
14134
14135 for (i, event) in ct.events.iter().enumerate() {
14137 if i > 0 {
14138 self.write_keyword(" OR");
14139 }
14140 self.write_space();
14141 match event {
14142 TriggerEvent::Insert => self.write_keyword("INSERT"),
14143 TriggerEvent::Update(cols) => {
14144 self.write_keyword("UPDATE");
14145 if let Some(cols) = cols {
14146 self.write_space();
14147 self.write_keyword("OF");
14148 for (j, col) in cols.iter().enumerate() {
14149 if j > 0 {
14150 self.write(",");
14151 }
14152 self.write_space();
14153 self.generate_identifier(col)?;
14154 }
14155 }
14156 }
14157 TriggerEvent::Delete => self.write_keyword("DELETE"),
14158 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
14159 }
14160 }
14161
14162 self.write_space();
14163 self.write_keyword("ON");
14164 self.write_space();
14165 self.generate_table(&ct.table)?;
14166
14167 if let Some(ref_clause) = &ct.referencing {
14169 self.write_space();
14170 self.write_keyword("REFERENCING");
14171 if let Some(old_table) = &ref_clause.old_table {
14172 self.write_space();
14173 self.write_keyword("OLD TABLE AS");
14174 self.write_space();
14175 self.generate_identifier(old_table)?;
14176 }
14177 if let Some(new_table) = &ref_clause.new_table {
14178 self.write_space();
14179 self.write_keyword("NEW TABLE AS");
14180 self.write_space();
14181 self.generate_identifier(new_table)?;
14182 }
14183 if let Some(old_row) = &ref_clause.old_row {
14184 self.write_space();
14185 self.write_keyword("OLD ROW AS");
14186 self.write_space();
14187 self.generate_identifier(old_row)?;
14188 }
14189 if let Some(new_row) = &ref_clause.new_row {
14190 self.write_space();
14191 self.write_keyword("NEW ROW AS");
14192 self.write_space();
14193 self.generate_identifier(new_row)?;
14194 }
14195 }
14196
14197 if let Some(deferrable) = ct.deferrable {
14199 self.write_space();
14200 if deferrable {
14201 self.write_keyword("DEFERRABLE");
14202 } else {
14203 self.write_keyword("NOT DEFERRABLE");
14204 }
14205 }
14206
14207 if let Some(initially) = ct.initially_deferred {
14208 self.write_space();
14209 self.write_keyword("INITIALLY");
14210 self.write_space();
14211 if initially {
14212 self.write_keyword("DEFERRED");
14213 } else {
14214 self.write_keyword("IMMEDIATE");
14215 }
14216 }
14217
14218 if let Some(for_each) = ct.for_each {
14219 self.write_space();
14220 self.write_keyword("FOR EACH");
14221 self.write_space();
14222 match for_each {
14223 TriggerForEach::Row => self.write_keyword("ROW"),
14224 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
14225 }
14226 }
14227
14228 if let Some(when) = &ct.when {
14230 self.write_space();
14231 self.write_keyword("WHEN");
14232 if ct.when_paren {
14233 self.write(" (");
14234 self.generate_expression(when)?;
14235 self.write(")");
14236 } else {
14237 self.write_space();
14238 self.generate_expression(when)?;
14239 }
14240 }
14241
14242 self.write_space();
14244 match &ct.body {
14245 TriggerBody::Execute { function, args } => {
14246 self.write_keyword("EXECUTE FUNCTION");
14247 self.write_space();
14248 self.generate_table(function)?;
14249 self.write("(");
14250 for (i, arg) in args.iter().enumerate() {
14251 if i > 0 {
14252 self.write(", ");
14253 }
14254 self.generate_expression(arg)?;
14255 }
14256 self.write(")");
14257 }
14258 TriggerBody::Block(block) => {
14259 self.write_keyword("BEGIN");
14260 self.write_space();
14261 self.write(block);
14262 self.write_space();
14263 self.write_keyword("END");
14264 }
14265 }
14266
14267 Ok(())
14268 }
14269
14270 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
14271 self.write_keyword("DROP TRIGGER");
14272
14273 if dt.if_exists {
14274 self.write_space();
14275 self.write_keyword("IF EXISTS");
14276 }
14277
14278 self.write_space();
14279 self.generate_identifier(&dt.name)?;
14280
14281 if let Some(table) = &dt.table {
14282 self.write_space();
14283 self.write_keyword("ON");
14284 self.write_space();
14285 self.generate_table(table)?;
14286 }
14287
14288 if dt.cascade {
14289 self.write_space();
14290 self.write_keyword("CASCADE");
14291 }
14292
14293 Ok(())
14294 }
14295
14296 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
14297 self.write_keyword("CREATE TYPE");
14298
14299 if ct.if_not_exists {
14300 self.write_space();
14301 self.write_keyword("IF NOT EXISTS");
14302 }
14303
14304 self.write_space();
14305 self.generate_table(&ct.name)?;
14306
14307 if let TypeDefinition::Base {
14308 input,
14309 output,
14310 internallength,
14311 } = &ct.definition
14312 {
14313 if input.is_empty() && output.is_empty() && internallength.is_none() {
14314 return Ok(());
14315 }
14316 }
14317
14318 self.write_space();
14319 self.write_keyword("AS");
14320 self.write_space();
14321
14322 match &ct.definition {
14323 TypeDefinition::Enum(values) => {
14324 self.write_keyword("ENUM");
14325 self.write(" (");
14326 for (i, val) in values.iter().enumerate() {
14327 if i > 0 {
14328 self.write(", ");
14329 }
14330 self.write(&format!("'{}'", val));
14331 }
14332 self.write(")");
14333 }
14334 TypeDefinition::Composite(attrs) => {
14335 self.write("(");
14336 for (i, attr) in attrs.iter().enumerate() {
14337 if i > 0 {
14338 self.write(", ");
14339 }
14340 self.generate_identifier(&attr.name)?;
14341 self.write_space();
14342 self.generate_data_type(&attr.data_type)?;
14343 if let Some(collate) = &attr.collate {
14344 self.write_space();
14345 self.write_keyword("COLLATE");
14346 self.write_space();
14347 self.generate_identifier(collate)?;
14348 }
14349 }
14350 self.write(")");
14351 }
14352 TypeDefinition::Range {
14353 subtype,
14354 subtype_diff,
14355 canonical,
14356 } => {
14357 self.write_keyword("RANGE");
14358 self.write(" (");
14359 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
14360 self.write("subtype");
14361 } else {
14362 self.write_keyword("SUBTYPE");
14363 }
14364 self.write(" = ");
14365 self.generate_data_type(subtype)?;
14366 if let Some(diff) = subtype_diff {
14367 self.write(", ");
14368 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
14369 self.write("subtype_diff");
14370 } else {
14371 self.write_keyword("SUBTYPE_DIFF");
14372 }
14373 self.write(" = ");
14374 self.write(diff);
14375 }
14376 if let Some(canon) = canonical {
14377 self.write(", ");
14378 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
14379 self.write("canonical");
14380 } else {
14381 self.write_keyword("CANONICAL");
14382 }
14383 self.write(" = ");
14384 self.write(canon);
14385 }
14386 self.write(")");
14387 }
14388 TypeDefinition::Base {
14389 input,
14390 output,
14391 internallength,
14392 } => {
14393 self.write("(");
14394 self.write_keyword("INPUT");
14395 self.write(" = ");
14396 self.write(input);
14397 self.write(", ");
14398 self.write_keyword("OUTPUT");
14399 self.write(" = ");
14400 self.write(output);
14401 if let Some(len) = internallength {
14402 self.write(", ");
14403 self.write_keyword("INTERNALLENGTH");
14404 self.write(" = ");
14405 self.write(&len.to_string());
14406 }
14407 self.write(")");
14408 }
14409 TypeDefinition::Domain {
14410 base_type,
14411 default,
14412 constraints,
14413 } => {
14414 self.generate_data_type(base_type)?;
14415 if let Some(def) = default {
14416 self.write_space();
14417 self.write_keyword("DEFAULT");
14418 self.write_space();
14419 self.generate_expression(def)?;
14420 }
14421 for constr in constraints {
14422 self.write_space();
14423 if let Some(name) = &constr.name {
14424 self.write_keyword("CONSTRAINT");
14425 self.write_space();
14426 self.generate_identifier(name)?;
14427 self.write_space();
14428 }
14429 self.write_keyword("CHECK");
14430 self.write(" (");
14431 self.generate_expression(&constr.check)?;
14432 self.write(")");
14433 }
14434 }
14435 }
14436
14437 Ok(())
14438 }
14439
14440 fn generate_create_task(&mut self, task: &crate::expressions::CreateTask) -> Result<()> {
14441 self.write_keyword("CREATE");
14442 if task.or_replace {
14443 self.write_space();
14444 self.write_keyword("OR REPLACE");
14445 }
14446 self.write_space();
14447 self.write_keyword("TASK");
14448 if task.if_not_exists {
14449 self.write_space();
14450 self.write_keyword("IF NOT EXISTS");
14451 }
14452 self.write_space();
14453 self.write(&task.name);
14454 if !task.properties.is_empty() {
14455 if !task.properties.starts_with('\n') && !task.properties.starts_with(' ') {
14457 self.write_space();
14458 }
14459 self.write(&task.properties);
14460 }
14461 self.write_space();
14462 self.write_keyword("AS");
14463 self.write_space();
14464 self.generate_expression(&task.body)?;
14465 Ok(())
14466 }
14467
14468 fn generate_try_catch(&mut self, try_catch: &TryCatch) -> Result<()> {
14469 self.write_keyword("BEGIN TRY");
14470 self.generate_tsql_block_statements(&try_catch.try_body)?;
14471 self.write_keyword("END TRY");
14472
14473 if let Some(catch_body) = &try_catch.catch_body {
14474 if self.config.pretty {
14475 self.write_newline();
14476 self.write_indent();
14477 } else {
14478 self.write_space();
14479 }
14480 self.write_keyword("BEGIN CATCH");
14481 self.generate_tsql_block_statements(catch_body)?;
14482 self.write_keyword("END CATCH");
14483 }
14484
14485 Ok(())
14486 }
14487
14488 fn generate_tsql_block_statements(&mut self, statements: &[Expression]) -> Result<()> {
14489 if statements.is_empty() {
14490 self.write_space();
14491 return Ok(());
14492 }
14493
14494 if self.config.pretty {
14495 self.indent_level += 1;
14496 for stmt in statements {
14497 self.write_newline();
14498 self.write_indent();
14499 self.generate_expression(stmt)?;
14500 self.write(";");
14501 }
14502 self.indent_level -= 1;
14503 self.write_newline();
14504 self.write_indent();
14505 } else {
14506 self.write_space();
14507 for (i, stmt) in statements.iter().enumerate() {
14508 if i > 0 {
14509 self.write_space();
14510 }
14511 self.generate_expression(stmt)?;
14512 self.write(";");
14513 }
14514 self.write_space();
14515 }
14516
14517 Ok(())
14518 }
14519
14520 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
14521 self.write_keyword("DROP TYPE");
14522
14523 if dt.if_exists {
14524 self.write_space();
14525 self.write_keyword("IF EXISTS");
14526 }
14527
14528 self.write_space();
14529 self.generate_table(&dt.name)?;
14530
14531 if dt.cascade {
14532 self.write_space();
14533 self.write_keyword("CASCADE");
14534 }
14535
14536 Ok(())
14537 }
14538
14539 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
14540 let saved_athena_hive_context = self.athena_hive_context;
14542 if matches!(
14543 self.config.dialect,
14544 Some(crate::dialects::DialectType::Athena)
14545 ) {
14546 self.athena_hive_context = true;
14547 }
14548
14549 for comment in &d.leading_comments {
14551 self.write_formatted_comment(comment);
14552 self.write(" ");
14553 }
14554
14555 self.write_keyword("DESCRIBE");
14556
14557 if d.extended {
14558 self.write_space();
14559 self.write_keyword("EXTENDED");
14560 } else if d.formatted {
14561 self.write_space();
14562 self.write_keyword("FORMATTED");
14563 }
14564
14565 if let Some(ref style) = d.style {
14567 self.write_space();
14568 self.write_keyword(style);
14569 }
14570
14571 let should_output_kind = match self.config.dialect {
14573 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
14575 false
14576 }
14577 Some(DialectType::Snowflake) => true,
14579 _ => d.kind.is_some(),
14580 };
14581 if should_output_kind {
14582 if let Some(ref kind) = d.kind {
14583 self.write_space();
14584 self.write_keyword(kind);
14585 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
14586 self.write_space();
14587 self.write_keyword("TABLE");
14588 }
14589 }
14590
14591 self.write_space();
14592 self.generate_expression(&d.target)?;
14593
14594 if !d.params.is_empty() {
14596 self.write("(");
14597 for (i, param) in d.params.iter().enumerate() {
14598 if i > 0 {
14599 self.write(", ");
14600 }
14601 self.write(param);
14602 }
14603 self.write(")");
14604 }
14605
14606 if let Some(ref partition) = d.partition {
14608 self.write_space();
14609 self.generate_expression(partition)?;
14610 }
14611
14612 if d.as_json {
14614 self.write_space();
14615 self.write_keyword("AS JSON");
14616 }
14617
14618 for (name, value) in &d.properties {
14620 self.write_space();
14621 self.write(name);
14622 self.write("=");
14623 self.write(value);
14624 }
14625
14626 self.athena_hive_context = saved_athena_hive_context;
14628
14629 Ok(())
14630 }
14631
14632 fn generate_show(&mut self, s: &Show) -> Result<()> {
14635 self.write_keyword("SHOW");
14636 self.write_space();
14637
14638 let show_terse = s.terse
14641 && !matches!(
14642 s.this.as_str(),
14643 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
14644 );
14645 if show_terse {
14646 self.write_keyword("TERSE");
14647 self.write_space();
14648 }
14649
14650 self.write_keyword(&s.this);
14652
14653 if let Some(ref target_expr) = s.target {
14655 self.write_space();
14656 self.generate_expression(target_expr)?;
14657 }
14658
14659 if s.history {
14661 self.write_space();
14662 self.write_keyword("HISTORY");
14663 }
14664
14665 if let Some(ref for_target) = s.for_target {
14667 self.write_space();
14668 self.write_keyword("FOR");
14669 self.write_space();
14670 self.generate_expression(for_target)?;
14671 }
14672
14673 use crate::dialects::DialectType;
14677 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
14678 let is_mysql = matches!(self.config.dialect, Some(DialectType::MySQL));
14679 let mysql_tables_scope_as_from = is_mysql
14680 && matches!(s.this.as_str(), "TABLES" | "FULL TABLES")
14681 && s.scope_kind.as_deref() == Some("SCHEMA")
14682 && s.scope.is_some()
14683 && s.from.is_none();
14684
14685 if !is_snowflake && s.from.is_some() {
14686 if let Some(ref scope_kind) = s.scope_kind {
14690 self.write_space();
14691 self.write_keyword("IN");
14692 self.write_space();
14693 self.write_keyword(scope_kind);
14694 if let Some(ref scope) = s.scope {
14695 self.write_space();
14696 self.generate_expression(scope)?;
14697 }
14698 } else if let Some(ref scope) = s.scope {
14699 self.write_space();
14700 self.write_keyword("IN");
14701 self.write_space();
14702 self.generate_expression(scope)?;
14703 }
14704
14705 if let Some(ref from) = s.from {
14707 self.write_space();
14708 self.write_keyword("FROM");
14709 self.write_space();
14710 self.generate_expression(from)?;
14711 }
14712
14713 if let Some(ref db) = s.db {
14715 self.write_space();
14716 self.write_keyword("FROM");
14717 self.write_space();
14718 self.generate_expression(db)?;
14719 }
14720
14721 if let Some(ref like) = s.like {
14723 self.write_space();
14724 self.write_keyword("LIKE");
14725 self.write_space();
14726 self.generate_expression(like)?;
14727 }
14728 } else {
14729 if let Some(ref like) = s.like {
14733 self.write_space();
14734 self.write_keyword("LIKE");
14735 self.write_space();
14736 self.generate_expression(like)?;
14737 }
14738
14739 if mysql_tables_scope_as_from {
14741 self.write_space();
14742 self.write_keyword("FROM");
14743 self.write_space();
14744 self.generate_expression(s.scope.as_ref().unwrap())?;
14745 } else if let Some(ref scope_kind) = s.scope_kind {
14746 self.write_space();
14747 self.write_keyword("IN");
14748 self.write_space();
14749 self.write_keyword(scope_kind);
14750 if let Some(ref scope) = s.scope {
14751 self.write_space();
14752 self.generate_expression(scope)?;
14753 }
14754 } else if let Some(ref scope) = s.scope {
14755 self.write_space();
14756 self.write_keyword("IN");
14757 self.write_space();
14758 self.generate_expression(scope)?;
14759 }
14760 }
14761
14762 if let Some(ref starts_with) = s.starts_with {
14764 self.write_space();
14765 self.write_keyword("STARTS WITH");
14766 self.write_space();
14767 self.generate_expression(starts_with)?;
14768 }
14769
14770 if let Some(ref limit) = s.limit {
14772 self.write_space();
14773 self.generate_limit(limit)?;
14774 }
14775
14776 if is_snowflake {
14778 if let Some(ref from) = s.from {
14779 self.write_space();
14780 self.write_keyword("FROM");
14781 self.write_space();
14782 self.generate_expression(from)?;
14783 }
14784 }
14785
14786 if let Some(ref where_clause) = s.where_clause {
14788 self.write_space();
14789 self.write_keyword("WHERE");
14790 self.write_space();
14791 self.generate_expression(where_clause)?;
14792 }
14793
14794 if let Some(is_mutex) = s.mutex {
14796 self.write_space();
14797 if is_mutex {
14798 self.write_keyword("MUTEX");
14799 } else {
14800 self.write_keyword("STATUS");
14801 }
14802 }
14803
14804 if !s.privileges.is_empty() {
14806 self.write_space();
14807 self.write_keyword("WITH PRIVILEGES");
14808 self.write_space();
14809 for (i, priv_name) in s.privileges.iter().enumerate() {
14810 if i > 0 {
14811 self.write(", ");
14812 }
14813 self.write_keyword(priv_name);
14814 }
14815 }
14816
14817 Ok(())
14818 }
14819
14820 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
14823 use crate::dialects::DialectType;
14824 match lit {
14825 Literal::String(s) => {
14826 self.generate_string_literal(s)?;
14827 }
14828 Literal::Number(n) => {
14829 if matches!(self.config.dialect, Some(DialectType::MySQL))
14830 && n.len() > 2
14831 && (n.starts_with("0x") || n.starts_with("0X"))
14832 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
14833 {
14834 return self.generate_identifier(&Identifier {
14835 name: n.clone(),
14836 quoted: true,
14837 trailing_comments: Vec::new(),
14838 span: None,
14839 });
14840 }
14841 let n = if n.contains('_')
14845 && !matches!(
14846 self.config.dialect,
14847 Some(DialectType::ClickHouse)
14848 | Some(DialectType::DuckDB)
14849 | Some(DialectType::PostgreSQL)
14850 | Some(DialectType::Hive)
14851 | Some(DialectType::Spark)
14852 | Some(DialectType::Databricks)
14853 ) {
14854 std::borrow::Cow::Owned(n.replace('_', ""))
14855 } else {
14856 std::borrow::Cow::Borrowed(n.as_str())
14857 };
14858 if n.starts_with('.') {
14861 self.write("0");
14862 self.write(&n);
14863 } else if n.starts_with("-.") {
14864 self.write("-0");
14866 self.write(&n[1..]);
14867 } else {
14868 self.write(&n);
14869 }
14870 }
14871 Literal::HexString(h) => {
14872 match self.config.dialect {
14874 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
14875 self.write("0x");
14876 self.write(h);
14877 return Ok(());
14878 }
14879 Some(DialectType::Spark)
14880 | Some(DialectType::Databricks)
14881 | Some(DialectType::Teradata) => self.write("X'"),
14882 _ => self.write("x'"),
14883 }
14884 self.write(h);
14885 self.write("'");
14886 }
14887 Literal::HexNumber(h) => {
14888 match self.config.dialect {
14892 Some(DialectType::BigQuery)
14893 | Some(DialectType::ClickHouse)
14894 | Some(DialectType::TSQL)
14895 | Some(DialectType::Fabric) => {
14896 self.write("0x");
14897 self.write(h);
14898 }
14899 _ => {
14900 if let Ok(val) = u64::from_str_radix(h, 16) {
14902 self.write(&val.to_string());
14903 } else {
14904 self.write("0x");
14906 self.write(h);
14907 }
14908 }
14909 }
14910 }
14911 Literal::BitString(b) => {
14912 self.write("B'");
14914 self.write(b);
14915 self.write("'");
14916 }
14917 Literal::ByteString(b) => {
14918 self.write("b'");
14920 self.write_escaped_byte_string(b);
14922 self.write("'");
14923 }
14924 Literal::NationalString(s) => {
14925 let keep_n_prefix = matches!(
14928 self.config.dialect,
14929 Some(DialectType::TSQL)
14930 | Some(DialectType::Oracle)
14931 | Some(DialectType::MySQL)
14932 | None
14933 );
14934 if keep_n_prefix {
14935 self.write("N'");
14936 } else {
14937 self.write("'");
14938 }
14939 self.write(s);
14940 self.write("'");
14941 }
14942 Literal::Date(d) => {
14943 self.generate_date_literal(d)?;
14944 }
14945 Literal::Time(t) => {
14946 self.generate_time_literal(t)?;
14947 }
14948 Literal::Timestamp(ts) => {
14949 self.generate_timestamp_literal(ts)?;
14950 }
14951 Literal::Datetime(dt) => {
14952 self.generate_datetime_literal(dt)?;
14953 }
14954 Literal::TripleQuotedString(s, _quote_char) => {
14955 if matches!(
14957 self.config.dialect,
14958 Some(crate::dialects::DialectType::BigQuery)
14959 | Some(crate::dialects::DialectType::DuckDB)
14960 | Some(crate::dialects::DialectType::Snowflake)
14961 | Some(crate::dialects::DialectType::Spark)
14962 | Some(crate::dialects::DialectType::Hive)
14963 | Some(crate::dialects::DialectType::Presto)
14964 | Some(crate::dialects::DialectType::Trino)
14965 | Some(crate::dialects::DialectType::PostgreSQL)
14966 | Some(crate::dialects::DialectType::MySQL)
14967 | Some(crate::dialects::DialectType::Redshift)
14968 | Some(crate::dialects::DialectType::TSQL)
14969 | Some(crate::dialects::DialectType::Oracle)
14970 | Some(crate::dialects::DialectType::ClickHouse)
14971 | Some(crate::dialects::DialectType::Databricks)
14972 | Some(crate::dialects::DialectType::SQLite)
14973 ) {
14974 self.generate_string_literal(s)?;
14975 } else {
14976 let quotes = format!("{0}{0}{0}", _quote_char);
14978 self.write("es);
14979 self.write(s);
14980 self.write("es);
14981 }
14982 }
14983 Literal::EscapeString(s) => {
14984 use crate::dialects::DialectType;
14988 let content = if let Some(c) = s.strip_prefix("e:") {
14989 c
14990 } else if let Some(c) = s.strip_prefix("E:") {
14991 c
14992 } else {
14993 s.as_str()
14994 };
14995
14996 if matches!(
14998 self.config.dialect,
14999 Some(DialectType::MySQL) | Some(DialectType::TiDB)
15000 ) {
15001 self.write("'");
15002 self.write(&content.replace('\'', "''"));
15003 self.write("'");
15004 } else {
15005 let prefix = if matches!(
15007 self.config.dialect,
15008 Some(DialectType::SingleStore)
15009 | Some(DialectType::DuckDB)
15010 | Some(DialectType::PostgreSQL)
15011 | Some(DialectType::CockroachDB)
15012 | Some(DialectType::Materialize)
15013 | Some(DialectType::RisingWave)
15014 ) {
15015 "e'"
15016 } else {
15017 "E'"
15018 };
15019
15020 let normalized = content.replace("\\'", "''");
15022 self.write(prefix);
15023 self.write(&normalized);
15024 self.write("'");
15025 }
15026 }
15027 Literal::DollarString(s) => {
15028 use crate::dialects::DialectType;
15031 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
15033 let escape_backslash = matches!(
15035 self.config.dialect,
15036 Some(DialectType::ClickHouse) | Some(DialectType::Snowflake)
15037 );
15038 let use_backslash_quote =
15042 matches!(self.config.dialect, Some(DialectType::Snowflake));
15043
15044 let mut escaped = String::with_capacity(content.len() + 4);
15045 for ch in content.chars() {
15046 if escape_backslash && ch == '\\' {
15047 escaped.push('\\');
15049 escaped.push('\\');
15050 } else if ch == '\'' {
15051 if use_backslash_quote {
15052 escaped.push('\\');
15053 escaped.push('\'');
15054 } else {
15055 escaped.push('\'');
15056 escaped.push('\'');
15057 }
15058 } else {
15059 escaped.push(ch);
15060 }
15061 }
15062 self.write("'");
15063 self.write(&escaped);
15064 self.write("'");
15065 }
15066 Literal::RawString(s) => {
15067 use crate::dialects::DialectType;
15073
15074 let escape_backslash = matches!(
15076 self.config.dialect,
15077 Some(DialectType::BigQuery)
15078 | Some(DialectType::MySQL)
15079 | Some(DialectType::SingleStore)
15080 | Some(DialectType::TiDB)
15081 | Some(DialectType::Hive)
15082 | Some(DialectType::Spark)
15083 | Some(DialectType::Databricks)
15084 | Some(DialectType::Drill)
15085 | Some(DialectType::Snowflake)
15086 | Some(DialectType::Redshift)
15087 | Some(DialectType::ClickHouse)
15088 );
15089
15090 let backslash_escapes_quote = matches!(
15093 self.config.dialect,
15094 Some(DialectType::BigQuery)
15095 | Some(DialectType::Hive)
15096 | Some(DialectType::Spark)
15097 | Some(DialectType::Databricks)
15098 | Some(DialectType::Drill)
15099 | Some(DialectType::Snowflake)
15100 | Some(DialectType::Redshift)
15101 );
15102
15103 let supports_escape_sequences = escape_backslash;
15106
15107 let mut escaped = String::with_capacity(s.len() + 4);
15108 for ch in s.chars() {
15109 if escape_backslash && ch == '\\' {
15110 escaped.push('\\');
15112 escaped.push('\\');
15113 } else if ch == '\'' {
15114 if backslash_escapes_quote {
15115 escaped.push('\\');
15117 escaped.push('\'');
15118 } else {
15119 escaped.push('\'');
15121 escaped.push('\'');
15122 }
15123 } else if supports_escape_sequences {
15124 match ch {
15127 '\n' => {
15128 escaped.push('\\');
15129 escaped.push('n');
15130 }
15131 '\r' => {
15132 escaped.push('\\');
15133 escaped.push('r');
15134 }
15135 '\t' => {
15136 escaped.push('\\');
15137 escaped.push('t');
15138 }
15139 '\x07' => {
15140 escaped.push('\\');
15141 escaped.push('a');
15142 }
15143 '\x08' => {
15144 escaped.push('\\');
15145 escaped.push('b');
15146 }
15147 '\x0C' => {
15148 escaped.push('\\');
15149 escaped.push('f');
15150 }
15151 '\x0B' => {
15152 escaped.push('\\');
15153 escaped.push('v');
15154 }
15155 _ => escaped.push(ch),
15156 }
15157 } else {
15158 escaped.push(ch);
15159 }
15160 }
15161 self.write("'");
15162 self.write(&escaped);
15163 self.write("'");
15164 }
15165 }
15166 Ok(())
15167 }
15168
15169 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
15171 use crate::dialects::DialectType;
15172
15173 match self.config.dialect {
15174 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
15176 self.write("CAST('");
15177 self.write(d);
15178 self.write("' AS DATE)");
15179 }
15180 Some(DialectType::BigQuery) => {
15183 self.write("CAST('");
15184 self.write(d);
15185 self.write("' AS DATE)");
15186 }
15187 Some(DialectType::Exasol) => {
15190 self.write("CAST('");
15191 self.write(d);
15192 self.write("' AS DATE)");
15193 }
15194 Some(DialectType::Snowflake) => {
15197 self.write("CAST('");
15198 self.write(d);
15199 self.write("' AS DATE)");
15200 }
15201 Some(DialectType::PostgreSQL)
15203 | Some(DialectType::MySQL)
15204 | Some(DialectType::SingleStore)
15205 | Some(DialectType::TiDB)
15206 | Some(DialectType::Redshift) => {
15207 self.write("CAST('");
15208 self.write(d);
15209 self.write("' AS DATE)");
15210 }
15211 Some(DialectType::DuckDB)
15213 | Some(DialectType::Presto)
15214 | Some(DialectType::Trino)
15215 | Some(DialectType::Athena)
15216 | Some(DialectType::Spark)
15217 | Some(DialectType::Databricks)
15218 | Some(DialectType::Hive) => {
15219 self.write("CAST('");
15220 self.write(d);
15221 self.write("' AS DATE)");
15222 }
15223 Some(DialectType::Oracle) => {
15225 self.write("TO_DATE('");
15226 self.write(d);
15227 self.write("', 'YYYY-MM-DD')");
15228 }
15229 _ => {
15231 self.write_keyword("DATE");
15232 self.write(" '");
15233 self.write(d);
15234 self.write("'");
15235 }
15236 }
15237 Ok(())
15238 }
15239
15240 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
15242 use crate::dialects::DialectType;
15243
15244 match self.config.dialect {
15245 Some(DialectType::TSQL) => {
15247 self.write("CAST('");
15248 self.write(t);
15249 self.write("' AS TIME)");
15250 }
15251 _ => {
15253 self.write_keyword("TIME");
15254 self.write(" '");
15255 self.write(t);
15256 self.write("'");
15257 }
15258 }
15259 Ok(())
15260 }
15261
15262 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
15264 use crate::expressions::Literal;
15265
15266 match expr {
15267 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
15268 let Literal::Date(d) = lit.as_ref() else {
15269 unreachable!()
15270 };
15271 self.write("CAST('");
15273 self.write(d);
15274 self.write("' AS DATE)");
15275 }
15276 _ => {
15277 self.generate_expression(expr)?;
15279 }
15280 }
15281 Ok(())
15282 }
15283
15284 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
15286 use crate::dialects::DialectType;
15287
15288 match self.config.dialect {
15289 Some(DialectType::TSQL) => {
15291 self.write("CAST('");
15292 self.write(ts);
15293 self.write("' AS DATETIME2)");
15294 }
15295 Some(DialectType::BigQuery) => {
15298 self.write("CAST('");
15299 self.write(ts);
15300 self.write("' AS TIMESTAMP)");
15301 }
15302 Some(DialectType::Snowflake) => {
15305 self.write("CAST('");
15306 self.write(ts);
15307 self.write("' AS TIMESTAMP)");
15308 }
15309 Some(DialectType::Dremio) => {
15312 self.write("CAST('");
15313 self.write(ts);
15314 self.write("' AS TIMESTAMP)");
15315 }
15316 Some(DialectType::Exasol) => {
15319 self.write("CAST('");
15320 self.write(ts);
15321 self.write("' AS TIMESTAMP)");
15322 }
15323 Some(DialectType::Oracle) => {
15326 self.write("TO_TIMESTAMP('");
15327 self.write(ts);
15328 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
15329 }
15330 Some(DialectType::Presto) | Some(DialectType::Trino) => {
15332 if Self::timestamp_has_timezone(ts) {
15333 self.write("CAST('");
15334 self.write(ts);
15335 self.write("' AS TIMESTAMP WITH TIME ZONE)");
15336 } else {
15337 self.write("CAST('");
15338 self.write(ts);
15339 self.write("' AS TIMESTAMP)");
15340 }
15341 }
15342 Some(DialectType::ClickHouse) => {
15344 self.write("CAST('");
15345 self.write(ts);
15346 self.write("' AS Nullable(DateTime))");
15347 }
15348 Some(DialectType::Spark) => {
15350 self.write("CAST('");
15351 self.write(ts);
15352 self.write("' AS TIMESTAMP)");
15353 }
15354 Some(DialectType::Redshift) => {
15357 if ts == "epoch" {
15358 self.write_keyword("TIMESTAMP");
15359 self.write(" '");
15360 self.write(ts);
15361 self.write("'");
15362 } else {
15363 self.write("CAST('");
15364 self.write(ts);
15365 self.write("' AS TIMESTAMP)");
15366 }
15367 }
15368 Some(DialectType::PostgreSQL)
15370 | Some(DialectType::Hive)
15371 | Some(DialectType::SQLite)
15372 | Some(DialectType::DuckDB)
15373 | Some(DialectType::Athena)
15374 | Some(DialectType::Drill)
15375 | Some(DialectType::Teradata) => {
15376 self.write("CAST('");
15377 self.write(ts);
15378 self.write("' AS TIMESTAMP)");
15379 }
15380 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
15382 self.write("CAST('");
15383 self.write(ts);
15384 self.write("' AS DATETIME)");
15385 }
15386 Some(DialectType::Databricks) => {
15388 self.write("CAST('");
15389 self.write(ts);
15390 self.write("' AS TIMESTAMP_NTZ)");
15391 }
15392 _ => {
15394 self.write_keyword("TIMESTAMP");
15395 self.write(" '");
15396 self.write(ts);
15397 self.write("'");
15398 }
15399 }
15400 Ok(())
15401 }
15402
15403 fn timestamp_has_timezone(ts: &str) -> bool {
15406 let ts_lower = ts.to_ascii_lowercase();
15410
15411 let continent_prefixes = [
15413 "africa/",
15414 "america/",
15415 "antarctica/",
15416 "arctic/",
15417 "asia/",
15418 "atlantic/",
15419 "australia/",
15420 "europe/",
15421 "indian/",
15422 "pacific/",
15423 "etc/",
15424 "brazil/",
15425 "canada/",
15426 "chile/",
15427 "mexico/",
15428 "us/",
15429 ];
15430
15431 for prefix in &continent_prefixes {
15432 if ts_lower.contains(prefix) {
15433 return true;
15434 }
15435 }
15436
15437 let tz_abbrevs = [
15440 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
15441 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
15442 " sgt", " aest", " aedt", " acst", " acdt", " awst",
15443 ];
15444
15445 for abbrev in &tz_abbrevs {
15446 if ts_lower.ends_with(abbrev) {
15447 return true;
15448 }
15449 }
15450
15451 let trimmed = ts.trim();
15455 if let Some(last_space) = trimmed.rfind(' ') {
15456 let suffix = &trimmed[last_space + 1..];
15457 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
15458 let rest = &suffix[1..];
15460 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
15461 return true;
15462 }
15463 }
15464 }
15465
15466 false
15467 }
15468
15469 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
15471 use crate::dialects::DialectType;
15472
15473 match self.config.dialect {
15474 Some(DialectType::BigQuery) => {
15477 self.write("CAST('");
15478 self.write(dt);
15479 self.write("' AS DATETIME)");
15480 }
15481 Some(DialectType::DuckDB) => {
15483 self.write("CAST('");
15484 self.write(dt);
15485 self.write("' AS TIMESTAMP)");
15486 }
15487 _ => {
15490 self.write_keyword("DATETIME");
15491 self.write(" '");
15492 self.write(dt);
15493 self.write("'");
15494 }
15495 }
15496 Ok(())
15497 }
15498
15499 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
15501 use crate::dialects::DialectType;
15502
15503 match self.config.dialect {
15504 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
15508 self.write("'");
15510 for c in s.chars() {
15511 match c {
15512 '\'' => self.write("\\'"),
15513 '\\' => self.write("\\\\"),
15514 '\n' => self.write("\\n"),
15515 '\r' => self.write("\\r"),
15516 '\t' => self.write("\\t"),
15517 '\0' => self.write("\\0"),
15518 _ => self.output.push(c),
15519 }
15520 }
15521 self.write("'");
15522 }
15523 Some(DialectType::Drill) => {
15524 self.write("'");
15527 for c in s.chars() {
15528 match c {
15529 '\'' => self.write("''"),
15530 '\\' => self.write("\\\\"),
15531 '\n' => self.write("\\n"),
15532 '\r' => self.write("\\r"),
15533 '\t' => self.write("\\t"),
15534 '\0' => self.write("\\0"),
15535 _ => self.output.push(c),
15536 }
15537 }
15538 self.write("'");
15539 }
15540 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
15541 self.write("'");
15542 for c in s.chars() {
15543 match c {
15544 '\'' => self.write("''"),
15546 '\\' => self.write("\\\\"),
15547 '\n' => self.write("\\n"),
15548 '\r' => self.write("\\r"),
15549 '\t' => self.write("\\t"),
15550 '\0' => self.output.push('\0'),
15552 _ => self.output.push(c),
15553 }
15554 }
15555 self.write("'");
15556 }
15557 Some(DialectType::BigQuery) => {
15559 self.write("'");
15560 for c in s.chars() {
15561 match c {
15562 '\'' => self.write("\\'"),
15563 '\\' => self.write("\\\\"),
15564 '\n' => self.write("\\n"),
15565 '\r' => self.write("\\r"),
15566 '\t' => self.write("\\t"),
15567 '\0' => self.write("\\0"),
15568 '\x07' => self.write("\\a"),
15569 '\x08' => self.write("\\b"),
15570 '\x0C' => self.write("\\f"),
15571 '\x0B' => self.write("\\v"),
15572 _ => self.output.push(c),
15573 }
15574 }
15575 self.write("'");
15576 }
15577 Some(DialectType::Athena) => {
15581 if self.athena_hive_context {
15582 self.write("'");
15584 for c in s.chars() {
15585 match c {
15586 '\'' => self.write("\\'"),
15587 '\\' => self.write("\\\\"),
15588 '\n' => self.write("\\n"),
15589 '\r' => self.write("\\r"),
15590 '\t' => self.write("\\t"),
15591 '\0' => self.write("\\0"),
15592 _ => self.output.push(c),
15593 }
15594 }
15595 self.write("'");
15596 } else {
15597 self.write("'");
15599 for c in s.chars() {
15600 match c {
15601 '\'' => self.write("''"),
15602 _ => self.output.push(c),
15604 }
15605 }
15606 self.write("'");
15607 }
15608 }
15609 Some(DialectType::Snowflake) => {
15614 self.write("'");
15615 for c in s.chars() {
15616 match c {
15617 '\'' => self.write("\\'"),
15618 '\n' => self.write("\\n"),
15621 '\r' => self.write("\\r"),
15622 '\t' => self.write("\\t"),
15623 _ => self.output.push(c),
15624 }
15625 }
15626 self.write("'");
15627 }
15628 Some(DialectType::PostgreSQL) => {
15630 self.write("'");
15631 for c in s.chars() {
15632 match c {
15633 '\'' => self.write("''"),
15634 _ => self.output.push(c),
15635 }
15636 }
15637 self.write("'");
15638 }
15639 Some(DialectType::Redshift) => {
15641 self.write("'");
15642 for c in s.chars() {
15643 match c {
15644 '\'' => self.write("\\'"),
15645 _ => self.output.push(c),
15646 }
15647 }
15648 self.write("'");
15649 }
15650 Some(DialectType::Oracle) => {
15652 self.write("'");
15653 for ch in s.chars() {
15654 if ch == '\'' {
15655 self.output.push_str("''");
15656 } else {
15657 self.output.push(ch);
15658 }
15659 }
15660 self.write("'");
15661 }
15662 Some(DialectType::ClickHouse) => {
15665 self.write("'");
15666 for c in s.chars() {
15667 match c {
15668 '\'' => self.write("''"),
15669 '\\' => self.write("\\\\"),
15670 '\n' => self.write("\\n"),
15671 '\r' => self.write("\\r"),
15672 '\t' => self.write("\\t"),
15673 '\0' => self.write("\\0"),
15674 '\x07' => self.write("\\a"),
15675 '\x08' => self.write("\\b"),
15676 '\x0C' => self.write("\\f"),
15677 '\x0B' => self.write("\\v"),
15678 c if c.is_control() || (c as u32) < 0x20 => {
15680 let byte = c as u32;
15681 if byte < 256 {
15682 self.write(&format!("\\x{:02X}", byte));
15683 } else {
15684 self.output.push(c);
15685 }
15686 }
15687 _ => self.output.push(c),
15688 }
15689 }
15690 self.write("'");
15691 }
15692 _ => {
15695 self.write("'");
15696 for ch in s.chars() {
15697 if ch == '\'' {
15698 self.output.push_str("''");
15699 } else {
15700 self.output.push(ch);
15701 }
15702 }
15703 self.write("'");
15704 }
15705 }
15706 Ok(())
15707 }
15708
15709 fn write_escaped_byte_string(&mut self, s: &str) {
15712 for c in s.chars() {
15713 match c {
15714 '\'' => self.write("\\'"),
15716 '\\' => self.write("\\\\"),
15718 _ if !c.is_control() => self.output.push(c),
15720 _ => {
15722 let byte = c as u32;
15723 if byte < 256 {
15724 self.write(&format!("\\x{:02x}", byte));
15725 } else {
15726 for b in c.to_string().as_bytes() {
15728 self.write(&format!("\\x{:02x}", b));
15729 }
15730 }
15731 }
15732 }
15733 }
15734 }
15735
15736 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
15737 use crate::dialects::DialectType;
15738
15739 match self.config.dialect {
15741 Some(DialectType::TSQL) => {
15744 self.write(if b.value { "1" } else { "0" });
15745 }
15746 Some(DialectType::Oracle) => {
15748 self.write(if b.value { "1" } else { "0" });
15749 }
15750 Some(DialectType::MySQL) => {
15752 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15753 }
15754 _ => {
15756 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15757 }
15758 }
15759 Ok(())
15760 }
15761
15762 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
15765 let name = &id.name;
15766 let quote_style = &self.config.identifier_quote_style;
15767
15768 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
15772
15773 let output_name = if self.config.normalize_identifiers && !id.quoted {
15775 name.to_ascii_lowercase()
15776 } else {
15777 name.to_string()
15778 };
15779
15780 if needs_quoting {
15781 let quote_style = if matches!(self.config.dialect, Some(DialectType::ClickHouse))
15782 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
15783 && quote_style.start == '"'
15784 && output_name.contains('"')
15785 {
15786 &IdentifierQuoteStyle::BACKTICK
15787 } else {
15788 quote_style
15789 };
15790 let escaped_name = if quote_style.start == quote_style.end {
15792 output_name.replace(
15793 quote_style.end,
15794 &format!("{}{}", quote_style.end, quote_style.end),
15795 )
15796 } else {
15797 output_name.replace(
15798 quote_style.end,
15799 &format!("{}{}", quote_style.end, quote_style.end),
15800 )
15801 };
15802 self.write(&format!(
15803 "{}{}{}",
15804 quote_style.start, escaped_name, quote_style.end
15805 ));
15806 } else {
15807 self.write(&output_name);
15808 }
15809
15810 for comment in &id.trailing_comments {
15812 self.write(" ");
15813 self.write_formatted_comment(comment);
15814 }
15815 Ok(())
15816 }
15817
15818 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
15819 use crate::dialects::DialectType;
15820
15821 let name = &id.name;
15822
15823 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
15825 && self.athena_hive_context
15826 {
15827 &IdentifierQuoteStyle::BACKTICK
15828 } else {
15829 &self.config.identifier_quote_style
15830 };
15831
15832 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
15839 let needs_digit_quoting = starts_with_digit
15840 && !self.config.identifiers_can_start_with_digit
15841 && self.config.dialect.is_some();
15842 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
15843 && name.len() > 2
15844 && (name.starts_with("0x") || name.starts_with("0X"))
15845 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
15846 let clickhouse_unsafe_identifier =
15847 matches!(self.config.dialect, Some(DialectType::ClickHouse))
15848 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
15849 && !name.starts_with('{')
15850 && !name.contains('(')
15851 && !name.contains(')')
15852 && name != "?"
15853 && name
15854 .chars()
15855 .any(|c| !(c.is_ascii_alphanumeric() || c == '_'));
15856 let needs_quoting = id.quoted
15857 || self.is_reserved_keyword(name)
15858 || self.config.always_quote_identifiers
15859 || needs_digit_quoting
15860 || mysql_invalid_hex_identifier
15861 || clickhouse_unsafe_identifier;
15862
15863 let (base_name, suffix) = if needs_quoting {
15866 if let Some(paren_pos) = name.find('(') {
15868 let base = &name[..paren_pos];
15869 let rest = &name[paren_pos..];
15870 if rest.starts_with('(')
15872 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
15873 {
15874 let close_paren = rest.find(')').unwrap_or(rest.len());
15876 let inside = &rest[1..close_paren];
15877 if inside.chars().all(|c| c.is_ascii_digit()) {
15878 (base.to_string(), rest.to_string())
15879 } else {
15880 (name.to_string(), String::new())
15881 }
15882 } else {
15883 (name.to_string(), String::new())
15884 }
15885 } else if name.ends_with(" ASC") {
15886 let base = &name[..name.len() - 4];
15887 (base.to_string(), " ASC".to_string())
15888 } else if name.ends_with(" DESC") {
15889 let base = &name[..name.len() - 5];
15890 (base.to_string(), " DESC".to_string())
15891 } else {
15892 (name.to_string(), String::new())
15893 }
15894 } else {
15895 (name.to_string(), String::new())
15896 };
15897
15898 let output_name = if self.config.normalize_identifiers && !id.quoted {
15902 base_name.to_ascii_lowercase()
15903 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
15904 && !id.quoted
15905 && self.is_reserved_keyword(name)
15906 {
15907 base_name.to_ascii_uppercase()
15910 } else {
15911 base_name
15912 };
15913
15914 if needs_quoting {
15915 let escaped_name = if quote_style.start == quote_style.end {
15917 output_name.replace(
15919 quote_style.end,
15920 &format!("{}{}", quote_style.end, quote_style.end),
15921 )
15922 } else {
15923 output_name.replace(
15925 quote_style.end,
15926 &format!("{}{}", quote_style.end, quote_style.end),
15927 )
15928 };
15929 self.write(&format!(
15930 "{}{}{}{}",
15931 quote_style.start, escaped_name, quote_style.end, suffix
15932 ));
15933 } else {
15934 self.write(&output_name);
15935 }
15936
15937 for comment in &id.trailing_comments {
15939 self.write(" ");
15940 self.write_formatted_comment(comment);
15941 }
15942 Ok(())
15943 }
15944
15945 fn generate_column(&mut self, col: &Column) -> Result<()> {
15946 use crate::dialects::DialectType;
15947
15948 if let Some(table) = &col.table {
15949 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
15953 && !table.quoted
15954 && table.name.eq_ignore_ascii_case("LOCAL");
15955
15956 if is_exasol_local_prefix {
15957 self.write("LOCAL");
15959 } else {
15960 self.generate_identifier(table)?;
15961 }
15962 self.write(".");
15963 }
15964 self.generate_identifier(&col.name)?;
15965 if col.join_mark && self.config.supports_column_join_marks {
15968 self.write(" (+)");
15969 }
15970 for comment in &col.trailing_comments {
15972 self.write_space();
15973 self.write_formatted_comment(comment);
15974 }
15975 Ok(())
15976 }
15977
15978 fn generate_prepare(&mut self, prepare: &PrepareStatement) -> Result<()> {
15979 self.write_keyword("PREPARE");
15980 self.write_space();
15981 self.generate_identifier(&prepare.name)?;
15982
15983 if !prepare.parameter_types.is_empty() {
15984 self.write(" (");
15985 for (i, data_type) in prepare.parameter_types.iter().enumerate() {
15986 if i > 0 {
15987 self.write(", ");
15988 }
15989 self.generate_data_type(data_type)?;
15990 }
15991 self.write(")");
15992 }
15993
15994 self.write_space();
15995 self.write_keyword("AS");
15996 self.write_space();
15997 self.generate_expression(&prepare.statement)
15998 }
15999
16000 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
16003 use crate::dialects::DialectType;
16004 use crate::expressions::PseudocolumnType;
16005
16006 if pc.kind == PseudocolumnType::Sysdate
16008 && !matches!(
16009 self.config.dialect,
16010 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
16011 )
16012 {
16013 self.write_keyword("CURRENT_TIMESTAMP");
16014 if matches!(
16016 self.config.dialect,
16017 Some(DialectType::MySQL)
16018 | Some(DialectType::ClickHouse)
16019 | Some(DialectType::Spark)
16020 | Some(DialectType::Databricks)
16021 | Some(DialectType::Hive)
16022 ) {
16023 self.write("()");
16024 }
16025 } else {
16026 self.write(pc.kind.as_str());
16027 }
16028 Ok(())
16029 }
16030
16031 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
16033 use crate::dialects::DialectType;
16034
16035 let supports_connect_by = matches!(
16038 self.config.dialect,
16039 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
16040 );
16041
16042 if !supports_connect_by && self.config.dialect.is_some() {
16043 if self.config.pretty {
16045 self.write_newline();
16046 } else {
16047 self.write_space();
16048 }
16049 self.write_unsupported_comment(
16050 "CONNECT BY requires manual conversion to recursive CTE",
16051 )?;
16052 }
16053
16054 if let Some(start) = &connect.start {
16056 if self.config.pretty {
16057 self.write_newline();
16058 } else {
16059 self.write_space();
16060 }
16061 self.write_keyword("START WITH");
16062 self.write_space();
16063 self.generate_expression(start)?;
16064 }
16065
16066 if self.config.pretty {
16068 self.write_newline();
16069 } else {
16070 self.write_space();
16071 }
16072 self.write_keyword("CONNECT BY");
16073 if connect.nocycle {
16074 self.write_space();
16075 self.write_keyword("NOCYCLE");
16076 }
16077 self.write_space();
16078 self.generate_expression(&connect.connect)?;
16079
16080 Ok(())
16081 }
16082
16083 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
16085 self.generate_connect(connect)
16086 }
16087
16088 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
16090 self.write_keyword("PRIOR");
16091 self.write_space();
16092 self.generate_expression(&prior.this)?;
16093 Ok(())
16094 }
16095
16096 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
16099 self.write_keyword("CONNECT_BY_ROOT");
16100 self.write_space();
16101 self.generate_expression(&cbr.this)?;
16102 Ok(())
16103 }
16104
16105 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
16107 use crate::dialects::DialectType;
16108
16109 let supports_match_recognize = matches!(
16111 self.config.dialect,
16112 Some(DialectType::Oracle)
16113 | Some(DialectType::Snowflake)
16114 | Some(DialectType::Presto)
16115 | Some(DialectType::Trino)
16116 );
16117
16118 if let Some(source) = &mr.this {
16120 self.generate_expression(source)?;
16121 }
16122
16123 if !supports_match_recognize {
16124 self.write_unsupported_comment("MATCH_RECOGNIZE not supported in this dialect")?;
16125 return Ok(());
16126 }
16127
16128 if self.config.pretty {
16130 self.write_newline();
16131 } else {
16132 self.write_space();
16133 }
16134
16135 self.write_keyword("MATCH_RECOGNIZE");
16136 self.write(" (");
16137
16138 if self.config.pretty {
16139 self.indent_level += 1;
16140 }
16141
16142 let mut needs_separator = false;
16143
16144 if let Some(partition_by) = &mr.partition_by {
16146 if !partition_by.is_empty() {
16147 if self.config.pretty {
16148 self.write_newline();
16149 self.write_indent();
16150 }
16151 self.write_keyword("PARTITION BY");
16152 self.write_space();
16153 for (i, expr) in partition_by.iter().enumerate() {
16154 if i > 0 {
16155 self.write(", ");
16156 }
16157 self.generate_expression(expr)?;
16158 }
16159 needs_separator = true;
16160 }
16161 }
16162
16163 if let Some(order_by) = &mr.order_by {
16165 if !order_by.is_empty() {
16166 if needs_separator {
16167 if self.config.pretty {
16168 self.write_newline();
16169 self.write_indent();
16170 } else {
16171 self.write_space();
16172 }
16173 } else if self.config.pretty {
16174 self.write_newline();
16175 self.write_indent();
16176 }
16177 self.write_keyword("ORDER BY");
16178 if self.config.pretty {
16180 self.indent_level += 1;
16181 for (i, ordered) in order_by.iter().enumerate() {
16182 if i > 0 {
16183 self.write(",");
16184 }
16185 self.write_newline();
16186 self.write_indent();
16187 self.generate_ordered(ordered)?;
16188 }
16189 self.indent_level -= 1;
16190 } else {
16191 self.write_space();
16192 for (i, ordered) in order_by.iter().enumerate() {
16193 if i > 0 {
16194 self.write(", ");
16195 }
16196 self.generate_ordered(ordered)?;
16197 }
16198 }
16199 needs_separator = true;
16200 }
16201 }
16202
16203 if let Some(measures) = &mr.measures {
16205 if !measures.is_empty() {
16206 if needs_separator {
16207 if self.config.pretty {
16208 self.write_newline();
16209 self.write_indent();
16210 } else {
16211 self.write_space();
16212 }
16213 } else if self.config.pretty {
16214 self.write_newline();
16215 self.write_indent();
16216 }
16217 self.write_keyword("MEASURES");
16218 if self.config.pretty {
16220 self.indent_level += 1;
16221 for (i, measure) in measures.iter().enumerate() {
16222 if i > 0 {
16223 self.write(",");
16224 }
16225 self.write_newline();
16226 self.write_indent();
16227 if let Some(semantics) = &measure.window_frame {
16229 match semantics {
16230 MatchRecognizeSemantics::Running => {
16231 self.write_keyword("RUNNING");
16232 self.write_space();
16233 }
16234 MatchRecognizeSemantics::Final => {
16235 self.write_keyword("FINAL");
16236 self.write_space();
16237 }
16238 }
16239 }
16240 self.generate_expression(&measure.this)?;
16241 }
16242 self.indent_level -= 1;
16243 } else {
16244 self.write_space();
16245 for (i, measure) in measures.iter().enumerate() {
16246 if i > 0 {
16247 self.write(", ");
16248 }
16249 if let Some(semantics) = &measure.window_frame {
16251 match semantics {
16252 MatchRecognizeSemantics::Running => {
16253 self.write_keyword("RUNNING");
16254 self.write_space();
16255 }
16256 MatchRecognizeSemantics::Final => {
16257 self.write_keyword("FINAL");
16258 self.write_space();
16259 }
16260 }
16261 }
16262 self.generate_expression(&measure.this)?;
16263 }
16264 }
16265 needs_separator = true;
16266 }
16267 }
16268
16269 if let Some(rows) = &mr.rows {
16271 if needs_separator {
16272 if self.config.pretty {
16273 self.write_newline();
16274 self.write_indent();
16275 } else {
16276 self.write_space();
16277 }
16278 } else if self.config.pretty {
16279 self.write_newline();
16280 self.write_indent();
16281 }
16282 match rows {
16283 MatchRecognizeRows::OneRowPerMatch => {
16284 self.write_keyword("ONE ROW PER MATCH");
16285 }
16286 MatchRecognizeRows::AllRowsPerMatch => {
16287 self.write_keyword("ALL ROWS PER MATCH");
16288 }
16289 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
16290 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
16291 }
16292 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
16293 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
16294 }
16295 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
16296 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
16297 }
16298 }
16299 needs_separator = true;
16300 }
16301
16302 if let Some(after) = &mr.after {
16304 if needs_separator {
16305 if self.config.pretty {
16306 self.write_newline();
16307 self.write_indent();
16308 } else {
16309 self.write_space();
16310 }
16311 } else if self.config.pretty {
16312 self.write_newline();
16313 self.write_indent();
16314 }
16315 match after {
16316 MatchRecognizeAfter::PastLastRow => {
16317 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
16318 }
16319 MatchRecognizeAfter::ToNextRow => {
16320 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
16321 }
16322 MatchRecognizeAfter::ToFirst(ident) => {
16323 self.write_keyword("AFTER MATCH SKIP TO FIRST");
16324 self.write_space();
16325 self.generate_identifier(ident)?;
16326 }
16327 MatchRecognizeAfter::ToLast(ident) => {
16328 self.write_keyword("AFTER MATCH SKIP TO LAST");
16329 self.write_space();
16330 self.generate_identifier(ident)?;
16331 }
16332 }
16333 needs_separator = true;
16334 }
16335
16336 if let Some(pattern) = &mr.pattern {
16338 if needs_separator {
16339 if self.config.pretty {
16340 self.write_newline();
16341 self.write_indent();
16342 } else {
16343 self.write_space();
16344 }
16345 } else if self.config.pretty {
16346 self.write_newline();
16347 self.write_indent();
16348 }
16349 self.write_keyword("PATTERN");
16350 self.write_space();
16351 self.write("(");
16352 self.write(pattern);
16353 self.write(")");
16354 needs_separator = true;
16355 }
16356
16357 if let Some(define) = &mr.define {
16359 if !define.is_empty() {
16360 if needs_separator {
16361 if self.config.pretty {
16362 self.write_newline();
16363 self.write_indent();
16364 } else {
16365 self.write_space();
16366 }
16367 } else if self.config.pretty {
16368 self.write_newline();
16369 self.write_indent();
16370 }
16371 self.write_keyword("DEFINE");
16372 if self.config.pretty {
16374 self.indent_level += 1;
16375 for (i, (name, expr)) in define.iter().enumerate() {
16376 if i > 0 {
16377 self.write(",");
16378 }
16379 self.write_newline();
16380 self.write_indent();
16381 self.generate_identifier(name)?;
16382 self.write(" AS ");
16383 self.generate_expression(expr)?;
16384 }
16385 self.indent_level -= 1;
16386 } else {
16387 self.write_space();
16388 for (i, (name, expr)) in define.iter().enumerate() {
16389 if i > 0 {
16390 self.write(", ");
16391 }
16392 self.generate_identifier(name)?;
16393 self.write(" AS ");
16394 self.generate_expression(expr)?;
16395 }
16396 }
16397 }
16398 }
16399
16400 if self.config.pretty {
16401 self.indent_level -= 1;
16402 self.write_newline();
16403 }
16404 self.write(")");
16405
16406 if let Some(alias) = &mr.alias {
16408 self.write(" ");
16409 if mr.alias_explicit_as {
16410 self.write_keyword("AS");
16411 self.write(" ");
16412 }
16413 self.generate_identifier(alias)?;
16414 }
16415
16416 Ok(())
16417 }
16418
16419 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
16421 use crate::dialects::DialectType;
16422
16423 let supports_hints = matches!(
16425 self.config.dialect,
16426 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
16428 Some(DialectType::Spark) | Some(DialectType::Hive) |
16429 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
16430 );
16431
16432 if !supports_hints || hint.expressions.is_empty() {
16433 return Ok(());
16434 }
16435
16436 let mut hint_strings: Vec<String> = Vec::new();
16439 for expr in &hint.expressions {
16440 match expr {
16441 HintExpression::Raw(text) => {
16442 let parsed = self.parse_raw_hint_text(text);
16444 hint_strings.extend(parsed);
16445 }
16446 _ => {
16447 hint_strings.push(self.hint_expression_to_string(expr)?);
16448 }
16449 }
16450 }
16451
16452 let use_multiline = self.config.pretty && hint_strings.len() > 1;
16456
16457 if use_multiline {
16458 self.write(" /*+ ");
16460 for (i, hint_str) in hint_strings.iter().enumerate() {
16461 if i > 0 {
16462 self.write_newline();
16463 self.write(" "); }
16465 self.write(hint_str);
16466 }
16467 self.write(" */");
16468 } else {
16469 self.write(" /*+ ");
16471 let sep = match self.config.dialect {
16472 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
16473 _ => " ",
16474 };
16475 for (i, hint_str) in hint_strings.iter().enumerate() {
16476 if i > 0 {
16477 self.write(sep);
16478 }
16479 self.write(hint_str);
16480 }
16481 self.write(" */");
16482 }
16483
16484 Ok(())
16485 }
16486
16487 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
16491 let mut results = Vec::new();
16492 let mut chars = text.chars().peekable();
16493 let mut current = String::new();
16494 let mut paren_depth = 0;
16495 let mut has_unparseable_content = false;
16496 let mut position_after_last_function = 0;
16497 let mut char_position = 0;
16498
16499 while let Some(c) = chars.next() {
16500 char_position += c.len_utf8();
16501 match c {
16502 '(' => {
16503 paren_depth += 1;
16504 current.push(c);
16505 }
16506 ')' => {
16507 paren_depth -= 1;
16508 current.push(c);
16509 if paren_depth == 0 {
16511 let trimmed = current.trim().to_string();
16512 if !trimmed.is_empty() {
16513 let formatted = self.format_hint_function(&trimmed);
16515 results.push(formatted);
16516 }
16517 current.clear();
16518 position_after_last_function = char_position;
16519 }
16520 }
16521 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
16522 }
16524 _ if paren_depth == 0 => {
16525 current.push(c);
16527 }
16528 _ => {
16529 current.push(c);
16530 }
16531 }
16532 }
16533
16534 let remaining_text = text[position_after_last_function..].trim();
16536 if !remaining_text.is_empty() {
16537 let words: Vec<&str> = remaining_text.split_whitespace().collect();
16541 let looks_like_hint_functions = words.iter().all(|word| {
16542 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
16544 });
16545
16546 if !looks_like_hint_functions && words.len() > 1 {
16547 has_unparseable_content = true;
16548 }
16549 }
16550
16551 if has_unparseable_content {
16553 return vec![text.trim().to_string()];
16554 }
16555
16556 if results.is_empty() {
16558 results.push(text.trim().to_string());
16559 }
16560
16561 results
16562 }
16563
16564 fn format_hint_function(&self, hint: &str) -> String {
16567 if !self.config.pretty {
16568 return hint.to_string();
16569 }
16570
16571 if let Some(paren_pos) = hint.find('(') {
16573 if hint.ends_with(')') {
16574 let name = &hint[..paren_pos];
16575 let args_str = &hint[paren_pos + 1..hint.len() - 1];
16576
16577 let args: Vec<&str> = args_str.split_whitespace().collect();
16579
16580 let total_args_width: usize =
16582 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() {
16586 let mut result = format!("{}(\n", name);
16587 for arg in &args {
16588 result.push_str(" "); result.push_str(arg);
16590 result.push('\n');
16591 }
16592 result.push_str(" )"); return result;
16594 }
16595 }
16596 }
16597
16598 hint.to_string()
16599 }
16600
16601 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
16603 match expr {
16604 HintExpression::Function { name, args } => {
16605 let arg_strings: Vec<String> = args
16607 .iter()
16608 .map(|arg| {
16609 let mut gen = Generator::with_arc_config(self.config.clone());
16610 gen.generate_expression(arg)?;
16611 Ok(gen.output)
16612 })
16613 .collect::<Result<Vec<_>>>()?;
16614
16615 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
16617 + arg_strings.len().saturating_sub(1); let args_multiline =
16622 self.config.pretty && total_args_width > self.config.max_text_width;
16623
16624 if args_multiline && !arg_strings.is_empty() {
16625 let mut result = format!("{}(\n", name);
16627 for arg_str in &arg_strings {
16628 result.push_str(" "); result.push_str(arg_str);
16630 result.push('\n');
16631 }
16632 result.push_str(" )"); Ok(result)
16634 } else {
16635 let args_str = arg_strings.join(" ");
16637 Ok(format!("{}({})", name, args_str))
16638 }
16639 }
16640 HintExpression::Identifier(name) => Ok(name.clone()),
16641 HintExpression::Raw(text) => {
16642 if self.config.pretty {
16644 Ok(self.format_hint_function(text))
16645 } else {
16646 Ok(text.clone())
16647 }
16648 }
16649 }
16650 }
16651
16652 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
16653 if table.only {
16655 self.write_keyword("ONLY");
16656 self.write_space();
16657 }
16658
16659 if let Some(ref identifier_func) = table.identifier_func {
16661 self.generate_expression(identifier_func)?;
16662 if !table.name.name.is_empty() {
16664 if let Some(catalog) = &table.catalog {
16665 self.write(".");
16666 self.generate_identifier(catalog)?;
16667 }
16668 if let Some(schema) = &table.schema {
16669 self.write(".");
16670 self.generate_identifier(schema)?;
16671 }
16672 self.write(".");
16673 self.generate_identifier(&table.name)?;
16674 }
16675 } else {
16676 if let Some(catalog) = &table.catalog {
16677 self.generate_identifier(catalog)?;
16678 self.write(".");
16679 }
16680 if let Some(schema) = &table.schema {
16681 self.generate_identifier(schema)?;
16682 self.write(".");
16683 }
16684 self.generate_identifier(&table.name)?;
16685 }
16686
16687 if let Some(changes) = &table.changes {
16689 self.write(" ");
16690 self.generate_changes(changes)?;
16691 }
16692
16693 if !table.partitions.is_empty() {
16695 self.write_space();
16696 self.write_keyword("PARTITION");
16697 self.write("(");
16698 for (i, partition) in table.partitions.iter().enumerate() {
16699 if i > 0 {
16700 self.write(", ");
16701 }
16702 self.generate_identifier(partition)?;
16703 }
16704 self.write(")");
16705 }
16706
16707 if table.changes.is_none() {
16710 if let Some(when) = &table.when {
16711 self.write_space();
16712 self.generate_historical_data(when)?;
16713 }
16714 }
16715
16716 let system_time_post_alias = matches!(self.config.dialect, Some(DialectType::BigQuery));
16718 if !system_time_post_alias {
16719 if let Some(ref system_time) = table.system_time {
16720 self.write_space();
16721 self.write(system_time);
16722 }
16723 }
16724
16725 if let Some(ref version) = table.version {
16727 self.write_space();
16728 self.generate_version(version)?;
16729 }
16730
16731 let alias_post_tablesample = self.config.alias_post_tablesample;
16735
16736 if alias_post_tablesample {
16737 self.generate_table_sample_clause(table)?;
16739 }
16740
16741 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
16744 && table.hints.iter().any(|h| {
16745 if let Expression::Identifier(id) = h {
16746 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
16747 } else {
16748 false
16749 }
16750 });
16751 if !table.hints.is_empty() && !is_sqlite_hint {
16752 for hint in &table.hints {
16753 self.write_space();
16754 self.generate_expression(hint)?;
16755 }
16756 }
16757
16758 if let Some(alias) = &table.alias {
16759 self.write_space();
16760 let always_use_as = self.config.dialect.is_none()
16763 || matches!(
16764 self.config.dialect,
16765 Some(DialectType::Generic)
16766 | Some(DialectType::PostgreSQL)
16767 | Some(DialectType::Redshift)
16768 | Some(DialectType::Snowflake)
16769 | Some(DialectType::BigQuery)
16770 | Some(DialectType::DuckDB)
16771 | Some(DialectType::Presto)
16772 | Some(DialectType::Trino)
16773 | Some(DialectType::TSQL)
16774 | Some(DialectType::Fabric)
16775 | Some(DialectType::MySQL)
16776 | Some(DialectType::Spark)
16777 | Some(DialectType::Hive)
16778 | Some(DialectType::SQLite)
16779 | Some(DialectType::Drill)
16780 );
16781 let is_stage_ref = table.name.name.starts_with('@');
16782 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
16784 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
16785 self.write_keyword("AS");
16786 self.write_space();
16787 }
16788 self.generate_identifier(alias)?;
16789
16790 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
16793 self.write("(");
16794 for (i, col_alias) in table.column_aliases.iter().enumerate() {
16795 if i > 0 {
16796 self.write(", ");
16797 }
16798 self.generate_identifier(col_alias)?;
16799 }
16800 self.write(")");
16801 }
16802 }
16803
16804 if system_time_post_alias {
16806 if let Some(ref system_time) = table.system_time {
16807 self.write_space();
16808 self.write(system_time);
16809 }
16810 }
16811
16812 if !alias_post_tablesample {
16814 self.generate_table_sample_clause(table)?;
16815 }
16816
16817 if is_sqlite_hint {
16819 for hint in &table.hints {
16820 self.write_space();
16821 self.generate_expression(hint)?;
16822 }
16823 }
16824
16825 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
16827 self.write_space();
16828 self.write_keyword("FINAL");
16829 }
16830
16831 for comment in &table.trailing_comments {
16833 self.write_space();
16834 self.write_formatted_comment(comment);
16835 }
16836 Ok(())
16840 }
16841
16842 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
16844 if let Some(ref ts) = table.table_sample {
16845 self.write_space();
16846 if ts.is_using_sample {
16847 self.write_keyword("USING SAMPLE");
16848 } else {
16849 self.write_keyword(self.config.tablesample_keywords);
16851 }
16852 self.generate_sample_body(ts)?;
16853 if let Some(ref seed) = ts.seed {
16855 self.write_space();
16856 self.write_keyword(self.config.tablesample_seed_keyword);
16857 self.write(" (");
16858 self.generate_expression(seed)?;
16859 self.write(")");
16860 }
16861 }
16862 Ok(())
16863 }
16864
16865 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
16866 if sr.quoted {
16870 self.write("'");
16871 }
16872
16873 self.write(&sr.name);
16874 if let Some(path) = &sr.path {
16875 self.write(path);
16876 }
16877
16878 if sr.quoted {
16879 self.write("'");
16880 }
16881
16882 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
16884 if has_options {
16885 self.write(" (");
16886 let mut first = true;
16887
16888 if let Some(file_format) = &sr.file_format {
16889 if !first {
16890 self.write(", ");
16891 }
16892 self.write_keyword("FILE_FORMAT");
16893 self.write(" => ");
16894 self.generate_expression(file_format)?;
16895 first = false;
16896 }
16897
16898 if let Some(pattern) = &sr.pattern {
16899 if !first {
16900 self.write(", ");
16901 }
16902 self.write_keyword("PATTERN");
16903 self.write(" => '");
16904 self.write(pattern);
16905 self.write("'");
16906 }
16907
16908 self.write(")");
16909 }
16910 Ok(())
16911 }
16912
16913 fn generate_star(&mut self, star: &Star) -> Result<()> {
16914 use crate::dialects::DialectType;
16915
16916 if let Some(table) = &star.table {
16917 self.generate_identifier(table)?;
16918 self.write(".");
16919 }
16920 self.write("*");
16921
16922 if let Some(except) = &star.except {
16924 if !except.is_empty() {
16925 self.write_space();
16926 match self.config.dialect {
16928 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
16929 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
16930 self.write_keyword("EXCLUDE")
16931 }
16932 _ => self.write_keyword("EXCEPT"), }
16934 self.write(" (");
16935 for (i, col) in except.iter().enumerate() {
16936 if i > 0 {
16937 self.write(", ");
16938 }
16939 self.generate_identifier(col)?;
16940 }
16941 self.write(")");
16942 }
16943 }
16944
16945 if let Some(replace) = &star.replace {
16947 if !replace.is_empty() {
16948 self.write_space();
16949 self.write_keyword("REPLACE");
16950 self.write(" (");
16951 for (i, alias) in replace.iter().enumerate() {
16952 if i > 0 {
16953 self.write(", ");
16954 }
16955 self.generate_expression(&alias.this)?;
16956 self.write_space();
16957 self.write_keyword("AS");
16958 self.write_space();
16959 self.generate_identifier(&alias.alias)?;
16960 }
16961 self.write(")");
16962 }
16963 }
16964
16965 if let Some(rename) = &star.rename {
16967 if !rename.is_empty() {
16968 self.write_space();
16969 self.write_keyword("RENAME");
16970 self.write(" (");
16971 for (i, (old_name, new_name)) in rename.iter().enumerate() {
16972 if i > 0 {
16973 self.write(", ");
16974 }
16975 self.generate_identifier(old_name)?;
16976 self.write_space();
16977 self.write_keyword("AS");
16978 self.write_space();
16979 self.generate_identifier(new_name)?;
16980 }
16981 self.write(")");
16982 }
16983 }
16984
16985 for comment in &star.trailing_comments {
16987 self.write_space();
16988 self.write_formatted_comment(comment);
16989 }
16990
16991 Ok(())
16992 }
16993
16994 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
16996 self.write("{");
16997 match expr {
16998 Expression::Star(star) => {
16999 self.generate_star(star)?;
17001 }
17002 Expression::ILike(ilike) => {
17003 self.generate_expression(&ilike.left)?;
17005 self.write_space();
17006 self.write_keyword("ILIKE");
17007 self.write_space();
17008 self.generate_expression(&ilike.right)?;
17009 }
17010 _ => {
17011 self.generate_expression(expr)?;
17012 }
17013 }
17014 self.write("}");
17015 Ok(())
17016 }
17017
17018 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
17019 match &alias.this {
17023 Expression::Column(col) => {
17024 if let Some(table) = &col.table {
17026 self.generate_identifier(table)?;
17027 self.write(".");
17028 }
17029 self.generate_identifier(&col.name)?;
17030 }
17031 _ => {
17032 self.generate_expression(&alias.this)?;
17033 }
17034 }
17035
17036 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
17040 for comment in &alias.pre_alias_comments {
17041 self.write_space();
17042 self.write_formatted_comment(comment);
17043 }
17044 }
17045
17046 use crate::dialects::DialectType;
17047
17048 let is_table_source = matches!(
17054 &alias.this,
17055 Expression::JSONTable(_)
17056 | Expression::XMLTable(_)
17057 | Expression::TableFromRows(_)
17058 | Expression::Unnest(_)
17059 | Expression::MatchRecognize(_)
17060 | Expression::Select(_)
17061 | Expression::Subquery(_)
17062 | Expression::Paren(_)
17063 );
17064 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
17065 let skip_as = is_table_source && dialect_skips_table_alias_as;
17066
17067 self.write_space();
17068 if !skip_as {
17069 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
17070 if let Some(ref alias_keyword) = alias.alias_keyword {
17071 self.write(alias_keyword);
17072 } else {
17073 self.write_keyword("AS");
17074 }
17075 } else {
17076 self.write_keyword("AS");
17077 }
17078 self.write_space();
17079 }
17080
17081 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
17083
17084 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
17086 self.write("(");
17088 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
17089 if i > 0 {
17090 self.write(", ");
17091 }
17092 self.generate_alias_identifier(col_alias)?;
17093 }
17094 self.write(")");
17095 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
17096 self.generate_alias_identifier(&alias.alias)?;
17098 self.write("(");
17099 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
17100 if i > 0 {
17101 self.write(", ");
17102 }
17103 self.generate_alias_identifier(col_alias)?;
17104 }
17105 self.write(")");
17106 } else {
17107 self.generate_alias_identifier(&alias.alias)?;
17109 }
17110
17111 for comment in &alias.trailing_comments {
17113 self.write_space();
17114 self.write_formatted_comment(comment);
17115 }
17116
17117 if alias.trailing_comments.is_empty() {
17122 for comment in &alias.pre_alias_comments {
17123 self.write_space();
17124 self.write_formatted_comment(comment);
17125 }
17126 }
17127
17128 Ok(())
17129 }
17130
17131 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
17132 use crate::dialects::DialectType;
17133
17134 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
17136 self.generate_expression(&cast.this)?;
17137 self.write(" :> ");
17138 self.generate_data_type(&cast.to)?;
17139 return Ok(());
17140 }
17141
17142 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
17144 let is_unknown_type = matches!(cast.to, DataType::Unknown)
17145 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
17146 if is_unknown_type {
17147 if let Some(format) = &cast.format {
17148 self.write_keyword("CAST");
17149 self.write("(");
17150 self.generate_expression(&cast.this)?;
17151 self.write_space();
17152 self.write_keyword("AS");
17153 self.write_space();
17154 self.write_keyword("FORMAT");
17155 self.write_space();
17156 self.generate_expression(format)?;
17157 self.write(")");
17158 return Ok(());
17159 }
17160 }
17161 }
17162
17163 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
17166 if let Some(format) = &cast.format {
17167 let is_date = matches!(cast.to, DataType::Date);
17169 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
17170
17171 if is_date || is_timestamp {
17172 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
17173 self.write_keyword(func_name);
17174 self.write("(");
17175 self.generate_expression(&cast.this)?;
17176 self.write(", ");
17177
17178 if let Expression::Literal(lit) = format.as_ref() {
17181 if let Literal::String(fmt_str) = lit.as_ref() {
17182 let normalized = self.normalize_oracle_format(fmt_str);
17183 self.write("'");
17184 self.write(&normalized);
17185 self.write("'");
17186 }
17187 } else {
17188 self.generate_expression(format)?;
17189 }
17190
17191 self.write(")");
17192 return Ok(());
17193 }
17194 }
17195 }
17196
17197 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
17200 if let Expression::Array(arr) = &cast.this {
17201 self.generate_data_type(&cast.to)?;
17202 self.write("[");
17204 for (i, expr) in arr.expressions.iter().enumerate() {
17205 if i > 0 {
17206 self.write(", ");
17207 }
17208 self.generate_expression(expr)?;
17209 }
17210 self.write("]");
17211 return Ok(());
17212 }
17213 if matches!(&cast.this, Expression::ArrayFunc(_)) {
17214 self.generate_data_type(&cast.to)?;
17215 self.generate_expression(&cast.this)?;
17216 return Ok(());
17217 }
17218 }
17219
17220 if matches!(
17223 self.config.dialect,
17224 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
17225 ) {
17226 if let Expression::Struct(ref s) = cast.this {
17227 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
17228 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
17229 self.write_keyword("CAST");
17230 self.write("(");
17231 self.generate_struct_as_row(s)?;
17232 self.write_space();
17233 self.write_keyword("AS");
17234 self.write_space();
17235 self.generate_data_type(&cast.to)?;
17236 self.write(")");
17237 return Ok(());
17238 }
17239 }
17240 }
17241
17242 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
17245
17246 if use_double_colon {
17247 self.generate_expression(&cast.this)?;
17249 self.write("::");
17250 self.generate_data_type(&cast.to)?;
17251 } else {
17252 self.write_keyword("CAST");
17254 self.write("(");
17255 self.generate_expression(&cast.this)?;
17256 self.write_space();
17257 self.write_keyword("AS");
17258 self.write_space();
17259 if matches!(
17262 self.config.dialect,
17263 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
17264 ) {
17265 match &cast.to {
17266 DataType::Custom { ref name } => {
17267 if name.eq_ignore_ascii_case("LONGTEXT")
17268 || name.eq_ignore_ascii_case("MEDIUMTEXT")
17269 || name.eq_ignore_ascii_case("TINYTEXT")
17270 || name.eq_ignore_ascii_case("LONGBLOB")
17271 || name.eq_ignore_ascii_case("MEDIUMBLOB")
17272 || name.eq_ignore_ascii_case("TINYBLOB")
17273 {
17274 self.write_keyword("CHAR");
17275 } else {
17276 self.generate_data_type(&cast.to)?;
17277 }
17278 }
17279 DataType::VarChar { length, .. } => {
17280 self.write_keyword("CHAR");
17282 if let Some(n) = length {
17283 self.write(&format!("({})", n));
17284 }
17285 }
17286 DataType::Text => {
17287 self.write_keyword("CHAR");
17289 }
17290 DataType::Timestamp {
17291 precision,
17292 timezone: false,
17293 } => {
17294 self.write_keyword("DATETIME");
17296 if let Some(p) = precision {
17297 self.write(&format!("({})", p));
17298 }
17299 }
17300 _ => {
17301 self.generate_data_type(&cast.to)?;
17302 }
17303 }
17304 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
17305 match &cast.to {
17307 DataType::String { length } => {
17308 self.write_keyword("VARCHAR");
17309 if let Some(n) = length {
17310 self.write(&format!("({})", n));
17311 }
17312 }
17313 _ => {
17314 self.generate_data_type(&cast.to)?;
17315 }
17316 }
17317 } else {
17318 self.generate_data_type(&cast.to)?;
17319 }
17320
17321 if let Some(default) = &cast.default {
17323 self.write_space();
17324 self.write_keyword("DEFAULT");
17325 self.write_space();
17326 self.generate_expression(default)?;
17327 self.write_space();
17328 self.write_keyword("ON");
17329 self.write_space();
17330 self.write_keyword("CONVERSION");
17331 self.write_space();
17332 self.write_keyword("ERROR");
17333 }
17334
17335 if let Some(format) = &cast.format {
17338 if matches!(
17340 self.config.dialect,
17341 Some(crate::dialects::DialectType::Oracle)
17342 ) {
17343 self.write(", ");
17344 } else {
17345 self.write_space();
17346 self.write_keyword("FORMAT");
17347 self.write_space();
17348 }
17349 self.generate_expression(format)?;
17350 }
17351
17352 self.write(")");
17353 for comment in &cast.trailing_comments {
17355 self.write_space();
17356 self.write_formatted_comment(comment);
17357 }
17358 }
17359 Ok(())
17360 }
17361
17362 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
17365 self.write_keyword("ROW");
17366 self.write("(");
17367 for (i, (_, expr)) in s.fields.iter().enumerate() {
17368 if i > 0 {
17369 self.write(", ");
17370 }
17371 if let Expression::Struct(ref inner_s) = expr {
17373 self.generate_struct_as_row(inner_s)?;
17374 } else {
17375 self.generate_expression(expr)?;
17376 }
17377 }
17378 self.write(")");
17379 Ok(())
17380 }
17381
17382 fn normalize_oracle_format(&self, format: &str) -> String {
17385 let mut result = String::new();
17388 let chars: Vec<char> = format.chars().collect();
17389 let mut i = 0;
17390
17391 while i < chars.len() {
17392 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
17393 if i + 2 < chars.len() {
17395 let next = chars[i + 2];
17396 if next == '1' || next == '2' {
17397 result.push('H');
17399 result.push('H');
17400 i += 2;
17401 continue;
17402 }
17403 }
17404 result.push_str("HH12");
17406 i += 2;
17407 } else {
17408 result.push(chars[i]);
17409 i += 1;
17410 }
17411 }
17412
17413 result
17414 }
17415
17416 fn dialect_prefers_double_colon(&self) -> bool {
17419 matches!(self.config.dialect, Some(DialectType::ClickHouse))
17420 }
17421
17422 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17424 use crate::dialects::DialectType;
17425
17426 let use_percent_operator = matches!(
17428 self.config.dialect,
17429 Some(DialectType::Snowflake)
17430 | Some(DialectType::MySQL)
17431 | Some(DialectType::Presto)
17432 | Some(DialectType::Trino)
17433 | Some(DialectType::PostgreSQL)
17434 | Some(DialectType::DuckDB)
17435 | Some(DialectType::Hive)
17436 | Some(DialectType::Spark)
17437 | Some(DialectType::Databricks)
17438 | Some(DialectType::Athena)
17439 | Some(DialectType::TSQL)
17440 | Some(DialectType::Fabric)
17441 );
17442
17443 if use_percent_operator {
17444 let needs_paren = |e: &Expression| {
17447 matches!(
17448 e,
17449 Expression::Add(_)
17450 | Expression::Sub(_)
17451 | Expression::Mul(_)
17452 | Expression::Div(_)
17453 | Expression::Mod(_)
17454 | Expression::ModFunc(_)
17455 )
17456 };
17457 if needs_paren(&f.this) {
17458 self.write("(");
17459 self.generate_expression(&f.this)?;
17460 self.write(")");
17461 } else {
17462 self.generate_expression(&f.this)?;
17463 }
17464 self.write(" % ");
17465 if needs_paren(&f.expression) {
17466 self.write("(");
17467 self.generate_expression(&f.expression)?;
17468 self.write(")");
17469 } else {
17470 self.generate_expression(&f.expression)?;
17471 }
17472 Ok(())
17473 } else {
17474 self.generate_binary_func("MOD", &f.this, &f.expression)
17475 }
17476 }
17477
17478 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17480 use crate::dialects::DialectType;
17481
17482 let func_name = match self.config.dialect {
17484 Some(DialectType::Snowflake) => "COALESCE",
17485 _ => "IFNULL",
17486 };
17487
17488 self.generate_binary_func(func_name, &f.this, &f.expression)
17489 }
17490
17491 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17493 if let Some(ref original_name) = f.original_name {
17495 return self.generate_binary_func(original_name, &f.this, &f.expression);
17496 }
17497
17498 use crate::dialects::DialectType;
17500 let func_name = match self.config.dialect {
17501 Some(DialectType::Snowflake)
17502 | Some(DialectType::ClickHouse)
17503 | Some(DialectType::PostgreSQL)
17504 | Some(DialectType::Presto)
17505 | Some(DialectType::Trino)
17506 | Some(DialectType::Athena)
17507 | Some(DialectType::DuckDB)
17508 | Some(DialectType::BigQuery)
17509 | Some(DialectType::Spark)
17510 | Some(DialectType::Databricks)
17511 | Some(DialectType::Hive) => "COALESCE",
17512 Some(DialectType::MySQL)
17513 | Some(DialectType::Doris)
17514 | Some(DialectType::StarRocks)
17515 | Some(DialectType::SingleStore)
17516 | Some(DialectType::TiDB) => "IFNULL",
17517 _ => "NVL",
17518 };
17519
17520 self.generate_binary_func(func_name, &f.this, &f.expression)
17521 }
17522
17523 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
17525 use crate::dialects::DialectType;
17526
17527 let func_name = match self.config.dialect {
17529 Some(DialectType::Snowflake) => "STDDEV",
17530 _ => "STDDEV_SAMP",
17531 };
17532
17533 self.generate_agg_func(func_name, f)
17534 }
17535
17536 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
17537 self.generate_expression(&coll.this)?;
17538 self.write_space();
17539 self.write_keyword("COLLATE");
17540 self.write_space();
17541 if coll.quoted {
17542 self.write("'");
17544 self.write(&coll.collation);
17545 self.write("'");
17546 } else if coll.double_quoted {
17547 self.write("\"");
17549 self.write(&coll.collation);
17550 self.write("\"");
17551 } else {
17552 self.write(&coll.collation);
17554 }
17555 Ok(())
17556 }
17557
17558 fn generate_case(&mut self, case: &Case) -> Result<()> {
17559 let multiline_case = if self.config.pretty {
17561 let mut statements: Vec<String> = Vec::new();
17563 let operand_str = if let Some(operand) = &case.operand {
17564 let s = self.generate_to_string(operand)?;
17565 statements.push(format!("CASE {}", s));
17566 s
17567 } else {
17568 statements.push("CASE".to_string());
17569 String::new()
17570 };
17571 let _ = operand_str;
17572 for (condition, result) in &case.whens {
17573 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
17574 statements.push(format!("THEN {}", self.generate_to_string(result)?));
17575 }
17576 if let Some(else_) = &case.else_ {
17577 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
17578 }
17579 statements.push("END".to_string());
17580 self.too_wide(&statements)
17581 } else {
17582 false
17583 };
17584
17585 self.write_keyword("CASE");
17586 if let Some(operand) = &case.operand {
17587 self.write_space();
17588 self.generate_expression(operand)?;
17589 }
17590 if multiline_case {
17591 self.indent_level += 1;
17592 }
17593 for (condition, result) in &case.whens {
17594 if multiline_case {
17595 self.write_newline();
17596 self.write_indent();
17597 } else {
17598 self.write_space();
17599 }
17600 self.write_keyword("WHEN");
17601 self.write_space();
17602 self.generate_expression(condition)?;
17603 if multiline_case {
17604 self.write_newline();
17605 self.write_indent();
17606 } else {
17607 self.write_space();
17608 }
17609 self.write_keyword("THEN");
17610 self.write_space();
17611 self.generate_expression(result)?;
17612 }
17613 if let Some(else_) = &case.else_ {
17614 if multiline_case {
17615 self.write_newline();
17616 self.write_indent();
17617 } else {
17618 self.write_space();
17619 }
17620 self.write_keyword("ELSE");
17621 self.write_space();
17622 self.generate_expression(else_)?;
17623 }
17624 if multiline_case {
17625 self.indent_level -= 1;
17626 self.write_newline();
17627 self.write_indent();
17628 } else {
17629 self.write_space();
17630 }
17631 self.write_keyword("END");
17632 for comment in &case.comments {
17634 self.write(" ");
17635 self.write_formatted_comment(comment);
17636 }
17637 Ok(())
17638 }
17639
17640 fn generate_function(&mut self, func: &Function) -> Result<()> {
17641 let normalized_name = if matches!(self.config.dialect, Some(DialectType::Snowflake))
17643 && func.name.to_ascii_uppercase().starts_with("IDENTIFIER(")
17644 {
17645 Cow::Borrowed(func.name.as_str())
17646 } else {
17647 self.normalize_func_name(&func.name)
17648 };
17649
17650 if matches!(self.config.dialect, Some(DialectType::DuckDB))
17652 && func.name.eq_ignore_ascii_case("ARRAY_CONSTRUCT_COMPACT")
17653 {
17654 self.write("LIST_FILTER(");
17655 self.write("[");
17656 for (i, arg) in func.args.iter().enumerate() {
17657 if i > 0 {
17658 self.write(", ");
17659 }
17660 self.generate_expression(arg)?;
17661 }
17662 self.write("], _u -> NOT _u IS NULL)");
17663 return Ok(());
17664 }
17665
17666 if matches!(self.config.dialect, Some(DialectType::Snowflake))
17669 && func.name.eq_ignore_ascii_case("TO_VARIANT")
17670 && func.args.len() == 1
17671 {
17672 let array_expressions = match &func.args[0] {
17673 Expression::ArrayFunc(arr) => Some(&arr.expressions),
17674 Expression::Array(arr) => Some(&arr.expressions),
17675 _ => None,
17676 };
17677 if let Some(expressions) = array_expressions {
17678 self.write_keyword("TO_VARIANT");
17679 self.write("(");
17680 self.write_keyword("ARRAY_CONSTRUCT");
17681 self.write("(");
17682 for (i, arg) in expressions.iter().enumerate() {
17683 if i > 0 {
17684 self.write(", ");
17685 }
17686 self.generate_expression(arg)?;
17687 }
17688 self.write(")");
17689 self.write(")");
17690 return Ok(());
17691 }
17692 }
17693
17694 if func.name.eq_ignore_ascii_case("STRUCT")
17696 && !matches!(
17697 self.config.dialect,
17698 Some(DialectType::BigQuery)
17699 | Some(DialectType::Spark)
17700 | Some(DialectType::Databricks)
17701 | Some(DialectType::Hive)
17702 | None
17703 )
17704 {
17705 return self.generate_struct_function_cross_dialect(func);
17706 }
17707
17708 if func.name.eq_ignore_ascii_case("__SS_JSON_PATH_QMARK__") && func.args.len() == 2 {
17711 self.generate_expression(&func.args[0])?;
17712 self.write("::?");
17713 if let Expression::Literal(lit) = &func.args[1] {
17715 if let crate::expressions::Literal::String(key) = lit.as_ref() {
17716 self.write(key);
17717 }
17718 } else {
17719 self.generate_expression(&func.args[1])?;
17720 }
17721 return Ok(());
17722 }
17723
17724 if func.name.eq_ignore_ascii_case("__PG_BITWISE_XOR__") && func.args.len() == 2 {
17726 self.generate_expression(&func.args[0])?;
17727 self.write(" # ");
17728 self.generate_expression(&func.args[1])?;
17729 return Ok(());
17730 }
17731
17732 if matches!(
17734 self.config.dialect,
17735 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
17736 ) && func.name.eq_ignore_ascii_case("TRY")
17737 && func.args.len() == 1
17738 {
17739 self.generate_expression(&func.args[0])?;
17740 return Ok(());
17741 }
17742
17743 if self.config.dialect == Some(DialectType::ClickHouse)
17745 && func.name.eq_ignore_ascii_case("TOSTARTOFDAY")
17746 && func.args.len() == 1
17747 {
17748 self.write("dateTrunc('DAY', ");
17749 self.generate_expression(&func.args[0])?;
17750 self.write(")");
17751 return Ok(());
17752 }
17753
17754 if self.config.dialect == Some(DialectType::ClickHouse)
17756 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
17757 && func.args.len() == 2
17758 {
17759 self.write("dateTrunc(");
17760 self.generate_expression(&func.args[0])?;
17761 self.write(", ");
17762 self.generate_expression(&func.args[1])?;
17763 self.write(")");
17764 return Ok(());
17765 }
17766
17767 if matches!(
17769 self.config.dialect,
17770 Some(DialectType::Presto | DialectType::Trino | DialectType::Athena)
17771 ) && func.name.eq_ignore_ascii_case("SUBSTRING")
17772 {
17773 self.write_keyword("SUBSTR");
17774 self.write("(");
17775 for (i, arg) in func.args.iter().enumerate() {
17776 if i > 0 {
17777 self.write(", ");
17778 }
17779 self.generate_expression(arg)?;
17780 }
17781 self.write(")");
17782 return Ok(());
17783 }
17784
17785 if self.config.dialect == Some(DialectType::Snowflake)
17786 && func.name.eq_ignore_ascii_case("LIST_DISTINCT")
17787 && func.args.len() == 1
17788 {
17789 self.write_keyword("ARRAY_DISTINCT");
17790 self.write("(");
17791 self.write_keyword("ARRAY_COMPACT");
17792 self.write("(");
17793 self.generate_expression(&func.args[0])?;
17794 self.write("))");
17795 return Ok(());
17796 }
17797
17798 if self.config.dialect == Some(DialectType::Snowflake)
17799 && func.name.eq_ignore_ascii_case("LIST")
17800 && func.args.len() == 1
17801 && !matches!(func.args.first(), Some(Expression::Select(_)))
17802 {
17803 self.write_keyword("ARRAY_AGG");
17804 self.write("(");
17805 self.generate_expression(&func.args[0])?;
17806 self.write(")");
17807 return Ok(());
17808 }
17809
17810 if self.config.dialect == Some(DialectType::Redshift)
17812 && func.name.eq_ignore_ascii_case("CONCAT")
17813 && func.args.len() >= 2
17814 {
17815 for (i, arg) in func.args.iter().enumerate() {
17816 if i > 0 {
17817 self.write(" || ");
17818 }
17819 self.generate_expression(arg)?;
17820 }
17821 return Ok(());
17822 }
17823
17824 if self.config.dialect == Some(DialectType::Redshift)
17826 && func.name.eq_ignore_ascii_case("CONCAT_WS")
17827 && func.args.len() >= 2
17828 {
17829 let sep = &func.args[0];
17830 for (i, arg) in func.args.iter().skip(1).enumerate() {
17831 if i > 0 {
17832 self.write(" || ");
17833 self.generate_expression(sep)?;
17834 self.write(" || ");
17835 }
17836 self.generate_expression(arg)?;
17837 }
17838 return Ok(());
17839 }
17840
17841 if self.config.dialect == Some(DialectType::Redshift)
17844 && (func.name.eq_ignore_ascii_case("DATEDIFF")
17845 || func.name.eq_ignore_ascii_case("DATE_DIFF"))
17846 && func.args.len() == 3
17847 {
17848 self.write_keyword("DATEDIFF");
17849 self.write("(");
17850 self.write_redshift_date_part(&func.args[0]);
17852 self.write(", ");
17853 self.generate_expression(&func.args[1])?;
17854 self.write(", ");
17855 self.generate_expression(&func.args[2])?;
17856 self.write(")");
17857 return Ok(());
17858 }
17859
17860 if self.config.dialect == Some(DialectType::Redshift)
17863 && (func.name.eq_ignore_ascii_case("DATEADD")
17864 || func.name.eq_ignore_ascii_case("DATE_ADD"))
17865 && func.args.len() == 3
17866 {
17867 self.write_keyword("DATEADD");
17868 self.write("(");
17869 self.write_redshift_date_part(&func.args[0]);
17871 self.write(", ");
17872 self.generate_expression(&func.args[1])?;
17873 self.write(", ");
17874 self.generate_expression(&func.args[2])?;
17875 self.write(")");
17876 return Ok(());
17877 }
17878
17879 if func.name.eq_ignore_ascii_case("UUID_STRING")
17881 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
17882 {
17883 if matches!(
17884 self.config.dialect,
17885 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
17886 ) {
17887 self.write_keyword("CAST");
17888 self.write("(");
17889 self.write_keyword("UUID");
17890 self.write("() ");
17891 self.write_keyword("AS");
17892 self.write(" ");
17893 self.write_keyword("STRING");
17894 self.write(")");
17895 return Ok(());
17896 }
17897
17898 if matches!(
17899 self.config.dialect,
17900 Some(DialectType::Presto | DialectType::Trino)
17901 ) {
17902 self.write_keyword("CAST");
17903 self.write("(");
17904 self.write_keyword("UUID");
17905 self.write("() ");
17906 self.write_keyword("AS");
17907 self.write(" ");
17908 self.write_keyword("VARCHAR");
17909 self.write(")");
17910 return Ok(());
17911 }
17912
17913 if self.config.dialect == Some(DialectType::DuckDB) && func.args.len() == 2 {
17914 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(");
17915 self.generate_expression(&func.args[0])?;
17916 self.write(", '-', '')) || ENCODE(");
17917 self.generate_expression(&func.args[1])?;
17918 self.write(")), 1, 32) AS h))");
17919 return Ok(());
17920 }
17921
17922 let func_name = match self.config.dialect {
17923 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
17924 Some(DialectType::BigQuery) => "GENERATE_UUID",
17925 _ => "UUID",
17926 };
17927 self.write_keyword(func_name);
17928 self.write("()");
17929 return Ok(());
17930 }
17931
17932 if matches!(self.config.dialect, Some(DialectType::Snowflake))
17936 && func.name.eq_ignore_ascii_case("GENERATOR")
17937 {
17938 let has_positional_args =
17939 !func.args.is_empty() && !matches!(&func.args[0], Expression::NamedArgument(_));
17940 if has_positional_args {
17941 let param_names = ["ROWCOUNT", "TIMELIMIT"];
17942 self.write_keyword("GENERATOR");
17943 self.write("(");
17944 for (i, arg) in func.args.iter().enumerate() {
17945 if i > 0 {
17946 self.write(", ");
17947 }
17948 if i < param_names.len() {
17949 self.write_keyword(param_names[i]);
17950 self.write(" => ");
17951 self.generate_expression(arg)?;
17952 } else {
17953 self.generate_expression(arg)?;
17954 }
17955 }
17956 self.write(")");
17957 return Ok(());
17958 }
17959 }
17960
17961 if self.config.dialect == Some(DialectType::Redshift)
17964 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
17965 && func.args.len() == 2
17966 {
17967 self.write_keyword("DATE_TRUNC");
17968 self.write("(");
17969 self.write_redshift_date_part_quoted(&func.args[0]);
17971 self.write(", ");
17972 self.generate_expression(&func.args[1])?;
17973 self.write(")");
17974 return Ok(());
17975 }
17976
17977 if matches!(
17979 self.config.dialect,
17980 Some(DialectType::TSQL) | Some(DialectType::Fabric)
17981 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17982 || func.name.eq_ignore_ascii_case("DATEPART"))
17983 && func.args.len() == 2
17984 {
17985 self.write_keyword("DATEPART");
17986 self.write("(");
17987 self.write_tsql_date_part(&func.args[0])?;
17988 self.write(", ");
17989 self.generate_expression(&func.args[1])?;
17990 self.write(")");
17991 return Ok(());
17992 }
17993
17994 if matches!(
17996 self.config.dialect,
17997 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
17998 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17999 || func.name.eq_ignore_ascii_case("DATEPART"))
18000 && func.args.len() == 2
18001 {
18002 self.write_keyword("EXTRACT");
18003 self.write("(");
18004 match &func.args[0] {
18006 Expression::Literal(lit)
18007 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
18008 {
18009 let crate::expressions::Literal::String(s) = lit.as_ref() else {
18010 unreachable!()
18011 };
18012 self.write(&s.to_ascii_lowercase());
18013 }
18014 _ => self.generate_expression(&func.args[0])?,
18015 }
18016 self.write_space();
18017 self.write_keyword("FROM");
18018 self.write_space();
18019 self.generate_expression(&func.args[1])?;
18020 self.write(")");
18021 return Ok(());
18022 }
18023
18024 if self.config.dialect == Some(DialectType::PostgreSQL)
18026 && matches!(
18027 func.name.to_ascii_uppercase().as_str(),
18028 "DATE_ADD" | "DATE_SUB"
18029 )
18030 && func.args.len() == 2
18031 && matches!(func.args[1], Expression::Interval(_))
18032 {
18033 self.generate_expression(&func.args[0])?;
18034 self.write_space();
18035 if func.name.eq_ignore_ascii_case("DATE_SUB") {
18036 self.write("-");
18037 } else {
18038 self.write("+");
18039 }
18040 self.write_space();
18041 self.generate_expression(&func.args[1])?;
18042 return Ok(());
18043 }
18044
18045 if self.config.dialect == Some(DialectType::Dremio)
18048 && (func.name.eq_ignore_ascii_case("DATE_PART")
18049 || func.name.eq_ignore_ascii_case("DATEPART"))
18050 && func.args.len() == 2
18051 {
18052 self.write_keyword("EXTRACT");
18053 self.write("(");
18054 self.generate_expression(&func.args[0])?;
18055 self.write_space();
18056 self.write_keyword("FROM");
18057 self.write_space();
18058 self.generate_dremio_date_expression(&func.args[1])?;
18060 self.write(")");
18061 return Ok(());
18062 }
18063
18064 if self.config.dialect == Some(DialectType::Dremio)
18066 && func.name.eq_ignore_ascii_case("CURRENT_DATE_UTC")
18067 && func.args.is_empty()
18068 {
18069 self.write_keyword("CURRENT_DATE_UTC");
18070 return Ok(());
18071 }
18072
18073 if self.config.dialect == Some(DialectType::Dremio)
18077 && func.name.eq_ignore_ascii_case("DATETYPE")
18078 && func.args.len() == 3
18079 {
18080 fn get_int_literal(expr: &Expression) -> Option<i64> {
18082 if let Expression::Literal(lit) = expr {
18083 if let crate::expressions::Literal::Number(s) = lit.as_ref() {
18084 s.parse::<i64>().ok()
18085 } else {
18086 None
18087 }
18088 } else {
18089 None
18090 }
18091 }
18092
18093 if let (Some(year), Some(month), Some(day)) = (
18095 get_int_literal(&func.args[0]),
18096 get_int_literal(&func.args[1]),
18097 get_int_literal(&func.args[2]),
18098 ) {
18099 self.write_keyword("DATE");
18101 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
18102 return Ok(());
18103 }
18104
18105 self.write_keyword("CAST");
18107 self.write("(");
18108 self.write_keyword("CONCAT");
18109 self.write("(");
18110 self.generate_expression(&func.args[0])?;
18111 self.write(", '-', ");
18112 self.generate_expression(&func.args[1])?;
18113 self.write(", '-', ");
18114 self.generate_expression(&func.args[2])?;
18115 self.write(")");
18116 self.write_space();
18117 self.write_keyword("AS");
18118 self.write_space();
18119 self.write_keyword("DATE");
18120 self.write(")");
18121 return Ok(());
18122 }
18123
18124 let is_presto_like = matches!(
18127 self.config.dialect,
18128 Some(DialectType::Presto) | Some(DialectType::Trino)
18129 );
18130 if is_presto_like && func.name.eq_ignore_ascii_case("DATE_ADD") && func.args.len() == 3 {
18131 self.write_keyword("DATE_ADD");
18132 self.write("(");
18133 self.generate_expression(&func.args[0])?;
18135 self.write(", ");
18136 let interval = &func.args[1];
18138 let needs_cast = !self.returns_integer_type(interval);
18139 if needs_cast {
18140 self.write_keyword("CAST");
18141 self.write("(");
18142 }
18143 self.generate_expression(interval)?;
18144 if needs_cast {
18145 self.write_space();
18146 self.write_keyword("AS");
18147 self.write_space();
18148 self.write_keyword("BIGINT");
18149 self.write(")");
18150 }
18151 self.write(", ");
18152 self.generate_expression(&func.args[2])?;
18154 self.write(")");
18155 return Ok(());
18156 }
18157
18158 let use_brackets = func.use_bracket_syntax;
18160
18161 let has_ordinality = func.name.len() >= 16
18166 && func.name[func.name.len() - 16..].eq_ignore_ascii_case(" WITH ORDINALITY");
18167 let output_name = if has_ordinality {
18168 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
18169 self.normalize_func_name(base_name)
18170 } else {
18171 normalized_name.clone()
18172 };
18173
18174 let quote_source_clickhouse_function =
18177 matches!(self.config.dialect, Some(DialectType::ClickHouse))
18178 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
18179 && func.quoted;
18180
18181 if quote_source_clickhouse_function {
18182 self.generate_identifier(&Identifier {
18183 name: func.name.clone(),
18184 quoted: true,
18185 trailing_comments: Vec::new(),
18186 span: None,
18187 })?;
18188 } else if func.name.contains('.') && !has_ordinality {
18189 if func.quoted {
18192 self.write("`");
18193 self.write(&func.name);
18194 self.write("`");
18195 } else {
18196 self.write(&func.name);
18197 }
18198 } else {
18199 self.write(&output_name);
18200 }
18201
18202 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
18205 let needs_parens = if func.name.eq_ignore_ascii_case("CURRENT_USER")
18206 || func.name.eq_ignore_ascii_case("SESSION_USER")
18207 || func.name.eq_ignore_ascii_case("SYSTEM_USER")
18208 {
18209 matches!(
18210 self.config.dialect,
18211 Some(DialectType::Snowflake)
18212 | Some(DialectType::Spark)
18213 | Some(DialectType::Databricks)
18214 | Some(DialectType::Hive)
18215 )
18216 } else {
18217 false
18218 };
18219 !needs_parens
18220 };
18221 if force_parens {
18222 for comment in &func.trailing_comments {
18224 self.write_space();
18225 self.write_formatted_comment(comment);
18226 }
18227 return Ok(());
18228 }
18229
18230 if func.name.eq_ignore_ascii_case("CUBE")
18232 || func.name.eq_ignore_ascii_case("ROLLUP")
18233 || func.name.eq_ignore_ascii_case("GROUPING SETS")
18234 {
18235 self.write(" (");
18236 } else if use_brackets {
18237 self.write("[");
18238 } else {
18239 self.write("(");
18240 }
18241 if func.distinct {
18242 self.write_keyword("DISTINCT");
18243 self.write_space();
18244 }
18245
18246 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
18248 && (func.name.eq_ignore_ascii_case("TABLE")
18249 || func.name.eq_ignore_ascii_case("FLATTEN"));
18250 let is_grouping_func = func.name.eq_ignore_ascii_case("GROUPING SETS")
18252 || func.name.eq_ignore_ascii_case("CUBE")
18253 || func.name.eq_ignore_ascii_case("ROLLUP");
18254 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
18255 if is_grouping_func {
18256 true
18257 } else {
18258 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
18260 for arg in &func.args {
18261 let mut temp_gen = Generator::with_arc_config(self.config.clone());
18262 Arc::make_mut(&mut temp_gen.config).pretty = false; temp_gen.generate_expression(arg)?;
18264 expr_strings.push(temp_gen.output);
18265 }
18266 self.too_wide(&expr_strings)
18267 }
18268 } else {
18269 false
18270 };
18271
18272 if should_split {
18273 self.write_newline();
18275 self.indent_level += 1;
18276 for (i, arg) in func.args.iter().enumerate() {
18277 self.write_indent();
18278 self.generate_expression(arg)?;
18279 if i + 1 < func.args.len() {
18280 self.write(",");
18281 }
18282 self.write_newline();
18283 }
18284 self.indent_level -= 1;
18285 self.write_indent();
18286 } else {
18287 for (i, arg) in func.args.iter().enumerate() {
18289 if i > 0 {
18290 self.write(", ");
18291 }
18292 self.generate_expression(arg)?;
18293 }
18294 }
18295
18296 if use_brackets {
18297 self.write("]");
18298 } else {
18299 self.write(")");
18300 }
18301 if has_ordinality {
18303 self.write_space();
18304 self.write_keyword("WITH ORDINALITY");
18305 }
18306 for comment in &func.trailing_comments {
18308 self.write_space();
18309 self.write_formatted_comment(comment);
18310 }
18311 Ok(())
18312 }
18313
18314 fn generate_function_emits(&mut self, fe: &FunctionEmits) -> Result<()> {
18315 self.generate_expression(&fe.this)?;
18316 self.write_keyword(" EMITS ");
18317 self.generate_expression(&fe.emits)?;
18318 Ok(())
18319 }
18320
18321 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
18322 let mut normalized_name = self.normalize_func_name(&func.name);
18324
18325 if func.name.eq_ignore_ascii_case("MAX_BY") || func.name.eq_ignore_ascii_case("MIN_BY") {
18327 let is_max = func.name.eq_ignore_ascii_case("MAX_BY");
18328 match self.config.dialect {
18329 Some(DialectType::ClickHouse) => {
18330 normalized_name = if is_max {
18331 Cow::Borrowed("argMax")
18332 } else {
18333 Cow::Borrowed("argMin")
18334 };
18335 }
18336 Some(DialectType::DuckDB) => {
18337 normalized_name = if is_max {
18338 Cow::Borrowed("ARG_MAX")
18339 } else {
18340 Cow::Borrowed("ARG_MIN")
18341 };
18342 }
18343 _ => {}
18344 }
18345 }
18346 self.write(normalized_name.as_ref());
18347 self.write("(");
18348 if func.distinct {
18349 self.write_keyword("DISTINCT");
18350 self.write_space();
18351 }
18352
18353 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
18357 let needs_multi_arg_transform =
18358 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
18359
18360 if needs_multi_arg_transform {
18361 self.write_keyword("CASE");
18363 for arg in &func.args {
18364 self.write_space();
18365 self.write_keyword("WHEN");
18366 self.write_space();
18367 self.generate_expression(arg)?;
18368 self.write_space();
18369 self.write_keyword("IS NULL THEN NULL");
18370 }
18371 self.write_space();
18372 self.write_keyword("ELSE");
18373 self.write(" (");
18374 for (i, arg) in func.args.iter().enumerate() {
18375 if i > 0 {
18376 self.write(", ");
18377 }
18378 self.generate_expression(arg)?;
18379 }
18380 self.write(")");
18381 self.write_space();
18382 self.write_keyword("END");
18383 } else {
18384 for (i, arg) in func.args.iter().enumerate() {
18385 if i > 0 {
18386 self.write(", ");
18387 }
18388 self.generate_expression(arg)?;
18389 }
18390 }
18391
18392 let clickhouse_ignore_nulls_outside =
18394 matches!(self.config.dialect, Some(DialectType::ClickHouse));
18395 if self.config.ignore_nulls_in_func
18396 && !matches!(
18397 self.config.dialect,
18398 Some(DialectType::DuckDB) | Some(DialectType::ClickHouse)
18399 )
18400 {
18401 if let Some(ignore) = func.ignore_nulls {
18402 self.write_space();
18403 if ignore {
18404 self.write_keyword("IGNORE NULLS");
18405 } else {
18406 self.write_keyword("RESPECT NULLS");
18407 }
18408 }
18409 }
18410
18411 if !func.order_by.is_empty() {
18413 self.write_space();
18414 self.write_keyword("ORDER BY");
18415 self.write_space();
18416 for (i, ord) in func.order_by.iter().enumerate() {
18417 if i > 0 {
18418 self.write(", ");
18419 }
18420 self.generate_ordered(ord)?;
18421 }
18422 }
18423
18424 if let Some(limit) = &func.limit {
18426 self.write_space();
18427 self.write_keyword("LIMIT");
18428 self.write_space();
18429 if let Expression::Tuple(t) = limit.as_ref() {
18431 if t.expressions.len() == 2 {
18432 self.generate_expression(&t.expressions[0])?;
18433 self.write(", ");
18434 self.generate_expression(&t.expressions[1])?;
18435 } else {
18436 self.generate_expression(limit)?;
18437 }
18438 } else {
18439 self.generate_expression(limit)?;
18440 }
18441 }
18442
18443 self.write(")");
18444
18445 if (!self.config.ignore_nulls_in_func || clickhouse_ignore_nulls_outside)
18447 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18448 {
18449 if let Some(ignore) = func.ignore_nulls {
18450 self.write_space();
18451 if ignore {
18452 self.write_keyword("IGNORE NULLS");
18453 } else {
18454 self.write_keyword("RESPECT NULLS");
18455 }
18456 }
18457 }
18458
18459 if let Some(filter) = &func.filter {
18460 self.write_space();
18461 self.write_keyword("FILTER");
18462 self.write("(");
18463 self.write_keyword("WHERE");
18464 self.write_space();
18465 self.generate_expression(filter)?;
18466 self.write(")");
18467 }
18468
18469 Ok(())
18470 }
18471
18472 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
18473 self.generate_expression(&wf.this)?;
18474
18475 if let Some(keep) = &wf.keep {
18477 self.write_space();
18478 self.write_keyword("KEEP");
18479 self.write(" (");
18480 self.write_keyword("DENSE_RANK");
18481 self.write_space();
18482 if keep.first {
18483 self.write_keyword("FIRST");
18484 } else {
18485 self.write_keyword("LAST");
18486 }
18487 self.write_space();
18488 self.write_keyword("ORDER BY");
18489 self.write_space();
18490 for (i, ord) in keep.order_by.iter().enumerate() {
18491 if i > 0 {
18492 self.write(", ");
18493 }
18494 self.generate_ordered(ord)?;
18495 }
18496 self.write(")");
18497 }
18498
18499 let has_over = !wf.over.partition_by.is_empty()
18501 || !wf.over.order_by.is_empty()
18502 || wf.over.frame.is_some()
18503 || wf.over.window_name.is_some();
18504
18505 if has_over {
18507 self.write_space();
18508 self.write_keyword("OVER");
18509
18510 let has_specs = !wf.over.partition_by.is_empty()
18512 || !wf.over.order_by.is_empty()
18513 || wf.over.frame.is_some();
18514
18515 if wf.over.window_name.is_some() && !has_specs {
18516 self.write_space();
18518 self.write(&wf.over.window_name.as_ref().unwrap().name);
18519 } else {
18520 self.write(" (");
18522 self.generate_over(&wf.over)?;
18523 self.write(")");
18524 }
18525 } else if wf.keep.is_none() {
18526 self.write_space();
18528 self.write_keyword("OVER");
18529 self.write(" ()");
18530 }
18531
18532 Ok(())
18533 }
18534
18535 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
18537 self.generate_expression(&wg.this)?;
18538 self.write_space();
18539 self.write_keyword("WITHIN GROUP");
18540 self.write(" (");
18541 self.write_keyword("ORDER BY");
18542 self.write_space();
18543 for (i, ord) in wg.order_by.iter().enumerate() {
18544 if i > 0 {
18545 self.write(", ");
18546 }
18547 self.generate_ordered(ord)?;
18548 }
18549 self.write(")");
18550 Ok(())
18551 }
18552
18553 fn generate_over(&mut self, over: &Over) -> Result<()> {
18555 let mut has_content = false;
18556
18557 if let Some(name) = &over.window_name {
18559 self.write(&name.name);
18560 has_content = true;
18561 }
18562
18563 if !over.partition_by.is_empty() {
18565 if has_content {
18566 self.write_space();
18567 }
18568 self.write_keyword("PARTITION BY");
18569 self.write_space();
18570 for (i, expr) in over.partition_by.iter().enumerate() {
18571 if i > 0 {
18572 self.write(", ");
18573 }
18574 self.generate_expression(expr)?;
18575 }
18576 has_content = true;
18577 }
18578
18579 if !over.order_by.is_empty() {
18581 if has_content {
18582 self.write_space();
18583 }
18584 self.write_keyword("ORDER BY");
18585 self.write_space();
18586 for (i, ordered) in over.order_by.iter().enumerate() {
18587 if i > 0 {
18588 self.write(", ");
18589 }
18590 self.generate_ordered(ordered)?;
18591 }
18592 has_content = true;
18593 }
18594
18595 if let Some(frame) = &over.frame {
18597 if has_content {
18598 self.write_space();
18599 }
18600 self.generate_window_frame(frame)?;
18601 }
18602
18603 Ok(())
18604 }
18605
18606 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
18607 let lowercase_frame = self.config.lowercase_window_frame_keywords;
18609
18610 if !lowercase_frame {
18612 if let Some(kind_text) = &frame.kind_text {
18613 self.write(kind_text);
18614 } else {
18615 match frame.kind {
18616 WindowFrameKind::Rows => self.write_keyword("ROWS"),
18617 WindowFrameKind::Range => self.write_keyword("RANGE"),
18618 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
18619 }
18620 }
18621 } else {
18622 match frame.kind {
18623 WindowFrameKind::Rows => self.write("rows"),
18624 WindowFrameKind::Range => self.write("range"),
18625 WindowFrameKind::Groups => self.write("groups"),
18626 }
18627 }
18628
18629 self.write_space();
18632 let should_normalize = self.config.normalize_window_frame_between
18633 && frame.end.is_none()
18634 && matches!(
18635 frame.start,
18636 WindowFrameBound::Preceding(_)
18637 | WindowFrameBound::Following(_)
18638 | WindowFrameBound::UnboundedPreceding
18639 | WindowFrameBound::UnboundedFollowing
18640 );
18641
18642 if let Some(end) = &frame.end {
18643 self.write_keyword("BETWEEN");
18645 self.write_space();
18646 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18647 self.write_space();
18648 self.write_keyword("AND");
18649 self.write_space();
18650 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
18651 } else if should_normalize {
18652 self.write_keyword("BETWEEN");
18654 self.write_space();
18655 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18656 self.write_space();
18657 self.write_keyword("AND");
18658 self.write_space();
18659 self.write_keyword("CURRENT ROW");
18660 } else {
18661 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18663 }
18664
18665 if let Some(exclude) = &frame.exclude {
18667 self.write_space();
18668 self.write_keyword("EXCLUDE");
18669 self.write_space();
18670 match exclude {
18671 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
18672 WindowFrameExclude::Group => self.write_keyword("GROUP"),
18673 WindowFrameExclude::Ties => self.write_keyword("TIES"),
18674 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
18675 }
18676 }
18677
18678 Ok(())
18679 }
18680
18681 fn generate_window_frame_bound(
18682 &mut self,
18683 bound: &WindowFrameBound,
18684 side_text: Option<&str>,
18685 ) -> Result<()> {
18686 let lowercase_frame = self.config.lowercase_window_frame_keywords;
18688
18689 match bound {
18690 WindowFrameBound::CurrentRow => {
18691 self.write_keyword("CURRENT ROW");
18692 }
18693 WindowFrameBound::UnboundedPreceding => {
18694 self.write_keyword("UNBOUNDED");
18695 self.write_space();
18696 if lowercase_frame {
18697 self.write("preceding");
18698 } else if let Some(text) = side_text {
18699 self.write(text);
18700 } else {
18701 self.write_keyword("PRECEDING");
18702 }
18703 }
18704 WindowFrameBound::UnboundedFollowing => {
18705 self.write_keyword("UNBOUNDED");
18706 self.write_space();
18707 if lowercase_frame {
18708 self.write("following");
18709 } else if let Some(text) = side_text {
18710 self.write(text);
18711 } else {
18712 self.write_keyword("FOLLOWING");
18713 }
18714 }
18715 WindowFrameBound::Preceding(expr) => {
18716 self.generate_expression(expr)?;
18717 self.write_space();
18718 if lowercase_frame {
18719 self.write("preceding");
18720 } else if let Some(text) = side_text {
18721 self.write(text);
18722 } else {
18723 self.write_keyword("PRECEDING");
18724 }
18725 }
18726 WindowFrameBound::Following(expr) => {
18727 self.generate_expression(expr)?;
18728 self.write_space();
18729 if lowercase_frame {
18730 self.write("following");
18731 } else if let Some(text) = side_text {
18732 self.write(text);
18733 } else {
18734 self.write_keyword("FOLLOWING");
18735 }
18736 }
18737 WindowFrameBound::BarePreceding => {
18738 if lowercase_frame {
18739 self.write("preceding");
18740 } else if let Some(text) = side_text {
18741 self.write(text);
18742 } else {
18743 self.write_keyword("PRECEDING");
18744 }
18745 }
18746 WindowFrameBound::BareFollowing => {
18747 if lowercase_frame {
18748 self.write("following");
18749 } else if let Some(text) = side_text {
18750 self.write(text);
18751 } else {
18752 self.write_keyword("FOLLOWING");
18753 }
18754 }
18755 WindowFrameBound::Value(expr) => {
18756 self.generate_expression(expr)?;
18758 }
18759 }
18760 Ok(())
18761 }
18762
18763 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
18764 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
18767 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
18768 && !matches!(&interval.this, Some(Expression::Literal(_)));
18769
18770 if self.config.single_string_interval {
18773 if let (
18774 Some(Expression::Literal(lit)),
18775 Some(IntervalUnitSpec::Simple {
18776 ref unit,
18777 ref use_plural,
18778 }),
18779 ) = (&interval.this, &interval.unit)
18780 {
18781 if let Literal::String(ref val) = lit.as_ref() {
18782 self.write_keyword("INTERVAL");
18783 self.write_space();
18784 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
18785 let unit_str = self.interval_unit_str(unit, effective_plural);
18786 self.write("'");
18787 self.write(val);
18788 self.write(" ");
18789 self.write(&unit_str);
18790 self.write("'");
18791 return Ok(());
18792 }
18793 }
18794 }
18795
18796 if !skip_interval_keyword {
18797 self.write_keyword("INTERVAL");
18798 }
18799
18800 if let Some(ref value) = interval.this {
18802 if !skip_interval_keyword {
18803 self.write_space();
18804 }
18805 let needs_parens = interval.unit.is_some()
18809 && matches!(
18810 value,
18811 Expression::Add(_)
18812 | Expression::Sub(_)
18813 | Expression::Mul(_)
18814 | Expression::Div(_)
18815 | Expression::Mod(_)
18816 | Expression::BitwiseAnd(_)
18817 | Expression::BitwiseOr(_)
18818 | Expression::BitwiseXor(_)
18819 );
18820 if needs_parens {
18821 self.write("(");
18822 }
18823 self.generate_expression(value)?;
18824 if needs_parens {
18825 self.write(")");
18826 }
18827 }
18828
18829 if let Some(ref unit_spec) = interval.unit {
18831 self.write_space();
18832 self.write_interval_unit_spec(unit_spec)?;
18833 }
18834
18835 Ok(())
18836 }
18837
18838 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
18840 match (unit, use_plural) {
18841 (IntervalUnit::Year, false) => "YEAR",
18842 (IntervalUnit::Year, true) => "YEARS",
18843 (IntervalUnit::Quarter, false) => "QUARTER",
18844 (IntervalUnit::Quarter, true) => "QUARTERS",
18845 (IntervalUnit::Month, false) => "MONTH",
18846 (IntervalUnit::Month, true) => "MONTHS",
18847 (IntervalUnit::Week, false) => "WEEK",
18848 (IntervalUnit::Week, true) => "WEEKS",
18849 (IntervalUnit::Day, false) => "DAY",
18850 (IntervalUnit::Day, true) => "DAYS",
18851 (IntervalUnit::Hour, false) => "HOUR",
18852 (IntervalUnit::Hour, true) => "HOURS",
18853 (IntervalUnit::Minute, false) => "MINUTE",
18854 (IntervalUnit::Minute, true) => "MINUTES",
18855 (IntervalUnit::Second, false) => "SECOND",
18856 (IntervalUnit::Second, true) => "SECONDS",
18857 (IntervalUnit::Millisecond, false) => "MILLISECOND",
18858 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
18859 (IntervalUnit::Microsecond, false) => "MICROSECOND",
18860 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
18861 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
18862 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
18863 }
18864 }
18865
18866 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
18867 match unit_spec {
18868 IntervalUnitSpec::Simple { unit, use_plural } => {
18869 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
18871 self.write_simple_interval_unit(unit, effective_plural);
18872 }
18873 IntervalUnitSpec::Span(span) => {
18874 self.write_simple_interval_unit(&span.this, false);
18875 self.write_space();
18876 self.write_keyword("TO");
18877 self.write_space();
18878 self.write_simple_interval_unit(&span.expression, false);
18879 }
18880 IntervalUnitSpec::ExprSpan(span) => {
18881 self.generate_expression(&span.this)?;
18883 self.write_space();
18884 self.write_keyword("TO");
18885 self.write_space();
18886 self.generate_expression(&span.expression)?;
18887 }
18888 IntervalUnitSpec::Expr(expr) => {
18889 self.generate_expression(expr)?;
18890 }
18891 }
18892 Ok(())
18893 }
18894
18895 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
18896 match (unit, use_plural) {
18898 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
18899 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
18900 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
18901 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
18902 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
18903 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
18904 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
18905 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
18906 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
18907 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
18908 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
18909 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
18910 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
18911 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
18912 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
18913 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
18914 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
18915 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
18916 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
18917 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
18918 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
18919 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
18920 }
18921 }
18922
18923 fn write_redshift_date_part(&mut self, expr: &Expression) {
18926 let part_str = self.extract_date_part_string(expr);
18927 if let Some(part) = part_str {
18928 let normalized = self.normalize_date_part(&part);
18929 self.write_keyword(&normalized);
18930 } else {
18931 let _ = self.generate_expression(expr);
18933 }
18934 }
18935
18936 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
18939 let part_str = self.extract_date_part_string(expr);
18940 if let Some(part) = part_str {
18941 let normalized = self.normalize_date_part(&part);
18942 self.write("'");
18943 self.write(&normalized);
18944 self.write("'");
18945 } else {
18946 let _ = self.generate_expression(expr);
18948 }
18949 }
18950
18951 fn write_tsql_date_part(&mut self, expr: &Expression) -> Result<()> {
18952 if let Some(part) = self.extract_date_part_string(expr) {
18953 let upper = part.to_ascii_uppercase();
18954 let unmapped = match upper.as_str() {
18955 "DAYOFWEEK" => "WEEKDAY",
18956 "WEEKISO" => "ISO_WEEK",
18957 "TIMEZONE_MINUTE" => "TZOFFSET",
18958 _ => part.as_str(),
18959 };
18960 self.write_keyword(unmapped);
18961 } else {
18962 self.generate_expression(expr)?;
18963 }
18964 Ok(())
18965 }
18966
18967 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
18969 match expr {
18970 Expression::Literal(lit)
18971 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
18972 {
18973 let crate::expressions::Literal::String(s) = lit.as_ref() else {
18974 unreachable!()
18975 };
18976 Some(s.clone())
18977 }
18978 Expression::Identifier(id) => Some(id.name.clone()),
18979 Expression::Var(v) => Some(v.this.clone()),
18980 Expression::Column(col) if col.table.is_none() => {
18981 Some(col.name.name.clone())
18983 }
18984 _ => None,
18985 }
18986 }
18987
18988 fn normalize_date_part(&self, part: &str) -> String {
18991 let mut buf = [0u8; 64];
18992 let lower: &str = if part.len() <= 64 {
18993 for (i, b) in part.bytes().enumerate() {
18994 buf[i] = b.to_ascii_lowercase();
18995 }
18996 std::str::from_utf8(&buf[..part.len()]).unwrap_or(part)
18997 } else {
18998 return part.to_ascii_uppercase();
18999 };
19000 match lower {
19001 "day" | "days" | "d" => "DAY".to_string(),
19002 "month" | "months" | "mon" | "mons" | "mm" => "MONTH".to_string(),
19003 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
19004 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
19005 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
19006 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
19007 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
19008 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
19009 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
19010 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
19011 _ => part.to_ascii_uppercase(),
19012 }
19013 }
19014
19015 fn write_datetime_field(&mut self, field: &DateTimeField) {
19016 match field {
19017 DateTimeField::Year => self.write_keyword("YEAR"),
19018 DateTimeField::Month => self.write_keyword("MONTH"),
19019 DateTimeField::Day => self.write_keyword("DAY"),
19020 DateTimeField::Hour => self.write_keyword("HOUR"),
19021 DateTimeField::Minute => self.write_keyword("MINUTE"),
19022 DateTimeField::Second => self.write_keyword("SECOND"),
19023 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
19024 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
19025 DateTimeField::DayOfWeek => {
19026 let name = match self.config.dialect {
19027 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
19028 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "WEEKDAY",
19029 _ => "DOW",
19030 };
19031 self.write_keyword(name);
19032 }
19033 DateTimeField::DayOfYear => {
19034 let name = match self.config.dialect {
19035 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
19036 _ => "DOY",
19037 };
19038 self.write_keyword(name);
19039 }
19040 DateTimeField::Week => self.write_keyword("WEEK"),
19041 DateTimeField::WeekWithModifier(modifier) => {
19042 self.write_keyword("WEEK");
19043 self.write("(");
19044 self.write(modifier);
19045 self.write(")");
19046 }
19047 DateTimeField::Quarter => self.write_keyword("QUARTER"),
19048 DateTimeField::Epoch => self.write_keyword("EPOCH"),
19049 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
19050 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
19051 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
19052 DateTimeField::Date => self.write_keyword("DATE"),
19053 DateTimeField::Time => self.write_keyword("TIME"),
19054 DateTimeField::Custom(name) => self.write(name),
19055 }
19056 }
19057
19058 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
19060 match field {
19061 DateTimeField::Year => self.write("year"),
19062 DateTimeField::Month => self.write("month"),
19063 DateTimeField::Day => self.write("day"),
19064 DateTimeField::Hour => self.write("hour"),
19065 DateTimeField::Minute => self.write("minute"),
19066 DateTimeField::Second => self.write("second"),
19067 DateTimeField::Millisecond => self.write("millisecond"),
19068 DateTimeField::Microsecond => self.write("microsecond"),
19069 DateTimeField::DayOfWeek => self.write("dow"),
19070 DateTimeField::DayOfYear => self.write("doy"),
19071 DateTimeField::Week => self.write("week"),
19072 DateTimeField::WeekWithModifier(modifier) => {
19073 self.write("week(");
19074 self.write(modifier);
19075 self.write(")");
19076 }
19077 DateTimeField::Quarter => self.write("quarter"),
19078 DateTimeField::Epoch => self.write("epoch"),
19079 DateTimeField::Timezone => self.write("timezone"),
19080 DateTimeField::TimezoneHour => self.write("timezone_hour"),
19081 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
19082 DateTimeField::Date => self.write("date"),
19083 DateTimeField::Time => self.write("time"),
19084 DateTimeField::Custom(name) => self.write(name),
19085 }
19086 }
19087
19088 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
19091 self.write_keyword(name);
19092 self.write("(");
19093 self.generate_expression(arg)?;
19094 self.write(")");
19095 Ok(())
19096 }
19097
19098 fn generate_unary_func(
19100 &mut self,
19101 default_name: &str,
19102 f: &crate::expressions::UnaryFunc,
19103 ) -> Result<()> {
19104 let name = f.original_name.as_deref().unwrap_or(default_name);
19105 self.write_keyword(name);
19106 self.write("(");
19107 self.generate_expression(&f.this)?;
19108 self.write(")");
19109 Ok(())
19110 }
19111
19112 fn generate_sqrt_cbrt(
19114 &mut self,
19115 f: &crate::expressions::UnaryFunc,
19116 func_name: &str,
19117 _op: &str,
19118 ) -> Result<()> {
19119 self.write_keyword(func_name);
19122 self.write("(");
19123 self.generate_expression(&f.this)?;
19124 self.write(")");
19125 Ok(())
19126 }
19127
19128 fn generate_binary_func(
19129 &mut self,
19130 name: &str,
19131 arg1: &Expression,
19132 arg2: &Expression,
19133 ) -> Result<()> {
19134 self.write_keyword(name);
19135 self.write("(");
19136 self.generate_expression(arg1)?;
19137 self.write(", ");
19138 self.generate_expression(arg2)?;
19139 self.write(")");
19140 Ok(())
19141 }
19142
19143 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
19147 let func_name = f.name.as_deref().unwrap_or("CHAR");
19149 self.write_keyword(func_name);
19150 self.write("(");
19151 for (i, arg) in f.args.iter().enumerate() {
19152 if i > 0 {
19153 self.write(", ");
19154 }
19155 self.generate_expression(arg)?;
19156 }
19157 if let Some(ref charset) = f.charset {
19158 self.write(" ");
19159 self.write_keyword("USING");
19160 self.write(" ");
19161 self.write(charset);
19162 }
19163 self.write(")");
19164 Ok(())
19165 }
19166
19167 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
19168 use crate::dialects::DialectType;
19169
19170 match self.config.dialect {
19171 Some(DialectType::Teradata) => {
19172 self.generate_expression(&f.this)?;
19174 self.write(" ** ");
19175 self.generate_expression(&f.expression)?;
19176 Ok(())
19177 }
19178 _ => {
19179 self.generate_binary_func("POWER", &f.this, &f.expression)
19181 }
19182 }
19183 }
19184
19185 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
19186 self.write_func_name(name);
19187 self.write("(");
19188 for (i, arg) in args.iter().enumerate() {
19189 if i > 0 {
19190 self.write(", ");
19191 }
19192 self.generate_expression(arg)?;
19193 }
19194 self.write(")");
19195 Ok(())
19196 }
19197
19198 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
19201 self.write_keyword("CONCAT_WS");
19202 self.write("(");
19203 self.generate_expression(&f.separator)?;
19204 for expr in &f.expressions {
19205 self.write(", ");
19206 self.generate_expression(expr)?;
19207 }
19208 self.write(")");
19209 Ok(())
19210 }
19211
19212 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
19213 if let Expression::Concat(op) = expr {
19214 Self::collect_concat_operands(&op.left, out);
19215 Self::collect_concat_operands(&op.right, out);
19216 } else {
19217 out.push(expr);
19218 }
19219 }
19220
19221 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
19222 let mut operands = Vec::new();
19223 Self::collect_concat_operands(&op.left, &mut operands);
19224 Self::collect_concat_operands(&op.right, &mut operands);
19225
19226 self.write_keyword("CONCAT");
19227 self.write("(");
19228 for (i, operand) in operands.iter().enumerate() {
19229 if i > 0 {
19230 self.write(", ");
19231 }
19232 self.generate_expression(operand)?;
19233 }
19234 self.write(")");
19235 Ok(())
19236 }
19237
19238 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
19239 if let Expression::DPipe(dpipe) = expr {
19240 Self::collect_dpipe_operands(&dpipe.this, out);
19241 Self::collect_dpipe_operands(&dpipe.expression, out);
19242 } else {
19243 out.push(expr);
19244 }
19245 }
19246
19247 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
19248 let mut operands = Vec::new();
19249 Self::collect_dpipe_operands(&e.this, &mut operands);
19250 Self::collect_dpipe_operands(&e.expression, &mut operands);
19251
19252 self.write_keyword("CONCAT");
19253 self.write("(");
19254 for (i, operand) in operands.iter().enumerate() {
19255 if i > 0 {
19256 self.write(", ");
19257 }
19258 self.generate_expression(operand)?;
19259 }
19260 self.write(")");
19261 Ok(())
19262 }
19263
19264 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
19265 let use_substr = matches!(
19267 self.config.dialect,
19268 Some(
19269 DialectType::Oracle
19270 | DialectType::Presto
19271 | DialectType::Trino
19272 | DialectType::Athena
19273 )
19274 );
19275 if use_substr {
19276 self.write_keyword("SUBSTR");
19277 } else {
19278 self.write_keyword("SUBSTRING");
19279 }
19280 self.write("(");
19281 self.generate_expression(&f.this)?;
19282 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
19284 let use_comma_syntax = matches!(
19286 self.config.dialect,
19287 Some(DialectType::Spark)
19288 | Some(DialectType::Hive)
19289 | Some(DialectType::Databricks)
19290 | Some(DialectType::TSQL)
19291 | Some(DialectType::Fabric)
19292 );
19293 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
19294 self.write_space();
19296 self.write_keyword("FROM");
19297 self.write_space();
19298 self.generate_expression(&f.start)?;
19299 if let Some(length) = &f.length {
19300 self.write_space();
19301 self.write_keyword("FOR");
19302 self.write_space();
19303 self.generate_expression(length)?;
19304 }
19305 } else {
19306 self.write(", ");
19308 self.generate_expression(&f.start)?;
19309 if let Some(length) = &f.length {
19310 self.write(", ");
19311 self.generate_expression(length)?;
19312 }
19313 }
19314 self.write(")");
19315 Ok(())
19316 }
19317
19318 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
19319 self.write_keyword("OVERLAY");
19320 self.write("(");
19321 self.generate_expression(&f.this)?;
19322 self.write_space();
19323 self.write_keyword("PLACING");
19324 self.write_space();
19325 self.generate_expression(&f.replacement)?;
19326 self.write_space();
19327 self.write_keyword("FROM");
19328 self.write_space();
19329 self.generate_expression(&f.from)?;
19330 if let Some(length) = &f.length {
19331 self.write_space();
19332 self.write_keyword("FOR");
19333 self.write_space();
19334 self.generate_expression(length)?;
19335 }
19336 self.write(")");
19337 Ok(())
19338 }
19339
19340 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
19341 if f.position_explicit && f.characters.is_none() {
19344 match f.position {
19345 TrimPosition::Leading => {
19346 self.write_keyword("LTRIM");
19347 self.write("(");
19348 self.generate_expression(&f.this)?;
19349 self.write(")");
19350 return Ok(());
19351 }
19352 TrimPosition::Trailing => {
19353 self.write_keyword("RTRIM");
19354 self.write("(");
19355 self.generate_expression(&f.this)?;
19356 self.write(")");
19357 return Ok(());
19358 }
19359 TrimPosition::Both => {
19360 }
19363 }
19364 }
19365
19366 self.write_keyword("TRIM");
19367 self.write("(");
19368 let force_standard = f.characters.is_some()
19371 && !f.sql_standard_syntax
19372 && matches!(
19373 self.config.dialect,
19374 Some(DialectType::Hive)
19375 | Some(DialectType::Spark)
19376 | Some(DialectType::Databricks)
19377 | Some(DialectType::ClickHouse)
19378 );
19379 let use_standard = (f.sql_standard_syntax || force_standard)
19380 && !(f.position_explicit
19381 && f.characters.is_none()
19382 && matches!(f.position, TrimPosition::Both));
19383 if use_standard {
19384 if f.position_explicit {
19387 match f.position {
19388 TrimPosition::Both => self.write_keyword("BOTH"),
19389 TrimPosition::Leading => self.write_keyword("LEADING"),
19390 TrimPosition::Trailing => self.write_keyword("TRAILING"),
19391 }
19392 self.write_space();
19393 }
19394 if let Some(chars) = &f.characters {
19395 self.generate_expression(chars)?;
19396 self.write_space();
19397 }
19398 self.write_keyword("FROM");
19399 self.write_space();
19400 self.generate_expression(&f.this)?;
19401 } else {
19402 self.generate_expression(&f.this)?;
19404 if let Some(chars) = &f.characters {
19405 self.write(", ");
19406 self.generate_expression(chars)?;
19407 }
19408 }
19409 self.write(")");
19410 Ok(())
19411 }
19412
19413 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
19414 self.write_keyword("REPLACE");
19415 self.write("(");
19416 self.generate_expression(&f.this)?;
19417 self.write(", ");
19418 self.generate_expression(&f.old)?;
19419 self.write(", ");
19420 self.generate_expression(&f.new)?;
19421 self.write(")");
19422 Ok(())
19423 }
19424
19425 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
19426 self.write_keyword(name);
19427 self.write("(");
19428 self.generate_expression(&f.this)?;
19429 self.write(", ");
19430 self.generate_expression(&f.length)?;
19431 self.write(")");
19432 Ok(())
19433 }
19434
19435 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
19436 self.write_keyword("REPEAT");
19437 self.write("(");
19438 self.generate_expression(&f.this)?;
19439 self.write(", ");
19440 self.generate_expression(&f.times)?;
19441 self.write(")");
19442 Ok(())
19443 }
19444
19445 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
19446 self.write_keyword(name);
19447 self.write("(");
19448 self.generate_expression(&f.this)?;
19449 self.write(", ");
19450 self.generate_expression(&f.length)?;
19451 if let Some(fill) = &f.fill {
19452 self.write(", ");
19453 self.generate_expression(fill)?;
19454 }
19455 self.write(")");
19456 Ok(())
19457 }
19458
19459 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
19460 self.write_keyword("SPLIT");
19461 self.write("(");
19462 self.generate_expression(&f.this)?;
19463 self.write(", ");
19464 self.generate_expression(&f.delimiter)?;
19465 self.write(")");
19466 Ok(())
19467 }
19468
19469 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
19470 use crate::dialects::DialectType;
19471 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
19473 self.generate_expression(&f.this)?;
19474 self.write(" ~ ");
19475 self.generate_expression(&f.pattern)?;
19476 } else if matches!(self.config.dialect, Some(DialectType::Exasol)) && f.flags.is_none() {
19477 self.generate_expression(&f.this)?;
19479 self.write_keyword(" REGEXP_LIKE ");
19480 self.generate_expression(&f.pattern)?;
19481 } else if matches!(
19482 self.config.dialect,
19483 Some(DialectType::SingleStore)
19484 | Some(DialectType::Spark)
19485 | Some(DialectType::Hive)
19486 | Some(DialectType::Databricks)
19487 ) && f.flags.is_none()
19488 {
19489 self.generate_expression(&f.this)?;
19491 self.write_keyword(" RLIKE ");
19492 self.generate_expression(&f.pattern)?;
19493 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
19494 self.write_keyword("REGEXP");
19496 self.write("(");
19497 self.generate_expression(&f.this)?;
19498 self.write(", ");
19499 self.generate_expression(&f.pattern)?;
19500 if let Some(flags) = &f.flags {
19501 self.write(", ");
19502 self.generate_expression(flags)?;
19503 }
19504 self.write(")");
19505 } else {
19506 self.write_keyword("REGEXP_LIKE");
19507 self.write("(");
19508 self.generate_expression(&f.this)?;
19509 self.write(", ");
19510 self.generate_expression(&f.pattern)?;
19511 if let Some(flags) = &f.flags {
19512 self.write(", ");
19513 self.generate_expression(flags)?;
19514 }
19515 self.write(")");
19516 }
19517 Ok(())
19518 }
19519
19520 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
19521 self.write_keyword("REGEXP_REPLACE");
19522 self.write("(");
19523 self.generate_expression(&f.this)?;
19524 self.write(", ");
19525 self.generate_expression(&f.pattern)?;
19526 self.write(", ");
19527 self.generate_expression(&f.replacement)?;
19528 if let Some(flags) = &f.flags {
19529 self.write(", ");
19530 self.generate_expression(flags)?;
19531 }
19532 self.write(")");
19533 Ok(())
19534 }
19535
19536 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
19537 self.write_keyword("REGEXP_EXTRACT");
19538 self.write("(");
19539 self.generate_expression(&f.this)?;
19540 self.write(", ");
19541 self.generate_expression(&f.pattern)?;
19542 if let Some(group) = &f.group {
19543 self.write(", ");
19544 self.generate_expression(group)?;
19545 }
19546 self.write(")");
19547 Ok(())
19548 }
19549
19550 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
19553 self.write_keyword("ROUND");
19554 self.write("(");
19555 self.generate_expression(&f.this)?;
19556 if let Some(decimals) = &f.decimals {
19557 self.write(", ");
19558 self.generate_expression(decimals)?;
19559 }
19560 self.write(")");
19561 Ok(())
19562 }
19563
19564 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
19565 self.write_keyword("FLOOR");
19566 self.write("(");
19567 self.generate_expression(&f.this)?;
19568 if let Some(to) = &f.to {
19570 self.write(" ");
19571 self.write_keyword("TO");
19572 self.write(" ");
19573 self.generate_expression(to)?;
19574 } else if let Some(scale) = &f.scale {
19575 self.write(", ");
19576 self.generate_expression(scale)?;
19577 }
19578 self.write(")");
19579 Ok(())
19580 }
19581
19582 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
19583 self.write_keyword("CEIL");
19584 self.write("(");
19585 self.generate_expression(&f.this)?;
19586 if let Some(to) = &f.to {
19588 self.write(" ");
19589 self.write_keyword("TO");
19590 self.write(" ");
19591 self.generate_expression(to)?;
19592 } else if let Some(decimals) = &f.decimals {
19593 self.write(", ");
19594 self.generate_expression(decimals)?;
19595 }
19596 self.write(")");
19597 Ok(())
19598 }
19599
19600 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
19601 use crate::expressions::Literal;
19602
19603 if let Some(base) = &f.base {
19604 if self.is_log_base_none() {
19607 if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "2"))
19608 {
19609 self.write_func_name("LOG2");
19610 self.write("(");
19611 self.generate_expression(&f.this)?;
19612 self.write(")");
19613 return Ok(());
19614 } else if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "10"))
19615 {
19616 self.write_func_name("LOG10");
19617 self.write("(");
19618 self.generate_expression(&f.this)?;
19619 self.write(")");
19620 return Ok(());
19621 }
19622 }
19624
19625 self.write_func_name("LOG");
19626 self.write("(");
19627 if self.is_log_value_first() {
19628 self.generate_expression(&f.this)?;
19630 self.write(", ");
19631 self.generate_expression(base)?;
19632 } else {
19633 self.generate_expression(base)?;
19635 self.write(", ");
19636 self.generate_expression(&f.this)?;
19637 }
19638 self.write(")");
19639 } else {
19640 self.write_func_name("LOG");
19642 self.write("(");
19643 self.generate_expression(&f.this)?;
19644 self.write(")");
19645 }
19646 Ok(())
19647 }
19648
19649 fn is_log_value_first(&self) -> bool {
19652 use crate::dialects::DialectType;
19653 matches!(
19654 self.config.dialect,
19655 Some(DialectType::BigQuery)
19656 | Some(DialectType::TSQL)
19657 | Some(DialectType::Tableau)
19658 | Some(DialectType::Fabric)
19659 )
19660 }
19661
19662 fn is_log_base_none(&self) -> bool {
19665 use crate::dialects::DialectType;
19666 matches!(
19667 self.config.dialect,
19668 Some(DialectType::Presto)
19669 | Some(DialectType::Trino)
19670 | Some(DialectType::ClickHouse)
19671 | Some(DialectType::Athena)
19672 )
19673 }
19674
19675 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
19678 self.write_keyword("CURRENT_TIME");
19679 if let Some(precision) = f.precision {
19680 self.write(&format!("({})", precision));
19681 } else if matches!(
19682 self.config.dialect,
19683 Some(crate::dialects::DialectType::MySQL)
19684 | Some(crate::dialects::DialectType::SingleStore)
19685 | Some(crate::dialects::DialectType::TiDB)
19686 ) {
19687 self.write("()");
19688 }
19689 Ok(())
19690 }
19691
19692 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
19693 use crate::dialects::DialectType;
19694
19695 if f.sysdate {
19697 match self.config.dialect {
19698 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
19699 self.write_keyword("SYSDATE");
19700 return Ok(());
19701 }
19702 Some(DialectType::Snowflake) => {
19703 self.write_keyword("SYSDATE");
19705 self.write("()");
19706 return Ok(());
19707 }
19708 _ => {
19709 }
19711 }
19712 }
19713
19714 self.write_keyword("CURRENT_TIMESTAMP");
19715 if let Some(precision) = f.precision {
19717 self.write(&format!("({})", precision));
19718 } else if matches!(
19719 self.config.dialect,
19720 Some(crate::dialects::DialectType::MySQL)
19721 | Some(crate::dialects::DialectType::SingleStore)
19722 | Some(crate::dialects::DialectType::TiDB)
19723 | Some(crate::dialects::DialectType::Spark)
19724 | Some(crate::dialects::DialectType::Hive)
19725 | Some(crate::dialects::DialectType::Databricks)
19726 | Some(crate::dialects::DialectType::ClickHouse)
19727 | Some(crate::dialects::DialectType::BigQuery)
19728 | Some(crate::dialects::DialectType::Snowflake)
19729 | Some(crate::dialects::DialectType::Exasol)
19730 ) {
19731 self.write("()");
19732 }
19733 Ok(())
19734 }
19735
19736 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
19737 if self.config.dialect == Some(DialectType::Exasol) {
19739 self.write_keyword("CONVERT_TZ");
19740 self.write("(");
19741 self.generate_expression(&f.this)?;
19742 self.write(", 'UTC', ");
19743 self.generate_expression(&f.zone)?;
19744 self.write(")");
19745 return Ok(());
19746 }
19747
19748 self.generate_expression(&f.this)?;
19749 self.write_space();
19750 self.write_keyword("AT TIME ZONE");
19751 self.write_space();
19752 self.generate_expression(&f.zone)?;
19753 Ok(())
19754 }
19755
19756 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
19757 use crate::dialects::DialectType;
19758
19759 let is_presto_like = matches!(
19762 self.config.dialect,
19763 Some(DialectType::Presto) | Some(DialectType::Trino)
19764 );
19765
19766 if is_presto_like {
19767 self.write_keyword(name);
19768 self.write("(");
19769 self.write("'");
19771 self.write_simple_interval_unit(&f.unit, false);
19772 self.write("'");
19773 self.write(", ");
19774 let needs_cast = !self.returns_integer_type(&f.interval);
19776 if needs_cast {
19777 self.write_keyword("CAST");
19778 self.write("(");
19779 }
19780 self.generate_expression(&f.interval)?;
19781 if needs_cast {
19782 self.write_space();
19783 self.write_keyword("AS");
19784 self.write_space();
19785 self.write_keyword("BIGINT");
19786 self.write(")");
19787 }
19788 self.write(", ");
19789 self.generate_expression(&f.this)?;
19790 self.write(")");
19791 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
19792 self.generate_expression(&f.this)?;
19793 self.write_space();
19794 if name.eq_ignore_ascii_case("DATE_SUB") {
19795 self.write("-");
19796 } else {
19797 self.write("+");
19798 }
19799 self.write_space();
19800 self.write_keyword("INTERVAL");
19801 self.write_space();
19802 self.write("'");
19803 let mut interval_gen = Generator::with_arc_config(self.config.clone());
19804 let interval_sql = interval_gen.generate(&f.interval)?;
19805 self.write(&interval_sql);
19806 self.write(" ");
19807 self.write_simple_interval_unit(&f.unit, false);
19808 self.write("'");
19809 } else {
19810 self.write_keyword(name);
19811 self.write("(");
19812 self.generate_expression(&f.this)?;
19813 self.write(", ");
19814 self.write_keyword("INTERVAL");
19815 self.write_space();
19816 self.generate_expression(&f.interval)?;
19817 self.write_space();
19818 self.write_simple_interval_unit(&f.unit, false); self.write(")");
19820 }
19821 Ok(())
19822 }
19823
19824 fn returns_integer_type(&self, expr: &Expression) -> bool {
19827 use crate::expressions::{DataType, Literal};
19828 match expr {
19829 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
19831 let Literal::Number(n) = lit.as_ref() else {
19832 unreachable!()
19833 };
19834 !n.contains('.')
19835 }
19836
19837 Expression::Floor(f) => self.returns_integer_type(&f.this),
19839
19840 Expression::Round(f) => {
19842 f.decimals.is_none() && self.returns_integer_type(&f.this)
19844 }
19845
19846 Expression::Sign(f) => self.returns_integer_type(&f.this),
19848
19849 Expression::Abs(f) => self.returns_integer_type(&f.this),
19851
19852 Expression::Mul(op) => {
19854 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19855 }
19856 Expression::Add(op) => {
19857 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19858 }
19859 Expression::Sub(op) => {
19860 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19861 }
19862 Expression::Mod(op) => self.returns_integer_type(&op.left),
19863
19864 Expression::Cast(c) => matches!(
19866 &c.to,
19867 DataType::BigInt { .. }
19868 | DataType::Int { .. }
19869 | DataType::SmallInt { .. }
19870 | DataType::TinyInt { .. }
19871 ),
19872
19873 Expression::Neg(op) => self.returns_integer_type(&op.this),
19875
19876 Expression::Paren(p) => self.returns_integer_type(&p.this),
19878
19879 _ => false,
19882 }
19883 }
19884
19885 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
19886 self.write_keyword("DATEDIFF");
19887 self.write("(");
19888 if let Some(unit) = &f.unit {
19889 self.write_simple_interval_unit(unit, false); self.write(", ");
19891 }
19892 if self.config.dialect == Some(DialectType::Snowflake) {
19893 self.generate_expression(&f.expression)?;
19894 self.write(", ");
19895 self.generate_expression(&f.this)?;
19896 } else {
19897 self.generate_expression(&f.this)?;
19898 self.write(", ");
19899 self.generate_expression(&f.expression)?;
19900 }
19901 self.write(")");
19902 Ok(())
19903 }
19904
19905 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
19906 if self.config.dialect == Some(DialectType::ClickHouse) {
19907 self.write("dateTrunc");
19908 } else {
19909 self.write_keyword("DATE_TRUNC");
19910 }
19911 self.write("('");
19912 self.write_datetime_field(&f.unit);
19913 self.write("', ");
19914 self.generate_expression(&f.this)?;
19915 self.write(")");
19916 Ok(())
19917 }
19918
19919 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
19920 use crate::dialects::DialectType;
19921 use crate::expressions::DateTimeField;
19922
19923 self.write_keyword("LAST_DAY");
19924 self.write("(");
19925 self.generate_expression(&f.this)?;
19926 if let Some(unit) = &f.unit {
19927 self.write(", ");
19928 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
19931 if let DateTimeField::WeekWithModifier(_) = unit {
19932 self.write_keyword("WEEK");
19933 } else {
19934 self.write_datetime_field(unit);
19935 }
19936 } else {
19937 self.write_datetime_field(unit);
19938 }
19939 }
19940 self.write(")");
19941 Ok(())
19942 }
19943
19944 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
19945 if matches!(
19947 self.config.dialect,
19948 Some(DialectType::TSQL) | Some(DialectType::Fabric)
19949 ) {
19950 self.write_keyword("DATEPART");
19951 self.write("(");
19952 self.write_datetime_field(&f.field);
19953 self.write(", ");
19954 self.generate_expression(&f.this)?;
19955 self.write(")");
19956 return Ok(());
19957 }
19958 self.write_keyword("EXTRACT");
19959 self.write("(");
19960 if matches!(
19962 self.config.dialect,
19963 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
19964 ) {
19965 self.write_datetime_field_lower(&f.field);
19966 } else {
19967 self.write_datetime_field(&f.field);
19968 }
19969 self.write_space();
19970 self.write_keyword("FROM");
19971 self.write_space();
19972 self.generate_expression(&f.this)?;
19973 self.write(")");
19974 Ok(())
19975 }
19976
19977 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
19978 self.write_keyword("TO_DATE");
19979 self.write("(");
19980 self.generate_expression(&f.this)?;
19981 if let Some(format) = &f.format {
19982 self.write(", ");
19983 self.generate_expression(format)?;
19984 }
19985 self.write(")");
19986 Ok(())
19987 }
19988
19989 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
19990 self.write_keyword("TO_TIMESTAMP");
19991 self.write("(");
19992 self.generate_expression(&f.this)?;
19993 if let Some(format) = &f.format {
19994 self.write(", ");
19995 self.generate_expression(format)?;
19996 }
19997 self.write(")");
19998 Ok(())
19999 }
20000
20001 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
20004 use crate::dialects::DialectType;
20005
20006 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
20008 self.write_keyword("CASE WHEN");
20009 self.write_space();
20010 self.generate_expression(&f.condition)?;
20011 self.write_space();
20012 self.write_keyword("THEN");
20013 self.write_space();
20014 self.generate_expression(&f.true_value)?;
20015 if let Some(false_val) = &f.false_value {
20016 self.write_space();
20017 self.write_keyword("ELSE");
20018 self.write_space();
20019 self.generate_expression(false_val)?;
20020 }
20021 self.write_space();
20022 self.write_keyword("END");
20023 return Ok(());
20024 }
20025
20026 if self.config.dialect == Some(DialectType::Exasol) {
20028 self.write_keyword("IF");
20029 self.write_space();
20030 self.generate_expression(&f.condition)?;
20031 self.write_space();
20032 self.write_keyword("THEN");
20033 self.write_space();
20034 self.generate_expression(&f.true_value)?;
20035 if let Some(false_val) = &f.false_value {
20036 self.write_space();
20037 self.write_keyword("ELSE");
20038 self.write_space();
20039 self.generate_expression(false_val)?;
20040 }
20041 self.write_space();
20042 self.write_keyword("ENDIF");
20043 return Ok(());
20044 }
20045
20046 let func_name = match self.config.dialect {
20048 Some(DialectType::ClickHouse) => f.original_name.as_deref().unwrap_or("IF"),
20049 Some(DialectType::Snowflake) => "IFF",
20050 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
20051 Some(DialectType::Drill) => "`IF`",
20052 _ => "IF",
20053 };
20054 self.write(func_name);
20055 self.write("(");
20056 self.generate_expression(&f.condition)?;
20057 self.write(", ");
20058 self.generate_expression(&f.true_value)?;
20059 if let Some(false_val) = &f.false_value {
20060 self.write(", ");
20061 self.generate_expression(false_val)?;
20062 }
20063 self.write(")");
20064 Ok(())
20065 }
20066
20067 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
20068 self.write_keyword("NVL2");
20069 self.write("(");
20070 self.generate_expression(&f.this)?;
20071 self.write(", ");
20072 self.generate_expression(&f.true_value)?;
20073 self.write(", ");
20074 self.generate_expression(&f.false_value)?;
20075 self.write(")");
20076 Ok(())
20077 }
20078
20079 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
20082 let count_name = match self.config.normalize_functions {
20084 NormalizeFunctions::Upper => "COUNT".to_string(),
20085 NormalizeFunctions::Lower => "count".to_string(),
20086 NormalizeFunctions::None => f
20087 .original_name
20088 .clone()
20089 .unwrap_or_else(|| "COUNT".to_string()),
20090 };
20091 self.write(&count_name);
20092 self.write("(");
20093 if f.distinct {
20094 self.write_keyword("DISTINCT");
20095 self.write_space();
20096 }
20097 if f.star {
20098 self.write("*");
20099 } else if let Some(ref expr) = f.this {
20100 if let Expression::Tuple(tuple) = expr {
20102 let needs_transform =
20106 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
20107
20108 if needs_transform {
20109 self.write_keyword("CASE");
20111 for e in &tuple.expressions {
20112 self.write_space();
20113 self.write_keyword("WHEN");
20114 self.write_space();
20115 self.generate_expression(e)?;
20116 self.write_space();
20117 self.write_keyword("IS NULL THEN NULL");
20118 }
20119 self.write_space();
20120 self.write_keyword("ELSE");
20121 self.write(" (");
20122 for (i, e) in tuple.expressions.iter().enumerate() {
20123 if i > 0 {
20124 self.write(", ");
20125 }
20126 self.generate_expression(e)?;
20127 }
20128 self.write(")");
20129 self.write_space();
20130 self.write_keyword("END");
20131 } else {
20132 for (i, e) in tuple.expressions.iter().enumerate() {
20133 if i > 0 {
20134 self.write(", ");
20135 }
20136 self.generate_expression(e)?;
20137 }
20138 }
20139 } else {
20140 self.generate_expression(expr)?;
20141 }
20142 }
20143 let clickhouse_ignore_nulls_outside =
20144 matches!(self.config.dialect, Some(DialectType::ClickHouse));
20145 if let Some(ignore) = f.ignore_nulls.filter(|_| !clickhouse_ignore_nulls_outside) {
20146 self.write_space();
20147 if ignore {
20148 self.write_keyword("IGNORE NULLS");
20149 } else {
20150 self.write_keyword("RESPECT NULLS");
20151 }
20152 }
20153 self.write(")");
20154 if let Some(ignore) = f.ignore_nulls.filter(|_| clickhouse_ignore_nulls_outside) {
20155 self.write_space();
20156 if ignore {
20157 self.write_keyword("IGNORE NULLS");
20158 } else {
20159 self.write_keyword("RESPECT NULLS");
20160 }
20161 }
20162 if let Some(ref filter) = f.filter {
20163 self.write_space();
20164 self.write_keyword("FILTER");
20165 self.write("(");
20166 self.write_keyword("WHERE");
20167 self.write_space();
20168 self.generate_expression(filter)?;
20169 self.write(")");
20170 }
20171 Ok(())
20172 }
20173
20174 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
20175 let func_name: Cow<'_, str> = match self.config.normalize_functions {
20177 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
20178 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
20179 NormalizeFunctions::None => {
20180 if let Some(ref original) = f.name {
20183 Cow::Owned(original.clone())
20184 } else {
20185 Cow::Owned(name.to_ascii_lowercase())
20186 }
20187 }
20188 };
20189 self.write(func_name.as_ref());
20190 self.write("(");
20191 if f.distinct {
20192 self.write_keyword("DISTINCT");
20193 self.write_space();
20194 }
20195 let is_zero_arg_mode =
20198 name.eq_ignore_ascii_case("MODE") && matches!(f.this, Expression::Null(_));
20199 if !is_zero_arg_mode {
20200 self.generate_expression(&f.this)?;
20201 }
20202 if self.config.ignore_nulls_in_func
20205 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
20206 {
20207 match f.ignore_nulls {
20208 Some(true) => {
20209 self.write_space();
20210 self.write_keyword("IGNORE NULLS");
20211 }
20212 Some(false) => {
20213 self.write_space();
20214 self.write_keyword("RESPECT NULLS");
20215 }
20216 None => {}
20217 }
20218 }
20219 if let Some((ref expr, is_max)) = f.having_max {
20222 self.write_space();
20223 self.write_keyword("HAVING");
20224 self.write_space();
20225 if is_max {
20226 self.write_keyword("MAX");
20227 } else {
20228 self.write_keyword("MIN");
20229 }
20230 self.write_space();
20231 self.generate_expression(expr)?;
20232 }
20233 if !f.order_by.is_empty() {
20235 self.write_space();
20236 self.write_keyword("ORDER BY");
20237 self.write_space();
20238 for (i, ord) in f.order_by.iter().enumerate() {
20239 if i > 0 {
20240 self.write(", ");
20241 }
20242 self.generate_ordered(ord)?;
20243 }
20244 }
20245 if let Some(ref limit) = f.limit {
20247 self.write_space();
20248 self.write_keyword("LIMIT");
20249 self.write_space();
20250 if let Expression::Tuple(t) = limit.as_ref() {
20252 if t.expressions.len() == 2 {
20253 self.generate_expression(&t.expressions[0])?;
20254 self.write(", ");
20255 self.generate_expression(&t.expressions[1])?;
20256 } else {
20257 self.generate_expression(limit)?;
20258 }
20259 } else {
20260 self.generate_expression(limit)?;
20261 }
20262 }
20263 self.write(")");
20264 if !self.config.ignore_nulls_in_func
20267 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
20268 {
20269 match f.ignore_nulls {
20270 Some(true) => {
20271 self.write_space();
20272 self.write_keyword("IGNORE NULLS");
20273 }
20274 Some(false) => {
20275 self.write_space();
20276 self.write_keyword("RESPECT NULLS");
20277 }
20278 None => {}
20279 }
20280 }
20281 if let Some(ref filter) = f.filter {
20282 self.write_space();
20283 self.write_keyword("FILTER");
20284 self.write("(");
20285 self.write_keyword("WHERE");
20286 self.write_space();
20287 self.generate_expression(filter)?;
20288 self.write(")");
20289 }
20290 Ok(())
20291 }
20292
20293 fn generate_agg_func_with_ignore_nulls_bool(&mut self, name: &str, f: &AggFunc) -> Result<()> {
20296 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
20298 let func_name: Cow<'_, str> = match self.config.normalize_functions {
20300 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
20301 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
20302 NormalizeFunctions::None => {
20303 if let Some(ref original) = f.name {
20304 Cow::Owned(original.clone())
20305 } else {
20306 Cow::Owned(name.to_ascii_lowercase())
20307 }
20308 }
20309 };
20310 self.write(func_name.as_ref());
20311 self.write("(");
20312 if f.distinct {
20313 self.write_keyword("DISTINCT");
20314 self.write_space();
20315 }
20316 if !matches!(f.this, Expression::Null(_)) {
20317 self.generate_expression(&f.this)?;
20318 }
20319 self.write(", ");
20320 self.write_keyword("TRUE");
20321 self.write(")");
20322 return Ok(());
20323 }
20324 self.generate_agg_func(name, f)
20325 }
20326
20327 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
20328 self.write_keyword("GROUP_CONCAT");
20329 self.write("(");
20330 if f.distinct {
20331 self.write_keyword("DISTINCT");
20332 self.write_space();
20333 }
20334 self.generate_expression(&f.this)?;
20335 if let Some(ref order_by) = f.order_by {
20336 self.write_space();
20337 self.write_keyword("ORDER BY");
20338 self.write_space();
20339 for (i, ord) in order_by.iter().enumerate() {
20340 if i > 0 {
20341 self.write(", ");
20342 }
20343 self.generate_ordered(ord)?;
20344 }
20345 }
20346 if let Some(ref sep) = f.separator {
20347 if matches!(
20350 self.config.dialect,
20351 Some(crate::dialects::DialectType::SQLite)
20352 ) {
20353 self.write(", ");
20354 self.generate_expression(sep)?;
20355 } else {
20356 self.write_space();
20357 self.write_keyword("SEPARATOR");
20358 self.write_space();
20359 self.generate_expression(sep)?;
20360 }
20361 }
20362 if let Some(ref limit) = f.limit {
20363 self.write_space();
20364 self.write_keyword("LIMIT");
20365 self.write_space();
20366 self.generate_expression(limit)?;
20367 }
20368 self.write(")");
20369 if let Some(ref filter) = f.filter {
20370 self.write_space();
20371 self.write_keyword("FILTER");
20372 self.write("(");
20373 self.write_keyword("WHERE");
20374 self.write_space();
20375 self.generate_expression(filter)?;
20376 self.write(")");
20377 }
20378 Ok(())
20379 }
20380
20381 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
20382 let uses_within_group_order = matches!(
20383 self.config.dialect,
20384 Some(crate::dialects::DialectType::TSQL | crate::dialects::DialectType::Fabric)
20385 );
20386 self.write_keyword("STRING_AGG");
20387 self.write("(");
20388 if f.distinct {
20389 self.write_keyword("DISTINCT");
20390 self.write_space();
20391 }
20392 self.generate_expression(&f.this)?;
20393 if let Some(ref separator) = f.separator {
20394 self.write(", ");
20395 self.generate_expression(separator)?;
20396 }
20397 if !uses_within_group_order {
20399 if let Some(ref order_by) = f.order_by {
20400 self.write_space();
20401 self.write_keyword("ORDER BY");
20402 self.write_space();
20403 for (i, ord) in order_by.iter().enumerate() {
20404 if i > 0 {
20405 self.write(", ");
20406 }
20407 self.generate_ordered(ord)?;
20408 }
20409 }
20410 }
20411 if let Some(ref limit) = f.limit {
20412 self.write_space();
20413 self.write_keyword("LIMIT");
20414 self.write_space();
20415 self.generate_expression(limit)?;
20416 }
20417 self.write(")");
20418 if uses_within_group_order {
20419 if let Some(ref order_by) = f.order_by {
20420 self.write_space();
20421 self.write_keyword("WITHIN GROUP");
20422 self.write(" (");
20423 self.write_keyword("ORDER BY");
20424 self.write_space();
20425 for (i, ord) in order_by.iter().enumerate() {
20426 if i > 0 {
20427 self.write(", ");
20428 }
20429 self.generate_ordered(ord)?;
20430 }
20431 self.write(")");
20432 }
20433 }
20434 if let Some(ref filter) = f.filter {
20435 self.write_space();
20436 self.write_keyword("FILTER");
20437 self.write("(");
20438 self.write_keyword("WHERE");
20439 self.write_space();
20440 self.generate_expression(filter)?;
20441 self.write(")");
20442 }
20443 Ok(())
20444 }
20445
20446 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
20447 use crate::dialects::DialectType;
20448 let order_inside_args = matches!(self.config.dialect, Some(DialectType::DuckDB));
20449 self.write_keyword("LISTAGG");
20450 self.write("(");
20451 if f.distinct {
20452 self.write_keyword("DISTINCT");
20453 self.write_space();
20454 }
20455 self.generate_expression(&f.this)?;
20456 if let Some(ref sep) = f.separator {
20457 self.write(", ");
20458 self.generate_expression(sep)?;
20459 } else if matches!(
20460 self.config.dialect,
20461 Some(DialectType::Trino) | Some(DialectType::Presto)
20462 ) {
20463 self.write(", ','");
20465 }
20466 if let Some(ref overflow) = f.on_overflow {
20467 self.write_space();
20468 self.write_keyword("ON OVERFLOW");
20469 self.write_space();
20470 match overflow {
20471 ListAggOverflow::Error => self.write_keyword("ERROR"),
20472 ListAggOverflow::Truncate { filler, with_count } => {
20473 self.write_keyword("TRUNCATE");
20474 if let Some(ref fill) = filler {
20475 self.write_space();
20476 self.generate_expression(fill)?;
20477 }
20478 if *with_count {
20479 self.write_space();
20480 self.write_keyword("WITH COUNT");
20481 } else {
20482 self.write_space();
20483 self.write_keyword("WITHOUT COUNT");
20484 }
20485 }
20486 }
20487 }
20488 if order_inside_args {
20489 if let Some(ref order_by) = f.order_by {
20490 self.write_space();
20491 self.write_keyword("ORDER BY");
20492 self.write_space();
20493 for (i, ord) in order_by.iter().enumerate() {
20494 if i > 0 {
20495 self.write(", ");
20496 }
20497 self.generate_ordered(ord)?;
20498 }
20499 }
20500 }
20501 self.write(")");
20502 if !order_inside_args {
20503 if let Some(ref order_by) = f.order_by {
20504 self.write_space();
20505 self.write_keyword("WITHIN GROUP");
20506 self.write(" (");
20507 self.write_keyword("ORDER BY");
20508 self.write_space();
20509 for (i, ord) in order_by.iter().enumerate() {
20510 if i > 0 {
20511 self.write(", ");
20512 }
20513 self.generate_ordered(ord)?;
20514 }
20515 self.write(")");
20516 }
20517 }
20518 if let Some(ref filter) = f.filter {
20519 self.write_space();
20520 self.write_keyword("FILTER");
20521 self.write("(");
20522 self.write_keyword("WHERE");
20523 self.write_space();
20524 self.generate_expression(filter)?;
20525 self.write(")");
20526 }
20527 Ok(())
20528 }
20529
20530 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
20531 self.write_keyword("SUM_IF");
20532 self.write("(");
20533 self.generate_expression(&f.this)?;
20534 self.write(", ");
20535 self.generate_expression(&f.condition)?;
20536 self.write(")");
20537 if let Some(ref filter) = f.filter {
20538 self.write_space();
20539 self.write_keyword("FILTER");
20540 self.write("(");
20541 self.write_keyword("WHERE");
20542 self.write_space();
20543 self.generate_expression(filter)?;
20544 self.write(")");
20545 }
20546 Ok(())
20547 }
20548
20549 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
20550 self.write_keyword("APPROX_PERCENTILE");
20551 self.write("(");
20552 self.generate_expression(&f.this)?;
20553 self.write(", ");
20554 self.generate_expression(&f.percentile)?;
20555 if let Some(ref acc) = f.accuracy {
20556 self.write(", ");
20557 self.generate_expression(acc)?;
20558 }
20559 self.write(")");
20560 if let Some(ref filter) = f.filter {
20561 self.write_space();
20562 self.write_keyword("FILTER");
20563 self.write("(");
20564 self.write_keyword("WHERE");
20565 self.write_space();
20566 self.generate_expression(filter)?;
20567 self.write(")");
20568 }
20569 Ok(())
20570 }
20571
20572 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
20573 self.write_keyword(name);
20574 self.write("(");
20575 self.generate_expression(&f.percentile)?;
20576 self.write(")");
20577 if let Some(ref order_by) = f.order_by {
20578 self.write_space();
20579 self.write_keyword("WITHIN GROUP");
20580 self.write(" (");
20581 self.write_keyword("ORDER BY");
20582 self.write_space();
20583 self.generate_expression(&f.this)?;
20584 for ord in order_by.iter() {
20585 if ord.desc {
20586 self.write_space();
20587 self.write_keyword("DESC");
20588 }
20589 }
20590 self.write(")");
20591 }
20592 if let Some(ref filter) = f.filter {
20593 self.write_space();
20594 self.write_keyword("FILTER");
20595 self.write("(");
20596 self.write_keyword("WHERE");
20597 self.write_space();
20598 self.generate_expression(filter)?;
20599 self.write(")");
20600 }
20601 Ok(())
20602 }
20603
20604 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
20607 self.write_keyword("NTILE");
20608 self.write("(");
20609 if let Some(num_buckets) = &f.num_buckets {
20610 self.generate_expression(num_buckets)?;
20611 }
20612 if let Some(order_by) = &f.order_by {
20613 self.write_keyword(" ORDER BY ");
20614 for (i, ob) in order_by.iter().enumerate() {
20615 if i > 0 {
20616 self.write(", ");
20617 }
20618 self.generate_ordered(ob)?;
20619 }
20620 }
20621 self.write(")");
20622 Ok(())
20623 }
20624
20625 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
20626 self.write_keyword(name);
20627 self.write("(");
20628 self.generate_expression(&f.this)?;
20629 if let Some(ref offset) = f.offset {
20630 self.write(", ");
20631 self.generate_expression(offset)?;
20632 if let Some(ref default) = f.default {
20633 self.write(", ");
20634 self.generate_expression(default)?;
20635 }
20636 }
20637 if self.config.ignore_nulls_in_func {
20639 match f.ignore_nulls {
20640 Some(true) => {
20641 self.write_space();
20642 self.write_keyword("IGNORE NULLS");
20643 }
20644 Some(false) => {
20645 self.write_space();
20646 self.write_keyword("RESPECT NULLS");
20647 }
20648 None => {}
20649 }
20650 }
20651 self.write(")");
20652 if !self.config.ignore_nulls_in_func {
20654 match f.ignore_nulls {
20655 Some(true) => {
20656 self.write_space();
20657 self.write_keyword("IGNORE NULLS");
20658 }
20659 Some(false) => {
20660 self.write_space();
20661 self.write_keyword("RESPECT NULLS");
20662 }
20663 None => {}
20664 }
20665 }
20666 Ok(())
20667 }
20668
20669 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
20670 self.write_keyword(name);
20671 self.write("(");
20672 self.generate_expression(&f.this)?;
20673 if !f.order_by.is_empty() {
20675 self.write_space();
20676 self.write_keyword("ORDER BY");
20677 self.write_space();
20678 for (i, ordered) in f.order_by.iter().enumerate() {
20679 if i > 0 {
20680 self.write(", ");
20681 }
20682 self.generate_ordered(ordered)?;
20683 }
20684 }
20685 if self.config.ignore_nulls_in_func {
20687 match f.ignore_nulls {
20688 Some(true) => {
20689 self.write_space();
20690 self.write_keyword("IGNORE NULLS");
20691 }
20692 Some(false) => {
20693 self.write_space();
20694 self.write_keyword("RESPECT NULLS");
20695 }
20696 None => {}
20697 }
20698 }
20699 self.write(")");
20700 if !self.config.ignore_nulls_in_func {
20702 match f.ignore_nulls {
20703 Some(true) => {
20704 self.write_space();
20705 self.write_keyword("IGNORE NULLS");
20706 }
20707 Some(false) => {
20708 self.write_space();
20709 self.write_keyword("RESPECT NULLS");
20710 }
20711 None => {}
20712 }
20713 }
20714 Ok(())
20715 }
20716
20717 fn generate_value_func_with_ignore_nulls_bool(
20720 &mut self,
20721 name: &str,
20722 f: &ValueFunc,
20723 ) -> Result<()> {
20724 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
20725 self.write_keyword(name);
20726 self.write("(");
20727 self.generate_expression(&f.this)?;
20728 self.write(", ");
20729 self.write_keyword("TRUE");
20730 self.write(")");
20731 return Ok(());
20732 }
20733 self.generate_value_func(name, f)
20734 }
20735
20736 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
20737 self.write_keyword("NTH_VALUE");
20738 self.write("(");
20739 self.generate_expression(&f.this)?;
20740 self.write(", ");
20741 self.generate_expression(&f.offset)?;
20742 if self.config.ignore_nulls_in_func {
20744 match f.ignore_nulls {
20745 Some(true) => {
20746 self.write_space();
20747 self.write_keyword("IGNORE NULLS");
20748 }
20749 Some(false) => {
20750 self.write_space();
20751 self.write_keyword("RESPECT NULLS");
20752 }
20753 None => {}
20754 }
20755 }
20756 self.write(")");
20757 if matches!(
20759 self.config.dialect,
20760 Some(crate::dialects::DialectType::Snowflake)
20761 ) {
20762 match f.from_first {
20763 Some(true) => {
20764 self.write_space();
20765 self.write_keyword("FROM FIRST");
20766 }
20767 Some(false) => {
20768 self.write_space();
20769 self.write_keyword("FROM LAST");
20770 }
20771 None => {}
20772 }
20773 }
20774 if !self.config.ignore_nulls_in_func {
20776 match f.ignore_nulls {
20777 Some(true) => {
20778 self.write_space();
20779 self.write_keyword("IGNORE NULLS");
20780 }
20781 Some(false) => {
20782 self.write_space();
20783 self.write_keyword("RESPECT NULLS");
20784 }
20785 None => {}
20786 }
20787 }
20788 Ok(())
20789 }
20790
20791 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
20794 if matches!(
20797 self.config.dialect,
20798 Some(crate::dialects::DialectType::ClickHouse)
20799 ) {
20800 self.write_keyword("POSITION");
20801 self.write("(");
20802 self.generate_expression(&f.string)?;
20803 self.write(", ");
20804 self.generate_expression(&f.substring)?;
20805 if let Some(ref start) = f.start {
20806 self.write(", ");
20807 self.generate_expression(start)?;
20808 }
20809 self.write(")");
20810 return Ok(());
20811 }
20812
20813 self.write_keyword("POSITION");
20814 self.write("(");
20815 self.generate_expression(&f.substring)?;
20816 self.write_space();
20817 self.write_keyword("IN");
20818 self.write_space();
20819 self.generate_expression(&f.string)?;
20820 if let Some(ref start) = f.start {
20821 self.write(", ");
20822 self.generate_expression(start)?;
20823 }
20824 self.write(")");
20825 Ok(())
20826 }
20827
20828 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
20831 if f.lower.is_some() || f.upper.is_some() {
20833 self.write_keyword("RANDOM");
20834 self.write("(");
20835 if let Some(ref lower) = f.lower {
20836 self.generate_expression(lower)?;
20837 }
20838 if let Some(ref upper) = f.upper {
20839 self.write(", ");
20840 self.generate_expression(upper)?;
20841 }
20842 self.write(")");
20843 return Ok(());
20844 }
20845 let func_name = match self.config.dialect {
20847 Some(crate::dialects::DialectType::Snowflake)
20848 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
20849 _ => "RAND",
20850 };
20851 self.write_keyword(func_name);
20852 self.write("(");
20853 if !matches!(
20855 self.config.dialect,
20856 Some(crate::dialects::DialectType::DuckDB)
20857 ) {
20858 if let Some(ref seed) = f.seed {
20859 self.generate_expression(seed)?;
20860 }
20861 }
20862 self.write(")");
20863 Ok(())
20864 }
20865
20866 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
20867 self.write_keyword("TRUNCATE");
20868 self.write("(");
20869 self.generate_expression(&f.this)?;
20870 if let Some(ref decimals) = f.decimals {
20871 self.write(", ");
20872 self.generate_expression(decimals)?;
20873 }
20874 self.write(")");
20875 Ok(())
20876 }
20877
20878 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
20881 self.write_keyword("DECODE");
20882 self.write("(");
20883 self.generate_expression(&f.this)?;
20884 for (search, result) in &f.search_results {
20885 self.write(", ");
20886 self.generate_expression(search)?;
20887 self.write(", ");
20888 self.generate_expression(result)?;
20889 }
20890 if let Some(ref default) = f.default {
20891 self.write(", ");
20892 self.generate_expression(default)?;
20893 }
20894 self.write(")");
20895 Ok(())
20896 }
20897
20898 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
20901 self.write_keyword(name);
20902 self.write("(");
20903 self.generate_expression(&f.this)?;
20904 self.write(", ");
20905 self.generate_expression(&f.format)?;
20906 self.write(")");
20907 Ok(())
20908 }
20909
20910 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
20911 self.write_keyword("FROM_UNIXTIME");
20912 self.write("(");
20913 self.generate_expression(&f.this)?;
20914 if let Some(ref format) = f.format {
20915 self.write(", ");
20916 self.generate_expression(format)?;
20917 }
20918 self.write(")");
20919 Ok(())
20920 }
20921
20922 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
20923 self.write_keyword("UNIX_TIMESTAMP");
20924 self.write("(");
20925 if let Some(ref expr) = f.this {
20926 self.generate_expression(expr)?;
20927 if let Some(ref format) = f.format {
20928 self.write(", ");
20929 self.generate_expression(format)?;
20930 }
20931 } else if matches!(
20932 self.config.dialect,
20933 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
20934 ) {
20935 self.write_keyword("CURRENT_TIMESTAMP");
20937 self.write("()");
20938 }
20939 self.write(")");
20940 Ok(())
20941 }
20942
20943 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
20944 self.write_keyword("MAKE_DATE");
20945 self.write("(");
20946 self.generate_expression(&f.year)?;
20947 self.write(", ");
20948 self.generate_expression(&f.month)?;
20949 self.write(", ");
20950 self.generate_expression(&f.day)?;
20951 self.write(")");
20952 Ok(())
20953 }
20954
20955 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
20956 self.write_keyword("MAKE_TIMESTAMP");
20957 self.write("(");
20958 self.generate_expression(&f.year)?;
20959 self.write(", ");
20960 self.generate_expression(&f.month)?;
20961 self.write(", ");
20962 self.generate_expression(&f.day)?;
20963 self.write(", ");
20964 self.generate_expression(&f.hour)?;
20965 self.write(", ");
20966 self.generate_expression(&f.minute)?;
20967 self.write(", ");
20968 self.generate_expression(&f.second)?;
20969 if let Some(ref tz) = f.timezone {
20970 self.write(", ");
20971 self.generate_expression(tz)?;
20972 }
20973 self.write(")");
20974 Ok(())
20975 }
20976
20977 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
20979 match expr {
20980 Expression::Struct(s) => {
20981 if s.fields.iter().all(|(name, _)| name.is_some()) {
20982 Some(
20983 s.fields
20984 .iter()
20985 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
20986 .collect(),
20987 )
20988 } else {
20989 None
20990 }
20991 }
20992 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20993 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
20995 Some(
20996 f.args
20997 .iter()
20998 .filter_map(|a| {
20999 if let Expression::Alias(alias) = a {
21000 Some(alias.alias.name.clone())
21001 } else {
21002 None
21003 }
21004 })
21005 .collect(),
21006 )
21007 } else {
21008 None
21009 }
21010 }
21011 _ => None,
21012 }
21013 }
21014
21015 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
21017 match expr {
21018 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
21019 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
21020 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
21021 }
21022 _ => false,
21023 }
21024 }
21025
21026 fn struct_field_count(expr: &Expression) -> usize {
21028 match expr {
21029 Expression::Struct(s) => s.fields.len(),
21030 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => f.args.len(),
21031 _ => 0,
21032 }
21033 }
21034
21035 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
21037 match expr {
21038 Expression::Struct(s) => {
21039 let mut new_fields = Vec::with_capacity(s.fields.len());
21040 for (i, (name, value)) in s.fields.iter().enumerate() {
21041 if name.is_none() && i < field_names.len() {
21042 new_fields.push((Some(field_names[i].clone()), value.clone()));
21043 } else {
21044 new_fields.push((name.clone(), value.clone()));
21045 }
21046 }
21047 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
21048 }
21049 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
21050 let mut new_args = Vec::with_capacity(f.args.len());
21051 for (i, arg) in f.args.iter().enumerate() {
21052 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
21053 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
21055 this: arg.clone(),
21056 alias: crate::expressions::Identifier::new(field_names[i].clone()),
21057 column_aliases: Vec::new(),
21058 alias_explicit_as: false,
21059 alias_keyword: None,
21060 pre_alias_comments: Vec::new(),
21061 trailing_comments: Vec::new(),
21062 inferred_type: None,
21063 })));
21064 } else {
21065 new_args.push(arg.clone());
21066 }
21067 }
21068 Expression::Function(Box::new(crate::expressions::Function {
21069 name: f.name.clone(),
21070 args: new_args,
21071 distinct: f.distinct,
21072 trailing_comments: f.trailing_comments.clone(),
21073 use_bracket_syntax: f.use_bracket_syntax,
21074 no_parens: f.no_parens,
21075 quoted: f.quoted,
21076 span: None,
21077 inferred_type: None,
21078 }))
21079 }
21080 _ => expr.clone(),
21081 }
21082 }
21083
21084 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
21088 let first = match expressions.first() {
21089 Some(e) => e,
21090 None => return expressions.to_vec(),
21091 };
21092
21093 let field_names = match Self::extract_struct_field_names(first) {
21094 Some(names) if !names.is_empty() => names,
21095 _ => return expressions.to_vec(),
21096 };
21097
21098 let mut result = Vec::with_capacity(expressions.len());
21099 for (idx, expr) in expressions.iter().enumerate() {
21100 if idx == 0 {
21101 result.push(expr.clone());
21102 continue;
21103 }
21104 if Self::struct_field_count(expr) == field_names.len()
21106 && Self::struct_has_unnamed_fields(expr)
21107 {
21108 result.push(Self::apply_struct_field_names(expr, &field_names));
21109 } else {
21110 result.push(expr.clone());
21111 }
21112 }
21113 result
21114 }
21115
21116 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
21119 let needs_inheritance = matches!(
21122 self.config.dialect,
21123 Some(DialectType::DuckDB)
21124 | Some(DialectType::Spark)
21125 | Some(DialectType::Databricks)
21126 | Some(DialectType::Hive)
21127 | Some(DialectType::Snowflake)
21128 | Some(DialectType::Presto)
21129 | Some(DialectType::Trino)
21130 );
21131 let propagated: Vec<Expression>;
21132 let expressions = if needs_inheritance && f.expressions.len() > 1 {
21133 propagated = Self::inherit_struct_field_names(&f.expressions);
21134 &propagated
21135 } else {
21136 &f.expressions
21137 };
21138
21139 let should_split = if self.config.pretty && !expressions.is_empty() {
21141 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
21142 for expr in expressions {
21143 let mut temp_gen = Generator::with_arc_config(self.config.clone());
21144 Arc::make_mut(&mut temp_gen.config).pretty = false;
21145 temp_gen.generate_expression(expr)?;
21146 expr_strings.push(temp_gen.output);
21147 }
21148 self.too_wide(&expr_strings)
21149 } else {
21150 false
21151 };
21152
21153 if f.bracket_notation {
21154 let (open, close) = match self.config.dialect {
21158 None
21159 | Some(DialectType::Generic)
21160 | Some(DialectType::Spark)
21161 | Some(DialectType::Databricks)
21162 | Some(DialectType::Hive) => {
21163 self.write_keyword("ARRAY");
21164 ("(", ")")
21165 }
21166 Some(DialectType::Presto)
21167 | Some(DialectType::Trino)
21168 | Some(DialectType::PostgreSQL)
21169 | Some(DialectType::Redshift)
21170 | Some(DialectType::Materialize)
21171 | Some(DialectType::RisingWave)
21172 | Some(DialectType::CockroachDB) => {
21173 self.write_keyword("ARRAY");
21174 ("[", "]")
21175 }
21176 _ => ("[", "]"),
21177 };
21178 self.write(open);
21179 if should_split {
21180 self.write_newline();
21181 self.indent_level += 1;
21182 for (i, expr) in expressions.iter().enumerate() {
21183 self.write_indent();
21184 self.generate_expression(expr)?;
21185 if i + 1 < expressions.len() {
21186 self.write(",");
21187 }
21188 self.write_newline();
21189 }
21190 self.indent_level -= 1;
21191 self.write_indent();
21192 } else {
21193 for (i, expr) in expressions.iter().enumerate() {
21194 if i > 0 {
21195 self.write(", ");
21196 }
21197 self.generate_expression(expr)?;
21198 }
21199 }
21200 self.write(close);
21201 } else {
21202 if f.use_list_keyword {
21204 self.write_keyword("LIST");
21205 } else {
21206 self.write_keyword("ARRAY");
21207 }
21208 let has_subquery = expressions
21211 .iter()
21212 .any(|e| matches!(e, Expression::Select(_)));
21213 let (open, close) = if matches!(
21214 self.config.dialect,
21215 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
21216 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
21217 && has_subquery)
21218 {
21219 ("(", ")")
21220 } else {
21221 ("[", "]")
21222 };
21223 self.write(open);
21224 if should_split {
21225 self.write_newline();
21226 self.indent_level += 1;
21227 for (i, expr) in expressions.iter().enumerate() {
21228 self.write_indent();
21229 self.generate_expression(expr)?;
21230 if i + 1 < expressions.len() {
21231 self.write(",");
21232 }
21233 self.write_newline();
21234 }
21235 self.indent_level -= 1;
21236 self.write_indent();
21237 } else {
21238 for (i, expr) in expressions.iter().enumerate() {
21239 if i > 0 {
21240 self.write(", ");
21241 }
21242 self.generate_expression(expr)?;
21243 }
21244 }
21245 self.write(close);
21246 }
21247 Ok(())
21248 }
21249
21250 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
21251 self.write_keyword("ARRAY_SORT");
21252 self.write("(");
21253 self.generate_expression(&f.this)?;
21254 if let Some(ref comp) = f.comparator {
21255 self.write(", ");
21256 self.generate_expression(comp)?;
21257 }
21258 self.write(")");
21259 Ok(())
21260 }
21261
21262 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
21263 self.write_keyword(name);
21264 self.write("(");
21265 self.generate_expression(&f.this)?;
21266 self.write(", ");
21267 self.generate_expression(&f.separator)?;
21268 if let Some(ref null_rep) = f.null_replacement {
21269 self.write(", ");
21270 self.generate_expression(null_rep)?;
21271 }
21272 self.write(")");
21273 Ok(())
21274 }
21275
21276 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
21277 self.write_keyword("UNNEST");
21278 self.write("(");
21279 self.generate_expression(&f.this)?;
21280 for extra in &f.expressions {
21281 self.write(", ");
21282 self.generate_expression(extra)?;
21283 }
21284 self.write(")");
21285 if f.with_ordinality {
21286 self.write_space();
21287 if self.config.unnest_with_ordinality {
21288 self.write_keyword("WITH ORDINALITY");
21290 } else if f.offset_alias.is_some() {
21291 if let Some(ref alias) = f.alias {
21294 self.write_keyword("AS");
21295 self.write_space();
21296 self.generate_identifier(alias)?;
21297 self.write_space();
21298 }
21299 self.write_keyword("WITH OFFSET");
21300 if let Some(ref offset_alias) = f.offset_alias {
21301 self.write_space();
21302 self.write_keyword("AS");
21303 self.write_space();
21304 self.generate_identifier(offset_alias)?;
21305 }
21306 } else {
21307 self.write_keyword("WITH OFFSET");
21309 if f.alias.is_none() {
21310 self.write(" AS offset");
21311 }
21312 }
21313 }
21314 if let Some(ref alias) = f.alias {
21315 let should_add_alias = if !f.with_ordinality {
21317 true
21318 } else if self.config.unnest_with_ordinality {
21319 true
21321 } else if f.offset_alias.is_some() {
21322 false
21324 } else {
21325 true
21327 };
21328 if should_add_alias {
21329 self.write_space();
21330 self.write_keyword("AS");
21331 self.write_space();
21332 self.generate_identifier(alias)?;
21333 }
21334 }
21335 Ok(())
21336 }
21337
21338 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
21339 self.write_keyword("FILTER");
21340 self.write("(");
21341 self.generate_expression(&f.this)?;
21342 self.write(", ");
21343 self.generate_expression(&f.filter)?;
21344 self.write(")");
21345 Ok(())
21346 }
21347
21348 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
21349 self.write_keyword("TRANSFORM");
21350 self.write("(");
21351 self.generate_expression(&f.this)?;
21352 self.write(", ");
21353 self.generate_expression(&f.transform)?;
21354 self.write(")");
21355 Ok(())
21356 }
21357
21358 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
21359 self.write_keyword(name);
21360 self.write("(");
21361 self.generate_expression(&f.start)?;
21362 self.write(", ");
21363 self.generate_expression(&f.stop)?;
21364 if let Some(ref step) = f.step {
21365 self.write(", ");
21366 self.generate_expression(step)?;
21367 }
21368 self.write(")");
21369 Ok(())
21370 }
21371
21372 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
21375 self.write_keyword("STRUCT");
21376 self.write("(");
21377 for (i, (name, expr)) in f.fields.iter().enumerate() {
21378 if i > 0 {
21379 self.write(", ");
21380 }
21381 if let Some(ref id) = name {
21382 self.generate_identifier(id)?;
21383 self.write(" ");
21384 self.write_keyword("AS");
21385 self.write(" ");
21386 }
21387 self.generate_expression(expr)?;
21388 }
21389 self.write(")");
21390 Ok(())
21391 }
21392
21393 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
21395 let mut names: Vec<Option<String>> = Vec::new();
21398 let mut values: Vec<&Expression> = Vec::new();
21399 let mut all_named = true;
21400
21401 for arg in &func.args {
21402 match arg {
21403 Expression::Alias(a) => {
21404 names.push(Some(a.alias.name.clone()));
21405 values.push(&a.this);
21406 }
21407 _ => {
21408 names.push(None);
21409 values.push(arg);
21410 all_named = false;
21411 }
21412 }
21413 }
21414
21415 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
21416 self.write("{");
21418 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
21419 if i > 0 {
21420 self.write(", ");
21421 }
21422 if let Some(n) = name {
21423 self.write("'");
21424 self.write(n);
21425 self.write("'");
21426 } else {
21427 self.write("'_");
21428 self.write(&i.to_string());
21429 self.write("'");
21430 }
21431 self.write(": ");
21432 self.generate_expression(value)?;
21433 }
21434 self.write("}");
21435 return Ok(());
21436 }
21437
21438 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
21439 self.write_keyword("OBJECT_CONSTRUCT");
21441 self.write("(");
21442 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
21443 if i > 0 {
21444 self.write(", ");
21445 }
21446 if let Some(n) = name {
21447 self.write("'");
21448 self.write(n);
21449 self.write("'");
21450 } else {
21451 self.write("'_");
21452 self.write(&i.to_string());
21453 self.write("'");
21454 }
21455 self.write(", ");
21456 self.generate_expression(value)?;
21457 }
21458 self.write(")");
21459 return Ok(());
21460 }
21461
21462 if matches!(
21463 self.config.dialect,
21464 Some(DialectType::Presto) | Some(DialectType::Trino)
21465 ) {
21466 if all_named && !names.is_empty() {
21467 self.write_keyword("CAST");
21470 self.write("(");
21471 self.write_keyword("ROW");
21472 self.write("(");
21473 for (i, value) in values.iter().enumerate() {
21474 if i > 0 {
21475 self.write(", ");
21476 }
21477 self.generate_expression(value)?;
21478 }
21479 self.write(")");
21480 self.write(" ");
21481 self.write_keyword("AS");
21482 self.write(" ");
21483 self.write_keyword("ROW");
21484 self.write("(");
21485 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
21486 if i > 0 {
21487 self.write(", ");
21488 }
21489 if let Some(n) = name {
21490 self.write(n);
21491 }
21492 self.write(" ");
21493 let type_str = Self::infer_sql_type_for_presto(value);
21494 self.write_keyword(&type_str);
21495 }
21496 self.write(")");
21497 self.write(")");
21498 } else {
21499 self.write_keyword("ROW");
21501 self.write("(");
21502 for (i, value) in values.iter().enumerate() {
21503 if i > 0 {
21504 self.write(", ");
21505 }
21506 self.generate_expression(value)?;
21507 }
21508 self.write(")");
21509 }
21510 return Ok(());
21511 }
21512
21513 self.write_keyword("ROW");
21515 self.write("(");
21516 for (i, value) in values.iter().enumerate() {
21517 if i > 0 {
21518 self.write(", ");
21519 }
21520 self.generate_expression(value)?;
21521 }
21522 self.write(")");
21523 Ok(())
21524 }
21525
21526 fn infer_sql_type_for_presto(expr: &Expression) -> String {
21528 match expr {
21529 Expression::Literal(lit)
21530 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
21531 {
21532 "VARCHAR".to_string()
21533 }
21534 Expression::Literal(lit)
21535 if matches!(lit.as_ref(), crate::expressions::Literal::Number(_)) =>
21536 {
21537 let crate::expressions::Literal::Number(n) = lit.as_ref() else {
21538 unreachable!()
21539 };
21540 if n.contains('.') {
21541 "DOUBLE".to_string()
21542 } else {
21543 "INTEGER".to_string()
21544 }
21545 }
21546 Expression::Boolean(_) => "BOOLEAN".to_string(),
21547 Expression::Literal(lit)
21548 if matches!(lit.as_ref(), crate::expressions::Literal::Date(_)) =>
21549 {
21550 "DATE".to_string()
21551 }
21552 Expression::Literal(lit)
21553 if matches!(lit.as_ref(), crate::expressions::Literal::Timestamp(_)) =>
21554 {
21555 "TIMESTAMP".to_string()
21556 }
21557 Expression::Literal(lit)
21558 if matches!(lit.as_ref(), crate::expressions::Literal::Datetime(_)) =>
21559 {
21560 "TIMESTAMP".to_string()
21561 }
21562 Expression::Array(_) | Expression::ArrayFunc(_) => {
21563 "ARRAY(VARCHAR)".to_string()
21565 }
21566 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
21568 Expression::Function(f) => {
21569 if f.name.eq_ignore_ascii_case("STRUCT") {
21570 "ROW".to_string()
21571 } else if f.name.eq_ignore_ascii_case("CURRENT_DATE") {
21572 "DATE".to_string()
21573 } else if f.name.eq_ignore_ascii_case("CURRENT_TIMESTAMP")
21574 || f.name.eq_ignore_ascii_case("NOW")
21575 {
21576 "TIMESTAMP".to_string()
21577 } else {
21578 "VARCHAR".to_string()
21579 }
21580 }
21581 _ => "VARCHAR".to_string(),
21582 }
21583 }
21584
21585 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
21586 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
21588 self.write_keyword("STRUCT_EXTRACT");
21589 self.write("(");
21590 self.generate_expression(&f.this)?;
21591 self.write(", ");
21592 self.write("'");
21594 self.write(&f.field.name);
21595 self.write("'");
21596 self.write(")");
21597 return Ok(());
21598 }
21599 self.generate_expression(&f.this)?;
21600 self.write(".");
21601 self.generate_identifier(&f.field)
21602 }
21603
21604 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
21605 if matches!(
21606 self.config.dialect,
21607 Some(DialectType::Spark | DialectType::Databricks)
21608 ) {
21609 self.write_keyword("STRUCT");
21610 self.write("(");
21611 for (i, (name, value)) in f.pairs.iter().enumerate() {
21612 if i > 0 {
21613 self.write(", ");
21614 }
21615 self.generate_expression(value)?;
21616 self.write(" ");
21617 self.write_keyword("AS");
21618 self.write(" ");
21619 if let Expression::Literal(lit) = name {
21620 if let Literal::String(field_name) = lit.as_ref() {
21621 self.generate_identifier(&Identifier::new(field_name))?;
21622 } else {
21623 self.generate_expression(name)?;
21624 }
21625 } else {
21626 self.generate_expression(name)?;
21627 }
21628 }
21629 self.write(")");
21630 return Ok(());
21631 }
21632
21633 self.write_keyword("NAMED_STRUCT");
21634 self.write("(");
21635 for (i, (name, value)) in f.pairs.iter().enumerate() {
21636 if i > 0 {
21637 self.write(", ");
21638 }
21639 self.generate_expression(name)?;
21640 self.write(", ");
21641 self.generate_expression(value)?;
21642 }
21643 self.write(")");
21644 Ok(())
21645 }
21646
21647 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
21650 if f.curly_brace_syntax {
21651 if f.with_map_keyword {
21653 self.write_keyword("MAP");
21654 self.write(" ");
21655 }
21656 self.write("{");
21657 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
21658 if i > 0 {
21659 self.write(", ");
21660 }
21661 self.generate_expression(key)?;
21662 self.write(": ");
21663 self.generate_expression(val)?;
21664 }
21665 self.write("}");
21666 } else {
21667 self.write_keyword("MAP");
21669 self.write("(");
21670 self.write_keyword("ARRAY");
21671 self.write("[");
21672 for (i, key) in f.keys.iter().enumerate() {
21673 if i > 0 {
21674 self.write(", ");
21675 }
21676 self.generate_expression(key)?;
21677 }
21678 self.write("], ");
21679 self.write_keyword("ARRAY");
21680 self.write("[");
21681 for (i, val) in f.values.iter().enumerate() {
21682 if i > 0 {
21683 self.write(", ");
21684 }
21685 self.generate_expression(val)?;
21686 }
21687 self.write("])");
21688 }
21689 Ok(())
21690 }
21691
21692 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
21693 self.write_keyword(name);
21694 self.write("(");
21695 self.generate_expression(&f.this)?;
21696 self.write(", ");
21697 self.generate_expression(&f.transform)?;
21698 self.write(")");
21699 Ok(())
21700 }
21701
21702 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
21705 use crate::dialects::DialectType;
21706
21707 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
21709
21710 if use_arrow {
21711 self.generate_expression(&f.this)?;
21713 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
21714 self.write(" ->> ");
21715 } else {
21716 self.write(" -> ");
21717 }
21718 self.generate_expression(&f.path)?;
21719 return Ok(());
21720 }
21721
21722 if f.hash_arrow_syntax
21724 && matches!(
21725 self.config.dialect,
21726 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21727 )
21728 {
21729 self.generate_expression(&f.this)?;
21730 self.write(" #>> ");
21731 self.generate_expression(&f.path)?;
21732 return Ok(());
21733 }
21734
21735 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
21738 match name {
21739 "JSON_EXTRACT_SCALAR"
21740 | "JSON_EXTRACT_PATH_TEXT"
21741 | "JSON_EXTRACT"
21742 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
21743 _ => name,
21744 }
21745 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
21746 match name {
21747 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
21748 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
21749 _ => name,
21750 }
21751 } else {
21752 name
21753 };
21754
21755 self.write_keyword(func_name);
21756 self.write("(");
21757 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
21759 if let Expression::Cast(ref cast) = f.this {
21760 if matches!(cast.to, crate::expressions::DataType::Json) {
21761 self.generate_expression(&cast.this)?;
21762 } else {
21763 self.generate_expression(&f.this)?;
21764 }
21765 } else {
21766 self.generate_expression(&f.this)?;
21767 }
21768 } else {
21769 self.generate_expression(&f.this)?;
21770 }
21771 if matches!(
21774 self.config.dialect,
21775 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21776 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
21777 {
21778 if let Expression::Literal(ref lit) = f.path {
21779 if let Literal::String(ref s) = lit.as_ref() {
21780 let parts = Self::decompose_json_path(s);
21781 for part in &parts {
21782 self.write(", '");
21783 self.write(part);
21784 self.write("'");
21785 }
21786 }
21787 } else {
21788 self.write(", ");
21789 self.generate_expression(&f.path)?;
21790 }
21791 } else {
21792 self.write(", ");
21793 self.generate_expression(&f.path)?;
21794 }
21795
21796 if let Some(ref wrapper) = f.wrapper_option {
21799 self.write_space();
21800 self.write_keyword(wrapper);
21801 }
21802 if let Some(ref quotes) = f.quotes_option {
21803 self.write_space();
21804 self.write_keyword(quotes);
21805 if f.on_scalar_string {
21806 self.write_space();
21807 self.write_keyword("ON SCALAR STRING");
21808 }
21809 }
21810 if let Some(ref on_err) = f.on_error {
21811 self.write_space();
21812 self.write_keyword(on_err);
21813 }
21814 if let Some(ref ret_type) = f.returning {
21815 self.write_space();
21816 self.write_keyword("RETURNING");
21817 self.write_space();
21818 self.generate_data_type(ret_type)?;
21819 }
21820
21821 self.write(")");
21822 Ok(())
21823 }
21824
21825 fn dialect_supports_json_arrow(&self) -> bool {
21827 use crate::dialects::DialectType;
21828 match self.config.dialect {
21829 Some(DialectType::PostgreSQL) => true,
21831 Some(DialectType::MySQL) => true,
21832 Some(DialectType::DuckDB) => true,
21833 Some(DialectType::CockroachDB) => true,
21834 Some(DialectType::StarRocks) => true,
21835 Some(DialectType::SQLite) => true,
21836 _ => false,
21838 }
21839 }
21840
21841 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
21842 use crate::dialects::DialectType;
21843
21844 if matches!(
21846 self.config.dialect,
21847 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21848 ) && name == "JSON_EXTRACT_PATH"
21849 {
21850 self.generate_expression(&f.this)?;
21851 self.write(" #> ");
21852 if f.paths.len() == 1 {
21853 self.generate_expression(&f.paths[0])?;
21854 } else {
21855 self.write_keyword("ARRAY");
21857 self.write("[");
21858 for (i, path) in f.paths.iter().enumerate() {
21859 if i > 0 {
21860 self.write(", ");
21861 }
21862 self.generate_expression(path)?;
21863 }
21864 self.write("]");
21865 }
21866 return Ok(());
21867 }
21868
21869 self.write_keyword(name);
21870 self.write("(");
21871 self.generate_expression(&f.this)?;
21872 for path in &f.paths {
21873 self.write(", ");
21874 self.generate_expression(path)?;
21875 }
21876 self.write(")");
21877 Ok(())
21878 }
21879
21880 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
21881 use crate::dialects::DialectType;
21882
21883 self.write_keyword("JSON_OBJECT");
21884 self.write("(");
21885 if f.star {
21886 self.write("*");
21887 } else {
21888 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
21892 || matches!(
21893 self.config.dialect,
21894 Some(DialectType::BigQuery)
21895 | Some(DialectType::MySQL)
21896 | Some(DialectType::SQLite)
21897 );
21898
21899 for (i, (key, value)) in f.pairs.iter().enumerate() {
21900 if i > 0 {
21901 self.write(", ");
21902 }
21903 self.generate_expression(key)?;
21904 if use_comma_syntax {
21905 self.write(", ");
21906 } else {
21907 self.write(": ");
21908 }
21909 self.generate_expression(value)?;
21910 }
21911 }
21912 if let Some(null_handling) = f.null_handling {
21913 self.write_space();
21914 match null_handling {
21915 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21916 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21917 }
21918 }
21919 if f.with_unique_keys {
21920 self.write_space();
21921 self.write_keyword("WITH UNIQUE KEYS");
21922 }
21923 if let Some(ref ret_type) = f.returning_type {
21924 self.write_space();
21925 self.write_keyword("RETURNING");
21926 self.write_space();
21927 self.generate_data_type(ret_type)?;
21928 if f.format_json {
21929 self.write_space();
21930 self.write_keyword("FORMAT JSON");
21931 }
21932 if let Some(ref enc) = f.encoding {
21933 self.write_space();
21934 self.write_keyword("ENCODING");
21935 self.write_space();
21936 self.write(enc);
21937 }
21938 }
21939 self.write(")");
21940 Ok(())
21941 }
21942
21943 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
21944 self.write_keyword(name);
21945 self.write("(");
21946 self.generate_expression(&f.this)?;
21947 for (path, value) in &f.path_values {
21948 self.write(", ");
21949 self.generate_expression(path)?;
21950 self.write(", ");
21951 self.generate_expression(value)?;
21952 }
21953 self.write(")");
21954 Ok(())
21955 }
21956
21957 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
21958 self.write_keyword("JSON_ARRAYAGG");
21959 self.write("(");
21960 self.generate_expression(&f.this)?;
21961 if let Some(ref order_by) = f.order_by {
21962 self.write_space();
21963 self.write_keyword("ORDER BY");
21964 self.write_space();
21965 for (i, ord) in order_by.iter().enumerate() {
21966 if i > 0 {
21967 self.write(", ");
21968 }
21969 self.generate_ordered(ord)?;
21970 }
21971 }
21972 if let Some(null_handling) = f.null_handling {
21973 self.write_space();
21974 match null_handling {
21975 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21976 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21977 }
21978 }
21979 self.write(")");
21980 if let Some(ref filter) = f.filter {
21981 self.write_space();
21982 self.write_keyword("FILTER");
21983 self.write("(");
21984 self.write_keyword("WHERE");
21985 self.write_space();
21986 self.generate_expression(filter)?;
21987 self.write(")");
21988 }
21989 Ok(())
21990 }
21991
21992 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
21993 self.write_keyword("JSON_OBJECTAGG");
21994 self.write("(");
21995 self.generate_expression(&f.key)?;
21996 self.write(": ");
21997 self.generate_expression(&f.value)?;
21998 if let Some(null_handling) = f.null_handling {
21999 self.write_space();
22000 match null_handling {
22001 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
22002 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
22003 }
22004 }
22005 self.write(")");
22006 if let Some(ref filter) = f.filter {
22007 self.write_space();
22008 self.write_keyword("FILTER");
22009 self.write("(");
22010 self.write_keyword("WHERE");
22011 self.write_space();
22012 self.generate_expression(filter)?;
22013 self.write(")");
22014 }
22015 Ok(())
22016 }
22017
22018 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
22021 use crate::dialects::DialectType;
22022
22023 if self.config.dialect == Some(DialectType::Redshift) {
22025 self.write_keyword("CAST");
22026 self.write("(");
22027 self.generate_expression(&f.this)?;
22028 self.write_space();
22029 self.write_keyword("AS");
22030 self.write_space();
22031 self.generate_data_type(&f.to)?;
22032 self.write(")");
22033 return Ok(());
22034 }
22035
22036 self.write_keyword("CONVERT");
22037 self.write("(");
22038 self.generate_data_type(&f.to)?;
22039 self.write(", ");
22040 self.generate_expression(&f.this)?;
22041 if let Some(ref style) = f.style {
22042 self.write(", ");
22043 self.generate_expression(style)?;
22044 }
22045 self.write(")");
22046 Ok(())
22047 }
22048
22049 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
22052 if f.colon {
22053 self.write_keyword("LAMBDA");
22055 self.write_space();
22056 for (i, param) in f.parameters.iter().enumerate() {
22057 if i > 0 {
22058 self.write(", ");
22059 }
22060 self.generate_identifier(param)?;
22061 }
22062 self.write(" : ");
22063 } else {
22064 if f.parameters.len() == 1 {
22066 self.generate_identifier(&f.parameters[0])?;
22067 } else {
22068 self.write("(");
22069 for (i, param) in f.parameters.iter().enumerate() {
22070 if i > 0 {
22071 self.write(", ");
22072 }
22073 self.generate_identifier(param)?;
22074 }
22075 self.write(")");
22076 }
22077 self.write(" -> ");
22078 }
22079 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22080 if let Expression::Lambda(inner) = &f.body {
22081 self.generate_lambda_with_parenthesized_single_param(inner)?;
22082 return Ok(());
22083 }
22084 }
22085
22086 self.generate_expression(&f.body)
22087 }
22088
22089 fn generate_lambda_with_parenthesized_single_param(&mut self, f: &LambdaExpr) -> Result<()> {
22090 if f.colon {
22091 return self.generate_lambda(f);
22092 }
22093
22094 self.write("(");
22095 for (i, param) in f.parameters.iter().enumerate() {
22096 if i > 0 {
22097 self.write(", ");
22098 }
22099 self.generate_identifier(param)?;
22100 }
22101 self.write(") -> ");
22102 self.generate_expression(&f.body)
22103 }
22104
22105 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
22106 self.generate_identifier(&f.name)?;
22107 match f.separator {
22108 NamedArgSeparator::DArrow => self.write(" => "),
22109 NamedArgSeparator::ColonEq => self.write(" := "),
22110 NamedArgSeparator::Eq => self.write(" = "),
22111 }
22112 self.generate_expression(&f.value)
22113 }
22114
22115 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
22116 self.write_keyword(&f.prefix);
22117 self.write(" ");
22118 self.generate_expression(&f.this)
22119 }
22120
22121 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
22122 match f.style {
22123 ParameterStyle::Question => self.write("?"),
22124 ParameterStyle::Dollar => {
22125 self.write("$");
22126 if let Some(idx) = f.index {
22127 self.write(&idx.to_string());
22128 } else if let Some(ref name) = f.name {
22129 self.write(name);
22131 }
22132 }
22133 ParameterStyle::DollarBrace => {
22134 self.write("${");
22136 if let Some(ref name) = f.name {
22137 self.write(name);
22138 }
22139 if let Some(ref expr) = f.expression {
22140 self.write(":");
22141 self.write(expr);
22142 }
22143 self.write("}");
22144 }
22145 ParameterStyle::Colon => {
22146 self.write(":");
22147 if let Some(idx) = f.index {
22148 self.write(&idx.to_string());
22149 } else if let Some(ref name) = f.name {
22150 self.write(name);
22151 }
22152 }
22153 ParameterStyle::At => {
22154 self.write("@");
22155 if let Some(ref name) = f.name {
22156 if f.string_quoted {
22157 self.write("'");
22158 self.write(name);
22159 self.write("'");
22160 } else if f.quoted {
22161 self.write("\"");
22162 self.write(name);
22163 self.write("\"");
22164 } else {
22165 self.write(name);
22166 }
22167 }
22168 }
22169 ParameterStyle::DoubleAt => {
22170 self.write("@@");
22171 if let Some(ref name) = f.name {
22172 self.write(name);
22173 }
22174 }
22175 ParameterStyle::DoubleDollar => {
22176 self.write("$$");
22177 if let Some(ref name) = f.name {
22178 self.write(name);
22179 }
22180 }
22181 ParameterStyle::Percent => {
22182 if let Some(ref name) = f.name {
22183 self.write("%(");
22185 self.write(name);
22186 self.write(")s");
22187 } else {
22188 self.write("%s");
22190 }
22191 }
22192 ParameterStyle::Brace => {
22193 self.write("{");
22196 if let Some(ref name) = f.name {
22197 self.write(name);
22198 }
22199 if let Some(ref expr) = f.expression {
22200 self.write(": ");
22201 self.write(expr);
22202 }
22203 self.write("}");
22204 }
22205 }
22206 Ok(())
22207 }
22208
22209 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
22210 self.write("?");
22211 if let Some(idx) = f.index {
22212 self.write(&idx.to_string());
22213 }
22214 Ok(())
22215 }
22216
22217 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
22218 if f.is_block {
22219 self.write("/*");
22220 self.write(&f.text);
22221 self.write("*/");
22222 } else {
22223 self.write("--");
22224 self.write(&f.text);
22225 }
22226 Ok(())
22227 }
22228
22229 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
22232 self.generate_expression(&f.this)?;
22233 if f.not {
22234 self.write_space();
22235 self.write_keyword("NOT");
22236 }
22237 self.write_space();
22238 self.write_keyword("SIMILAR TO");
22239 self.write_space();
22240 self.generate_expression(&f.pattern)?;
22241 if let Some(ref escape) = f.escape {
22242 self.write_space();
22243 self.write_keyword("ESCAPE");
22244 self.write_space();
22245 self.generate_expression(escape)?;
22246 }
22247 Ok(())
22248 }
22249
22250 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
22251 self.generate_expression(&f.this)?;
22252 self.write_space();
22253 if let Some(op) = &f.op {
22255 match op {
22256 QuantifiedOp::Eq => self.write("="),
22257 QuantifiedOp::Neq => self.write("<>"),
22258 QuantifiedOp::Lt => self.write("<"),
22259 QuantifiedOp::Lte => self.write("<="),
22260 QuantifiedOp::Gt => self.write(">"),
22261 QuantifiedOp::Gte => self.write(">="),
22262 }
22263 self.write_space();
22264 }
22265 self.write_keyword(name);
22266
22267 if matches!(&f.subquery, Expression::Subquery(_)) {
22269 self.write_space();
22270 self.generate_expression(&f.subquery)?;
22271 } else {
22272 let is_statement = matches!(
22273 &f.subquery,
22274 Expression::Select(_)
22275 | Expression::Union(_)
22276 | Expression::Intersect(_)
22277 | Expression::Except(_)
22278 );
22279 if is_statement
22280 && !self.config.quantified_no_paren_space
22281 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
22282 {
22283 self.write_space();
22284 }
22285 self.write("(");
22286
22287 if self.config.pretty && is_statement {
22288 self.write_newline();
22289 self.indent_level += 1;
22290 self.write_indent();
22291 }
22292 self.generate_expression(&f.subquery)?;
22293 if self.config.pretty && is_statement {
22294 self.write_newline();
22295 self.indent_level -= 1;
22296 self.write_indent();
22297 }
22298 self.write(")");
22299 }
22300 Ok(())
22301 }
22302
22303 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
22304 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
22306 self.generate_expression(this)?;
22307 self.write_space();
22308 self.write_keyword("OVERLAPS");
22309 self.write_space();
22310 self.generate_expression(expr)?;
22311 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
22312 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
22313 {
22314 self.write("(");
22316 self.generate_expression(ls)?;
22317 self.write(", ");
22318 self.generate_expression(le)?;
22319 self.write(")");
22320 self.write_space();
22321 self.write_keyword("OVERLAPS");
22322 self.write_space();
22323 self.write("(");
22324 self.generate_expression(rs)?;
22325 self.write(", ");
22326 self.generate_expression(re)?;
22327 self.write(")");
22328 }
22329 Ok(())
22330 }
22331
22332 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
22335 use crate::dialects::DialectType;
22336
22337 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
22339 self.generate_expression(&cast.this)?;
22340 self.write(" !:> ");
22341 self.generate_data_type(&cast.to)?;
22342 return Ok(());
22343 }
22344
22345 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
22347 self.write_keyword("TRYCAST");
22348 self.write("(");
22349 self.generate_expression(&cast.this)?;
22350 self.write_space();
22351 self.write_keyword("AS");
22352 self.write_space();
22353 self.generate_data_type(&cast.to)?;
22354 self.write(")");
22355 return Ok(());
22356 }
22357
22358 let keyword = if matches!(
22360 self.config.dialect,
22361 Some(DialectType::Hive)
22362 | Some(DialectType::MySQL)
22363 | Some(DialectType::SQLite)
22364 | Some(DialectType::Oracle)
22365 | Some(DialectType::ClickHouse)
22366 | Some(DialectType::Redshift)
22367 | Some(DialectType::PostgreSQL)
22368 | Some(DialectType::StarRocks)
22369 | Some(DialectType::Doris)
22370 ) {
22371 "CAST"
22372 } else {
22373 "TRY_CAST"
22374 };
22375
22376 self.write_keyword(keyword);
22377 self.write("(");
22378 self.generate_expression(&cast.this)?;
22379 self.write_space();
22380 self.write_keyword("AS");
22381 self.write_space();
22382 self.generate_data_type(&cast.to)?;
22383
22384 if let Some(format) = &cast.format {
22386 self.write_space();
22387 self.write_keyword("FORMAT");
22388 self.write_space();
22389 self.generate_expression(format)?;
22390 }
22391
22392 self.write(")");
22393 Ok(())
22394 }
22395
22396 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
22397 self.write_keyword("SAFE_CAST");
22398 self.write("(");
22399 self.generate_expression(&cast.this)?;
22400 self.write_space();
22401 self.write_keyword("AS");
22402 self.write_space();
22403 self.generate_data_type(&cast.to)?;
22404
22405 if let Some(format) = &cast.format {
22407 self.write_space();
22408 self.write_keyword("FORMAT");
22409 self.write_space();
22410 self.generate_expression(format)?;
22411 }
22412
22413 self.write(")");
22414 Ok(())
22415 }
22416
22417 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
22420 let needs_parens = matches!(&s.this, Expression::JsonExtract(ref f) if f.arrow_syntax);
22424 if needs_parens {
22425 self.write("(");
22426 }
22427 self.generate_expression(&s.this)?;
22428 if needs_parens {
22429 self.write(")");
22430 }
22431 self.write("[");
22432 self.generate_expression(&s.index)?;
22433 self.write("]");
22434 Ok(())
22435 }
22436
22437 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
22438 self.generate_expression(&d.this)?;
22439 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
22442 && matches!(
22443 &d.this,
22444 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
22445 );
22446 if use_colon {
22447 self.write(":");
22448 } else {
22449 self.write(".");
22450 }
22451 self.generate_identifier(&d.field)
22452 }
22453
22454 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
22455 self.generate_expression(&m.this)?;
22456 self.write(".");
22457 if m.method.quoted {
22460 let q = self.config.identifier_quote;
22461 self.write(&format!("{}{}{}", q, m.method.name, q));
22462 } else {
22463 self.write(&m.method.name);
22464 }
22465 self.write("(");
22466 for (i, arg) in m.args.iter().enumerate() {
22467 if i > 0 {
22468 self.write(", ");
22469 }
22470 self.generate_expression(arg)?;
22471 }
22472 self.write(")");
22473 Ok(())
22474 }
22475
22476 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
22477 let needs_parens = matches!(
22480 &s.this,
22481 Expression::JsonExtract(f) if f.arrow_syntax
22482 ) || matches!(
22483 &s.this,
22484 Expression::JsonExtractScalar(f) if f.arrow_syntax
22485 );
22486
22487 if needs_parens {
22488 self.write("(");
22489 }
22490 self.generate_expression(&s.this)?;
22491 if needs_parens {
22492 self.write(")");
22493 }
22494 self.write("[");
22495 if let Some(start) = &s.start {
22496 self.generate_expression(start)?;
22497 }
22498 self.write(":");
22499 if let Some(end) = &s.end {
22500 self.generate_expression(end)?;
22501 }
22502 self.write("]");
22503 Ok(())
22504 }
22505
22506 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
22507 match &op.left {
22511 Expression::Column(col) => {
22512 if let Some(table) = &col.table {
22515 self.generate_identifier(table)?;
22516 self.write(".");
22517 }
22518 self.generate_identifier(&col.name)?;
22519 if col.join_mark && self.config.supports_column_join_marks {
22521 self.write(" (+)");
22522 }
22523 if op.left_comments.is_empty() {
22525 for comment in &col.trailing_comments {
22526 self.write_space();
22527 self.write_formatted_comment(comment);
22528 }
22529 }
22530 }
22531 Expression::Add(inner_op)
22532 | Expression::Sub(inner_op)
22533 | Expression::Mul(inner_op)
22534 | Expression::Div(inner_op)
22535 | Expression::Concat(inner_op) => {
22536 self.generate_binary_op_no_trailing(inner_op, match &op.left {
22538 Expression::Add(_) => "+",
22539 Expression::Sub(_) => "-",
22540 Expression::Mul(_) => "*",
22541 Expression::Div(_) => "/",
22542 Expression::Concat(_) => "||",
22543 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
22544 })?;
22545 }
22546 _ => {
22547 self.generate_expression(&op.left)?;
22548 }
22549 }
22550 for comment in &op.left_comments {
22552 self.write_space();
22553 self.write_formatted_comment(comment);
22554 }
22555 if self.config.pretty
22556 && matches!(self.config.dialect, Some(DialectType::Snowflake))
22557 && (operator == "AND" || operator == "OR")
22558 {
22559 self.write_newline();
22560 self.write_indent();
22561 self.write_keyword(operator);
22562 } else {
22563 self.write_space();
22564 if operator.chars().all(|c| c.is_alphabetic()) {
22565 self.write_keyword(operator);
22566 } else {
22567 self.write(operator);
22568 }
22569 }
22570 for comment in &op.operator_comments {
22572 self.write_space();
22573 self.write_formatted_comment(comment);
22574 }
22575 self.write_space();
22576 self.generate_expression(&op.right)?;
22577 for comment in &op.trailing_comments {
22579 self.write_space();
22580 self.write_formatted_comment(comment);
22581 }
22582 Ok(())
22583 }
22584
22585 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
22586 let keyword = connector.keyword();
22587 let Some(terms) = self.flatten_connector_terms(op, connector) else {
22588 return self.generate_binary_op(op, keyword);
22589 };
22590
22591 let wrap_clickhouse_or_term = |generator: &mut Self, term: &Expression| -> Result<()> {
22592 let should_wrap = matches!(connector, ConnectorOperator::Or)
22593 && matches!(generator.config.dialect, Some(DialectType::ClickHouse))
22594 && matches!(
22595 generator.config.source_dialect,
22596 Some(DialectType::ClickHouse)
22597 )
22598 && matches!(term, Expression::And(_));
22599 if should_wrap {
22600 generator.write("(");
22601 generator.generate_expression(term)?;
22602 generator.write(")");
22603 } else {
22604 generator.generate_expression(term)?;
22605 }
22606 Ok(())
22607 };
22608
22609 wrap_clickhouse_or_term(self, terms[0])?;
22610 for term in terms.iter().skip(1) {
22611 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
22612 self.write_newline();
22613 self.write_indent();
22614 self.write_keyword(keyword);
22615 } else {
22616 self.write_space();
22617 self.write_keyword(keyword);
22618 }
22619 self.write_space();
22620 wrap_clickhouse_or_term(self, term)?;
22621 }
22622
22623 Ok(())
22624 }
22625
22626 fn flatten_connector_terms<'a>(
22627 &self,
22628 root: &'a BinaryOp,
22629 connector: ConnectorOperator,
22630 ) -> Option<Vec<&'a Expression>> {
22631 if !root.left_comments.is_empty()
22632 || !root.operator_comments.is_empty()
22633 || !root.trailing_comments.is_empty()
22634 {
22635 return None;
22636 }
22637
22638 let mut terms = Vec::new();
22639 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
22640
22641 while let Some(expr) = stack.pop() {
22642 match (connector, expr) {
22643 (ConnectorOperator::And, Expression::And(inner))
22644 if inner.left_comments.is_empty()
22645 && inner.operator_comments.is_empty()
22646 && inner.trailing_comments.is_empty() =>
22647 {
22648 stack.push(&inner.right);
22649 stack.push(&inner.left);
22650 }
22651 (ConnectorOperator::Or, Expression::Or(inner))
22652 if inner.left_comments.is_empty()
22653 && inner.operator_comments.is_empty()
22654 && inner.trailing_comments.is_empty() =>
22655 {
22656 stack.push(&inner.right);
22657 stack.push(&inner.left);
22658 }
22659 _ => terms.push(expr),
22660 }
22661 }
22662
22663 if terms.len() > 1 {
22664 Some(terms)
22665 } else {
22666 None
22667 }
22668 }
22669
22670 fn missing_closing_parens_outside_quotes(sql: &str) -> usize {
22671 let mut depth = 0usize;
22672 let mut quote: Option<char> = None;
22673 let mut chars = sql.chars().peekable();
22674
22675 while let Some(ch) = chars.next() {
22676 if let Some(quote_char) = quote {
22677 if ch == '\\' {
22678 chars.next();
22679 } else if ch == quote_char {
22680 if quote_char == '\'' && chars.peek() == Some(&'\'') {
22681 chars.next();
22682 } else {
22683 quote = None;
22684 }
22685 }
22686 continue;
22687 }
22688
22689 match ch {
22690 '\'' | '"' | '`' => quote = Some(ch),
22691 '(' => depth += 1,
22692 ')' => depth = depth.saturating_sub(1),
22693 _ => {}
22694 }
22695 }
22696
22697 depth
22698 }
22699
22700 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
22702 self.generate_like_op_inner(op, operator, false)
22703 }
22704
22705 fn generate_like_op_negated(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
22706 self.generate_like_op_inner(op, operator, true)
22707 }
22708
22709 fn generate_like_op_inner(&mut self, op: &LikeOp, operator: &str, negated: bool) -> Result<()> {
22710 if negated
22711 && matches!(
22712 self.config.dialect,
22713 Some(DialectType::ClickHouse)
22714 | Some(DialectType::DataFusion)
22715 | Some(DialectType::TSQL)
22716 | Some(DialectType::Fabric)
22717 )
22718 {
22719 self.write_keyword("NOT");
22720 self.write_space();
22721 return self.generate_like_op_inner(op, operator, false);
22722 }
22723
22724 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22725 if let Expression::Star(star) = &op.left {
22726 if star
22727 .except
22728 .as_ref()
22729 .is_some_and(|except| !except.is_empty())
22730 {
22731 if let Some(table) = &star.table {
22732 self.generate_identifier(table)?;
22733 self.write(".");
22734 }
22735 self.write("*");
22736 self.write_space();
22737 self.write_keyword(operator);
22738 if let Some(quantifier) = &op.quantifier {
22739 self.write_space();
22740 self.write_keyword(quantifier);
22741 self.write_space();
22742 } else {
22743 self.write_space();
22744 }
22745 self.generate_expression(&op.right)?;
22746 if let Some(escape) = &op.escape {
22747 self.write_space();
22748 self.write_keyword("ESCAPE");
22749 self.write_space();
22750 self.generate_expression(escape)?;
22751 }
22752 if let Some(except) = &star.except {
22753 self.write_space();
22754 self.write_keyword("EXCEPT");
22755 self.write(" (");
22756 for (i, col) in except.iter().enumerate() {
22757 if i > 0 {
22758 self.write(", ");
22759 }
22760 self.generate_identifier(col)?;
22761 }
22762 self.write(")");
22763 }
22764 return Ok(());
22765 }
22766 }
22767 }
22768
22769 self.generate_expression(&op.left)?;
22770 self.write_space();
22771 if negated {
22772 self.write_keyword("NOT");
22773 self.write_space();
22774 }
22775 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
22777 self.write("`ILIKE`");
22778 } else {
22779 self.write_keyword(operator);
22780 }
22781 if let Some(quantifier) = &op.quantifier {
22782 self.write_space();
22783 self.write_keyword(quantifier);
22784 let is_any =
22789 quantifier.eq_ignore_ascii_case("ANY") || quantifier.eq_ignore_ascii_case("SOME");
22790 if !(is_any && matches!(&op.right, Expression::Paren(_))) {
22791 self.write_space();
22792 }
22793 } else {
22794 self.write_space();
22795 }
22796 self.generate_expression(&op.right)?;
22797 if let Some(escape) = &op.escape {
22798 self.write_space();
22799 self.write_keyword("ESCAPE");
22800 self.write_space();
22801 self.generate_expression(escape)?;
22802 }
22803 Ok(())
22804 }
22805
22806 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
22809 use crate::dialects::DialectType;
22810 self.generate_expression(&op.left)?;
22811 self.write_space();
22812 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
22813 self.write("<=>");
22814 } else {
22815 self.write_keyword("IS NOT DISTINCT FROM");
22816 }
22817 self.write_space();
22818 self.generate_expression(&op.right)?;
22819 Ok(())
22820 }
22821
22822 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
22824 self.generate_expression(&op.left)?;
22825 self.write_space();
22826 self.write_keyword("IS DISTINCT FROM");
22827 self.write_space();
22828 self.generate_expression(&op.right)?;
22829 Ok(())
22830 }
22831
22832 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
22834 match &op.left {
22836 Expression::Column(col) => {
22837 if let Some(table) = &col.table {
22838 self.generate_identifier(table)?;
22839 self.write(".");
22840 }
22841 self.generate_identifier(&col.name)?;
22842 if col.join_mark && self.config.supports_column_join_marks {
22844 self.write(" (+)");
22845 }
22846 }
22847 Expression::Add(inner_op)
22848 | Expression::Sub(inner_op)
22849 | Expression::Mul(inner_op)
22850 | Expression::Div(inner_op)
22851 | Expression::Concat(inner_op) => {
22852 self.generate_binary_op_no_trailing(inner_op, match &op.left {
22853 Expression::Add(_) => "+",
22854 Expression::Sub(_) => "-",
22855 Expression::Mul(_) => "*",
22856 Expression::Div(_) => "/",
22857 Expression::Concat(_) => "||",
22858 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
22859 })?;
22860 }
22861 _ => {
22862 self.generate_expression(&op.left)?;
22863 }
22864 }
22865 for comment in &op.left_comments {
22867 self.write_space();
22868 self.write_formatted_comment(comment);
22869 }
22870 self.write_space();
22871 if operator.chars().all(|c| c.is_alphabetic()) {
22872 self.write_keyword(operator);
22873 } else {
22874 self.write(operator);
22875 }
22876 for comment in &op.operator_comments {
22878 self.write_space();
22879 self.write_formatted_comment(comment);
22880 }
22881 self.write_space();
22882 match &op.right {
22885 Expression::Column(col) => {
22886 if let Some(table) = &col.table {
22887 self.generate_identifier(table)?;
22888 self.write(".");
22889 }
22890 self.generate_identifier(&col.name)?;
22891 if col.join_mark && self.config.supports_column_join_marks {
22893 self.write(" (+)");
22894 }
22895 }
22896 _ => {
22897 self.generate_expression(&op.right)?;
22898 }
22899 }
22900 Ok(())
22902 }
22903
22904 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
22905 if operator.chars().all(|c| c.is_alphabetic()) {
22906 self.write_keyword(operator);
22907 self.write_space();
22908 } else {
22909 self.write(operator);
22910 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
22912 self.write_space();
22913 }
22914 }
22915 self.generate_expression(&op.this)
22916 }
22917
22918 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
22919 let is_generic =
22923 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
22924 let use_prefix_not =
22925 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
22926 if use_prefix_not {
22927 self.write_keyword("NOT");
22928 self.write_space();
22929 }
22930 self.generate_expression(&in_expr.this)?;
22931 if in_expr.global {
22932 self.write_space();
22933 self.write_keyword("GLOBAL");
22934 }
22935 if in_expr.not && !use_prefix_not {
22936 self.write_space();
22937 self.write_keyword("NOT");
22938 }
22939 self.write_space();
22940 self.write_keyword("IN");
22941
22942 if let Some(unnest_expr) = &in_expr.unnest {
22944 self.write_space();
22945 self.write_keyword("UNNEST");
22946 self.write("(");
22947 self.generate_expression(unnest_expr)?;
22948 self.write(")");
22949 return Ok(());
22950 }
22951
22952 if let Some(query) = &in_expr.query {
22953 let is_bare = in_expr.expressions.is_empty()
22956 && !matches!(
22957 query,
22958 Expression::Select(_)
22959 | Expression::Union(_)
22960 | Expression::Intersect(_)
22961 | Expression::Except(_)
22962 | Expression::Subquery(_)
22963 );
22964 if is_bare {
22965 self.write_space();
22967 self.generate_expression(query)?;
22968 } else {
22969 self.write(" (");
22971 let is_statement = matches!(
22972 query,
22973 Expression::Select(_)
22974 | Expression::Union(_)
22975 | Expression::Intersect(_)
22976 | Expression::Except(_)
22977 | Expression::Subquery(_)
22978 );
22979 if self.config.pretty && is_statement {
22980 self.write_newline();
22981 self.indent_level += 1;
22982 self.write_indent();
22983 }
22984 self.generate_expression(query)?;
22985 if self.config.pretty && is_statement {
22986 self.write_newline();
22987 self.indent_level -= 1;
22988 self.write_indent();
22989 }
22990 self.write(")");
22991 }
22992 } else {
22993 let is_duckdb = matches!(
22997 self.config.dialect,
22998 Some(crate::dialects::DialectType::DuckDB)
22999 );
23000 let is_clickhouse = matches!(
23001 self.config.dialect,
23002 Some(crate::dialects::DialectType::ClickHouse)
23003 );
23004 let single_expr = in_expr.expressions.len() == 1;
23005 if is_clickhouse && single_expr {
23006 if let Expression::Array(arr) = &in_expr.expressions[0] {
23007 self.write(" (");
23009 for (i, expr) in arr.expressions.iter().enumerate() {
23010 if i > 0 {
23011 self.write(", ");
23012 }
23013 self.generate_expression(expr)?;
23014 }
23015 self.write(")");
23016 } else if in_expr.is_field {
23017 self.write_space();
23018 self.generate_expression(&in_expr.expressions[0])?;
23019 } else {
23020 self.write(" (");
23021 self.generate_expression(&in_expr.expressions[0])?;
23022 self.write(")");
23023 }
23024 } else {
23025 let is_bare_ref = single_expr
23026 && matches!(
23027 &in_expr.expressions[0],
23028 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
23029 );
23030 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
23031 self.write_space();
23034 self.generate_expression(&in_expr.expressions[0])?;
23035 } else {
23036 self.write(" (");
23038 for (i, expr) in in_expr.expressions.iter().enumerate() {
23039 if i > 0 {
23040 self.write(", ");
23041 }
23042 self.generate_expression(expr)?;
23043 }
23044 self.write(")");
23045 }
23046 }
23047 }
23048
23049 Ok(())
23050 }
23051
23052 fn generate_between(&mut self, between: &Between) -> Result<()> {
23053 let use_prefix_not = between.not
23055 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
23056 if use_prefix_not {
23057 self.write_keyword("NOT");
23058 self.write_space();
23059 }
23060 self.generate_expression(&between.this)?;
23061 if between.not && !use_prefix_not {
23062 self.write_space();
23063 self.write_keyword("NOT");
23064 }
23065 self.write_space();
23066 self.write_keyword("BETWEEN");
23067 if let Some(sym) = between.symmetric {
23069 if sym {
23070 self.write(" SYMMETRIC");
23071 } else {
23072 self.write(" ASYMMETRIC");
23073 }
23074 }
23075 self.write_space();
23076 self.generate_expression(&between.low)?;
23077 self.write_space();
23078 self.write_keyword("AND");
23079 self.write_space();
23080 self.generate_expression(&between.high)
23081 }
23082
23083 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
23084 let use_prefix_not = is_null.not
23086 && (self.config.dialect.is_none()
23087 || self.config.dialect == Some(DialectType::Generic)
23088 || is_null.postfix_form);
23089 if use_prefix_not {
23090 self.write_keyword("NOT");
23092 self.write_space();
23093 self.generate_expression(&is_null.this)?;
23094 self.write_space();
23095 self.write_keyword("IS");
23096 self.write_space();
23097 self.write_keyword("NULL");
23098 } else {
23099 self.generate_expression(&is_null.this)?;
23100 self.write_space();
23101 self.write_keyword("IS");
23102 if is_null.not {
23103 self.write_space();
23104 self.write_keyword("NOT");
23105 }
23106 self.write_space();
23107 self.write_keyword("NULL");
23108 }
23109 Ok(())
23110 }
23111
23112 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
23113 self.generate_expression(&is_true.this)?;
23114 self.write_space();
23115 self.write_keyword("IS");
23116 if is_true.not {
23117 self.write_space();
23118 self.write_keyword("NOT");
23119 }
23120 self.write_space();
23121 self.write_keyword("TRUE");
23122 Ok(())
23123 }
23124
23125 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
23126 self.generate_expression(&is_false.this)?;
23127 self.write_space();
23128 self.write_keyword("IS");
23129 if is_false.not {
23130 self.write_space();
23131 self.write_keyword("NOT");
23132 }
23133 self.write_space();
23134 self.write_keyword("FALSE");
23135 Ok(())
23136 }
23137
23138 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
23139 self.generate_expression(&is_json.this)?;
23140 self.write_space();
23141 self.write_keyword("IS");
23142 if is_json.negated {
23143 self.write_space();
23144 self.write_keyword("NOT");
23145 }
23146 self.write_space();
23147 self.write_keyword("JSON");
23148
23149 if let Some(ref json_type) = is_json.json_type {
23151 self.write_space();
23152 self.write_keyword(json_type);
23153 }
23154
23155 match &is_json.unique_keys {
23157 Some(JsonUniqueKeys::With) => {
23158 self.write_space();
23159 self.write_keyword("WITH UNIQUE KEYS");
23160 }
23161 Some(JsonUniqueKeys::Without) => {
23162 self.write_space();
23163 self.write_keyword("WITHOUT UNIQUE KEYS");
23164 }
23165 Some(JsonUniqueKeys::Shorthand) => {
23166 self.write_space();
23167 self.write_keyword("UNIQUE KEYS");
23168 }
23169 None => {}
23170 }
23171
23172 Ok(())
23173 }
23174
23175 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
23176 self.generate_expression(&is_expr.left)?;
23177 self.write_space();
23178 self.write_keyword("IS");
23179 self.write_space();
23180 self.generate_expression(&is_expr.right)
23181 }
23182
23183 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
23184 if exists.not {
23185 self.write_keyword("NOT");
23186 self.write_space();
23187 }
23188 self.write_keyword("EXISTS");
23189 self.write("(");
23190 let is_statement = matches!(
23191 &exists.this,
23192 Expression::Select(_)
23193 | Expression::Union(_)
23194 | Expression::Intersect(_)
23195 | Expression::Except(_)
23196 );
23197 if self.config.pretty && is_statement {
23198 self.write_newline();
23199 self.indent_level += 1;
23200 self.write_indent();
23201 self.generate_expression(&exists.this)?;
23202 self.write_newline();
23203 self.indent_level -= 1;
23204 self.write_indent();
23205 self.write(")");
23206 } else {
23207 self.generate_expression(&exists.this)?;
23208 self.write(")");
23209 }
23210 Ok(())
23211 }
23212
23213 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
23214 self.generate_expression(&op.left)?;
23215 self.write_space();
23216 self.write_keyword("MEMBER OF");
23217 self.write("(");
23218 self.generate_expression(&op.right)?;
23219 self.write(")");
23220 Ok(())
23221 }
23222
23223 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
23224 if subquery.lateral {
23225 self.write_keyword("LATERAL");
23226 self.write_space();
23227 }
23228
23229 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
23233 matches!(
23234 &p.this,
23235 Expression::Select(_)
23236 | Expression::Union(_)
23237 | Expression::Intersect(_)
23238 | Expression::Except(_)
23239 | Expression::Subquery(_)
23240 )
23241 } else {
23242 false
23243 };
23244
23245 let is_statement = matches!(
23247 &subquery.this,
23248 Expression::Select(_)
23249 | Expression::Union(_)
23250 | Expression::Intersect(_)
23251 | Expression::Except(_)
23252 | Expression::Merge(_)
23253 );
23254
23255 if !skip_outer_parens {
23256 self.write("(");
23257 if self.config.pretty && is_statement {
23258 self.write_newline();
23259 self.indent_level += 1;
23260 self.write_indent();
23261 }
23262 }
23263 self.generate_expression(&subquery.this)?;
23264
23265 if subquery.modifiers_inside {
23267 if let Some(order_by) = &subquery.order_by {
23269 self.write_space();
23270 self.write_keyword("ORDER BY");
23271 self.write_space();
23272 for (i, ord) in order_by.expressions.iter().enumerate() {
23273 if i > 0 {
23274 self.write(", ");
23275 }
23276 self.generate_ordered(ord)?;
23277 }
23278 }
23279
23280 if let Some(limit) = &subquery.limit {
23281 self.write_space();
23282 self.write_keyword("LIMIT");
23283 self.write_space();
23284 self.generate_expression(&limit.this)?;
23285 if limit.percent {
23286 self.write_space();
23287 self.write_keyword("PERCENT");
23288 }
23289 }
23290
23291 if let Some(offset) = &subquery.offset {
23292 self.write_space();
23293 self.write_keyword("OFFSET");
23294 self.write_space();
23295 self.generate_expression(&offset.this)?;
23296 }
23297 }
23298
23299 if !skip_outer_parens {
23300 if self.config.pretty && is_statement {
23301 self.write_newline();
23302 self.indent_level -= 1;
23303 self.write_indent();
23304 }
23305 self.write(")");
23306 }
23307
23308 if !subquery.modifiers_inside {
23310 if let Some(order_by) = &subquery.order_by {
23311 self.write_space();
23312 self.write_keyword("ORDER BY");
23313 self.write_space();
23314 for (i, ord) in order_by.expressions.iter().enumerate() {
23315 if i > 0 {
23316 self.write(", ");
23317 }
23318 self.generate_ordered(ord)?;
23319 }
23320 }
23321
23322 if let Some(limit) = &subquery.limit {
23323 self.write_space();
23324 self.write_keyword("LIMIT");
23325 self.write_space();
23326 self.generate_expression(&limit.this)?;
23327 if limit.percent {
23328 self.write_space();
23329 self.write_keyword("PERCENT");
23330 }
23331 }
23332
23333 if let Some(offset) = &subquery.offset {
23334 self.write_space();
23335 self.write_keyword("OFFSET");
23336 self.write_space();
23337 self.generate_expression(&offset.this)?;
23338 }
23339
23340 if let Some(distribute_by) = &subquery.distribute_by {
23342 self.write_space();
23343 self.write_keyword("DISTRIBUTE BY");
23344 self.write_space();
23345 for (i, expr) in distribute_by.expressions.iter().enumerate() {
23346 if i > 0 {
23347 self.write(", ");
23348 }
23349 self.generate_expression(expr)?;
23350 }
23351 }
23352
23353 if let Some(sort_by) = &subquery.sort_by {
23355 self.write_space();
23356 self.write_keyword("SORT BY");
23357 self.write_space();
23358 for (i, ord) in sort_by.expressions.iter().enumerate() {
23359 if i > 0 {
23360 self.write(", ");
23361 }
23362 self.generate_ordered(ord)?;
23363 }
23364 }
23365
23366 if let Some(cluster_by) = &subquery.cluster_by {
23368 self.write_space();
23369 self.write_keyword("CLUSTER BY");
23370 self.write_space();
23371 for (i, ord) in cluster_by.expressions.iter().enumerate() {
23372 if i > 0 {
23373 self.write(", ");
23374 }
23375 self.generate_ordered(ord)?;
23376 }
23377 }
23378 }
23379
23380 if let Some(alias) = &subquery.alias {
23381 self.write_space();
23382 let skip_as = matches!(self.config.dialect, Some(DialectType::Oracle))
23383 || (matches!(self.config.dialect, Some(DialectType::ClickHouse))
23384 && !subquery.alias_explicit_as);
23385 if !skip_as {
23386 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23387 self.write(subquery.alias_keyword.as_deref().unwrap_or("AS"));
23388 } else {
23389 self.write_keyword("AS");
23390 }
23391 self.write_space();
23392 }
23393 self.generate_identifier(alias)?;
23394 if !subquery.column_aliases.is_empty() {
23395 self.write("(");
23396 for (i, col) in subquery.column_aliases.iter().enumerate() {
23397 if i > 0 {
23398 self.write(", ");
23399 }
23400 self.generate_identifier(col)?;
23401 }
23402 self.write(")");
23403 }
23404 }
23405 for comment in &subquery.trailing_comments {
23407 self.write(" ");
23408 self.write_formatted_comment(comment);
23409 }
23410 Ok(())
23411 }
23412
23413 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
23414 if let Some(ref with) = pivot.with {
23416 self.generate_with(with)?;
23417 self.write_space();
23418 }
23419
23420 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
23421
23422 let is_redshift_unpivot = pivot.unpivot
23426 && pivot.expressions.is_empty()
23427 && pivot.fields.is_empty()
23428 && pivot.using.is_empty()
23429 && pivot.into.is_none()
23430 && !matches!(&pivot.this, Expression::Null(_));
23431
23432 if is_redshift_unpivot {
23433 self.write_keyword("UNPIVOT");
23435 self.write_space();
23436 self.generate_expression(&pivot.this)?;
23437 if let Some(alias) = &pivot.alias {
23439 self.write_space();
23440 self.write_keyword("AS");
23441 self.write_space();
23442 self.write(&alias.name);
23444 }
23445 return Ok(());
23446 }
23447
23448 let is_simplified = !pivot.using.is_empty()
23450 || pivot.into.is_some()
23451 || (pivot.fields.is_empty()
23452 && !pivot.expressions.is_empty()
23453 && !matches!(&pivot.this, Expression::Null(_)));
23454
23455 if is_simplified {
23456 self.write_keyword(direction);
23460 self.write_space();
23461 self.generate_expression(&pivot.this)?;
23462
23463 if !pivot.expressions.is_empty() {
23464 self.write_space();
23465 self.write_keyword("ON");
23466 self.write_space();
23467 for (i, expr) in pivot.expressions.iter().enumerate() {
23468 if i > 0 {
23469 self.write(", ");
23470 }
23471 self.generate_expression(expr)?;
23472 }
23473 }
23474
23475 if let Some(into) = &pivot.into {
23477 self.write_space();
23478 self.write_keyword("INTO");
23479 self.write_space();
23480 self.generate_expression(into)?;
23481 }
23482
23483 if !pivot.using.is_empty() {
23485 self.write_space();
23486 self.write_keyword("USING");
23487 self.write_space();
23488 for (i, expr) in pivot.using.iter().enumerate() {
23489 if i > 0 {
23490 self.write(", ");
23491 }
23492 self.generate_expression(expr)?;
23493 }
23494 }
23495
23496 if let Some(group) = &pivot.group {
23498 self.write_space();
23499 self.generate_expression(group)?;
23500 }
23501 } else {
23502 if !matches!(&pivot.this, Expression::Null(_)) {
23507 self.generate_expression(&pivot.this)?;
23508 self.write_space();
23509 }
23510 self.write_keyword(direction);
23511 self.write("(");
23512
23513 for (i, expr) in pivot.expressions.iter().enumerate() {
23515 if i > 0 {
23516 self.write(", ");
23517 }
23518 self.generate_expression(expr)?;
23519 }
23520
23521 if !pivot.fields.is_empty() {
23523 if !pivot.expressions.is_empty() {
23524 self.write_space();
23525 }
23526 self.write_keyword("FOR");
23527 self.write_space();
23528 for (i, field) in pivot.fields.iter().enumerate() {
23529 if i > 0 {
23530 self.write_space();
23531 }
23532 self.generate_expression(field)?;
23534 }
23535 }
23536
23537 if let Some(default_val) = &pivot.default_on_null {
23539 self.write_space();
23540 self.write_keyword("DEFAULT ON NULL");
23541 self.write(" (");
23542 self.generate_expression(default_val)?;
23543 self.write(")");
23544 }
23545
23546 if let Some(group) = &pivot.group {
23548 self.write_space();
23549 self.generate_expression(group)?;
23550 }
23551
23552 self.write(")");
23553 }
23554
23555 if let Some(alias) = &pivot.alias {
23557 self.write_space();
23558 self.write_keyword("AS");
23559 self.write_space();
23560 self.generate_identifier(alias)?;
23561 self.generate_alias_column_list(&pivot.alias_columns)?;
23562 }
23563
23564 Ok(())
23565 }
23566
23567 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
23568 self.generate_expression(&unpivot.this)?;
23569 self.write_space();
23570 self.write_keyword("UNPIVOT");
23571 if let Some(include) = unpivot.include_nulls {
23573 self.write_space();
23574 if include {
23575 self.write_keyword("INCLUDE NULLS");
23576 } else {
23577 self.write_keyword("EXCLUDE NULLS");
23578 }
23579 self.write_space();
23580 }
23581 self.write("(");
23582 if unpivot.value_column_parenthesized {
23583 self.write("(");
23584 }
23585 self.generate_identifier(&unpivot.value_column)?;
23586 for extra_col in &unpivot.extra_value_columns {
23588 self.write(", ");
23589 self.generate_identifier(extra_col)?;
23590 }
23591 if unpivot.value_column_parenthesized {
23592 self.write(")");
23593 }
23594 self.write_space();
23595 self.write_keyword("FOR");
23596 self.write_space();
23597 self.generate_identifier(&unpivot.name_column)?;
23598 self.write_space();
23599 self.write_keyword("IN");
23600 self.write(" (");
23601 for (i, col) in unpivot.columns.iter().enumerate() {
23602 if i > 0 {
23603 self.write(", ");
23604 }
23605 self.generate_expression(col)?;
23606 }
23607 self.write("))");
23608 if let Some(alias) = &unpivot.alias {
23609 self.write_space();
23610 self.write_keyword("AS");
23611 self.write_space();
23612 self.generate_identifier(alias)?;
23613 self.generate_alias_column_list(&unpivot.alias_columns)?;
23614 }
23615 Ok(())
23616 }
23617
23618 fn generate_alias_column_list(&mut self, columns: &[Identifier]) -> Result<()> {
23619 if columns.is_empty() {
23620 return Ok(());
23621 }
23622
23623 self.write("(");
23624 for (i, column) in columns.iter().enumerate() {
23625 if i > 0 {
23626 self.write(", ");
23627 }
23628 self.generate_identifier(column)?;
23629 }
23630 self.write(")");
23631 Ok(())
23632 }
23633
23634 fn generate_values(&mut self, values: &Values) -> Result<()> {
23635 self.write_keyword("VALUES");
23636 for (i, row) in values.expressions.iter().enumerate() {
23637 if i > 0 {
23638 self.write(",");
23639 }
23640 self.write(" (");
23641 for (j, expr) in row.expressions.iter().enumerate() {
23642 if j > 0 {
23643 self.write(", ");
23644 }
23645 self.generate_expression(expr)?;
23646 }
23647 self.write(")");
23648 }
23649 if let Some(alias) = &values.alias {
23650 self.write_space();
23651 self.write_keyword("AS");
23652 self.write_space();
23653 self.generate_identifier(alias)?;
23654 if !values.column_aliases.is_empty() {
23655 self.write("(");
23656 for (i, col) in values.column_aliases.iter().enumerate() {
23657 if i > 0 {
23658 self.write(", ");
23659 }
23660 self.generate_identifier(col)?;
23661 }
23662 self.write(")");
23663 }
23664 }
23665 Ok(())
23666 }
23667
23668 fn generate_array(&mut self, arr: &Array) -> Result<()> {
23669 let needs_inheritance = matches!(
23671 self.config.dialect,
23672 Some(DialectType::DuckDB)
23673 | Some(DialectType::Spark)
23674 | Some(DialectType::Databricks)
23675 | Some(DialectType::Hive)
23676 | Some(DialectType::Snowflake)
23677 | Some(DialectType::Presto)
23678 | Some(DialectType::Trino)
23679 );
23680 let propagated: Vec<Expression>;
23681 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
23682 propagated = Self::inherit_struct_field_names(&arr.expressions);
23683 &propagated
23684 } else {
23685 &arr.expressions
23686 };
23687
23688 let use_parens =
23691 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
23692 if !self.config.array_bracket_only {
23693 self.write_keyword("ARRAY");
23694 }
23695 if use_parens {
23696 self.write("(");
23697 } else {
23698 self.write("[");
23699 }
23700 for (i, expr) in expressions.iter().enumerate() {
23701 if i > 0 {
23702 self.write(", ");
23703 }
23704 self.generate_expression(expr)?;
23705 }
23706 if use_parens {
23707 self.write(")");
23708 } else {
23709 self.write("]");
23710 }
23711 Ok(())
23712 }
23713
23714 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
23715 if tuple.expressions.len() == 2 {
23718 if let Expression::TableAlias(_) = &tuple.expressions[1] {
23719 self.generate_expression(&tuple.expressions[0])?;
23721 self.write_space();
23722 self.write_keyword("AS");
23723 self.write_space();
23724 self.generate_expression(&tuple.expressions[1])?;
23725 return Ok(());
23726 }
23727 }
23728
23729 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
23732 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
23733 for expr in &tuple.expressions {
23734 expr_strings.push(self.generate_to_string(expr)?);
23735 }
23736 self.too_wide(&expr_strings)
23737 } else {
23738 false
23739 };
23740
23741 if expand_tuple {
23742 self.write("(");
23743 self.write_newline();
23744 self.indent_level += 1;
23745 for (i, expr) in tuple.expressions.iter().enumerate() {
23746 if i > 0 {
23747 self.write(",");
23748 self.write_newline();
23749 }
23750 self.write_indent();
23751 self.generate_expression(expr)?;
23752 }
23753 self.indent_level -= 1;
23754 self.write_newline();
23755 self.write_indent();
23756 self.write(")");
23757 } else {
23758 self.write("(");
23759 for (i, expr) in tuple.expressions.iter().enumerate() {
23760 if i > 0 {
23761 self.write(", ");
23762 }
23763 self.generate_expression(expr)?;
23764 }
23765 self.write(")");
23766 }
23767 Ok(())
23768 }
23769
23770 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
23771 self.generate_expression(&pipe.this)?;
23772 self.write(" |> ");
23773 self.generate_expression(&pipe.expression)?;
23774 Ok(())
23775 }
23776
23777 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
23778 let unsupported_tsql_null_ordering = ordered.nulls_first.is_some()
23779 && !self.config.null_ordering_supported
23780 && matches!(
23781 self.config.dialect,
23782 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23783 );
23784 let random_ordering = matches!(ordered.this, Expression::Rand(_) | Expression::Random(_));
23785 let emulate_tsql_null_ordering = if let Some(nulls_first) = ordered.nulls_first {
23786 let target_default_nulls_first = !ordered.desc;
23787
23788 unsupported_tsql_null_ordering
23789 && nulls_first != target_default_nulls_first
23790 && !random_ordering
23791 } else {
23792 false
23793 };
23794
23795 if emulate_tsql_null_ordering {
23796 self.write_keyword("CASE WHEN");
23797 self.write_space();
23798 self.generate_expression(&ordered.this)?;
23799 self.write_space();
23800 self.write_keyword("IS NULL THEN 1 ELSE 0 END");
23801 if ordered.nulls_first == Some(true) {
23802 self.write_space();
23803 self.write_keyword("DESC");
23804 }
23805 self.write(", ");
23806 }
23807
23808 self.generate_expression(&ordered.this)?;
23809 if ordered.desc {
23810 self.write_space();
23811 self.write_keyword("DESC");
23812 } else if ordered.explicit_asc {
23813 self.write_space();
23814 self.write_keyword("ASC");
23815 }
23816 if let Some(nulls_first) = ordered.nulls_first {
23817 if !unsupported_tsql_null_ordering
23818 && (self.config.null_ordering_supported
23819 || !matches!(self.config.dialect, Some(DialectType::Fabric)))
23820 {
23821 let is_asc = !ordered.desc;
23835 let is_nulls_are_large = matches!(
23836 self.config.dialect,
23837 Some(DialectType::Oracle)
23838 | Some(DialectType::PostgreSQL)
23839 | Some(DialectType::Redshift)
23840 | Some(DialectType::Snowflake)
23841 );
23842 let is_nulls_are_last = matches!(
23843 self.config.dialect,
23844 Some(DialectType::Dremio)
23845 | Some(DialectType::DuckDB)
23846 | Some(DialectType::Presto)
23847 | Some(DialectType::Trino)
23848 | Some(DialectType::Athena)
23849 | Some(DialectType::ClickHouse)
23850 | Some(DialectType::Drill)
23851 | Some(DialectType::Exasol)
23852 );
23853
23854 let is_default_nulls = if is_nulls_are_large {
23856 (is_asc && !nulls_first) || (!is_asc && nulls_first)
23858 } else if is_nulls_are_last {
23859 !nulls_first
23861 } else {
23862 false
23863 };
23864
23865 if !is_default_nulls {
23866 self.write_space();
23867 self.write_keyword("NULLS");
23868 self.write_space();
23869 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
23870 }
23871 }
23872 }
23873 if let Some(ref with_fill) = ordered.with_fill {
23875 self.write_space();
23876 self.generate_with_fill(with_fill)?;
23877 }
23878 Ok(())
23879 }
23880
23881 fn write_clickhouse_type(&mut self, type_str: &str) {
23883 if self.clickhouse_nullable_depth < 0 {
23884 self.write(type_str);
23886 } else {
23887 self.write(&format!("Nullable({})", type_str));
23888 }
23889 }
23890
23891 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
23892 use crate::dialects::DialectType;
23893
23894 match dt {
23895 DataType::Boolean => {
23896 match self.config.dialect {
23898 Some(DialectType::TSQL) => self.write_keyword("BIT"),
23899 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
23901 self.write_keyword("NUMBER(1)")
23903 }
23904 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
23906 }
23907 }
23908 DataType::TinyInt { length } => {
23909 match self.config.dialect {
23913 Some(DialectType::PostgreSQL)
23914 | Some(DialectType::Redshift)
23915 | Some(DialectType::Oracle)
23916 | Some(DialectType::Exasol) => {
23917 self.write_keyword("SMALLINT");
23918 }
23919 Some(DialectType::Teradata) => {
23920 self.write_keyword("BYTEINT");
23922 }
23923 Some(DialectType::Dremio) => {
23924 self.write_keyword("INT");
23926 }
23927 Some(DialectType::ClickHouse) => {
23928 self.write_clickhouse_type("Int8");
23929 }
23930 _ => {
23931 self.write_keyword("TINYINT");
23932 }
23933 }
23934 if let Some(n) = length {
23935 if !matches!(
23936 self.config.dialect,
23937 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
23938 ) {
23939 self.write(&format!("({})", n));
23940 }
23941 }
23942 }
23943 DataType::SmallInt { length } => {
23944 match self.config.dialect {
23946 Some(DialectType::Dremio) => {
23947 self.write_keyword("INT");
23948 }
23949 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
23950 self.write_keyword("INTEGER");
23951 }
23952 Some(DialectType::BigQuery) => {
23953 self.write_keyword("INT64");
23954 }
23955 Some(DialectType::ClickHouse) => {
23956 self.write_clickhouse_type("Int16");
23957 }
23958 _ => {
23959 self.write_keyword("SMALLINT");
23960 if let Some(n) = length {
23961 self.write(&format!("({})", n));
23962 }
23963 }
23964 }
23965 }
23966 DataType::Int {
23967 length,
23968 integer_spelling: _,
23969 } => {
23970 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
23972 self.write_keyword("INT64");
23973 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23974 self.write_clickhouse_type("Int32");
23975 } else {
23976 let use_integer = match self.config.dialect {
23978 Some(DialectType::TSQL)
23979 | Some(DialectType::Fabric)
23980 | Some(DialectType::Presto)
23981 | Some(DialectType::Trino)
23982 | Some(DialectType::SQLite)
23983 | Some(DialectType::Redshift) => true,
23984 _ => false,
23985 };
23986 if use_integer {
23987 self.write_keyword("INTEGER");
23988 } else {
23989 self.write_keyword("INT");
23990 }
23991 if let Some(n) = length {
23992 self.write(&format!("({})", n));
23993 }
23994 }
23995 }
23996 DataType::BigInt { length } => {
23997 match self.config.dialect {
23999 Some(DialectType::Oracle) => {
24000 self.write_keyword("INT");
24002 }
24003 Some(DialectType::ClickHouse) => {
24004 self.write_clickhouse_type("Int64");
24005 }
24006 _ => {
24007 self.write_keyword("BIGINT");
24008 if let Some(n) = length {
24009 self.write(&format!("({})", n));
24010 }
24011 }
24012 }
24013 }
24014 DataType::Float {
24015 precision,
24016 scale,
24017 real_spelling,
24018 } => {
24019 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24023 self.write_clickhouse_type("Float32");
24024 } else if *real_spelling
24025 && !matches!(
24026 self.config.dialect,
24027 Some(DialectType::Spark)
24028 | Some(DialectType::Databricks)
24029 | Some(DialectType::Hive)
24030 | Some(DialectType::Snowflake)
24031 | Some(DialectType::MySQL)
24032 | Some(DialectType::BigQuery)
24033 )
24034 {
24035 self.write_keyword("REAL")
24036 } else {
24037 match self.config.dialect {
24038 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
24039 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
24040 _ => self.write_keyword("FLOAT"),
24041 }
24042 }
24043 if !matches!(
24046 self.config.dialect,
24047 Some(DialectType::Spark)
24048 | Some(DialectType::Databricks)
24049 | Some(DialectType::Hive)
24050 | Some(DialectType::Presto)
24051 | Some(DialectType::Trino)
24052 ) {
24053 if let Some(p) = precision {
24054 self.write(&format!("({}", p));
24055 if let Some(s) = scale {
24056 self.write(&format!(", {})", s));
24057 } else {
24058 self.write(")");
24059 }
24060 }
24061 }
24062 }
24063 DataType::Double { precision, scale } => {
24064 match self.config.dialect {
24066 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24067 self.write_keyword("FLOAT")
24068 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
24070 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
24071 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
24072 Some(DialectType::SQLite) => self.write_keyword("REAL"),
24073 Some(DialectType::PostgreSQL)
24074 | Some(DialectType::Redshift)
24075 | Some(DialectType::Teradata)
24076 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
24077 _ => self.write_keyword("DOUBLE"),
24078 }
24079 if let Some(p) = precision {
24081 self.write(&format!("({}", p));
24082 if let Some(s) = scale {
24083 self.write(&format!(", {})", s));
24084 } else {
24085 self.write(")");
24086 }
24087 }
24088 }
24089 DataType::Decimal { precision, scale } => {
24090 match self.config.dialect {
24092 Some(DialectType::ClickHouse) => {
24093 self.write("Decimal");
24094 if let Some(p) = precision {
24095 self.write(&format!("({}", p));
24096 if let Some(s) = scale {
24097 self.write(&format!(", {}", s));
24098 }
24099 self.write(")");
24100 }
24101 }
24102 Some(DialectType::Oracle) => {
24103 self.write_keyword("NUMBER");
24105 if let Some(p) = precision {
24106 self.write(&format!("({}", p));
24107 if let Some(s) = scale {
24108 self.write(&format!(", {}", s));
24109 }
24110 self.write(")");
24111 }
24112 }
24113 Some(DialectType::BigQuery) => {
24114 self.write_keyword("NUMERIC");
24116 if let Some(p) = precision {
24117 self.write(&format!("({}", p));
24118 if let Some(s) = scale {
24119 self.write(&format!(", {}", s));
24120 }
24121 self.write(")");
24122 }
24123 }
24124 _ => {
24125 self.write_keyword("DECIMAL");
24126 if let Some(p) = precision {
24127 self.write(&format!("({}", p));
24128 if let Some(s) = scale {
24129 self.write(&format!(", {}", s));
24130 }
24131 self.write(")");
24132 }
24133 }
24134 }
24135 }
24136 DataType::Char { length } => {
24137 match self.config.dialect {
24139 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24140 self.write_keyword("TEXT");
24142 }
24143 Some(DialectType::Hive)
24144 | Some(DialectType::Spark)
24145 | Some(DialectType::Databricks) => {
24146 if length.is_some()
24149 && !matches!(self.config.dialect, Some(DialectType::Hive))
24150 {
24151 self.write_keyword("CHAR");
24152 if let Some(n) = length {
24153 self.write(&format!("({})", n));
24154 }
24155 } else {
24156 self.write_keyword("STRING");
24157 }
24158 }
24159 Some(DialectType::Dremio) => {
24160 self.write_keyword("VARCHAR");
24162 if let Some(n) = length {
24163 self.write(&format!("({})", n));
24164 }
24165 }
24166 _ => {
24167 self.write_keyword("CHAR");
24168 if let Some(n) = length {
24169 self.write(&format!("({})", n));
24170 }
24171 }
24172 }
24173 }
24174 DataType::VarChar {
24175 length,
24176 parenthesized_length,
24177 } => {
24178 match self.config.dialect {
24180 Some(DialectType::Oracle) => {
24181 self.write_keyword("VARCHAR2");
24182 if let Some(n) = length {
24183 self.write(&format!("({})", n));
24184 }
24185 }
24186 Some(DialectType::DuckDB) => {
24187 self.write_keyword("TEXT");
24189 if let Some(n) = length {
24190 self.write(&format!("({})", n));
24191 }
24192 }
24193 Some(DialectType::SQLite) => {
24194 self.write_keyword("TEXT");
24196 if let Some(n) = length {
24197 self.write(&format!("({})", n));
24198 }
24199 }
24200 Some(DialectType::MySQL) if length.is_none() => {
24201 self.write_keyword("TEXT");
24203 }
24204 Some(DialectType::Hive)
24205 | Some(DialectType::Spark)
24206 | Some(DialectType::Databricks)
24207 if length.is_none() =>
24208 {
24209 self.write_keyword("STRING");
24211 }
24212 _ => {
24213 self.write_keyword("VARCHAR");
24214 if let Some(n) = length {
24215 if *parenthesized_length {
24217 self.write(&format!("(({}))", n));
24218 } else {
24219 self.write(&format!("({})", n));
24220 }
24221 }
24222 }
24223 }
24224 }
24225 DataType::Text => {
24226 match self.config.dialect {
24228 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
24229 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24230 self.write_keyword("VARCHAR(MAX)")
24231 }
24232 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
24233 Some(DialectType::Snowflake)
24234 | Some(DialectType::Dremio)
24235 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
24236 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
24237 Some(DialectType::Presto)
24238 | Some(DialectType::Trino)
24239 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
24240 Some(DialectType::Spark)
24241 | Some(DialectType::Databricks)
24242 | Some(DialectType::Hive) => self.write_keyword("STRING"),
24243 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
24244 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
24245 self.write_keyword("STRING")
24246 }
24247 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
24248 _ => self.write_keyword("TEXT"),
24249 }
24250 }
24251 DataType::TextWithLength { length } => {
24252 match self.config.dialect {
24254 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
24255 Some(DialectType::Hive)
24256 | Some(DialectType::Spark)
24257 | Some(DialectType::Databricks) => {
24258 self.write(&format!("VARCHAR({})", length));
24259 }
24260 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
24261 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
24262 Some(DialectType::Snowflake)
24263 | Some(DialectType::Presto)
24264 | Some(DialectType::Trino)
24265 | Some(DialectType::Athena)
24266 | Some(DialectType::Drill)
24267 | Some(DialectType::Dremio) => {
24268 self.write(&format!("VARCHAR({})", length));
24269 }
24270 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24271 self.write(&format!("VARCHAR({})", length))
24272 }
24273 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
24274 self.write(&format!("STRING({})", length))
24275 }
24276 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
24277 _ => self.write(&format!("TEXT({})", length)),
24278 }
24279 }
24280 DataType::String { length } => {
24281 match self.config.dialect {
24283 Some(DialectType::ClickHouse) => {
24284 self.write("String");
24286 if let Some(n) = length {
24287 self.write(&format!("({})", n));
24288 }
24289 }
24290 Some(DialectType::BigQuery)
24291 | Some(DialectType::Hive)
24292 | Some(DialectType::Spark)
24293 | Some(DialectType::Databricks)
24294 | Some(DialectType::StarRocks)
24295 | Some(DialectType::Doris) => {
24296 self.write_keyword("STRING");
24297 if let Some(n) = length {
24298 self.write(&format!("({})", n));
24299 }
24300 }
24301 Some(DialectType::PostgreSQL) => {
24302 if let Some(n) = length {
24304 self.write_keyword("VARCHAR");
24305 self.write(&format!("({})", n));
24306 } else {
24307 self.write_keyword("TEXT");
24308 }
24309 }
24310 Some(DialectType::Redshift) => {
24311 if let Some(n) = length {
24313 self.write_keyword("VARCHAR");
24314 self.write(&format!("({})", n));
24315 } else {
24316 self.write_keyword("VARCHAR(MAX)");
24317 }
24318 }
24319 Some(DialectType::MySQL) => {
24320 if let Some(n) = length {
24322 self.write_keyword("VARCHAR");
24323 self.write(&format!("({})", n));
24324 } else {
24325 self.write_keyword("TEXT");
24326 }
24327 }
24328 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24329 if let Some(n) = length {
24331 self.write_keyword("VARCHAR");
24332 self.write(&format!("({})", n));
24333 } else {
24334 self.write_keyword("VARCHAR(MAX)");
24335 }
24336 }
24337 Some(DialectType::Oracle) => {
24338 self.write_keyword("CLOB");
24340 }
24341 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
24342 self.write_keyword("TEXT");
24344 if let Some(n) = length {
24345 self.write(&format!("({})", n));
24346 }
24347 }
24348 Some(DialectType::Presto)
24349 | Some(DialectType::Trino)
24350 | Some(DialectType::Drill)
24351 | Some(DialectType::Dremio) => {
24352 self.write_keyword("VARCHAR");
24354 if let Some(n) = length {
24355 self.write(&format!("({})", n));
24356 }
24357 }
24358 Some(DialectType::Snowflake) => {
24359 self.write_keyword("STRING");
24362 if let Some(n) = length {
24363 self.write(&format!("({})", n));
24364 }
24365 }
24366 _ => {
24367 self.write_keyword("STRING");
24369 if let Some(n) = length {
24370 self.write(&format!("({})", n));
24371 }
24372 }
24373 }
24374 }
24375 DataType::Binary { length } => {
24376 match self.config.dialect {
24378 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
24379 self.write_keyword("BYTEA");
24380 if let Some(n) = length {
24381 self.write(&format!("({})", n));
24382 }
24383 }
24384 Some(DialectType::Redshift) => {
24385 self.write_keyword("VARBYTE");
24386 if let Some(n) = length {
24387 self.write(&format!("({})", n));
24388 }
24389 }
24390 Some(DialectType::DuckDB)
24391 | Some(DialectType::SQLite)
24392 | Some(DialectType::Oracle) => {
24393 self.write_keyword("BLOB");
24395 if let Some(n) = length {
24396 self.write(&format!("({})", n));
24397 }
24398 }
24399 Some(DialectType::Presto)
24400 | Some(DialectType::Trino)
24401 | Some(DialectType::Athena)
24402 | Some(DialectType::Drill)
24403 | Some(DialectType::Dremio) => {
24404 self.write_keyword("VARBINARY");
24406 if let Some(n) = length {
24407 self.write(&format!("({})", n));
24408 }
24409 }
24410 Some(DialectType::ClickHouse) => {
24411 if self.clickhouse_nullable_depth < 0 {
24413 self.write("BINARY");
24414 } else {
24415 self.write("Nullable(BINARY");
24416 }
24417 if let Some(n) = length {
24418 self.write(&format!("({})", n));
24419 }
24420 if self.clickhouse_nullable_depth >= 0 {
24421 self.write(")");
24422 }
24423 }
24424 _ => {
24425 self.write_keyword("BINARY");
24426 if let Some(n) = length {
24427 self.write(&format!("({})", n));
24428 }
24429 }
24430 }
24431 }
24432 DataType::VarBinary { length } => {
24433 match self.config.dialect {
24435 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
24436 self.write_keyword("BYTEA");
24437 if let Some(n) = length {
24438 self.write(&format!("({})", n));
24439 }
24440 }
24441 Some(DialectType::Redshift) => {
24442 self.write_keyword("VARBYTE");
24443 if let Some(n) = length {
24444 self.write(&format!("({})", n));
24445 }
24446 }
24447 Some(DialectType::DuckDB)
24448 | Some(DialectType::SQLite)
24449 | Some(DialectType::Oracle) => {
24450 self.write_keyword("BLOB");
24452 if let Some(n) = length {
24453 self.write(&format!("({})", n));
24454 }
24455 }
24456 Some(DialectType::Exasol) => {
24457 self.write_keyword("VARCHAR");
24459 }
24460 Some(DialectType::Spark)
24461 | Some(DialectType::Hive)
24462 | Some(DialectType::Databricks) => {
24463 self.write_keyword("BINARY");
24465 if let Some(n) = length {
24466 self.write(&format!("({})", n));
24467 }
24468 }
24469 Some(DialectType::ClickHouse) => {
24470 self.write_clickhouse_type("String");
24472 }
24473 _ => {
24474 self.write_keyword("VARBINARY");
24475 if let Some(n) = length {
24476 self.write(&format!("({})", n));
24477 }
24478 }
24479 }
24480 }
24481 DataType::Blob => {
24482 match self.config.dialect {
24484 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
24485 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
24486 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24487 self.write_keyword("VARBINARY")
24488 }
24489 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
24490 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
24491 Some(DialectType::Presto)
24492 | Some(DialectType::Trino)
24493 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
24494 Some(DialectType::DuckDB) => {
24495 self.write_keyword("VARBINARY");
24498 }
24499 Some(DialectType::Spark)
24500 | Some(DialectType::Databricks)
24501 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
24502 Some(DialectType::ClickHouse) => {
24503 self.write("Nullable(String)");
24507 }
24508 _ => self.write_keyword("BLOB"),
24509 }
24510 }
24511 DataType::Bit { length } => {
24512 match self.config.dialect {
24514 Some(DialectType::Dremio)
24515 | Some(DialectType::Spark)
24516 | Some(DialectType::Databricks)
24517 | Some(DialectType::Hive)
24518 | Some(DialectType::Snowflake)
24519 | Some(DialectType::BigQuery)
24520 | Some(DialectType::Presto)
24521 | Some(DialectType::Trino)
24522 | Some(DialectType::ClickHouse)
24523 | Some(DialectType::Redshift) => {
24524 self.write_keyword("BOOLEAN");
24526 }
24527 _ => {
24528 self.write_keyword("BIT");
24529 if let Some(n) = length {
24530 self.write(&format!("({})", n));
24531 }
24532 }
24533 }
24534 }
24535 DataType::VarBit { length } => {
24536 self.write_keyword("VARBIT");
24537 if let Some(n) = length {
24538 self.write(&format!("({})", n));
24539 }
24540 }
24541 DataType::Date => self.write_keyword("DATE"),
24542 DataType::Time {
24543 precision,
24544 timezone,
24545 } => {
24546 if *timezone {
24547 match self.config.dialect {
24549 Some(DialectType::DuckDB) => {
24550 self.write_keyword("TIMETZ");
24552 }
24553 Some(DialectType::PostgreSQL) => {
24554 self.write_keyword("TIMETZ");
24556 if let Some(p) = precision {
24557 self.write(&format!("({})", p));
24558 }
24559 }
24560 _ => {
24561 self.write_keyword("TIME");
24563 if let Some(p) = precision {
24564 self.write(&format!("({})", p));
24565 }
24566 self.write_keyword(" WITH TIME ZONE");
24567 }
24568 }
24569 } else {
24570 if matches!(
24572 self.config.dialect,
24573 Some(DialectType::Spark)
24574 | Some(DialectType::Databricks)
24575 | Some(DialectType::Hive)
24576 ) {
24577 self.write_keyword("TIMESTAMP");
24578 } else {
24579 self.write_keyword("TIME");
24580 if let Some(p) = precision {
24581 self.write(&format!("({})", p));
24582 }
24583 }
24584 }
24585 }
24586 DataType::Timestamp {
24587 precision,
24588 timezone,
24589 } => {
24590 match self.config.dialect {
24592 Some(DialectType::Snowflake) if *timezone => {
24593 self.write_keyword("TIMESTAMPTZ");
24594 if let Some(p) = precision {
24595 self.write(&format!("({})", p));
24596 }
24597 }
24598 Some(DialectType::ClickHouse) => {
24599 self.write("DateTime");
24600 if let Some(p) = precision {
24601 self.write(&format!("({})", p));
24602 }
24603 }
24604 Some(DialectType::TSQL) => {
24605 if *timezone {
24606 self.write_keyword("DATETIMEOFFSET");
24607 } else {
24608 self.write_keyword("DATETIME2");
24609 }
24610 if let Some(p) = precision {
24611 self.write(&format!("({})", p));
24612 }
24613 }
24614 Some(DialectType::MySQL) => {
24615 self.write_keyword("TIMESTAMP");
24617 if let Some(p) = precision {
24618 self.write(&format!("({})", p));
24619 }
24620 }
24621 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
24622 self.write_keyword("DATETIME");
24624 if let Some(p) = precision {
24625 self.write(&format!("({})", p));
24626 }
24627 }
24628 Some(DialectType::BigQuery) => {
24629 if *timezone {
24631 self.write_keyword("TIMESTAMP");
24632 } else {
24633 self.write_keyword("DATETIME");
24634 }
24635 }
24636 Some(DialectType::DuckDB) => {
24637 if *timezone {
24639 self.write_keyword("TIMESTAMPTZ");
24640 } else {
24641 self.write_keyword("TIMESTAMP");
24642 if let Some(p) = precision {
24643 self.write(&format!("({})", p));
24644 }
24645 }
24646 }
24647 _ => {
24648 if *timezone && !self.config.tz_to_with_time_zone {
24649 self.write_keyword("TIMESTAMPTZ");
24651 if let Some(p) = precision {
24652 self.write(&format!("({})", p));
24653 }
24654 } else {
24655 self.write_keyword("TIMESTAMP");
24656 if let Some(p) = precision {
24657 self.write(&format!("({})", p));
24658 }
24659 if *timezone {
24660 self.write_space();
24661 self.write_keyword("WITH TIME ZONE");
24662 }
24663 }
24664 }
24665 }
24666 }
24667 DataType::Interval { unit, to } => {
24668 self.write_keyword("INTERVAL");
24669 if let Some(u) = unit {
24670 self.write_space();
24671 self.write_keyword(u);
24672 }
24673 if let Some(t) = to {
24675 self.write_space();
24676 self.write_keyword("TO");
24677 self.write_space();
24678 self.write_keyword(t);
24679 }
24680 }
24681 DataType::Json => {
24682 match self.config.dialect {
24684 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
24687 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
24688 _ => self.write_keyword("JSON"),
24689 }
24690 }
24691 DataType::JsonB => {
24692 match self.config.dialect {
24694 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
24695 Some(DialectType::Doris) => self.write_keyword("JSONB"),
24696 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
24697 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
24698 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
24701 }
24702 DataType::Uuid => {
24703 match self.config.dialect {
24705 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
24706 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
24707 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
24708 Some(DialectType::BigQuery)
24709 | Some(DialectType::Spark)
24710 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
24711 _ => self.write_keyword("UUID"),
24712 }
24713 }
24714 DataType::Array {
24715 element_type,
24716 dimension,
24717 } => {
24718 match self.config.dialect {
24720 Some(DialectType::PostgreSQL)
24721 | Some(DialectType::Redshift)
24722 | Some(DialectType::DuckDB) => {
24723 self.generate_data_type(element_type)?;
24725 if let Some(dim) = dimension {
24726 self.write(&format!("[{}]", dim));
24727 } else {
24728 self.write("[]");
24729 }
24730 }
24731 Some(DialectType::BigQuery) => {
24732 self.write_keyword("ARRAY<");
24733 self.generate_data_type(element_type)?;
24734 self.write(">");
24735 }
24736 Some(DialectType::Snowflake)
24737 | Some(DialectType::Presto)
24738 | Some(DialectType::Trino)
24739 | Some(DialectType::ClickHouse) => {
24740 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24742 self.write("Array(");
24743 } else {
24744 self.write_keyword("ARRAY(");
24745 }
24746 self.generate_data_type(element_type)?;
24747 self.write(")");
24748 }
24749 Some(DialectType::TSQL)
24750 | Some(DialectType::MySQL)
24751 | Some(DialectType::Oracle) => {
24752 match self.config.dialect {
24755 Some(DialectType::MySQL) => self.write_keyword("JSON"),
24756 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
24757 _ => self.write_keyword("JSON"),
24758 }
24759 }
24760 _ => {
24761 self.write_keyword("ARRAY<");
24763 self.generate_data_type(element_type)?;
24764 self.write(">");
24765 }
24766 }
24767 }
24768 DataType::List { element_type } => {
24769 self.generate_data_type(element_type)?;
24771 self.write_keyword(" LIST");
24772 }
24773 DataType::Map {
24774 key_type,
24775 value_type,
24776 } => {
24777 match self.config.dialect {
24779 Some(DialectType::Materialize) => {
24780 self.write_keyword("MAP[");
24782 self.generate_data_type(key_type)?;
24783 self.write(" => ");
24784 self.generate_data_type(value_type)?;
24785 self.write("]");
24786 }
24787 Some(DialectType::Snowflake)
24788 | Some(DialectType::RisingWave)
24789 | Some(DialectType::DuckDB)
24790 | Some(DialectType::Presto)
24791 | Some(DialectType::Trino)
24792 | Some(DialectType::Athena) => {
24793 self.write_keyword("MAP(");
24794 self.generate_data_type(key_type)?;
24795 self.write(", ");
24796 self.generate_data_type(value_type)?;
24797 self.write(")");
24798 }
24799 Some(DialectType::ClickHouse) => {
24800 self.write("Map(");
24803 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
24805 self.clickhouse_nullable_depth = 0;
24806 self.write(", ");
24807 self.generate_data_type(value_type)?;
24808 self.write(")");
24809 }
24810 _ => {
24811 self.write_keyword("MAP<");
24812 self.generate_data_type(key_type)?;
24813 self.write(", ");
24814 self.generate_data_type(value_type)?;
24815 self.write(">");
24816 }
24817 }
24818 }
24819 DataType::Vector {
24820 element_type,
24821 dimension,
24822 } => {
24823 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
24824 self.write_keyword("VECTOR(");
24826 if let Some(dim) = dimension {
24827 self.write(&dim.to_string());
24828 }
24829 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
24831 DataType::TinyInt { .. } => Some("I8"),
24832 DataType::SmallInt { .. } => Some("I16"),
24833 DataType::Int { .. } => Some("I32"),
24834 DataType::BigInt { .. } => Some("I64"),
24835 DataType::Float { .. } => Some("F32"),
24836 DataType::Double { .. } => Some("F64"),
24837 _ => None,
24838 });
24839 if let Some(alias) = type_alias {
24840 if dimension.is_some() {
24841 self.write(", ");
24842 }
24843 self.write(alias);
24844 }
24845 self.write(")");
24846 } else {
24847 self.write_keyword("VECTOR(");
24849 if let Some(ref et) = element_type {
24850 self.generate_data_type(et)?;
24851 if dimension.is_some() {
24852 self.write(", ");
24853 }
24854 }
24855 if let Some(dim) = dimension {
24856 self.write(&dim.to_string());
24857 }
24858 self.write(")");
24859 }
24860 }
24861 DataType::Object { fields, modifier } => {
24862 self.write_keyword("OBJECT(");
24863 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
24864 if i > 0 {
24865 self.write(", ");
24866 }
24867 self.write(name);
24868 self.write(" ");
24869 self.generate_data_type(dt)?;
24870 if *not_null {
24871 self.write_keyword(" NOT NULL");
24872 }
24873 }
24874 self.write(")");
24875 if let Some(mod_str) = modifier {
24876 self.write(" ");
24877 self.write_keyword(mod_str);
24878 }
24879 }
24880 DataType::Struct { fields, nested } => {
24881 match self.config.dialect {
24883 Some(DialectType::Snowflake) => {
24884 self.write_keyword("OBJECT(");
24886 for (i, field) in fields.iter().enumerate() {
24887 if i > 0 {
24888 self.write(", ");
24889 }
24890 if !field.name.is_empty() {
24891 self.write(&field.name);
24892 self.write(" ");
24893 }
24894 self.generate_data_type(&field.data_type)?;
24895 }
24896 self.write(")");
24897 }
24898 Some(DialectType::Presto) | Some(DialectType::Trino) => {
24899 self.write_keyword("ROW(");
24901 for (i, field) in fields.iter().enumerate() {
24902 if i > 0 {
24903 self.write(", ");
24904 }
24905 if !field.name.is_empty() {
24906 self.write(&field.name);
24907 self.write(" ");
24908 }
24909 self.generate_data_type(&field.data_type)?;
24910 }
24911 self.write(")");
24912 }
24913 Some(DialectType::DuckDB) => {
24914 self.write_keyword("STRUCT(");
24916 for (i, field) in fields.iter().enumerate() {
24917 if i > 0 {
24918 self.write(", ");
24919 }
24920 if !field.name.is_empty() {
24921 self.write(&field.name);
24922 self.write(" ");
24923 }
24924 self.generate_data_type(&field.data_type)?;
24925 }
24926 self.write(")");
24927 }
24928 Some(DialectType::ClickHouse) => {
24929 self.write("Tuple(");
24931 for (i, field) in fields.iter().enumerate() {
24932 if i > 0 {
24933 self.write(", ");
24934 }
24935 if !field.name.is_empty() {
24936 self.write(&field.name);
24937 self.write(" ");
24938 }
24939 self.generate_data_type(&field.data_type)?;
24940 }
24941 self.write(")");
24942 }
24943 Some(DialectType::SingleStore) => {
24944 self.write_keyword("RECORD(");
24946 for (i, field) in fields.iter().enumerate() {
24947 if i > 0 {
24948 self.write(", ");
24949 }
24950 if !field.name.is_empty() {
24951 self.write(&field.name);
24952 self.write(" ");
24953 }
24954 self.generate_data_type(&field.data_type)?;
24955 }
24956 self.write(")");
24957 }
24958 _ => {
24959 let force_angle_brackets = matches!(
24961 self.config.dialect,
24962 Some(DialectType::Hive)
24963 | Some(DialectType::Spark)
24964 | Some(DialectType::Databricks)
24965 );
24966 if *nested && !force_angle_brackets {
24967 self.write_keyword("STRUCT(");
24968 for (i, field) in fields.iter().enumerate() {
24969 if i > 0 {
24970 self.write(", ");
24971 }
24972 if !field.name.is_empty() {
24973 self.write(&field.name);
24974 self.write(" ");
24975 }
24976 self.generate_data_type(&field.data_type)?;
24977 }
24978 self.write(")");
24979 } else {
24980 self.write_keyword("STRUCT<");
24981 for (i, field) in fields.iter().enumerate() {
24982 if i > 0 {
24983 self.write(", ");
24984 }
24985 if !field.name.is_empty() {
24986 self.write(&field.name);
24988 self.write(self.config.struct_field_sep);
24989 }
24990 self.generate_data_type(&field.data_type)?;
24992 if let Some(comment) = &field.comment {
24994 self.write(" COMMENT '");
24995 self.write(comment);
24996 self.write("'");
24997 }
24998 if !field.options.is_empty() {
25000 self.write(" ");
25001 self.generate_options_clause(&field.options)?;
25002 }
25003 }
25004 self.write(">");
25005 }
25006 }
25007 }
25008 }
25009 DataType::Enum {
25010 values,
25011 assignments,
25012 } => {
25013 if self.config.dialect == Some(DialectType::ClickHouse) {
25016 self.write("Enum(");
25017 } else {
25018 self.write_keyword("ENUM(");
25019 }
25020 for (i, val) in values.iter().enumerate() {
25021 if i > 0 {
25022 self.write(", ");
25023 }
25024 self.write("'");
25025 self.write(val);
25026 self.write("'");
25027 if let Some(Some(assignment)) = assignments.get(i) {
25028 self.write(" = ");
25029 self.write(assignment);
25030 }
25031 }
25032 self.write(")");
25033 }
25034 DataType::Set { values } => {
25035 self.write_keyword("SET(");
25037 for (i, val) in values.iter().enumerate() {
25038 if i > 0 {
25039 self.write(", ");
25040 }
25041 self.write("'");
25042 self.write(val);
25043 self.write("'");
25044 }
25045 self.write(")");
25046 }
25047 DataType::Union { fields } => {
25048 self.write_keyword("UNION(");
25050 for (i, (name, dt)) in fields.iter().enumerate() {
25051 if i > 0 {
25052 self.write(", ");
25053 }
25054 if !name.is_empty() {
25055 self.write(name);
25056 self.write(" ");
25057 }
25058 self.generate_data_type(dt)?;
25059 }
25060 self.write(")");
25061 }
25062 DataType::Nullable { inner } => {
25063 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
25065 self.write("Nullable(");
25066 let saved_depth = self.clickhouse_nullable_depth;
25068 self.clickhouse_nullable_depth = -1;
25069 self.generate_data_type(inner)?;
25070 self.clickhouse_nullable_depth = saved_depth;
25071 self.write(")");
25072 } else {
25073 match inner.as_ref() {
25075 DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
25076 self.generate_data_type(&DataType::Timestamp {
25077 precision: None,
25078 timezone: false,
25079 })?;
25080 }
25081 _ => {
25082 self.generate_data_type(inner)?;
25083 }
25084 }
25085 }
25086 }
25087 DataType::Custom { name } => {
25088 let name_upper = name.to_ascii_uppercase();
25090 match self.config.dialect {
25091 Some(DialectType::ClickHouse) => {
25092 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
25093 (name_upper[..idx].to_string(), &name[idx..])
25094 } else {
25095 (name_upper.clone(), "")
25096 };
25097 let mapped = match base_upper.as_str() {
25098 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
25099 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
25100 "DATETIME64" => "DateTime64",
25101 "DATE32" => "Date32",
25102 "INT" => "Int32",
25103 "MEDIUMINT" => "Int32",
25104 "INT8" => "Int8",
25105 "INT16" => "Int16",
25106 "INT32" => "Int32",
25107 "INT64" => "Int64",
25108 "INT128" => "Int128",
25109 "INT256" => "Int256",
25110 "UINT8" => "UInt8",
25111 "UINT16" => "UInt16",
25112 "UINT32" => "UInt32",
25113 "UINT64" => "UInt64",
25114 "UINT128" => "UInt128",
25115 "UINT256" => "UInt256",
25116 "FLOAT32" => "Float32",
25117 "FLOAT64" => "Float64",
25118 "DECIMAL32" => "Decimal32",
25119 "DECIMAL64" => "Decimal64",
25120 "DECIMAL128" => "Decimal128",
25121 "DECIMAL256" => "Decimal256",
25122 "ENUM" => "Enum",
25123 "ENUM8" => "Enum8",
25124 "ENUM16" => "Enum16",
25125 "FIXEDSTRING" => "FixedString",
25126 "NESTED" => "Nested",
25127 "LOWCARDINALITY" => "LowCardinality",
25128 "NULLABLE" => "Nullable",
25129 "IPV4" => "IPv4",
25130 "IPV6" => "IPv6",
25131 "POINT" => "Point",
25132 "RING" => "Ring",
25133 "LINESTRING" => "LineString",
25134 "MULTILINESTRING" => "MultiLineString",
25135 "POLYGON" => "Polygon",
25136 "MULTIPOLYGON" => "MultiPolygon",
25137 "AGGREGATEFUNCTION" => "AggregateFunction",
25138 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
25139 "DYNAMIC" => "Dynamic",
25140 _ => "",
25141 };
25142 if mapped.is_empty() {
25143 self.write(name);
25144 } else {
25145 self.write(mapped);
25146 if matches!(base_upper.as_str(), "ENUM8" | "ENUM16")
25147 && !suffix.is_empty()
25148 {
25149 let escaped_suffix = suffix
25150 .replace('\\', "\\\\")
25151 .replace('\t', "\\t")
25152 .replace('\n', "\\n")
25153 .replace('\r', "\\r");
25154 self.write(&escaped_suffix);
25155 } else {
25156 self.write(suffix);
25157 }
25158 }
25159 }
25160 Some(DialectType::MySQL)
25161 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
25162 {
25163 self.write_keyword("TIMESTAMP");
25165 }
25166 Some(DialectType::Snowflake) => {
25167 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
25168 (name_upper[..idx].to_string(), &name[idx..])
25169 } else {
25170 (name_upper.clone(), "")
25171 };
25172
25173 match base_upper.as_str() {
25174 "TIMESTAMPNTZ" | "TIMESTAMP_NTZ" => {
25175 self.write_keyword("TIMESTAMPNTZ");
25176 self.write(suffix);
25177 }
25178 "TIMESTAMPLTZ" | "TIMESTAMP_LTZ" => {
25179 self.write_keyword("TIMESTAMPLTZ");
25180 self.write(suffix);
25181 }
25182 "TIMESTAMPTZ" | "TIMESTAMP_TZ" => {
25183 self.write_keyword("TIMESTAMPTZ");
25184 self.write(suffix);
25185 }
25186 _ => self.write(name),
25187 }
25188 }
25189 Some(DialectType::Fabric) => {
25190 let (base_upper, args_str) = if let Some(idx) = name.find('(') {
25191 (name_upper[..idx].to_string(), Some(&name[idx..]))
25192 } else {
25193 (name_upper.clone(), None)
25194 };
25195
25196 match base_upper.as_str() {
25197 "NVARCHAR" => {
25198 self.write_keyword("VARCHAR");
25199 if let Some(args) = args_str {
25200 self.write(args);
25201 }
25202 }
25203 "NCHAR" => {
25204 self.write_keyword("CHAR");
25205 if let Some(args) = args_str {
25206 self.write(args);
25207 }
25208 }
25209 _ => self.write(name),
25210 }
25211 }
25212 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
25213 self.write_keyword("SQL_VARIANT");
25214 }
25215 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
25216 self.write_keyword("DECIMAL(38, 5)");
25217 }
25218 Some(DialectType::Exasol) => {
25219 match name_upper.as_str() {
25221 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
25223 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
25225 "MEDIUMINT" => self.write_keyword("INT"),
25227 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
25229 self.write_keyword("DECIMAL")
25230 }
25231 "DATETIME" => self.write_keyword("TIMESTAMP"),
25233 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
25234 _ => self.write(name),
25235 }
25236 }
25237 Some(DialectType::Dremio) => {
25238 match name_upper.as_str() {
25240 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
25241 "ARRAY" => self.write_keyword("LIST"),
25242 "NCHAR" => self.write_keyword("VARCHAR"),
25243 _ => self.write(name),
25244 }
25245 }
25246 _ => {
25248 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
25250 (name_upper[..idx].to_string(), Some(&name[idx..]))
25251 } else {
25252 (name_upper.clone(), None)
25253 };
25254
25255 match base_upper.as_str() {
25256 "INT64"
25257 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25258 {
25259 self.write_keyword("BIGINT");
25260 }
25261 "FLOAT64"
25262 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25263 {
25264 self.write_keyword("DOUBLE");
25265 }
25266 "BOOL"
25267 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25268 {
25269 self.write_keyword("BOOLEAN");
25270 }
25271 "BYTES"
25272 if matches!(
25273 self.config.dialect,
25274 Some(DialectType::Spark)
25275 | Some(DialectType::Hive)
25276 | Some(DialectType::Databricks)
25277 ) =>
25278 {
25279 self.write_keyword("BINARY");
25280 }
25281 "BYTES"
25282 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25283 {
25284 self.write_keyword("VARBINARY");
25285 }
25286 "DATETIME2" | "SMALLDATETIME"
25288 if !matches!(
25289 self.config.dialect,
25290 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25291 ) =>
25292 {
25293 if matches!(
25295 self.config.dialect,
25296 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
25297 ) {
25298 self.write_keyword("TIMESTAMP");
25299 if let Some(args) = _args_str {
25300 self.write(args);
25301 }
25302 } else {
25303 self.write_keyword("TIMESTAMP");
25304 }
25305 }
25306 "DATETIMEOFFSET"
25308 if !matches!(
25309 self.config.dialect,
25310 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25311 ) =>
25312 {
25313 if matches!(
25314 self.config.dialect,
25315 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
25316 ) {
25317 self.write_keyword("TIMESTAMPTZ");
25318 if let Some(args) = _args_str {
25319 self.write(args);
25320 }
25321 } else {
25322 self.write_keyword("TIMESTAMPTZ");
25323 }
25324 }
25325 "UNIQUEIDENTIFIER"
25327 if !matches!(
25328 self.config.dialect,
25329 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25330 ) =>
25331 {
25332 match self.config.dialect {
25333 Some(DialectType::Spark)
25334 | Some(DialectType::Databricks)
25335 | Some(DialectType::Hive) => self.write_keyword("STRING"),
25336 _ => self.write_keyword("UUID"),
25337 }
25338 }
25339 "BIT"
25341 if !matches!(
25342 self.config.dialect,
25343 Some(DialectType::TSQL)
25344 | Some(DialectType::Fabric)
25345 | Some(DialectType::PostgreSQL)
25346 | Some(DialectType::MySQL)
25347 | Some(DialectType::DuckDB)
25348 ) =>
25349 {
25350 self.write_keyword("BOOLEAN");
25351 }
25352 "NVARCHAR"
25354 if !matches!(
25355 self.config.dialect,
25356 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25357 ) =>
25358 {
25359 match self.config.dialect {
25360 Some(DialectType::Oracle) => {
25361 self.write_keyword("NVARCHAR2");
25363 if let Some(args) = _args_str {
25364 self.write(args);
25365 }
25366 }
25367 Some(DialectType::BigQuery) => {
25368 self.write_keyword("STRING");
25370 }
25371 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
25372 self.write_keyword("TEXT");
25373 if let Some(args) = _args_str {
25374 self.write(args);
25375 }
25376 }
25377 Some(DialectType::Hive) => {
25378 self.write_keyword("STRING");
25380 }
25381 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
25382 if _args_str.is_some() {
25383 self.write_keyword("VARCHAR");
25384 self.write(_args_str.unwrap());
25385 } else {
25386 self.write_keyword("STRING");
25387 }
25388 }
25389 _ => {
25390 self.write_keyword("VARCHAR");
25391 if let Some(args) = _args_str {
25392 self.write(args);
25393 }
25394 }
25395 }
25396 }
25397 "NCHAR"
25399 if !matches!(
25400 self.config.dialect,
25401 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25402 ) =>
25403 {
25404 match self.config.dialect {
25405 Some(DialectType::Oracle) => {
25406 self.write_keyword("NCHAR");
25408 if let Some(args) = _args_str {
25409 self.write(args);
25410 }
25411 }
25412 Some(DialectType::BigQuery) => {
25413 self.write_keyword("STRING");
25415 }
25416 Some(DialectType::Hive) => {
25417 self.write_keyword("STRING");
25419 }
25420 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
25421 self.write_keyword("TEXT");
25422 if let Some(args) = _args_str {
25423 self.write(args);
25424 }
25425 }
25426 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
25427 if _args_str.is_some() {
25428 self.write_keyword("CHAR");
25429 self.write(_args_str.unwrap());
25430 } else {
25431 self.write_keyword("STRING");
25432 }
25433 }
25434 _ => {
25435 self.write_keyword("CHAR");
25436 if let Some(args) = _args_str {
25437 self.write(args);
25438 }
25439 }
25440 }
25441 }
25442 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
25445 Some(DialectType::MySQL)
25446 | Some(DialectType::SingleStore)
25447 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
25448 Some(DialectType::Spark)
25449 | Some(DialectType::Databricks)
25450 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
25451 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
25452 Some(DialectType::Presto)
25453 | Some(DialectType::Trino)
25454 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
25455 Some(DialectType::Snowflake)
25456 | Some(DialectType::Redshift)
25457 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
25458 _ => self.write_keyword("TEXT"),
25459 },
25460 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
25463 Some(DialectType::MySQL)
25464 | Some(DialectType::SingleStore)
25465 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
25466 Some(DialectType::Spark)
25467 | Some(DialectType::Databricks)
25468 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
25469 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
25470 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
25471 Some(DialectType::Presto)
25472 | Some(DialectType::Trino)
25473 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
25474 Some(DialectType::Snowflake)
25475 | Some(DialectType::Redshift)
25476 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
25477 _ => self.write_keyword("BLOB"),
25478 },
25479 "LONGVARCHAR" => match self.config.dialect {
25481 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
25482 _ => self.write_keyword("VARCHAR"),
25483 },
25484 "DATETIME" => {
25486 match self.config.dialect {
25487 Some(DialectType::MySQL)
25488 | Some(DialectType::Doris)
25489 | Some(DialectType::StarRocks)
25490 | Some(DialectType::TSQL)
25491 | Some(DialectType::Fabric)
25492 | Some(DialectType::BigQuery)
25493 | Some(DialectType::SQLite)
25494 | Some(DialectType::Snowflake) => {
25495 self.write_keyword("DATETIME");
25496 if let Some(args) = _args_str {
25497 self.write(args);
25498 }
25499 }
25500 Some(_) => {
25501 self.write_keyword("TIMESTAMP");
25503 if let Some(args) = _args_str {
25504 self.write(args);
25505 }
25506 }
25507 None => {
25508 self.write(name);
25510 }
25511 }
25512 }
25513 "VARCHAR2"
25515 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
25516 {
25517 match self.config.dialect {
25518 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
25519 self.write_keyword("TEXT");
25520 }
25521 Some(DialectType::Hive)
25522 | Some(DialectType::Spark)
25523 | Some(DialectType::Databricks)
25524 | Some(DialectType::BigQuery)
25525 | Some(DialectType::ClickHouse)
25526 | Some(DialectType::StarRocks)
25527 | Some(DialectType::Doris) => {
25528 self.write_keyword("STRING");
25529 }
25530 _ => {
25531 self.write_keyword("VARCHAR");
25532 if let Some(args) = _args_str {
25533 self.write(args);
25534 }
25535 }
25536 }
25537 }
25538 "NVARCHAR2"
25539 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
25540 {
25541 match self.config.dialect {
25542 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
25543 self.write_keyword("TEXT");
25544 }
25545 Some(DialectType::Hive)
25546 | Some(DialectType::Spark)
25547 | Some(DialectType::Databricks)
25548 | Some(DialectType::BigQuery)
25549 | Some(DialectType::ClickHouse)
25550 | Some(DialectType::StarRocks)
25551 | Some(DialectType::Doris) => {
25552 self.write_keyword("STRING");
25553 }
25554 _ => {
25555 self.write_keyword("VARCHAR");
25556 if let Some(args) = _args_str {
25557 self.write(args);
25558 }
25559 }
25560 }
25561 }
25562 _ => self.write(name),
25563 }
25564 }
25565 }
25566 }
25567 DataType::Geometry { subtype, srid } => {
25568 match self.config.dialect {
25570 Some(DialectType::MySQL) => {
25571 if let Some(sub) = subtype {
25573 self.write_keyword(sub);
25574 if let Some(s) = srid {
25575 self.write(" SRID ");
25576 self.write(&s.to_string());
25577 }
25578 } else {
25579 self.write_keyword("GEOMETRY");
25580 }
25581 }
25582 Some(DialectType::BigQuery) => {
25583 self.write_keyword("GEOGRAPHY");
25585 }
25586 Some(DialectType::Teradata) => {
25587 self.write_keyword("ST_GEOMETRY");
25589 if subtype.is_some() || srid.is_some() {
25590 self.write("(");
25591 if let Some(sub) = subtype {
25592 self.write_keyword(sub);
25593 }
25594 if let Some(s) = srid {
25595 if subtype.is_some() {
25596 self.write(", ");
25597 }
25598 self.write(&s.to_string());
25599 }
25600 self.write(")");
25601 }
25602 }
25603 _ => {
25604 self.write_keyword("GEOMETRY");
25606 if subtype.is_some() || srid.is_some() {
25607 self.write("(");
25608 if let Some(sub) = subtype {
25609 self.write_keyword(sub);
25610 }
25611 if let Some(s) = srid {
25612 if subtype.is_some() {
25613 self.write(", ");
25614 }
25615 self.write(&s.to_string());
25616 }
25617 self.write(")");
25618 }
25619 }
25620 }
25621 }
25622 DataType::Geography { subtype, srid } => {
25623 match self.config.dialect {
25625 Some(DialectType::MySQL) => {
25626 if let Some(sub) = subtype {
25628 self.write_keyword(sub);
25629 } else {
25630 self.write_keyword("GEOMETRY");
25631 }
25632 let effective_srid = srid.unwrap_or(4326);
25634 self.write(" SRID ");
25635 self.write(&effective_srid.to_string());
25636 }
25637 Some(DialectType::BigQuery) => {
25638 self.write_keyword("GEOGRAPHY");
25640 }
25641 Some(DialectType::Snowflake) => {
25642 self.write_keyword("GEOGRAPHY");
25644 }
25645 _ => {
25646 self.write_keyword("GEOGRAPHY");
25648 if subtype.is_some() || srid.is_some() {
25649 self.write("(");
25650 if let Some(sub) = subtype {
25651 self.write_keyword(sub);
25652 }
25653 if let Some(s) = srid {
25654 if subtype.is_some() {
25655 self.write(", ");
25656 }
25657 self.write(&s.to_string());
25658 }
25659 self.write(")");
25660 }
25661 }
25662 }
25663 }
25664 DataType::CharacterSet { name } => {
25665 self.write_keyword("CHAR CHARACTER SET ");
25667 self.write(name);
25668 }
25669 _ => self.write("UNKNOWN"),
25670 }
25671 Ok(())
25672 }
25673
25674 #[inline]
25677 fn write(&mut self, s: &str) {
25678 self.output.push_str(s);
25679 }
25680
25681 #[inline]
25682 fn write_space(&mut self) {
25683 self.output.push(' ');
25684 }
25685
25686 #[inline]
25687 fn write_keyword(&mut self, keyword: &str) {
25688 if self.config.uppercase_keywords {
25689 self.output.push_str(keyword);
25690 } else {
25691 for b in keyword.bytes() {
25692 self.output.push(b.to_ascii_lowercase() as char);
25693 }
25694 }
25695 }
25696
25697 fn write_func_name(&mut self, name: &str) {
25699 let normalized = self.normalize_func_name(name);
25700 self.output.push_str(normalized.as_ref());
25701 }
25702
25703 fn convert_strptime_to_exasol_format(format: &str) -> String {
25707 let mut result = String::new();
25708 let chars: Vec<char> = format.chars().collect();
25709 let mut i = 0;
25710 while i < chars.len() {
25711 if chars[i] == '%' && i + 1 < chars.len() {
25712 let spec = chars[i + 1];
25713 let exasol_spec = match spec {
25714 'Y' => "YYYY",
25715 'y' => "YY",
25716 'm' => "MM",
25717 'd' => "DD",
25718 'H' => "HH",
25719 'M' => "MI",
25720 'S' => "SS",
25721 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
25733 result.push('%');
25735 result.push(spec);
25736 i += 2;
25737 continue;
25738 }
25739 };
25740 result.push_str(exasol_spec);
25741 i += 2;
25742 } else {
25743 result.push(chars[i]);
25744 i += 1;
25745 }
25746 }
25747 result
25748 }
25749
25750 fn convert_strptime_to_postgres_format(format: &str) -> String {
25754 let mut result = String::new();
25755 let chars: Vec<char> = format.chars().collect();
25756 let mut i = 0;
25757 while i < chars.len() {
25758 if chars[i] == '%' && i + 1 < chars.len() {
25759 if chars[i + 1] == '-' && i + 2 < chars.len() {
25761 let spec = chars[i + 2];
25762 let pg_spec = match spec {
25763 'd' => "FMDD",
25764 'm' => "FMMM",
25765 'H' => "FMHH24",
25766 'M' => "FMMI",
25767 'S' => "FMSS",
25768 _ => {
25769 result.push('%');
25770 result.push('-');
25771 result.push(spec);
25772 i += 3;
25773 continue;
25774 }
25775 };
25776 result.push_str(pg_spec);
25777 i += 3;
25778 continue;
25779 }
25780 let spec = chars[i + 1];
25781 let pg_spec = match spec {
25782 'Y' => "YYYY",
25783 'y' => "YY",
25784 'm' => "MM",
25785 'd' => "DD",
25786 'H' => "HH24",
25787 'I' => "HH12",
25788 'M' => "MI",
25789 'S' => "SS",
25790 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
25801 result.push('%');
25803 result.push(spec);
25804 i += 2;
25805 continue;
25806 }
25807 };
25808 result.push_str(pg_spec);
25809 i += 2;
25810 } else {
25811 result.push(chars[i]);
25812 i += 1;
25813 }
25814 }
25815 result
25816 }
25817
25818 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
25820 if self.config.limit_only_literals {
25821 if let Some(value) = Self::try_evaluate_constant(expr) {
25822 self.write(&value.to_string());
25823 return Ok(());
25824 }
25825 }
25826 self.generate_expression(expr)
25827 }
25828
25829 fn write_formatted_comment(&mut self, comment: &str) {
25833 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
25836 &comment[2..comment.len() - 2]
25839 } else if comment.starts_with("--") {
25840 &comment[2..]
25843 } else {
25844 comment
25846 };
25847 if content.trim().is_empty() {
25849 return;
25850 }
25851 let sanitized = content.replace("*/", "* /").replace("/*", "/ *");
25854 let content = &sanitized;
25855 self.output.push_str("/*");
25857 if !content.starts_with(' ') {
25858 self.output.push(' ');
25859 }
25860 self.output.push_str(content);
25861 if !content.ends_with(' ') {
25862 self.output.push(' ');
25863 }
25864 self.output.push_str("*/");
25865 }
25866
25867 fn escape_block_for_single_quote(&self, block: &str) -> String {
25870 let escape_backslash = matches!(
25871 self.config.dialect,
25872 Some(crate::dialects::DialectType::Snowflake)
25873 );
25874 let mut escaped = String::with_capacity(block.len() + 4);
25875 for ch in block.chars() {
25876 if ch == '\'' {
25877 escaped.push('\\');
25878 escaped.push('\'');
25879 } else if escape_backslash && ch == '\\' {
25880 escaped.push('\\');
25881 escaped.push('\\');
25882 } else {
25883 escaped.push(ch);
25884 }
25885 }
25886 escaped
25887 }
25888
25889 fn write_newline(&mut self) {
25890 self.output.push('\n');
25891 }
25892
25893 fn write_indent(&mut self) {
25894 for _ in 0..self.indent_level {
25895 self.output.push_str(self.config.indent);
25896 }
25897 }
25898
25899 fn too_wide(&self, args: &[String]) -> bool {
25905 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
25906 }
25907
25908 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
25911 let config = GeneratorConfig {
25912 pretty: false,
25913 dialect: self.config.dialect,
25914 ..Default::default()
25915 };
25916 let mut gen = Generator::with_config(config);
25917 gen.generate_expression(expr)?;
25918 Ok(gen.output)
25919 }
25920
25921 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
25924 if self.config.pretty {
25925 self.write_newline();
25926 self.write_indent();
25927 self.write_keyword(keyword);
25928 self.write_newline();
25929 self.indent_level += 1;
25930 self.write_indent();
25931 self.generate_expression(condition)?;
25932 self.indent_level -= 1;
25933 } else {
25934 self.write_space();
25935 self.write_keyword(keyword);
25936 self.write_space();
25937 self.generate_expression(condition)?;
25938 }
25939 Ok(())
25940 }
25941
25942 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
25945 if exprs.is_empty() {
25946 return Ok(());
25947 }
25948
25949 if self.config.pretty {
25950 self.write_newline();
25951 self.write_indent();
25952 self.write_keyword(keyword);
25953 self.write_newline();
25954 self.indent_level += 1;
25955 for (i, expr) in exprs.iter().enumerate() {
25956 if i > 0 {
25957 self.write(",");
25958 self.write_newline();
25959 }
25960 self.write_indent();
25961 self.generate_expression(expr)?;
25962 }
25963 self.indent_level -= 1;
25964 } else {
25965 self.write_space();
25966 self.write_keyword(keyword);
25967 self.write_space();
25968 for (i, expr) in exprs.iter().enumerate() {
25969 if i > 0 {
25970 self.write(", ");
25971 }
25972 self.generate_expression(expr)?;
25973 }
25974 }
25975 Ok(())
25976 }
25977
25978 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
25980 if orderings.is_empty() {
25981 return Ok(());
25982 }
25983
25984 if self.config.pretty {
25985 self.write_newline();
25986 self.write_indent();
25987 self.write_keyword(keyword);
25988 self.write_newline();
25989 self.indent_level += 1;
25990 for (i, ordered) in orderings.iter().enumerate() {
25991 if i > 0 {
25992 self.write(",");
25993 self.write_newline();
25994 }
25995 self.write_indent();
25996 self.generate_ordered(ordered)?;
25997 }
25998 self.indent_level -= 1;
25999 } else {
26000 self.write_space();
26001 self.write_keyword(keyword);
26002 self.write_space();
26003 for (i, ordered) in orderings.iter().enumerate() {
26004 if i > 0 {
26005 self.write(", ");
26006 }
26007 self.generate_ordered(ordered)?;
26008 }
26009 }
26010 Ok(())
26011 }
26012
26013 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
26015 if windows.is_empty() {
26016 return Ok(());
26017 }
26018
26019 if self.config.pretty {
26020 self.write_newline();
26021 self.write_indent();
26022 self.write_keyword("WINDOW");
26023 self.write_newline();
26024 self.indent_level += 1;
26025 for (i, named_window) in windows.iter().enumerate() {
26026 if i > 0 {
26027 self.write(",");
26028 self.write_newline();
26029 }
26030 self.write_indent();
26031 self.generate_identifier(&named_window.name)?;
26032 self.write_space();
26033 self.write_keyword("AS");
26034 self.write(" (");
26035 self.generate_over(&named_window.spec)?;
26036 self.write(")");
26037 }
26038 self.indent_level -= 1;
26039 } else {
26040 self.write_space();
26041 self.write_keyword("WINDOW");
26042 self.write_space();
26043 for (i, named_window) in windows.iter().enumerate() {
26044 if i > 0 {
26045 self.write(", ");
26046 }
26047 self.generate_identifier(&named_window.name)?;
26048 self.write_space();
26049 self.write_keyword("AS");
26050 self.write(" (");
26051 self.generate_over(&named_window.spec)?;
26052 self.write(")");
26053 }
26054 }
26055 Ok(())
26056 }
26057
26058 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
26060 self.write_keyword("AI_AGG");
26062 self.write("(");
26063 self.generate_expression(&e.this)?;
26064 self.write(", ");
26065 self.generate_expression(&e.expression)?;
26066 self.write(")");
26067 Ok(())
26068 }
26069
26070 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
26071 self.write_keyword("AI_CLASSIFY");
26073 self.write("(");
26074 self.generate_expression(&e.this)?;
26075 if let Some(categories) = &e.categories {
26076 self.write(", ");
26077 self.generate_expression(categories)?;
26078 }
26079 if let Some(config) = &e.config {
26080 self.write(", ");
26081 self.generate_expression(config)?;
26082 }
26083 self.write(")");
26084 Ok(())
26085 }
26086
26087 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
26088 self.write_keyword("ADD");
26090 self.write_space();
26091 if e.exists {
26092 self.write_keyword("IF NOT EXISTS");
26093 self.write_space();
26094 }
26095 self.generate_expression(&e.this)?;
26096 if let Some(location) = &e.location {
26097 self.write_space();
26098 self.generate_expression(location)?;
26099 }
26100 Ok(())
26101 }
26102
26103 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
26104 self.write_keyword("ALGORITHM");
26106 self.write("=");
26107 self.generate_expression(&e.this)?;
26108 Ok(())
26109 }
26110
26111 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
26112 self.generate_expression(&e.this)?;
26114 self.write_space();
26115 self.write_keyword("AS");
26116 self.write(" (");
26117 for (i, expr) in e.expressions.iter().enumerate() {
26118 if i > 0 {
26119 self.write(", ");
26120 }
26121 self.generate_expression(expr)?;
26122 }
26123 self.write(")");
26124 Ok(())
26125 }
26126
26127 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
26128 self.write_keyword("ALLOWED_VALUES");
26130 self.write_space();
26131 for (i, expr) in e.expressions.iter().enumerate() {
26132 if i > 0 {
26133 self.write(", ");
26134 }
26135 self.generate_expression(expr)?;
26136 }
26137 Ok(())
26138 }
26139
26140 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
26141 self.write_keyword("ALTER COLUMN");
26143 self.write_space();
26144 self.generate_expression(&e.this)?;
26145
26146 if let Some(dtype) = &e.dtype {
26147 self.write_space();
26148 self.write_keyword("SET DATA TYPE");
26149 self.write_space();
26150 self.generate_expression(dtype)?;
26151 if let Some(collate) = &e.collate {
26152 self.write_space();
26153 self.write_keyword("COLLATE");
26154 self.write_space();
26155 self.generate_expression(collate)?;
26156 }
26157 if let Some(using) = &e.using {
26158 self.write_space();
26159 self.write_keyword("USING");
26160 self.write_space();
26161 self.generate_expression(using)?;
26162 }
26163 } else if let Some(default) = &e.default {
26164 self.write_space();
26165 self.write_keyword("SET DEFAULT");
26166 self.write_space();
26167 self.generate_expression(default)?;
26168 } else if let Some(comment) = &e.comment {
26169 self.write_space();
26170 self.write_keyword("COMMENT");
26171 self.write_space();
26172 self.generate_expression(comment)?;
26173 } else if let Some(drop) = &e.drop {
26174 self.write_space();
26175 self.write_keyword("DROP");
26176 self.write_space();
26177 self.generate_expression(drop)?;
26178 } else if let Some(visible) = &e.visible {
26179 self.write_space();
26180 self.generate_expression(visible)?;
26181 } else if let Some(rename_to) = &e.rename_to {
26182 self.write_space();
26183 self.write_keyword("RENAME TO");
26184 self.write_space();
26185 self.generate_expression(rename_to)?;
26186 } else if let Some(allow_null) = &e.allow_null {
26187 self.write_space();
26188 self.generate_expression(allow_null)?;
26189 }
26190 Ok(())
26191 }
26192
26193 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
26194 self.write_keyword("ALTER SESSION");
26196 self.write_space();
26197 if e.unset.is_some() {
26198 self.write_keyword("UNSET");
26199 } else {
26200 self.write_keyword("SET");
26201 }
26202 self.write_space();
26203 for (i, expr) in e.expressions.iter().enumerate() {
26204 if i > 0 {
26205 self.write(", ");
26206 }
26207 self.generate_expression(expr)?;
26208 }
26209 Ok(())
26210 }
26211
26212 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
26213 self.write_keyword("SET");
26215
26216 if let Some(opt) = &e.option {
26218 self.write_space();
26219 self.generate_expression(opt)?;
26220 }
26221
26222 if !e.expressions.is_empty() {
26225 let is_properties = e
26227 .expressions
26228 .iter()
26229 .any(|expr| matches!(expr, Expression::Eq(_)));
26230 if is_properties && e.option.is_none() {
26231 self.write_space();
26232 self.write_keyword("PROPERTIES");
26233 }
26234 self.write_space();
26235 for (i, expr) in e.expressions.iter().enumerate() {
26236 if i > 0 {
26237 self.write(", ");
26238 }
26239 self.generate_expression(expr)?;
26240 }
26241 }
26242
26243 if let Some(file_format) = &e.file_format {
26245 self.write(" ");
26246 self.write_keyword("STAGE_FILE_FORMAT");
26247 self.write(" = (");
26248 self.generate_space_separated_properties(file_format)?;
26249 self.write(")");
26250 }
26251
26252 if let Some(copy_options) = &e.copy_options {
26254 self.write(" ");
26255 self.write_keyword("STAGE_COPY_OPTIONS");
26256 self.write(" = (");
26257 self.generate_space_separated_properties(copy_options)?;
26258 self.write(")");
26259 }
26260
26261 if let Some(tag) = &e.tag {
26263 self.write(" ");
26264 self.write_keyword("TAG");
26265 self.write(" ");
26266 self.generate_expression(tag)?;
26267 }
26268
26269 Ok(())
26270 }
26271
26272 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
26274 match expr {
26275 Expression::Tuple(t) => {
26276 for (i, prop) in t.expressions.iter().enumerate() {
26277 if i > 0 {
26278 self.write(" ");
26279 }
26280 self.generate_expression(prop)?;
26281 }
26282 }
26283 _ => {
26284 self.generate_expression(expr)?;
26285 }
26286 }
26287 Ok(())
26288 }
26289
26290 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
26291 self.write_keyword("ALTER");
26293 if e.compound.is_some() {
26294 self.write_space();
26295 self.write_keyword("COMPOUND");
26296 }
26297 self.write_space();
26298 self.write_keyword("SORTKEY");
26299 self.write_space();
26300 if let Some(this) = &e.this {
26301 self.generate_expression(this)?;
26302 } else if !e.expressions.is_empty() {
26303 self.write("(");
26304 for (i, expr) in e.expressions.iter().enumerate() {
26305 if i > 0 {
26306 self.write(", ");
26307 }
26308 self.generate_expression(expr)?;
26309 }
26310 self.write(")");
26311 }
26312 Ok(())
26313 }
26314
26315 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
26316 self.write_keyword("ANALYZE");
26318 if !e.options.is_empty() {
26319 self.write_space();
26320 for (i, opt) in e.options.iter().enumerate() {
26321 if i > 0 {
26322 self.write_space();
26323 }
26324 if let Expression::Identifier(id) = opt {
26326 self.write_keyword(&id.name);
26327 } else {
26328 self.generate_expression(opt)?;
26329 }
26330 }
26331 }
26332 if let Some(kind) = &e.kind {
26333 self.write_space();
26334 self.write_keyword(kind);
26335 }
26336 if let Some(this) = &e.this {
26337 self.write_space();
26338 self.generate_expression(this)?;
26339 }
26340 if !e.columns.is_empty() {
26342 self.write("(");
26343 for (i, col) in e.columns.iter().enumerate() {
26344 if i > 0 {
26345 self.write(", ");
26346 }
26347 self.write(col);
26348 }
26349 self.write(")");
26350 }
26351 if let Some(partition) = &e.partition {
26352 self.write_space();
26353 self.generate_expression(partition)?;
26354 }
26355 if let Some(mode) = &e.mode {
26356 self.write_space();
26357 self.generate_expression(mode)?;
26358 }
26359 if let Some(expression) = &e.expression {
26360 self.write_space();
26361 self.generate_expression(expression)?;
26362 }
26363 if !e.properties.is_empty() {
26364 self.write_space();
26365 self.write_keyword(self.config.with_properties_prefix);
26366 self.write(" (");
26367 for (i, prop) in e.properties.iter().enumerate() {
26368 if i > 0 {
26369 self.write(", ");
26370 }
26371 self.generate_expression(prop)?;
26372 }
26373 self.write(")");
26374 }
26375 Ok(())
26376 }
26377
26378 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
26379 self.write_keyword("DELETE");
26381 if let Some(kind) = &e.kind {
26382 self.write_space();
26383 self.write_keyword(kind);
26384 }
26385 self.write_space();
26386 self.write_keyword("STATISTICS");
26387 Ok(())
26388 }
26389
26390 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
26391 if let Expression::Identifier(id) = e.this.as_ref() {
26394 self.write_keyword(&id.name);
26395 } else {
26396 self.generate_expression(&e.this)?;
26397 }
26398 self.write_space();
26399 self.write_keyword("HISTOGRAM ON");
26400 self.write_space();
26401 for (i, expr) in e.expressions.iter().enumerate() {
26402 if i > 0 {
26403 self.write(", ");
26404 }
26405 self.generate_expression(expr)?;
26406 }
26407 if let Some(expression) = &e.expression {
26408 self.write_space();
26409 self.generate_expression(expression)?;
26410 }
26411 if let Some(update_options) = &e.update_options {
26412 self.write_space();
26413 self.generate_expression(update_options)?;
26414 self.write_space();
26415 self.write_keyword("UPDATE");
26416 }
26417 Ok(())
26418 }
26419
26420 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
26421 self.write_keyword("LIST CHAINED ROWS");
26423 if let Some(expression) = &e.expression {
26424 self.write_space();
26425 self.write_keyword("INTO");
26426 self.write_space();
26427 self.generate_expression(expression)?;
26428 }
26429 Ok(())
26430 }
26431
26432 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
26433 self.write_keyword("SAMPLE");
26435 self.write_space();
26436 if let Some(sample) = &e.sample {
26437 self.generate_expression(sample)?;
26438 self.write_space();
26439 }
26440 self.write_keyword(&e.kind);
26441 Ok(())
26442 }
26443
26444 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
26445 self.write_keyword(&e.kind);
26447 if let Some(option) = &e.option {
26448 self.write_space();
26449 self.generate_expression(option)?;
26450 }
26451 self.write_space();
26452 self.write_keyword("STATISTICS");
26453 if let Some(this) = &e.this {
26454 self.write_space();
26455 self.generate_expression(this)?;
26456 }
26457 if !e.expressions.is_empty() {
26458 self.write_space();
26459 for (i, expr) in e.expressions.iter().enumerate() {
26460 if i > 0 {
26461 self.write(", ");
26462 }
26463 self.generate_expression(expr)?;
26464 }
26465 }
26466 Ok(())
26467 }
26468
26469 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
26470 self.write_keyword("VALIDATE");
26472 self.write_space();
26473 self.write_keyword(&e.kind);
26474 if let Some(this) = &e.this {
26475 self.write_space();
26476 if let Expression::Identifier(id) = this.as_ref() {
26478 self.write_keyword(&id.name);
26479 } else {
26480 self.generate_expression(this)?;
26481 }
26482 }
26483 if let Some(expression) = &e.expression {
26484 self.write_space();
26485 self.write_keyword("INTO");
26486 self.write_space();
26487 self.generate_expression(expression)?;
26488 }
26489 Ok(())
26490 }
26491
26492 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
26493 self.write_keyword("WITH");
26495 self.write_space();
26496 for (i, expr) in e.expressions.iter().enumerate() {
26497 if i > 0 {
26498 self.write(", ");
26499 }
26500 self.generate_expression(expr)?;
26501 }
26502 Ok(())
26503 }
26504
26505 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
26506 self.generate_expression(&e.this)?;
26509 self.write("(");
26510 for (i, arg) in e.expressions.iter().enumerate() {
26511 if i > 0 {
26512 self.write(", ");
26513 }
26514 self.generate_expression(arg)?;
26515 }
26516 self.write(")");
26517 Ok(())
26518 }
26519
26520 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
26521 self.generate_expression(&e.this)?;
26523 self.write("(");
26524 for (i, arg) in e.expressions.iter().enumerate() {
26525 if i > 0 {
26526 self.write(", ");
26527 }
26528 self.generate_expression(arg)?;
26529 }
26530 self.write(")");
26531 Ok(())
26532 }
26533
26534 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
26535 self.generate_expression(&e.this)?;
26537 self.write_space();
26538 self.write_keyword("APPLY");
26539 self.write("(");
26540 self.generate_expression(&e.expression)?;
26541 self.write(")");
26542 Ok(())
26543 }
26544
26545 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
26546 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
26548 self.write("(");
26549 self.generate_expression(&e.this)?;
26550 if let Some(percentile) = &e.percentile {
26551 self.write(", ");
26552 self.generate_expression(percentile)?;
26553 }
26554 self.write(")");
26555 Ok(())
26556 }
26557
26558 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
26559 self.write_keyword("APPROX_QUANTILE");
26561 self.write("(");
26562 self.generate_expression(&e.this)?;
26563 if let Some(quantile) = &e.quantile {
26564 self.write(", ");
26565 self.generate_expression(quantile)?;
26566 }
26567 if let Some(accuracy) = &e.accuracy {
26568 self.write(", ");
26569 self.generate_expression(accuracy)?;
26570 }
26571 if let Some(weight) = &e.weight {
26572 self.write(", ");
26573 self.generate_expression(weight)?;
26574 }
26575 self.write(")");
26576 Ok(())
26577 }
26578
26579 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
26580 self.write_keyword("APPROX_QUANTILES");
26582 self.write("(");
26583 self.generate_expression(&e.this)?;
26584 if let Some(expression) = &e.expression {
26585 self.write(", ");
26586 self.generate_expression(expression)?;
26587 }
26588 self.write(")");
26589 Ok(())
26590 }
26591
26592 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
26593 self.write_keyword("APPROX_TOP_K");
26595 self.write("(");
26596 self.generate_expression(&e.this)?;
26597 if let Some(expression) = &e.expression {
26598 self.write(", ");
26599 self.generate_expression(expression)?;
26600 }
26601 if let Some(counters) = &e.counters {
26602 self.write(", ");
26603 self.generate_expression(counters)?;
26604 }
26605 self.write(")");
26606 Ok(())
26607 }
26608
26609 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
26610 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
26612 self.write("(");
26613 self.generate_expression(&e.this)?;
26614 if let Some(expression) = &e.expression {
26615 self.write(", ");
26616 self.generate_expression(expression)?;
26617 }
26618 self.write(")");
26619 Ok(())
26620 }
26621
26622 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
26623 self.write_keyword("APPROX_TOP_K_COMBINE");
26625 self.write("(");
26626 self.generate_expression(&e.this)?;
26627 if let Some(expression) = &e.expression {
26628 self.write(", ");
26629 self.generate_expression(expression)?;
26630 }
26631 self.write(")");
26632 Ok(())
26633 }
26634
26635 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
26636 self.write_keyword("APPROX_TOP_K_ESTIMATE");
26638 self.write("(");
26639 self.generate_expression(&e.this)?;
26640 if let Some(expression) = &e.expression {
26641 self.write(", ");
26642 self.generate_expression(expression)?;
26643 }
26644 self.write(")");
26645 Ok(())
26646 }
26647
26648 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
26649 self.write_keyword("APPROX_TOP_SUM");
26651 self.write("(");
26652 self.generate_expression(&e.this)?;
26653 self.write(", ");
26654 self.generate_expression(&e.expression)?;
26655 if let Some(count) = &e.count {
26656 self.write(", ");
26657 self.generate_expression(count)?;
26658 }
26659 self.write(")");
26660 Ok(())
26661 }
26662
26663 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
26664 self.write_keyword("ARG_MAX");
26666 self.write("(");
26667 self.generate_expression(&e.this)?;
26668 self.write(", ");
26669 self.generate_expression(&e.expression)?;
26670 if let Some(count) = &e.count {
26671 self.write(", ");
26672 self.generate_expression(count)?;
26673 }
26674 self.write(")");
26675 Ok(())
26676 }
26677
26678 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
26679 self.write_keyword("ARG_MIN");
26681 self.write("(");
26682 self.generate_expression(&e.this)?;
26683 self.write(", ");
26684 self.generate_expression(&e.expression)?;
26685 if let Some(count) = &e.count {
26686 self.write(", ");
26687 self.generate_expression(count)?;
26688 }
26689 self.write(")");
26690 Ok(())
26691 }
26692
26693 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
26694 self.write_keyword("ARRAY_ALL");
26696 self.write("(");
26697 self.generate_expression(&e.this)?;
26698 self.write(", ");
26699 self.generate_expression(&e.expression)?;
26700 self.write(")");
26701 Ok(())
26702 }
26703
26704 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
26705 self.write_keyword("ARRAY_ANY");
26707 self.write("(");
26708 self.generate_expression(&e.this)?;
26709 self.write(", ");
26710 self.generate_expression(&e.expression)?;
26711 self.write(")");
26712 Ok(())
26713 }
26714
26715 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
26716 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
26718 self.write("(");
26719 for (i, expr) in e.expressions.iter().enumerate() {
26720 if i > 0 {
26721 self.write(", ");
26722 }
26723 self.generate_expression(expr)?;
26724 }
26725 self.write(")");
26726 Ok(())
26727 }
26728
26729 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
26730 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
26732 self.write("arraySum");
26733 } else {
26734 self.write_keyword("ARRAY_SUM");
26735 }
26736 self.write("(");
26737 self.generate_expression(&e.this)?;
26738 if let Some(expression) = &e.expression {
26739 self.write(", ");
26740 self.generate_expression(expression)?;
26741 }
26742 self.write(")");
26743 Ok(())
26744 }
26745
26746 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
26747 self.generate_expression(&e.this)?;
26749 self.write_space();
26750 self.write_keyword("AT");
26751 self.write_space();
26752 self.generate_expression(&e.expression)?;
26753 Ok(())
26754 }
26755
26756 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
26757 self.write_keyword("ATTACH");
26759 if e.exists {
26760 self.write_space();
26761 self.write_keyword("IF NOT EXISTS");
26762 }
26763 self.write_space();
26764 self.generate_expression(&e.this)?;
26765 if !e.expressions.is_empty() {
26766 self.write(" (");
26767 for (i, expr) in e.expressions.iter().enumerate() {
26768 if i > 0 {
26769 self.write(", ");
26770 }
26771 self.generate_expression(expr)?;
26772 }
26773 self.write(")");
26774 }
26775 Ok(())
26776 }
26777
26778 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
26779 self.generate_expression(&e.this)?;
26782 if let Some(expression) = &e.expression {
26783 self.write_space();
26784 self.generate_expression(expression)?;
26785 }
26786 Ok(())
26787 }
26788
26789 fn generate_auto_increment_keyword(
26793 &mut self,
26794 col: &crate::expressions::ColumnDef,
26795 ) -> Result<()> {
26796 use crate::dialects::DialectType;
26797 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
26798 self.write_keyword("IDENTITY");
26799 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26800 self.write("(");
26801 if let Some(ref start) = col.auto_increment_start {
26802 self.generate_expression(start)?;
26803 } else {
26804 self.write("0");
26805 }
26806 self.write(", ");
26807 if let Some(ref inc) = col.auto_increment_increment {
26808 self.generate_expression(inc)?;
26809 } else {
26810 self.write("1");
26811 }
26812 self.write(")");
26813 }
26814 } else if matches!(
26815 self.config.dialect,
26816 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
26817 ) {
26818 self.write_keyword("AUTOINCREMENT");
26819 if let Some(ref start) = col.auto_increment_start {
26820 self.write_space();
26821 self.write_keyword("START");
26822 self.write_space();
26823 self.generate_expression(start)?;
26824 }
26825 if let Some(ref inc) = col.auto_increment_increment {
26826 self.write_space();
26827 self.write_keyword("INCREMENT");
26828 self.write_space();
26829 self.generate_expression(inc)?;
26830 }
26831 if let Some(order) = col.auto_increment_order {
26832 self.write_space();
26833 if order {
26834 self.write_keyword("ORDER");
26835 } else {
26836 self.write_keyword("NOORDER");
26837 }
26838 }
26839 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
26840 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
26841 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26842 self.write(" (");
26843 let mut first = true;
26844 if let Some(ref start) = col.auto_increment_start {
26845 self.write_keyword("START WITH");
26846 self.write_space();
26847 self.generate_expression(start)?;
26848 first = false;
26849 }
26850 if let Some(ref inc) = col.auto_increment_increment {
26851 if !first {
26852 self.write_space();
26853 }
26854 self.write_keyword("INCREMENT BY");
26855 self.write_space();
26856 self.generate_expression(inc)?;
26857 }
26858 self.write(")");
26859 }
26860 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
26861 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26864 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
26865 } else {
26866 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
26867 }
26868 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26869 self.write(" (");
26870 let mut first = true;
26871 if let Some(ref start) = col.auto_increment_start {
26872 self.write_keyword("START WITH");
26873 self.write_space();
26874 self.generate_expression(start)?;
26875 first = false;
26876 }
26877 if let Some(ref inc) = col.auto_increment_increment {
26878 if !first {
26879 self.write_space();
26880 }
26881 self.write_keyword("INCREMENT BY");
26882 self.write_space();
26883 self.generate_expression(inc)?;
26884 }
26885 self.write(")");
26886 }
26887 } else if matches!(
26888 self.config.dialect,
26889 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26890 ) {
26891 self.write_keyword("IDENTITY");
26892 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26893 self.write("(");
26894 if let Some(ref start) = col.auto_increment_start {
26895 self.generate_expression(start)?;
26896 } else {
26897 self.write("0");
26898 }
26899 self.write(", ");
26900 if let Some(ref inc) = col.auto_increment_increment {
26901 self.generate_expression(inc)?;
26902 } else {
26903 self.write("1");
26904 }
26905 self.write(")");
26906 }
26907 } else {
26908 self.write_keyword("AUTO_INCREMENT");
26909 if let Some(ref start) = col.auto_increment_start {
26910 self.write_space();
26911 self.write_keyword("START");
26912 self.write_space();
26913 self.generate_expression(start)?;
26914 }
26915 if let Some(ref inc) = col.auto_increment_increment {
26916 self.write_space();
26917 self.write_keyword("INCREMENT");
26918 self.write_space();
26919 self.generate_expression(inc)?;
26920 }
26921 if let Some(order) = col.auto_increment_order {
26922 self.write_space();
26923 if order {
26924 self.write_keyword("ORDER");
26925 } else {
26926 self.write_keyword("NOORDER");
26927 }
26928 }
26929 }
26930 Ok(())
26931 }
26932
26933 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
26934 self.write_keyword("AUTO_INCREMENT");
26936 self.write("=");
26937 self.generate_expression(&e.this)?;
26938 Ok(())
26939 }
26940
26941 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
26942 self.write_keyword("AUTO_REFRESH");
26944 self.write("=");
26945 self.generate_expression(&e.this)?;
26946 Ok(())
26947 }
26948
26949 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
26950 self.write_keyword("BACKUP");
26952 self.write_space();
26953 self.generate_expression(&e.this)?;
26954 Ok(())
26955 }
26956
26957 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
26958 self.write_keyword("BASE64_DECODE_BINARY");
26960 self.write("(");
26961 self.generate_expression(&e.this)?;
26962 if let Some(alphabet) = &e.alphabet {
26963 self.write(", ");
26964 self.generate_expression(alphabet)?;
26965 }
26966 self.write(")");
26967 Ok(())
26968 }
26969
26970 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
26971 self.write_keyword("BASE64_DECODE_STRING");
26973 self.write("(");
26974 self.generate_expression(&e.this)?;
26975 if let Some(alphabet) = &e.alphabet {
26976 self.write(", ");
26977 self.generate_expression(alphabet)?;
26978 }
26979 self.write(")");
26980 Ok(())
26981 }
26982
26983 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
26984 self.write_keyword("BASE64_ENCODE");
26986 self.write("(");
26987 self.generate_expression(&e.this)?;
26988 if let Some(max_line_length) = &e.max_line_length {
26989 self.write(", ");
26990 self.generate_expression(max_line_length)?;
26991 }
26992 if let Some(alphabet) = &e.alphabet {
26993 self.write(", ");
26994 self.generate_expression(alphabet)?;
26995 }
26996 self.write(")");
26997 Ok(())
26998 }
26999
27000 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
27001 self.write_keyword("BLOCKCOMPRESSION");
27003 self.write("=");
27004 if let Some(autotemp) = &e.autotemp {
27005 self.write_keyword("AUTOTEMP");
27006 self.write("(");
27007 self.generate_expression(autotemp)?;
27008 self.write(")");
27009 }
27010 if let Some(always) = &e.always {
27011 self.generate_expression(always)?;
27012 }
27013 if let Some(default) = &e.default {
27014 self.generate_expression(default)?;
27015 }
27016 if let Some(manual) = &e.manual {
27017 self.generate_expression(manual)?;
27018 }
27019 if let Some(never) = &e.never {
27020 self.generate_expression(never)?;
27021 }
27022 Ok(())
27023 }
27024
27025 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
27026 self.write("((");
27028 self.generate_expression(&e.this)?;
27029 self.write(") ");
27030 self.write_keyword("AND");
27031 self.write(" (");
27032 self.generate_expression(&e.expression)?;
27033 self.write("))");
27034 Ok(())
27035 }
27036
27037 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
27038 self.write("((");
27040 self.generate_expression(&e.this)?;
27041 self.write(") ");
27042 self.write_keyword("OR");
27043 self.write(" (");
27044 self.generate_expression(&e.expression)?;
27045 self.write("))");
27046 Ok(())
27047 }
27048
27049 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
27050 self.write_keyword("BUILD");
27052 self.write_space();
27053 self.generate_expression(&e.this)?;
27054 Ok(())
27055 }
27056
27057 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
27058 self.generate_expression(&e.this)?;
27060 Ok(())
27061 }
27062
27063 fn generate_case_specific_column_constraint(
27064 &mut self,
27065 e: &CaseSpecificColumnConstraint,
27066 ) -> Result<()> {
27067 if e.not_.is_some() {
27069 self.write_keyword("NOT");
27070 self.write_space();
27071 }
27072 self.write_keyword("CASESPECIFIC");
27073 Ok(())
27074 }
27075
27076 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
27077 self.write_keyword("CAST");
27079 self.write("(");
27080 self.generate_expression(&e.this)?;
27081 if self.config.dialect == Some(DialectType::ClickHouse) {
27082 self.write(", ");
27084 } else {
27085 self.write_space();
27086 self.write_keyword("AS");
27087 self.write_space();
27088 }
27089 if let Some(to) = &e.to {
27090 self.generate_expression(to)?;
27091 }
27092 self.write(")");
27093 Ok(())
27094 }
27095
27096 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
27097 self.write_keyword("CHANGES");
27100 self.write(" (");
27101 if let Some(information) = &e.information {
27102 self.write_keyword("INFORMATION");
27103 self.write(" => ");
27104 self.generate_expression(information)?;
27105 }
27106 self.write(")");
27107 if let Some(at_before) = &e.at_before {
27109 self.write(" ");
27110 self.generate_expression(at_before)?;
27111 }
27112 if let Some(end) = &e.end {
27113 self.write(" ");
27114 self.generate_expression(end)?;
27115 }
27116 Ok(())
27117 }
27118
27119 fn generate_character_set_column_constraint(
27120 &mut self,
27121 e: &CharacterSetColumnConstraint,
27122 ) -> Result<()> {
27123 self.write_keyword("CHARACTER SET");
27125 self.write_space();
27126 self.generate_expression(&e.this)?;
27127 Ok(())
27128 }
27129
27130 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
27131 if e.default.is_some() {
27133 self.write_keyword("DEFAULT");
27134 self.write_space();
27135 }
27136 self.write_keyword("CHARACTER SET");
27137 self.write("=");
27138 self.generate_expression(&e.this)?;
27139 Ok(())
27140 }
27141
27142 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
27143 self.write_keyword("CHECK");
27145 self.write(" (");
27146 self.generate_expression(&e.this)?;
27147 self.write(")");
27148 if e.enforced.is_some() {
27149 self.write_space();
27150 self.write_keyword("ENFORCED");
27151 }
27152 Ok(())
27153 }
27154
27155 fn generate_assume_column_constraint(&mut self, e: &AssumeColumnConstraint) -> Result<()> {
27156 self.write_keyword("ASSUME");
27158 self.write(" (");
27159 self.generate_expression(&e.this)?;
27160 self.write(")");
27161 Ok(())
27162 }
27163
27164 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
27165 self.write_keyword("CHECK_JSON");
27167 self.write("(");
27168 self.generate_expression(&e.this)?;
27169 self.write(")");
27170 Ok(())
27171 }
27172
27173 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
27174 self.write_keyword("CHECK_XML");
27176 self.write("(");
27177 self.generate_expression(&e.this)?;
27178 self.write(")");
27179 Ok(())
27180 }
27181
27182 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
27183 self.write_keyword("CHECKSUM");
27185 self.write("=");
27186 if e.on.is_some() {
27187 self.write_keyword("ON");
27188 } else if e.default.is_some() {
27189 self.write_keyword("DEFAULT");
27190 } else {
27191 self.write_keyword("OFF");
27192 }
27193 Ok(())
27194 }
27195
27196 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
27197 if e.shallow.is_some() {
27199 self.write_keyword("SHALLOW");
27200 self.write_space();
27201 }
27202 if e.copy.is_some() {
27203 self.write_keyword("COPY");
27204 } else {
27205 self.write_keyword("CLONE");
27206 }
27207 self.write_space();
27208 self.generate_expression(&e.this)?;
27209 Ok(())
27210 }
27211
27212 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
27213 self.write_keyword("CLUSTER BY");
27215 self.write(" (");
27216 for (i, ord) in e.expressions.iter().enumerate() {
27217 if i > 0 {
27218 self.write(", ");
27219 }
27220 self.generate_ordered(ord)?;
27221 }
27222 self.write(")");
27223 Ok(())
27224 }
27225
27226 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
27227 self.write_keyword("CLUSTER BY");
27229 self.write_space();
27230 for (i, col) in e.columns.iter().enumerate() {
27231 if i > 0 {
27232 self.write(", ");
27233 }
27234 self.generate_identifier(col)?;
27235 }
27236 Ok(())
27237 }
27238
27239 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
27240 self.write_keyword("CLUSTERED BY");
27242 self.write(" (");
27243 for (i, expr) in e.expressions.iter().enumerate() {
27244 if i > 0 {
27245 self.write(", ");
27246 }
27247 self.generate_expression(expr)?;
27248 }
27249 self.write(")");
27250 if let Some(sorted_by) = &e.sorted_by {
27251 self.write_space();
27252 self.write_keyword("SORTED BY");
27253 self.write(" (");
27254 if let Expression::Tuple(t) = sorted_by.as_ref() {
27256 for (i, expr) in t.expressions.iter().enumerate() {
27257 if i > 0 {
27258 self.write(", ");
27259 }
27260 self.generate_expression(expr)?;
27261 }
27262 } else {
27263 self.generate_expression(sorted_by)?;
27264 }
27265 self.write(")");
27266 }
27267 if let Some(buckets) = &e.buckets {
27268 self.write_space();
27269 self.write_keyword("INTO");
27270 self.write_space();
27271 self.generate_expression(buckets)?;
27272 self.write_space();
27273 self.write_keyword("BUCKETS");
27274 }
27275 Ok(())
27276 }
27277
27278 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
27279 if e.default.is_some() {
27283 self.write_keyword("DEFAULT");
27284 self.write_space();
27285 }
27286 self.write_keyword("COLLATE");
27287 match self.config.dialect {
27289 Some(DialectType::BigQuery) => self.write_space(),
27290 _ => self.write("="),
27291 }
27292 self.generate_expression(&e.this)?;
27293 Ok(())
27294 }
27295
27296 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
27297 match e {
27299 ColumnConstraint::NotNull => {
27300 self.write_keyword("NOT NULL");
27301 }
27302 ColumnConstraint::Null => {
27303 self.write_keyword("NULL");
27304 }
27305 ColumnConstraint::Unique => {
27306 self.write_keyword("UNIQUE");
27307 }
27308 ColumnConstraint::PrimaryKey => {
27309 self.write_keyword("PRIMARY KEY");
27310 }
27311 ColumnConstraint::Default(expr) => {
27312 self.write_keyword("DEFAULT");
27313 self.write_space();
27314 self.generate_expression(expr)?;
27315 }
27316 ColumnConstraint::Check(expr) => {
27317 self.write_keyword("CHECK");
27318 self.write(" (");
27319 self.generate_expression(expr)?;
27320 self.write(")");
27321 }
27322 ColumnConstraint::References(fk_ref) => {
27323 if fk_ref.has_foreign_key_keywords {
27324 self.write_keyword("FOREIGN KEY");
27325 self.write_space();
27326 }
27327 self.write_keyword("REFERENCES");
27328 self.write_space();
27329 self.generate_table(&fk_ref.table)?;
27330 if !fk_ref.columns.is_empty() {
27331 self.write(" (");
27332 for (i, col) in fk_ref.columns.iter().enumerate() {
27333 if i > 0 {
27334 self.write(", ");
27335 }
27336 self.generate_identifier(col)?;
27337 }
27338 self.write(")");
27339 }
27340 }
27341 ColumnConstraint::GeneratedAsIdentity(gen) => {
27342 self.write_keyword("GENERATED");
27343 self.write_space();
27344 if gen.always {
27345 self.write_keyword("ALWAYS");
27346 } else {
27347 self.write_keyword("BY DEFAULT");
27348 if gen.on_null {
27349 self.write_space();
27350 self.write_keyword("ON NULL");
27351 }
27352 }
27353 self.write_space();
27354 self.write_keyword("AS IDENTITY");
27355 }
27356 ColumnConstraint::Collate(collation) => {
27357 self.write_keyword("COLLATE");
27358 self.write_space();
27359 self.generate_identifier(collation)?;
27360 }
27361 ColumnConstraint::Comment(comment) => {
27362 self.write_keyword("COMMENT");
27363 self.write(" '");
27364 self.write(comment);
27365 self.write("'");
27366 }
27367 ColumnConstraint::ComputedColumn(cc) => {
27368 self.generate_computed_column_inline(cc)?;
27369 }
27370 ColumnConstraint::GeneratedAsRow(gar) => {
27371 self.generate_generated_as_row_inline(gar)?;
27372 }
27373 ColumnConstraint::Tags(tags) => {
27374 self.write_keyword("TAG");
27375 self.write(" (");
27376 for (i, expr) in tags.expressions.iter().enumerate() {
27377 if i > 0 {
27378 self.write(", ");
27379 }
27380 self.generate_expression(expr)?;
27381 }
27382 self.write(")");
27383 }
27384 ColumnConstraint::Path(path_expr) => {
27385 self.write_keyword("PATH");
27386 self.write_space();
27387 self.generate_expression(path_expr)?;
27388 }
27389 }
27390 Ok(())
27391 }
27392
27393 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
27394 match e {
27396 ColumnPosition::First => {
27397 self.write_keyword("FIRST");
27398 }
27399 ColumnPosition::After(ident) => {
27400 self.write_keyword("AFTER");
27401 self.write_space();
27402 self.generate_identifier(ident)?;
27403 }
27404 }
27405 Ok(())
27406 }
27407
27408 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
27409 self.generate_expression(&e.this)?;
27411 self.write("(");
27412 self.generate_expression(&e.expression)?;
27413 self.write(")");
27414 Ok(())
27415 }
27416
27417 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
27418 if let Some(ref unpack) = e.unpack {
27421 if let Expression::Boolean(b) = unpack.as_ref() {
27422 if b.value {
27423 self.write("*");
27424 }
27425 }
27426 }
27427 self.write_keyword("COLUMNS");
27428 self.write("(");
27429 self.generate_expression(&e.this)?;
27430 self.write(")");
27431 Ok(())
27432 }
27433
27434 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
27435 self.generate_expression(&e.this)?;
27437 self.write("(");
27438 for (i, expr) in e.expressions.iter().enumerate() {
27439 if i > 0 {
27440 self.write(", ");
27441 }
27442 self.generate_expression(expr)?;
27443 }
27444 self.write(")");
27445 Ok(())
27446 }
27447
27448 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
27449 self.generate_expression(&e.this)?;
27451 self.write("(");
27452 for (i, param) in e.params.iter().enumerate() {
27453 if i > 0 {
27454 self.write(", ");
27455 }
27456 self.generate_expression(param)?;
27457 }
27458 self.write(")(");
27459 for (i, expr) in e.expressions.iter().enumerate() {
27460 if i > 0 {
27461 self.write(", ");
27462 }
27463 self.generate_expression(expr)?;
27464 }
27465 self.write(")");
27466 Ok(())
27467 }
27468
27469 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
27470 self.write_keyword("COMMIT");
27472
27473 if e.this.is_none()
27475 && matches!(
27476 self.config.dialect,
27477 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27478 )
27479 {
27480 self.write_space();
27481 self.write_keyword("TRANSACTION");
27482 }
27483
27484 if let Some(this) = &e.this {
27486 let is_transaction_marker = matches!(
27488 this.as_ref(),
27489 Expression::Identifier(id) if id.name == "TRANSACTION"
27490 );
27491
27492 self.write_space();
27493 self.write_keyword("TRANSACTION");
27494
27495 if !is_transaction_marker {
27497 self.write_space();
27498 self.generate_expression(this)?;
27499 }
27500 }
27501
27502 if let Some(durability) = &e.durability {
27504 self.write_space();
27505 self.write_keyword("WITH");
27506 self.write(" (");
27507 self.write_keyword("DELAYED_DURABILITY");
27508 self.write(" = ");
27509 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
27510 self.write_keyword("ON");
27511 } else {
27512 self.write_keyword("OFF");
27513 }
27514 self.write(")");
27515 }
27516
27517 if let Some(chain) = &e.chain {
27519 self.write_space();
27520 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
27521 self.write_keyword("AND NO CHAIN");
27522 } else {
27523 self.write_keyword("AND CHAIN");
27524 }
27525 }
27526 Ok(())
27527 }
27528
27529 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
27530 self.write("[");
27532 self.generate_expression(&e.this)?;
27533 self.write_space();
27534 self.write_keyword("FOR");
27535 self.write_space();
27536 self.generate_expression(&e.expression)?;
27537 if let Some(pos) = &e.position {
27539 self.write(", ");
27540 self.generate_expression(pos)?;
27541 }
27542 if let Some(iterator) = &e.iterator {
27543 self.write_space();
27544 self.write_keyword("IN");
27545 self.write_space();
27546 self.generate_expression(iterator)?;
27547 }
27548 if let Some(condition) = &e.condition {
27549 self.write_space();
27550 self.write_keyword("IF");
27551 self.write_space();
27552 self.generate_expression(condition)?;
27553 }
27554 self.write("]");
27555 Ok(())
27556 }
27557
27558 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
27559 self.write_keyword("COMPRESS");
27561 self.write("(");
27562 self.generate_expression(&e.this)?;
27563 if let Some(method) = &e.method {
27564 self.write(", '");
27565 self.write(method);
27566 self.write("'");
27567 }
27568 self.write(")");
27569 Ok(())
27570 }
27571
27572 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
27573 self.write_keyword("COMPRESS");
27575 if let Some(this) = &e.this {
27576 self.write_space();
27577 self.generate_expression(this)?;
27578 }
27579 Ok(())
27580 }
27581
27582 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
27583 self.write_keyword("AS");
27585 self.write_space();
27586 self.generate_expression(&e.this)?;
27587 if e.not_null.is_some() {
27588 self.write_space();
27589 self.write_keyword("PERSISTED NOT NULL");
27590 } else if e.persisted.is_some() {
27591 self.write_space();
27592 self.write_keyword("PERSISTED");
27593 }
27594 Ok(())
27595 }
27596
27597 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
27601 let computed_expr = if matches!(
27602 self.config.dialect,
27603 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27604 ) {
27605 match &*cc.expression {
27606 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
27607 {
27608 let wrapped = Expression::Cast(Box::new(Cast {
27609 this: y.this.clone(),
27610 to: DataType::Date,
27611 trailing_comments: Vec::new(),
27612 double_colon_syntax: false,
27613 format: None,
27614 default: None,
27615 inferred_type: None,
27616 }));
27617 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
27618 }
27619 Expression::Function(f)
27620 if f.name.eq_ignore_ascii_case("YEAR")
27621 && f.args.len() == 1
27622 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
27623 {
27624 let wrapped = Expression::Cast(Box::new(Cast {
27625 this: f.args[0].clone(),
27626 to: DataType::Date,
27627 trailing_comments: Vec::new(),
27628 double_colon_syntax: false,
27629 format: None,
27630 default: None,
27631 inferred_type: None,
27632 }));
27633 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
27634 }
27635 _ => *cc.expression.clone(),
27636 }
27637 } else {
27638 *cc.expression.clone()
27639 };
27640
27641 match cc.persistence_kind.as_deref() {
27642 Some("STORED") | Some("VIRTUAL") => {
27643 self.write_keyword("GENERATED ALWAYS AS");
27645 self.write(" (");
27646 self.generate_expression(&computed_expr)?;
27647 self.write(")");
27648 self.write_space();
27649 if cc.persisted {
27650 self.write_keyword("STORED");
27651 } else {
27652 self.write_keyword("VIRTUAL");
27653 }
27654 }
27655 Some("PERSISTED") => {
27656 self.write_keyword("AS");
27658 self.write(" (");
27659 self.generate_expression(&computed_expr)?;
27660 self.write(")");
27661 self.write_space();
27662 self.write_keyword("PERSISTED");
27663 if let Some(ref dt) = cc.data_type {
27665 self.write_space();
27666 self.generate_data_type(dt)?;
27667 }
27668 if cc.not_null {
27669 self.write_space();
27670 self.write_keyword("NOT NULL");
27671 }
27672 }
27673 _ => {
27674 if matches!(
27677 self.config.dialect,
27678 Some(DialectType::Spark)
27679 | Some(DialectType::Databricks)
27680 | Some(DialectType::Hive)
27681 ) {
27682 self.write_keyword("GENERATED ALWAYS AS");
27683 self.write(" (");
27684 self.generate_expression(&computed_expr)?;
27685 self.write(")");
27686 } else if matches!(
27687 self.config.dialect,
27688 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27689 ) {
27690 self.write_keyword("AS");
27691 let omit_parens = matches!(computed_expr, Expression::Year(_))
27692 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
27693 if omit_parens {
27694 self.write_space();
27695 self.generate_expression(&computed_expr)?;
27696 } else {
27697 self.write(" (");
27698 self.generate_expression(&computed_expr)?;
27699 self.write(")");
27700 }
27701 } else {
27702 self.write_keyword("AS");
27703 self.write(" (");
27704 self.generate_expression(&computed_expr)?;
27705 self.write(")");
27706 }
27707 }
27708 }
27709 Ok(())
27710 }
27711
27712 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
27715 self.write_keyword("GENERATED ALWAYS AS ROW ");
27716 if gar.start {
27717 self.write_keyword("START");
27718 } else {
27719 self.write_keyword("END");
27720 }
27721 if gar.hidden {
27722 self.write_space();
27723 self.write_keyword("HIDDEN");
27724 }
27725 Ok(())
27726 }
27727
27728 fn generate_system_versioning_content(
27730 &mut self,
27731 e: &WithSystemVersioningProperty,
27732 ) -> Result<()> {
27733 let mut parts = Vec::new();
27734
27735 if let Some(this) = &e.this {
27736 let mut s = String::from("HISTORY_TABLE=");
27737 let mut gen = Generator::with_arc_config(self.config.clone());
27738 gen.generate_expression(this)?;
27739 s.push_str(&gen.output);
27740 parts.push(s);
27741 }
27742
27743 if let Some(data_consistency) = &e.data_consistency {
27744 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
27745 let mut gen = Generator::with_arc_config(self.config.clone());
27746 gen.generate_expression(data_consistency)?;
27747 s.push_str(&gen.output);
27748 parts.push(s);
27749 }
27750
27751 if let Some(retention_period) = &e.retention_period {
27752 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
27753 let mut gen = Generator::with_arc_config(self.config.clone());
27754 gen.generate_expression(retention_period)?;
27755 s.push_str(&gen.output);
27756 parts.push(s);
27757 }
27758
27759 self.write_keyword("SYSTEM_VERSIONING");
27760 self.write("=");
27761
27762 if !parts.is_empty() {
27763 self.write_keyword("ON");
27764 self.write("(");
27765 self.write(&parts.join(", "));
27766 self.write(")");
27767 } else if e.on.is_some() {
27768 self.write_keyword("ON");
27769 } else {
27770 self.write_keyword("OFF");
27771 }
27772
27773 Ok(())
27774 }
27775
27776 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
27777 if e.else_.is_some() {
27780 self.write_keyword("ELSE");
27781 self.write_space();
27782 } else if let Some(expression) = &e.expression {
27783 self.write_keyword("WHEN");
27784 self.write_space();
27785 self.generate_expression(expression)?;
27786 self.write_space();
27787 self.write_keyword("THEN");
27788 self.write_space();
27789 }
27790
27791 if let Expression::Insert(insert) = e.this.as_ref() {
27794 self.write_keyword("INTO");
27795 self.write_space();
27796 self.generate_table(&insert.table)?;
27797
27798 if !insert.columns.is_empty() {
27800 self.write(" (");
27801 for (i, col) in insert.columns.iter().enumerate() {
27802 if i > 0 {
27803 self.write(", ");
27804 }
27805 self.generate_identifier(col)?;
27806 }
27807 self.write(")");
27808 }
27809
27810 if !insert.values.is_empty() {
27812 self.write_space();
27813 self.write_keyword("VALUES");
27814 for (row_idx, row) in insert.values.iter().enumerate() {
27815 if row_idx > 0 {
27816 self.write(", ");
27817 }
27818 self.write(" (");
27819 for (i, val) in row.iter().enumerate() {
27820 if i > 0 {
27821 self.write(", ");
27822 }
27823 self.generate_expression(val)?;
27824 }
27825 self.write(")");
27826 }
27827 }
27828 } else {
27829 self.generate_expression(&e.this)?;
27831 }
27832 Ok(())
27833 }
27834
27835 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
27836 self.write_keyword("CONSTRAINT");
27838 self.write_space();
27839 self.generate_expression(&e.this)?;
27840 if !e.expressions.is_empty() {
27841 self.write_space();
27842 for (i, expr) in e.expressions.iter().enumerate() {
27843 if i > 0 {
27844 self.write_space();
27845 }
27846 self.generate_expression(expr)?;
27847 }
27848 }
27849 Ok(())
27850 }
27851
27852 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
27853 self.write_keyword("CONVERT_TIMEZONE");
27855 self.write("(");
27856 let mut first = true;
27857 if let Some(source_tz) = &e.source_tz {
27858 self.generate_expression(source_tz)?;
27859 first = false;
27860 }
27861 if let Some(target_tz) = &e.target_tz {
27862 if !first {
27863 self.write(", ");
27864 }
27865 self.generate_expression(target_tz)?;
27866 first = false;
27867 }
27868 if let Some(timestamp) = &e.timestamp {
27869 if !first {
27870 self.write(", ");
27871 }
27872 self.generate_expression(timestamp)?;
27873 }
27874 self.write(")");
27875 Ok(())
27876 }
27877
27878 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
27879 self.write_keyword("CONVERT");
27881 self.write("(");
27882 self.generate_expression(&e.this)?;
27883 if let Some(dest) = &e.dest {
27884 self.write_space();
27885 self.write_keyword("USING");
27886 self.write_space();
27887 self.generate_expression(dest)?;
27888 }
27889 self.write(")");
27890 Ok(())
27891 }
27892
27893 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
27894 self.write_keyword("COPY");
27895 if e.is_into {
27896 self.write_space();
27897 self.write_keyword("INTO");
27898 }
27899 self.write_space();
27900
27901 if let Expression::Literal(lit) = &e.this {
27903 if let Literal::String(s) = lit.as_ref() {
27904 if s.starts_with('@') {
27905 self.write(s);
27906 } else {
27907 self.generate_expression(&e.this)?;
27908 }
27909 }
27910 } else {
27911 self.generate_expression(&e.this)?;
27912 }
27913
27914 if e.kind {
27916 if self.config.pretty {
27918 self.write_newline();
27919 } else {
27920 self.write_space();
27921 }
27922 self.write_keyword("FROM");
27923 self.write_space();
27924 } else if !e.files.is_empty() {
27925 if self.config.pretty {
27927 self.write_newline();
27928 } else {
27929 self.write_space();
27930 }
27931 self.write_keyword("TO");
27932 self.write_space();
27933 }
27934
27935 for (i, file) in e.files.iter().enumerate() {
27937 if i > 0 {
27938 self.write_space();
27939 }
27940 if let Expression::Literal(lit) = file {
27942 if let Literal::String(s) = lit.as_ref() {
27943 if s.starts_with('@') {
27944 self.write(s);
27945 } else {
27946 self.generate_expression(file)?;
27947 }
27948 }
27949 } else if let Expression::Identifier(id) = file {
27950 if id.quoted {
27952 self.write("`");
27953 self.write(&id.name);
27954 self.write("`");
27955 } else {
27956 self.generate_expression(file)?;
27957 }
27958 } else {
27959 self.generate_expression(file)?;
27960 }
27961 }
27962
27963 if !e.with_wrapped {
27965 if let Some(ref creds) = e.credentials {
27966 if let Some(ref storage) = creds.storage {
27967 if self.config.pretty {
27968 self.write_newline();
27969 } else {
27970 self.write_space();
27971 }
27972 self.write_keyword("STORAGE_INTEGRATION");
27973 self.write(" = ");
27974 self.write(storage);
27975 }
27976 if creds.credentials.is_empty() {
27977 if self.config.pretty {
27979 self.write_newline();
27980 } else {
27981 self.write_space();
27982 }
27983 self.write_keyword("CREDENTIALS");
27984 self.write(" = ()");
27985 } else {
27986 if self.config.pretty {
27987 self.write_newline();
27988 } else {
27989 self.write_space();
27990 }
27991 self.write_keyword("CREDENTIALS");
27992 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
27995 self.write(" '");
27997 self.write(&creds.credentials[0].1);
27998 self.write("'");
27999 } else {
28000 self.write(" = (");
28002 for (i, (k, v)) in creds.credentials.iter().enumerate() {
28003 if i > 0 {
28004 self.write_space();
28005 }
28006 self.write(k);
28007 self.write("='");
28008 self.write(v);
28009 self.write("'");
28010 }
28011 self.write(")");
28012 }
28013 }
28014 if let Some(ref encryption) = creds.encryption {
28015 self.write_space();
28016 self.write_keyword("ENCRYPTION");
28017 self.write(" = ");
28018 self.write(encryption);
28019 }
28020 }
28021 }
28022
28023 if !e.params.is_empty() {
28025 if e.with_wrapped {
28026 self.write_space();
28028 self.write_keyword("WITH");
28029 self.write(" (");
28030 for (i, param) in e.params.iter().enumerate() {
28031 if i > 0 {
28032 self.write(", ");
28033 }
28034 self.generate_copy_param_with_format(param)?;
28035 }
28036 self.write(")");
28037 } else {
28038 for param in &e.params {
28042 if self.config.pretty {
28043 self.write_newline();
28044 } else {
28045 self.write_space();
28046 }
28047 self.write(¶m.name);
28049 if let Some(ref value) = param.value {
28050 if param.eq {
28052 self.write(" = ");
28053 } else {
28054 self.write(" ");
28055 }
28056 if !param.values.is_empty() {
28057 self.write("(");
28058 for (i, v) in param.values.iter().enumerate() {
28059 if i > 0 {
28060 self.write_space();
28061 }
28062 self.generate_copy_nested_param(v)?;
28063 }
28064 self.write(")");
28065 } else {
28066 self.generate_copy_param_value(value)?;
28068 }
28069 } else if !param.values.is_empty() {
28070 if param.eq {
28072 self.write(" = (");
28073 } else {
28074 self.write(" (");
28075 }
28076 let is_key_value_pairs = param
28081 .values
28082 .first()
28083 .map_or(false, |v| matches!(v, Expression::Eq(_)));
28084 let sep = if is_key_value_pairs && param.eq {
28085 " "
28086 } else {
28087 ", "
28088 };
28089 for (i, v) in param.values.iter().enumerate() {
28090 if i > 0 {
28091 self.write(sep);
28092 }
28093 self.generate_copy_nested_param(v)?;
28094 }
28095 self.write(")");
28096 }
28097 }
28098 }
28099 }
28100
28101 Ok(())
28102 }
28103
28104 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
28107 self.write_keyword(¶m.name);
28108 if !param.values.is_empty() {
28109 self.write(" = (");
28111 for (i, v) in param.values.iter().enumerate() {
28112 if i > 0 {
28113 self.write(", ");
28114 }
28115 self.generate_copy_nested_param(v)?;
28116 }
28117 self.write(")");
28118 } else if let Some(ref value) = param.value {
28119 if param.eq {
28120 self.write(" = ");
28121 } else {
28122 self.write(" ");
28123 }
28124 self.generate_expression(value)?;
28125 }
28126 Ok(())
28127 }
28128
28129 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
28131 match expr {
28132 Expression::Eq(eq) => {
28133 match &eq.left {
28135 Expression::Column(c) => self.write(&c.name.name),
28136 _ => self.generate_expression(&eq.left)?,
28137 }
28138 self.write("=");
28139 match &eq.right {
28141 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
28142 let Literal::String(s) = lit.as_ref() else {
28143 unreachable!()
28144 };
28145 self.write("'");
28146 self.write(s);
28147 self.write("'");
28148 }
28149 Expression::Tuple(t) => {
28150 self.write("(");
28152 if self.config.pretty {
28153 self.write_newline();
28154 self.indent_level += 1;
28155 for (i, item) in t.expressions.iter().enumerate() {
28156 if i > 0 {
28157 self.write(", ");
28158 }
28159 self.write_indent();
28160 self.generate_expression(item)?;
28161 }
28162 self.write_newline();
28163 self.indent_level -= 1;
28164 } else {
28165 for (i, item) in t.expressions.iter().enumerate() {
28166 if i > 0 {
28167 self.write(", ");
28168 }
28169 self.generate_expression(item)?;
28170 }
28171 }
28172 self.write(")");
28173 }
28174 _ => self.generate_expression(&eq.right)?,
28175 }
28176 Ok(())
28177 }
28178 Expression::Column(c) => {
28179 self.write(&c.name.name);
28181 Ok(())
28182 }
28183 _ => self.generate_expression(expr),
28184 }
28185 }
28186
28187 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
28190 match expr {
28191 Expression::Column(c) => {
28192 if c.name.quoted {
28194 self.write("\"");
28195 self.write(&c.name.name);
28196 self.write("\"");
28197 } else {
28198 self.write(&c.name.name);
28199 }
28200 Ok(())
28201 }
28202 Expression::Identifier(id) => {
28203 if id.quoted {
28205 self.write("\"");
28206 self.write(&id.name);
28207 self.write("\"");
28208 } else {
28209 self.write(&id.name);
28210 }
28211 Ok(())
28212 }
28213 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
28214 let Literal::String(s) = lit.as_ref() else {
28215 unreachable!()
28216 };
28217 self.write("'");
28219 self.write(s);
28220 self.write("'");
28221 Ok(())
28222 }
28223 _ => self.generate_expression(expr),
28224 }
28225 }
28226
28227 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
28228 self.write_keyword(&e.name);
28229 if let Some(ref value) = e.value {
28230 if e.eq {
28231 self.write(" = ");
28232 } else {
28233 self.write(" ");
28234 }
28235 self.generate_expression(value)?;
28236 }
28237 if !e.values.is_empty() {
28238 if e.eq {
28239 self.write(" = ");
28240 } else {
28241 self.write(" ");
28242 }
28243 self.write("(");
28244 for (i, v) in e.values.iter().enumerate() {
28245 if i > 0 {
28246 self.write(", ");
28247 }
28248 self.generate_expression(v)?;
28249 }
28250 self.write(")");
28251 }
28252 Ok(())
28253 }
28254
28255 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
28256 self.write_keyword("CORR");
28258 self.write("(");
28259 self.generate_expression(&e.this)?;
28260 self.write(", ");
28261 self.generate_expression(&e.expression)?;
28262 self.write(")");
28263 Ok(())
28264 }
28265
28266 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
28267 self.write_keyword("COSINE_DISTANCE");
28269 self.write("(");
28270 self.generate_expression(&e.this)?;
28271 self.write(", ");
28272 self.generate_expression(&e.expression)?;
28273 self.write(")");
28274 Ok(())
28275 }
28276
28277 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
28278 self.write_keyword("COVAR_POP");
28280 self.write("(");
28281 self.generate_expression(&e.this)?;
28282 self.write(", ");
28283 self.generate_expression(&e.expression)?;
28284 self.write(")");
28285 Ok(())
28286 }
28287
28288 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
28289 self.write_keyword("COVAR_SAMP");
28291 self.write("(");
28292 self.generate_expression(&e.this)?;
28293 self.write(", ");
28294 self.generate_expression(&e.expression)?;
28295 self.write(")");
28296 Ok(())
28297 }
28298
28299 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
28300 self.write_keyword("CREDENTIALS");
28302 self.write(" (");
28303 for (i, (key, value)) in e.credentials.iter().enumerate() {
28304 if i > 0 {
28305 self.write(", ");
28306 }
28307 self.write(key);
28308 self.write("='");
28309 self.write(value);
28310 self.write("'");
28311 }
28312 self.write(")");
28313 Ok(())
28314 }
28315
28316 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
28317 self.write_keyword("CREDENTIALS");
28319 self.write("=(");
28320 for (i, expr) in e.expressions.iter().enumerate() {
28321 if i > 0 {
28322 self.write(", ");
28323 }
28324 self.generate_expression(expr)?;
28325 }
28326 self.write(")");
28327 Ok(())
28328 }
28329
28330 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
28331 use crate::dialects::DialectType;
28332
28333 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
28336 self.generate_expression(&e.this)?;
28337 self.write_space();
28338 self.write_keyword("AS");
28339 self.write_space();
28340 self.generate_identifier(&e.alias)?;
28341 return Ok(());
28342 }
28343 self.write(&e.alias.name);
28344
28345 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
28347
28348 if !e.columns.is_empty() && !skip_cte_columns {
28349 self.write("(");
28350 for (i, col) in e.columns.iter().enumerate() {
28351 if i > 0 {
28352 self.write(", ");
28353 }
28354 self.write(&col.name);
28355 }
28356 self.write(")");
28357 }
28358 if !e.key_expressions.is_empty() {
28360 self.write_space();
28361 self.write_keyword("USING KEY");
28362 self.write(" (");
28363 for (i, key) in e.key_expressions.iter().enumerate() {
28364 if i > 0 {
28365 self.write(", ");
28366 }
28367 self.write(&key.name);
28368 }
28369 self.write(")");
28370 }
28371 self.write_space();
28372 self.write_keyword("AS");
28373 self.write_space();
28374 if let Some(materialized) = e.materialized {
28375 if materialized {
28376 self.write_keyword("MATERIALIZED");
28377 } else {
28378 self.write_keyword("NOT MATERIALIZED");
28379 }
28380 self.write_space();
28381 }
28382 self.write("(");
28383 self.generate_expression(&e.this)?;
28384 self.write(")");
28385 Ok(())
28386 }
28387
28388 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
28389 if e.expressions.is_empty() {
28391 self.write_keyword("WITH CUBE");
28392 } else {
28393 self.write_keyword("CUBE");
28394 self.write("(");
28395 for (i, expr) in e.expressions.iter().enumerate() {
28396 if i > 0 {
28397 self.write(", ");
28398 }
28399 self.generate_expression(expr)?;
28400 }
28401 self.write(")");
28402 }
28403 Ok(())
28404 }
28405
28406 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
28407 self.write_keyword("CURRENT_DATETIME");
28409 if let Some(this) = &e.this {
28410 self.write("(");
28411 self.generate_expression(this)?;
28412 self.write(")");
28413 }
28414 Ok(())
28415 }
28416
28417 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
28418 self.write_keyword("CURRENT_SCHEMA");
28420 Ok(())
28421 }
28422
28423 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
28424 self.write_keyword("CURRENT_SCHEMAS");
28426 self.write("(");
28427 if !matches!(
28429 self.config.dialect,
28430 Some(crate::dialects::DialectType::Snowflake)
28431 ) {
28432 if let Some(this) = &e.this {
28433 self.generate_expression(this)?;
28434 }
28435 }
28436 self.write(")");
28437 Ok(())
28438 }
28439
28440 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
28441 self.write_keyword("CURRENT_USER");
28443 let needs_parens = e.this.is_some()
28445 || matches!(
28446 self.config.dialect,
28447 Some(DialectType::Snowflake)
28448 | Some(DialectType::Spark)
28449 | Some(DialectType::Hive)
28450 | Some(DialectType::DuckDB)
28451 | Some(DialectType::BigQuery)
28452 | Some(DialectType::MySQL)
28453 | Some(DialectType::Databricks)
28454 );
28455 if needs_parens {
28456 self.write("()");
28457 }
28458 Ok(())
28459 }
28460
28461 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
28462 if self.config.dialect == Some(DialectType::Solr) {
28464 self.generate_expression(&e.this)?;
28465 self.write(" ");
28466 self.write_keyword("OR");
28467 self.write(" ");
28468 self.generate_expression(&e.expression)?;
28469 } else if self.config.dialect == Some(DialectType::MySQL) {
28470 self.generate_mysql_concat_from_dpipe(e)?;
28471 } else {
28472 self.generate_expression(&e.this)?;
28474 self.write(" || ");
28475 self.generate_expression(&e.expression)?;
28476 }
28477 Ok(())
28478 }
28479
28480 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
28481 self.write_keyword("DATABLOCKSIZE");
28483 self.write("=");
28484 if let Some(size) = e.size {
28485 self.write(&size.to_string());
28486 if let Some(units) = &e.units {
28487 self.write_space();
28488 self.generate_expression(units)?;
28489 }
28490 } else if e.minimum.is_some() {
28491 self.write_keyword("MINIMUM");
28492 } else if e.maximum.is_some() {
28493 self.write_keyword("MAXIMUM");
28494 } else if e.default.is_some() {
28495 self.write_keyword("DEFAULT");
28496 }
28497 Ok(())
28498 }
28499
28500 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
28501 self.write_keyword("DATA_DELETION");
28503 self.write("=");
28504
28505 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
28506 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
28507
28508 if is_on {
28509 self.write_keyword("ON");
28510 if has_options {
28511 self.write("(");
28512 let mut first = true;
28513 if let Some(filter_column) = &e.filter_column {
28514 self.write_keyword("FILTER_COLUMN");
28515 self.write("=");
28516 self.generate_expression(filter_column)?;
28517 first = false;
28518 }
28519 if let Some(retention_period) = &e.retention_period {
28520 if !first {
28521 self.write(", ");
28522 }
28523 self.write_keyword("RETENTION_PERIOD");
28524 self.write("=");
28525 self.generate_expression(retention_period)?;
28526 }
28527 self.write(")");
28528 }
28529 } else {
28530 self.write_keyword("OFF");
28531 }
28532 Ok(())
28533 }
28534
28535 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
28539 use crate::dialects::DialectType;
28540 use crate::expressions::Literal;
28541
28542 match self.config.dialect {
28543 Some(DialectType::Exasol) => {
28545 self.write_keyword("TO_DATE");
28546 self.write("(");
28547 match &e.this {
28549 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
28550 let Literal::String(s) = lit.as_ref() else {
28551 unreachable!()
28552 };
28553 self.write("'");
28554 self.write(s);
28555 self.write("'");
28556 }
28557 _ => {
28558 self.generate_expression(&e.this)?;
28559 }
28560 }
28561 self.write(")");
28562 }
28563 _ => {
28565 self.write_keyword("DATE");
28566 self.write("(");
28567 self.generate_expression(&e.this)?;
28568 self.write(")");
28569 }
28570 }
28571 Ok(())
28572 }
28573
28574 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
28575 self.write_keyword("DATE_BIN");
28577 self.write("(");
28578 self.generate_expression(&e.this)?;
28579 self.write(", ");
28580 self.generate_expression(&e.expression)?;
28581 if let Some(origin) = &e.origin {
28582 self.write(", ");
28583 self.generate_expression(origin)?;
28584 }
28585 self.write(")");
28586 Ok(())
28587 }
28588
28589 fn generate_date_format_column_constraint(
28590 &mut self,
28591 e: &DateFormatColumnConstraint,
28592 ) -> Result<()> {
28593 self.write_keyword("FORMAT");
28595 self.write_space();
28596 self.generate_expression(&e.this)?;
28597 Ok(())
28598 }
28599
28600 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
28601 self.write_keyword("DATE_FROM_PARTS");
28603 self.write("(");
28604 let mut first = true;
28605 if let Some(year) = &e.year {
28606 self.generate_expression(year)?;
28607 first = false;
28608 }
28609 if let Some(month) = &e.month {
28610 if !first {
28611 self.write(", ");
28612 }
28613 self.generate_expression(month)?;
28614 first = false;
28615 }
28616 if let Some(day) = &e.day {
28617 if !first {
28618 self.write(", ");
28619 }
28620 self.generate_expression(day)?;
28621 }
28622 self.write(")");
28623 Ok(())
28624 }
28625
28626 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
28627 self.write_keyword("DATETIME");
28629 self.write("(");
28630 self.generate_expression(&e.this)?;
28631 if let Some(expr) = &e.expression {
28632 self.write(", ");
28633 self.generate_expression(expr)?;
28634 }
28635 self.write(")");
28636 Ok(())
28637 }
28638
28639 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
28640 self.write_keyword("DATETIME_ADD");
28642 self.write("(");
28643 self.generate_expression(&e.this)?;
28644 self.write(", ");
28645 self.generate_expression(&e.expression)?;
28646 if let Some(unit) = &e.unit {
28647 self.write(", ");
28648 self.write_keyword(unit);
28649 }
28650 self.write(")");
28651 Ok(())
28652 }
28653
28654 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
28655 self.write_keyword("DATETIME_DIFF");
28657 self.write("(");
28658 self.generate_expression(&e.this)?;
28659 self.write(", ");
28660 self.generate_expression(&e.expression)?;
28661 if let Some(unit) = &e.unit {
28662 self.write(", ");
28663 self.write_keyword(unit);
28664 }
28665 self.write(")");
28666 Ok(())
28667 }
28668
28669 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
28670 self.write_keyword("DATETIME_SUB");
28672 self.write("(");
28673 self.generate_expression(&e.this)?;
28674 self.write(", ");
28675 self.generate_expression(&e.expression)?;
28676 if let Some(unit) = &e.unit {
28677 self.write(", ");
28678 self.write_keyword(unit);
28679 }
28680 self.write(")");
28681 Ok(())
28682 }
28683
28684 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
28685 self.write_keyword("DATETIME_TRUNC");
28687 self.write("(");
28688 self.generate_expression(&e.this)?;
28689 self.write(", ");
28690 self.write_keyword(&e.unit);
28691 if let Some(zone) = &e.zone {
28692 self.write(", ");
28693 self.generate_expression(zone)?;
28694 }
28695 self.write(")");
28696 Ok(())
28697 }
28698
28699 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
28700 self.write_keyword("DAYNAME");
28702 self.write("(");
28703 self.generate_expression(&e.this)?;
28704 self.write(")");
28705 Ok(())
28706 }
28707
28708 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
28709 self.write_keyword("DECLARE");
28711 self.write_space();
28712 if e.replace {
28713 self.write_keyword("OR");
28714 self.write_space();
28715 self.write_keyword("REPLACE");
28716 self.write_space();
28717 }
28718 for (i, expr) in e.expressions.iter().enumerate() {
28719 if i > 0 {
28720 self.write(", ");
28721 }
28722 self.generate_expression(expr)?;
28723 }
28724 Ok(())
28725 }
28726
28727 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
28728 use crate::dialects::DialectType;
28729
28730 self.generate_expression(&e.this)?;
28732 for name in &e.additional_names {
28734 self.write(", ");
28735 self.generate_expression(name)?;
28736 }
28737 if let Some(kind) = &e.kind {
28738 self.write_space();
28739 match self.config.dialect {
28743 Some(DialectType::BigQuery) => {
28744 self.write(kind);
28745 }
28746 Some(DialectType::TSQL) => {
28747 let is_complex_table = kind.starts_with("TABLE")
28751 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
28752 if is_complex_table {
28753 self.write(kind);
28754 } else if kind == "INT" {
28755 self.write("INTEGER");
28756 } else if kind.starts_with("TABLE") {
28757 let normalized = kind
28759 .replace(" INT ", " INTEGER ")
28760 .replace(" INT,", " INTEGER,")
28761 .replace(" INT)", " INTEGER)")
28762 .replace("(INT ", "(INTEGER ");
28763 self.write(&normalized);
28764 } else {
28765 self.write(kind);
28766 }
28767 }
28768 _ => {
28769 if e.has_as {
28770 self.write_keyword("AS");
28771 self.write_space();
28772 }
28773 self.write(kind);
28774 }
28775 }
28776 }
28777 if let Some(default) = &e.default {
28778 match self.config.dialect {
28780 Some(DialectType::BigQuery) => {
28781 self.write_space();
28782 self.write_keyword("DEFAULT");
28783 self.write_space();
28784 }
28785 _ => {
28786 self.write(" = ");
28787 }
28788 }
28789 self.generate_expression(default)?;
28790 }
28791 Ok(())
28792 }
28793
28794 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
28795 self.write_keyword("DECODE");
28797 self.write("(");
28798 for (i, expr) in e.expressions.iter().enumerate() {
28799 if i > 0 {
28800 self.write(", ");
28801 }
28802 self.generate_expression(expr)?;
28803 }
28804 self.write(")");
28805 Ok(())
28806 }
28807
28808 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
28809 self.write_keyword("DECOMPRESS");
28811 self.write("(");
28812 self.generate_expression(&e.this)?;
28813 self.write(", '");
28814 self.write(&e.method);
28815 self.write("')");
28816 Ok(())
28817 }
28818
28819 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
28820 self.write_keyword("DECOMPRESS");
28822 self.write("(");
28823 self.generate_expression(&e.this)?;
28824 self.write(", '");
28825 self.write(&e.method);
28826 self.write("')");
28827 Ok(())
28828 }
28829
28830 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
28831 self.write_keyword("DECRYPT");
28833 self.write("(");
28834 self.generate_expression(&e.this)?;
28835 if let Some(passphrase) = &e.passphrase {
28836 self.write(", ");
28837 self.generate_expression(passphrase)?;
28838 }
28839 if let Some(aad) = &e.aad {
28840 self.write(", ");
28841 self.generate_expression(aad)?;
28842 }
28843 if let Some(method) = &e.encryption_method {
28844 self.write(", ");
28845 self.generate_expression(method)?;
28846 }
28847 self.write(")");
28848 Ok(())
28849 }
28850
28851 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
28852 self.write_keyword("DECRYPT_RAW");
28854 self.write("(");
28855 self.generate_expression(&e.this)?;
28856 if let Some(key) = &e.key {
28857 self.write(", ");
28858 self.generate_expression(key)?;
28859 }
28860 if let Some(iv) = &e.iv {
28861 self.write(", ");
28862 self.generate_expression(iv)?;
28863 }
28864 if let Some(aad) = &e.aad {
28865 self.write(", ");
28866 self.generate_expression(aad)?;
28867 }
28868 if let Some(method) = &e.encryption_method {
28869 self.write(", ");
28870 self.generate_expression(method)?;
28871 }
28872 self.write(")");
28873 Ok(())
28874 }
28875
28876 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
28877 self.write_keyword("DEFINER");
28879 self.write(" = ");
28880 self.generate_expression(&e.this)?;
28881 Ok(())
28882 }
28883
28884 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
28885 self.write_keyword("DETACH");
28887 if e.exists {
28888 self.write_keyword(" DATABASE IF EXISTS");
28889 }
28890 self.write_space();
28891 self.generate_expression(&e.this)?;
28892 Ok(())
28893 }
28894
28895 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
28896 let property_name = match e.this.as_ref() {
28897 Expression::Identifier(id) => id.name.as_str(),
28898 Expression::Var(v) => v.this.as_str(),
28899 _ => "DICTIONARY",
28900 };
28901 self.write_keyword(property_name);
28902 self.write("(");
28903 self.write(&e.kind);
28904 if let Some(settings) = &e.settings {
28905 self.write("(");
28906 if let Expression::Tuple(t) = settings.as_ref() {
28907 if self.config.pretty && !t.expressions.is_empty() {
28908 self.write_newline();
28909 self.indent_level += 1;
28910 for (i, pair) in t.expressions.iter().enumerate() {
28911 if i > 0 {
28912 self.write(",");
28913 self.write_newline();
28914 }
28915 self.write_indent();
28916 if let Expression::Tuple(pair_tuple) = pair {
28917 if let Some(k) = pair_tuple.expressions.first() {
28918 self.generate_expression(k)?;
28919 }
28920 if let Some(v) = pair_tuple.expressions.get(1) {
28921 self.write(" ");
28922 self.generate_expression(v)?;
28923 }
28924 } else {
28925 self.generate_expression(pair)?;
28926 }
28927 }
28928 self.indent_level -= 1;
28929 self.write_newline();
28930 self.write_indent();
28931 } else {
28932 for (i, pair) in t.expressions.iter().enumerate() {
28933 if i > 0 {
28934 self.write(" ");
28936 }
28937 if let Expression::Tuple(pair_tuple) = pair {
28938 if let Some(k) = pair_tuple.expressions.first() {
28939 self.generate_expression(k)?;
28940 }
28941 if let Some(v) = pair_tuple.expressions.get(1) {
28942 self.write(" ");
28943 self.generate_expression(v)?;
28944 }
28945 } else {
28946 self.generate_expression(pair)?;
28947 }
28948 }
28949 }
28950 } else {
28951 self.generate_expression(settings)?;
28952 }
28953 self.write(")");
28954 } else {
28955 self.write("()");
28957 }
28958 self.write(")");
28959 Ok(())
28960 }
28961
28962 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
28963 let property_name = match e.this.as_ref() {
28964 Expression::Identifier(id) => id.name.as_str(),
28965 Expression::Var(v) => v.this.as_str(),
28966 _ => "RANGE",
28967 };
28968 self.write_keyword(property_name);
28969 self.write("(");
28970 if let Some(min) = &e.min {
28971 self.write_keyword("MIN");
28972 self.write_space();
28973 self.generate_expression(min)?;
28974 }
28975 if let Some(max) = &e.max {
28976 self.write_space();
28977 self.write_keyword("MAX");
28978 self.write_space();
28979 self.generate_expression(max)?;
28980 }
28981 self.write(")");
28982 Ok(())
28983 }
28984
28985 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
28986 if e.local.is_some() {
28988 self.write_keyword("LOCAL ");
28989 }
28990 self.write_keyword("DIRECTORY");
28991 self.write_space();
28992 self.generate_expression(&e.this)?;
28993 if let Some(row_format) = &e.row_format {
28994 self.write_space();
28995 self.generate_expression(row_format)?;
28996 }
28997 Ok(())
28998 }
28999
29000 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
29001 self.write_keyword("DISTKEY");
29003 self.write("(");
29004 self.generate_expression(&e.this)?;
29005 self.write(")");
29006 Ok(())
29007 }
29008
29009 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
29010 self.write_keyword("DISTSTYLE");
29012 self.write_space();
29013 self.generate_expression(&e.this)?;
29014 Ok(())
29015 }
29016
29017 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
29018 self.write_keyword("DISTRIBUTE BY");
29020 self.write_space();
29021 for (i, expr) in e.expressions.iter().enumerate() {
29022 if i > 0 {
29023 self.write(", ");
29024 }
29025 self.generate_expression(expr)?;
29026 }
29027 Ok(())
29028 }
29029
29030 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
29031 self.write_keyword("DISTRIBUTED BY");
29033 self.write_space();
29034 self.write(&e.kind);
29035 if !e.expressions.is_empty() {
29036 self.write(" (");
29037 for (i, expr) in e.expressions.iter().enumerate() {
29038 if i > 0 {
29039 self.write(", ");
29040 }
29041 self.generate_expression(expr)?;
29042 }
29043 self.write(")");
29044 }
29045 if let Some(buckets) = &e.buckets {
29046 self.write_space();
29047 self.write_keyword("BUCKETS");
29048 self.write_space();
29049 self.generate_expression(buckets)?;
29050 }
29051 if let Some(order) = &e.order {
29052 self.write_space();
29053 self.generate_expression(order)?;
29054 }
29055 Ok(())
29056 }
29057
29058 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
29059 self.write_keyword("DOT_PRODUCT");
29061 self.write("(");
29062 self.generate_expression(&e.this)?;
29063 self.write(", ");
29064 self.generate_expression(&e.expression)?;
29065 self.write(")");
29066 Ok(())
29067 }
29068
29069 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
29070 self.write_keyword("DROP");
29072 if e.exists {
29073 self.write_keyword(" IF EXISTS ");
29074 } else {
29075 self.write_space();
29076 }
29077 for (i, expr) in e.expressions.iter().enumerate() {
29078 if i > 0 {
29079 self.write(", ");
29080 }
29081 self.generate_expression(expr)?;
29082 }
29083 Ok(())
29084 }
29085
29086 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
29087 self.write_keyword("DUPLICATE KEY");
29089 self.write(" (");
29090 for (i, expr) in e.expressions.iter().enumerate() {
29091 if i > 0 {
29092 self.write(", ");
29093 }
29094 self.generate_expression(expr)?;
29095 }
29096 self.write(")");
29097 Ok(())
29098 }
29099
29100 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
29101 self.write_keyword("ELT");
29103 self.write("(");
29104 self.generate_expression(&e.this)?;
29105 for expr in &e.expressions {
29106 self.write(", ");
29107 self.generate_expression(expr)?;
29108 }
29109 self.write(")");
29110 Ok(())
29111 }
29112
29113 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
29114 self.write_keyword("ENCODE");
29116 self.write("(");
29117 self.generate_expression(&e.this)?;
29118 if let Some(charset) = &e.charset {
29119 self.write(", ");
29120 self.generate_expression(charset)?;
29121 }
29122 self.write(")");
29123 Ok(())
29124 }
29125
29126 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
29127 if e.key.is_some() {
29129 self.write_keyword("KEY ");
29130 }
29131 self.write_keyword("ENCODE");
29132 self.write_space();
29133 self.generate_expression(&e.this)?;
29134 if !e.properties.is_empty() {
29135 self.write(" (");
29136 for (i, prop) in e.properties.iter().enumerate() {
29137 if i > 0 {
29138 self.write(", ");
29139 }
29140 self.generate_expression(prop)?;
29141 }
29142 self.write(")");
29143 }
29144 Ok(())
29145 }
29146
29147 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
29148 self.write_keyword("ENCRYPT");
29150 self.write("(");
29151 self.generate_expression(&e.this)?;
29152 if let Some(passphrase) = &e.passphrase {
29153 self.write(", ");
29154 self.generate_expression(passphrase)?;
29155 }
29156 if let Some(aad) = &e.aad {
29157 self.write(", ");
29158 self.generate_expression(aad)?;
29159 }
29160 if let Some(method) = &e.encryption_method {
29161 self.write(", ");
29162 self.generate_expression(method)?;
29163 }
29164 self.write(")");
29165 Ok(())
29166 }
29167
29168 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
29169 self.write_keyword("ENCRYPT_RAW");
29171 self.write("(");
29172 self.generate_expression(&e.this)?;
29173 if let Some(key) = &e.key {
29174 self.write(", ");
29175 self.generate_expression(key)?;
29176 }
29177 if let Some(iv) = &e.iv {
29178 self.write(", ");
29179 self.generate_expression(iv)?;
29180 }
29181 if let Some(aad) = &e.aad {
29182 self.write(", ");
29183 self.generate_expression(aad)?;
29184 }
29185 if let Some(method) = &e.encryption_method {
29186 self.write(", ");
29187 self.generate_expression(method)?;
29188 }
29189 self.write(")");
29190 Ok(())
29191 }
29192
29193 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
29194 self.write_keyword("ENGINE");
29196 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
29197 self.write("=");
29198 } else {
29199 self.write(" = ");
29200 }
29201 self.generate_expression(&e.this)?;
29202 Ok(())
29203 }
29204
29205 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
29206 self.write_keyword("ENVIRONMENT");
29208 self.write(" (");
29209 for (i, expr) in e.expressions.iter().enumerate() {
29210 if i > 0 {
29211 self.write(", ");
29212 }
29213 self.generate_expression(expr)?;
29214 }
29215 self.write(")");
29216 Ok(())
29217 }
29218
29219 fn generate_ephemeral_column_constraint(
29220 &mut self,
29221 e: &EphemeralColumnConstraint,
29222 ) -> Result<()> {
29223 self.write_keyword("EPHEMERAL");
29225 if let Some(this) = &e.this {
29226 self.write_space();
29227 self.generate_expression(this)?;
29228 }
29229 Ok(())
29230 }
29231
29232 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
29233 self.write_keyword("EQUAL_NULL");
29235 self.write("(");
29236 self.generate_expression(&e.this)?;
29237 self.write(", ");
29238 self.generate_expression(&e.expression)?;
29239 self.write(")");
29240 Ok(())
29241 }
29242
29243 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
29244 use crate::dialects::DialectType;
29245
29246 match self.config.dialect {
29248 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
29249 self.generate_expression(&e.this)?;
29250 self.write(" <-> ");
29251 self.generate_expression(&e.expression)?;
29252 }
29253 _ => {
29254 self.write_keyword("EUCLIDEAN_DISTANCE");
29256 self.write("(");
29257 self.generate_expression(&e.this)?;
29258 self.write(", ");
29259 self.generate_expression(&e.expression)?;
29260 self.write(")");
29261 }
29262 }
29263 Ok(())
29264 }
29265
29266 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
29267 self.write_keyword("EXECUTE AS");
29269 self.write_space();
29270 self.generate_expression(&e.this)?;
29271 Ok(())
29272 }
29273
29274 fn generate_export(&mut self, e: &Export) -> Result<()> {
29275 self.write_keyword("EXPORT DATA");
29277 if let Some(connection) = &e.connection {
29278 self.write_space();
29279 self.write_keyword("WITH CONNECTION");
29280 self.write_space();
29281 self.generate_expression(connection)?;
29282 }
29283 if !e.options.is_empty() {
29284 self.write_space();
29285 self.generate_options_clause(&e.options)?;
29286 }
29287 self.write_space();
29288 self.write_keyword("AS");
29289 self.write_space();
29290 self.generate_expression(&e.this)?;
29291 Ok(())
29292 }
29293
29294 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
29295 self.write_keyword("EXTERNAL");
29297 if let Some(this) = &e.this {
29298 self.write_space();
29299 self.generate_expression(this)?;
29300 }
29301 Ok(())
29302 }
29303
29304 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
29305 if e.no.is_some() {
29307 self.write_keyword("NO ");
29308 }
29309 self.write_keyword("FALLBACK");
29310 if e.protection.is_some() {
29311 self.write_keyword(" PROTECTION");
29312 }
29313 Ok(())
29314 }
29315
29316 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
29317 self.write_keyword("FARM_FINGERPRINT");
29319 self.write("(");
29320 for (i, expr) in e.expressions.iter().enumerate() {
29321 if i > 0 {
29322 self.write(", ");
29323 }
29324 self.generate_expression(expr)?;
29325 }
29326 self.write(")");
29327 Ok(())
29328 }
29329
29330 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
29331 self.write_keyword("FEATURES_AT_TIME");
29333 self.write("(");
29334 self.generate_expression(&e.this)?;
29335 if let Some(time) = &e.time {
29336 self.write(", ");
29337 self.generate_expression(time)?;
29338 }
29339 if let Some(num_rows) = &e.num_rows {
29340 self.write(", ");
29341 self.generate_expression(num_rows)?;
29342 }
29343 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
29344 self.write(", ");
29345 self.generate_expression(ignore_nulls)?;
29346 }
29347 self.write(")");
29348 Ok(())
29349 }
29350
29351 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
29352 let use_limit = !e.percent
29354 && !e.with_ties
29355 && e.count.is_some()
29356 && matches!(
29357 self.config.dialect,
29358 Some(DialectType::Spark)
29359 | Some(DialectType::Hive)
29360 | Some(DialectType::DuckDB)
29361 | Some(DialectType::SQLite)
29362 | Some(DialectType::MySQL)
29363 | Some(DialectType::BigQuery)
29364 | Some(DialectType::Databricks)
29365 | Some(DialectType::StarRocks)
29366 | Some(DialectType::Doris)
29367 | Some(DialectType::Athena)
29368 | Some(DialectType::ClickHouse)
29369 );
29370
29371 if use_limit {
29372 self.write_keyword("LIMIT");
29373 self.write_space();
29374 self.generate_expression(e.count.as_ref().unwrap())?;
29375 return Ok(());
29376 }
29377
29378 self.write_keyword("FETCH");
29380 if !e.direction.is_empty() {
29381 self.write_space();
29382 self.write_keyword(&e.direction);
29383 }
29384 if let Some(count) = &e.count {
29385 self.write_space();
29386 self.generate_expression(count)?;
29387 }
29388 if e.percent {
29390 self.write_keyword(" PERCENT");
29391 }
29392 if e.rows {
29393 self.write_keyword(" ROWS");
29394 }
29395 if e.with_ties {
29396 self.write_keyword(" WITH TIES");
29397 } else if e.rows {
29398 self.write_keyword(" ONLY");
29399 } else {
29400 self.write_keyword(" ROWS ONLY");
29401 }
29402 Ok(())
29403 }
29404
29405 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
29406 if e.hive_format.is_some() {
29410 self.write_keyword("STORED AS");
29412 self.write_space();
29413 if let Some(this) = &e.this {
29414 if let Expression::Identifier(id) = this.as_ref() {
29416 self.write_keyword(&id.name.to_ascii_uppercase());
29417 } else {
29418 self.generate_expression(this)?;
29419 }
29420 }
29421 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
29422 self.write_keyword("STORED AS");
29424 self.write_space();
29425 if let Some(this) = &e.this {
29426 if let Expression::Identifier(id) = this.as_ref() {
29427 self.write_keyword(&id.name.to_ascii_uppercase());
29428 } else {
29429 self.generate_expression(this)?;
29430 }
29431 }
29432 } else if matches!(
29433 self.config.dialect,
29434 Some(DialectType::Spark) | Some(DialectType::Databricks)
29435 ) {
29436 self.write_keyword("USING");
29438 self.write_space();
29439 if let Some(this) = &e.this {
29440 self.generate_expression(this)?;
29441 }
29442 } else {
29443 self.write_keyword("FILE_FORMAT");
29445 self.write(" = ");
29446 if let Some(this) = &e.this {
29447 self.generate_expression(this)?;
29448 } else if !e.expressions.is_empty() {
29449 self.write("(");
29450 for (i, expr) in e.expressions.iter().enumerate() {
29451 if i > 0 {
29452 self.write(", ");
29453 }
29454 self.generate_expression(expr)?;
29455 }
29456 self.write(")");
29457 }
29458 }
29459 Ok(())
29460 }
29461
29462 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
29463 self.generate_expression(&e.this)?;
29465 self.write_space();
29466 self.write_keyword("FILTER");
29467 self.write("(");
29468 self.write_keyword("WHERE");
29469 self.write_space();
29470 self.generate_expression(&e.expression)?;
29471 self.write(")");
29472 Ok(())
29473 }
29474
29475 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
29476 self.write_keyword("FLOAT64");
29478 self.write("(");
29479 self.generate_expression(&e.this)?;
29480 if let Some(expr) = &e.expression {
29481 self.write(", ");
29482 self.generate_expression(expr)?;
29483 }
29484 self.write(")");
29485 Ok(())
29486 }
29487
29488 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
29489 self.write_keyword("FOR");
29491 self.write_space();
29492 self.generate_expression(&e.this)?;
29493 self.write_space();
29494 self.write_keyword("DO");
29495 self.write_space();
29496 self.generate_expression(&e.expression)?;
29497 Ok(())
29498 }
29499
29500 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
29501 self.write_keyword("FOREIGN KEY");
29503 if !e.expressions.is_empty() {
29504 self.write(" (");
29505 for (i, expr) in e.expressions.iter().enumerate() {
29506 if i > 0 {
29507 self.write(", ");
29508 }
29509 self.generate_expression(expr)?;
29510 }
29511 self.write(")");
29512 }
29513 if let Some(reference) = &e.reference {
29514 self.write_space();
29515 self.generate_expression(reference)?;
29516 }
29517 if let Some(delete) = &e.delete {
29518 self.write_space();
29519 self.write_keyword("ON DELETE");
29520 self.write_space();
29521 self.generate_expression(delete)?;
29522 }
29523 if let Some(update) = &e.update {
29524 self.write_space();
29525 self.write_keyword("ON UPDATE");
29526 self.write_space();
29527 self.generate_expression(update)?;
29528 }
29529 if !e.options.is_empty() {
29530 self.write_space();
29531 for (i, opt) in e.options.iter().enumerate() {
29532 if i > 0 {
29533 self.write_space();
29534 }
29535 self.generate_expression(opt)?;
29536 }
29537 }
29538 Ok(())
29539 }
29540
29541 fn generate_format(&mut self, e: &Format) -> Result<()> {
29542 self.write_keyword("FORMAT");
29544 self.write("(");
29545 self.generate_expression(&e.this)?;
29546 for expr in &e.expressions {
29547 self.write(", ");
29548 self.generate_expression(expr)?;
29549 }
29550 self.write(")");
29551 Ok(())
29552 }
29553
29554 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
29555 self.generate_expression(&e.this)?;
29557 self.write(" (");
29558 self.write_keyword("FORMAT");
29559 self.write(" '");
29560 self.write(&e.format);
29561 self.write("')");
29562 Ok(())
29563 }
29564
29565 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
29566 self.write_keyword("FREESPACE");
29568 self.write("=");
29569 self.generate_expression(&e.this)?;
29570 if e.percent.is_some() {
29571 self.write_keyword(" PERCENT");
29572 }
29573 Ok(())
29574 }
29575
29576 fn generate_from(&mut self, e: &From) -> Result<()> {
29577 self.write_keyword("FROM");
29579 self.write_space();
29580
29581 use crate::dialects::DialectType;
29585 let has_tablesample = e
29586 .expressions
29587 .iter()
29588 .any(|expr| matches!(expr, Expression::TableSample(_)));
29589 let is_cross_join_dialect = matches!(
29590 self.config.dialect,
29591 Some(DialectType::BigQuery)
29592 | Some(DialectType::Hive)
29593 | Some(DialectType::Spark)
29594 | Some(DialectType::Databricks)
29595 | Some(DialectType::SQLite)
29596 | Some(DialectType::ClickHouse)
29597 );
29598 let source_is_same_as_target2 = self.config.source_dialect.is_some()
29599 && self.config.source_dialect == self.config.dialect;
29600 let source_is_cross_join_dialect2 = matches!(
29601 self.config.source_dialect,
29602 Some(DialectType::BigQuery)
29603 | Some(DialectType::Hive)
29604 | Some(DialectType::Spark)
29605 | Some(DialectType::Databricks)
29606 | Some(DialectType::SQLite)
29607 | Some(DialectType::ClickHouse)
29608 );
29609 let use_cross_join = !has_tablesample
29610 && is_cross_join_dialect
29611 && (source_is_same_as_target2
29612 || source_is_cross_join_dialect2
29613 || self.config.source_dialect.is_none());
29614
29615 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
29617
29618 for (i, expr) in e.expressions.iter().enumerate() {
29619 if i > 0 {
29620 if use_cross_join {
29621 self.write(" CROSS JOIN ");
29622 } else {
29623 self.write(", ");
29624 }
29625 }
29626 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
29627 self.write("(");
29628 self.generate_expression(expr)?;
29629 self.write(")");
29630 } else {
29631 self.generate_expression(expr)?;
29632 }
29633 let leading = Self::extract_table_leading_comments(expr);
29636 for comment in &leading {
29637 self.write_space();
29638 self.write_formatted_comment(comment);
29639 }
29640 }
29641 Ok(())
29642 }
29643
29644 fn extract_table_leading_comments(expr: &Expression) -> Vec<String> {
29646 match expr {
29647 Expression::Table(t) => t.leading_comments.clone(),
29648 Expression::Pivot(p) => {
29649 if let Expression::Table(t) = &p.this {
29650 t.leading_comments.clone()
29651 } else {
29652 Vec::new()
29653 }
29654 }
29655 _ => Vec::new(),
29656 }
29657 }
29658
29659 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
29660 self.write_keyword("FROM_BASE");
29662 self.write("(");
29663 self.generate_expression(&e.this)?;
29664 self.write(", ");
29665 self.generate_expression(&e.expression)?;
29666 self.write(")");
29667 Ok(())
29668 }
29669
29670 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
29671 self.generate_expression(&e.this)?;
29673 if let Some(zone) = &e.zone {
29674 self.write_space();
29675 self.write_keyword("AT TIME ZONE");
29676 self.write_space();
29677 self.generate_expression(zone)?;
29678 self.write_space();
29679 self.write_keyword("AT TIME ZONE");
29680 self.write(" 'UTC'");
29681 }
29682 Ok(())
29683 }
29684
29685 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
29686 self.write_keyword("GAP_FILL");
29688 self.write("(");
29689 self.generate_expression(&e.this)?;
29690 if let Some(ts_column) = &e.ts_column {
29691 self.write(", ");
29692 self.generate_expression(ts_column)?;
29693 }
29694 if let Some(bucket_width) = &e.bucket_width {
29695 self.write(", ");
29696 self.generate_expression(bucket_width)?;
29697 }
29698 if let Some(partitioning_columns) = &e.partitioning_columns {
29699 self.write(", ");
29700 self.generate_expression(partitioning_columns)?;
29701 }
29702 if let Some(value_columns) = &e.value_columns {
29703 self.write(", ");
29704 self.generate_expression(value_columns)?;
29705 }
29706 self.write(")");
29707 Ok(())
29708 }
29709
29710 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
29711 self.write_keyword("GENERATE_DATE_ARRAY");
29713 self.write("(");
29714 let mut first = true;
29715 if let Some(start) = &e.start {
29716 self.generate_expression(start)?;
29717 first = false;
29718 }
29719 if let Some(end) = &e.end {
29720 if !first {
29721 self.write(", ");
29722 }
29723 self.generate_expression(end)?;
29724 first = false;
29725 }
29726 if let Some(step) = &e.step {
29727 if !first {
29728 self.write(", ");
29729 }
29730 self.generate_expression(step)?;
29731 }
29732 self.write(")");
29733 Ok(())
29734 }
29735
29736 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
29737 self.write_keyword("ML.GENERATE_EMBEDDING");
29739 self.write("(");
29740 self.generate_expression(&e.this)?;
29741 self.write(", ");
29742 self.generate_expression(&e.expression)?;
29743 if let Some(params) = &e.params_struct {
29744 self.write(", ");
29745 self.generate_expression(params)?;
29746 }
29747 self.write(")");
29748 Ok(())
29749 }
29750
29751 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
29752 let fn_name = match self.config.dialect {
29754 Some(DialectType::Presto)
29755 | Some(DialectType::Trino)
29756 | Some(DialectType::Athena)
29757 | Some(DialectType::Spark)
29758 | Some(DialectType::Databricks)
29759 | Some(DialectType::Hive) => "SEQUENCE",
29760 _ => "GENERATE_SERIES",
29761 };
29762 self.write_keyword(fn_name);
29763 self.write("(");
29764 let mut first = true;
29765 if let Some(start) = &e.start {
29766 self.generate_expression(start)?;
29767 first = false;
29768 }
29769 if let Some(end) = &e.end {
29770 if !first {
29771 self.write(", ");
29772 }
29773 self.generate_expression(end)?;
29774 first = false;
29775 }
29776 if let Some(step) = &e.step {
29777 if !first {
29778 self.write(", ");
29779 }
29780 if matches!(
29783 self.config.dialect,
29784 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
29785 ) {
29786 if let Some(converted) = self.convert_week_interval_to_day(step) {
29787 self.generate_expression(&converted)?;
29788 } else {
29789 self.generate_expression(step)?;
29790 }
29791 } else {
29792 self.generate_expression(step)?;
29793 }
29794 }
29795 self.write(")");
29796 Ok(())
29797 }
29798
29799 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
29802 use crate::expressions::*;
29803 if let Expression::Interval(ref iv) = expr {
29804 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
29806 unit: IntervalUnit::Week,
29807 ..
29808 }) = &iv.unit
29809 {
29810 let count = match &iv.this {
29812 Some(Expression::Literal(lit)) => match lit.as_ref() {
29813 Literal::String(s) | Literal::Number(s) => s.clone(),
29814 _ => return None,
29815 },
29816 _ => return None,
29817 };
29818 (true, count)
29819 } else if iv.unit.is_none() {
29820 if let Some(Expression::Literal(lit)) = &iv.this {
29822 if let Literal::String(s) = lit.as_ref() {
29823 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
29824 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
29825 (true, parts[0].to_string())
29826 } else {
29827 (false, String::new())
29828 }
29829 } else {
29830 (false, String::new())
29831 }
29832 } else {
29833 (false, String::new())
29834 }
29835 } else {
29836 (false, String::new())
29837 };
29838
29839 if is_week {
29840 let count_expr = Expression::Literal(Box::new(Literal::Number(count_str)));
29842 let day_interval = Expression::Interval(Box::new(Interval {
29843 this: Some(Expression::Literal(Box::new(Literal::String(
29844 "7".to_string(),
29845 )))),
29846 unit: Some(IntervalUnitSpec::Simple {
29847 unit: IntervalUnit::Day,
29848 use_plural: false,
29849 }),
29850 }));
29851 let mul = Expression::Mul(Box::new(BinaryOp {
29852 left: count_expr,
29853 right: day_interval,
29854 left_comments: vec![],
29855 operator_comments: vec![],
29856 trailing_comments: vec![],
29857 inferred_type: None,
29858 }));
29859 return Some(Expression::Paren(Box::new(Paren {
29860 this: mul,
29861 trailing_comments: vec![],
29862 })));
29863 }
29864 }
29865 None
29866 }
29867
29868 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
29869 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
29871 self.write("(");
29872 let mut first = true;
29873 if let Some(start) = &e.start {
29874 self.generate_expression(start)?;
29875 first = false;
29876 }
29877 if let Some(end) = &e.end {
29878 if !first {
29879 self.write(", ");
29880 }
29881 self.generate_expression(end)?;
29882 first = false;
29883 }
29884 if let Some(step) = &e.step {
29885 if !first {
29886 self.write(", ");
29887 }
29888 self.generate_expression(step)?;
29889 }
29890 self.write(")");
29891 Ok(())
29892 }
29893
29894 fn generate_generated_as_identity_column_constraint(
29895 &mut self,
29896 e: &GeneratedAsIdentityColumnConstraint,
29897 ) -> Result<()> {
29898 use crate::dialects::DialectType;
29899
29900 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
29902 self.write_keyword("AUTOINCREMENT");
29903 if let Some(start) = &e.start {
29904 self.write_keyword(" START ");
29905 self.generate_expression(start)?;
29906 }
29907 if let Some(increment) = &e.increment {
29908 self.write_keyword(" INCREMENT ");
29909 self.generate_expression(increment)?;
29910 }
29911 return Ok(());
29912 }
29913
29914 self.write_keyword("GENERATED");
29916 if let Some(this) = &e.this {
29917 if let Expression::Boolean(b) = this.as_ref() {
29919 if b.value {
29920 self.write_keyword(" ALWAYS");
29921 } else {
29922 self.write_keyword(" BY DEFAULT");
29923 if e.on_null.is_some() {
29924 self.write_keyword(" ON NULL");
29925 }
29926 }
29927 } else {
29928 self.write_keyword(" ALWAYS");
29929 }
29930 }
29931 self.write_keyword(" AS IDENTITY");
29932 let has_options = e.start.is_some()
29934 || e.increment.is_some()
29935 || e.minvalue.is_some()
29936 || e.maxvalue.is_some();
29937 if has_options {
29938 self.write(" (");
29939 let mut first = true;
29940 if let Some(start) = &e.start {
29941 self.write_keyword("START WITH ");
29942 self.generate_expression(start)?;
29943 first = false;
29944 }
29945 if let Some(increment) = &e.increment {
29946 if !first {
29947 self.write(" ");
29948 }
29949 self.write_keyword("INCREMENT BY ");
29950 self.generate_expression(increment)?;
29951 first = false;
29952 }
29953 if let Some(minvalue) = &e.minvalue {
29954 if !first {
29955 self.write(" ");
29956 }
29957 self.write_keyword("MINVALUE ");
29958 self.generate_expression(minvalue)?;
29959 first = false;
29960 }
29961 if let Some(maxvalue) = &e.maxvalue {
29962 if !first {
29963 self.write(" ");
29964 }
29965 self.write_keyword("MAXVALUE ");
29966 self.generate_expression(maxvalue)?;
29967 }
29968 self.write(")");
29969 }
29970 Ok(())
29971 }
29972
29973 fn generate_generated_as_row_column_constraint(
29974 &mut self,
29975 e: &GeneratedAsRowColumnConstraint,
29976 ) -> Result<()> {
29977 self.write_keyword("GENERATED ALWAYS AS ROW ");
29979 if e.start.is_some() {
29980 self.write_keyword("START");
29981 } else {
29982 self.write_keyword("END");
29983 }
29984 if e.hidden.is_some() {
29985 self.write_keyword(" HIDDEN");
29986 }
29987 Ok(())
29988 }
29989
29990 fn generate_get(&mut self, e: &Get) -> Result<()> {
29991 self.write_keyword("GET");
29993 self.write_space();
29994 self.generate_expression(&e.this)?;
29995 if let Some(target) = &e.target {
29996 self.write_space();
29997 self.generate_expression(target)?;
29998 }
29999 for prop in &e.properties {
30000 self.write_space();
30001 self.generate_expression(prop)?;
30002 }
30003 Ok(())
30004 }
30005
30006 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
30007 self.generate_expression(&e.this)?;
30009 self.write("[");
30010 self.generate_expression(&e.expression)?;
30011 self.write("]");
30012 Ok(())
30013 }
30014
30015 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
30016 self.write_keyword("GETBIT");
30018 self.write("(");
30019 self.generate_expression(&e.this)?;
30020 self.write(", ");
30021 self.generate_expression(&e.expression)?;
30022 self.write(")");
30023 Ok(())
30024 }
30025
30026 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
30027 if e.is_role {
30029 self.write_keyword("ROLE");
30030 self.write_space();
30031 } else if e.is_group {
30032 self.write_keyword("GROUP");
30033 self.write_space();
30034 } else if e.is_share {
30035 self.write_keyword("SHARE");
30036 self.write_space();
30037 }
30038 self.write(&e.name.name);
30039 Ok(())
30040 }
30041
30042 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
30043 self.generate_expression(&e.this)?;
30045 if !e.expressions.is_empty() {
30046 self.write("(");
30047 for (i, expr) in e.expressions.iter().enumerate() {
30048 if i > 0 {
30049 self.write(", ");
30050 }
30051 self.generate_expression(expr)?;
30052 }
30053 self.write(")");
30054 }
30055 Ok(())
30056 }
30057
30058 fn generate_group(&mut self, e: &Group) -> Result<()> {
30059 self.write_keyword("GROUP BY");
30061 match e.all {
30063 Some(true) => {
30064 self.write_space();
30065 self.write_keyword("ALL");
30066 }
30067 Some(false) => {
30068 self.write_space();
30069 self.write_keyword("DISTINCT");
30070 }
30071 None => {}
30072 }
30073 if !e.expressions.is_empty() {
30074 self.write_space();
30075 for (i, expr) in e.expressions.iter().enumerate() {
30076 if i > 0 {
30077 self.write(", ");
30078 }
30079 self.generate_expression(expr)?;
30080 }
30081 }
30082 if let Some(cube) = &e.cube {
30084 if !e.expressions.is_empty() {
30085 self.write(", ");
30086 } else {
30087 self.write_space();
30088 }
30089 self.generate_expression(cube)?;
30090 }
30091 if let Some(rollup) = &e.rollup {
30092 if !e.expressions.is_empty() || e.cube.is_some() {
30093 self.write(", ");
30094 } else {
30095 self.write_space();
30096 }
30097 self.generate_expression(rollup)?;
30098 }
30099 if let Some(grouping_sets) = &e.grouping_sets {
30100 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
30101 self.write(", ");
30102 } else {
30103 self.write_space();
30104 }
30105 self.generate_expression(grouping_sets)?;
30106 }
30107 if let Some(totals) = &e.totals {
30108 self.write_space();
30109 self.write_keyword("WITH TOTALS");
30110 self.generate_expression(totals)?;
30111 }
30112 Ok(())
30113 }
30114
30115 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
30116 self.write_keyword("GROUP BY");
30118 match e.all {
30120 Some(true) => {
30121 self.write_space();
30122 self.write_keyword("ALL");
30123 }
30124 Some(false) => {
30125 self.write_space();
30126 self.write_keyword("DISTINCT");
30127 }
30128 None => {}
30129 }
30130
30131 let mut trailing_cube = false;
30134 let mut trailing_rollup = false;
30135 let mut regular_expressions: Vec<&Expression> = Vec::new();
30136
30137 for expr in &e.expressions {
30138 match expr {
30139 Expression::Cube(c) if c.expressions.is_empty() => {
30140 trailing_cube = true;
30141 }
30142 Expression::Rollup(r) if r.expressions.is_empty() => {
30143 trailing_rollup = true;
30144 }
30145 _ => {
30146 regular_expressions.push(expr);
30147 }
30148 }
30149 }
30150
30151 if self.config.pretty {
30153 self.write_newline();
30154 self.indent_level += 1;
30155 for (i, expr) in regular_expressions.iter().enumerate() {
30156 if i > 0 {
30157 self.write(",");
30158 self.write_newline();
30159 }
30160 self.write_indent();
30161 self.generate_expression(expr)?;
30162 }
30163 self.indent_level -= 1;
30164 } else {
30165 self.write_space();
30166 for (i, expr) in regular_expressions.iter().enumerate() {
30167 if i > 0 {
30168 self.write(", ");
30169 }
30170 self.generate_expression(expr)?;
30171 }
30172 }
30173
30174 if trailing_cube {
30176 self.write_space();
30177 self.write_keyword("WITH CUBE");
30178 } else if trailing_rollup {
30179 self.write_space();
30180 self.write_keyword("WITH ROLLUP");
30181 }
30182
30183 if e.totals {
30185 self.write_space();
30186 self.write_keyword("WITH TOTALS");
30187 }
30188
30189 Ok(())
30190 }
30191
30192 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
30193 self.write_keyword("GROUPING");
30195 self.write("(");
30196 for (i, expr) in e.expressions.iter().enumerate() {
30197 if i > 0 {
30198 self.write(", ");
30199 }
30200 self.generate_expression(expr)?;
30201 }
30202 self.write(")");
30203 Ok(())
30204 }
30205
30206 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
30207 self.write_keyword("GROUPING_ID");
30209 self.write("(");
30210 for (i, expr) in e.expressions.iter().enumerate() {
30211 if i > 0 {
30212 self.write(", ");
30213 }
30214 self.generate_expression(expr)?;
30215 }
30216 self.write(")");
30217 Ok(())
30218 }
30219
30220 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
30221 self.write_keyword("GROUPING SETS");
30223 self.write(" (");
30224 for (i, expr) in e.expressions.iter().enumerate() {
30225 if i > 0 {
30226 self.write(", ");
30227 }
30228 self.generate_expression(expr)?;
30229 }
30230 self.write(")");
30231 Ok(())
30232 }
30233
30234 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
30235 self.write_keyword("HASH_AGG");
30237 self.write("(");
30238 self.generate_expression(&e.this)?;
30239 for expr in &e.expressions {
30240 self.write(", ");
30241 self.generate_expression(expr)?;
30242 }
30243 self.write(")");
30244 Ok(())
30245 }
30246
30247 fn generate_having(&mut self, e: &Having) -> Result<()> {
30248 self.write_keyword("HAVING");
30250 self.write_space();
30251 self.generate_expression(&e.this)?;
30252 Ok(())
30253 }
30254
30255 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
30256 self.generate_expression(&e.this)?;
30258 self.write_space();
30259 self.write_keyword("HAVING");
30260 self.write_space();
30261 if e.max.is_some() {
30262 self.write_keyword("MAX");
30263 } else {
30264 self.write_keyword("MIN");
30265 }
30266 self.write_space();
30267 self.generate_expression(&e.expression)?;
30268 Ok(())
30269 }
30270
30271 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
30272 use crate::dialects::DialectType;
30273 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
30275 if let Expression::Literal(ref lit) = *e.this {
30277 if let Literal::String(ref s) = lit.as_ref() {
30278 return self.generate_string_literal(s);
30279 }
30280 }
30281 }
30282 if matches!(
30284 self.config.dialect,
30285 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
30286 ) {
30287 self.write("$");
30288 if let Some(tag) = &e.tag {
30289 self.generate_expression(tag)?;
30290 }
30291 self.write("$");
30292 self.generate_expression(&e.this)?;
30293 self.write("$");
30294 if let Some(tag) = &e.tag {
30295 self.generate_expression(tag)?;
30296 }
30297 self.write("$");
30298 return Ok(());
30299 }
30300 self.write("$");
30302 if let Some(tag) = &e.tag {
30303 self.generate_expression(tag)?;
30304 }
30305 self.write("$");
30306 self.generate_expression(&e.this)?;
30307 self.write("$");
30308 if let Some(tag) = &e.tag {
30309 self.generate_expression(tag)?;
30310 }
30311 self.write("$");
30312 Ok(())
30313 }
30314
30315 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
30316 self.write_keyword("HEX_ENCODE");
30318 self.write("(");
30319 self.generate_expression(&e.this)?;
30320 self.write(")");
30321 Ok(())
30322 }
30323
30324 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
30325 match e.this.as_ref() {
30328 Expression::Identifier(id) => self.write(&id.name),
30329 other => self.generate_expression(other)?,
30330 }
30331 self.write(" (");
30332 self.write(&e.kind);
30333 self.write(" => ");
30334 self.generate_expression(&e.expression)?;
30335 self.write(")");
30336 Ok(())
30337 }
30338
30339 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
30340 self.write_keyword("HLL");
30342 self.write("(");
30343 self.generate_expression(&e.this)?;
30344 for expr in &e.expressions {
30345 self.write(", ");
30346 self.generate_expression(expr)?;
30347 }
30348 self.write(")");
30349 Ok(())
30350 }
30351
30352 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
30353 if e.input_.is_some() && e.output.is_some() {
30355 self.write_keyword("IN OUT");
30356 } else if e.input_.is_some() {
30357 self.write_keyword("IN");
30358 } else if e.output.is_some() {
30359 self.write_keyword("OUT");
30360 }
30361 Ok(())
30362 }
30363
30364 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
30365 self.write_keyword("INCLUDE");
30367 self.write_space();
30368 self.generate_expression(&e.this)?;
30369 if let Some(column_def) = &e.column_def {
30370 self.write_space();
30371 self.generate_expression(column_def)?;
30372 }
30373 if let Some(alias) = &e.alias {
30374 self.write_space();
30375 self.write_keyword("AS");
30376 self.write_space();
30377 self.write(alias);
30378 }
30379 Ok(())
30380 }
30381
30382 fn generate_index(&mut self, e: &Index) -> Result<()> {
30383 if e.unique {
30385 self.write_keyword("UNIQUE");
30386 self.write_space();
30387 }
30388 if e.primary.is_some() {
30389 self.write_keyword("PRIMARY");
30390 self.write_space();
30391 }
30392 if e.amp.is_some() {
30393 self.write_keyword("AMP");
30394 self.write_space();
30395 }
30396 if e.table.is_none() {
30397 self.write_keyword("INDEX");
30398 self.write_space();
30399 }
30400 if let Some(name) = &e.this {
30401 self.generate_expression(name)?;
30402 self.write_space();
30403 }
30404 if let Some(table) = &e.table {
30405 self.write_keyword("ON");
30406 self.write_space();
30407 self.generate_expression(table)?;
30408 }
30409 if !e.params.is_empty() {
30410 self.write("(");
30411 for (i, param) in e.params.iter().enumerate() {
30412 if i > 0 {
30413 self.write(", ");
30414 }
30415 self.generate_expression(param)?;
30416 }
30417 self.write(")");
30418 }
30419 Ok(())
30420 }
30421
30422 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
30423 if let Some(kind) = &e.kind {
30425 self.write(kind);
30426 self.write_space();
30427 }
30428 self.write_keyword("INDEX");
30429 if let Some(this) = &e.this {
30430 self.write_space();
30431 self.generate_expression(this)?;
30432 }
30433 if let Some(index_type) = &e.index_type {
30434 self.write_space();
30435 self.write_keyword("USING");
30436 self.write_space();
30437 self.generate_expression(index_type)?;
30438 }
30439 if !e.expressions.is_empty() {
30440 self.write(" (");
30441 for (i, expr) in e.expressions.iter().enumerate() {
30442 if i > 0 {
30443 self.write(", ");
30444 }
30445 self.generate_expression(expr)?;
30446 }
30447 self.write(")");
30448 }
30449 for opt in &e.options {
30450 self.write_space();
30451 self.generate_expression(opt)?;
30452 }
30453 Ok(())
30454 }
30455
30456 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
30457 if let Some(key_block_size) = &e.key_block_size {
30459 self.write_keyword("KEY_BLOCK_SIZE");
30460 self.write(" = ");
30461 self.generate_expression(key_block_size)?;
30462 } else if let Some(using) = &e.using {
30463 self.write_keyword("USING");
30464 self.write_space();
30465 self.generate_expression(using)?;
30466 } else if let Some(parser) = &e.parser {
30467 self.write_keyword("WITH PARSER");
30468 self.write_space();
30469 self.generate_expression(parser)?;
30470 } else if let Some(comment) = &e.comment {
30471 self.write_keyword("COMMENT");
30472 self.write_space();
30473 self.generate_expression(comment)?;
30474 } else if let Some(visible) = &e.visible {
30475 self.generate_expression(visible)?;
30476 } else if let Some(engine_attr) = &e.engine_attr {
30477 self.write_keyword("ENGINE_ATTRIBUTE");
30478 self.write(" = ");
30479 self.generate_expression(engine_attr)?;
30480 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
30481 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
30482 self.write(" = ");
30483 self.generate_expression(secondary_engine_attr)?;
30484 }
30485 Ok(())
30486 }
30487
30488 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
30489 if let Some(using) = &e.using {
30491 self.write_keyword("USING");
30492 self.write_space();
30493 self.generate_expression(using)?;
30494 }
30495 if !e.columns.is_empty() {
30496 self.write("(");
30497 for (i, col) in e.columns.iter().enumerate() {
30498 if i > 0 {
30499 self.write(", ");
30500 }
30501 self.generate_expression(col)?;
30502 }
30503 self.write(")");
30504 }
30505 if let Some(partition_by) = &e.partition_by {
30506 self.write_space();
30507 self.write_keyword("PARTITION BY");
30508 self.write_space();
30509 self.generate_expression(partition_by)?;
30510 }
30511 if let Some(where_) = &e.where_ {
30512 self.write_space();
30513 self.generate_expression(where_)?;
30514 }
30515 if let Some(include) = &e.include {
30516 self.write_space();
30517 self.write_keyword("INCLUDE");
30518 self.write(" (");
30519 self.generate_expression(include)?;
30520 self.write(")");
30521 }
30522 if let Some(with_storage) = &e.with_storage {
30523 self.write_space();
30524 self.write_keyword("WITH");
30525 self.write(" (");
30526 self.generate_expression(with_storage)?;
30527 self.write(")");
30528 }
30529 if let Some(tablespace) = &e.tablespace {
30530 self.write_space();
30531 self.write_keyword("USING INDEX TABLESPACE");
30532 self.write_space();
30533 self.generate_expression(tablespace)?;
30534 }
30535 Ok(())
30536 }
30537
30538 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
30539 if let Expression::Identifier(id) = &*e.this {
30543 self.write_keyword(&id.name);
30544 } else {
30545 self.generate_expression(&e.this)?;
30546 }
30547 self.write_space();
30548 self.write_keyword("INDEX");
30549 if let Some(target) = &e.target {
30550 self.write_space();
30551 self.write_keyword("FOR");
30552 self.write_space();
30553 if let Expression::Identifier(id) = &**target {
30554 self.write_keyword(&id.name);
30555 } else {
30556 self.generate_expression(target)?;
30557 }
30558 }
30559 self.write(" (");
30561 for (i, expr) in e.expressions.iter().enumerate() {
30562 if i > 0 {
30563 self.write(", ");
30564 }
30565 self.generate_expression(expr)?;
30566 }
30567 self.write(")");
30568 Ok(())
30569 }
30570
30571 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
30572 self.write_keyword("INHERITS");
30574 self.write(" (");
30575 for (i, expr) in e.expressions.iter().enumerate() {
30576 if i > 0 {
30577 self.write(", ");
30578 }
30579 self.generate_expression(expr)?;
30580 }
30581 self.write(")");
30582 Ok(())
30583 }
30584
30585 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
30586 self.write_keyword("INPUT");
30588 self.write("(");
30589 self.generate_expression(&e.this)?;
30590 self.write(")");
30591 Ok(())
30592 }
30593
30594 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
30595 if let Some(input_format) = &e.input_format {
30597 self.write_keyword("INPUTFORMAT");
30598 self.write_space();
30599 self.generate_expression(input_format)?;
30600 }
30601 if let Some(output_format) = &e.output_format {
30602 if e.input_format.is_some() {
30603 self.write(" ");
30604 }
30605 self.write_keyword("OUTPUTFORMAT");
30606 self.write_space();
30607 self.generate_expression(output_format)?;
30608 }
30609 Ok(())
30610 }
30611
30612 fn generate_install(&mut self, e: &Install) -> Result<()> {
30613 if e.force.is_some() {
30615 self.write_keyword("FORCE");
30616 self.write_space();
30617 }
30618 self.write_keyword("INSTALL");
30619 self.write_space();
30620 self.generate_expression(&e.this)?;
30621 if let Some(from) = &e.from_ {
30622 self.write_space();
30623 self.write_keyword("FROM");
30624 self.write_space();
30625 self.generate_expression(from)?;
30626 }
30627 Ok(())
30628 }
30629
30630 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
30631 self.write_keyword("INTERVAL");
30633 self.write_space();
30634 self.generate_expression(&e.expression)?;
30636 if let Some(unit) = &e.unit {
30637 self.write_space();
30638 self.write(unit);
30639 }
30640 Ok(())
30641 }
30642
30643 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
30644 self.write(&format!("{:?}", e.this).to_ascii_uppercase());
30646 self.write_space();
30647 self.write_keyword("TO");
30648 self.write_space();
30649 self.write(&format!("{:?}", e.expression).to_ascii_uppercase());
30650 Ok(())
30651 }
30652
30653 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
30654 self.write_keyword("INTO");
30656 if e.temporary {
30657 self.write_keyword(" TEMPORARY");
30658 }
30659 if e.unlogged.is_some() {
30660 self.write_keyword(" UNLOGGED");
30661 }
30662 if let Some(this) = &e.this {
30663 self.write_space();
30664 self.generate_expression(this)?;
30665 }
30666 if !e.expressions.is_empty() {
30667 self.write(" (");
30668 for (i, expr) in e.expressions.iter().enumerate() {
30669 if i > 0 {
30670 self.write(", ");
30671 }
30672 self.generate_expression(expr)?;
30673 }
30674 self.write(")");
30675 }
30676 Ok(())
30677 }
30678
30679 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
30680 self.generate_expression(&e.this)?;
30682 self.write_space();
30683 self.generate_expression(&e.expression)?;
30684 Ok(())
30685 }
30686
30687 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
30688 self.write_keyword("WITH");
30690 if e.no.is_some() {
30691 self.write_keyword(" NO");
30692 }
30693 if e.concurrent.is_some() {
30694 self.write_keyword(" CONCURRENT");
30695 }
30696 self.write_keyword(" ISOLATED LOADING");
30697 if let Some(target) = &e.target {
30698 self.write_space();
30699 self.generate_expression(target)?;
30700 }
30701 Ok(())
30702 }
30703
30704 fn generate_json(&mut self, e: &JSON) -> Result<()> {
30705 self.write_keyword("JSON");
30707 if let Some(this) = &e.this {
30708 self.write_space();
30709 self.generate_expression(this)?;
30710 }
30711 if let Some(with_) = &e.with_ {
30712 if let Expression::Boolean(b) = with_.as_ref() {
30714 if b.value {
30715 self.write_keyword(" WITH");
30716 } else {
30717 self.write_keyword(" WITHOUT");
30718 }
30719 }
30720 }
30721 if e.unique {
30722 self.write_keyword(" UNIQUE KEYS");
30723 }
30724 Ok(())
30725 }
30726
30727 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
30728 self.write_keyword("JSON_ARRAY");
30730 self.write("(");
30731 for (i, expr) in e.expressions.iter().enumerate() {
30732 if i > 0 {
30733 self.write(", ");
30734 }
30735 self.generate_expression(expr)?;
30736 }
30737 if let Some(null_handling) = &e.null_handling {
30738 self.write_space();
30739 self.generate_expression(null_handling)?;
30740 }
30741 if let Some(return_type) = &e.return_type {
30742 self.write_space();
30743 self.write_keyword("RETURNING");
30744 self.write_space();
30745 self.generate_expression(return_type)?;
30746 }
30747 if e.strict.is_some() {
30748 self.write_space();
30749 self.write_keyword("STRICT");
30750 }
30751 self.write(")");
30752 Ok(())
30753 }
30754
30755 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
30756 self.write_keyword("JSON_ARRAYAGG");
30758 self.write("(");
30759 self.generate_expression(&e.this)?;
30760 if let Some(order) = &e.order {
30761 self.write_space();
30762 if let Expression::OrderBy(ob) = order.as_ref() {
30764 self.write_keyword("ORDER BY");
30765 self.write_space();
30766 for (i, ord) in ob.expressions.iter().enumerate() {
30767 if i > 0 {
30768 self.write(", ");
30769 }
30770 self.generate_ordered(ord)?;
30771 }
30772 } else {
30773 self.generate_expression(order)?;
30775 }
30776 }
30777 if let Some(null_handling) = &e.null_handling {
30778 self.write_space();
30779 self.generate_expression(null_handling)?;
30780 }
30781 if let Some(return_type) = &e.return_type {
30782 self.write_space();
30783 self.write_keyword("RETURNING");
30784 self.write_space();
30785 self.generate_expression(return_type)?;
30786 }
30787 if e.strict.is_some() {
30788 self.write_space();
30789 self.write_keyword("STRICT");
30790 }
30791 self.write(")");
30792 Ok(())
30793 }
30794
30795 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
30796 self.write_keyword("JSON_OBJECTAGG");
30798 self.write("(");
30799 for (i, expr) in e.expressions.iter().enumerate() {
30800 if i > 0 {
30801 self.write(", ");
30802 }
30803 self.generate_expression(expr)?;
30804 }
30805 if let Some(null_handling) = &e.null_handling {
30806 self.write_space();
30807 self.generate_expression(null_handling)?;
30808 }
30809 if let Some(unique_keys) = &e.unique_keys {
30810 self.write_space();
30811 if let Expression::Boolean(b) = unique_keys.as_ref() {
30812 if b.value {
30813 self.write_keyword("WITH UNIQUE KEYS");
30814 } else {
30815 self.write_keyword("WITHOUT UNIQUE KEYS");
30816 }
30817 }
30818 }
30819 if let Some(return_type) = &e.return_type {
30820 self.write_space();
30821 self.write_keyword("RETURNING");
30822 self.write_space();
30823 self.generate_expression(return_type)?;
30824 }
30825 self.write(")");
30826 Ok(())
30827 }
30828
30829 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
30830 self.write_keyword("JSON_ARRAY_APPEND");
30832 self.write("(");
30833 self.generate_expression(&e.this)?;
30834 for expr in &e.expressions {
30835 self.write(", ");
30836 self.generate_expression(expr)?;
30837 }
30838 self.write(")");
30839 Ok(())
30840 }
30841
30842 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
30843 self.write_keyword("JSON_ARRAY_CONTAINS");
30845 self.write("(");
30846 self.generate_expression(&e.this)?;
30847 self.write(", ");
30848 self.generate_expression(&e.expression)?;
30849 self.write(")");
30850 Ok(())
30851 }
30852
30853 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
30854 self.write_keyword("JSON_ARRAY_INSERT");
30856 self.write("(");
30857 self.generate_expression(&e.this)?;
30858 for expr in &e.expressions {
30859 self.write(", ");
30860 self.generate_expression(expr)?;
30861 }
30862 self.write(")");
30863 Ok(())
30864 }
30865
30866 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
30867 self.write_keyword("JSONB_EXISTS");
30869 self.write("(");
30870 self.generate_expression(&e.this)?;
30871 if let Some(path) = &e.path {
30872 self.write(", ");
30873 self.generate_expression(path)?;
30874 }
30875 self.write(")");
30876 Ok(())
30877 }
30878
30879 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
30880 self.write_keyword("JSONB_EXTRACT_SCALAR");
30882 self.write("(");
30883 self.generate_expression(&e.this)?;
30884 self.write(", ");
30885 self.generate_expression(&e.expression)?;
30886 self.write(")");
30887 Ok(())
30888 }
30889
30890 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
30891 self.write_keyword("JSONB_OBJECT_AGG");
30893 self.write("(");
30894 self.generate_expression(&e.this)?;
30895 self.write(", ");
30896 self.generate_expression(&e.expression)?;
30897 self.write(")");
30898 Ok(())
30899 }
30900
30901 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
30902 if let Some(nested_schema) = &e.nested_schema {
30904 self.write_keyword("NESTED");
30905 if let Some(path) = &e.path {
30906 self.write_space();
30907 self.write_keyword("PATH");
30908 self.write_space();
30909 self.generate_expression(path)?;
30910 }
30911 self.write_space();
30912 self.generate_expression(nested_schema)?;
30913 } else {
30914 if let Some(this) = &e.this {
30915 self.generate_expression(this)?;
30916 }
30917 if let Some(kind) = &e.kind {
30918 self.write_space();
30919 self.write(kind);
30920 }
30921 if e.format_json {
30922 self.write_space();
30923 self.write_keyword("FORMAT JSON");
30924 }
30925 if let Some(path) = &e.path {
30926 self.write_space();
30927 self.write_keyword("PATH");
30928 self.write_space();
30929 self.generate_expression(path)?;
30930 }
30931 if e.ordinality.is_some() {
30932 self.write_keyword(" FOR ORDINALITY");
30933 }
30934 }
30935 Ok(())
30936 }
30937
30938 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
30939 self.write_keyword("JSON_EXISTS");
30941 self.write("(");
30942 self.generate_expression(&e.this)?;
30943 if let Some(path) = &e.path {
30944 self.write(", ");
30945 self.generate_expression(path)?;
30946 }
30947 if let Some(passing) = &e.passing {
30948 self.write_space();
30949 self.write_keyword("PASSING");
30950 self.write_space();
30951 self.generate_expression(passing)?;
30952 }
30953 if let Some(on_condition) = &e.on_condition {
30954 self.write_space();
30955 self.generate_expression(on_condition)?;
30956 }
30957 self.write(")");
30958 Ok(())
30959 }
30960
30961 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
30962 self.generate_expression(&e.this)?;
30963 self.write(".:");
30964 if Self::data_type_has_nested_expressions(&e.to) {
30968 let saved = std::mem::take(&mut self.output);
30970 self.generate_data_type(&e.to)?;
30971 let type_sql = std::mem::replace(&mut self.output, saved);
30972 self.write("\"");
30973 self.write(&type_sql);
30974 self.write("\"");
30975 } else {
30976 self.generate_data_type(&e.to)?;
30977 }
30978 Ok(())
30979 }
30980
30981 fn data_type_has_nested_expressions(dt: &DataType) -> bool {
30984 matches!(
30985 dt,
30986 DataType::Array { .. } | DataType::Map { .. } | DataType::Struct { .. }
30987 )
30988 }
30989
30990 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
30991 self.write_keyword("JSON_EXTRACT_ARRAY");
30993 self.write("(");
30994 self.generate_expression(&e.this)?;
30995 if let Some(expr) = &e.expression {
30996 self.write(", ");
30997 self.generate_expression(expr)?;
30998 }
30999 self.write(")");
31000 Ok(())
31001 }
31002
31003 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
31004 if let Some(option) = &e.option {
31006 self.generate_expression(option)?;
31007 self.write_space();
31008 }
31009 self.write_keyword("QUOTES");
31010 if e.scalar.is_some() {
31011 self.write_keyword(" SCALAR_ONLY");
31012 }
31013 Ok(())
31014 }
31015
31016 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
31017 self.write_keyword("JSON_EXTRACT_SCALAR");
31019 self.write("(");
31020 self.generate_expression(&e.this)?;
31021 self.write(", ");
31022 self.generate_expression(&e.expression)?;
31023 self.write(")");
31024 Ok(())
31025 }
31026
31027 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
31028 if e.variant_extract.is_some() {
31032 use crate::dialects::DialectType;
31033 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
31034 self.generate_expression(&e.this)?;
31038 self.write(":");
31039 match e.expression.as_ref() {
31040 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
31041 let Literal::String(s) = lit.as_ref() else {
31042 unreachable!()
31043 };
31044 self.write_databricks_json_path(s);
31045 }
31046 _ => {
31047 self.generate_expression(&e.expression)?;
31049 }
31050 }
31051 } else {
31052 self.write_keyword("GET_PATH");
31054 self.write("(");
31055 self.generate_expression(&e.this)?;
31056 self.write(", ");
31057 self.generate_expression(&e.expression)?;
31058 self.write(")");
31059 }
31060 } else {
31061 self.write_keyword("JSON_EXTRACT");
31062 self.write("(");
31063 self.generate_expression(&e.this)?;
31064 self.write(", ");
31065 self.generate_expression(&e.expression)?;
31066 for expr in &e.expressions {
31067 self.write(", ");
31068 self.generate_expression(expr)?;
31069 }
31070 self.write(")");
31071 }
31072 Ok(())
31073 }
31074
31075 fn write_databricks_json_path(&mut self, path: &str) {
31079 if path.starts_with("[\"") || path.starts_with("['") {
31082 self.write(path);
31083 return;
31084 }
31085 let mut first = true;
31089 for segment in path.split('.') {
31090 if !first {
31091 self.write(".");
31092 }
31093 first = false;
31094 if let Some(bracket_pos) = segment.find('[') {
31096 let key = &segment[..bracket_pos];
31097 let subscript = &segment[bracket_pos..];
31098 if key.is_empty() {
31099 self.write(segment);
31101 } else if Self::is_safe_json_path_key(key) {
31102 self.write(key);
31103 self.write(subscript);
31104 } else {
31105 self.write("[\"");
31106 self.write(key);
31107 self.write("\"]");
31108 self.write(subscript);
31109 }
31110 } else if Self::is_safe_json_path_key(segment) {
31111 self.write(segment);
31112 } else {
31113 self.write("[\"");
31114 self.write(segment);
31115 self.write("\"]");
31116 }
31117 }
31118 }
31119
31120 fn is_safe_json_path_key(key: &str) -> bool {
31123 if key.is_empty() {
31124 return false;
31125 }
31126 let mut chars = key.chars();
31127 let first = chars.next().unwrap();
31128 if first != '_' && !first.is_ascii_alphabetic() {
31129 return false;
31130 }
31131 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
31132 }
31133
31134 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
31135 if let Some(this) = &e.this {
31138 self.generate_expression(this)?;
31139 self.write_space();
31140 }
31141 self.write_keyword("FORMAT JSON");
31142 Ok(())
31143 }
31144
31145 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
31146 self.generate_expression(&e.this)?;
31148 self.write(": ");
31149 self.generate_expression(&e.expression)?;
31150 Ok(())
31151 }
31152
31153 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
31154 self.write_keyword("JSON_KEYS");
31156 self.write("(");
31157 self.generate_expression(&e.this)?;
31158 if let Some(expr) = &e.expression {
31159 self.write(", ");
31160 self.generate_expression(expr)?;
31161 }
31162 for expr in &e.expressions {
31163 self.write(", ");
31164 self.generate_expression(expr)?;
31165 }
31166 self.write(")");
31167 Ok(())
31168 }
31169
31170 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
31171 self.write_keyword("JSON_KEYS");
31173 self.write("(");
31174 self.generate_expression(&e.this)?;
31175 if let Some(expr) = &e.expression {
31176 self.write(", ");
31177 self.generate_expression(expr)?;
31178 }
31179 self.write(")");
31180 Ok(())
31181 }
31182
31183 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
31184 let mut path_str = String::new();
31187 for expr in &e.expressions {
31188 match expr {
31189 Expression::JSONPathRoot(_) => {
31190 path_str.push('$');
31191 }
31192 Expression::JSONPathKey(k) => {
31193 if let Expression::Literal(lit) = k.this.as_ref() {
31195 if let crate::expressions::Literal::String(s) = lit.as_ref() {
31196 path_str.push('.');
31197 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
31199 if needs_quoting {
31200 path_str.push('"');
31201 path_str.push_str(s);
31202 path_str.push('"');
31203 } else {
31204 path_str.push_str(s);
31205 }
31206 }
31207 }
31208 }
31209 Expression::JSONPathSubscript(s) => {
31210 if let Expression::Literal(lit) = s.this.as_ref() {
31212 if let crate::expressions::Literal::Number(n) = lit.as_ref() {
31213 path_str.push('[');
31214 path_str.push_str(n);
31215 path_str.push(']');
31216 }
31217 }
31218 }
31219 _ => {
31220 let mut temp_gen = Self::with_arc_config(self.config.clone());
31222 temp_gen.generate_expression(expr)?;
31223 path_str.push_str(&temp_gen.output);
31224 }
31225 }
31226 }
31227 self.write("'");
31229 self.write(&path_str);
31230 self.write("'");
31231 Ok(())
31232 }
31233
31234 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
31235 self.write("?(");
31237 self.generate_expression(&e.this)?;
31238 self.write(")");
31239 Ok(())
31240 }
31241
31242 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
31243 self.write(".");
31245 self.generate_expression(&e.this)?;
31246 Ok(())
31247 }
31248
31249 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
31250 self.write("..");
31252 if let Some(this) = &e.this {
31253 self.generate_expression(this)?;
31254 }
31255 Ok(())
31256 }
31257
31258 fn generate_json_path_root(&mut self) -> Result<()> {
31259 self.write("$");
31261 Ok(())
31262 }
31263
31264 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
31265 self.write("(");
31267 self.generate_expression(&e.this)?;
31268 self.write(")");
31269 Ok(())
31270 }
31271
31272 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
31273 self.generate_expression(&e.this)?;
31275 Ok(())
31276 }
31277
31278 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
31279 self.write("[");
31281 if let Some(start) = &e.start {
31282 self.generate_expression(start)?;
31283 }
31284 self.write(":");
31285 if let Some(end) = &e.end {
31286 self.generate_expression(end)?;
31287 }
31288 if let Some(step) = &e.step {
31289 self.write(":");
31290 self.generate_expression(step)?;
31291 }
31292 self.write("]");
31293 Ok(())
31294 }
31295
31296 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
31297 self.write("[");
31299 self.generate_expression(&e.this)?;
31300 self.write("]");
31301 Ok(())
31302 }
31303
31304 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
31305 self.write("[");
31307 for (i, expr) in e.expressions.iter().enumerate() {
31308 if i > 0 {
31309 self.write(", ");
31310 }
31311 self.generate_expression(expr)?;
31312 }
31313 self.write("]");
31314 Ok(())
31315 }
31316
31317 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
31318 self.write_keyword("JSON_REMOVE");
31320 self.write("(");
31321 self.generate_expression(&e.this)?;
31322 for expr in &e.expressions {
31323 self.write(", ");
31324 self.generate_expression(expr)?;
31325 }
31326 self.write(")");
31327 Ok(())
31328 }
31329
31330 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
31331 self.write_keyword("COLUMNS");
31334 self.write("(");
31335
31336 if self.config.pretty && !e.expressions.is_empty() {
31337 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
31339 for expr in &e.expressions {
31340 let mut temp_gen = Generator::with_arc_config(self.config.clone());
31341 temp_gen.generate_expression(expr)?;
31342 expr_strings.push(temp_gen.output);
31343 }
31344
31345 if self.too_wide(&expr_strings) {
31347 self.write_newline();
31349 self.indent_level += 1;
31350 for (i, expr_str) in expr_strings.iter().enumerate() {
31351 if i > 0 {
31352 self.write(",");
31353 self.write_newline();
31354 }
31355 self.write_indent();
31356 self.write(expr_str);
31357 }
31358 self.write_newline();
31359 self.indent_level -= 1;
31360 self.write_indent();
31361 } else {
31362 for (i, expr_str) in expr_strings.iter().enumerate() {
31364 if i > 0 {
31365 self.write(", ");
31366 }
31367 self.write(expr_str);
31368 }
31369 }
31370 } else {
31371 for (i, expr) in e.expressions.iter().enumerate() {
31373 if i > 0 {
31374 self.write(", ");
31375 }
31376 self.generate_expression(expr)?;
31377 }
31378 }
31379 self.write(")");
31380 Ok(())
31381 }
31382
31383 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
31384 self.write_keyword("JSON_SET");
31386 self.write("(");
31387 self.generate_expression(&e.this)?;
31388 for expr in &e.expressions {
31389 self.write(", ");
31390 self.generate_expression(expr)?;
31391 }
31392 self.write(")");
31393 Ok(())
31394 }
31395
31396 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
31397 self.write_keyword("JSON_STRIP_NULLS");
31399 self.write("(");
31400 self.generate_expression(&e.this)?;
31401 if let Some(expr) = &e.expression {
31402 self.write(", ");
31403 self.generate_expression(expr)?;
31404 }
31405 self.write(")");
31406 Ok(())
31407 }
31408
31409 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
31410 self.write_keyword("JSON_TABLE");
31412 self.write("(");
31413 self.generate_expression(&e.this)?;
31414 if let Some(path) = &e.path {
31415 self.write(", ");
31416 self.generate_expression(path)?;
31417 }
31418 if let Some(error_handling) = &e.error_handling {
31419 self.write_space();
31420 self.generate_expression(error_handling)?;
31421 }
31422 if let Some(empty_handling) = &e.empty_handling {
31423 self.write_space();
31424 self.generate_expression(empty_handling)?;
31425 }
31426 if let Some(schema) = &e.schema {
31427 self.write_space();
31428 self.generate_expression(schema)?;
31429 }
31430 self.write(")");
31431 Ok(())
31432 }
31433
31434 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
31435 self.write_keyword("JSON_TYPE");
31437 self.write("(");
31438 self.generate_expression(&e.this)?;
31439 self.write(")");
31440 Ok(())
31441 }
31442
31443 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
31444 self.write_keyword("JSON_VALUE");
31446 self.write("(");
31447 self.generate_expression(&e.this)?;
31448 if let Some(path) = &e.path {
31449 self.write(", ");
31450 self.generate_expression(path)?;
31451 }
31452 if let Some(returning) = &e.returning {
31453 self.write_space();
31454 self.write_keyword("RETURNING");
31455 self.write_space();
31456 self.generate_expression(returning)?;
31457 }
31458 if let Some(on_condition) = &e.on_condition {
31459 self.write_space();
31460 self.generate_expression(on_condition)?;
31461 }
31462 self.write(")");
31463 Ok(())
31464 }
31465
31466 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
31467 self.write_keyword("JSON_VALUE_ARRAY");
31469 self.write("(");
31470 self.generate_expression(&e.this)?;
31471 self.write(")");
31472 Ok(())
31473 }
31474
31475 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
31476 self.write_keyword("JAROWINKLER_SIMILARITY");
31478 self.write("(");
31479 self.generate_expression(&e.this)?;
31480 self.write(", ");
31481 self.generate_expression(&e.expression)?;
31482 self.write(")");
31483 Ok(())
31484 }
31485
31486 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
31487 self.generate_expression(&e.this)?;
31489 self.write("(");
31490 for (i, expr) in e.expressions.iter().enumerate() {
31491 if i > 0 {
31492 self.write(", ");
31493 }
31494 self.generate_expression(expr)?;
31495 }
31496 self.write(")");
31497 Ok(())
31498 }
31499
31500 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
31501 if e.no.is_some() {
31503 self.write_keyword("NO ");
31504 }
31505 if let Some(local) = &e.local {
31506 self.generate_expression(local)?;
31507 self.write_space();
31508 }
31509 if e.dual.is_some() {
31510 self.write_keyword("DUAL ");
31511 }
31512 if e.before.is_some() {
31513 self.write_keyword("BEFORE ");
31514 }
31515 if e.after.is_some() {
31516 self.write_keyword("AFTER ");
31517 }
31518 self.write_keyword("JOURNAL");
31519 Ok(())
31520 }
31521
31522 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
31523 self.write_keyword("LANGUAGE");
31525 self.write_space();
31526 self.generate_expression(&e.this)?;
31527 Ok(())
31528 }
31529
31530 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
31531 if e.view.is_some() {
31533 self.write_keyword("LATERAL VIEW");
31535 if e.outer.is_some() {
31536 self.write_space();
31537 self.write_keyword("OUTER");
31538 }
31539 self.write_space();
31540 self.generate_expression(&e.this)?;
31541 if let Some(alias) = &e.alias {
31542 self.write_space();
31543 self.write(alias);
31544 }
31545 } else {
31546 self.write_keyword("LATERAL");
31548 self.write_space();
31549 self.generate_expression(&e.this)?;
31550 if e.ordinality.is_some() {
31551 self.write_space();
31552 self.write_keyword("WITH ORDINALITY");
31553 }
31554 if let Some(alias) = &e.alias {
31555 self.write_space();
31556 self.write_keyword("AS");
31557 self.write_space();
31558 self.write(alias);
31559 if !e.column_aliases.is_empty() {
31560 self.write("(");
31561 for (i, col) in e.column_aliases.iter().enumerate() {
31562 if i > 0 {
31563 self.write(", ");
31564 }
31565 self.write(col);
31566 }
31567 self.write(")");
31568 }
31569 }
31570 }
31571 Ok(())
31572 }
31573
31574 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
31575 self.write_keyword("LIKE");
31577 self.write_space();
31578 self.generate_expression(&e.this)?;
31579 for expr in &e.expressions {
31580 self.write_space();
31581 self.generate_expression(expr)?;
31582 }
31583 Ok(())
31584 }
31585
31586 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
31587 self.write_keyword("LIMIT");
31588 self.write_space();
31589 self.write_limit_expr(&e.this)?;
31590 if e.percent {
31591 self.write_space();
31592 self.write_keyword("PERCENT");
31593 }
31594 for comment in &e.comments {
31596 self.write(" ");
31597 self.write_formatted_comment(comment);
31598 }
31599 Ok(())
31600 }
31601
31602 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
31603 if e.percent.is_some() {
31605 self.write_keyword(" PERCENT");
31606 }
31607 if e.rows.is_some() {
31608 self.write_keyword(" ROWS");
31609 }
31610 if e.with_ties.is_some() {
31611 self.write_keyword(" WITH TIES");
31612 } else if e.rows.is_some() {
31613 self.write_keyword(" ONLY");
31614 }
31615 Ok(())
31616 }
31617
31618 fn generate_list(&mut self, e: &List) -> Result<()> {
31619 use crate::dialects::DialectType;
31620 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
31621
31622 if e.expressions.len() == 1 {
31624 if let Expression::Select(_) = &e.expressions[0] {
31625 self.write_keyword("LIST");
31626 self.write("(");
31627 self.generate_expression(&e.expressions[0])?;
31628 self.write(")");
31629 return Ok(());
31630 }
31631 }
31632
31633 if is_materialize {
31635 self.write_keyword("LIST");
31636 self.write("[");
31637 for (i, expr) in e.expressions.iter().enumerate() {
31638 if i > 0 {
31639 self.write(", ");
31640 }
31641 self.generate_expression(expr)?;
31642 }
31643 self.write("]");
31644 } else {
31645 self.write_keyword("LIST");
31647 self.write("(");
31648 for (i, expr) in e.expressions.iter().enumerate() {
31649 if i > 0 {
31650 self.write(", ");
31651 }
31652 self.generate_expression(expr)?;
31653 }
31654 self.write(")");
31655 }
31656 Ok(())
31657 }
31658
31659 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
31660 if let Expression::Select(_) = &*e.this {
31662 self.write_keyword("MAP");
31663 self.write("(");
31664 self.generate_expression(&e.this)?;
31665 self.write(")");
31666 return Ok(());
31667 }
31668
31669 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
31670
31671 self.write_keyword("MAP");
31673 if is_duckdb {
31674 self.write(" {");
31675 } else {
31676 self.write("[");
31677 }
31678 if let Expression::Struct(s) = &*e.this {
31679 for (i, (_, expr)) in s.fields.iter().enumerate() {
31680 if i > 0 {
31681 self.write(", ");
31682 }
31683 if let Expression::PropertyEQ(op) = expr {
31684 self.generate_expression(&op.left)?;
31685 if is_duckdb {
31686 self.write(": ");
31687 } else {
31688 self.write(" => ");
31689 }
31690 self.generate_expression(&op.right)?;
31691 } else {
31692 self.generate_expression(expr)?;
31693 }
31694 }
31695 }
31696 if is_duckdb {
31697 self.write("}");
31698 } else {
31699 self.write("]");
31700 }
31701 Ok(())
31702 }
31703
31704 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
31705 self.write_keyword("LOCALTIME");
31707 if let Some(precision) = &e.this {
31708 self.write("(");
31709 self.generate_expression(precision)?;
31710 self.write(")");
31711 }
31712 Ok(())
31713 }
31714
31715 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
31716 self.write_keyword("LOCALTIMESTAMP");
31718 if let Some(precision) = &e.this {
31719 self.write("(");
31720 self.generate_expression(precision)?;
31721 self.write(")");
31722 }
31723 Ok(())
31724 }
31725
31726 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
31727 self.write_keyword("LOCATION");
31729 self.write_space();
31730 self.generate_expression(&e.this)?;
31731 Ok(())
31732 }
31733
31734 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
31735 if e.update.is_some() {
31737 if e.key.is_some() {
31738 self.write_keyword("FOR NO KEY UPDATE");
31739 } else {
31740 self.write_keyword("FOR UPDATE");
31741 }
31742 } else {
31743 if e.key.is_some() {
31744 self.write_keyword("FOR KEY SHARE");
31745 } else {
31746 self.write_keyword("FOR SHARE");
31747 }
31748 }
31749 if !e.expressions.is_empty() {
31750 self.write_keyword(" OF ");
31751 for (i, expr) in e.expressions.iter().enumerate() {
31752 if i > 0 {
31753 self.write(", ");
31754 }
31755 self.generate_expression(expr)?;
31756 }
31757 }
31758 if let Some(wait) = &e.wait {
31763 match wait.as_ref() {
31764 Expression::Boolean(b) => {
31765 if b.value {
31766 self.write_keyword(" NOWAIT");
31767 } else {
31768 self.write_keyword(" SKIP LOCKED");
31769 }
31770 }
31771 _ => {
31772 self.write_keyword(" WAIT ");
31774 self.generate_expression(wait)?;
31775 }
31776 }
31777 }
31778 Ok(())
31779 }
31780
31781 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
31782 self.write_keyword("LOCK");
31784 self.write_space();
31785 self.generate_expression(&e.this)?;
31786 Ok(())
31787 }
31788
31789 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
31790 self.write_keyword("LOCKING");
31792 self.write_space();
31793 self.write(&e.kind);
31794 if let Some(this) = &e.this {
31795 self.write_space();
31796 self.generate_expression(this)?;
31797 }
31798 if let Some(for_or_in) = &e.for_or_in {
31799 self.write_space();
31800 self.generate_expression(for_or_in)?;
31801 }
31802 if let Some(lock_type) = &e.lock_type {
31803 self.write_space();
31804 self.generate_expression(lock_type)?;
31805 }
31806 if e.override_.is_some() {
31807 self.write_keyword(" OVERRIDE");
31808 }
31809 Ok(())
31810 }
31811
31812 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
31813 self.generate_expression(&e.this)?;
31815 self.write_space();
31816 self.generate_expression(&e.expression)?;
31817 Ok(())
31818 }
31819
31820 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
31821 if e.no.is_some() {
31823 self.write_keyword("NO ");
31824 }
31825 self.write_keyword("LOG");
31826 Ok(())
31827 }
31828
31829 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
31830 self.write_keyword("MD5");
31832 self.write("(");
31833 self.generate_expression(&e.this)?;
31834 for expr in &e.expressions {
31835 self.write(", ");
31836 self.generate_expression(expr)?;
31837 }
31838 self.write(")");
31839 Ok(())
31840 }
31841
31842 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
31843 self.write_keyword("ML.FORECAST");
31845 self.write("(");
31846 self.generate_expression(&e.this)?;
31847 if let Some(expression) = &e.expression {
31848 self.write(", ");
31849 self.generate_expression(expression)?;
31850 }
31851 if let Some(params) = &e.params_struct {
31852 self.write(", ");
31853 self.generate_expression(params)?;
31854 }
31855 self.write(")");
31856 Ok(())
31857 }
31858
31859 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
31860 self.write_keyword("ML.TRANSLATE");
31862 self.write("(");
31863 self.generate_expression(&e.this)?;
31864 self.write(", ");
31865 self.generate_expression(&e.expression)?;
31866 if let Some(params) = &e.params_struct {
31867 self.write(", ");
31868 self.generate_expression(params)?;
31869 }
31870 self.write(")");
31871 Ok(())
31872 }
31873
31874 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
31875 self.write_keyword("MAKE_INTERVAL");
31877 self.write("(");
31878 let mut first = true;
31879 if let Some(year) = &e.year {
31880 self.write("years => ");
31881 self.generate_expression(year)?;
31882 first = false;
31883 }
31884 if let Some(month) = &e.month {
31885 if !first {
31886 self.write(", ");
31887 }
31888 self.write("months => ");
31889 self.generate_expression(month)?;
31890 first = false;
31891 }
31892 if let Some(week) = &e.week {
31893 if !first {
31894 self.write(", ");
31895 }
31896 self.write("weeks => ");
31897 self.generate_expression(week)?;
31898 first = false;
31899 }
31900 if let Some(day) = &e.day {
31901 if !first {
31902 self.write(", ");
31903 }
31904 self.write("days => ");
31905 self.generate_expression(day)?;
31906 first = false;
31907 }
31908 if let Some(hour) = &e.hour {
31909 if !first {
31910 self.write(", ");
31911 }
31912 self.write("hours => ");
31913 self.generate_expression(hour)?;
31914 first = false;
31915 }
31916 if let Some(minute) = &e.minute {
31917 if !first {
31918 self.write(", ");
31919 }
31920 self.write("mins => ");
31921 self.generate_expression(minute)?;
31922 first = false;
31923 }
31924 if let Some(second) = &e.second {
31925 if !first {
31926 self.write(", ");
31927 }
31928 self.write("secs => ");
31929 self.generate_expression(second)?;
31930 }
31931 self.write(")");
31932 Ok(())
31933 }
31934
31935 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
31936 self.write_keyword("MANHATTAN_DISTANCE");
31938 self.write("(");
31939 self.generate_expression(&e.this)?;
31940 self.write(", ");
31941 self.generate_expression(&e.expression)?;
31942 self.write(")");
31943 Ok(())
31944 }
31945
31946 fn generate_map(&mut self, e: &Map) -> Result<()> {
31947 self.write_keyword("MAP");
31949 self.write("(");
31950 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
31951 if i > 0 {
31952 self.write(", ");
31953 }
31954 self.generate_expression(key)?;
31955 self.write(", ");
31956 self.generate_expression(value)?;
31957 }
31958 self.write(")");
31959 Ok(())
31960 }
31961
31962 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
31963 self.write_keyword("MAP_CAT");
31965 self.write("(");
31966 self.generate_expression(&e.this)?;
31967 self.write(", ");
31968 self.generate_expression(&e.expression)?;
31969 self.write(")");
31970 Ok(())
31971 }
31972
31973 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
31974 self.write_keyword("MAP_DELETE");
31976 self.write("(");
31977 self.generate_expression(&e.this)?;
31978 for expr in &e.expressions {
31979 self.write(", ");
31980 self.generate_expression(expr)?;
31981 }
31982 self.write(")");
31983 Ok(())
31984 }
31985
31986 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
31987 self.write_keyword("MAP_INSERT");
31989 self.write("(");
31990 self.generate_expression(&e.this)?;
31991 if let Some(key) = &e.key {
31992 self.write(", ");
31993 self.generate_expression(key)?;
31994 }
31995 if let Some(value) = &e.value {
31996 self.write(", ");
31997 self.generate_expression(value)?;
31998 }
31999 if let Some(update_flag) = &e.update_flag {
32000 self.write(", ");
32001 self.generate_expression(update_flag)?;
32002 }
32003 self.write(")");
32004 Ok(())
32005 }
32006
32007 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
32008 self.write_keyword("MAP_PICK");
32010 self.write("(");
32011 self.generate_expression(&e.this)?;
32012 for expr in &e.expressions {
32013 self.write(", ");
32014 self.generate_expression(expr)?;
32015 }
32016 self.write(")");
32017 Ok(())
32018 }
32019
32020 fn generate_masking_policy_column_constraint(
32021 &mut self,
32022 e: &MaskingPolicyColumnConstraint,
32023 ) -> Result<()> {
32024 self.write_keyword("MASKING POLICY");
32026 self.write_space();
32027 self.generate_expression(&e.this)?;
32028 if !e.expressions.is_empty() {
32029 self.write_keyword(" USING");
32030 self.write(" (");
32031 for (i, expr) in e.expressions.iter().enumerate() {
32032 if i > 0 {
32033 self.write(", ");
32034 }
32035 self.generate_expression(expr)?;
32036 }
32037 self.write(")");
32038 }
32039 Ok(())
32040 }
32041
32042 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
32043 if matches!(
32044 self.config.dialect,
32045 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
32046 ) {
32047 if e.expressions.len() > 1 {
32048 self.write("(");
32049 }
32050 for (i, expr) in e.expressions.iter().enumerate() {
32051 if i > 0 {
32052 self.write_keyword(" OR ");
32053 }
32054 self.generate_expression(expr)?;
32055 self.write_space();
32056 self.write("@@");
32057 self.write_space();
32058 self.generate_expression(&e.this)?;
32059 }
32060 if e.expressions.len() > 1 {
32061 self.write(")");
32062 }
32063 return Ok(());
32064 }
32065
32066 self.write_keyword("MATCH");
32068 self.write("(");
32069 for (i, expr) in e.expressions.iter().enumerate() {
32070 if i > 0 {
32071 self.write(", ");
32072 }
32073 self.generate_expression(expr)?;
32074 }
32075 self.write(")");
32076 self.write_keyword(" AGAINST");
32077 self.write("(");
32078 self.generate_expression(&e.this)?;
32079 if let Some(modifier) = &e.modifier {
32080 self.write_space();
32081 self.generate_expression(modifier)?;
32082 }
32083 self.write(")");
32084 Ok(())
32085 }
32086
32087 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
32088 if let Some(window_frame) = &e.window_frame {
32090 self.write(&format!("{:?}", window_frame).to_ascii_uppercase());
32091 self.write_space();
32092 }
32093 self.generate_expression(&e.this)?;
32094 Ok(())
32095 }
32096
32097 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
32098 self.write_keyword("MATERIALIZED");
32100 if let Some(this) = &e.this {
32101 self.write_space();
32102 self.generate_expression(this)?;
32103 }
32104 Ok(())
32105 }
32106
32107 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
32108 if let Some(with_) = &e.with_ {
32111 if let Expression::With(with_clause) = with_.as_ref() {
32112 self.generate_with(with_clause)?;
32113 self.write_space();
32114 } else {
32115 self.generate_expression(with_)?;
32116 self.write_space();
32117 }
32118 }
32119 self.write_keyword("MERGE INTO");
32120 self.write_space();
32121 if matches!(self.config.dialect, Some(crate::DialectType::Oracle)) {
32122 if let Expression::Alias(alias) = e.this.as_ref() {
32123 self.generate_expression(&alias.this)?;
32124 self.write_space();
32125 self.generate_identifier(&alias.alias)?;
32126 } else {
32127 self.generate_expression(&e.this)?;
32128 }
32129 } else {
32130 self.generate_expression(&e.this)?;
32131 }
32132
32133 if self.config.pretty {
32135 self.write_newline();
32136 self.write_indent();
32137 } else {
32138 self.write_space();
32139 }
32140 self.write_keyword("USING");
32141 self.write_space();
32142 self.generate_expression(&e.using)?;
32143
32144 if let Some(on) = &e.on {
32146 if self.config.pretty {
32147 self.write_newline();
32148 self.write_indent();
32149 } else {
32150 self.write_space();
32151 }
32152 self.write_keyword("ON");
32153 self.write_space();
32154 self.generate_expression(on)?;
32155 }
32156 if let Some(using_cond) = &e.using_cond {
32158 self.write_space();
32159 self.write_keyword("USING");
32160 self.write_space();
32161 self.write("(");
32162 if let Expression::Tuple(tuple) = using_cond.as_ref() {
32164 for (i, col) in tuple.expressions.iter().enumerate() {
32165 if i > 0 {
32166 self.write(", ");
32167 }
32168 self.generate_expression(col)?;
32169 }
32170 } else {
32171 self.generate_expression(using_cond)?;
32172 }
32173 self.write(")");
32174 }
32175 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
32177 if matches!(
32178 self.config.dialect,
32179 Some(crate::DialectType::PostgreSQL)
32180 | Some(crate::DialectType::Redshift)
32181 | Some(crate::DialectType::Trino)
32182 | Some(crate::DialectType::Presto)
32183 | Some(crate::DialectType::Athena)
32184 ) {
32185 let mut names = Vec::new();
32186 match e.this.as_ref() {
32187 Expression::Alias(a) => {
32188 if let Expression::Table(t) = &a.this {
32190 names.push(t.name.name.clone());
32191 } else if let Expression::Identifier(id) = &a.this {
32192 names.push(id.name.clone());
32193 }
32194 names.push(a.alias.name.clone());
32195 }
32196 Expression::Table(t) => {
32197 names.push(t.name.name.clone());
32198 }
32199 Expression::Identifier(id) => {
32200 names.push(id.name.clone());
32201 }
32202 _ => {}
32203 }
32204 self.merge_strip_qualifiers = names;
32205 }
32206
32207 if let Some(whens) = &e.whens {
32209 if self.config.pretty {
32210 self.write_newline();
32211 self.write_indent();
32212 } else {
32213 self.write_space();
32214 }
32215 self.generate_expression(whens)?;
32216 }
32217
32218 self.merge_strip_qualifiers = saved_merge_strip;
32220
32221 if let Some(returning) = &e.returning {
32223 if self.config.pretty {
32224 self.write_newline();
32225 self.write_indent();
32226 } else {
32227 self.write_space();
32228 }
32229 self.generate_expression(returning)?;
32230 }
32231 Ok(())
32232 }
32233
32234 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
32235 if e.no.is_some() {
32237 self.write_keyword("NO MERGEBLOCKRATIO");
32238 } else if e.default.is_some() {
32239 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
32240 } else {
32241 self.write_keyword("MERGEBLOCKRATIO");
32242 self.write("=");
32243 if let Some(this) = &e.this {
32244 self.generate_expression(this)?;
32245 }
32246 if e.percent.is_some() {
32247 self.write_keyword(" PERCENT");
32248 }
32249 }
32250 Ok(())
32251 }
32252
32253 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
32254 self.write_keyword("TTL");
32256 let pretty_clickhouse = self.config.pretty
32257 && matches!(
32258 self.config.dialect,
32259 Some(crate::dialects::DialectType::ClickHouse)
32260 );
32261
32262 if pretty_clickhouse {
32263 self.write_newline();
32264 self.indent_level += 1;
32265 for (i, expr) in e.expressions.iter().enumerate() {
32266 if i > 0 {
32267 self.write(",");
32268 self.write_newline();
32269 }
32270 self.write_indent();
32271 self.generate_expression(expr)?;
32272 }
32273 self.indent_level -= 1;
32274 } else {
32275 self.write_space();
32276 for (i, expr) in e.expressions.iter().enumerate() {
32277 if i > 0 {
32278 self.write(", ");
32279 }
32280 self.generate_expression(expr)?;
32281 }
32282 }
32283
32284 if let Some(where_) = &e.where_ {
32285 if pretty_clickhouse {
32286 self.write_newline();
32287 if let Expression::Where(w) = where_.as_ref() {
32288 self.write_indent();
32289 self.write_keyword("WHERE");
32290 self.write_newline();
32291 self.indent_level += 1;
32292 self.write_indent();
32293 self.generate_expression(&w.this)?;
32294 self.indent_level -= 1;
32295 } else {
32296 self.write_indent();
32297 self.generate_expression(where_)?;
32298 }
32299 } else {
32300 self.write_space();
32301 self.generate_expression(where_)?;
32302 }
32303 }
32304 if let Some(group) = &e.group {
32305 if pretty_clickhouse {
32306 self.write_newline();
32307 if let Expression::Group(g) = group.as_ref() {
32308 self.write_indent();
32309 self.write_keyword("GROUP BY");
32310 self.write_newline();
32311 self.indent_level += 1;
32312 for (i, expr) in g.expressions.iter().enumerate() {
32313 if i > 0 {
32314 self.write(",");
32315 self.write_newline();
32316 }
32317 self.write_indent();
32318 self.generate_expression(expr)?;
32319 }
32320 self.indent_level -= 1;
32321 } else {
32322 self.write_indent();
32323 self.generate_expression(group)?;
32324 }
32325 } else {
32326 self.write_space();
32327 self.generate_expression(group)?;
32328 }
32329 }
32330 if let Some(aggregates) = &e.aggregates {
32331 if pretty_clickhouse {
32332 self.write_newline();
32333 self.write_indent();
32334 self.write_keyword("SET");
32335 self.write_newline();
32336 self.indent_level += 1;
32337 if let Expression::Tuple(t) = aggregates.as_ref() {
32338 for (i, agg) in t.expressions.iter().enumerate() {
32339 if i > 0 {
32340 self.write(",");
32341 self.write_newline();
32342 }
32343 self.write_indent();
32344 self.generate_expression(agg)?;
32345 }
32346 } else {
32347 self.write_indent();
32348 self.generate_expression(aggregates)?;
32349 }
32350 self.indent_level -= 1;
32351 } else {
32352 self.write_space();
32353 self.write_keyword("SET");
32354 self.write_space();
32355 if let Expression::Tuple(t) = aggregates.as_ref() {
32356 for (i, agg) in t.expressions.iter().enumerate() {
32357 if i > 0 {
32358 self.write(", ");
32359 }
32360 self.generate_expression(agg)?;
32361 }
32362 } else {
32363 self.generate_expression(aggregates)?;
32364 }
32365 }
32366 }
32367 Ok(())
32368 }
32369
32370 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
32371 self.generate_expression(&e.this)?;
32373 if e.delete.is_some() {
32374 self.write_keyword(" DELETE");
32375 }
32376 if let Some(recompress) = &e.recompress {
32377 self.write_keyword(" RECOMPRESS ");
32378 self.generate_expression(recompress)?;
32379 }
32380 if let Some(to_disk) = &e.to_disk {
32381 self.write_keyword(" TO DISK ");
32382 self.generate_expression(to_disk)?;
32383 }
32384 if let Some(to_volume) = &e.to_volume {
32385 self.write_keyword(" TO VOLUME ");
32386 self.generate_expression(to_volume)?;
32387 }
32388 Ok(())
32389 }
32390
32391 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
32392 self.write_keyword("MINHASH");
32394 self.write("(");
32395 self.generate_expression(&e.this)?;
32396 for expr in &e.expressions {
32397 self.write(", ");
32398 self.generate_expression(expr)?;
32399 }
32400 self.write(")");
32401 Ok(())
32402 }
32403
32404 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
32405 self.generate_expression(&e.this)?;
32407 self.write("!");
32408 self.generate_expression(&e.expression)?;
32409 Ok(())
32410 }
32411
32412 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
32413 self.write_keyword("MONTHNAME");
32415 self.write("(");
32416 self.generate_expression(&e.this)?;
32417 self.write(")");
32418 Ok(())
32419 }
32420
32421 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
32422 for comment in &e.leading_comments {
32424 self.write_formatted_comment(comment);
32425 if self.config.pretty {
32426 self.write_newline();
32427 self.write_indent();
32428 } else {
32429 self.write_space();
32430 }
32431 }
32432 self.write_keyword("INSERT");
32434 if e.overwrite {
32435 self.write_space();
32436 self.write_keyword("OVERWRITE");
32437 }
32438 self.write_space();
32439 self.write(&e.kind);
32440 if self.config.pretty {
32441 self.indent_level += 1;
32442 for expr in &e.expressions {
32443 self.write_newline();
32444 self.write_indent();
32445 self.generate_expression(expr)?;
32446 }
32447 self.indent_level -= 1;
32448 } else {
32449 for expr in &e.expressions {
32450 self.write_space();
32451 self.generate_expression(expr)?;
32452 }
32453 }
32454 if let Some(source) = &e.source {
32455 if self.config.pretty {
32456 self.write_newline();
32457 self.write_indent();
32458 } else {
32459 self.write_space();
32460 }
32461 self.generate_expression(source)?;
32462 }
32463 Ok(())
32464 }
32465
32466 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
32467 self.write_keyword("NEXT VALUE FOR");
32469 self.write_space();
32470 self.generate_expression(&e.this)?;
32471 if let Some(order) = &e.order {
32472 self.write_space();
32473 self.write_keyword("OVER");
32474 self.write(" (");
32475 self.generate_expression(order)?;
32476 self.write(")");
32477 }
32478 Ok(())
32479 }
32480
32481 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
32482 self.write_keyword("NORMAL");
32484 self.write("(");
32485 self.generate_expression(&e.this)?;
32486 if let Some(stddev) = &e.stddev {
32487 self.write(", ");
32488 self.generate_expression(stddev)?;
32489 }
32490 if let Some(gen) = &e.gen {
32491 self.write(", ");
32492 self.generate_expression(gen)?;
32493 }
32494 self.write(")");
32495 Ok(())
32496 }
32497
32498 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
32499 if e.is_casefold.is_some() {
32501 self.write_keyword("NORMALIZE_AND_CASEFOLD");
32502 } else {
32503 self.write_keyword("NORMALIZE");
32504 }
32505 self.write("(");
32506 self.generate_expression(&e.this)?;
32507 if let Some(form) = &e.form {
32508 self.write(", ");
32509 self.generate_expression(form)?;
32510 }
32511 self.write(")");
32512 Ok(())
32513 }
32514
32515 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
32516 if e.allow_null.is_none() {
32518 self.write_keyword("NOT ");
32519 }
32520 self.write_keyword("NULL");
32521 Ok(())
32522 }
32523
32524 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
32525 self.write_keyword("NULLIF");
32527 self.write("(");
32528 self.generate_expression(&e.this)?;
32529 self.write(", ");
32530 self.generate_expression(&e.expression)?;
32531 self.write(")");
32532 Ok(())
32533 }
32534
32535 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
32536 self.write_keyword("FORMAT");
32538 self.write("(");
32539 self.generate_expression(&e.this)?;
32540 self.write(", '");
32541 self.write(&e.format);
32542 self.write("'");
32543 if let Some(culture) = &e.culture {
32544 self.write(", ");
32545 self.generate_expression(culture)?;
32546 }
32547 self.write(")");
32548 Ok(())
32549 }
32550
32551 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
32552 self.write_keyword("OBJECT_AGG");
32554 self.write("(");
32555 self.generate_expression(&e.this)?;
32556 self.write(", ");
32557 self.generate_expression(&e.expression)?;
32558 self.write(")");
32559 Ok(())
32560 }
32561
32562 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
32563 self.generate_expression(&e.this)?;
32565 Ok(())
32566 }
32567
32568 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
32569 self.write_keyword("OBJECT_INSERT");
32571 self.write("(");
32572 self.generate_expression(&e.this)?;
32573 if let Some(key) = &e.key {
32574 self.write(", ");
32575 self.generate_expression(key)?;
32576 }
32577 if let Some(value) = &e.value {
32578 self.write(", ");
32579 self.generate_expression(value)?;
32580 }
32581 if let Some(update_flag) = &e.update_flag {
32582 self.write(", ");
32583 self.generate_expression(update_flag)?;
32584 }
32585 self.write(")");
32586 Ok(())
32587 }
32588
32589 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
32590 self.write_keyword("OFFSET");
32592 self.write_space();
32593 self.generate_expression(&e.this)?;
32594 if e.rows == Some(true)
32596 && matches!(
32597 self.config.dialect,
32598 Some(crate::dialects::DialectType::TSQL)
32599 | Some(crate::dialects::DialectType::Oracle)
32600 )
32601 {
32602 self.write_space();
32603 self.write_keyword("ROWS");
32604 }
32605 Ok(())
32606 }
32607
32608 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
32609 self.write_keyword("QUALIFY");
32611 self.write_space();
32612 self.generate_expression(&e.this)?;
32613 Ok(())
32614 }
32615
32616 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
32617 self.write_keyword("ON CLUSTER");
32619 self.write_space();
32620 self.generate_expression(&e.this)?;
32621 Ok(())
32622 }
32623
32624 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
32625 self.write_keyword("ON COMMIT");
32627 if e.delete.is_some() {
32628 self.write_keyword(" DELETE ROWS");
32629 } else {
32630 self.write_keyword(" PRESERVE ROWS");
32631 }
32632 Ok(())
32633 }
32634
32635 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
32636 if let Some(empty) = &e.empty {
32638 self.generate_expression(empty)?;
32639 self.write_keyword(" ON EMPTY");
32640 }
32641 if let Some(error) = &e.error {
32642 if e.empty.is_some() {
32643 self.write_space();
32644 }
32645 self.generate_expression(error)?;
32646 self.write_keyword(" ON ERROR");
32647 }
32648 if let Some(null) = &e.null {
32649 if e.empty.is_some() || e.error.is_some() {
32650 self.write_space();
32651 }
32652 self.generate_expression(null)?;
32653 self.write_keyword(" ON NULL");
32654 }
32655 Ok(())
32656 }
32657
32658 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
32659 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
32661 return Ok(());
32662 }
32663 if e.duplicate.is_some() {
32665 self.write_keyword("ON DUPLICATE KEY UPDATE");
32667 for (i, expr) in e.expressions.iter().enumerate() {
32668 if i > 0 {
32669 self.write(",");
32670 }
32671 self.write_space();
32672 self.generate_expression(expr)?;
32673 }
32674 return Ok(());
32675 } else {
32676 self.write_keyword("ON CONFLICT");
32677 }
32678 if let Some(constraint) = &e.constraint {
32679 self.write_keyword(" ON CONSTRAINT ");
32680 self.generate_expression(constraint)?;
32681 }
32682 if let Some(conflict_keys) = &e.conflict_keys {
32683 if let Expression::Tuple(t) = conflict_keys.as_ref() {
32685 self.write("(");
32686 for (i, expr) in t.expressions.iter().enumerate() {
32687 if i > 0 {
32688 self.write(", ");
32689 }
32690 self.generate_expression(expr)?;
32691 }
32692 self.write(")");
32693 } else {
32694 self.write("(");
32695 self.generate_expression(conflict_keys)?;
32696 self.write(")");
32697 }
32698 }
32699 if let Some(index_predicate) = &e.index_predicate {
32700 self.write_keyword(" WHERE ");
32701 self.generate_expression(index_predicate)?;
32702 }
32703 if let Some(action) = &e.action {
32704 if let Expression::Identifier(id) = action.as_ref() {
32706 if id.name.eq_ignore_ascii_case("NOTHING") {
32707 self.write_keyword(" DO NOTHING");
32708 } else {
32709 self.write_keyword(" DO ");
32710 self.generate_expression(action)?;
32711 }
32712 } else if let Expression::Tuple(t) = action.as_ref() {
32713 self.write_keyword(" DO UPDATE SET ");
32715 for (i, expr) in t.expressions.iter().enumerate() {
32716 if i > 0 {
32717 self.write(", ");
32718 }
32719 self.generate_expression(expr)?;
32720 }
32721 } else {
32722 self.write_keyword(" DO ");
32723 self.generate_expression(action)?;
32724 }
32725 }
32726 if let Some(where_) = &e.where_ {
32728 self.write_keyword(" WHERE ");
32729 self.generate_expression(where_)?;
32730 }
32731 Ok(())
32732 }
32733
32734 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
32735 self.write_keyword("ON");
32737 self.write_space();
32738 self.generate_expression(&e.this)?;
32739 Ok(())
32740 }
32741
32742 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
32743 self.generate_expression(&e.this)?;
32745 self.write_space();
32746 self.generate_expression(&e.expression)?;
32747 Ok(())
32748 }
32749
32750 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
32751 self.write_keyword("OPENJSON");
32753 self.write("(");
32754 self.generate_expression(&e.this)?;
32755 if let Some(path) = &e.path {
32756 self.write(", ");
32757 self.generate_expression(path)?;
32758 }
32759 self.write(")");
32760 if !e.expressions.is_empty() {
32761 self.write_keyword(" WITH");
32762 if self.config.pretty {
32763 self.write(" (\n");
32764 self.indent_level += 2;
32765 for (i, expr) in e.expressions.iter().enumerate() {
32766 if i > 0 {
32767 self.write(",\n");
32768 }
32769 self.write_indent();
32770 self.generate_expression(expr)?;
32771 }
32772 self.write("\n");
32773 self.indent_level -= 2;
32774 self.write(")");
32775 } else {
32776 self.write(" (");
32777 for (i, expr) in e.expressions.iter().enumerate() {
32778 if i > 0 {
32779 self.write(", ");
32780 }
32781 self.generate_expression(expr)?;
32782 }
32783 self.write(")");
32784 }
32785 }
32786 Ok(())
32787 }
32788
32789 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
32790 self.generate_expression(&e.this)?;
32792 self.write_space();
32793 if let Some(ref dt) = e.data_type {
32795 self.generate_data_type(dt)?;
32796 } else if !e.kind.is_empty() {
32797 self.write(&e.kind);
32798 }
32799 if let Some(path) = &e.path {
32800 self.write_space();
32801 self.generate_expression(path)?;
32802 }
32803 if e.as_json.is_some() {
32804 self.write_keyword(" AS JSON");
32805 }
32806 Ok(())
32807 }
32808
32809 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
32810 self.generate_expression(&e.this)?;
32812 self.write_space();
32813 if let Some(op) = &e.operator {
32814 self.write_keyword("OPERATOR");
32815 self.write("(");
32816 self.generate_expression(op)?;
32817 self.write(")");
32818 }
32819 for comment in &e.comments {
32821 self.write_space();
32822 self.write_formatted_comment(comment);
32823 }
32824 self.write_space();
32825 self.generate_expression(&e.expression)?;
32826 Ok(())
32827 }
32828
32829 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
32830 self.write_keyword("ORDER BY");
32832 let pretty_clickhouse_single_paren = self.config.pretty
32833 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
32834 && e.expressions.len() == 1
32835 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
32836 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
32837 && e.expressions.len() == 1
32838 && matches!(e.expressions[0].this, Expression::Tuple(_))
32839 && !e.expressions[0].desc
32840 && e.expressions[0].nulls_first.is_none();
32841
32842 if pretty_clickhouse_single_paren {
32843 self.write_space();
32844 if let Expression::Paren(p) = &e.expressions[0].this {
32845 self.write("(");
32846 self.write_newline();
32847 self.indent_level += 1;
32848 self.write_indent();
32849 self.generate_expression(&p.this)?;
32850 self.indent_level -= 1;
32851 self.write_newline();
32852 self.write(")");
32853 }
32854 return Ok(());
32855 }
32856
32857 if clickhouse_single_tuple {
32858 self.write_space();
32859 if let Expression::Tuple(t) = &e.expressions[0].this {
32860 self.write("(");
32861 for (i, expr) in t.expressions.iter().enumerate() {
32862 if i > 0 {
32863 self.write(", ");
32864 }
32865 self.generate_expression(expr)?;
32866 }
32867 self.write(")");
32868 }
32869 return Ok(());
32870 }
32871
32872 self.write_space();
32873 for (i, ordered) in e.expressions.iter().enumerate() {
32874 if i > 0 {
32875 self.write(", ");
32876 }
32877 self.generate_expression(&ordered.this)?;
32878 if ordered.desc {
32879 self.write_space();
32880 self.write_keyword("DESC");
32881 } else if ordered.explicit_asc {
32882 self.write_space();
32883 self.write_keyword("ASC");
32884 }
32885 if let Some(nulls_first) = ordered.nulls_first {
32886 let skip_nulls_last =
32888 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
32889 if !skip_nulls_last {
32890 self.write_space();
32891 self.write_keyword("NULLS");
32892 self.write_space();
32893 if nulls_first {
32894 self.write_keyword("FIRST");
32895 } else {
32896 self.write_keyword("LAST");
32897 }
32898 }
32899 }
32900 }
32901 Ok(())
32902 }
32903
32904 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
32905 self.write_keyword("OUTPUT");
32907 self.write("(");
32908 if self.config.pretty {
32909 self.indent_level += 1;
32910 self.write_newline();
32911 self.write_indent();
32912 self.generate_expression(&e.this)?;
32913 self.indent_level -= 1;
32914 self.write_newline();
32915 } else {
32916 self.generate_expression(&e.this)?;
32917 }
32918 self.write(")");
32919 Ok(())
32920 }
32921
32922 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
32923 self.write_keyword("TRUNCATE");
32925 if let Some(this) = &e.this {
32926 self.write_space();
32927 self.generate_expression(this)?;
32928 }
32929 if e.with_count.is_some() {
32930 self.write_keyword(" WITH COUNT");
32931 } else {
32932 self.write_keyword(" WITHOUT COUNT");
32933 }
32934 Ok(())
32935 }
32936
32937 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
32938 self.generate_expression(&e.this)?;
32940 self.write("(");
32941 for (i, expr) in e.expressions.iter().enumerate() {
32942 if i > 0 {
32943 self.write(", ");
32944 }
32945 self.generate_expression(expr)?;
32946 }
32947 self.write(")(");
32948 for (i, param) in e.params.iter().enumerate() {
32949 if i > 0 {
32950 self.write(", ");
32951 }
32952 self.generate_expression(param)?;
32953 }
32954 self.write(")");
32955 Ok(())
32956 }
32957
32958 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
32959 self.write_keyword("PARSE_DATETIME");
32961 self.write("(");
32962 if let Some(format) = &e.format {
32963 self.write("'");
32964 self.write(format);
32965 self.write("', ");
32966 }
32967 self.generate_expression(&e.this)?;
32968 if let Some(zone) = &e.zone {
32969 self.write(", ");
32970 self.generate_expression(zone)?;
32971 }
32972 self.write(")");
32973 Ok(())
32974 }
32975
32976 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
32977 self.write_keyword("PARSE_IP");
32979 self.write("(");
32980 self.generate_expression(&e.this)?;
32981 if let Some(type_) = &e.type_ {
32982 self.write(", ");
32983 self.generate_expression(type_)?;
32984 }
32985 if let Some(permissive) = &e.permissive {
32986 self.write(", ");
32987 self.generate_expression(permissive)?;
32988 }
32989 self.write(")");
32990 Ok(())
32991 }
32992
32993 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
32994 self.write_keyword("PARSE_JSON");
32996 self.write("(");
32997 self.generate_expression(&e.this)?;
32998 if let Some(expression) = &e.expression {
32999 self.write(", ");
33000 self.generate_expression(expression)?;
33001 }
33002 self.write(")");
33003 Ok(())
33004 }
33005
33006 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
33007 self.write_keyword("PARSE_TIME");
33009 self.write("(");
33010 self.write(&format!("'{}'", e.format));
33011 self.write(", ");
33012 self.generate_expression(&e.this)?;
33013 self.write(")");
33014 Ok(())
33015 }
33016
33017 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
33018 self.write_keyword("PARSE_URL");
33020 self.write("(");
33021 self.generate_expression(&e.this)?;
33022 if let Some(part) = &e.part_to_extract {
33023 self.write(", ");
33024 self.generate_expression(part)?;
33025 }
33026 if let Some(key) = &e.key {
33027 self.write(", ");
33028 self.generate_expression(key)?;
33029 }
33030 if let Some(permissive) = &e.permissive {
33031 self.write(", ");
33032 self.generate_expression(permissive)?;
33033 }
33034 self.write(")");
33035 Ok(())
33036 }
33037
33038 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
33039 if e.subpartition {
33041 self.write_keyword("SUBPARTITION");
33042 } else {
33043 self.write_keyword("PARTITION");
33044 }
33045 self.write("(");
33046 for (i, expr) in e.expressions.iter().enumerate() {
33047 if i > 0 {
33048 self.write(", ");
33049 }
33050 self.generate_expression(expr)?;
33051 }
33052 self.write(")");
33053 Ok(())
33054 }
33055
33056 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
33057 if let Some(this) = &e.this {
33059 if let Some(expression) = &e.expression {
33060 self.write_keyword("WITH");
33062 self.write(" (");
33063 self.write_keyword("MODULUS");
33064 self.write_space();
33065 self.generate_expression(this)?;
33066 self.write(", ");
33067 self.write_keyword("REMAINDER");
33068 self.write_space();
33069 self.generate_expression(expression)?;
33070 self.write(")");
33071 } else {
33072 self.write_keyword("IN");
33074 self.write(" (");
33075 self.generate_partition_bound_values(this)?;
33076 self.write(")");
33077 }
33078 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
33079 self.write_keyword("FROM");
33081 self.write(" (");
33082 self.generate_partition_bound_values(from)?;
33083 self.write(") ");
33084 self.write_keyword("TO");
33085 self.write(" (");
33086 self.generate_partition_bound_values(to)?;
33087 self.write(")");
33088 }
33089 Ok(())
33090 }
33091
33092 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
33095 if let Expression::Tuple(t) = expr {
33096 for (i, e) in t.expressions.iter().enumerate() {
33097 if i > 0 {
33098 self.write(", ");
33099 }
33100 self.generate_expression(e)?;
33101 }
33102 Ok(())
33103 } else {
33104 self.generate_expression(expr)
33105 }
33106 }
33107
33108 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
33109 self.write_keyword("PARTITION BY LIST");
33111 if let Some(partition_exprs) = &e.partition_expressions {
33112 self.write(" (");
33113 self.generate_doris_partition_expressions(partition_exprs)?;
33115 self.write(")");
33116 }
33117 if let Some(create_exprs) = &e.create_expressions {
33118 self.write(" (");
33119 self.generate_doris_partition_definitions(create_exprs)?;
33121 self.write(")");
33122 }
33123 Ok(())
33124 }
33125
33126 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
33127 self.write_keyword("PARTITION BY RANGE");
33129 if let Some(partition_exprs) = &e.partition_expressions {
33130 self.write(" (");
33131 self.generate_doris_partition_expressions(partition_exprs)?;
33133 self.write(")");
33134 }
33135 if let Some(create_exprs) = &e.create_expressions {
33136 self.write(" (");
33137 self.generate_doris_partition_definitions(create_exprs)?;
33139 self.write(")");
33140 }
33141 Ok(())
33142 }
33143
33144 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
33146 if let Expression::Tuple(t) = expr {
33147 for (i, e) in t.expressions.iter().enumerate() {
33148 if i > 0 {
33149 self.write(", ");
33150 }
33151 self.generate_expression(e)?;
33152 }
33153 } else {
33154 self.generate_expression(expr)?;
33155 }
33156 Ok(())
33157 }
33158
33159 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
33161 match expr {
33162 Expression::Tuple(t) => {
33163 for (i, part) in t.expressions.iter().enumerate() {
33165 if i > 0 {
33166 self.write(", ");
33167 }
33168 if let Expression::Partition(p) = part {
33170 for (j, inner) in p.expressions.iter().enumerate() {
33171 if j > 0 {
33172 self.write(", ");
33173 }
33174 self.generate_expression(inner)?;
33175 }
33176 } else {
33177 self.generate_expression(part)?;
33178 }
33179 }
33180 }
33181 Expression::PartitionByRangePropertyDynamic(_) => {
33182 self.generate_expression(expr)?;
33184 }
33185 _ => {
33186 self.generate_expression(expr)?;
33187 }
33188 }
33189 Ok(())
33190 }
33191
33192 fn generate_partition_by_range_property_dynamic(
33193 &mut self,
33194 e: &PartitionByRangePropertyDynamic,
33195 ) -> Result<()> {
33196 if e.use_start_end {
33197 if let Some(start) = &e.start {
33199 self.write_keyword("START");
33200 self.write(" (");
33201 self.generate_expression(start)?;
33202 self.write(")");
33203 }
33204 if let Some(end) = &e.end {
33205 self.write_space();
33206 self.write_keyword("END");
33207 self.write(" (");
33208 self.generate_expression(end)?;
33209 self.write(")");
33210 }
33211 if let Some(every) = &e.every {
33212 self.write_space();
33213 self.write_keyword("EVERY");
33214 self.write(" (");
33215 self.generate_doris_interval(every)?;
33217 self.write(")");
33218 }
33219 } else {
33220 if let Some(start) = &e.start {
33222 self.write_keyword("FROM");
33223 self.write(" (");
33224 self.generate_expression(start)?;
33225 self.write(")");
33226 }
33227 if let Some(end) = &e.end {
33228 self.write_space();
33229 self.write_keyword("TO");
33230 self.write(" (");
33231 self.generate_expression(end)?;
33232 self.write(")");
33233 }
33234 if let Some(every) = &e.every {
33235 self.write_space();
33236 self.generate_doris_interval(every)?;
33238 }
33239 }
33240 Ok(())
33241 }
33242
33243 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
33245 if let Expression::Interval(interval) = expr {
33246 self.write_keyword("INTERVAL");
33247 if let Some(ref value) = interval.this {
33248 self.write_space();
33249 match value {
33253 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()) => {
33254 if let Literal::String(s) = lit.as_ref() {
33255 self.write(s);
33256 }
33257 }
33258 _ => {
33259 self.generate_expression(value)?;
33260 }
33261 }
33262 }
33263 if let Some(ref unit_spec) = interval.unit {
33264 self.write_space();
33265 self.write_interval_unit_spec(unit_spec)?;
33266 }
33267 Ok(())
33268 } else {
33269 self.generate_expression(expr)
33270 }
33271 }
33272
33273 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
33274 self.write_keyword("TRUNCATE");
33276 self.write("(");
33277 self.generate_expression(&e.expression)?;
33278 self.write(", ");
33279 self.generate_expression(&e.this)?;
33280 self.write(")");
33281 Ok(())
33282 }
33283
33284 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
33285 self.write_keyword("PARTITION");
33287 self.write_space();
33288 self.generate_expression(&e.this)?;
33289 self.write_space();
33290 self.write_keyword("VALUES IN");
33291 self.write(" (");
33292 for (i, expr) in e.expressions.iter().enumerate() {
33293 if i > 0 {
33294 self.write(", ");
33295 }
33296 self.generate_expression(expr)?;
33297 }
33298 self.write(")");
33299 Ok(())
33300 }
33301
33302 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
33303 if e.expressions.is_empty() && e.expression.is_some() {
33306 self.generate_expression(&e.this)?;
33308 self.write_space();
33309 self.write_keyword("TO");
33310 self.write_space();
33311 self.generate_expression(e.expression.as_ref().unwrap())?;
33312 return Ok(());
33313 }
33314
33315 self.write_keyword("PARTITION");
33317 self.write_space();
33318 self.generate_expression(&e.this)?;
33319 self.write_space();
33320
33321 if e.expressions.len() == 1 {
33323 self.write_keyword("VALUES LESS THAN");
33325 self.write(" (");
33326 self.generate_expression(&e.expressions[0])?;
33327 self.write(")");
33328 } else if !e.expressions.is_empty() {
33329 self.write_keyword("VALUES");
33331 self.write(" [");
33332 for (i, expr) in e.expressions.iter().enumerate() {
33333 if i > 0 {
33334 self.write(", ");
33335 }
33336 if let Expression::Tuple(t) = expr {
33338 self.write("(");
33339 for (j, inner) in t.expressions.iter().enumerate() {
33340 if j > 0 {
33341 self.write(", ");
33342 }
33343 self.generate_expression(inner)?;
33344 }
33345 self.write(")");
33346 } else {
33347 self.write("(");
33348 self.generate_expression(expr)?;
33349 self.write(")");
33350 }
33351 }
33352 self.write(")");
33353 }
33354 Ok(())
33355 }
33356
33357 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
33358 self.write_keyword("BUCKET");
33360 self.write("(");
33361 self.generate_expression(&e.this)?;
33362 self.write(", ");
33363 self.generate_expression(&e.expression)?;
33364 self.write(")");
33365 Ok(())
33366 }
33367
33368 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
33369 self.write_keyword("PARTITION BY");
33371 self.write_space();
33372 for (i, expr) in e.expressions.iter().enumerate() {
33373 if i > 0 {
33374 self.write(", ");
33375 }
33376 self.generate_expression(expr)?;
33377 }
33378 Ok(())
33379 }
33380
33381 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
33382 if matches!(
33384 self.config.dialect,
33385 Some(crate::dialects::DialectType::Teradata)
33386 | Some(crate::dialects::DialectType::ClickHouse)
33387 ) {
33388 self.write_keyword("PARTITION BY");
33389 } else {
33390 self.write_keyword("PARTITIONED BY");
33391 }
33392 self.write_space();
33393 if self.config.pretty {
33395 if let Expression::Tuple(ref tuple) = *e.this {
33396 self.write("(");
33397 self.write_newline();
33398 self.indent_level += 1;
33399 for (i, expr) in tuple.expressions.iter().enumerate() {
33400 if i > 0 {
33401 self.write(",");
33402 self.write_newline();
33403 }
33404 self.write_indent();
33405 self.generate_expression(expr)?;
33406 }
33407 self.indent_level -= 1;
33408 self.write_newline();
33409 self.write(")");
33410 } else {
33411 self.generate_expression(&e.this)?;
33412 }
33413 } else {
33414 self.generate_expression(&e.this)?;
33415 }
33416 Ok(())
33417 }
33418
33419 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
33420 self.write_keyword("PARTITION OF");
33422 self.write_space();
33423 self.generate_expression(&e.this)?;
33424 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
33426 self.write_space();
33427 self.write_keyword("FOR VALUES");
33428 self.write_space();
33429 self.generate_expression(&e.expression)?;
33430 } else {
33431 self.write_space();
33432 self.write_keyword("DEFAULT");
33433 }
33434 Ok(())
33435 }
33436
33437 fn generate_period_for_system_time_constraint(
33438 &mut self,
33439 e: &PeriodForSystemTimeConstraint,
33440 ) -> Result<()> {
33441 self.write_keyword("PERIOD FOR SYSTEM_TIME");
33443 self.write(" (");
33444 self.generate_expression(&e.this)?;
33445 self.write(", ");
33446 self.generate_expression(&e.expression)?;
33447 self.write(")");
33448 Ok(())
33449 }
33450
33451 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
33452 self.generate_expression(&e.this)?;
33455 self.write_space();
33456 self.write_keyword("AS");
33457 self.write_space();
33458 if self.config.unpivot_aliases_are_identifiers {
33460 match &e.alias {
33461 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
33462 let Literal::String(s) = lit.as_ref() else {
33463 unreachable!()
33464 };
33465 self.generate_identifier(&Identifier::new(s.clone()))?;
33467 }
33468 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
33469 let Literal::Number(n) = lit.as_ref() else {
33470 unreachable!()
33471 };
33472 let mut id = Identifier::new(n.clone());
33474 id.quoted = true;
33475 self.generate_identifier(&id)?;
33476 }
33477 other => {
33478 self.generate_expression(other)?;
33479 }
33480 }
33481 } else {
33482 self.generate_expression(&e.alias)?;
33483 }
33484 Ok(())
33485 }
33486
33487 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
33488 self.write_keyword("ANY");
33490 if let Some(this) = &e.this {
33491 self.write_space();
33492 self.generate_expression(this)?;
33493 }
33494 Ok(())
33495 }
33496
33497 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
33498 self.write_keyword("ML.PREDICT");
33500 self.write("(");
33501 self.write_keyword("MODEL");
33502 self.write_space();
33503 self.generate_expression(&e.this)?;
33504 self.write(", ");
33505 self.generate_expression(&e.expression)?;
33506 if let Some(params) = &e.params_struct {
33507 self.write(", ");
33508 self.generate_expression(params)?;
33509 }
33510 self.write(")");
33511 Ok(())
33512 }
33513
33514 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
33515 self.write_keyword("PREVIOUS_DAY");
33517 self.write("(");
33518 self.generate_expression(&e.this)?;
33519 self.write(", ");
33520 self.generate_expression(&e.expression)?;
33521 self.write(")");
33522 Ok(())
33523 }
33524
33525 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
33526 self.write_keyword("PRIMARY KEY");
33528 if let Some(name) = &e.this {
33529 self.write_space();
33530 self.generate_expression(name)?;
33531 }
33532 if !e.expressions.is_empty() {
33533 self.write(" (");
33534 for (i, expr) in e.expressions.iter().enumerate() {
33535 if i > 0 {
33536 self.write(", ");
33537 }
33538 self.generate_expression(expr)?;
33539 }
33540 self.write(")");
33541 }
33542 if let Some(include) = &e.include {
33543 self.write_space();
33544 self.generate_expression(include)?;
33545 }
33546 if !e.options.is_empty() {
33547 self.write_space();
33548 for (i, opt) in e.options.iter().enumerate() {
33549 if i > 0 {
33550 self.write_space();
33551 }
33552 self.generate_expression(opt)?;
33553 }
33554 }
33555 Ok(())
33556 }
33557
33558 fn generate_primary_key_column_constraint(
33559 &mut self,
33560 _e: &PrimaryKeyColumnConstraint,
33561 ) -> Result<()> {
33562 self.write_keyword("PRIMARY KEY");
33564 Ok(())
33565 }
33566
33567 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
33568 self.write_keyword("PATH");
33570 self.write_space();
33571 self.generate_expression(&e.this)?;
33572 Ok(())
33573 }
33574
33575 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
33576 self.write_keyword("PROJECTION");
33578 self.write_space();
33579 self.generate_expression(&e.this)?;
33580 self.write(" (");
33581 self.generate_expression(&e.expression)?;
33582 self.write(")");
33583 Ok(())
33584 }
33585
33586 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
33587 for (i, prop) in e.expressions.iter().enumerate() {
33589 if i > 0 {
33590 self.write(", ");
33591 }
33592 self.generate_expression(prop)?;
33593 }
33594 Ok(())
33595 }
33596
33597 fn generate_property(&mut self, e: &Property) -> Result<()> {
33598 self.generate_expression(&e.this)?;
33600 if let Some(value) = &e.value {
33601 self.write("=");
33602 self.generate_expression(value)?;
33603 }
33604 Ok(())
33605 }
33606
33607 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
33608 self.write_keyword("OPTIONS");
33609 if e.entries.is_empty() {
33610 self.write(" ()");
33611 return Ok(());
33612 }
33613
33614 if self.config.pretty {
33615 self.write(" (");
33616 self.write_newline();
33617 self.indent_level += 1;
33618 for (i, entry) in e.entries.iter().enumerate() {
33619 if i > 0 {
33620 self.write(",");
33621 self.write_newline();
33622 }
33623 self.write_indent();
33624 self.generate_identifier(&entry.key)?;
33625 self.write("=");
33626 self.generate_expression(&entry.value)?;
33627 }
33628 self.indent_level -= 1;
33629 self.write_newline();
33630 self.write(")");
33631 } else {
33632 self.write(" (");
33633 for (i, entry) in e.entries.iter().enumerate() {
33634 if i > 0 {
33635 self.write(", ");
33636 }
33637 self.generate_identifier(&entry.key)?;
33638 self.write("=");
33639 self.generate_expression(&entry.value)?;
33640 }
33641 self.write(")");
33642 }
33643 Ok(())
33644 }
33645
33646 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
33648 self.write_keyword("OPTIONS");
33649 self.write(" (");
33650 for (i, opt) in options.iter().enumerate() {
33651 if i > 0 {
33652 self.write(", ");
33653 }
33654 self.generate_option_expression(opt)?;
33655 }
33656 self.write(")");
33657 Ok(())
33658 }
33659
33660 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
33662 self.write_keyword("PROPERTIES");
33663 self.write(" (");
33664 for (i, prop) in properties.iter().enumerate() {
33665 if i > 0 {
33666 self.write(", ");
33667 }
33668 self.generate_option_expression(prop)?;
33669 }
33670 self.write(")");
33671 Ok(())
33672 }
33673
33674 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
33676 self.write_keyword("ENVIRONMENT");
33677 self.write(" (");
33678 for (i, env_item) in environment.iter().enumerate() {
33679 if i > 0 {
33680 self.write(", ");
33681 }
33682 self.generate_environment_expression(env_item)?;
33683 }
33684 self.write(")");
33685 Ok(())
33686 }
33687
33688 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
33690 match expr {
33691 Expression::Eq(eq) => {
33692 self.generate_expression(&eq.left)?;
33694 self.write(" = ");
33695 self.generate_expression(&eq.right)?;
33696 Ok(())
33697 }
33698 _ => self.generate_expression(expr),
33699 }
33700 }
33701
33702 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
33704 self.write_keyword("TBLPROPERTIES");
33705 if self.config.pretty {
33706 self.write(" (");
33707 self.write_newline();
33708 self.indent_level += 1;
33709 for (i, opt) in options.iter().enumerate() {
33710 if i > 0 {
33711 self.write(",");
33712 self.write_newline();
33713 }
33714 self.write_indent();
33715 self.generate_option_expression(opt)?;
33716 }
33717 self.indent_level -= 1;
33718 self.write_newline();
33719 self.write(")");
33720 } else {
33721 self.write(" (");
33722 for (i, opt) in options.iter().enumerate() {
33723 if i > 0 {
33724 self.write(", ");
33725 }
33726 self.generate_option_expression(opt)?;
33727 }
33728 self.write(")");
33729 }
33730 Ok(())
33731 }
33732
33733 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
33735 match expr {
33736 Expression::Eq(eq) => {
33737 self.generate_expression(&eq.left)?;
33739 self.write("=");
33740 self.generate_expression(&eq.right)?;
33741 Ok(())
33742 }
33743 _ => self.generate_expression(expr),
33744 }
33745 }
33746
33747 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
33748 self.generate_expression(&e.this)?;
33750 Ok(())
33751 }
33752
33753 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
33754 self.write_keyword("PUT");
33756 self.write_space();
33757
33758 if e.source_quoted {
33760 self.write("'");
33761 self.write(&e.source);
33762 self.write("'");
33763 } else {
33764 self.write(&e.source);
33765 }
33766
33767 self.write_space();
33768
33769 if let Expression::Literal(lit) = &e.target {
33771 if let Literal::String(s) = lit.as_ref() {
33772 self.write(s);
33773 }
33774 } else {
33775 self.generate_expression(&e.target)?;
33776 }
33777
33778 for param in &e.params {
33780 self.write_space();
33781 self.write(¶m.name);
33782 if let Some(ref value) = param.value {
33783 self.write("=");
33784 self.generate_expression(value)?;
33785 }
33786 }
33787
33788 Ok(())
33789 }
33790
33791 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
33792 self.write_keyword("QUANTILE");
33794 self.write("(");
33795 self.generate_expression(&e.this)?;
33796 if let Some(quantile) = &e.quantile {
33797 self.write(", ");
33798 self.generate_expression(quantile)?;
33799 }
33800 self.write(")");
33801 Ok(())
33802 }
33803
33804 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
33805 if matches!(
33807 self.config.dialect,
33808 Some(crate::dialects::DialectType::Teradata)
33809 ) {
33810 self.write_keyword("SET");
33811 self.write_space();
33812 }
33813 self.write_keyword("QUERY_BAND");
33814 self.write(" = ");
33815 self.generate_expression(&e.this)?;
33816 if e.update.is_some() {
33817 self.write_space();
33818 self.write_keyword("UPDATE");
33819 }
33820 if let Some(scope) = &e.scope {
33821 self.write_space();
33822 self.write_keyword("FOR");
33823 self.write_space();
33824 self.generate_expression(scope)?;
33825 }
33826 Ok(())
33827 }
33828
33829 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
33830 self.generate_expression(&e.this)?;
33832 if let Some(expression) = &e.expression {
33833 self.write(" = ");
33834 self.generate_expression(expression)?;
33835 }
33836 Ok(())
33837 }
33838
33839 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
33840 self.write_keyword("TRANSFORM");
33842 self.write("(");
33843 for (i, expr) in e.expressions.iter().enumerate() {
33844 if i > 0 {
33845 self.write(", ");
33846 }
33847 self.generate_expression(expr)?;
33848 }
33849 self.write(")");
33850 if let Some(row_format_before) = &e.row_format_before {
33851 self.write_space();
33852 self.generate_expression(row_format_before)?;
33853 }
33854 if let Some(record_writer) = &e.record_writer {
33855 self.write_space();
33856 self.write_keyword("RECORDWRITER");
33857 self.write_space();
33858 self.generate_expression(record_writer)?;
33859 }
33860 if let Some(command_script) = &e.command_script {
33861 self.write_space();
33862 self.write_keyword("USING");
33863 self.write_space();
33864 self.generate_expression(command_script)?;
33865 }
33866 if let Some(schema) = &e.schema {
33867 self.write_space();
33868 self.write_keyword("AS");
33869 self.write_space();
33870 self.generate_expression(schema)?;
33871 }
33872 if let Some(row_format_after) = &e.row_format_after {
33873 self.write_space();
33874 self.generate_expression(row_format_after)?;
33875 }
33876 if let Some(record_reader) = &e.record_reader {
33877 self.write_space();
33878 self.write_keyword("RECORDREADER");
33879 self.write_space();
33880 self.generate_expression(record_reader)?;
33881 }
33882 Ok(())
33883 }
33884
33885 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
33886 self.write_keyword("RANDN");
33888 self.write("(");
33889 if let Some(this) = &e.this {
33890 self.generate_expression(this)?;
33891 }
33892 self.write(")");
33893 Ok(())
33894 }
33895
33896 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
33897 self.write_keyword("RANDSTR");
33899 self.write("(");
33900 self.generate_expression(&e.this)?;
33901 if let Some(generator) = &e.generator {
33902 self.write(", ");
33903 self.generate_expression(generator)?;
33904 }
33905 self.write(")");
33906 Ok(())
33907 }
33908
33909 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
33910 self.write_keyword("RANGE_BUCKET");
33912 self.write("(");
33913 self.generate_expression(&e.this)?;
33914 self.write(", ");
33915 self.generate_expression(&e.expression)?;
33916 self.write(")");
33917 Ok(())
33918 }
33919
33920 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
33921 self.write_keyword("RANGE_N");
33923 self.write("(");
33924 self.generate_expression(&e.this)?;
33925 self.write_space();
33926 self.write_keyword("BETWEEN");
33927 self.write_space();
33928 for (i, expr) in e.expressions.iter().enumerate() {
33929 if i > 0 {
33930 self.write(", ");
33931 }
33932 self.generate_expression(expr)?;
33933 }
33934 if let Some(each) = &e.each {
33935 self.write_space();
33936 self.write_keyword("EACH");
33937 self.write_space();
33938 self.generate_expression(each)?;
33939 }
33940 self.write(")");
33941 Ok(())
33942 }
33943
33944 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
33945 self.write_keyword("READ_CSV");
33947 self.write("(");
33948 self.generate_expression(&e.this)?;
33949 for expr in &e.expressions {
33950 self.write(", ");
33951 self.generate_expression(expr)?;
33952 }
33953 self.write(")");
33954 Ok(())
33955 }
33956
33957 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
33958 self.write_keyword("READ_PARQUET");
33960 self.write("(");
33961 for (i, expr) in e.expressions.iter().enumerate() {
33962 if i > 0 {
33963 self.write(", ");
33964 }
33965 self.generate_expression(expr)?;
33966 }
33967 self.write(")");
33968 Ok(())
33969 }
33970
33971 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
33972 if e.kind == "CYCLE" {
33975 self.write_keyword("CYCLE");
33976 } else {
33977 self.write_keyword("SEARCH");
33978 self.write_space();
33979 self.write(&e.kind);
33980 self.write_space();
33981 self.write_keyword("FIRST BY");
33982 }
33983 self.write_space();
33984 self.generate_expression(&e.this)?;
33985 self.write_space();
33986 self.write_keyword("SET");
33987 self.write_space();
33988 self.generate_expression(&e.expression)?;
33989 if let Some(using) = &e.using {
33990 self.write_space();
33991 self.write_keyword("USING");
33992 self.write_space();
33993 self.generate_expression(using)?;
33994 }
33995 Ok(())
33996 }
33997
33998 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
33999 self.write_keyword("REDUCE");
34001 self.write("(");
34002 self.generate_expression(&e.this)?;
34003 if let Some(initial) = &e.initial {
34004 self.write(", ");
34005 self.generate_expression(initial)?;
34006 }
34007 if let Some(merge) = &e.merge {
34008 self.write(", ");
34009 self.generate_expression(merge)?;
34010 }
34011 if let Some(finish) = &e.finish {
34012 self.write(", ");
34013 self.generate_expression(finish)?;
34014 }
34015 self.write(")");
34016 Ok(())
34017 }
34018
34019 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
34020 self.write_keyword("REFERENCES");
34022 self.write_space();
34023 self.generate_expression(&e.this)?;
34024 if !e.expressions.is_empty() {
34025 self.write(" (");
34026 for (i, expr) in e.expressions.iter().enumerate() {
34027 if i > 0 {
34028 self.write(", ");
34029 }
34030 self.generate_expression(expr)?;
34031 }
34032 self.write(")");
34033 }
34034 for opt in &e.options {
34035 self.write_space();
34036 self.generate_expression(opt)?;
34037 }
34038 Ok(())
34039 }
34040
34041 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
34042 self.write_keyword("REFRESH");
34044 if !e.kind.is_empty() {
34045 self.write_space();
34046 self.write_keyword(&e.kind);
34047 }
34048 self.write_space();
34049 self.generate_expression(&e.this)?;
34050 Ok(())
34051 }
34052
34053 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
34054 self.write_keyword("REFRESH");
34056 self.write_space();
34057 self.write_keyword(&e.method);
34058
34059 if let Some(ref kind) = e.kind {
34060 self.write_space();
34061 self.write_keyword("ON");
34062 self.write_space();
34063 self.write_keyword(kind);
34064
34065 if let Some(ref every) = e.every {
34067 self.write_space();
34068 self.write_keyword("EVERY");
34069 self.write_space();
34070 self.generate_expression(every)?;
34071 if let Some(ref unit) = e.unit {
34072 self.write_space();
34073 self.write_keyword(unit);
34074 }
34075 }
34076
34077 if let Some(ref starts) = e.starts {
34079 self.write_space();
34080 self.write_keyword("STARTS");
34081 self.write_space();
34082 self.generate_expression(starts)?;
34083 }
34084 }
34085 Ok(())
34086 }
34087
34088 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
34089 self.write_keyword("REGEXP_COUNT");
34091 self.write("(");
34092 self.generate_expression(&e.this)?;
34093 self.write(", ");
34094 self.generate_expression(&e.expression)?;
34095 if let Some(position) = &e.position {
34096 self.write(", ");
34097 self.generate_expression(position)?;
34098 }
34099 if let Some(parameters) = &e.parameters {
34100 self.write(", ");
34101 self.generate_expression(parameters)?;
34102 }
34103 self.write(")");
34104 Ok(())
34105 }
34106
34107 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
34108 self.write_keyword("REGEXP_EXTRACT_ALL");
34110 self.write("(");
34111 self.generate_expression(&e.this)?;
34112 self.write(", ");
34113 self.generate_expression(&e.expression)?;
34114 if let Some(group) = &e.group {
34115 self.write(", ");
34116 self.generate_expression(group)?;
34117 }
34118 self.write(")");
34119 Ok(())
34120 }
34121
34122 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
34123 self.write_keyword("REGEXP_FULL_MATCH");
34125 self.write("(");
34126 self.generate_expression(&e.this)?;
34127 self.write(", ");
34128 self.generate_expression(&e.expression)?;
34129 self.write(")");
34130 Ok(())
34131 }
34132
34133 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
34134 use crate::dialects::DialectType;
34135 if matches!(
34137 self.config.dialect,
34138 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
34139 ) && e.flag.is_none()
34140 {
34141 self.generate_expression(&e.this)?;
34142 self.write(" ~* ");
34143 self.generate_expression(&e.expression)?;
34144 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
34145 self.write_keyword("REGEXP_LIKE");
34147 self.write("(");
34148 self.generate_expression(&e.this)?;
34149 self.write(", ");
34150 self.generate_expression(&e.expression)?;
34151 self.write(", ");
34152 if let Some(flag) = &e.flag {
34153 self.generate_expression(flag)?;
34154 } else {
34155 self.write("'i'");
34156 }
34157 self.write(")");
34158 } else {
34159 self.generate_expression(&e.this)?;
34161 self.write_space();
34162 self.write_keyword("REGEXP_ILIKE");
34163 self.write_space();
34164 self.generate_expression(&e.expression)?;
34165 if let Some(flag) = &e.flag {
34166 self.write(", ");
34167 self.generate_expression(flag)?;
34168 }
34169 }
34170 Ok(())
34171 }
34172
34173 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
34174 self.write_keyword("REGEXP_INSTR");
34176 self.write("(");
34177 self.generate_expression(&e.this)?;
34178 self.write(", ");
34179 self.generate_expression(&e.expression)?;
34180 if let Some(position) = &e.position {
34181 self.write(", ");
34182 self.generate_expression(position)?;
34183 }
34184 if let Some(occurrence) = &e.occurrence {
34185 self.write(", ");
34186 self.generate_expression(occurrence)?;
34187 }
34188 if let Some(option) = &e.option {
34189 self.write(", ");
34190 self.generate_expression(option)?;
34191 }
34192 if let Some(parameters) = &e.parameters {
34193 self.write(", ");
34194 self.generate_expression(parameters)?;
34195 }
34196 if let Some(group) = &e.group {
34197 self.write(", ");
34198 self.generate_expression(group)?;
34199 }
34200 self.write(")");
34201 Ok(())
34202 }
34203
34204 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
34205 self.write_keyword("REGEXP_SPLIT");
34207 self.write("(");
34208 self.generate_expression(&e.this)?;
34209 self.write(", ");
34210 self.generate_expression(&e.expression)?;
34211 if let Some(limit) = &e.limit {
34212 self.write(", ");
34213 self.generate_expression(limit)?;
34214 }
34215 self.write(")");
34216 Ok(())
34217 }
34218
34219 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
34220 self.write_keyword("REGR_AVGX");
34222 self.write("(");
34223 self.generate_expression(&e.this)?;
34224 self.write(", ");
34225 self.generate_expression(&e.expression)?;
34226 self.write(")");
34227 Ok(())
34228 }
34229
34230 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
34231 self.write_keyword("REGR_AVGY");
34233 self.write("(");
34234 self.generate_expression(&e.this)?;
34235 self.write(", ");
34236 self.generate_expression(&e.expression)?;
34237 self.write(")");
34238 Ok(())
34239 }
34240
34241 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
34242 self.write_keyword("REGR_COUNT");
34244 self.write("(");
34245 self.generate_expression(&e.this)?;
34246 self.write(", ");
34247 self.generate_expression(&e.expression)?;
34248 self.write(")");
34249 Ok(())
34250 }
34251
34252 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
34253 self.write_keyword("REGR_INTERCEPT");
34255 self.write("(");
34256 self.generate_expression(&e.this)?;
34257 self.write(", ");
34258 self.generate_expression(&e.expression)?;
34259 self.write(")");
34260 Ok(())
34261 }
34262
34263 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
34264 self.write_keyword("REGR_R2");
34266 self.write("(");
34267 self.generate_expression(&e.this)?;
34268 self.write(", ");
34269 self.generate_expression(&e.expression)?;
34270 self.write(")");
34271 Ok(())
34272 }
34273
34274 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
34275 self.write_keyword("REGR_SLOPE");
34277 self.write("(");
34278 self.generate_expression(&e.this)?;
34279 self.write(", ");
34280 self.generate_expression(&e.expression)?;
34281 self.write(")");
34282 Ok(())
34283 }
34284
34285 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
34286 self.write_keyword("REGR_SXX");
34288 self.write("(");
34289 self.generate_expression(&e.this)?;
34290 self.write(", ");
34291 self.generate_expression(&e.expression)?;
34292 self.write(")");
34293 Ok(())
34294 }
34295
34296 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
34297 self.write_keyword("REGR_SXY");
34299 self.write("(");
34300 self.generate_expression(&e.this)?;
34301 self.write(", ");
34302 self.generate_expression(&e.expression)?;
34303 self.write(")");
34304 Ok(())
34305 }
34306
34307 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
34308 self.write_keyword("REGR_SYY");
34310 self.write("(");
34311 self.generate_expression(&e.this)?;
34312 self.write(", ");
34313 self.generate_expression(&e.expression)?;
34314 self.write(")");
34315 Ok(())
34316 }
34317
34318 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
34319 self.write_keyword("REGR_VALX");
34321 self.write("(");
34322 self.generate_expression(&e.this)?;
34323 self.write(", ");
34324 self.generate_expression(&e.expression)?;
34325 self.write(")");
34326 Ok(())
34327 }
34328
34329 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
34330 self.write_keyword("REGR_VALY");
34332 self.write("(");
34333 self.generate_expression(&e.this)?;
34334 self.write(", ");
34335 self.generate_expression(&e.expression)?;
34336 self.write(")");
34337 Ok(())
34338 }
34339
34340 fn generate_remote_with_connection_model_property(
34341 &mut self,
34342 e: &RemoteWithConnectionModelProperty,
34343 ) -> Result<()> {
34344 self.write_keyword("REMOTE WITH CONNECTION");
34346 self.write_space();
34347 self.generate_expression(&e.this)?;
34348 Ok(())
34349 }
34350
34351 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
34352 self.write_keyword("RENAME COLUMN");
34354 if e.exists {
34355 self.write_space();
34356 self.write_keyword("IF EXISTS");
34357 }
34358 self.write_space();
34359 self.generate_expression(&e.this)?;
34360 if let Some(to) = &e.to {
34361 self.write_space();
34362 self.write_keyword("TO");
34363 self.write_space();
34364 self.generate_expression(to)?;
34365 }
34366 Ok(())
34367 }
34368
34369 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
34370 self.write_keyword("REPLACE PARTITION");
34372 self.write_space();
34373 self.generate_expression(&e.expression)?;
34374 if let Some(source) = &e.source {
34375 self.write_space();
34376 self.write_keyword("FROM");
34377 self.write_space();
34378 self.generate_expression(source)?;
34379 }
34380 Ok(())
34381 }
34382
34383 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
34384 let keyword = match self.config.dialect {
34387 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
34388 _ => "RETURNING",
34389 };
34390 self.write_keyword(keyword);
34391 self.write_space();
34392 for (i, expr) in e.expressions.iter().enumerate() {
34393 if i > 0 {
34394 self.write(", ");
34395 }
34396 self.generate_expression(expr)?;
34397 }
34398 if let Some(into) = &e.into {
34399 self.write_space();
34400 self.write_keyword("INTO");
34401 self.write_space();
34402 self.generate_expression(into)?;
34403 }
34404 Ok(())
34405 }
34406
34407 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
34408 self.write_space();
34410 self.write_keyword("OUTPUT");
34411 self.write_space();
34412 for (i, expr) in output.columns.iter().enumerate() {
34413 if i > 0 {
34414 self.write(", ");
34415 }
34416 self.generate_expression(expr)?;
34417 }
34418 if let Some(into_table) = &output.into_table {
34419 self.write_space();
34420 self.write_keyword("INTO");
34421 self.write_space();
34422 self.generate_expression(into_table)?;
34423 }
34424 Ok(())
34425 }
34426
34427 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
34428 self.write_keyword("RETURNS");
34430 if e.is_table.is_some() {
34431 self.write_space();
34432 self.write_keyword("TABLE");
34433 }
34434 if let Some(table) = &e.table {
34435 self.write_space();
34436 self.generate_expression(table)?;
34437 } else if let Some(this) = &e.this {
34438 self.write_space();
34439 self.generate_expression(this)?;
34440 }
34441 if e.null.is_some() {
34442 self.write_space();
34443 self.write_keyword("NULL ON NULL INPUT");
34444 }
34445 Ok(())
34446 }
34447
34448 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
34449 self.write_keyword("ROLLBACK");
34451
34452 if e.this.is_none()
34454 && matches!(
34455 self.config.dialect,
34456 Some(DialectType::TSQL) | Some(DialectType::Fabric)
34457 )
34458 {
34459 self.write_space();
34460 self.write_keyword("TRANSACTION");
34461 }
34462
34463 if let Some(this) = &e.this {
34465 let is_transaction_marker = matches!(
34467 this.as_ref(),
34468 Expression::Identifier(id) if id.name == "TRANSACTION"
34469 );
34470
34471 self.write_space();
34472 self.write_keyword("TRANSACTION");
34473
34474 if !is_transaction_marker {
34476 self.write_space();
34477 self.generate_expression(this)?;
34478 }
34479 }
34480
34481 if let Some(savepoint) = &e.savepoint {
34483 self.write_space();
34484 self.write_keyword("TO");
34485 self.write_space();
34486 self.generate_expression(savepoint)?;
34487 }
34488 Ok(())
34489 }
34490
34491 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
34492 if e.expressions.is_empty() {
34494 self.write_keyword("WITH ROLLUP");
34495 } else {
34496 self.write_keyword("ROLLUP");
34497 self.write("(");
34498 for (i, expr) in e.expressions.iter().enumerate() {
34499 if i > 0 {
34500 self.write(", ");
34501 }
34502 self.generate_expression(expr)?;
34503 }
34504 self.write(")");
34505 }
34506 Ok(())
34507 }
34508
34509 fn generate_row_format_delimited_property(
34510 &mut self,
34511 e: &RowFormatDelimitedProperty,
34512 ) -> Result<()> {
34513 self.write_keyword("ROW FORMAT DELIMITED");
34515 if let Some(fields) = &e.fields {
34516 self.write_space();
34517 self.write_keyword("FIELDS TERMINATED BY");
34518 self.write_space();
34519 self.generate_expression(fields)?;
34520 }
34521 if let Some(escaped) = &e.escaped {
34522 self.write_space();
34523 self.write_keyword("ESCAPED BY");
34524 self.write_space();
34525 self.generate_expression(escaped)?;
34526 }
34527 if let Some(items) = &e.collection_items {
34528 self.write_space();
34529 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
34530 self.write_space();
34531 self.generate_expression(items)?;
34532 }
34533 if let Some(keys) = &e.map_keys {
34534 self.write_space();
34535 self.write_keyword("MAP KEYS TERMINATED BY");
34536 self.write_space();
34537 self.generate_expression(keys)?;
34538 }
34539 if let Some(lines) = &e.lines {
34540 self.write_space();
34541 self.write_keyword("LINES TERMINATED BY");
34542 self.write_space();
34543 self.generate_expression(lines)?;
34544 }
34545 if let Some(null) = &e.null {
34546 self.write_space();
34547 self.write_keyword("NULL DEFINED AS");
34548 self.write_space();
34549 self.generate_expression(null)?;
34550 }
34551 if let Some(serde) = &e.serde {
34552 self.write_space();
34553 self.generate_expression(serde)?;
34554 }
34555 Ok(())
34556 }
34557
34558 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
34559 self.write_keyword("ROW FORMAT");
34561 self.write_space();
34562 self.generate_expression(&e.this)?;
34563 Ok(())
34564 }
34565
34566 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
34567 self.write_keyword("ROW FORMAT SERDE");
34569 self.write_space();
34570 self.generate_expression(&e.this)?;
34571 if let Some(props) = &e.serde_properties {
34572 self.write_space();
34573 self.generate_expression(props)?;
34575 }
34576 Ok(())
34577 }
34578
34579 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
34580 self.write_keyword("SHA2");
34582 self.write("(");
34583 self.generate_expression(&e.this)?;
34584 if let Some(length) = e.length {
34585 self.write(", ");
34586 self.write(&length.to_string());
34587 }
34588 self.write(")");
34589 Ok(())
34590 }
34591
34592 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
34593 self.write_keyword("SHA2_DIGEST");
34595 self.write("(");
34596 self.generate_expression(&e.this)?;
34597 if let Some(length) = e.length {
34598 self.write(", ");
34599 self.write(&length.to_string());
34600 }
34601 self.write(")");
34602 Ok(())
34603 }
34604
34605 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
34606 let name = if matches!(
34607 self.config.dialect,
34608 Some(crate::dialects::DialectType::Spark)
34609 | Some(crate::dialects::DialectType::Databricks)
34610 ) {
34611 "TRY_ADD"
34612 } else {
34613 "SAFE_ADD"
34614 };
34615 self.write_keyword(name);
34616 self.write("(");
34617 self.generate_expression(&e.this)?;
34618 self.write(", ");
34619 self.generate_expression(&e.expression)?;
34620 self.write(")");
34621 Ok(())
34622 }
34623
34624 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
34625 self.write_keyword("SAFE_DIVIDE");
34627 self.write("(");
34628 self.generate_expression(&e.this)?;
34629 self.write(", ");
34630 self.generate_expression(&e.expression)?;
34631 self.write(")");
34632 Ok(())
34633 }
34634
34635 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
34636 let name = if matches!(
34637 self.config.dialect,
34638 Some(crate::dialects::DialectType::Spark)
34639 | Some(crate::dialects::DialectType::Databricks)
34640 ) {
34641 "TRY_MULTIPLY"
34642 } else {
34643 "SAFE_MULTIPLY"
34644 };
34645 self.write_keyword(name);
34646 self.write("(");
34647 self.generate_expression(&e.this)?;
34648 self.write(", ");
34649 self.generate_expression(&e.expression)?;
34650 self.write(")");
34651 Ok(())
34652 }
34653
34654 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
34655 let name = if matches!(
34656 self.config.dialect,
34657 Some(crate::dialects::DialectType::Spark)
34658 | Some(crate::dialects::DialectType::Databricks)
34659 ) {
34660 "TRY_SUBTRACT"
34661 } else {
34662 "SAFE_SUBTRACT"
34663 };
34664 self.write_keyword(name);
34665 self.write("(");
34666 self.generate_expression(&e.this)?;
34667 self.write(", ");
34668 self.generate_expression(&e.expression)?;
34669 self.write(")");
34670 Ok(())
34671 }
34672
34673 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
34676 if matches!(sample.method, SampleMethod::Bucket) {
34678 self.write(" (");
34679 self.write_keyword("BUCKET");
34680 self.write_space();
34681 if let Some(ref num) = sample.bucket_numerator {
34682 self.generate_expression(num)?;
34683 }
34684 self.write_space();
34685 self.write_keyword("OUT OF");
34686 self.write_space();
34687 if let Some(ref denom) = sample.bucket_denominator {
34688 self.generate_expression(denom)?;
34689 }
34690 if let Some(ref field) = sample.bucket_field {
34691 self.write_space();
34692 self.write_keyword("ON");
34693 self.write_space();
34694 self.generate_expression(field)?;
34695 }
34696 self.write(")");
34697 return Ok(());
34698 }
34699
34700 let is_snowflake = matches!(
34702 self.config.dialect,
34703 Some(crate::dialects::DialectType::Snowflake)
34704 );
34705 let is_postgres = matches!(
34706 self.config.dialect,
34707 Some(crate::dialects::DialectType::PostgreSQL)
34708 | Some(crate::dialects::DialectType::Redshift)
34709 );
34710 let is_databricks = matches!(
34712 self.config.dialect,
34713 Some(crate::dialects::DialectType::Databricks)
34714 );
34715 let is_spark = matches!(
34716 self.config.dialect,
34717 Some(crate::dialects::DialectType::Spark)
34718 );
34719 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
34720 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
34722 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
34723 self.write_space();
34724 if !sample.explicit_method && (is_snowflake || force_method) {
34725 self.write_keyword("BERNOULLI");
34727 } else {
34728 match sample.method {
34729 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
34730 SampleMethod::System => self.write_keyword("SYSTEM"),
34731 SampleMethod::Block => self.write_keyword("BLOCK"),
34732 SampleMethod::Row => self.write_keyword("ROW"),
34733 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
34734 SampleMethod::Percent => self.write_keyword("SYSTEM"),
34735 SampleMethod::Bucket => {} }
34737 }
34738 }
34739
34740 let emit_size_no_parens = !self.config.tablesample_requires_parens;
34742 if emit_size_no_parens {
34743 self.write_space();
34744 match &sample.size {
34745 Expression::Tuple(tuple) => {
34746 for (i, expr) in tuple.expressions.iter().enumerate() {
34747 if i > 0 {
34748 self.write(", ");
34749 }
34750 self.generate_expression(expr)?;
34751 }
34752 }
34753 expr => self.generate_expression(expr)?,
34754 }
34755 } else {
34756 self.write(" (");
34757 self.generate_expression(&sample.size)?;
34758 }
34759
34760 let is_rows_method = matches!(
34762 sample.method,
34763 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
34764 );
34765 let is_percent = matches!(
34766 sample.method,
34767 SampleMethod::Percent
34768 | SampleMethod::System
34769 | SampleMethod::Bernoulli
34770 | SampleMethod::Block
34771 );
34772
34773 let is_presto = matches!(
34777 self.config.dialect,
34778 Some(crate::dialects::DialectType::Presto)
34779 | Some(crate::dialects::DialectType::Trino)
34780 | Some(crate::dialects::DialectType::Athena)
34781 );
34782 let should_output_unit = if is_databricks || is_spark {
34783 is_percent || is_rows_method || sample.unit_after_size
34785 } else if is_snowflake || is_postgres || is_presto {
34786 sample.unit_after_size
34787 } else {
34788 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
34789 };
34790
34791 if should_output_unit {
34792 self.write_space();
34793 if sample.is_percent {
34794 self.write_keyword("PERCENT");
34795 } else if is_rows_method && !sample.unit_after_size {
34796 self.write_keyword("ROWS");
34797 } else if sample.unit_after_size {
34798 match sample.method {
34799 SampleMethod::Percent
34800 | SampleMethod::System
34801 | SampleMethod::Bernoulli
34802 | SampleMethod::Block => {
34803 self.write_keyword("PERCENT");
34804 }
34805 SampleMethod::Row | SampleMethod::Reservoir => {
34806 self.write_keyword("ROWS");
34807 }
34808 _ => self.write_keyword("ROWS"),
34809 }
34810 } else {
34811 self.write_keyword("PERCENT");
34812 }
34813 }
34814
34815 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34816 if let Some(ref offset) = sample.offset {
34817 self.write_space();
34818 self.write_keyword("OFFSET");
34819 self.write_space();
34820 self.generate_expression(offset)?;
34821 }
34822 }
34823 if !emit_size_no_parens {
34824 self.write(")");
34825 }
34826
34827 Ok(())
34828 }
34829
34830 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
34831 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34833 self.write_keyword("SAMPLE BY");
34834 } else {
34835 self.write_keyword("SAMPLE");
34836 }
34837 self.write_space();
34838 self.generate_expression(&e.this)?;
34839 Ok(())
34840 }
34841
34842 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
34843 if let Some(this) = &e.this {
34845 self.generate_expression(this)?;
34846 }
34847 if !e.expressions.is_empty() {
34848 if e.this.is_some() {
34850 self.write_space();
34851 }
34852 self.write("(");
34853 for (i, expr) in e.expressions.iter().enumerate() {
34854 if i > 0 {
34855 self.write(", ");
34856 }
34857 self.generate_expression(expr)?;
34858 }
34859 self.write(")");
34860 }
34861 Ok(())
34862 }
34863
34864 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
34865 self.write_keyword("COMMENT");
34867 self.write_space();
34868 self.generate_expression(&e.this)?;
34869 Ok(())
34870 }
34871
34872 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
34873 if let Some(this) = &e.this {
34875 self.generate_expression(this)?;
34876 self.write("::");
34877 }
34878 self.generate_expression(&e.expression)?;
34879 Ok(())
34880 }
34881
34882 fn generate_search(&mut self, e: &Search) -> Result<()> {
34883 self.write_keyword("SEARCH");
34885 self.write("(");
34886 self.generate_expression(&e.this)?;
34887 self.write(", ");
34888 self.generate_expression(&e.expression)?;
34889 if let Some(json_scope) = &e.json_scope {
34890 self.write(", ");
34891 self.generate_expression(json_scope)?;
34892 }
34893 if let Some(analyzer) = &e.analyzer {
34894 self.write(", ");
34895 self.generate_expression(analyzer)?;
34896 }
34897 if let Some(analyzer_options) = &e.analyzer_options {
34898 self.write(", ");
34899 self.generate_expression(analyzer_options)?;
34900 }
34901 if let Some(search_mode) = &e.search_mode {
34902 self.write(", ");
34903 self.generate_expression(search_mode)?;
34904 }
34905 self.write(")");
34906 Ok(())
34907 }
34908
34909 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
34910 self.write_keyword("SEARCH_IP");
34912 self.write("(");
34913 self.generate_expression(&e.this)?;
34914 self.write(", ");
34915 self.generate_expression(&e.expression)?;
34916 self.write(")");
34917 Ok(())
34918 }
34919
34920 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
34921 self.write_keyword("SECURITY");
34923 self.write_space();
34924 self.generate_expression(&e.this)?;
34925 Ok(())
34926 }
34927
34928 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
34929 self.write("SEMANTIC_VIEW(");
34931
34932 if self.config.pretty {
34933 self.write_newline();
34935 self.indent_level += 1;
34936 self.write_indent();
34937 self.generate_expression(&e.this)?;
34938
34939 if let Some(metrics) = &e.metrics {
34940 self.write_newline();
34941 self.write_indent();
34942 self.write_keyword("METRICS");
34943 self.write_space();
34944 self.generate_semantic_view_tuple(metrics)?;
34945 }
34946 if let Some(dimensions) = &e.dimensions {
34947 self.write_newline();
34948 self.write_indent();
34949 self.write_keyword("DIMENSIONS");
34950 self.write_space();
34951 self.generate_semantic_view_tuple(dimensions)?;
34952 }
34953 if let Some(facts) = &e.facts {
34954 self.write_newline();
34955 self.write_indent();
34956 self.write_keyword("FACTS");
34957 self.write_space();
34958 self.generate_semantic_view_tuple(facts)?;
34959 }
34960 if let Some(where_) = &e.where_ {
34961 self.write_newline();
34962 self.write_indent();
34963 self.write_keyword("WHERE");
34964 self.write_space();
34965 self.generate_expression(where_)?;
34966 }
34967 self.write_newline();
34968 self.indent_level -= 1;
34969 self.write_indent();
34970 } else {
34971 self.generate_expression(&e.this)?;
34973 if let Some(metrics) = &e.metrics {
34974 self.write_space();
34975 self.write_keyword("METRICS");
34976 self.write_space();
34977 self.generate_semantic_view_tuple(metrics)?;
34978 }
34979 if let Some(dimensions) = &e.dimensions {
34980 self.write_space();
34981 self.write_keyword("DIMENSIONS");
34982 self.write_space();
34983 self.generate_semantic_view_tuple(dimensions)?;
34984 }
34985 if let Some(facts) = &e.facts {
34986 self.write_space();
34987 self.write_keyword("FACTS");
34988 self.write_space();
34989 self.generate_semantic_view_tuple(facts)?;
34990 }
34991 if let Some(where_) = &e.where_ {
34992 self.write_space();
34993 self.write_keyword("WHERE");
34994 self.write_space();
34995 self.generate_expression(where_)?;
34996 }
34997 }
34998 self.write(")");
34999 Ok(())
35000 }
35001
35002 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
35004 if let Expression::Tuple(t) = expr {
35005 for (i, e) in t.expressions.iter().enumerate() {
35006 if i > 0 {
35007 self.write(", ");
35008 }
35009 self.generate_expression(e)?;
35010 }
35011 } else {
35012 self.generate_expression(expr)?;
35013 }
35014 Ok(())
35015 }
35016
35017 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
35018 if let Some(start) = &e.start {
35020 self.write_keyword("START WITH");
35021 self.write_space();
35022 self.generate_expression(start)?;
35023 }
35024 if let Some(increment) = &e.increment {
35025 self.write_space();
35026 self.write_keyword("INCREMENT BY");
35027 self.write_space();
35028 self.generate_expression(increment)?;
35029 }
35030 if let Some(minvalue) = &e.minvalue {
35031 self.write_space();
35032 self.write_keyword("MINVALUE");
35033 self.write_space();
35034 self.generate_expression(minvalue)?;
35035 }
35036 if let Some(maxvalue) = &e.maxvalue {
35037 self.write_space();
35038 self.write_keyword("MAXVALUE");
35039 self.write_space();
35040 self.generate_expression(maxvalue)?;
35041 }
35042 if let Some(cache) = &e.cache {
35043 self.write_space();
35044 self.write_keyword("CACHE");
35045 self.write_space();
35046 self.generate_expression(cache)?;
35047 }
35048 if let Some(owned) = &e.owned {
35049 self.write_space();
35050 self.write_keyword("OWNED BY");
35051 self.write_space();
35052 self.generate_expression(owned)?;
35053 }
35054 for opt in &e.options {
35055 self.write_space();
35056 self.generate_expression(opt)?;
35057 }
35058 Ok(())
35059 }
35060
35061 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
35062 if e.with_.is_some() {
35064 self.write_keyword("WITH");
35065 self.write_space();
35066 }
35067 self.write_keyword("SERDEPROPERTIES");
35068 self.write(" (");
35069 for (i, expr) in e.expressions.iter().enumerate() {
35070 if i > 0 {
35071 self.write(", ");
35072 }
35073 match expr {
35075 Expression::Eq(eq) => {
35076 self.generate_expression(&eq.left)?;
35077 self.write("=");
35078 self.generate_expression(&eq.right)?;
35079 }
35080 _ => self.generate_expression(expr)?,
35081 }
35082 }
35083 self.write(")");
35084 Ok(())
35085 }
35086
35087 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
35088 self.write("@@");
35090 if let Some(kind) = &e.kind {
35091 self.write(kind);
35092 self.write(".");
35093 }
35094 self.generate_expression(&e.this)?;
35095 Ok(())
35096 }
35097
35098 fn generate_set(&mut self, e: &Set) -> Result<()> {
35099 if e.unset.is_some() {
35101 self.write_keyword("UNSET");
35102 } else {
35103 self.write_keyword("SET");
35104 }
35105 if e.tag.is_some() {
35106 self.write_space();
35107 self.write_keyword("TAG");
35108 }
35109 if !e.expressions.is_empty() {
35110 self.write_space();
35111 for (i, expr) in e.expressions.iter().enumerate() {
35112 if i > 0 {
35113 self.write(", ");
35114 }
35115 self.generate_expression(expr)?;
35116 }
35117 }
35118 Ok(())
35119 }
35120
35121 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
35122 self.write_keyword("SET");
35124 self.write_space();
35125 self.generate_expression(&e.this)?;
35126 Ok(())
35127 }
35128
35129 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
35130 if let Some(kind) = &e.kind {
35132 self.write_keyword(kind);
35133 self.write_space();
35134 }
35135 self.generate_expression(&e.name)?;
35136 self.write(" = ");
35137 self.generate_expression(&e.value)?;
35138 Ok(())
35139 }
35140
35141 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
35142 if let Some(with_) = &e.with_ {
35144 self.generate_expression(with_)?;
35145 self.write_space();
35146 }
35147 self.generate_expression(&e.this)?;
35148 self.write_space();
35149 if let Some(kind) = &e.kind {
35151 self.write_keyword(kind);
35152 }
35153 if e.distinct {
35154 self.write_space();
35155 self.write_keyword("DISTINCT");
35156 } else {
35157 self.write_space();
35158 self.write_keyword("ALL");
35159 }
35160 if e.by_name.is_some() {
35161 self.write_space();
35162 self.write_keyword("BY NAME");
35163 }
35164 self.write_space();
35165 self.generate_expression(&e.expression)?;
35166 Ok(())
35167 }
35168
35169 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
35170 if e.multi.is_some() {
35172 self.write_keyword("MULTISET");
35173 } else {
35174 self.write_keyword("SET");
35175 }
35176 Ok(())
35177 }
35178
35179 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
35180 self.write_keyword("SETTINGS");
35182 if self.config.pretty && e.expressions.len() > 1 {
35183 self.indent_level += 1;
35185 for (i, expr) in e.expressions.iter().enumerate() {
35186 if i > 0 {
35187 self.write(",");
35188 }
35189 self.write_newline();
35190 self.write_indent();
35191 self.generate_expression(expr)?;
35192 }
35193 self.indent_level -= 1;
35194 } else {
35195 self.write_space();
35196 for (i, expr) in e.expressions.iter().enumerate() {
35197 if i > 0 {
35198 self.write(", ");
35199 }
35200 self.generate_expression(expr)?;
35201 }
35202 }
35203 Ok(())
35204 }
35205
35206 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
35207 self.write_keyword("SHARING");
35209 if let Some(this) = &e.this {
35210 self.write(" = ");
35211 self.generate_expression(this)?;
35212 }
35213 Ok(())
35214 }
35215
35216 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
35217 if let Some(begin) = &e.this {
35219 self.generate_expression(begin)?;
35220 }
35221 self.write(":");
35222 if let Some(end) = &e.expression {
35223 self.generate_expression(end)?;
35224 }
35225 if let Some(step) = &e.step {
35226 self.write(":");
35227 self.generate_expression(step)?;
35228 }
35229 Ok(())
35230 }
35231
35232 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
35233 self.write_keyword("SORT_ARRAY");
35235 self.write("(");
35236 self.generate_expression(&e.this)?;
35237 if let Some(asc) = &e.asc {
35238 self.write(", ");
35239 self.generate_expression(asc)?;
35240 }
35241 self.write(")");
35242 Ok(())
35243 }
35244
35245 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
35246 self.write_keyword("SORT BY");
35248 self.write_space();
35249 for (i, expr) in e.expressions.iter().enumerate() {
35250 if i > 0 {
35251 self.write(", ");
35252 }
35253 self.generate_ordered(expr)?;
35254 }
35255 Ok(())
35256 }
35257
35258 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
35259 if e.compound.is_some() {
35261 self.write_keyword("COMPOUND");
35262 self.write_space();
35263 }
35264 self.write_keyword("SORTKEY");
35265 self.write("(");
35266 if let Expression::Tuple(t) = e.this.as_ref() {
35268 for (i, expr) in t.expressions.iter().enumerate() {
35269 if i > 0 {
35270 self.write(", ");
35271 }
35272 self.generate_expression(expr)?;
35273 }
35274 } else {
35275 self.generate_expression(&e.this)?;
35276 }
35277 self.write(")");
35278 Ok(())
35279 }
35280
35281 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
35282 self.write_keyword("SPLIT_PART");
35284 self.write("(");
35285 self.generate_expression(&e.this)?;
35286 if let Some(delimiter) = &e.delimiter {
35287 self.write(", ");
35288 self.generate_expression(delimiter)?;
35289 }
35290 if let Some(part_index) = &e.part_index {
35291 self.write(", ");
35292 self.generate_expression(part_index)?;
35293 }
35294 self.write(")");
35295 Ok(())
35296 }
35297
35298 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
35299 self.generate_expression(&e.this)?;
35301 Ok(())
35302 }
35303
35304 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
35305 self.write_keyword("SQL SECURITY");
35307 self.write_space();
35308 self.generate_expression(&e.this)?;
35309 Ok(())
35310 }
35311
35312 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
35313 self.write_keyword("ST_DISTANCE");
35315 self.write("(");
35316 self.generate_expression(&e.this)?;
35317 self.write(", ");
35318 self.generate_expression(&e.expression)?;
35319 if let Some(use_spheroid) = &e.use_spheroid {
35320 self.write(", ");
35321 self.generate_expression(use_spheroid)?;
35322 }
35323 self.write(")");
35324 Ok(())
35325 }
35326
35327 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
35328 self.write_keyword("ST_POINT");
35330 self.write("(");
35331 self.generate_expression(&e.this)?;
35332 self.write(", ");
35333 self.generate_expression(&e.expression)?;
35334 self.write(")");
35335 Ok(())
35336 }
35337
35338 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
35339 self.generate_expression(&e.this)?;
35341 Ok(())
35342 }
35343
35344 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
35345 self.write_keyword("STANDARD_HASH");
35347 self.write("(");
35348 self.generate_expression(&e.this)?;
35349 if let Some(expression) = &e.expression {
35350 self.write(", ");
35351 self.generate_expression(expression)?;
35352 }
35353 self.write(")");
35354 Ok(())
35355 }
35356
35357 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
35358 self.write_keyword("STORED BY");
35360 self.write_space();
35361 self.generate_expression(&e.this)?;
35362 Ok(())
35363 }
35364
35365 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
35366 use crate::dialects::DialectType;
35369 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35370 self.write_keyword("CHARINDEX");
35372 self.write("(");
35373 if let Some(substr) = &e.substr {
35374 self.generate_expression(substr)?;
35375 self.write(", ");
35376 }
35377 self.generate_expression(&e.this)?;
35378 if let Some(position) = &e.position {
35379 self.write(", ");
35380 self.generate_expression(position)?;
35381 }
35382 self.write(")");
35383 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
35384 self.write_keyword("POSITION");
35385 self.write("(");
35386 self.generate_expression(&e.this)?;
35387 if let Some(substr) = &e.substr {
35388 self.write(", ");
35389 self.generate_expression(substr)?;
35390 }
35391 if let Some(position) = &e.position {
35392 self.write(", ");
35393 self.generate_expression(position)?;
35394 }
35395 if let Some(occurrence) = &e.occurrence {
35396 self.write(", ");
35397 self.generate_expression(occurrence)?;
35398 }
35399 self.write(")");
35400 } else if matches!(
35401 self.config.dialect,
35402 Some(DialectType::SQLite)
35403 | Some(DialectType::Oracle)
35404 | Some(DialectType::BigQuery)
35405 | Some(DialectType::Teradata)
35406 ) {
35407 self.write_keyword("INSTR");
35408 self.write("(");
35409 self.generate_expression(&e.this)?;
35410 if let Some(substr) = &e.substr {
35411 self.write(", ");
35412 self.generate_expression(substr)?;
35413 }
35414 if let Some(position) = &e.position {
35415 self.write(", ");
35416 self.generate_expression(position)?;
35417 } else if e.occurrence.is_some() {
35418 self.write(", 1");
35421 }
35422 if let Some(occurrence) = &e.occurrence {
35423 self.write(", ");
35424 self.generate_expression(occurrence)?;
35425 }
35426 self.write(")");
35427 } else if matches!(
35428 self.config.dialect,
35429 Some(DialectType::MySQL)
35430 | Some(DialectType::SingleStore)
35431 | Some(DialectType::Doris)
35432 | Some(DialectType::StarRocks)
35433 | Some(DialectType::Hive)
35434 | Some(DialectType::Spark)
35435 | Some(DialectType::Databricks)
35436 ) {
35437 self.write_keyword("LOCATE");
35439 self.write("(");
35440 if let Some(substr) = &e.substr {
35441 self.generate_expression(substr)?;
35442 self.write(", ");
35443 }
35444 self.generate_expression(&e.this)?;
35445 if let Some(position) = &e.position {
35446 self.write(", ");
35447 self.generate_expression(position)?;
35448 }
35449 self.write(")");
35450 } else if matches!(
35451 self.config.dialect,
35452 Some(DialectType::TSQL) | Some(DialectType::Fabric)
35453 ) {
35454 self.write_keyword("CHARINDEX");
35456 self.write("(");
35457 if let Some(substr) = &e.substr {
35458 self.generate_expression(substr)?;
35459 self.write(", ");
35460 }
35461 self.generate_expression(&e.this)?;
35462 if let Some(position) = &e.position {
35463 self.write(", ");
35464 self.generate_expression(position)?;
35465 }
35466 self.write(")");
35467 } else if matches!(
35468 self.config.dialect,
35469 Some(DialectType::PostgreSQL)
35470 | Some(DialectType::Materialize)
35471 | Some(DialectType::RisingWave)
35472 | Some(DialectType::Redshift)
35473 ) {
35474 self.write_keyword("POSITION");
35476 self.write("(");
35477 if let Some(substr) = &e.substr {
35478 self.generate_expression(substr)?;
35479 self.write(" IN ");
35480 }
35481 self.generate_expression(&e.this)?;
35482 self.write(")");
35483 } else {
35484 self.write_keyword("STRPOS");
35485 self.write("(");
35486 self.generate_expression(&e.this)?;
35487 if let Some(substr) = &e.substr {
35488 self.write(", ");
35489 self.generate_expression(substr)?;
35490 }
35491 if let Some(position) = &e.position {
35492 self.write(", ");
35493 self.generate_expression(position)?;
35494 }
35495 if let Some(occurrence) = &e.occurrence {
35496 self.write(", ");
35497 self.generate_expression(occurrence)?;
35498 }
35499 self.write(")");
35500 }
35501 Ok(())
35502 }
35503
35504 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
35505 match self.config.dialect {
35506 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
35507 self.write_keyword("TO_DATE");
35509 self.write("(");
35510 self.generate_expression(&e.this)?;
35511 if let Some(format) = &e.format {
35512 self.write(", '");
35513 self.write(&Self::strftime_to_java_format(format));
35514 self.write("'");
35515 }
35516 self.write(")");
35517 }
35518 Some(DialectType::DuckDB) => {
35519 self.write_keyword("CAST");
35521 self.write("(");
35522 self.write_keyword("STRPTIME");
35523 self.write("(");
35524 self.generate_expression(&e.this)?;
35525 if let Some(format) = &e.format {
35526 self.write(", '");
35527 self.write(format);
35528 self.write("'");
35529 }
35530 self.write(")");
35531 self.write_keyword(" AS ");
35532 self.write_keyword("DATE");
35533 self.write(")");
35534 }
35535 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
35536 self.write_keyword("TO_DATE");
35538 self.write("(");
35539 self.generate_expression(&e.this)?;
35540 if let Some(format) = &e.format {
35541 self.write(", '");
35542 self.write(&Self::strftime_to_postgres_format(format));
35543 self.write("'");
35544 }
35545 self.write(")");
35546 }
35547 Some(DialectType::BigQuery) => {
35548 self.write_keyword("PARSE_DATE");
35550 self.write("(");
35551 if let Some(format) = &e.format {
35552 self.write("'");
35553 self.write(format);
35554 self.write("'");
35555 self.write(", ");
35556 }
35557 self.generate_expression(&e.this)?;
35558 self.write(")");
35559 }
35560 Some(DialectType::Teradata) => {
35561 self.write_keyword("CAST");
35563 self.write("(");
35564 self.generate_expression(&e.this)?;
35565 self.write_keyword(" AS ");
35566 self.write_keyword("DATE");
35567 if let Some(format) = &e.format {
35568 self.write_keyword(" FORMAT ");
35569 self.write("'");
35570 self.write(&Self::strftime_to_teradata_format(format));
35571 self.write("'");
35572 }
35573 self.write(")");
35574 }
35575 _ => {
35576 self.write_keyword("STR_TO_DATE");
35578 self.write("(");
35579 self.generate_expression(&e.this)?;
35580 if let Some(format) = &e.format {
35581 self.write(", '");
35582 self.write(format);
35583 self.write("'");
35584 }
35585 self.write(")");
35586 }
35587 }
35588 Ok(())
35589 }
35590
35591 fn strftime_to_teradata_format(fmt: &str) -> String {
35593 let mut result = String::with_capacity(fmt.len() * 2);
35594 let bytes = fmt.as_bytes();
35595 let len = bytes.len();
35596 let mut i = 0;
35597 while i < len {
35598 if bytes[i] == b'%' && i + 1 < len {
35599 let replacement = match bytes[i + 1] {
35600 b'Y' => "YYYY",
35601 b'y' => "YY",
35602 b'm' => "MM",
35603 b'B' => "MMMM",
35604 b'b' => "MMM",
35605 b'd' => "DD",
35606 b'j' => "DDD",
35607 b'H' => "HH",
35608 b'M' => "MI",
35609 b'S' => "SS",
35610 b'f' => "SSSSSS",
35611 b'A' => "EEEE",
35612 b'a' => "EEE",
35613 _ => {
35614 result.push('%');
35615 i += 1;
35616 continue;
35617 }
35618 };
35619 result.push_str(replacement);
35620 i += 2;
35621 } else {
35622 result.push(bytes[i] as char);
35623 i += 1;
35624 }
35625 }
35626 result
35627 }
35628
35629 pub fn strftime_to_java_format_static(fmt: &str) -> String {
35632 Self::strftime_to_java_format(fmt)
35633 }
35634
35635 fn strftime_to_java_format(fmt: &str) -> String {
35637 let mut result = String::with_capacity(fmt.len() * 2);
35638 let bytes = fmt.as_bytes();
35639 let len = bytes.len();
35640 let mut i = 0;
35641 while i < len {
35642 if bytes[i] == b'%' && i + 1 < len {
35643 if bytes[i + 1] == b'-' && i + 2 < len {
35645 let replacement = match bytes[i + 2] {
35646 b'd' => "d",
35647 b'm' => "M",
35648 b'H' => "H",
35649 b'M' => "m",
35650 b'S' => "s",
35651 _ => {
35652 result.push('%');
35653 i += 1;
35654 continue;
35655 }
35656 };
35657 result.push_str(replacement);
35658 i += 3;
35659 } else {
35660 let replacement = match bytes[i + 1] {
35661 b'Y' => "yyyy",
35662 b'y' => "yy",
35663 b'm' => "MM",
35664 b'B' => "MMMM",
35665 b'b' => "MMM",
35666 b'd' => "dd",
35667 b'j' => "DDD",
35668 b'H' => "HH",
35669 b'M' => "mm",
35670 b'S' => "ss",
35671 b'f' => "SSSSSS",
35672 b'A' => "EEEE",
35673 b'a' => "EEE",
35674 _ => {
35675 result.push('%');
35676 i += 1;
35677 continue;
35678 }
35679 };
35680 result.push_str(replacement);
35681 i += 2;
35682 }
35683 } else {
35684 result.push(bytes[i] as char);
35685 i += 1;
35686 }
35687 }
35688 result
35689 }
35690
35691 fn strftime_to_tsql_format(fmt: &str) -> String {
35694 let mut result = String::with_capacity(fmt.len() * 2);
35695 let bytes = fmt.as_bytes();
35696 let len = bytes.len();
35697 let mut i = 0;
35698 while i < len {
35699 if bytes[i] == b'%' && i + 1 < len {
35700 if bytes[i + 1] == b'-' && i + 2 < len {
35702 let replacement = match bytes[i + 2] {
35703 b'd' => "d",
35704 b'm' => "M",
35705 b'H' => "H",
35706 b'M' => "m",
35707 b'S' => "s",
35708 _ => {
35709 result.push('%');
35710 i += 1;
35711 continue;
35712 }
35713 };
35714 result.push_str(replacement);
35715 i += 3;
35716 } else {
35717 let replacement = match bytes[i + 1] {
35718 b'Y' => "yyyy",
35719 b'y' => "yy",
35720 b'm' => "MM",
35721 b'B' => "MMMM",
35722 b'b' => "MMM",
35723 b'd' => "dd",
35724 b'j' => "DDD",
35725 b'H' => "HH",
35726 b'M' => "mm",
35727 b'S' => "ss",
35728 b'f' => "ffffff",
35729 b'A' => "dddd",
35730 b'a' => "ddd",
35731 _ => {
35732 result.push('%');
35733 i += 1;
35734 continue;
35735 }
35736 };
35737 result.push_str(replacement);
35738 i += 2;
35739 }
35740 } else {
35741 result.push(bytes[i] as char);
35742 i += 1;
35743 }
35744 }
35745 result
35746 }
35747
35748 fn decompose_json_path(path: &str) -> Vec<String> {
35751 let mut parts = Vec::new();
35752 let path = if path.starts_with("$.") {
35754 &path[2..]
35755 } else if path.starts_with('$') {
35756 &path[1..]
35757 } else {
35758 path
35759 };
35760 if path.is_empty() {
35761 return parts;
35762 }
35763 let mut current = String::new();
35764 let chars: Vec<char> = path.chars().collect();
35765 let mut i = 0;
35766 while i < chars.len() {
35767 match chars[i] {
35768 '.' => {
35769 if !current.is_empty() {
35770 parts.push(current.clone());
35771 current.clear();
35772 }
35773 i += 1;
35774 }
35775 '[' => {
35776 if !current.is_empty() {
35777 parts.push(current.clone());
35778 current.clear();
35779 }
35780 i += 1;
35781 let mut bracket_content = String::new();
35783 while i < chars.len() && chars[i] != ']' {
35784 if chars[i] == '"' || chars[i] == '\'' {
35786 let quote = chars[i];
35787 i += 1;
35788 while i < chars.len() && chars[i] != quote {
35789 bracket_content.push(chars[i]);
35790 i += 1;
35791 }
35792 if i < chars.len() {
35793 i += 1;
35794 } } else {
35796 bracket_content.push(chars[i]);
35797 i += 1;
35798 }
35799 }
35800 if i < chars.len() {
35801 i += 1;
35802 } if bracket_content != "*" {
35805 parts.push(bracket_content);
35806 }
35807 }
35808 _ => {
35809 current.push(chars[i]);
35810 i += 1;
35811 }
35812 }
35813 }
35814 if !current.is_empty() {
35815 parts.push(current);
35816 }
35817 parts
35818 }
35819
35820 fn strftime_to_postgres_format(fmt: &str) -> String {
35822 let mut result = String::with_capacity(fmt.len() * 2);
35823 let bytes = fmt.as_bytes();
35824 let len = bytes.len();
35825 let mut i = 0;
35826 while i < len {
35827 if bytes[i] == b'%' && i + 1 < len {
35828 if bytes[i + 1] == b'-' && i + 2 < len {
35830 let replacement = match bytes[i + 2] {
35831 b'd' => "FMDD",
35832 b'm' => "FMMM",
35833 b'H' => "FMHH24",
35834 b'M' => "FMMI",
35835 b'S' => "FMSS",
35836 _ => {
35837 result.push('%');
35838 i += 1;
35839 continue;
35840 }
35841 };
35842 result.push_str(replacement);
35843 i += 3;
35844 } else {
35845 let replacement = match bytes[i + 1] {
35846 b'Y' => "YYYY",
35847 b'y' => "YY",
35848 b'm' => "MM",
35849 b'B' => "Month",
35850 b'b' => "Mon",
35851 b'd' => "DD",
35852 b'j' => "DDD",
35853 b'H' => "HH24",
35854 b'M' => "MI",
35855 b'S' => "SS",
35856 b'f' => "US",
35857 b'A' => "Day",
35858 b'a' => "Dy",
35859 _ => {
35860 result.push('%');
35861 i += 1;
35862 continue;
35863 }
35864 };
35865 result.push_str(replacement);
35866 i += 2;
35867 }
35868 } else {
35869 result.push(bytes[i] as char);
35870 i += 1;
35871 }
35872 }
35873 result
35874 }
35875
35876 fn strftime_to_snowflake_format(fmt: &str) -> String {
35878 let mut result = String::with_capacity(fmt.len() * 2);
35879 let bytes = fmt.as_bytes();
35880 let len = bytes.len();
35881 let mut i = 0;
35882 while i < len {
35883 if bytes[i] == b'%' && i + 1 < len {
35884 if bytes[i + 1] == b'-' && i + 2 < len {
35886 let replacement = match bytes[i + 2] {
35887 b'd' => "dd",
35888 b'm' => "mm",
35889 _ => {
35890 result.push('%');
35891 i += 1;
35892 continue;
35893 }
35894 };
35895 result.push_str(replacement);
35896 i += 3;
35897 } else {
35898 let replacement = match bytes[i + 1] {
35899 b'Y' => "yyyy",
35900 b'y' => "yy",
35901 b'm' => "mm",
35902 b'd' => "DD",
35903 b'H' => "hh24",
35904 b'M' => "mi",
35905 b'S' => "ss",
35906 b'f' => "ff",
35907 _ => {
35908 result.push('%');
35909 i += 1;
35910 continue;
35911 }
35912 };
35913 result.push_str(replacement);
35914 i += 2;
35915 }
35916 } else {
35917 result.push(bytes[i] as char);
35918 i += 1;
35919 }
35920 }
35921 result
35922 }
35923
35924 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
35925 self.write_keyword("STR_TO_MAP");
35927 self.write("(");
35928 self.generate_expression(&e.this)?;
35929 let needs_defaults = matches!(
35931 self.config.dialect,
35932 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
35933 );
35934 if let Some(pair_delim) = &e.pair_delim {
35935 self.write(", ");
35936 self.generate_expression(pair_delim)?;
35937 } else if needs_defaults {
35938 self.write(", ','");
35939 }
35940 if let Some(key_value_delim) = &e.key_value_delim {
35941 self.write(", ");
35942 self.generate_expression(key_value_delim)?;
35943 } else if needs_defaults {
35944 self.write(", ':'");
35945 }
35946 self.write(")");
35947 Ok(())
35948 }
35949
35950 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
35951 let is_strftime = e.format.contains('%');
35953 let to_strftime = |f: &str| -> String {
35955 if is_strftime {
35956 f.to_string()
35957 } else {
35958 Self::snowflake_format_to_strftime(f)
35959 }
35960 };
35961 let to_java = |f: &str| -> String {
35963 if is_strftime {
35964 Self::strftime_to_java_format(f)
35965 } else {
35966 Self::snowflake_format_to_spark(f)
35967 }
35968 };
35969 let to_pg = |f: &str| -> String {
35971 if is_strftime {
35972 Self::strftime_to_postgres_format(f)
35973 } else {
35974 Self::convert_strptime_to_postgres_format(f)
35975 }
35976 };
35977
35978 match self.config.dialect {
35979 Some(DialectType::Exasol) => {
35980 self.write_keyword("TO_DATE");
35981 self.write("(");
35982 self.generate_expression(&e.this)?;
35983 self.write(", '");
35984 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
35985 self.write("'");
35986 self.write(")");
35987 }
35988 Some(DialectType::BigQuery) => {
35989 let fmt = to_strftime(&e.format);
35991 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
35993 self.write_keyword("PARSE_TIMESTAMP");
35994 self.write("('");
35995 self.write(&fmt);
35996 self.write("', ");
35997 self.generate_expression(&e.this)?;
35998 self.write(")");
35999 }
36000 Some(DialectType::Hive) => {
36001 let java_fmt = to_java(&e.format);
36004 if java_fmt == "yyyy-MM-dd HH:mm:ss"
36005 || java_fmt == "yyyy-MM-dd"
36006 || e.format == "yyyy-MM-dd HH:mm:ss"
36007 || e.format == "yyyy-MM-dd"
36008 {
36009 self.write_keyword("CAST");
36010 self.write("(");
36011 self.generate_expression(&e.this)?;
36012 self.write(" ");
36013 self.write_keyword("AS TIMESTAMP");
36014 self.write(")");
36015 } else {
36016 self.write_keyword("CAST");
36018 self.write("(");
36019 self.write_keyword("FROM_UNIXTIME");
36020 self.write("(");
36021 self.write_keyword("UNIX_TIMESTAMP");
36022 self.write("(");
36023 self.generate_expression(&e.this)?;
36024 self.write(", '");
36025 self.write(&java_fmt);
36026 self.write("')");
36027 self.write(") ");
36028 self.write_keyword("AS TIMESTAMP");
36029 self.write(")");
36030 }
36031 }
36032 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36033 let java_fmt = to_java(&e.format);
36035 self.write_keyword("TO_TIMESTAMP");
36036 self.write("(");
36037 self.generate_expression(&e.this)?;
36038 self.write(", '");
36039 self.write(&java_fmt);
36040 self.write("')");
36041 }
36042 Some(DialectType::MySQL) => {
36043 let mut fmt = to_strftime(&e.format);
36045 fmt = fmt.replace("%-d", "%e");
36047 fmt = fmt.replace("%-m", "%c");
36048 fmt = fmt.replace("%H:%M:%S", "%T");
36049 self.write_keyword("STR_TO_DATE");
36050 self.write("(");
36051 self.generate_expression(&e.this)?;
36052 self.write(", '");
36053 self.write(&fmt);
36054 self.write("')");
36055 }
36056 Some(DialectType::Drill) => {
36057 let java_fmt = to_java(&e.format);
36059 let java_fmt = java_fmt.replace('T', "''T''");
36061 self.write_keyword("TO_TIMESTAMP");
36062 self.write("(");
36063 self.generate_expression(&e.this)?;
36064 self.write(", '");
36065 self.write(&java_fmt);
36066 self.write("')");
36067 }
36068 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
36069 let mut fmt = to_strftime(&e.format);
36071 fmt = fmt.replace("%-d", "%e");
36073 fmt = fmt.replace("%-m", "%c");
36074 fmt = fmt.replace("%H:%M:%S", "%T");
36075 self.write_keyword("DATE_PARSE");
36076 self.write("(");
36077 self.generate_expression(&e.this)?;
36078 self.write(", '");
36079 self.write(&fmt);
36080 self.write("')");
36081 }
36082 Some(DialectType::DuckDB) => {
36083 let fmt = to_strftime(&e.format);
36085 self.write_keyword("STRPTIME");
36086 self.write("(");
36087 self.generate_expression(&e.this)?;
36088 self.write(", '");
36089 self.write(&fmt);
36090 self.write("')");
36091 }
36092 Some(DialectType::PostgreSQL)
36093 | Some(DialectType::Redshift)
36094 | Some(DialectType::Materialize) => {
36095 let pg_fmt = to_pg(&e.format);
36097 self.write_keyword("TO_TIMESTAMP");
36098 self.write("(");
36099 self.generate_expression(&e.this)?;
36100 self.write(", '");
36101 self.write(&pg_fmt);
36102 self.write("')");
36103 }
36104 Some(DialectType::Oracle) => {
36105 let pg_fmt = to_pg(&e.format);
36107 self.write_keyword("TO_TIMESTAMP");
36108 self.write("(");
36109 self.generate_expression(&e.this)?;
36110 self.write(", '");
36111 self.write(&pg_fmt);
36112 self.write("')");
36113 }
36114 Some(DialectType::Snowflake) => {
36115 self.write_keyword("TO_TIMESTAMP");
36117 self.write("(");
36118 self.generate_expression(&e.this)?;
36119 self.write(", '");
36120 self.write(&e.format);
36121 self.write("')");
36122 }
36123 _ => {
36124 self.write_keyword("STR_TO_TIME");
36126 self.write("(");
36127 self.generate_expression(&e.this)?;
36128 self.write(", '");
36129 self.write(&e.format);
36130 self.write("'");
36131 self.write(")");
36132 }
36133 }
36134 Ok(())
36135 }
36136
36137 fn snowflake_format_to_strftime(format: &str) -> String {
36139 let mut result = String::new();
36140 let chars: Vec<char> = format.chars().collect();
36141 let mut i = 0;
36142 while i < chars.len() {
36143 let remaining = &format[i..];
36144 if remaining.starts_with("yyyy") {
36145 result.push_str("%Y");
36146 i += 4;
36147 } else if remaining.starts_with("yy") {
36148 result.push_str("%y");
36149 i += 2;
36150 } else if remaining.starts_with("mmmm") {
36151 result.push_str("%B"); i += 4;
36153 } else if remaining.starts_with("mon") {
36154 result.push_str("%b"); i += 3;
36156 } else if remaining.starts_with("mm") {
36157 result.push_str("%m");
36158 i += 2;
36159 } else if remaining.starts_with("DD") {
36160 result.push_str("%d");
36161 i += 2;
36162 } else if remaining.starts_with("dy") {
36163 result.push_str("%a"); i += 2;
36165 } else if remaining.starts_with("hh24") {
36166 result.push_str("%H");
36167 i += 4;
36168 } else if remaining.starts_with("hh12") {
36169 result.push_str("%I");
36170 i += 4;
36171 } else if remaining.starts_with("hh") {
36172 result.push_str("%H");
36173 i += 2;
36174 } else if remaining.starts_with("mi") {
36175 result.push_str("%M");
36176 i += 2;
36177 } else if remaining.starts_with("ss") {
36178 result.push_str("%S");
36179 i += 2;
36180 } else if remaining.starts_with("ff") {
36181 result.push_str("%f");
36183 i += 2;
36184 while i < chars.len() && chars[i].is_ascii_digit() {
36186 i += 1;
36187 }
36188 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
36189 result.push_str("%p");
36190 i += 2;
36191 } else if remaining.starts_with("tz") {
36192 result.push_str("%Z");
36193 i += 2;
36194 } else {
36195 result.push(chars[i]);
36196 i += 1;
36197 }
36198 }
36199 result
36200 }
36201
36202 fn snowflake_format_to_spark(format: &str) -> String {
36204 let mut result = String::new();
36205 let chars: Vec<char> = format.chars().collect();
36206 let mut i = 0;
36207 while i < chars.len() {
36208 let remaining = &format[i..];
36209 if remaining.starts_with("yyyy") {
36210 result.push_str("yyyy");
36211 i += 4;
36212 } else if remaining.starts_with("yy") {
36213 result.push_str("yy");
36214 i += 2;
36215 } else if remaining.starts_with("mmmm") {
36216 result.push_str("MMMM"); i += 4;
36218 } else if remaining.starts_with("mon") {
36219 result.push_str("MMM"); i += 3;
36221 } else if remaining.starts_with("mm") {
36222 result.push_str("MM");
36223 i += 2;
36224 } else if remaining.starts_with("DD") {
36225 result.push_str("dd");
36226 i += 2;
36227 } else if remaining.starts_with("dy") {
36228 result.push_str("EEE"); i += 2;
36230 } else if remaining.starts_with("hh24") {
36231 result.push_str("HH");
36232 i += 4;
36233 } else if remaining.starts_with("hh12") {
36234 result.push_str("hh");
36235 i += 4;
36236 } else if remaining.starts_with("hh") {
36237 result.push_str("HH");
36238 i += 2;
36239 } else if remaining.starts_with("mi") {
36240 result.push_str("mm");
36241 i += 2;
36242 } else if remaining.starts_with("ss") {
36243 result.push_str("ss");
36244 i += 2;
36245 } else if remaining.starts_with("ff") {
36246 result.push_str("SSS"); i += 2;
36248 while i < chars.len() && chars[i].is_ascii_digit() {
36250 i += 1;
36251 }
36252 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
36253 result.push_str("a");
36254 i += 2;
36255 } else if remaining.starts_with("tz") {
36256 result.push_str("z");
36257 i += 2;
36258 } else {
36259 result.push(chars[i]);
36260 i += 1;
36261 }
36262 }
36263 result
36264 }
36265
36266 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
36267 match self.config.dialect {
36268 Some(DialectType::DuckDB) => {
36269 self.write_keyword("EPOCH");
36271 self.write("(");
36272 self.write_keyword("STRPTIME");
36273 self.write("(");
36274 if let Some(this) = &e.this {
36275 self.generate_expression(this)?;
36276 }
36277 if let Some(format) = &e.format {
36278 self.write(", '");
36279 self.write(format);
36280 self.write("'");
36281 }
36282 self.write("))");
36283 }
36284 Some(DialectType::Hive) => {
36285 self.write_keyword("UNIX_TIMESTAMP");
36287 self.write("(");
36288 if let Some(this) = &e.this {
36289 self.generate_expression(this)?;
36290 }
36291 if let Some(format) = &e.format {
36292 let java_fmt = Self::strftime_to_java_format(format);
36293 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
36294 self.write(", '");
36295 self.write(&java_fmt);
36296 self.write("'");
36297 }
36298 }
36299 self.write(")");
36300 }
36301 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
36302 self.write_keyword("UNIX_TIMESTAMP");
36304 self.write("(");
36305 if let Some(this) = &e.this {
36306 self.generate_expression(this)?;
36307 }
36308 if let Some(format) = &e.format {
36309 self.write(", '");
36310 self.write(format);
36311 self.write("'");
36312 }
36313 self.write(")");
36314 }
36315 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36316 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
36319 let java_fmt = Self::strftime_to_java_format(c_fmt);
36320 self.write_keyword("TO_UNIXTIME");
36321 self.write("(");
36322 self.write_keyword("COALESCE");
36323 self.write("(");
36324 self.write_keyword("TRY");
36325 self.write("(");
36326 self.write_keyword("DATE_PARSE");
36327 self.write("(");
36328 self.write_keyword("CAST");
36329 self.write("(");
36330 if let Some(this) = &e.this {
36331 self.generate_expression(this)?;
36332 }
36333 self.write(" ");
36334 self.write_keyword("AS VARCHAR");
36335 self.write("), '");
36336 self.write(c_fmt);
36337 self.write("')), ");
36338 self.write_keyword("PARSE_DATETIME");
36339 self.write("(");
36340 self.write_keyword("DATE_FORMAT");
36341 self.write("(");
36342 self.write_keyword("CAST");
36343 self.write("(");
36344 if let Some(this) = &e.this {
36345 self.generate_expression(this)?;
36346 }
36347 self.write(" ");
36348 self.write_keyword("AS TIMESTAMP");
36349 self.write("), '");
36350 self.write(c_fmt);
36351 self.write("'), '");
36352 self.write(&java_fmt);
36353 self.write("')))");
36354 }
36355 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36356 self.write_keyword("UNIX_TIMESTAMP");
36358 self.write("(");
36359 if let Some(this) = &e.this {
36360 self.generate_expression(this)?;
36361 }
36362 if let Some(format) = &e.format {
36363 let java_fmt = Self::strftime_to_java_format(format);
36364 self.write(", '");
36365 self.write(&java_fmt);
36366 self.write("'");
36367 }
36368 self.write(")");
36369 }
36370 _ => {
36371 self.write_keyword("STR_TO_UNIX");
36373 self.write("(");
36374 if let Some(this) = &e.this {
36375 self.generate_expression(this)?;
36376 }
36377 if let Some(format) = &e.format {
36378 self.write(", '");
36379 self.write(format);
36380 self.write("'");
36381 }
36382 self.write(")");
36383 }
36384 }
36385 Ok(())
36386 }
36387
36388 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
36389 self.write_keyword("STRING_TO_ARRAY");
36391 self.write("(");
36392 self.generate_expression(&e.this)?;
36393 if let Some(expression) = &e.expression {
36394 self.write(", ");
36395 self.generate_expression(expression)?;
36396 }
36397 if let Some(null_val) = &e.null {
36398 self.write(", ");
36399 self.generate_expression(null_val)?;
36400 }
36401 self.write(")");
36402 Ok(())
36403 }
36404
36405 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
36406 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
36407 self.write_keyword("OBJECT_CONSTRUCT");
36409 self.write("(");
36410 for (i, (name, expr)) in e.fields.iter().enumerate() {
36411 if i > 0 {
36412 self.write(", ");
36413 }
36414 if let Some(name) = name {
36415 self.write("'");
36416 self.write(name);
36417 self.write("'");
36418 self.write(", ");
36419 } else {
36420 self.write("'_");
36421 self.write(&i.to_string());
36422 self.write("'");
36423 self.write(", ");
36424 }
36425 self.generate_expression(expr)?;
36426 }
36427 self.write(")");
36428 } else if self.config.struct_curly_brace_notation {
36429 self.write("{");
36431 for (i, (name, expr)) in e.fields.iter().enumerate() {
36432 if i > 0 {
36433 self.write(", ");
36434 }
36435 if let Some(name) = name {
36436 self.write("'");
36438 self.write(name);
36439 self.write("'");
36440 self.write(": ");
36441 } else {
36442 self.write("'_");
36444 self.write(&i.to_string());
36445 self.write("'");
36446 self.write(": ");
36447 }
36448 self.generate_expression(expr)?;
36449 }
36450 self.write("}");
36451 } else {
36452 let value_as_name = matches!(
36456 self.config.dialect,
36457 Some(DialectType::BigQuery)
36458 | Some(DialectType::Spark)
36459 | Some(DialectType::Databricks)
36460 | Some(DialectType::Hive)
36461 );
36462 self.write_keyword("STRUCT");
36463 self.write("(");
36464 for (i, (name, expr)) in e.fields.iter().enumerate() {
36465 if i > 0 {
36466 self.write(", ");
36467 }
36468 if let Some(name) = name {
36469 if value_as_name {
36470 self.generate_expression(expr)?;
36472 self.write_space();
36473 self.write_keyword("AS");
36474 self.write_space();
36475 let needs_quoting = name.contains(' ') || name.contains('-');
36477 if needs_quoting {
36478 if matches!(
36479 self.config.dialect,
36480 Some(DialectType::Spark)
36481 | Some(DialectType::Databricks)
36482 | Some(DialectType::Hive)
36483 ) {
36484 self.write("`");
36485 self.write(name);
36486 self.write("`");
36487 } else {
36488 self.write(name);
36489 }
36490 } else {
36491 self.write(name);
36492 }
36493 } else {
36494 self.write(name);
36496 self.write_space();
36497 self.write_keyword("AS");
36498 self.write_space();
36499 self.generate_expression(expr)?;
36500 }
36501 } else {
36502 self.generate_expression(expr)?;
36503 }
36504 }
36505 self.write(")");
36506 }
36507 Ok(())
36508 }
36509
36510 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
36511 self.write_keyword("STUFF");
36513 self.write("(");
36514 self.generate_expression(&e.this)?;
36515 if let Some(start) = &e.start {
36516 self.write(", ");
36517 self.generate_expression(start)?;
36518 }
36519 if let Some(length) = e.length {
36520 self.write(", ");
36521 self.write(&length.to_string());
36522 }
36523 self.write(", ");
36524 self.generate_expression(&e.expression)?;
36525 self.write(")");
36526 Ok(())
36527 }
36528
36529 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
36530 self.write_keyword("SUBSTRING_INDEX");
36532 self.write("(");
36533 self.generate_expression(&e.this)?;
36534 if let Some(delimiter) = &e.delimiter {
36535 self.write(", ");
36536 self.generate_expression(delimiter)?;
36537 }
36538 if let Some(count) = &e.count {
36539 self.write(", ");
36540 self.generate_expression(count)?;
36541 }
36542 self.write(")");
36543 Ok(())
36544 }
36545
36546 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
36547 self.write_keyword("SUMMARIZE");
36549 if e.table.is_some() {
36550 self.write_space();
36551 self.write_keyword("TABLE");
36552 }
36553 self.write_space();
36554 self.generate_expression(&e.this)?;
36555 Ok(())
36556 }
36557
36558 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
36559 self.write_keyword("SYSTIMESTAMP");
36561 Ok(())
36562 }
36563
36564 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
36565 if let Some(this) = &e.this {
36567 self.generate_expression(this)?;
36568 }
36569 if !e.columns.is_empty() {
36570 self.write("(");
36571 for (i, col) in e.columns.iter().enumerate() {
36572 if i > 0 {
36573 self.write(", ");
36574 }
36575 self.generate_expression(col)?;
36576 }
36577 self.write(")");
36578 }
36579 Ok(())
36580 }
36581
36582 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
36583 self.write_keyword("TABLE");
36585 self.write("(");
36586 self.generate_expression(&e.this)?;
36587 self.write(")");
36588 if let Some(alias) = &e.alias {
36589 self.write_space();
36590 self.write_keyword("AS");
36591 self.write_space();
36592 self.write(alias);
36593 }
36594 Ok(())
36595 }
36596
36597 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
36598 self.write_keyword("ROWS FROM");
36600 self.write(" (");
36601 for (i, expr) in e.expressions.iter().enumerate() {
36602 if i > 0 {
36603 self.write(", ");
36604 }
36605 match expr {
36609 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
36610 self.generate_expression(&tuple.expressions[0])?;
36612 self.write_space();
36613 self.write_keyword("AS");
36614 self.write_space();
36615 self.generate_expression(&tuple.expressions[1])?;
36616 }
36617 _ => {
36618 self.generate_expression(expr)?;
36619 }
36620 }
36621 }
36622 self.write(")");
36623 if e.ordinality {
36624 self.write_space();
36625 self.write_keyword("WITH ORDINALITY");
36626 }
36627 if let Some(alias) = &e.alias {
36628 self.write_space();
36629 self.write_keyword("AS");
36630 self.write_space();
36631 self.generate_expression(alias)?;
36632 }
36633 Ok(())
36634 }
36635
36636 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
36637 use crate::dialects::DialectType;
36638
36639 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
36641 if self.config.alias_post_tablesample {
36643 if let Expression::Subquery(ref s) = **this {
36645 if let Some(ref alias) = s.alias {
36646 let mut subquery_no_alias = (**s).clone();
36648 subquery_no_alias.alias = None;
36649 subquery_no_alias.column_aliases = Vec::new();
36650 self.generate_expression(&Expression::Subquery(Box::new(
36651 subquery_no_alias,
36652 )))?;
36653 self.write_space();
36654 self.write_keyword(self.config.tablesample_keywords);
36655 self.generate_sample_body(sample)?;
36656 if let Some(ref seed) = sample.seed {
36657 self.write_space();
36658 let use_seed = sample.use_seed_keyword
36659 && !matches!(
36660 self.config.dialect,
36661 Some(crate::dialects::DialectType::Databricks)
36662 | Some(crate::dialects::DialectType::Spark)
36663 );
36664 if use_seed {
36665 self.write_keyword("SEED");
36666 } else {
36667 self.write_keyword("REPEATABLE");
36668 }
36669 self.write(" (");
36670 self.generate_expression(seed)?;
36671 self.write(")");
36672 }
36673 self.write_space();
36674 self.write_keyword("AS");
36675 self.write_space();
36676 self.generate_identifier(alias)?;
36677 return Ok(());
36678 }
36679 } else if let Expression::Alias(ref a) = **this {
36680 self.generate_expression(&a.this)?;
36682 self.write_space();
36683 self.write_keyword(self.config.tablesample_keywords);
36684 self.generate_sample_body(sample)?;
36685 if let Some(ref seed) = sample.seed {
36686 self.write_space();
36687 let use_seed = sample.use_seed_keyword
36688 && !matches!(
36689 self.config.dialect,
36690 Some(crate::dialects::DialectType::Databricks)
36691 | Some(crate::dialects::DialectType::Spark)
36692 );
36693 if use_seed {
36694 self.write_keyword("SEED");
36695 } else {
36696 self.write_keyword("REPEATABLE");
36697 }
36698 self.write(" (");
36699 self.generate_expression(seed)?;
36700 self.write(")");
36701 }
36702 self.write_space();
36704 self.write_keyword("AS");
36705 self.write_space();
36706 self.generate_identifier(&a.alias)?;
36707 return Ok(());
36708 }
36709 }
36710 self.generate_expression(this)?;
36712 self.write_space();
36713 self.write_keyword(self.config.tablesample_keywords);
36714 self.generate_sample_body(sample)?;
36715 if let Some(ref seed) = sample.seed {
36717 self.write_space();
36718 let use_seed = sample.use_seed_keyword
36720 && !matches!(
36721 self.config.dialect,
36722 Some(crate::dialects::DialectType::Databricks)
36723 | Some(crate::dialects::DialectType::Spark)
36724 );
36725 if use_seed {
36726 self.write_keyword("SEED");
36727 } else {
36728 self.write_keyword("REPEATABLE");
36729 }
36730 self.write(" (");
36731 self.generate_expression(seed)?;
36732 self.write(")");
36733 }
36734 return Ok(());
36735 }
36736
36737 self.write_keyword(self.config.tablesample_keywords);
36739 if let Some(method) = &e.method {
36740 self.write_space();
36741 self.write_keyword(method);
36742 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
36743 self.write_space();
36745 self.write_keyword("BERNOULLI");
36746 }
36747 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
36748 self.write_space();
36749 self.write_keyword("BUCKET");
36750 self.write_space();
36751 self.generate_expression(numerator)?;
36752 self.write_space();
36753 self.write_keyword("OUT OF");
36754 self.write_space();
36755 self.generate_expression(denominator)?;
36756 if let Some(field) = &e.bucket_field {
36757 self.write_space();
36758 self.write_keyword("ON");
36759 self.write_space();
36760 self.generate_expression(field)?;
36761 }
36762 } else if !e.expressions.is_empty() {
36763 self.write(" (");
36764 for (i, expr) in e.expressions.iter().enumerate() {
36765 if i > 0 {
36766 self.write(", ");
36767 }
36768 self.generate_expression(expr)?;
36769 }
36770 self.write(")");
36771 } else if let Some(percent) = &e.percent {
36772 self.write(" (");
36773 self.generate_expression(percent)?;
36774 self.write_space();
36775 self.write_keyword("PERCENT");
36776 self.write(")");
36777 }
36778 Ok(())
36779 }
36780
36781 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
36782 if let Some(prefix) = &e.prefix {
36784 self.generate_expression(prefix)?;
36785 }
36786 if let Some(this) = &e.this {
36787 self.generate_expression(this)?;
36788 }
36789 if let Some(postfix) = &e.postfix {
36790 self.generate_expression(postfix)?;
36791 }
36792 Ok(())
36793 }
36794
36795 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
36796 self.write_keyword("TAG");
36798 self.write(" (");
36799 for (i, expr) in e.expressions.iter().enumerate() {
36800 if i > 0 {
36801 self.write(", ");
36802 }
36803 self.generate_expression(expr)?;
36804 }
36805 self.write(")");
36806 Ok(())
36807 }
36808
36809 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
36810 if let Some(this) = &e.this {
36812 self.generate_expression(this)?;
36813 self.write_space();
36814 }
36815 self.write_keyword("TEMPORARY");
36816 Ok(())
36817 }
36818
36819 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
36822 self.write_keyword("TIME");
36824 self.write("(");
36825 self.generate_expression(&e.this)?;
36826 self.write(")");
36827 Ok(())
36828 }
36829
36830 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
36831 self.write_keyword("TIME_ADD");
36833 self.write("(");
36834 self.generate_expression(&e.this)?;
36835 self.write(", ");
36836 self.generate_expression(&e.expression)?;
36837 if let Some(unit) = &e.unit {
36838 self.write(", ");
36839 self.write_keyword(unit);
36840 }
36841 self.write(")");
36842 Ok(())
36843 }
36844
36845 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
36846 self.write_keyword("TIME_DIFF");
36848 self.write("(");
36849 self.generate_expression(&e.this)?;
36850 self.write(", ");
36851 self.generate_expression(&e.expression)?;
36852 if let Some(unit) = &e.unit {
36853 self.write(", ");
36854 self.write_keyword(unit);
36855 }
36856 self.write(")");
36857 Ok(())
36858 }
36859
36860 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
36861 self.write_keyword("TIME_FROM_PARTS");
36863 self.write("(");
36864 let mut first = true;
36865 if let Some(hour) = &e.hour {
36866 self.generate_expression(hour)?;
36867 first = false;
36868 }
36869 if let Some(minute) = &e.min {
36870 if !first {
36871 self.write(", ");
36872 }
36873 self.generate_expression(minute)?;
36874 first = false;
36875 }
36876 if let Some(second) = &e.sec {
36877 if !first {
36878 self.write(", ");
36879 }
36880 self.generate_expression(second)?;
36881 first = false;
36882 }
36883 if let Some(ns) = &e.nano {
36884 if !first {
36885 self.write(", ");
36886 }
36887 self.generate_expression(ns)?;
36888 }
36889 self.write(")");
36890 Ok(())
36891 }
36892
36893 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
36894 self.write_keyword("TIME_SLICE");
36896 self.write("(");
36897 self.generate_expression(&e.this)?;
36898 self.write(", ");
36899 self.generate_expression(&e.expression)?;
36900 self.write(", ");
36901 self.write_keyword(&e.unit);
36902 self.write(")");
36903 Ok(())
36904 }
36905
36906 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
36907 self.write_keyword("TIME_STR_TO_TIME");
36909 self.write("(");
36910 self.generate_expression(&e.this)?;
36911 self.write(")");
36912 Ok(())
36913 }
36914
36915 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
36916 self.write_keyword("TIME_SUB");
36918 self.write("(");
36919 self.generate_expression(&e.this)?;
36920 self.write(", ");
36921 self.generate_expression(&e.expression)?;
36922 if let Some(unit) = &e.unit {
36923 self.write(", ");
36924 self.write_keyword(unit);
36925 }
36926 self.write(")");
36927 Ok(())
36928 }
36929
36930 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
36931 match self.config.dialect {
36932 Some(DialectType::Exasol) => {
36933 self.write_keyword("TO_CHAR");
36935 self.write("(");
36936 self.generate_expression(&e.this)?;
36937 self.write(", '");
36938 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
36939 self.write("'");
36940 self.write(")");
36941 }
36942 Some(DialectType::PostgreSQL)
36943 | Some(DialectType::Redshift)
36944 | Some(DialectType::Materialize) => {
36945 self.write_keyword("TO_CHAR");
36947 self.write("(");
36948 self.generate_expression(&e.this)?;
36949 self.write(", '");
36950 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
36951 self.write("'");
36952 self.write(")");
36953 }
36954 Some(DialectType::Oracle) => {
36955 self.write_keyword("TO_CHAR");
36957 self.write("(");
36958 self.generate_expression(&e.this)?;
36959 self.write(", '");
36960 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
36961 self.write("'");
36962 self.write(")");
36963 }
36964 Some(DialectType::Drill) => {
36965 self.write_keyword("TO_CHAR");
36967 self.write("(");
36968 self.generate_expression(&e.this)?;
36969 self.write(", '");
36970 self.write(&Self::strftime_to_java_format(&e.format));
36971 self.write("'");
36972 self.write(")");
36973 }
36974 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
36975 self.write_keyword("FORMAT");
36977 self.write("(");
36978 self.generate_expression(&e.this)?;
36979 self.write(", '");
36980 self.write(&Self::strftime_to_tsql_format(&e.format));
36981 self.write("'");
36982 self.write(")");
36983 }
36984 Some(DialectType::DuckDB) => {
36985 self.write_keyword("STRFTIME");
36987 self.write("(");
36988 self.generate_expression(&e.this)?;
36989 self.write(", '");
36990 self.write(&e.format);
36991 self.write("'");
36992 self.write(")");
36993 }
36994 Some(DialectType::BigQuery) => {
36995 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
36998 self.write_keyword("FORMAT_DATE");
36999 self.write("('");
37000 self.write(&fmt);
37001 self.write("', ");
37002 self.generate_expression(&e.this)?;
37003 self.write(")");
37004 }
37005 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
37006 self.write_keyword("DATE_FORMAT");
37008 self.write("(");
37009 self.generate_expression(&e.this)?;
37010 self.write(", '");
37011 self.write(&Self::strftime_to_java_format(&e.format));
37012 self.write("'");
37013 self.write(")");
37014 }
37015 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
37016 self.write_keyword("DATE_FORMAT");
37018 self.write("(");
37019 self.generate_expression(&e.this)?;
37020 self.write(", '");
37021 self.write(&e.format);
37022 self.write("'");
37023 self.write(")");
37024 }
37025 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
37026 self.write_keyword("DATE_FORMAT");
37028 self.write("(");
37029 self.generate_expression(&e.this)?;
37030 self.write(", '");
37031 self.write(&e.format);
37032 self.write("'");
37033 self.write(")");
37034 }
37035 _ => {
37036 self.write_keyword("TIME_TO_STR");
37038 self.write("(");
37039 self.generate_expression(&e.this)?;
37040 self.write(", '");
37041 self.write(&e.format);
37042 self.write("'");
37043 self.write(")");
37044 }
37045 }
37046 Ok(())
37047 }
37048
37049 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
37050 match self.config.dialect {
37051 Some(DialectType::DuckDB) => {
37052 self.write_keyword("EPOCH");
37054 self.write("(");
37055 self.generate_expression(&e.this)?;
37056 self.write(")");
37057 }
37058 Some(DialectType::Hive)
37059 | Some(DialectType::Spark)
37060 | Some(DialectType::Databricks)
37061 | Some(DialectType::Doris)
37062 | Some(DialectType::StarRocks)
37063 | Some(DialectType::Drill) => {
37064 self.write_keyword("UNIX_TIMESTAMP");
37066 self.write("(");
37067 self.generate_expression(&e.this)?;
37068 self.write(")");
37069 }
37070 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37071 self.write_keyword("TO_UNIXTIME");
37073 self.write("(");
37074 self.generate_expression(&e.this)?;
37075 self.write(")");
37076 }
37077 _ => {
37078 self.write_keyword("TIME_TO_UNIX");
37080 self.write("(");
37081 self.generate_expression(&e.this)?;
37082 self.write(")");
37083 }
37084 }
37085 Ok(())
37086 }
37087
37088 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
37089 match self.config.dialect {
37090 Some(DialectType::Hive) => {
37091 self.write_keyword("TO_DATE");
37093 self.write("(");
37094 self.generate_expression(&e.this)?;
37095 self.write(")");
37096 }
37097 _ => {
37098 self.write_keyword("TIME_STR_TO_DATE");
37100 self.write("(");
37101 self.generate_expression(&e.this)?;
37102 self.write(")");
37103 }
37104 }
37105 Ok(())
37106 }
37107
37108 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
37109 self.write_keyword("TIME_TRUNC");
37111 self.write("(");
37112 self.generate_expression(&e.this)?;
37113 self.write(", ");
37114 self.write_keyword(&e.unit);
37115 self.write(")");
37116 Ok(())
37117 }
37118
37119 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
37120 if let Some(unit) = &e.unit {
37122 self.write_keyword(unit);
37123 }
37124 Ok(())
37125 }
37126
37127 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
37131 use crate::dialects::DialectType;
37132 use crate::expressions::Literal;
37133
37134 match self.config.dialect {
37135 Some(DialectType::Exasol) => {
37137 self.write_keyword("TO_TIMESTAMP");
37138 self.write("(");
37139 if let Some(this) = &e.this {
37141 match this.as_ref() {
37142 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
37143 let Literal::String(s) = lit.as_ref() else {
37144 unreachable!()
37145 };
37146 self.write("'");
37147 self.write(s);
37148 self.write("'");
37149 }
37150 _ => {
37151 self.generate_expression(this)?;
37152 }
37153 }
37154 }
37155 self.write(")");
37156 }
37157 _ => {
37159 self.write_keyword("TIMESTAMP");
37160 self.write("(");
37161 if let Some(this) = &e.this {
37162 self.generate_expression(this)?;
37163 }
37164 if let Some(zone) = &e.zone {
37165 self.write(", ");
37166 self.generate_expression(zone)?;
37167 }
37168 self.write(")");
37169 }
37170 }
37171 Ok(())
37172 }
37173
37174 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
37175 self.write_keyword("TIMESTAMP_ADD");
37177 self.write("(");
37178 self.generate_expression(&e.this)?;
37179 self.write(", ");
37180 self.generate_expression(&e.expression)?;
37181 if let Some(unit) = &e.unit {
37182 self.write(", ");
37183 self.write_keyword(unit);
37184 }
37185 self.write(")");
37186 Ok(())
37187 }
37188
37189 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
37190 self.write_keyword("TIMESTAMP_DIFF");
37192 self.write("(");
37193 self.generate_expression(&e.this)?;
37194 self.write(", ");
37195 self.generate_expression(&e.expression)?;
37196 if let Some(unit) = &e.unit {
37197 self.write(", ");
37198 self.write_keyword(unit);
37199 }
37200 self.write(")");
37201 Ok(())
37202 }
37203
37204 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
37205 self.write_keyword("TIMESTAMP_FROM_PARTS");
37207 self.write("(");
37208 if let Some(this) = &e.this {
37209 self.generate_expression(this)?;
37210 }
37211 if let Some(expression) = &e.expression {
37212 self.write(", ");
37213 self.generate_expression(expression)?;
37214 }
37215 if let Some(zone) = &e.zone {
37216 self.write(", ");
37217 self.generate_expression(zone)?;
37218 }
37219 if let Some(milli) = &e.milli {
37220 self.write(", ");
37221 self.generate_expression(milli)?;
37222 }
37223 self.write(")");
37224 Ok(())
37225 }
37226
37227 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
37228 self.write_keyword("TIMESTAMP_SUB");
37230 self.write("(");
37231 self.generate_expression(&e.this)?;
37232 self.write(", ");
37233 self.write_keyword("INTERVAL");
37234 self.write_space();
37235 self.generate_expression(&e.expression)?;
37236 if let Some(unit) = &e.unit {
37237 self.write_space();
37238 self.write_keyword(unit);
37239 }
37240 self.write(")");
37241 Ok(())
37242 }
37243
37244 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
37245 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
37247 self.write("(");
37248 if let Some(zone) = &e.zone {
37249 self.generate_expression(zone)?;
37250 }
37251 self.write(")");
37252 Ok(())
37253 }
37254
37255 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
37256 self.write_keyword("TO_BINARY");
37258 self.write("(");
37259 self.generate_expression(&e.this)?;
37260 if let Some(format) = &e.format {
37261 self.write(", '");
37262 self.write(format);
37263 self.write("'");
37264 }
37265 self.write(")");
37266 Ok(())
37267 }
37268
37269 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
37270 self.write_keyword("TO_BOOLEAN");
37272 self.write("(");
37273 self.generate_expression(&e.this)?;
37274 self.write(")");
37275 Ok(())
37276 }
37277
37278 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
37279 self.write_keyword("TO_CHAR");
37281 self.write("(");
37282 self.generate_expression(&e.this)?;
37283 if let Some(format) = &e.format {
37284 self.write(", '");
37285 self.write(format);
37286 self.write("'");
37287 }
37288 if let Some(nlsparam) = &e.nlsparam {
37289 self.write(", ");
37290 self.generate_expression(nlsparam)?;
37291 }
37292 self.write(")");
37293 Ok(())
37294 }
37295
37296 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
37297 self.write_keyword("TO_DECFLOAT");
37299 self.write("(");
37300 self.generate_expression(&e.this)?;
37301 if let Some(format) = &e.format {
37302 self.write(", '");
37303 self.write(format);
37304 self.write("'");
37305 }
37306 self.write(")");
37307 Ok(())
37308 }
37309
37310 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
37311 self.write_keyword("TO_DOUBLE");
37313 self.write("(");
37314 self.generate_expression(&e.this)?;
37315 if let Some(format) = &e.format {
37316 self.write(", '");
37317 self.write(format);
37318 self.write("'");
37319 }
37320 self.write(")");
37321 Ok(())
37322 }
37323
37324 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
37325 self.write_keyword("TO_FILE");
37327 self.write("(");
37328 self.generate_expression(&e.this)?;
37329 if let Some(path) = &e.path {
37330 self.write(", ");
37331 self.generate_expression(path)?;
37332 }
37333 self.write(")");
37334 Ok(())
37335 }
37336
37337 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
37338 let is_safe = e.safe.is_some();
37341 if is_safe {
37342 self.write_keyword("TRY_TO_NUMBER");
37343 } else {
37344 self.write_keyword("TO_NUMBER");
37345 }
37346 self.write("(");
37347 self.generate_expression(&e.this)?;
37348 let precision_is_snowflake_default = e.precision.is_none()
37349 || matches!(
37350 e.precision.as_deref(),
37351 Some(Expression::Literal(lit))
37352 if matches!(lit.as_ref(), Literal::Number(n) if n == "0")
37353 );
37354 let is_snowflake_default_precision =
37355 matches!(self.config.dialect, Some(DialectType::Snowflake))
37356 && e.nlsparam.is_none()
37357 && e.scale.is_none()
37358 && matches!(
37359 e.format.as_deref(),
37360 Some(Expression::Literal(lit))
37361 if matches!(lit.as_ref(), Literal::Number(n) if n == "38")
37362 )
37363 && precision_is_snowflake_default;
37364
37365 if !is_snowflake_default_precision {
37366 if let Some(format) = &e.format {
37367 self.write(", ");
37368 self.generate_expression(format)?;
37369 }
37370 if let Some(nlsparam) = &e.nlsparam {
37371 self.write(", ");
37372 self.generate_expression(nlsparam)?;
37373 }
37374 if let Some(precision) = &e.precision {
37375 self.write(", ");
37376 self.generate_expression(precision)?;
37377 }
37378 if let Some(scale) = &e.scale {
37379 self.write(", ");
37380 self.generate_expression(scale)?;
37381 }
37382 }
37383 self.write(")");
37384 Ok(())
37385 }
37386
37387 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
37388 self.write_keyword("TO_TABLE");
37390 self.write_space();
37391 self.generate_expression(&e.this)?;
37392 Ok(())
37393 }
37394
37395 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
37396 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
37398 Expression::Identifier(id) => id.name.clone(),
37399 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
37400 let Literal::String(s) = lit.as_ref() else {
37401 unreachable!()
37402 };
37403 s.clone()
37404 }
37405 _ => String::new(),
37406 });
37407
37408 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
37409 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
37410 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
37411 matches!(m.as_ref(), Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)))
37412 });
37413
37414 let use_start_transaction = matches!(
37416 self.config.dialect,
37417 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
37418 );
37419 let strip_transaction = matches!(
37421 self.config.dialect,
37422 Some(DialectType::Snowflake)
37423 | Some(DialectType::PostgreSQL)
37424 | Some(DialectType::Redshift)
37425 | Some(DialectType::MySQL)
37426 | Some(DialectType::Hive)
37427 | Some(DialectType::Spark)
37428 | Some(DialectType::Databricks)
37429 | Some(DialectType::DuckDB)
37430 | Some(DialectType::Oracle)
37431 | Some(DialectType::Doris)
37432 | Some(DialectType::StarRocks)
37433 | Some(DialectType::Materialize)
37434 | Some(DialectType::ClickHouse)
37435 );
37436
37437 if is_start || use_start_transaction {
37438 self.write_keyword("START TRANSACTION");
37440 if let Some(modes) = &e.modes {
37441 self.write_space();
37442 self.generate_expression(modes)?;
37443 }
37444 } else {
37445 self.write_keyword("BEGIN");
37447
37448 let is_kind = e.this.as_ref().map_or(false, |t| {
37450 if let Expression::Identifier(id) = t.as_ref() {
37451 id.name.eq_ignore_ascii_case("DEFERRED")
37452 || id.name.eq_ignore_ascii_case("IMMEDIATE")
37453 || id.name.eq_ignore_ascii_case("EXCLUSIVE")
37454 } else {
37455 false
37456 }
37457 });
37458
37459 if is_kind {
37461 if let Some(this) = &e.this {
37462 self.write_space();
37463 if let Expression::Identifier(id) = this.as_ref() {
37464 self.write_keyword(&id.name);
37465 }
37466 }
37467 }
37468
37469 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
37471 self.write_space();
37472 self.write_keyword("TRANSACTION");
37473 }
37474
37475 if !is_kind {
37477 if let Some(this) = &e.this {
37478 self.write_space();
37479 self.generate_expression(this)?;
37480 }
37481 }
37482
37483 if has_with_mark {
37485 self.write_space();
37486 self.write_keyword("WITH MARK");
37487 if let Some(Expression::Literal(lit)) = e.mark.as_deref() {
37488 if let Literal::String(desc) = lit.as_ref() {
37489 if !desc.is_empty() {
37490 self.write_space();
37491 self.write(&format!("'{}'", desc));
37492 }
37493 }
37494 }
37495 }
37496
37497 if let Some(modes) = &e.modes {
37499 self.write_space();
37500 self.generate_expression(modes)?;
37501 }
37502 }
37503 Ok(())
37504 }
37505
37506 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
37507 self.write_keyword("TRANSFORM");
37509 self.write("(");
37510 self.generate_expression(&e.this)?;
37511 self.write(", ");
37512 self.generate_expression(&e.expression)?;
37513 self.write(")");
37514 Ok(())
37515 }
37516
37517 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
37518 self.write_keyword("TRANSFORM");
37520 self.write("(");
37521 if self.config.pretty && !e.expressions.is_empty() {
37522 self.indent_level += 1;
37523 for (i, expr) in e.expressions.iter().enumerate() {
37524 if i > 0 {
37525 self.write(",");
37526 }
37527 self.write_newline();
37528 self.write_indent();
37529 self.generate_expression(expr)?;
37530 }
37531 self.indent_level -= 1;
37532 self.write_newline();
37533 self.write(")");
37534 } else {
37535 for (i, expr) in e.expressions.iter().enumerate() {
37536 if i > 0 {
37537 self.write(", ");
37538 }
37539 self.generate_expression(expr)?;
37540 }
37541 self.write(")");
37542 }
37543 Ok(())
37544 }
37545
37546 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
37547 use crate::dialects::DialectType;
37548 if let Some(this) = &e.this {
37550 self.generate_expression(this)?;
37551 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
37552 self.write_space();
37553 }
37554 }
37555 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
37556 self.write_keyword("TRANSIENT");
37557 }
37558 Ok(())
37559 }
37560
37561 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
37562 self.write_keyword("TRANSLATE");
37564 self.write("(");
37565 self.generate_expression(&e.this)?;
37566 if let Some(from) = &e.from_ {
37567 self.write(", ");
37568 self.generate_expression(from)?;
37569 }
37570 if let Some(to) = &e.to {
37571 self.write(", ");
37572 self.generate_expression(to)?;
37573 }
37574 self.write(")");
37575 Ok(())
37576 }
37577
37578 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
37579 self.write_keyword("TRANSLATE");
37581 self.write("(");
37582 self.generate_expression(&e.this)?;
37583 self.write_space();
37584 self.write_keyword("USING");
37585 self.write_space();
37586 self.generate_expression(&e.expression)?;
37587 if e.with_error.is_some() {
37588 self.write_space();
37589 self.write_keyword("WITH ERROR");
37590 }
37591 self.write(")");
37592 Ok(())
37593 }
37594
37595 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
37596 self.write_keyword("TRUNCATE TABLE");
37598 self.write_space();
37599 for (i, expr) in e.expressions.iter().enumerate() {
37600 if i > 0 {
37601 self.write(", ");
37602 }
37603 self.generate_expression(expr)?;
37604 }
37605 Ok(())
37606 }
37607
37608 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
37609 self.write_keyword("TRY_BASE64_DECODE_BINARY");
37611 self.write("(");
37612 self.generate_expression(&e.this)?;
37613 if let Some(alphabet) = &e.alphabet {
37614 self.write(", ");
37615 self.generate_expression(alphabet)?;
37616 }
37617 self.write(")");
37618 Ok(())
37619 }
37620
37621 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
37622 self.write_keyword("TRY_BASE64_DECODE_STRING");
37624 self.write("(");
37625 self.generate_expression(&e.this)?;
37626 if let Some(alphabet) = &e.alphabet {
37627 self.write(", ");
37628 self.generate_expression(alphabet)?;
37629 }
37630 self.write(")");
37631 Ok(())
37632 }
37633
37634 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
37635 self.write_keyword("TRY_TO_DECFLOAT");
37637 self.write("(");
37638 self.generate_expression(&e.this)?;
37639 if let Some(format) = &e.format {
37640 self.write(", '");
37641 self.write(format);
37642 self.write("'");
37643 }
37644 self.write(")");
37645 Ok(())
37646 }
37647
37648 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
37649 self.write_keyword("TS_OR_DS_ADD");
37651 self.write("(");
37652 self.generate_expression(&e.this)?;
37653 self.write(", ");
37654 self.generate_expression(&e.expression)?;
37655 if let Some(unit) = &e.unit {
37656 self.write(", ");
37657 self.write_keyword(unit);
37658 }
37659 if let Some(return_type) = &e.return_type {
37660 self.write(", ");
37661 self.generate_expression(return_type)?;
37662 }
37663 self.write(")");
37664 Ok(())
37665 }
37666
37667 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
37668 self.write_keyword("TS_OR_DS_DIFF");
37670 self.write("(");
37671 self.generate_expression(&e.this)?;
37672 self.write(", ");
37673 self.generate_expression(&e.expression)?;
37674 if let Some(unit) = &e.unit {
37675 self.write(", ");
37676 self.write_keyword(unit);
37677 }
37678 self.write(")");
37679 Ok(())
37680 }
37681
37682 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
37683 let default_time_format = "%Y-%m-%d %H:%M:%S";
37684 let default_date_format = "%Y-%m-%d";
37685 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
37686 f != default_time_format && f != default_date_format
37687 });
37688
37689 if has_non_default_format {
37690 let fmt = e.format.as_ref().unwrap();
37692 match self.config.dialect {
37693 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
37694 let str_to_time = crate::expressions::StrToTime {
37697 this: Box::new((*e.this).clone()),
37698 format: fmt.clone(),
37699 zone: None,
37700 safe: None,
37701 target_type: None,
37702 };
37703 self.generate_str_to_time(&str_to_time)?;
37704 }
37705 Some(DialectType::Hive)
37706 | Some(DialectType::Spark)
37707 | Some(DialectType::Databricks) => {
37708 self.write_keyword("TO_DATE");
37710 self.write("(");
37711 self.generate_expression(&e.this)?;
37712 self.write(", '");
37713 self.write(&Self::strftime_to_java_format(fmt));
37714 self.write("')");
37715 }
37716 Some(DialectType::Snowflake) => {
37717 self.write_keyword("TO_DATE");
37719 self.write("(");
37720 self.generate_expression(&e.this)?;
37721 self.write(", '");
37722 self.write(&Self::strftime_to_snowflake_format(fmt));
37723 self.write("')");
37724 }
37725 Some(DialectType::Doris) => {
37726 self.write_keyword("TO_DATE");
37728 self.write("(");
37729 self.generate_expression(&e.this)?;
37730 self.write(")");
37731 }
37732 _ => {
37733 self.write_keyword("CAST");
37735 self.write("(");
37736 let str_to_time = crate::expressions::StrToTime {
37737 this: Box::new((*e.this).clone()),
37738 format: fmt.clone(),
37739 zone: None,
37740 safe: None,
37741 target_type: None,
37742 };
37743 self.generate_str_to_time(&str_to_time)?;
37744 self.write_keyword(" AS ");
37745 self.write_keyword("DATE");
37746 self.write(")");
37747 }
37748 }
37749 } else {
37750 match self.config.dialect {
37752 Some(DialectType::MySQL)
37753 | Some(DialectType::SQLite)
37754 | Some(DialectType::StarRocks) => {
37755 self.write_keyword("DATE");
37757 self.write("(");
37758 self.generate_expression(&e.this)?;
37759 self.write(")");
37760 }
37761 Some(DialectType::Hive)
37762 | Some(DialectType::Spark)
37763 | Some(DialectType::Databricks)
37764 | Some(DialectType::Snowflake)
37765 | Some(DialectType::Doris) => {
37766 self.write_keyword("TO_DATE");
37768 self.write("(");
37769 self.generate_expression(&e.this)?;
37770 self.write(")");
37771 }
37772 Some(DialectType::Presto)
37773 | Some(DialectType::Trino)
37774 | Some(DialectType::Athena) => {
37775 self.write_keyword("CAST");
37777 self.write("(");
37778 self.write_keyword("CAST");
37779 self.write("(");
37780 self.generate_expression(&e.this)?;
37781 self.write_keyword(" AS ");
37782 self.write_keyword("TIMESTAMP");
37783 self.write(")");
37784 self.write_keyword(" AS ");
37785 self.write_keyword("DATE");
37786 self.write(")");
37787 }
37788 Some(DialectType::ClickHouse) => {
37789 self.write_keyword("CAST");
37791 self.write("(");
37792 self.generate_expression(&e.this)?;
37793 self.write_keyword(" AS ");
37794 self.write("Nullable(DATE)");
37795 self.write(")");
37796 }
37797 _ => {
37798 self.write_keyword("CAST");
37800 self.write("(");
37801 self.generate_expression(&e.this)?;
37802 self.write_keyword(" AS ");
37803 self.write_keyword("DATE");
37804 self.write(")");
37805 }
37806 }
37807 }
37808 Ok(())
37809 }
37810
37811 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
37812 self.write_keyword("TS_OR_DS_TO_TIME");
37814 self.write("(");
37815 self.generate_expression(&e.this)?;
37816 if let Some(format) = &e.format {
37817 self.write(", '");
37818 self.write(format);
37819 self.write("'");
37820 }
37821 self.write(")");
37822 Ok(())
37823 }
37824
37825 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
37826 self.write_keyword("UNHEX");
37828 self.write("(");
37829 self.generate_expression(&e.this)?;
37830 if let Some(expression) = &e.expression {
37831 self.write(", ");
37832 self.generate_expression(expression)?;
37833 }
37834 self.write(")");
37835 Ok(())
37836 }
37837
37838 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
37839 self.write("U&");
37841 self.generate_expression(&e.this)?;
37842 if let Some(escape) = &e.escape {
37843 self.write_space();
37844 self.write_keyword("UESCAPE");
37845 self.write_space();
37846 self.generate_expression(escape)?;
37847 }
37848 Ok(())
37849 }
37850
37851 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
37852 self.write_keyword("UNIFORM");
37854 self.write("(");
37855 self.generate_expression(&e.this)?;
37856 self.write(", ");
37857 self.generate_expression(&e.expression)?;
37858 if let Some(gen) = &e.gen {
37859 self.write(", ");
37860 self.generate_expression(gen)?;
37861 }
37862 if let Some(seed) = &e.seed {
37863 self.write(", ");
37864 self.generate_expression(seed)?;
37865 }
37866 self.write(")");
37867 Ok(())
37868 }
37869
37870 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
37871 self.write_keyword("UNIQUE");
37873 if e.nulls.is_some() {
37875 self.write(" NULLS NOT DISTINCT");
37876 }
37877 if let Some(this) = &e.this {
37878 self.write_space();
37879 self.generate_expression(this)?;
37880 }
37881 if let Some(index_type) = &e.index_type {
37882 self.write(" USING ");
37883 self.generate_expression(index_type)?;
37884 }
37885 if let Some(on_conflict) = &e.on_conflict {
37886 self.write_space();
37887 self.generate_expression(on_conflict)?;
37888 }
37889 for opt in &e.options {
37890 self.write_space();
37891 self.generate_expression(opt)?;
37892 }
37893 Ok(())
37894 }
37895
37896 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
37897 self.write_keyword("UNIQUE KEY");
37899 self.write(" (");
37900 for (i, expr) in e.expressions.iter().enumerate() {
37901 if i > 0 {
37902 self.write(", ");
37903 }
37904 self.generate_expression(expr)?;
37905 }
37906 self.write(")");
37907 Ok(())
37908 }
37909
37910 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
37911 self.write_keyword("ROLLUP");
37913 self.write(" (");
37914 for (i, index) in e.expressions.iter().enumerate() {
37915 if i > 0 {
37916 self.write(", ");
37917 }
37918 self.generate_identifier(&index.name)?;
37919 self.write("(");
37920 for (j, col) in index.expressions.iter().enumerate() {
37921 if j > 0 {
37922 self.write(", ");
37923 }
37924 self.generate_identifier(col)?;
37925 }
37926 self.write(")");
37927 }
37928 self.write(")");
37929 Ok(())
37930 }
37931
37932 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
37933 match self.config.dialect {
37934 Some(DialectType::DuckDB) => {
37935 self.write_keyword("STRFTIME");
37937 self.write("(");
37938 self.write_keyword("TO_TIMESTAMP");
37939 self.write("(");
37940 self.generate_expression(&e.this)?;
37941 self.write("), '");
37942 if let Some(format) = &e.format {
37943 self.write(format);
37944 }
37945 self.write("')");
37946 }
37947 Some(DialectType::Hive) => {
37948 self.write_keyword("FROM_UNIXTIME");
37950 self.write("(");
37951 self.generate_expression(&e.this)?;
37952 if let Some(format) = &e.format {
37953 if format != "yyyy-MM-dd HH:mm:ss" {
37954 self.write(", '");
37955 self.write(format);
37956 self.write("'");
37957 }
37958 }
37959 self.write(")");
37960 }
37961 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37962 self.write_keyword("DATE_FORMAT");
37964 self.write("(");
37965 self.write_keyword("FROM_UNIXTIME");
37966 self.write("(");
37967 self.generate_expression(&e.this)?;
37968 self.write("), '");
37969 if let Some(format) = &e.format {
37970 self.write(format);
37971 }
37972 self.write("')");
37973 }
37974 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
37975 self.write_keyword("FROM_UNIXTIME");
37977 self.write("(");
37978 self.generate_expression(&e.this)?;
37979 if let Some(format) = &e.format {
37980 self.write(", '");
37981 self.write(format);
37982 self.write("'");
37983 }
37984 self.write(")");
37985 }
37986 _ => {
37987 self.write_keyword("UNIX_TO_STR");
37989 self.write("(");
37990 self.generate_expression(&e.this)?;
37991 if let Some(format) = &e.format {
37992 self.write(", '");
37993 self.write(format);
37994 self.write("'");
37995 }
37996 self.write(")");
37997 }
37998 }
37999 Ok(())
38000 }
38001
38002 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
38003 use crate::dialects::DialectType;
38004 let scale = e.scale.unwrap_or(0); match self.config.dialect {
38007 Some(DialectType::Snowflake) => {
38008 self.write_keyword("TO_TIMESTAMP");
38010 self.write("(");
38011 self.generate_expression(&e.this)?;
38012 if let Some(s) = e.scale {
38013 if s > 0 {
38014 self.write(", ");
38015 self.write(&s.to_string());
38016 }
38017 }
38018 self.write(")");
38019 }
38020 Some(DialectType::BigQuery) => {
38021 match scale {
38024 0 => {
38025 self.write_keyword("TIMESTAMP_SECONDS");
38026 self.write("(");
38027 self.generate_expression(&e.this)?;
38028 self.write(")");
38029 }
38030 3 => {
38031 self.write_keyword("TIMESTAMP_MILLIS");
38032 self.write("(");
38033 self.generate_expression(&e.this)?;
38034 self.write(")");
38035 }
38036 6 => {
38037 self.write_keyword("TIMESTAMP_MICROS");
38038 self.write("(");
38039 self.generate_expression(&e.this)?;
38040 self.write(")");
38041 }
38042 _ => {
38043 self.write_keyword("TIMESTAMP_SECONDS");
38045 self.write("(CAST(");
38046 self.generate_expression(&e.this)?;
38047 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
38048 }
38049 }
38050 }
38051 Some(DialectType::Spark) => {
38052 match scale {
38057 0 => {
38058 self.write_keyword("CAST");
38059 self.write("(");
38060 self.write_keyword("FROM_UNIXTIME");
38061 self.write("(");
38062 self.generate_expression(&e.this)?;
38063 self.write(") ");
38064 self.write_keyword("AS TIMESTAMP");
38065 self.write(")");
38066 }
38067 3 => {
38068 self.write_keyword("TIMESTAMP_MILLIS");
38069 self.write("(");
38070 self.generate_expression(&e.this)?;
38071 self.write(")");
38072 }
38073 6 => {
38074 self.write_keyword("TIMESTAMP_MICROS");
38075 self.write("(");
38076 self.generate_expression(&e.this)?;
38077 self.write(")");
38078 }
38079 _ => {
38080 self.write_keyword("TIMESTAMP_SECONDS");
38081 self.write("(");
38082 self.generate_expression(&e.this)?;
38083 self.write(&format!(" / POWER(10, {}))", scale));
38084 }
38085 }
38086 }
38087 Some(DialectType::Databricks) => {
38088 match scale {
38092 0 => {
38093 self.write_keyword("CAST");
38094 self.write("(");
38095 self.write_keyword("FROM_UNIXTIME");
38096 self.write("(");
38097 self.generate_expression(&e.this)?;
38098 self.write(") ");
38099 self.write_keyword("AS TIMESTAMP");
38100 self.write(")");
38101 }
38102 3 => {
38103 self.write_keyword("TIMESTAMP_MILLIS");
38104 self.write("(");
38105 self.generate_expression(&e.this)?;
38106 self.write(")");
38107 }
38108 6 => {
38109 self.write_keyword("TIMESTAMP_MICROS");
38110 self.write("(");
38111 self.generate_expression(&e.this)?;
38112 self.write(")");
38113 }
38114 _ => {
38115 self.write_keyword("TIMESTAMP_SECONDS");
38116 self.write("(");
38117 self.generate_expression(&e.this)?;
38118 self.write(&format!(" / POWER(10, {}))", scale));
38119 }
38120 }
38121 }
38122 Some(DialectType::Hive) => {
38123 if scale == 0 {
38125 self.write_keyword("FROM_UNIXTIME");
38126 self.write("(");
38127 self.generate_expression(&e.this)?;
38128 self.write(")");
38129 } else {
38130 self.write_keyword("FROM_UNIXTIME");
38131 self.write("(");
38132 self.generate_expression(&e.this)?;
38133 self.write(&format!(" / POWER(10, {})", scale));
38134 self.write(")");
38135 }
38136 }
38137 Some(DialectType::Presto) | Some(DialectType::Trino) => {
38138 if scale == 0 {
38141 self.write_keyword("FROM_UNIXTIME");
38142 self.write("(");
38143 self.generate_expression(&e.this)?;
38144 self.write(")");
38145 } else {
38146 self.write_keyword("FROM_UNIXTIME");
38147 self.write("(CAST(");
38148 self.generate_expression(&e.this)?;
38149 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
38150 }
38151 }
38152 Some(DialectType::DuckDB) => {
38153 match scale {
38157 0 => {
38158 self.write_keyword("TO_TIMESTAMP");
38159 self.write("(");
38160 self.generate_expression(&e.this)?;
38161 self.write(")");
38162 }
38163 3 => {
38164 self.write_keyword("EPOCH_MS");
38165 self.write("(");
38166 self.generate_expression(&e.this)?;
38167 self.write(")");
38168 }
38169 6 => {
38170 self.write_keyword("MAKE_TIMESTAMP");
38171 self.write("(");
38172 self.generate_expression(&e.this)?;
38173 self.write(")");
38174 }
38175 _ => {
38176 self.write_keyword("TO_TIMESTAMP");
38177 self.write("(");
38178 self.generate_expression(&e.this)?;
38179 self.write(&format!(" / POWER(10, {}))", scale));
38180 self.write_keyword(" AT TIME ZONE");
38181 self.write(" 'UTC'");
38182 }
38183 }
38184 }
38185 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
38186 self.write_keyword("FROM_UNIXTIME");
38188 self.write("(");
38189 self.generate_expression(&e.this)?;
38190 self.write(")");
38191 }
38192 Some(DialectType::Oracle) => {
38193 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
38195 self.generate_expression(&e.this)?;
38196 self.write(" / 86400)");
38197 }
38198 Some(DialectType::Redshift) => {
38199 self.write("(TIMESTAMP 'epoch' + ");
38202 if scale == 0 {
38203 self.generate_expression(&e.this)?;
38204 } else {
38205 self.write("(");
38206 self.generate_expression(&e.this)?;
38207 self.write(&format!(" / POWER(10, {}))", scale));
38208 }
38209 self.write(" * INTERVAL '1 SECOND')");
38210 }
38211 Some(DialectType::Exasol) => {
38212 self.write_keyword("FROM_POSIX_TIME");
38214 self.write("(");
38215 self.generate_expression(&e.this)?;
38216 self.write(")");
38217 }
38218 _ => {
38219 self.write_keyword("TO_TIMESTAMP");
38221 self.write("(");
38222 self.generate_expression(&e.this)?;
38223 if let Some(s) = e.scale {
38224 self.write(", ");
38225 self.write(&s.to_string());
38226 }
38227 self.write(")");
38228 }
38229 }
38230 Ok(())
38231 }
38232
38233 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
38234 if !matches!(&*e.this, Expression::Null(_)) {
38236 self.write_keyword("NAME");
38237 self.write_space();
38238 self.generate_expression(&e.this)?;
38239 }
38240 if !e.expressions.is_empty() {
38241 self.write_space();
38242 self.write_keyword("VALUE");
38243 self.write_space();
38244 for (i, expr) in e.expressions.iter().enumerate() {
38245 if i > 0 {
38246 self.write(", ");
38247 }
38248 self.generate_expression(expr)?;
38249 }
38250 }
38251 Ok(())
38252 }
38253
38254 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
38255 if e.wrapped.is_some() {
38257 self.write("(");
38258 }
38259 self.generate_expression(&e.this)?;
38260 if e.wrapped.is_some() {
38261 self.write(")");
38262 }
38263 self.write("(");
38264 for (i, expr) in e.expressions.iter().enumerate() {
38265 if i > 0 {
38266 self.write(", ");
38267 }
38268 self.generate_expression(expr)?;
38269 }
38270 self.write(")");
38271 Ok(())
38272 }
38273
38274 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
38275 self.write_keyword("USING TEMPLATE");
38277 self.write_space();
38278 self.generate_expression(&e.this)?;
38279 Ok(())
38280 }
38281
38282 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
38283 self.write_keyword("UTC_TIME");
38285 Ok(())
38286 }
38287
38288 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
38289 if matches!(
38290 self.config.dialect,
38291 Some(crate::dialects::DialectType::ClickHouse)
38292 ) {
38293 self.write_keyword("CURRENT_TIMESTAMP");
38294 self.write("('UTC')");
38295 } else {
38296 self.write_keyword("UTC_TIMESTAMP");
38297 }
38298 Ok(())
38299 }
38300
38301 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
38302 use crate::dialects::DialectType;
38303 let func_name = match self.config.dialect {
38305 Some(DialectType::Snowflake) => "UUID_STRING",
38306 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
38307 Some(DialectType::BigQuery) => "GENERATE_UUID",
38308 _ => {
38309 if let Some(name) = &e.name {
38310 name.as_str()
38311 } else {
38312 "UUID"
38313 }
38314 }
38315 };
38316 self.write_keyword(func_name);
38317 self.write("(");
38318 if let Some(this) = &e.this {
38319 self.generate_expression(this)?;
38320 }
38321 self.write(")");
38322 Ok(())
38323 }
38324
38325 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
38326 self.write_keyword("MAP");
38328 self.write("(");
38329 let mut first = true;
38330 for (k, v) in e.keys.iter().zip(e.values.iter()) {
38331 if !first {
38332 self.write(", ");
38333 }
38334 self.generate_expression(k)?;
38335 self.write(", ");
38336 self.generate_expression(v)?;
38337 first = false;
38338 }
38339 self.write(")");
38340 Ok(())
38341 }
38342
38343 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
38344 self.write_keyword("VECTOR_SEARCH");
38346 self.write("(");
38347 self.generate_expression(&e.this)?;
38348 if let Some(col) = &e.column_to_search {
38349 self.write(", ");
38350 self.generate_expression(col)?;
38351 }
38352 if let Some(query_table) = &e.query_table {
38353 self.write(", ");
38354 self.generate_expression(query_table)?;
38355 }
38356 if let Some(query_col) = &e.query_column_to_search {
38357 self.write(", ");
38358 self.generate_expression(query_col)?;
38359 }
38360 if let Some(top_k) = &e.top_k {
38361 self.write(", ");
38362 self.generate_expression(top_k)?;
38363 }
38364 if let Some(dist_type) = &e.distance_type {
38365 self.write(", ");
38366 self.generate_expression(dist_type)?;
38367 }
38368 self.write(")");
38369 Ok(())
38370 }
38371
38372 fn generate_version(&mut self, e: &Version) -> Result<()> {
38373 use crate::dialects::DialectType;
38379 let skip_for = matches!(
38380 self.config.dialect,
38381 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
38382 );
38383 if !skip_for {
38384 self.write_keyword("FOR");
38385 self.write_space();
38386 }
38387 match e.this.as_ref() {
38389 Expression::Identifier(ident) => {
38390 self.write_keyword(&ident.name);
38391 }
38392 _ => {
38393 self.generate_expression(&e.this)?;
38394 }
38395 }
38396 self.write_space();
38397 self.write_keyword(&e.kind);
38398 if let Some(expression) = &e.expression {
38399 self.write_space();
38400 self.generate_expression(expression)?;
38401 }
38402 Ok(())
38403 }
38404
38405 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
38406 self.generate_expression(&e.this)?;
38408 Ok(())
38409 }
38410
38411 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
38412 if e.this.is_some() {
38414 self.write_keyword("NOT VOLATILE");
38415 } else {
38416 self.write_keyword("VOLATILE");
38417 }
38418 Ok(())
38419 }
38420
38421 fn generate_watermark_column_constraint(
38422 &mut self,
38423 e: &WatermarkColumnConstraint,
38424 ) -> Result<()> {
38425 self.write_keyword("WATERMARK FOR");
38427 self.write_space();
38428 self.generate_expression(&e.this)?;
38429 self.write_space();
38430 self.write_keyword("AS");
38431 self.write_space();
38432 self.generate_expression(&e.expression)?;
38433 Ok(())
38434 }
38435
38436 fn generate_week(&mut self, e: &Week) -> Result<()> {
38437 self.write_keyword("WEEK");
38439 self.write("(");
38440 self.generate_expression(&e.this)?;
38441 if let Some(mode) = &e.mode {
38442 self.write(", ");
38443 self.generate_expression(mode)?;
38444 }
38445 self.write(")");
38446 Ok(())
38447 }
38448
38449 fn generate_when(&mut self, e: &When) -> Result<()> {
38450 self.write_keyword("WHEN");
38454 self.write_space();
38455
38456 if let Some(matched) = &e.matched {
38458 match matched.as_ref() {
38460 Expression::Boolean(b) if b.value => {
38461 self.write_keyword("MATCHED");
38462 }
38463 _ => {
38464 self.write_keyword("NOT MATCHED");
38465 }
38466 }
38467 } else {
38468 self.write_keyword("NOT MATCHED");
38469 }
38470
38471 if self.config.matched_by_source {
38476 if let Some(source) = &e.source {
38477 if let Expression::Boolean(b) = source.as_ref() {
38478 if b.value {
38479 self.write_space();
38481 self.write_keyword("BY SOURCE");
38482 }
38483 } else {
38485 self.write_space();
38487 self.write_keyword("BY SOURCE");
38488 }
38489 }
38490 }
38491
38492 if let Some(condition) = &e.condition {
38494 self.write_space();
38495 self.write_keyword("AND");
38496 self.write_space();
38497 self.generate_expression(condition)?;
38498 }
38499
38500 self.write_space();
38501 self.write_keyword("THEN");
38502 self.write_space();
38503
38504 self.generate_merge_action(&e.then)?;
38507
38508 Ok(())
38509 }
38510
38511 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
38512 match action {
38513 Expression::Tuple(tuple) => {
38514 let elements = &tuple.expressions;
38515 if elements.is_empty() {
38516 return self.generate_expression(action);
38517 }
38518 match &elements[0] {
38520 Expression::Var(v) if v.this == "INSERT" => {
38521 self.write_keyword("INSERT");
38522 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
38524 self.write(" *");
38525 if let Some(Expression::Where(w)) = elements.get(2) {
38526 self.write_space();
38527 self.generate_where(w)?;
38528 }
38529 } else {
38530 let mut values_idx = 1;
38531 if elements.len() > 1 {
38533 if let Expression::Tuple(cols) = &elements[1] {
38534 if elements.len() > 2 {
38536 self.write(" (");
38538 for (i, col) in cols.expressions.iter().enumerate() {
38539 if i > 0 {
38540 self.write(", ");
38541 }
38542 if !self.merge_strip_qualifiers.is_empty() {
38544 let stripped = self.strip_merge_qualifier(col);
38545 self.generate_expression(&stripped)?;
38546 } else {
38547 self.generate_expression(col)?;
38548 }
38549 }
38550 self.write(")");
38551 values_idx = 2;
38552 } else {
38553 values_idx = 1;
38555 }
38556 }
38557 }
38558 let mut next_idx = values_idx;
38559 if values_idx < elements.len()
38561 && !matches!(&elements[values_idx], Expression::Where(_))
38562 {
38563 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
38565 if !is_row {
38566 self.write_space();
38567 self.write_keyword("VALUES");
38568 }
38569 self.write(" ");
38570 if let Expression::Tuple(vals) = &elements[values_idx] {
38571 self.write("(");
38572 for (i, val) in vals.expressions.iter().enumerate() {
38573 if i > 0 {
38574 self.write(", ");
38575 }
38576 self.generate_expression(val)?;
38577 }
38578 self.write(")");
38579 } else {
38580 self.generate_expression(&elements[values_idx])?;
38581 }
38582 next_idx += 1;
38583 }
38584 if let Some(Expression::Where(w)) = elements.get(next_idx) {
38585 self.write_space();
38586 self.generate_where(w)?;
38587 }
38588 } }
38590 Expression::Var(v) if v.this == "UPDATE" => {
38591 self.write_keyword("UPDATE");
38592 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
38594 self.write(" *");
38595 if let Some(Expression::Where(w)) = elements.get(2) {
38596 self.write_space();
38597 self.generate_where(w)?;
38598 }
38599 } else if elements.len() > 1 {
38600 self.write_space();
38601 self.write_keyword("SET");
38602 if self.config.pretty {
38604 self.write_newline();
38605 self.indent_level += 1;
38606 self.write_indent();
38607 } else {
38608 self.write_space();
38609 }
38610 if let Expression::Tuple(assignments) = &elements[1] {
38611 for (i, assignment) in assignments.expressions.iter().enumerate() {
38612 if i > 0 {
38613 if self.config.pretty {
38614 self.write(",");
38615 self.write_newline();
38616 self.write_indent();
38617 } else {
38618 self.write(", ");
38619 }
38620 }
38621 if !self.merge_strip_qualifiers.is_empty() {
38623 self.generate_merge_set_assignment(assignment)?;
38624 } else {
38625 self.generate_expression(assignment)?;
38626 }
38627 }
38628 } else {
38629 self.generate_expression(&elements[1])?;
38630 }
38631 if self.config.pretty {
38632 self.indent_level -= 1;
38633 }
38634 if let Some(Expression::Where(w)) = elements.get(2) {
38635 self.write_space();
38636 self.generate_where(w)?;
38637 }
38638 }
38639 }
38640 Expression::Var(v) if v.this == "DELETE" => {
38641 self.write_keyword("DELETE");
38642 if let Some(Expression::Where(w)) = elements.get(1) {
38643 self.write_space();
38644 self.generate_where(w)?;
38645 }
38646 }
38647 _ => {
38648 self.generate_expression(action)?;
38650 }
38651 }
38652 }
38653 Expression::Var(v)
38654 if v.this == "INSERT"
38655 || v.this == "UPDATE"
38656 || v.this == "DELETE"
38657 || v.this == "DO NOTHING" =>
38658 {
38659 self.write_keyword(&v.this);
38660 }
38661 _ => {
38662 self.generate_expression(action)?;
38663 }
38664 }
38665 Ok(())
38666 }
38667
38668 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
38670 match assignment {
38671 Expression::Eq(eq) => {
38672 let stripped_left = self.strip_merge_qualifier(&eq.left);
38674 self.generate_expression(&stripped_left)?;
38675 self.write(" = ");
38676 self.generate_expression(&eq.right)?;
38677 Ok(())
38678 }
38679 other => self.generate_expression(other),
38680 }
38681 }
38682
38683 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
38685 match expr {
38686 Expression::Column(col) => {
38687 if let Some(ref table_ident) = col.table {
38688 if self
38689 .merge_strip_qualifiers
38690 .iter()
38691 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
38692 {
38693 let mut col = col.clone();
38695 col.table = None;
38696 return Expression::Column(col);
38697 }
38698 }
38699 expr.clone()
38700 }
38701 Expression::Dot(dot) => {
38702 if let Expression::Identifier(id) = &dot.this {
38704 if self
38705 .merge_strip_qualifiers
38706 .iter()
38707 .any(|n| n.eq_ignore_ascii_case(&id.name))
38708 {
38709 return Expression::Identifier(dot.field.clone());
38710 }
38711 }
38712 expr.clone()
38713 }
38714 _ => expr.clone(),
38715 }
38716 }
38717
38718 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
38719 for (i, expr) in e.expressions.iter().enumerate() {
38721 if i > 0 {
38722 if self.config.pretty {
38724 self.write_newline();
38725 self.write_indent();
38726 } else {
38727 self.write_space();
38728 }
38729 }
38730 self.generate_expression(expr)?;
38731 }
38732 Ok(())
38733 }
38734
38735 fn generate_where(&mut self, e: &Where) -> Result<()> {
38736 self.write_keyword("WHERE");
38738 self.write_space();
38739 self.generate_expression(&e.this)?;
38740 Ok(())
38741 }
38742
38743 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
38744 self.write_keyword("WIDTH_BUCKET");
38746 self.write("(");
38747 self.generate_expression(&e.this)?;
38748 if let Some(min_value) = &e.min_value {
38749 self.write(", ");
38750 self.generate_expression(min_value)?;
38751 }
38752 if let Some(max_value) = &e.max_value {
38753 self.write(", ");
38754 self.generate_expression(max_value)?;
38755 }
38756 if let Some(num_buckets) = &e.num_buckets {
38757 self.write(", ");
38758 self.generate_expression(num_buckets)?;
38759 }
38760 self.write(")");
38761 Ok(())
38762 }
38763
38764 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
38765 self.generate_window_spec(e)
38767 }
38768
38769 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
38770 let mut has_content = false;
38772
38773 if !e.partition_by.is_empty() {
38775 self.write_keyword("PARTITION BY");
38776 self.write_space();
38777 for (i, expr) in e.partition_by.iter().enumerate() {
38778 if i > 0 {
38779 self.write(", ");
38780 }
38781 self.generate_expression(expr)?;
38782 }
38783 has_content = true;
38784 }
38785
38786 if !e.order_by.is_empty() {
38788 if has_content {
38789 self.write_space();
38790 }
38791 self.write_keyword("ORDER BY");
38792 self.write_space();
38793 for (i, ordered) in e.order_by.iter().enumerate() {
38794 if i > 0 {
38795 self.write(", ");
38796 }
38797 self.generate_expression(&ordered.this)?;
38798 if ordered.desc {
38799 self.write_space();
38800 self.write_keyword("DESC");
38801 } else if ordered.explicit_asc {
38802 self.write_space();
38803 self.write_keyword("ASC");
38804 }
38805 if let Some(nulls_first) = ordered.nulls_first {
38806 self.write_space();
38807 self.write_keyword("NULLS");
38808 self.write_space();
38809 if nulls_first {
38810 self.write_keyword("FIRST");
38811 } else {
38812 self.write_keyword("LAST");
38813 }
38814 }
38815 }
38816 has_content = true;
38817 }
38818
38819 if let Some(frame) = &e.frame {
38821 if has_content {
38822 self.write_space();
38823 }
38824 self.generate_window_frame(frame)?;
38825 }
38826
38827 Ok(())
38828 }
38829
38830 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
38831 self.write_keyword("WITH");
38833 self.write_space();
38834 if e.no.is_some() {
38835 self.write_keyword("NO");
38836 self.write_space();
38837 }
38838 self.write_keyword("DATA");
38839
38840 if let Some(statistics) = &e.statistics {
38842 self.write_space();
38843 self.write_keyword("AND");
38844 self.write_space();
38845 match statistics.as_ref() {
38847 Expression::Boolean(b) if !b.value => {
38848 self.write_keyword("NO");
38849 self.write_space();
38850 }
38851 _ => {}
38852 }
38853 self.write_keyword("STATISTICS");
38854 }
38855 Ok(())
38856 }
38857
38858 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
38859 self.write_keyword("WITH FILL");
38861
38862 if let Some(from_) = &e.from_ {
38863 self.write_space();
38864 self.write_keyword("FROM");
38865 self.write_space();
38866 self.generate_expression(from_)?;
38867 }
38868
38869 if let Some(to) = &e.to {
38870 self.write_space();
38871 self.write_keyword("TO");
38872 self.write_space();
38873 self.generate_expression(to)?;
38874 }
38875
38876 if let Some(step) = &e.step {
38877 self.write_space();
38878 self.write_keyword("STEP");
38879 self.write_space();
38880 self.generate_expression(step)?;
38881 }
38882
38883 if let Some(staleness) = &e.staleness {
38884 self.write_space();
38885 self.write_keyword("STALENESS");
38886 self.write_space();
38887 self.generate_expression(staleness)?;
38888 }
38889
38890 if let Some(interpolate) = &e.interpolate {
38891 self.write_space();
38892 self.write_keyword("INTERPOLATE");
38893 self.write(" (");
38894 self.generate_interpolate_item(interpolate)?;
38896 self.write(")");
38897 }
38898
38899 Ok(())
38900 }
38901
38902 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
38904 match expr {
38905 Expression::Alias(alias) => {
38906 self.generate_identifier(&alias.alias)?;
38908 self.write_space();
38909 self.write_keyword("AS");
38910 self.write_space();
38911 self.generate_expression(&alias.this)?;
38912 }
38913 Expression::Tuple(tuple) => {
38914 for (i, item) in tuple.expressions.iter().enumerate() {
38915 if i > 0 {
38916 self.write(", ");
38917 }
38918 self.generate_interpolate_item(item)?;
38919 }
38920 }
38921 other => {
38922 self.generate_expression(other)?;
38923 }
38924 }
38925 Ok(())
38926 }
38927
38928 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
38929 self.write_keyword("WITH JOURNAL TABLE");
38931 self.write("=");
38932 self.generate_expression(&e.this)?;
38933 Ok(())
38934 }
38935
38936 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
38937 self.generate_expression(&e.this)?;
38939 self.write_space();
38940 self.write_keyword("WITH");
38941 self.write_space();
38942 self.write_keyword(&e.op);
38943 Ok(())
38944 }
38945
38946 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
38947 self.write_keyword("WITH");
38949 self.write_space();
38950 for (i, expr) in e.expressions.iter().enumerate() {
38951 if i > 0 {
38952 self.write(", ");
38953 }
38954 self.generate_expression(expr)?;
38955 }
38956 Ok(())
38957 }
38958
38959 fn generate_with_schema_binding_property(
38960 &mut self,
38961 e: &WithSchemaBindingProperty,
38962 ) -> Result<()> {
38963 self.write_keyword("WITH");
38965 self.write_space();
38966 self.generate_expression(&e.this)?;
38967 Ok(())
38968 }
38969
38970 fn generate_with_system_versioning_property(
38971 &mut self,
38972 e: &WithSystemVersioningProperty,
38973 ) -> Result<()> {
38974 let mut parts = Vec::new();
38980
38981 if let Some(this) = &e.this {
38982 let mut s = String::from("HISTORY_TABLE=");
38984 let mut gen = Generator::new();
38985 gen.generate_expression(this)?;
38986 s.push_str(&gen.output);
38987 parts.push(s);
38988 }
38989
38990 if let Some(data_consistency) = &e.data_consistency {
38991 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
38992 let mut gen = Generator::new();
38993 gen.generate_expression(data_consistency)?;
38994 s.push_str(&gen.output);
38995 parts.push(s);
38996 }
38997
38998 if let Some(retention_period) = &e.retention_period {
38999 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
39000 let mut gen = Generator::new();
39001 gen.generate_expression(retention_period)?;
39002 s.push_str(&gen.output);
39003 parts.push(s);
39004 }
39005
39006 self.write_keyword("SYSTEM_VERSIONING");
39007 self.write("=");
39008
39009 if !parts.is_empty() {
39010 self.write_keyword("ON");
39011 self.write("(");
39012 self.write(&parts.join(", "));
39013 self.write(")");
39014 } else if e.on.is_some() {
39015 self.write_keyword("ON");
39016 } else {
39017 self.write_keyword("OFF");
39018 }
39019
39020 if e.with_.is_some() {
39022 let inner = self.output.clone();
39023 self.output.clear();
39024 self.write("WITH(");
39025 self.write(&inner);
39026 self.write(")");
39027 }
39028
39029 Ok(())
39030 }
39031
39032 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
39033 self.write_keyword("WITH");
39035 self.write(" (");
39036 for (i, expr) in e.expressions.iter().enumerate() {
39037 if i > 0 {
39038 self.write(", ");
39039 }
39040 self.generate_expression(expr)?;
39041 }
39042 self.write(")");
39043 Ok(())
39044 }
39045
39046 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
39047 self.write_keyword("XMLELEMENT");
39050 self.write("(");
39051
39052 if e.evalname.is_some() {
39053 self.write_keyword("EVALNAME");
39054 } else {
39055 self.write_keyword("NAME");
39056 }
39057 self.write_space();
39058 self.generate_expression(&e.this)?;
39059
39060 for expr in &e.expressions {
39061 self.write(", ");
39062 self.generate_expression(expr)?;
39063 }
39064 self.write(")");
39065 Ok(())
39066 }
39067
39068 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
39069 self.write_keyword("XMLGET");
39071 self.write("(");
39072 self.generate_expression(&e.this)?;
39073 self.write(", ");
39074 self.generate_expression(&e.expression)?;
39075 if let Some(instance) = &e.instance {
39076 self.write(", ");
39077 self.generate_expression(instance)?;
39078 }
39079 self.write(")");
39080 Ok(())
39081 }
39082
39083 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
39084 self.generate_expression(&e.this)?;
39086 if let Some(expression) = &e.expression {
39087 self.write("(");
39088 self.generate_expression(expression)?;
39089 self.write(")");
39090 }
39091 Ok(())
39092 }
39093
39094 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
39095 self.write_keyword("XMLTABLE");
39097 self.write("(");
39098
39099 if self.config.pretty {
39100 self.indent_level += 1;
39101 self.write_newline();
39102 self.write_indent();
39103 self.generate_expression(&e.this)?;
39104
39105 if let Some(passing) = &e.passing {
39106 self.write_newline();
39107 self.write_indent();
39108 self.write_keyword("PASSING");
39109 if let Expression::Tuple(tuple) = passing.as_ref() {
39110 for expr in &tuple.expressions {
39111 self.write_newline();
39112 self.indent_level += 1;
39113 self.write_indent();
39114 self.generate_expression(expr)?;
39115 self.indent_level -= 1;
39116 }
39117 } else {
39118 self.write_newline();
39119 self.indent_level += 1;
39120 self.write_indent();
39121 self.generate_expression(passing)?;
39122 self.indent_level -= 1;
39123 }
39124 }
39125
39126 if e.by_ref.is_some() {
39127 self.write_newline();
39128 self.write_indent();
39129 self.write_keyword("RETURNING SEQUENCE BY REF");
39130 }
39131
39132 if !e.columns.is_empty() {
39133 self.write_newline();
39134 self.write_indent();
39135 self.write_keyword("COLUMNS");
39136 for (i, col) in e.columns.iter().enumerate() {
39137 self.write_newline();
39138 self.indent_level += 1;
39139 self.write_indent();
39140 self.generate_expression(col)?;
39141 self.indent_level -= 1;
39142 if i < e.columns.len() - 1 {
39143 self.write(",");
39144 }
39145 }
39146 }
39147
39148 self.indent_level -= 1;
39149 self.write_newline();
39150 self.write_indent();
39151 self.write(")");
39152 return Ok(());
39153 }
39154
39155 if let Some(namespaces) = &e.namespaces {
39157 self.write_keyword("XMLNAMESPACES");
39158 self.write("(");
39159 if let Expression::Tuple(tuple) = namespaces.as_ref() {
39161 for (i, expr) in tuple.expressions.iter().enumerate() {
39162 if i > 0 {
39163 self.write(", ");
39164 }
39165 if !matches!(expr, Expression::Alias(_)) {
39168 self.write_keyword("DEFAULT");
39169 self.write_space();
39170 }
39171 self.generate_expression(expr)?;
39172 }
39173 } else {
39174 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
39176 self.write_keyword("DEFAULT");
39177 self.write_space();
39178 }
39179 self.generate_expression(namespaces)?;
39180 }
39181 self.write("), ");
39182 }
39183
39184 self.generate_expression(&e.this)?;
39186
39187 if let Some(passing) = &e.passing {
39189 self.write_space();
39190 self.write_keyword("PASSING");
39191 self.write_space();
39192 if let Expression::Tuple(tuple) = passing.as_ref() {
39194 for (i, expr) in tuple.expressions.iter().enumerate() {
39195 if i > 0 {
39196 self.write(", ");
39197 }
39198 self.generate_expression(expr)?;
39199 }
39200 } else {
39201 self.generate_expression(passing)?;
39202 }
39203 }
39204
39205 if e.by_ref.is_some() {
39207 self.write_space();
39208 self.write_keyword("RETURNING SEQUENCE BY REF");
39209 }
39210
39211 if !e.columns.is_empty() {
39213 self.write_space();
39214 self.write_keyword("COLUMNS");
39215 self.write_space();
39216 for (i, col) in e.columns.iter().enumerate() {
39217 if i > 0 {
39218 self.write(", ");
39219 }
39220 self.generate_expression(col)?;
39221 }
39222 }
39223
39224 self.write(")");
39225 Ok(())
39226 }
39227
39228 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
39229 if let Some(this) = &e.this {
39232 self.generate_expression(this)?;
39233 if let Some(expression) = &e.expression {
39234 self.write_space();
39235 self.write_keyword("XOR");
39236 self.write_space();
39237 self.generate_expression(expression)?;
39238 }
39239 }
39240
39241 for (i, expr) in e.expressions.iter().enumerate() {
39243 if i > 0 || e.this.is_some() {
39244 self.write_space();
39245 self.write_keyword("XOR");
39246 self.write_space();
39247 }
39248 self.generate_expression(expr)?;
39249 }
39250 Ok(())
39251 }
39252
39253 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
39254 self.write_keyword("ZIPF");
39256 self.write("(");
39257 self.generate_expression(&e.this)?;
39258 if let Some(elementcount) = &e.elementcount {
39259 self.write(", ");
39260 self.generate_expression(elementcount)?;
39261 }
39262 if let Some(gen) = &e.gen {
39263 self.write(", ");
39264 self.generate_expression(gen)?;
39265 }
39266 self.write(")");
39267 Ok(())
39268 }
39269}
39270
39271impl Default for Generator {
39272 fn default() -> Self {
39273 Self::new()
39274 }
39275}
39276
39277#[cfg(test)]
39278mod tests {
39279 use super::*;
39280 use crate::parser::Parser;
39281
39282 fn roundtrip(sql: &str) -> String {
39283 let ast = Parser::parse_sql(sql).unwrap();
39284 Generator::sql(&ast[0]).unwrap()
39285 }
39286
39287 #[test]
39288 fn test_simple_select() {
39289 let result = roundtrip("SELECT 1");
39290 assert_eq!(result, "SELECT 1");
39291 }
39292
39293 #[test]
39294 fn test_select_from() {
39295 let result = roundtrip("SELECT a, b FROM t");
39296 assert_eq!(result, "SELECT a, b FROM t");
39297 }
39298
39299 #[test]
39300 fn test_select_where() {
39301 let result = roundtrip("SELECT * FROM t WHERE x = 1");
39302 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
39303 }
39304
39305 #[test]
39306 fn test_select_join() {
39307 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
39308 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
39309 }
39310
39311 #[test]
39312 fn test_insert() {
39313 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
39314 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
39315 }
39316
39317 #[test]
39318 fn test_pretty_print() {
39319 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
39320 let result = Generator::pretty_sql(&ast[0]).unwrap();
39321 assert!(result.contains('\n'));
39322 }
39323
39324 #[test]
39325 fn test_window_function() {
39326 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
39327 assert_eq!(
39328 result,
39329 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
39330 );
39331 }
39332
39333 #[test]
39334 fn test_window_function_with_frame() {
39335 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
39336 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
39337 }
39338
39339 #[test]
39340 fn test_aggregate_with_filter() {
39341 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
39342 assert_eq!(
39343 result,
39344 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
39345 );
39346 }
39347
39348 #[test]
39349 fn test_subscript() {
39350 let result = roundtrip("SELECT arr[0]");
39351 assert_eq!(result, "SELECT arr[0]");
39352 }
39353
39354 #[test]
39356 fn test_create_table() {
39357 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
39358 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
39359 }
39360
39361 #[test]
39362 fn test_create_table_with_constraints() {
39363 let result = roundtrip(
39364 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
39365 );
39366 assert_eq!(
39367 result,
39368 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
39369 );
39370 }
39371
39372 #[test]
39373 fn test_create_table_if_not_exists() {
39374 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
39375 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
39376 }
39377
39378 #[test]
39379 fn test_drop_table() {
39380 let result = roundtrip("DROP TABLE users");
39381 assert_eq!(result, "DROP TABLE users");
39382 }
39383
39384 #[test]
39385 fn test_drop_table_if_exists_cascade() {
39386 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
39387 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
39388 }
39389
39390 #[test]
39391 fn test_alter_table_add_column() {
39392 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
39393 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
39394 }
39395
39396 #[test]
39397 fn test_alter_table_drop_column() {
39398 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
39399 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
39400 }
39401
39402 #[test]
39403 fn test_create_index() {
39404 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
39405 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
39406 }
39407
39408 #[test]
39409 fn test_create_unique_index() {
39410 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
39411 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
39412 }
39413
39414 #[test]
39415 fn test_drop_index() {
39416 let result = roundtrip("DROP INDEX idx_name");
39417 assert_eq!(result, "DROP INDEX idx_name");
39418
39419 let result = roundtrip(r#"DROP INDEX IF EXISTS "idx_tokenKey__pb_users_auth_""#);
39420 assert_eq!(
39421 result,
39422 r#"DROP INDEX IF EXISTS "idx_tokenKey__pb_users_auth_""#
39423 );
39424
39425 let result = roundtrip(r#"DROP INDEX "public"."IdxMixed""#);
39426 assert_eq!(result, r#"DROP INDEX "public"."IdxMixed""#);
39427 }
39428
39429 #[test]
39430 fn test_create_view() {
39431 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
39432 assert_eq!(
39433 result,
39434 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
39435 );
39436 }
39437
39438 #[test]
39439 fn test_drop_view() {
39440 let result = roundtrip("DROP VIEW active_users");
39441 assert_eq!(result, "DROP VIEW active_users");
39442 }
39443
39444 #[test]
39445 fn test_truncate() {
39446 let result = roundtrip("TRUNCATE TABLE users");
39447 assert_eq!(result, "TRUNCATE TABLE users");
39448 }
39449
39450 #[test]
39451 fn test_string_literal_escaping_default() {
39452 let result = roundtrip("SELECT 'hello'");
39454 assert_eq!(result, "SELECT 'hello'");
39455
39456 let result = roundtrip("SELECT 'it''s a test'");
39458 assert_eq!(result, "SELECT 'it''s a test'");
39459 }
39460
39461 #[test]
39462 fn test_not_in_style_prefix_default_generic() {
39463 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
39464 assert_eq!(
39465 result,
39466 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
39467 );
39468 }
39469
39470 #[test]
39471 fn test_not_in_style_infix_generic_override() {
39472 let ast =
39473 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
39474 .unwrap();
39475 let config = GeneratorConfig {
39476 not_in_style: NotInStyle::Infix,
39477 ..Default::default()
39478 };
39479 let mut gen = Generator::with_config(config);
39480 let result = gen.generate(&ast[0]).unwrap();
39481 assert_eq!(
39482 result,
39483 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
39484 );
39485 }
39486
39487 #[test]
39488 fn test_string_literal_escaping_mysql() {
39489 use crate::dialects::DialectType;
39490
39491 let config = GeneratorConfig {
39492 dialect: Some(DialectType::MySQL),
39493 ..Default::default()
39494 };
39495
39496 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
39497 let mut gen = Generator::with_config(config.clone());
39498 let result = gen.generate(&ast[0]).unwrap();
39499 assert_eq!(result, "SELECT 'hello'");
39500
39501 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
39503 let mut gen = Generator::with_config(config.clone());
39504 let result = gen.generate(&ast[0]).unwrap();
39505 assert_eq!(result, "SELECT 'it''s'");
39506 }
39507
39508 #[test]
39509 fn test_string_literal_escaping_postgres() {
39510 use crate::dialects::DialectType;
39511
39512 let config = GeneratorConfig {
39513 dialect: Some(DialectType::PostgreSQL),
39514 ..Default::default()
39515 };
39516
39517 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
39518 let mut gen = Generator::with_config(config.clone());
39519 let result = gen.generate(&ast[0]).unwrap();
39520 assert_eq!(result, "SELECT 'hello'");
39521
39522 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
39524 let mut gen = Generator::with_config(config.clone());
39525 let result = gen.generate(&ast[0]).unwrap();
39526 assert_eq!(result, "SELECT 'it''s'");
39527 }
39528
39529 #[test]
39530 fn test_string_literal_escaping_bigquery() {
39531 use crate::dialects::DialectType;
39532
39533 let config = GeneratorConfig {
39534 dialect: Some(DialectType::BigQuery),
39535 ..Default::default()
39536 };
39537
39538 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
39539 let mut gen = Generator::with_config(config.clone());
39540 let result = gen.generate(&ast[0]).unwrap();
39541 assert_eq!(result, "SELECT 'hello'");
39542
39543 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
39545 let mut gen = Generator::with_config(config.clone());
39546 let result = gen.generate(&ast[0]).unwrap();
39547 assert_eq!(result, "SELECT 'it\\'s'");
39548 }
39549
39550 #[test]
39551 fn test_generate_deep_and_chain_without_stack_growth() {
39552 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
39553 Expression::column("c0"),
39554 Expression::number(0),
39555 )));
39556
39557 for i in 1..2500 {
39558 let predicate = Expression::Eq(Box::new(BinaryOp::new(
39559 Expression::column(format!("c{i}")),
39560 Expression::number(i as i64),
39561 )));
39562 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
39563 }
39564
39565 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
39566 assert!(sql.contains("c2499 = 2499"), "{}", sql);
39567 }
39568
39569 #[test]
39570 fn test_generate_deep_or_chain_without_stack_growth() {
39571 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
39572 Expression::column("c0"),
39573 Expression::number(0),
39574 )));
39575
39576 for i in 1..2500 {
39577 let predicate = Expression::Eq(Box::new(BinaryOp::new(
39578 Expression::column(format!("c{i}")),
39579 Expression::number(i as i64),
39580 )));
39581 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
39582 }
39583
39584 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
39585 assert!(sql.contains("c2499 = 2499"), "{}", sql);
39586 }
39587}