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 if let Some(idx) = f.index {
22126 if matches!(
22127 self.config.dialect,
22128 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22129 ) {
22130 self.write("@P");
22131 self.write(&idx.to_string());
22132 } else {
22133 self.write("$");
22134 self.write(&idx.to_string());
22135 }
22136 } else {
22137 self.write("$");
22138 if let Some(ref name) = f.name {
22139 self.write(name);
22141 }
22142 }
22143 }
22144 ParameterStyle::DollarBrace => {
22145 self.write("${");
22147 if let Some(ref name) = f.name {
22148 self.write(name);
22149 }
22150 if let Some(ref expr) = f.expression {
22151 self.write(":");
22152 self.write(expr);
22153 }
22154 self.write("}");
22155 }
22156 ParameterStyle::Colon => {
22157 self.write(":");
22158 if let Some(idx) = f.index {
22159 self.write(&idx.to_string());
22160 } else if let Some(ref name) = f.name {
22161 self.write(name);
22162 }
22163 }
22164 ParameterStyle::At => {
22165 self.write("@");
22166 if let Some(ref name) = f.name {
22167 if f.string_quoted {
22168 self.write("'");
22169 self.write(name);
22170 self.write("'");
22171 } else if f.quoted {
22172 self.write("\"");
22173 self.write(name);
22174 self.write("\"");
22175 } else {
22176 self.write(name);
22177 }
22178 }
22179 }
22180 ParameterStyle::DoubleAt => {
22181 self.write("@@");
22182 if let Some(ref name) = f.name {
22183 self.write(name);
22184 }
22185 }
22186 ParameterStyle::DoubleDollar => {
22187 self.write("$$");
22188 if let Some(ref name) = f.name {
22189 self.write(name);
22190 }
22191 }
22192 ParameterStyle::Percent => {
22193 if let Some(ref name) = f.name {
22194 self.write("%(");
22196 self.write(name);
22197 self.write(")s");
22198 } else {
22199 self.write("%s");
22201 }
22202 }
22203 ParameterStyle::Brace => {
22204 self.write("{");
22207 if let Some(ref name) = f.name {
22208 self.write(name);
22209 }
22210 if let Some(ref expr) = f.expression {
22211 self.write(": ");
22212 self.write(expr);
22213 }
22214 self.write("}");
22215 }
22216 }
22217 Ok(())
22218 }
22219
22220 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
22221 self.write("?");
22222 if let Some(idx) = f.index {
22223 self.write(&idx.to_string());
22224 }
22225 Ok(())
22226 }
22227
22228 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
22229 if f.is_block {
22230 self.write("/*");
22231 self.write(&f.text);
22232 self.write("*/");
22233 } else {
22234 self.write("--");
22235 self.write(&f.text);
22236 }
22237 Ok(())
22238 }
22239
22240 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
22243 self.generate_expression(&f.this)?;
22244 if f.not {
22245 self.write_space();
22246 self.write_keyword("NOT");
22247 }
22248 self.write_space();
22249 self.write_keyword("SIMILAR TO");
22250 self.write_space();
22251 self.generate_expression(&f.pattern)?;
22252 if let Some(ref escape) = f.escape {
22253 self.write_space();
22254 self.write_keyword("ESCAPE");
22255 self.write_space();
22256 self.generate_expression(escape)?;
22257 }
22258 Ok(())
22259 }
22260
22261 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
22262 self.generate_expression(&f.this)?;
22263 self.write_space();
22264 if let Some(op) = &f.op {
22266 match op {
22267 QuantifiedOp::Eq => self.write("="),
22268 QuantifiedOp::Neq => self.write("<>"),
22269 QuantifiedOp::Lt => self.write("<"),
22270 QuantifiedOp::Lte => self.write("<="),
22271 QuantifiedOp::Gt => self.write(">"),
22272 QuantifiedOp::Gte => self.write(">="),
22273 }
22274 self.write_space();
22275 }
22276 self.write_keyword(name);
22277
22278 if matches!(&f.subquery, Expression::Subquery(_)) {
22280 self.write_space();
22281 self.generate_expression(&f.subquery)?;
22282 } else {
22283 let is_statement = matches!(
22284 &f.subquery,
22285 Expression::Select(_)
22286 | Expression::Union(_)
22287 | Expression::Intersect(_)
22288 | Expression::Except(_)
22289 );
22290 if is_statement
22291 && !self.config.quantified_no_paren_space
22292 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
22293 {
22294 self.write_space();
22295 }
22296 self.write("(");
22297
22298 if self.config.pretty && is_statement {
22299 self.write_newline();
22300 self.indent_level += 1;
22301 self.write_indent();
22302 }
22303 self.generate_expression(&f.subquery)?;
22304 if self.config.pretty && is_statement {
22305 self.write_newline();
22306 self.indent_level -= 1;
22307 self.write_indent();
22308 }
22309 self.write(")");
22310 }
22311 Ok(())
22312 }
22313
22314 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
22315 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
22317 self.generate_expression(this)?;
22318 self.write_space();
22319 self.write_keyword("OVERLAPS");
22320 self.write_space();
22321 self.generate_expression(expr)?;
22322 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
22323 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
22324 {
22325 self.write("(");
22327 self.generate_expression(ls)?;
22328 self.write(", ");
22329 self.generate_expression(le)?;
22330 self.write(")");
22331 self.write_space();
22332 self.write_keyword("OVERLAPS");
22333 self.write_space();
22334 self.write("(");
22335 self.generate_expression(rs)?;
22336 self.write(", ");
22337 self.generate_expression(re)?;
22338 self.write(")");
22339 }
22340 Ok(())
22341 }
22342
22343 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
22346 use crate::dialects::DialectType;
22347
22348 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
22350 self.generate_expression(&cast.this)?;
22351 self.write(" !:> ");
22352 self.generate_data_type(&cast.to)?;
22353 return Ok(());
22354 }
22355
22356 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
22358 self.write_keyword("TRYCAST");
22359 self.write("(");
22360 self.generate_expression(&cast.this)?;
22361 self.write_space();
22362 self.write_keyword("AS");
22363 self.write_space();
22364 self.generate_data_type(&cast.to)?;
22365 self.write(")");
22366 return Ok(());
22367 }
22368
22369 let keyword = if matches!(
22371 self.config.dialect,
22372 Some(DialectType::Hive)
22373 | Some(DialectType::MySQL)
22374 | Some(DialectType::SQLite)
22375 | Some(DialectType::Oracle)
22376 | Some(DialectType::ClickHouse)
22377 | Some(DialectType::Redshift)
22378 | Some(DialectType::PostgreSQL)
22379 | Some(DialectType::StarRocks)
22380 | Some(DialectType::Doris)
22381 ) {
22382 "CAST"
22383 } else {
22384 "TRY_CAST"
22385 };
22386
22387 self.write_keyword(keyword);
22388 self.write("(");
22389 self.generate_expression(&cast.this)?;
22390 self.write_space();
22391 self.write_keyword("AS");
22392 self.write_space();
22393 self.generate_data_type(&cast.to)?;
22394
22395 if let Some(format) = &cast.format {
22397 self.write_space();
22398 self.write_keyword("FORMAT");
22399 self.write_space();
22400 self.generate_expression(format)?;
22401 }
22402
22403 self.write(")");
22404 Ok(())
22405 }
22406
22407 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
22408 self.write_keyword("SAFE_CAST");
22409 self.write("(");
22410 self.generate_expression(&cast.this)?;
22411 self.write_space();
22412 self.write_keyword("AS");
22413 self.write_space();
22414 self.generate_data_type(&cast.to)?;
22415
22416 if let Some(format) = &cast.format {
22418 self.write_space();
22419 self.write_keyword("FORMAT");
22420 self.write_space();
22421 self.generate_expression(format)?;
22422 }
22423
22424 self.write(")");
22425 Ok(())
22426 }
22427
22428 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
22431 let needs_parens = matches!(&s.this, Expression::JsonExtract(ref f) if f.arrow_syntax);
22435 if needs_parens {
22436 self.write("(");
22437 }
22438 self.generate_expression(&s.this)?;
22439 if needs_parens {
22440 self.write(")");
22441 }
22442 self.write("[");
22443 self.generate_expression(&s.index)?;
22444 self.write("]");
22445 Ok(())
22446 }
22447
22448 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
22449 self.generate_expression(&d.this)?;
22450 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
22453 && matches!(
22454 &d.this,
22455 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
22456 );
22457 if use_colon {
22458 self.write(":");
22459 } else {
22460 self.write(".");
22461 }
22462 self.generate_identifier(&d.field)
22463 }
22464
22465 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
22466 self.generate_expression(&m.this)?;
22467 self.write(".");
22468 if m.method.quoted {
22471 let q = self.config.identifier_quote;
22472 self.write(&format!("{}{}{}", q, m.method.name, q));
22473 } else {
22474 self.write(&m.method.name);
22475 }
22476 self.write("(");
22477 for (i, arg) in m.args.iter().enumerate() {
22478 if i > 0 {
22479 self.write(", ");
22480 }
22481 self.generate_expression(arg)?;
22482 }
22483 self.write(")");
22484 Ok(())
22485 }
22486
22487 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
22488 let needs_parens = matches!(
22491 &s.this,
22492 Expression::JsonExtract(f) if f.arrow_syntax
22493 ) || matches!(
22494 &s.this,
22495 Expression::JsonExtractScalar(f) if f.arrow_syntax
22496 );
22497
22498 if needs_parens {
22499 self.write("(");
22500 }
22501 self.generate_expression(&s.this)?;
22502 if needs_parens {
22503 self.write(")");
22504 }
22505 self.write("[");
22506 if let Some(start) = &s.start {
22507 self.generate_expression(start)?;
22508 }
22509 self.write(":");
22510 if let Some(end) = &s.end {
22511 self.generate_expression(end)?;
22512 }
22513 self.write("]");
22514 Ok(())
22515 }
22516
22517 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
22518 match &op.left {
22522 Expression::Column(col) => {
22523 if let Some(table) = &col.table {
22526 self.generate_identifier(table)?;
22527 self.write(".");
22528 }
22529 self.generate_identifier(&col.name)?;
22530 if col.join_mark && self.config.supports_column_join_marks {
22532 self.write(" (+)");
22533 }
22534 if op.left_comments.is_empty() {
22536 for comment in &col.trailing_comments {
22537 self.write_space();
22538 self.write_formatted_comment(comment);
22539 }
22540 }
22541 }
22542 Expression::Add(inner_op)
22543 | Expression::Sub(inner_op)
22544 | Expression::Mul(inner_op)
22545 | Expression::Div(inner_op)
22546 | Expression::Concat(inner_op) => {
22547 self.generate_binary_op_no_trailing(inner_op, match &op.left {
22549 Expression::Add(_) => "+",
22550 Expression::Sub(_) => "-",
22551 Expression::Mul(_) => "*",
22552 Expression::Div(_) => "/",
22553 Expression::Concat(_) => "||",
22554 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
22555 })?;
22556 }
22557 _ => {
22558 self.generate_expression(&op.left)?;
22559 }
22560 }
22561 for comment in &op.left_comments {
22563 self.write_space();
22564 self.write_formatted_comment(comment);
22565 }
22566 if self.config.pretty
22567 && matches!(self.config.dialect, Some(DialectType::Snowflake))
22568 && (operator == "AND" || operator == "OR")
22569 {
22570 self.write_newline();
22571 self.write_indent();
22572 self.write_keyword(operator);
22573 } else {
22574 self.write_space();
22575 if operator.chars().all(|c| c.is_alphabetic()) {
22576 self.write_keyword(operator);
22577 } else {
22578 self.write(operator);
22579 }
22580 }
22581 for comment in &op.operator_comments {
22583 self.write_space();
22584 self.write_formatted_comment(comment);
22585 }
22586 self.write_space();
22587 self.generate_expression(&op.right)?;
22588 for comment in &op.trailing_comments {
22590 self.write_space();
22591 self.write_formatted_comment(comment);
22592 }
22593 Ok(())
22594 }
22595
22596 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
22597 let keyword = connector.keyword();
22598 let Some(terms) = self.flatten_connector_terms(op, connector) else {
22599 return self.generate_binary_op(op, keyword);
22600 };
22601
22602 let wrap_clickhouse_or_term = |generator: &mut Self, term: &Expression| -> Result<()> {
22603 let should_wrap = matches!(connector, ConnectorOperator::Or)
22604 && matches!(generator.config.dialect, Some(DialectType::ClickHouse))
22605 && matches!(
22606 generator.config.source_dialect,
22607 Some(DialectType::ClickHouse)
22608 )
22609 && matches!(term, Expression::And(_));
22610 if should_wrap {
22611 generator.write("(");
22612 generator.generate_expression(term)?;
22613 generator.write(")");
22614 } else {
22615 generator.generate_expression(term)?;
22616 }
22617 Ok(())
22618 };
22619
22620 wrap_clickhouse_or_term(self, terms[0])?;
22621 for term in terms.iter().skip(1) {
22622 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
22623 self.write_newline();
22624 self.write_indent();
22625 self.write_keyword(keyword);
22626 } else {
22627 self.write_space();
22628 self.write_keyword(keyword);
22629 }
22630 self.write_space();
22631 wrap_clickhouse_or_term(self, term)?;
22632 }
22633
22634 Ok(())
22635 }
22636
22637 fn flatten_connector_terms<'a>(
22638 &self,
22639 root: &'a BinaryOp,
22640 connector: ConnectorOperator,
22641 ) -> Option<Vec<&'a Expression>> {
22642 if !root.left_comments.is_empty()
22643 || !root.operator_comments.is_empty()
22644 || !root.trailing_comments.is_empty()
22645 {
22646 return None;
22647 }
22648
22649 let mut terms = Vec::new();
22650 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
22651
22652 while let Some(expr) = stack.pop() {
22653 match (connector, expr) {
22654 (ConnectorOperator::And, Expression::And(inner))
22655 if inner.left_comments.is_empty()
22656 && inner.operator_comments.is_empty()
22657 && inner.trailing_comments.is_empty() =>
22658 {
22659 stack.push(&inner.right);
22660 stack.push(&inner.left);
22661 }
22662 (ConnectorOperator::Or, Expression::Or(inner))
22663 if inner.left_comments.is_empty()
22664 && inner.operator_comments.is_empty()
22665 && inner.trailing_comments.is_empty() =>
22666 {
22667 stack.push(&inner.right);
22668 stack.push(&inner.left);
22669 }
22670 _ => terms.push(expr),
22671 }
22672 }
22673
22674 if terms.len() > 1 {
22675 Some(terms)
22676 } else {
22677 None
22678 }
22679 }
22680
22681 fn missing_closing_parens_outside_quotes(sql: &str) -> usize {
22682 let mut depth = 0usize;
22683 let mut quote: Option<char> = None;
22684 let mut chars = sql.chars().peekable();
22685
22686 while let Some(ch) = chars.next() {
22687 if let Some(quote_char) = quote {
22688 if ch == '\\' {
22689 chars.next();
22690 } else if ch == quote_char {
22691 if quote_char == '\'' && chars.peek() == Some(&'\'') {
22692 chars.next();
22693 } else {
22694 quote = None;
22695 }
22696 }
22697 continue;
22698 }
22699
22700 match ch {
22701 '\'' | '"' | '`' => quote = Some(ch),
22702 '(' => depth += 1,
22703 ')' => depth = depth.saturating_sub(1),
22704 _ => {}
22705 }
22706 }
22707
22708 depth
22709 }
22710
22711 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
22713 self.generate_like_op_inner(op, operator, false)
22714 }
22715
22716 fn generate_like_op_negated(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
22717 self.generate_like_op_inner(op, operator, true)
22718 }
22719
22720 fn generate_like_op_inner(&mut self, op: &LikeOp, operator: &str, negated: bool) -> Result<()> {
22721 if negated
22722 && matches!(
22723 self.config.dialect,
22724 Some(DialectType::ClickHouse)
22725 | Some(DialectType::DataFusion)
22726 | Some(DialectType::TSQL)
22727 | Some(DialectType::Fabric)
22728 )
22729 {
22730 self.write_keyword("NOT");
22731 self.write_space();
22732 return self.generate_like_op_inner(op, operator, false);
22733 }
22734
22735 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22736 if let Expression::Star(star) = &op.left {
22737 if star
22738 .except
22739 .as_ref()
22740 .is_some_and(|except| !except.is_empty())
22741 {
22742 if let Some(table) = &star.table {
22743 self.generate_identifier(table)?;
22744 self.write(".");
22745 }
22746 self.write("*");
22747 self.write_space();
22748 self.write_keyword(operator);
22749 if let Some(quantifier) = &op.quantifier {
22750 self.write_space();
22751 self.write_keyword(quantifier);
22752 self.write_space();
22753 } else {
22754 self.write_space();
22755 }
22756 self.generate_expression(&op.right)?;
22757 if let Some(escape) = &op.escape {
22758 self.write_space();
22759 self.write_keyword("ESCAPE");
22760 self.write_space();
22761 self.generate_expression(escape)?;
22762 }
22763 if let Some(except) = &star.except {
22764 self.write_space();
22765 self.write_keyword("EXCEPT");
22766 self.write(" (");
22767 for (i, col) in except.iter().enumerate() {
22768 if i > 0 {
22769 self.write(", ");
22770 }
22771 self.generate_identifier(col)?;
22772 }
22773 self.write(")");
22774 }
22775 return Ok(());
22776 }
22777 }
22778 }
22779
22780 self.generate_expression(&op.left)?;
22781 self.write_space();
22782 if negated {
22783 self.write_keyword("NOT");
22784 self.write_space();
22785 }
22786 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
22788 self.write("`ILIKE`");
22789 } else {
22790 self.write_keyword(operator);
22791 }
22792 if let Some(quantifier) = &op.quantifier {
22793 self.write_space();
22794 self.write_keyword(quantifier);
22795 let is_any =
22800 quantifier.eq_ignore_ascii_case("ANY") || quantifier.eq_ignore_ascii_case("SOME");
22801 if !(is_any && matches!(&op.right, Expression::Paren(_))) {
22802 self.write_space();
22803 }
22804 } else {
22805 self.write_space();
22806 }
22807 self.generate_expression(&op.right)?;
22808 if let Some(escape) = &op.escape {
22809 self.write_space();
22810 self.write_keyword("ESCAPE");
22811 self.write_space();
22812 self.generate_expression(escape)?;
22813 }
22814 Ok(())
22815 }
22816
22817 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
22820 use crate::dialects::DialectType;
22821 self.generate_expression(&op.left)?;
22822 self.write_space();
22823 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
22824 self.write("<=>");
22825 } else {
22826 self.write_keyword("IS NOT DISTINCT FROM");
22827 }
22828 self.write_space();
22829 self.generate_expression(&op.right)?;
22830 Ok(())
22831 }
22832
22833 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
22835 self.generate_expression(&op.left)?;
22836 self.write_space();
22837 self.write_keyword("IS DISTINCT FROM");
22838 self.write_space();
22839 self.generate_expression(&op.right)?;
22840 Ok(())
22841 }
22842
22843 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
22845 match &op.left {
22847 Expression::Column(col) => {
22848 if let Some(table) = &col.table {
22849 self.generate_identifier(table)?;
22850 self.write(".");
22851 }
22852 self.generate_identifier(&col.name)?;
22853 if col.join_mark && self.config.supports_column_join_marks {
22855 self.write(" (+)");
22856 }
22857 }
22858 Expression::Add(inner_op)
22859 | Expression::Sub(inner_op)
22860 | Expression::Mul(inner_op)
22861 | Expression::Div(inner_op)
22862 | Expression::Concat(inner_op) => {
22863 self.generate_binary_op_no_trailing(inner_op, match &op.left {
22864 Expression::Add(_) => "+",
22865 Expression::Sub(_) => "-",
22866 Expression::Mul(_) => "*",
22867 Expression::Div(_) => "/",
22868 Expression::Concat(_) => "||",
22869 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
22870 })?;
22871 }
22872 _ => {
22873 self.generate_expression(&op.left)?;
22874 }
22875 }
22876 for comment in &op.left_comments {
22878 self.write_space();
22879 self.write_formatted_comment(comment);
22880 }
22881 self.write_space();
22882 if operator.chars().all(|c| c.is_alphabetic()) {
22883 self.write_keyword(operator);
22884 } else {
22885 self.write(operator);
22886 }
22887 for comment in &op.operator_comments {
22889 self.write_space();
22890 self.write_formatted_comment(comment);
22891 }
22892 self.write_space();
22893 match &op.right {
22896 Expression::Column(col) => {
22897 if let Some(table) = &col.table {
22898 self.generate_identifier(table)?;
22899 self.write(".");
22900 }
22901 self.generate_identifier(&col.name)?;
22902 if col.join_mark && self.config.supports_column_join_marks {
22904 self.write(" (+)");
22905 }
22906 }
22907 _ => {
22908 self.generate_expression(&op.right)?;
22909 }
22910 }
22911 Ok(())
22913 }
22914
22915 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
22916 if operator.chars().all(|c| c.is_alphabetic()) {
22917 self.write_keyword(operator);
22918 self.write_space();
22919 } else {
22920 self.write(operator);
22921 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
22923 self.write_space();
22924 }
22925 }
22926 self.generate_expression(&op.this)
22927 }
22928
22929 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
22930 let is_generic =
22934 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
22935 let use_prefix_not =
22936 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
22937 if use_prefix_not {
22938 self.write_keyword("NOT");
22939 self.write_space();
22940 }
22941 self.generate_expression(&in_expr.this)?;
22942 if in_expr.global {
22943 self.write_space();
22944 self.write_keyword("GLOBAL");
22945 }
22946 if in_expr.not && !use_prefix_not {
22947 self.write_space();
22948 self.write_keyword("NOT");
22949 }
22950 self.write_space();
22951 self.write_keyword("IN");
22952
22953 if let Some(unnest_expr) = &in_expr.unnest {
22955 self.write_space();
22956 self.write_keyword("UNNEST");
22957 self.write("(");
22958 self.generate_expression(unnest_expr)?;
22959 self.write(")");
22960 return Ok(());
22961 }
22962
22963 if let Some(query) = &in_expr.query {
22964 let is_bare = in_expr.expressions.is_empty()
22967 && !matches!(
22968 query,
22969 Expression::Select(_)
22970 | Expression::Union(_)
22971 | Expression::Intersect(_)
22972 | Expression::Except(_)
22973 | Expression::Subquery(_)
22974 );
22975 if is_bare {
22976 self.write_space();
22978 self.generate_expression(query)?;
22979 } else {
22980 self.write(" (");
22982 let is_statement = matches!(
22983 query,
22984 Expression::Select(_)
22985 | Expression::Union(_)
22986 | Expression::Intersect(_)
22987 | Expression::Except(_)
22988 | Expression::Subquery(_)
22989 );
22990 if self.config.pretty && is_statement {
22991 self.write_newline();
22992 self.indent_level += 1;
22993 self.write_indent();
22994 }
22995 self.generate_expression(query)?;
22996 if self.config.pretty && is_statement {
22997 self.write_newline();
22998 self.indent_level -= 1;
22999 self.write_indent();
23000 }
23001 self.write(")");
23002 }
23003 } else {
23004 let is_duckdb = matches!(
23008 self.config.dialect,
23009 Some(crate::dialects::DialectType::DuckDB)
23010 );
23011 let is_clickhouse = matches!(
23012 self.config.dialect,
23013 Some(crate::dialects::DialectType::ClickHouse)
23014 );
23015 let single_expr = in_expr.expressions.len() == 1;
23016 if is_clickhouse && single_expr {
23017 if let Expression::Array(arr) = &in_expr.expressions[0] {
23018 self.write(" (");
23020 for (i, expr) in arr.expressions.iter().enumerate() {
23021 if i > 0 {
23022 self.write(", ");
23023 }
23024 self.generate_expression(expr)?;
23025 }
23026 self.write(")");
23027 } else if in_expr.is_field {
23028 self.write_space();
23029 self.generate_expression(&in_expr.expressions[0])?;
23030 } else {
23031 self.write(" (");
23032 self.generate_expression(&in_expr.expressions[0])?;
23033 self.write(")");
23034 }
23035 } else {
23036 let is_bare_ref = single_expr
23037 && matches!(
23038 &in_expr.expressions[0],
23039 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
23040 );
23041 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
23042 self.write_space();
23045 self.generate_expression(&in_expr.expressions[0])?;
23046 } else {
23047 self.write(" (");
23049 for (i, expr) in in_expr.expressions.iter().enumerate() {
23050 if i > 0 {
23051 self.write(", ");
23052 }
23053 self.generate_expression(expr)?;
23054 }
23055 self.write(")");
23056 }
23057 }
23058 }
23059
23060 Ok(())
23061 }
23062
23063 fn generate_between(&mut self, between: &Between) -> Result<()> {
23064 let use_prefix_not = between.not
23066 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
23067 if use_prefix_not {
23068 self.write_keyword("NOT");
23069 self.write_space();
23070 }
23071 self.generate_expression(&between.this)?;
23072 if between.not && !use_prefix_not {
23073 self.write_space();
23074 self.write_keyword("NOT");
23075 }
23076 self.write_space();
23077 self.write_keyword("BETWEEN");
23078 if let Some(sym) = between.symmetric {
23080 if sym {
23081 self.write(" SYMMETRIC");
23082 } else {
23083 self.write(" ASYMMETRIC");
23084 }
23085 }
23086 self.write_space();
23087 self.generate_expression(&between.low)?;
23088 self.write_space();
23089 self.write_keyword("AND");
23090 self.write_space();
23091 self.generate_expression(&between.high)
23092 }
23093
23094 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
23095 let use_prefix_not = is_null.not
23097 && (self.config.dialect.is_none()
23098 || self.config.dialect == Some(DialectType::Generic)
23099 || is_null.postfix_form);
23100 if use_prefix_not {
23101 self.write_keyword("NOT");
23103 self.write_space();
23104 self.generate_expression(&is_null.this)?;
23105 self.write_space();
23106 self.write_keyword("IS");
23107 self.write_space();
23108 self.write_keyword("NULL");
23109 } else {
23110 self.generate_expression(&is_null.this)?;
23111 self.write_space();
23112 self.write_keyword("IS");
23113 if is_null.not {
23114 self.write_space();
23115 self.write_keyword("NOT");
23116 }
23117 self.write_space();
23118 self.write_keyword("NULL");
23119 }
23120 Ok(())
23121 }
23122
23123 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
23124 self.generate_expression(&is_true.this)?;
23125 self.write_space();
23126 self.write_keyword("IS");
23127 if is_true.not {
23128 self.write_space();
23129 self.write_keyword("NOT");
23130 }
23131 self.write_space();
23132 self.write_keyword("TRUE");
23133 Ok(())
23134 }
23135
23136 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
23137 self.generate_expression(&is_false.this)?;
23138 self.write_space();
23139 self.write_keyword("IS");
23140 if is_false.not {
23141 self.write_space();
23142 self.write_keyword("NOT");
23143 }
23144 self.write_space();
23145 self.write_keyword("FALSE");
23146 Ok(())
23147 }
23148
23149 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
23150 self.generate_expression(&is_json.this)?;
23151 self.write_space();
23152 self.write_keyword("IS");
23153 if is_json.negated {
23154 self.write_space();
23155 self.write_keyword("NOT");
23156 }
23157 self.write_space();
23158 self.write_keyword("JSON");
23159
23160 if let Some(ref json_type) = is_json.json_type {
23162 self.write_space();
23163 self.write_keyword(json_type);
23164 }
23165
23166 match &is_json.unique_keys {
23168 Some(JsonUniqueKeys::With) => {
23169 self.write_space();
23170 self.write_keyword("WITH UNIQUE KEYS");
23171 }
23172 Some(JsonUniqueKeys::Without) => {
23173 self.write_space();
23174 self.write_keyword("WITHOUT UNIQUE KEYS");
23175 }
23176 Some(JsonUniqueKeys::Shorthand) => {
23177 self.write_space();
23178 self.write_keyword("UNIQUE KEYS");
23179 }
23180 None => {}
23181 }
23182
23183 Ok(())
23184 }
23185
23186 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
23187 self.generate_expression(&is_expr.left)?;
23188 self.write_space();
23189 self.write_keyword("IS");
23190 self.write_space();
23191 self.generate_expression(&is_expr.right)
23192 }
23193
23194 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
23195 if exists.not {
23196 self.write_keyword("NOT");
23197 self.write_space();
23198 }
23199 self.write_keyword("EXISTS");
23200 self.write("(");
23201 let is_statement = matches!(
23202 &exists.this,
23203 Expression::Select(_)
23204 | Expression::Union(_)
23205 | Expression::Intersect(_)
23206 | Expression::Except(_)
23207 );
23208 if self.config.pretty && is_statement {
23209 self.write_newline();
23210 self.indent_level += 1;
23211 self.write_indent();
23212 self.generate_expression(&exists.this)?;
23213 self.write_newline();
23214 self.indent_level -= 1;
23215 self.write_indent();
23216 self.write(")");
23217 } else {
23218 self.generate_expression(&exists.this)?;
23219 self.write(")");
23220 }
23221 Ok(())
23222 }
23223
23224 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
23225 self.generate_expression(&op.left)?;
23226 self.write_space();
23227 self.write_keyword("MEMBER OF");
23228 self.write("(");
23229 self.generate_expression(&op.right)?;
23230 self.write(")");
23231 Ok(())
23232 }
23233
23234 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
23235 if subquery.lateral {
23236 self.write_keyword("LATERAL");
23237 self.write_space();
23238 }
23239
23240 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
23244 matches!(
23245 &p.this,
23246 Expression::Select(_)
23247 | Expression::Union(_)
23248 | Expression::Intersect(_)
23249 | Expression::Except(_)
23250 | Expression::Subquery(_)
23251 )
23252 } else {
23253 false
23254 };
23255
23256 let is_statement = matches!(
23258 &subquery.this,
23259 Expression::Select(_)
23260 | Expression::Union(_)
23261 | Expression::Intersect(_)
23262 | Expression::Except(_)
23263 | Expression::Merge(_)
23264 );
23265
23266 if !skip_outer_parens {
23267 self.write("(");
23268 if self.config.pretty && is_statement {
23269 self.write_newline();
23270 self.indent_level += 1;
23271 self.write_indent();
23272 }
23273 }
23274 self.generate_expression(&subquery.this)?;
23275
23276 if subquery.modifiers_inside {
23278 if let Some(order_by) = &subquery.order_by {
23280 self.write_space();
23281 self.write_keyword("ORDER BY");
23282 self.write_space();
23283 for (i, ord) in order_by.expressions.iter().enumerate() {
23284 if i > 0 {
23285 self.write(", ");
23286 }
23287 self.generate_ordered(ord)?;
23288 }
23289 }
23290
23291 if let Some(limit) = &subquery.limit {
23292 self.write_space();
23293 self.write_keyword("LIMIT");
23294 self.write_space();
23295 self.generate_expression(&limit.this)?;
23296 if limit.percent {
23297 self.write_space();
23298 self.write_keyword("PERCENT");
23299 }
23300 }
23301
23302 if let Some(offset) = &subquery.offset {
23303 self.write_space();
23304 self.write_keyword("OFFSET");
23305 self.write_space();
23306 self.generate_expression(&offset.this)?;
23307 }
23308 }
23309
23310 if !skip_outer_parens {
23311 if self.config.pretty && is_statement {
23312 self.write_newline();
23313 self.indent_level -= 1;
23314 self.write_indent();
23315 }
23316 self.write(")");
23317 }
23318
23319 if !subquery.modifiers_inside {
23321 if let Some(order_by) = &subquery.order_by {
23322 self.write_space();
23323 self.write_keyword("ORDER BY");
23324 self.write_space();
23325 for (i, ord) in order_by.expressions.iter().enumerate() {
23326 if i > 0 {
23327 self.write(", ");
23328 }
23329 self.generate_ordered(ord)?;
23330 }
23331 }
23332
23333 if let Some(limit) = &subquery.limit {
23334 self.write_space();
23335 self.write_keyword("LIMIT");
23336 self.write_space();
23337 self.generate_expression(&limit.this)?;
23338 if limit.percent {
23339 self.write_space();
23340 self.write_keyword("PERCENT");
23341 }
23342 }
23343
23344 if let Some(offset) = &subquery.offset {
23345 self.write_space();
23346 self.write_keyword("OFFSET");
23347 self.write_space();
23348 self.generate_expression(&offset.this)?;
23349 }
23350
23351 if let Some(distribute_by) = &subquery.distribute_by {
23353 self.write_space();
23354 self.write_keyword("DISTRIBUTE BY");
23355 self.write_space();
23356 for (i, expr) in distribute_by.expressions.iter().enumerate() {
23357 if i > 0 {
23358 self.write(", ");
23359 }
23360 self.generate_expression(expr)?;
23361 }
23362 }
23363
23364 if let Some(sort_by) = &subquery.sort_by {
23366 self.write_space();
23367 self.write_keyword("SORT BY");
23368 self.write_space();
23369 for (i, ord) in sort_by.expressions.iter().enumerate() {
23370 if i > 0 {
23371 self.write(", ");
23372 }
23373 self.generate_ordered(ord)?;
23374 }
23375 }
23376
23377 if let Some(cluster_by) = &subquery.cluster_by {
23379 self.write_space();
23380 self.write_keyword("CLUSTER BY");
23381 self.write_space();
23382 for (i, ord) in cluster_by.expressions.iter().enumerate() {
23383 if i > 0 {
23384 self.write(", ");
23385 }
23386 self.generate_ordered(ord)?;
23387 }
23388 }
23389 }
23390
23391 if let Some(alias) = &subquery.alias {
23392 self.write_space();
23393 let skip_as = matches!(self.config.dialect, Some(DialectType::Oracle))
23394 || (matches!(self.config.dialect, Some(DialectType::ClickHouse))
23395 && !subquery.alias_explicit_as);
23396 if !skip_as {
23397 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23398 self.write(subquery.alias_keyword.as_deref().unwrap_or("AS"));
23399 } else {
23400 self.write_keyword("AS");
23401 }
23402 self.write_space();
23403 }
23404 self.generate_identifier(alias)?;
23405 if !subquery.column_aliases.is_empty() {
23406 self.write("(");
23407 for (i, col) in subquery.column_aliases.iter().enumerate() {
23408 if i > 0 {
23409 self.write(", ");
23410 }
23411 self.generate_identifier(col)?;
23412 }
23413 self.write(")");
23414 }
23415 }
23416 for comment in &subquery.trailing_comments {
23418 self.write(" ");
23419 self.write_formatted_comment(comment);
23420 }
23421 Ok(())
23422 }
23423
23424 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
23425 if let Some(ref with) = pivot.with {
23427 self.generate_with(with)?;
23428 self.write_space();
23429 }
23430
23431 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
23432
23433 let is_redshift_unpivot = pivot.unpivot
23437 && pivot.expressions.is_empty()
23438 && pivot.fields.is_empty()
23439 && pivot.using.is_empty()
23440 && pivot.into.is_none()
23441 && !matches!(&pivot.this, Expression::Null(_));
23442
23443 if is_redshift_unpivot {
23444 self.write_keyword("UNPIVOT");
23446 self.write_space();
23447 self.generate_expression(&pivot.this)?;
23448 if let Some(alias) = &pivot.alias {
23450 self.write_space();
23451 self.write_keyword("AS");
23452 self.write_space();
23453 self.write(&alias.name);
23455 }
23456 return Ok(());
23457 }
23458
23459 let is_simplified = !pivot.using.is_empty()
23461 || pivot.into.is_some()
23462 || (pivot.fields.is_empty()
23463 && !pivot.expressions.is_empty()
23464 && !matches!(&pivot.this, Expression::Null(_)));
23465
23466 if is_simplified {
23467 self.write_keyword(direction);
23471 self.write_space();
23472 self.generate_expression(&pivot.this)?;
23473
23474 if !pivot.expressions.is_empty() {
23475 self.write_space();
23476 self.write_keyword("ON");
23477 self.write_space();
23478 for (i, expr) in pivot.expressions.iter().enumerate() {
23479 if i > 0 {
23480 self.write(", ");
23481 }
23482 self.generate_expression(expr)?;
23483 }
23484 }
23485
23486 if let Some(into) = &pivot.into {
23488 self.write_space();
23489 self.write_keyword("INTO");
23490 self.write_space();
23491 self.generate_expression(into)?;
23492 }
23493
23494 if !pivot.using.is_empty() {
23496 self.write_space();
23497 self.write_keyword("USING");
23498 self.write_space();
23499 for (i, expr) in pivot.using.iter().enumerate() {
23500 if i > 0 {
23501 self.write(", ");
23502 }
23503 self.generate_expression(expr)?;
23504 }
23505 }
23506
23507 if let Some(group) = &pivot.group {
23509 self.write_space();
23510 self.generate_expression(group)?;
23511 }
23512 } else {
23513 if !matches!(&pivot.this, Expression::Null(_)) {
23518 self.generate_expression(&pivot.this)?;
23519 self.write_space();
23520 }
23521 self.write_keyword(direction);
23522 self.write("(");
23523
23524 for (i, expr) in pivot.expressions.iter().enumerate() {
23526 if i > 0 {
23527 self.write(", ");
23528 }
23529 self.generate_expression(expr)?;
23530 }
23531
23532 if !pivot.fields.is_empty() {
23534 if !pivot.expressions.is_empty() {
23535 self.write_space();
23536 }
23537 self.write_keyword("FOR");
23538 self.write_space();
23539 for (i, field) in pivot.fields.iter().enumerate() {
23540 if i > 0 {
23541 self.write_space();
23542 }
23543 self.generate_expression(field)?;
23545 }
23546 }
23547
23548 if let Some(default_val) = &pivot.default_on_null {
23550 self.write_space();
23551 self.write_keyword("DEFAULT ON NULL");
23552 self.write(" (");
23553 self.generate_expression(default_val)?;
23554 self.write(")");
23555 }
23556
23557 if let Some(group) = &pivot.group {
23559 self.write_space();
23560 self.generate_expression(group)?;
23561 }
23562
23563 self.write(")");
23564 }
23565
23566 if let Some(alias) = &pivot.alias {
23568 self.write_space();
23569 self.write_keyword("AS");
23570 self.write_space();
23571 self.generate_identifier(alias)?;
23572 self.generate_alias_column_list(&pivot.alias_columns)?;
23573 }
23574
23575 Ok(())
23576 }
23577
23578 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
23579 self.generate_expression(&unpivot.this)?;
23580 self.write_space();
23581 self.write_keyword("UNPIVOT");
23582 if let Some(include) = unpivot.include_nulls {
23584 self.write_space();
23585 if include {
23586 self.write_keyword("INCLUDE NULLS");
23587 } else {
23588 self.write_keyword("EXCLUDE NULLS");
23589 }
23590 self.write_space();
23591 }
23592 self.write("(");
23593 if unpivot.value_column_parenthesized {
23594 self.write("(");
23595 }
23596 self.generate_identifier(&unpivot.value_column)?;
23597 for extra_col in &unpivot.extra_value_columns {
23599 self.write(", ");
23600 self.generate_identifier(extra_col)?;
23601 }
23602 if unpivot.value_column_parenthesized {
23603 self.write(")");
23604 }
23605 self.write_space();
23606 self.write_keyword("FOR");
23607 self.write_space();
23608 self.generate_identifier(&unpivot.name_column)?;
23609 self.write_space();
23610 self.write_keyword("IN");
23611 self.write(" (");
23612 for (i, col) in unpivot.columns.iter().enumerate() {
23613 if i > 0 {
23614 self.write(", ");
23615 }
23616 self.generate_expression(col)?;
23617 }
23618 self.write("))");
23619 if let Some(alias) = &unpivot.alias {
23620 self.write_space();
23621 self.write_keyword("AS");
23622 self.write_space();
23623 self.generate_identifier(alias)?;
23624 self.generate_alias_column_list(&unpivot.alias_columns)?;
23625 }
23626 Ok(())
23627 }
23628
23629 fn generate_alias_column_list(&mut self, columns: &[Identifier]) -> Result<()> {
23630 if columns.is_empty() {
23631 return Ok(());
23632 }
23633
23634 self.write("(");
23635 for (i, column) in columns.iter().enumerate() {
23636 if i > 0 {
23637 self.write(", ");
23638 }
23639 self.generate_identifier(column)?;
23640 }
23641 self.write(")");
23642 Ok(())
23643 }
23644
23645 fn generate_values(&mut self, values: &Values) -> Result<()> {
23646 self.write_keyword("VALUES");
23647 for (i, row) in values.expressions.iter().enumerate() {
23648 if i > 0 {
23649 self.write(",");
23650 }
23651 self.write(" (");
23652 for (j, expr) in row.expressions.iter().enumerate() {
23653 if j > 0 {
23654 self.write(", ");
23655 }
23656 self.generate_expression(expr)?;
23657 }
23658 self.write(")");
23659 }
23660 if let Some(alias) = &values.alias {
23661 self.write_space();
23662 self.write_keyword("AS");
23663 self.write_space();
23664 self.generate_identifier(alias)?;
23665 if !values.column_aliases.is_empty() {
23666 self.write("(");
23667 for (i, col) in values.column_aliases.iter().enumerate() {
23668 if i > 0 {
23669 self.write(", ");
23670 }
23671 self.generate_identifier(col)?;
23672 }
23673 self.write(")");
23674 }
23675 }
23676 Ok(())
23677 }
23678
23679 fn generate_array(&mut self, arr: &Array) -> Result<()> {
23680 let needs_inheritance = matches!(
23682 self.config.dialect,
23683 Some(DialectType::DuckDB)
23684 | Some(DialectType::Spark)
23685 | Some(DialectType::Databricks)
23686 | Some(DialectType::Hive)
23687 | Some(DialectType::Snowflake)
23688 | Some(DialectType::Presto)
23689 | Some(DialectType::Trino)
23690 );
23691 let propagated: Vec<Expression>;
23692 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
23693 propagated = Self::inherit_struct_field_names(&arr.expressions);
23694 &propagated
23695 } else {
23696 &arr.expressions
23697 };
23698
23699 let use_parens =
23702 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
23703 if !self.config.array_bracket_only {
23704 self.write_keyword("ARRAY");
23705 }
23706 if use_parens {
23707 self.write("(");
23708 } else {
23709 self.write("[");
23710 }
23711 for (i, expr) in expressions.iter().enumerate() {
23712 if i > 0 {
23713 self.write(", ");
23714 }
23715 self.generate_expression(expr)?;
23716 }
23717 if use_parens {
23718 self.write(")");
23719 } else {
23720 self.write("]");
23721 }
23722 Ok(())
23723 }
23724
23725 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
23726 if tuple.expressions.len() == 2 {
23729 if let Expression::TableAlias(_) = &tuple.expressions[1] {
23730 self.generate_expression(&tuple.expressions[0])?;
23732 self.write_space();
23733 self.write_keyword("AS");
23734 self.write_space();
23735 self.generate_expression(&tuple.expressions[1])?;
23736 return Ok(());
23737 }
23738 }
23739
23740 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
23743 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
23744 for expr in &tuple.expressions {
23745 expr_strings.push(self.generate_to_string(expr)?);
23746 }
23747 self.too_wide(&expr_strings)
23748 } else {
23749 false
23750 };
23751
23752 if expand_tuple {
23753 self.write("(");
23754 self.write_newline();
23755 self.indent_level += 1;
23756 for (i, expr) in tuple.expressions.iter().enumerate() {
23757 if i > 0 {
23758 self.write(",");
23759 self.write_newline();
23760 }
23761 self.write_indent();
23762 self.generate_expression(expr)?;
23763 }
23764 self.indent_level -= 1;
23765 self.write_newline();
23766 self.write_indent();
23767 self.write(")");
23768 } else {
23769 self.write("(");
23770 for (i, expr) in tuple.expressions.iter().enumerate() {
23771 if i > 0 {
23772 self.write(", ");
23773 }
23774 self.generate_expression(expr)?;
23775 }
23776 self.write(")");
23777 }
23778 Ok(())
23779 }
23780
23781 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
23782 self.generate_expression(&pipe.this)?;
23783 self.write(" |> ");
23784 self.generate_expression(&pipe.expression)?;
23785 Ok(())
23786 }
23787
23788 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
23789 let unsupported_tsql_null_ordering = ordered.nulls_first.is_some()
23790 && !self.config.null_ordering_supported
23791 && matches!(
23792 self.config.dialect,
23793 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23794 );
23795 let random_ordering = matches!(ordered.this, Expression::Rand(_) | Expression::Random(_));
23796 let emulate_tsql_null_ordering = if let Some(nulls_first) = ordered.nulls_first {
23797 let target_default_nulls_first = !ordered.desc;
23798
23799 unsupported_tsql_null_ordering
23800 && nulls_first != target_default_nulls_first
23801 && !random_ordering
23802 } else {
23803 false
23804 };
23805
23806 if emulate_tsql_null_ordering {
23807 self.write_keyword("CASE WHEN");
23808 self.write_space();
23809 self.generate_expression(&ordered.this)?;
23810 self.write_space();
23811 self.write_keyword("IS NULL THEN 1 ELSE 0 END");
23812 if ordered.nulls_first == Some(true) {
23813 self.write_space();
23814 self.write_keyword("DESC");
23815 }
23816 self.write(", ");
23817 }
23818
23819 self.generate_expression(&ordered.this)?;
23820 if ordered.desc {
23821 self.write_space();
23822 self.write_keyword("DESC");
23823 } else if ordered.explicit_asc {
23824 self.write_space();
23825 self.write_keyword("ASC");
23826 }
23827 if let Some(nulls_first) = ordered.nulls_first {
23828 if !unsupported_tsql_null_ordering
23829 && (self.config.null_ordering_supported
23830 || !matches!(self.config.dialect, Some(DialectType::Fabric)))
23831 {
23832 let is_asc = !ordered.desc;
23846 let is_nulls_are_large = matches!(
23847 self.config.dialect,
23848 Some(DialectType::Oracle)
23849 | Some(DialectType::PostgreSQL)
23850 | Some(DialectType::Redshift)
23851 | Some(DialectType::Snowflake)
23852 );
23853 let is_nulls_are_last = matches!(
23854 self.config.dialect,
23855 Some(DialectType::Dremio)
23856 | Some(DialectType::DuckDB)
23857 | Some(DialectType::Presto)
23858 | Some(DialectType::Trino)
23859 | Some(DialectType::Athena)
23860 | Some(DialectType::ClickHouse)
23861 | Some(DialectType::Drill)
23862 | Some(DialectType::Exasol)
23863 );
23864
23865 let is_default_nulls = if is_nulls_are_large {
23867 (is_asc && !nulls_first) || (!is_asc && nulls_first)
23869 } else if is_nulls_are_last {
23870 !nulls_first
23872 } else {
23873 false
23874 };
23875
23876 if !is_default_nulls {
23877 self.write_space();
23878 self.write_keyword("NULLS");
23879 self.write_space();
23880 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
23881 }
23882 }
23883 }
23884 if let Some(ref with_fill) = ordered.with_fill {
23886 self.write_space();
23887 self.generate_with_fill(with_fill)?;
23888 }
23889 Ok(())
23890 }
23891
23892 fn write_clickhouse_type(&mut self, type_str: &str) {
23894 if self.clickhouse_nullable_depth < 0 {
23895 self.write(type_str);
23897 } else {
23898 self.write(&format!("Nullable({})", type_str));
23899 }
23900 }
23901
23902 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
23903 use crate::dialects::DialectType;
23904
23905 match dt {
23906 DataType::Boolean => {
23907 match self.config.dialect {
23909 Some(DialectType::TSQL) => self.write_keyword("BIT"),
23910 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
23912 self.write_keyword("NUMBER(1)")
23914 }
23915 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
23917 }
23918 }
23919 DataType::TinyInt { length } => {
23920 match self.config.dialect {
23924 Some(DialectType::PostgreSQL)
23925 | Some(DialectType::Redshift)
23926 | Some(DialectType::Oracle)
23927 | Some(DialectType::Exasol) => {
23928 self.write_keyword("SMALLINT");
23929 }
23930 Some(DialectType::Teradata) => {
23931 self.write_keyword("BYTEINT");
23933 }
23934 Some(DialectType::Dremio) => {
23935 self.write_keyword("INT");
23937 }
23938 Some(DialectType::ClickHouse) => {
23939 self.write_clickhouse_type("Int8");
23940 }
23941 _ => {
23942 self.write_keyword("TINYINT");
23943 }
23944 }
23945 if let Some(n) = length {
23946 if !matches!(
23947 self.config.dialect,
23948 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
23949 ) {
23950 self.write(&format!("({})", n));
23951 }
23952 }
23953 }
23954 DataType::SmallInt { length } => {
23955 match self.config.dialect {
23957 Some(DialectType::Dremio) => {
23958 self.write_keyword("INT");
23959 }
23960 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
23961 self.write_keyword("INTEGER");
23962 }
23963 Some(DialectType::BigQuery) => {
23964 self.write_keyword("INT64");
23965 }
23966 Some(DialectType::ClickHouse) => {
23967 self.write_clickhouse_type("Int16");
23968 }
23969 _ => {
23970 self.write_keyword("SMALLINT");
23971 if let Some(n) = length {
23972 self.write(&format!("({})", n));
23973 }
23974 }
23975 }
23976 }
23977 DataType::Int {
23978 length,
23979 integer_spelling: _,
23980 } => {
23981 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
23983 self.write_keyword("INT64");
23984 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23985 self.write_clickhouse_type("Int32");
23986 } else {
23987 let use_integer = match self.config.dialect {
23989 Some(DialectType::TSQL)
23990 | Some(DialectType::Fabric)
23991 | Some(DialectType::Presto)
23992 | Some(DialectType::Trino)
23993 | Some(DialectType::SQLite)
23994 | Some(DialectType::Redshift) => true,
23995 _ => false,
23996 };
23997 if use_integer {
23998 self.write_keyword("INTEGER");
23999 } else {
24000 self.write_keyword("INT");
24001 }
24002 if let Some(n) = length {
24003 self.write(&format!("({})", n));
24004 }
24005 }
24006 }
24007 DataType::BigInt { length } => {
24008 match self.config.dialect {
24010 Some(DialectType::Oracle) => {
24011 self.write_keyword("INT");
24013 }
24014 Some(DialectType::ClickHouse) => {
24015 self.write_clickhouse_type("Int64");
24016 }
24017 _ => {
24018 self.write_keyword("BIGINT");
24019 if let Some(n) = length {
24020 self.write(&format!("({})", n));
24021 }
24022 }
24023 }
24024 }
24025 DataType::Float {
24026 precision,
24027 scale,
24028 real_spelling,
24029 } => {
24030 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24034 self.write_clickhouse_type("Float32");
24035 } else if *real_spelling
24036 && !matches!(
24037 self.config.dialect,
24038 Some(DialectType::Spark)
24039 | Some(DialectType::Databricks)
24040 | Some(DialectType::Hive)
24041 | Some(DialectType::Snowflake)
24042 | Some(DialectType::MySQL)
24043 | Some(DialectType::BigQuery)
24044 )
24045 {
24046 self.write_keyword("REAL")
24047 } else {
24048 match self.config.dialect {
24049 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
24050 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
24051 _ => self.write_keyword("FLOAT"),
24052 }
24053 }
24054 if !matches!(
24057 self.config.dialect,
24058 Some(DialectType::Spark)
24059 | Some(DialectType::Databricks)
24060 | Some(DialectType::Hive)
24061 | Some(DialectType::Presto)
24062 | Some(DialectType::Trino)
24063 ) {
24064 if let Some(p) = precision {
24065 self.write(&format!("({}", p));
24066 if let Some(s) = scale {
24067 self.write(&format!(", {})", s));
24068 } else {
24069 self.write(")");
24070 }
24071 }
24072 }
24073 }
24074 DataType::Double { precision, scale } => {
24075 match self.config.dialect {
24077 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24078 self.write_keyword("FLOAT")
24079 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
24081 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
24082 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
24083 Some(DialectType::SQLite) => self.write_keyword("REAL"),
24084 Some(DialectType::PostgreSQL)
24085 | Some(DialectType::Redshift)
24086 | Some(DialectType::Teradata)
24087 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
24088 _ => self.write_keyword("DOUBLE"),
24089 }
24090 if let Some(p) = precision {
24092 self.write(&format!("({}", p));
24093 if let Some(s) = scale {
24094 self.write(&format!(", {})", s));
24095 } else {
24096 self.write(")");
24097 }
24098 }
24099 }
24100 DataType::Decimal { precision, scale } => {
24101 match self.config.dialect {
24103 Some(DialectType::ClickHouse) => {
24104 self.write("Decimal");
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::Oracle) => {
24114 self.write_keyword("NUMBER");
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 Some(DialectType::BigQuery) => {
24125 self.write_keyword("NUMERIC");
24127 if let Some(p) = precision {
24128 self.write(&format!("({}", p));
24129 if let Some(s) = scale {
24130 self.write(&format!(", {}", s));
24131 }
24132 self.write(")");
24133 }
24134 }
24135 _ => {
24136 self.write_keyword("DECIMAL");
24137 if let Some(p) = precision {
24138 self.write(&format!("({}", p));
24139 if let Some(s) = scale {
24140 self.write(&format!(", {}", s));
24141 }
24142 self.write(")");
24143 }
24144 }
24145 }
24146 }
24147 DataType::Char { length } => {
24148 match self.config.dialect {
24150 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24151 self.write_keyword("TEXT");
24153 }
24154 Some(DialectType::Hive)
24155 | Some(DialectType::Spark)
24156 | Some(DialectType::Databricks) => {
24157 if length.is_some()
24160 && !matches!(self.config.dialect, Some(DialectType::Hive))
24161 {
24162 self.write_keyword("CHAR");
24163 if let Some(n) = length {
24164 self.write(&format!("({})", n));
24165 }
24166 } else {
24167 self.write_keyword("STRING");
24168 }
24169 }
24170 Some(DialectType::Dremio) => {
24171 self.write_keyword("VARCHAR");
24173 if let Some(n) = length {
24174 self.write(&format!("({})", n));
24175 }
24176 }
24177 _ => {
24178 self.write_keyword("CHAR");
24179 if let Some(n) = length {
24180 self.write(&format!("({})", n));
24181 }
24182 }
24183 }
24184 }
24185 DataType::VarChar {
24186 length,
24187 parenthesized_length,
24188 } => {
24189 match self.config.dialect {
24191 Some(DialectType::Oracle) => {
24192 self.write_keyword("VARCHAR2");
24193 if let Some(n) = length {
24194 self.write(&format!("({})", n));
24195 }
24196 }
24197 Some(DialectType::DuckDB) => {
24198 self.write_keyword("TEXT");
24200 if let Some(n) = length {
24201 self.write(&format!("({})", n));
24202 }
24203 }
24204 Some(DialectType::SQLite) => {
24205 self.write_keyword("TEXT");
24207 if let Some(n) = length {
24208 self.write(&format!("({})", n));
24209 }
24210 }
24211 Some(DialectType::MySQL) if length.is_none() => {
24212 self.write_keyword("TEXT");
24214 }
24215 Some(DialectType::Hive)
24216 | Some(DialectType::Spark)
24217 | Some(DialectType::Databricks)
24218 if length.is_none() =>
24219 {
24220 self.write_keyword("STRING");
24222 }
24223 _ => {
24224 self.write_keyword("VARCHAR");
24225 if let Some(n) = length {
24226 if *parenthesized_length {
24228 self.write(&format!("(({}))", n));
24229 } else {
24230 self.write(&format!("({})", n));
24231 }
24232 }
24233 }
24234 }
24235 }
24236 DataType::Text => {
24237 match self.config.dialect {
24239 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
24240 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24241 self.write_keyword("VARCHAR(MAX)")
24242 }
24243 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
24244 Some(DialectType::Snowflake)
24245 | Some(DialectType::Dremio)
24246 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
24247 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
24248 Some(DialectType::Presto)
24249 | Some(DialectType::Trino)
24250 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
24251 Some(DialectType::Spark)
24252 | Some(DialectType::Databricks)
24253 | Some(DialectType::Hive) => self.write_keyword("STRING"),
24254 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
24255 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
24256 self.write_keyword("STRING")
24257 }
24258 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
24259 _ => self.write_keyword("TEXT"),
24260 }
24261 }
24262 DataType::TextWithLength { length } => {
24263 match self.config.dialect {
24265 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
24266 Some(DialectType::Hive)
24267 | Some(DialectType::Spark)
24268 | Some(DialectType::Databricks) => {
24269 self.write(&format!("VARCHAR({})", length));
24270 }
24271 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
24272 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
24273 Some(DialectType::Snowflake)
24274 | Some(DialectType::Presto)
24275 | Some(DialectType::Trino)
24276 | Some(DialectType::Athena)
24277 | Some(DialectType::Drill)
24278 | Some(DialectType::Dremio) => {
24279 self.write(&format!("VARCHAR({})", length));
24280 }
24281 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24282 self.write(&format!("VARCHAR({})", length))
24283 }
24284 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
24285 self.write(&format!("STRING({})", length))
24286 }
24287 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
24288 _ => self.write(&format!("TEXT({})", length)),
24289 }
24290 }
24291 DataType::String { length } => {
24292 match self.config.dialect {
24294 Some(DialectType::ClickHouse) => {
24295 self.write("String");
24297 if let Some(n) = length {
24298 self.write(&format!("({})", n));
24299 }
24300 }
24301 Some(DialectType::BigQuery)
24302 | Some(DialectType::Hive)
24303 | Some(DialectType::Spark)
24304 | Some(DialectType::Databricks)
24305 | Some(DialectType::StarRocks)
24306 | Some(DialectType::Doris) => {
24307 self.write_keyword("STRING");
24308 if let Some(n) = length {
24309 self.write(&format!("({})", n));
24310 }
24311 }
24312 Some(DialectType::PostgreSQL) => {
24313 if let Some(n) = length {
24315 self.write_keyword("VARCHAR");
24316 self.write(&format!("({})", n));
24317 } else {
24318 self.write_keyword("TEXT");
24319 }
24320 }
24321 Some(DialectType::Redshift) => {
24322 if let Some(n) = length {
24324 self.write_keyword("VARCHAR");
24325 self.write(&format!("({})", n));
24326 } else {
24327 self.write_keyword("VARCHAR(MAX)");
24328 }
24329 }
24330 Some(DialectType::MySQL) => {
24331 if let Some(n) = length {
24333 self.write_keyword("VARCHAR");
24334 self.write(&format!("({})", n));
24335 } else {
24336 self.write_keyword("TEXT");
24337 }
24338 }
24339 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24340 if let Some(n) = length {
24342 self.write_keyword("VARCHAR");
24343 self.write(&format!("({})", n));
24344 } else {
24345 self.write_keyword("VARCHAR(MAX)");
24346 }
24347 }
24348 Some(DialectType::Oracle) => {
24349 self.write_keyword("CLOB");
24351 }
24352 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
24353 self.write_keyword("TEXT");
24355 if let Some(n) = length {
24356 self.write(&format!("({})", n));
24357 }
24358 }
24359 Some(DialectType::Presto)
24360 | Some(DialectType::Trino)
24361 | Some(DialectType::Drill)
24362 | Some(DialectType::Dremio) => {
24363 self.write_keyword("VARCHAR");
24365 if let Some(n) = length {
24366 self.write(&format!("({})", n));
24367 }
24368 }
24369 Some(DialectType::Snowflake) => {
24370 self.write_keyword("STRING");
24373 if let Some(n) = length {
24374 self.write(&format!("({})", n));
24375 }
24376 }
24377 _ => {
24378 self.write_keyword("STRING");
24380 if let Some(n) = length {
24381 self.write(&format!("({})", n));
24382 }
24383 }
24384 }
24385 }
24386 DataType::Binary { length } => {
24387 match self.config.dialect {
24389 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
24390 self.write_keyword("BYTEA");
24391 if let Some(n) = length {
24392 self.write(&format!("({})", n));
24393 }
24394 }
24395 Some(DialectType::Redshift) => {
24396 self.write_keyword("VARBYTE");
24397 if let Some(n) = length {
24398 self.write(&format!("({})", n));
24399 }
24400 }
24401 Some(DialectType::DuckDB)
24402 | Some(DialectType::SQLite)
24403 | Some(DialectType::Oracle) => {
24404 self.write_keyword("BLOB");
24406 if let Some(n) = length {
24407 self.write(&format!("({})", n));
24408 }
24409 }
24410 Some(DialectType::Presto)
24411 | Some(DialectType::Trino)
24412 | Some(DialectType::Athena)
24413 | Some(DialectType::Drill)
24414 | Some(DialectType::Dremio) => {
24415 self.write_keyword("VARBINARY");
24417 if let Some(n) = length {
24418 self.write(&format!("({})", n));
24419 }
24420 }
24421 Some(DialectType::ClickHouse) => {
24422 if self.clickhouse_nullable_depth < 0 {
24424 self.write("BINARY");
24425 } else {
24426 self.write("Nullable(BINARY");
24427 }
24428 if let Some(n) = length {
24429 self.write(&format!("({})", n));
24430 }
24431 if self.clickhouse_nullable_depth >= 0 {
24432 self.write(")");
24433 }
24434 }
24435 _ => {
24436 self.write_keyword("BINARY");
24437 if let Some(n) = length {
24438 self.write(&format!("({})", n));
24439 }
24440 }
24441 }
24442 }
24443 DataType::VarBinary { length } => {
24444 match self.config.dialect {
24446 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
24447 self.write_keyword("BYTEA");
24448 if let Some(n) = length {
24449 self.write(&format!("({})", n));
24450 }
24451 }
24452 Some(DialectType::Redshift) => {
24453 self.write_keyword("VARBYTE");
24454 if let Some(n) = length {
24455 self.write(&format!("({})", n));
24456 }
24457 }
24458 Some(DialectType::DuckDB)
24459 | Some(DialectType::SQLite)
24460 | Some(DialectType::Oracle) => {
24461 self.write_keyword("BLOB");
24463 if let Some(n) = length {
24464 self.write(&format!("({})", n));
24465 }
24466 }
24467 Some(DialectType::Exasol) => {
24468 self.write_keyword("VARCHAR");
24470 }
24471 Some(DialectType::Spark)
24472 | Some(DialectType::Hive)
24473 | Some(DialectType::Databricks) => {
24474 self.write_keyword("BINARY");
24476 if let Some(n) = length {
24477 self.write(&format!("({})", n));
24478 }
24479 }
24480 Some(DialectType::ClickHouse) => {
24481 self.write_clickhouse_type("String");
24483 }
24484 _ => {
24485 self.write_keyword("VARBINARY");
24486 if let Some(n) = length {
24487 self.write(&format!("({})", n));
24488 }
24489 }
24490 }
24491 }
24492 DataType::Blob => {
24493 match self.config.dialect {
24495 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
24496 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
24497 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24498 self.write_keyword("VARBINARY")
24499 }
24500 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
24501 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
24502 Some(DialectType::Presto)
24503 | Some(DialectType::Trino)
24504 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
24505 Some(DialectType::DuckDB) => {
24506 self.write_keyword("VARBINARY");
24509 }
24510 Some(DialectType::Spark)
24511 | Some(DialectType::Databricks)
24512 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
24513 Some(DialectType::ClickHouse) => {
24514 self.write("Nullable(String)");
24518 }
24519 _ => self.write_keyword("BLOB"),
24520 }
24521 }
24522 DataType::Bit { length } => {
24523 match self.config.dialect {
24525 Some(DialectType::Dremio)
24526 | Some(DialectType::Spark)
24527 | Some(DialectType::Databricks)
24528 | Some(DialectType::Hive)
24529 | Some(DialectType::Snowflake)
24530 | Some(DialectType::BigQuery)
24531 | Some(DialectType::Presto)
24532 | Some(DialectType::Trino)
24533 | Some(DialectType::ClickHouse)
24534 | Some(DialectType::Redshift) => {
24535 self.write_keyword("BOOLEAN");
24537 }
24538 _ => {
24539 self.write_keyword("BIT");
24540 if let Some(n) = length {
24541 self.write(&format!("({})", n));
24542 }
24543 }
24544 }
24545 }
24546 DataType::VarBit { length } => {
24547 self.write_keyword("VARBIT");
24548 if let Some(n) = length {
24549 self.write(&format!("({})", n));
24550 }
24551 }
24552 DataType::Date => self.write_keyword("DATE"),
24553 DataType::Time {
24554 precision,
24555 timezone,
24556 } => {
24557 if *timezone {
24558 match self.config.dialect {
24560 Some(DialectType::DuckDB) => {
24561 self.write_keyword("TIMETZ");
24563 }
24564 Some(DialectType::PostgreSQL) => {
24565 self.write_keyword("TIMETZ");
24567 if let Some(p) = precision {
24568 self.write(&format!("({})", p));
24569 }
24570 }
24571 _ => {
24572 self.write_keyword("TIME");
24574 if let Some(p) = precision {
24575 self.write(&format!("({})", p));
24576 }
24577 self.write_keyword(" WITH TIME ZONE");
24578 }
24579 }
24580 } else {
24581 if matches!(
24583 self.config.dialect,
24584 Some(DialectType::Spark)
24585 | Some(DialectType::Databricks)
24586 | Some(DialectType::Hive)
24587 ) {
24588 self.write_keyword("TIMESTAMP");
24589 } else {
24590 self.write_keyword("TIME");
24591 if let Some(p) = precision {
24592 self.write(&format!("({})", p));
24593 }
24594 }
24595 }
24596 }
24597 DataType::Timestamp {
24598 precision,
24599 timezone,
24600 } => {
24601 match self.config.dialect {
24603 Some(DialectType::Snowflake) if *timezone => {
24604 self.write_keyword("TIMESTAMPTZ");
24605 if let Some(p) = precision {
24606 self.write(&format!("({})", p));
24607 }
24608 }
24609 Some(DialectType::ClickHouse) => {
24610 self.write("DateTime");
24611 if let Some(p) = precision {
24612 self.write(&format!("({})", p));
24613 }
24614 }
24615 Some(DialectType::TSQL) => {
24616 if *timezone {
24617 self.write_keyword("DATETIMEOFFSET");
24618 } else {
24619 self.write_keyword("DATETIME2");
24620 }
24621 if let Some(p) = precision {
24622 self.write(&format!("({})", p));
24623 }
24624 }
24625 Some(DialectType::MySQL) => {
24626 self.write_keyword("TIMESTAMP");
24628 if let Some(p) = precision {
24629 self.write(&format!("({})", p));
24630 }
24631 }
24632 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
24633 self.write_keyword("DATETIME");
24635 if let Some(p) = precision {
24636 self.write(&format!("({})", p));
24637 }
24638 }
24639 Some(DialectType::BigQuery) => {
24640 if *timezone {
24642 self.write_keyword("TIMESTAMP");
24643 } else {
24644 self.write_keyword("DATETIME");
24645 }
24646 }
24647 Some(DialectType::DuckDB) => {
24648 if *timezone {
24650 self.write_keyword("TIMESTAMPTZ");
24651 } else {
24652 self.write_keyword("TIMESTAMP");
24653 if let Some(p) = precision {
24654 self.write(&format!("({})", p));
24655 }
24656 }
24657 }
24658 _ => {
24659 if *timezone && !self.config.tz_to_with_time_zone {
24660 self.write_keyword("TIMESTAMPTZ");
24662 if let Some(p) = precision {
24663 self.write(&format!("({})", p));
24664 }
24665 } else {
24666 self.write_keyword("TIMESTAMP");
24667 if let Some(p) = precision {
24668 self.write(&format!("({})", p));
24669 }
24670 if *timezone {
24671 self.write_space();
24672 self.write_keyword("WITH TIME ZONE");
24673 }
24674 }
24675 }
24676 }
24677 }
24678 DataType::Interval { unit, to } => {
24679 self.write_keyword("INTERVAL");
24680 if let Some(u) = unit {
24681 self.write_space();
24682 self.write_keyword(u);
24683 }
24684 if let Some(t) = to {
24686 self.write_space();
24687 self.write_keyword("TO");
24688 self.write_space();
24689 self.write_keyword(t);
24690 }
24691 }
24692 DataType::Json => {
24693 match self.config.dialect {
24695 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
24698 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
24699 _ => self.write_keyword("JSON"),
24700 }
24701 }
24702 DataType::JsonB => {
24703 match self.config.dialect {
24705 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
24706 Some(DialectType::Doris) => self.write_keyword("JSONB"),
24707 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
24708 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
24709 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
24712 }
24713 DataType::Uuid => {
24714 match self.config.dialect {
24716 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
24717 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
24718 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
24719 Some(DialectType::BigQuery)
24720 | Some(DialectType::Spark)
24721 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
24722 _ => self.write_keyword("UUID"),
24723 }
24724 }
24725 DataType::Array {
24726 element_type,
24727 dimension,
24728 } => {
24729 match self.config.dialect {
24731 Some(DialectType::PostgreSQL)
24732 | Some(DialectType::Redshift)
24733 | Some(DialectType::DuckDB) => {
24734 self.generate_data_type(element_type)?;
24736 if let Some(dim) = dimension {
24737 self.write(&format!("[{}]", dim));
24738 } else {
24739 self.write("[]");
24740 }
24741 }
24742 Some(DialectType::BigQuery) => {
24743 self.write_keyword("ARRAY<");
24744 self.generate_data_type(element_type)?;
24745 self.write(">");
24746 }
24747 Some(DialectType::Snowflake)
24748 | Some(DialectType::Presto)
24749 | Some(DialectType::Trino)
24750 | Some(DialectType::ClickHouse) => {
24751 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24753 self.write("Array(");
24754 } else {
24755 self.write_keyword("ARRAY(");
24756 }
24757 self.generate_data_type(element_type)?;
24758 self.write(")");
24759 }
24760 Some(DialectType::TSQL)
24761 | Some(DialectType::MySQL)
24762 | Some(DialectType::Oracle) => {
24763 match self.config.dialect {
24766 Some(DialectType::MySQL) => self.write_keyword("JSON"),
24767 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
24768 _ => self.write_keyword("JSON"),
24769 }
24770 }
24771 _ => {
24772 self.write_keyword("ARRAY<");
24774 self.generate_data_type(element_type)?;
24775 self.write(">");
24776 }
24777 }
24778 }
24779 DataType::List { element_type } => {
24780 self.generate_data_type(element_type)?;
24782 self.write_keyword(" LIST");
24783 }
24784 DataType::Map {
24785 key_type,
24786 value_type,
24787 } => {
24788 match self.config.dialect {
24790 Some(DialectType::Materialize) => {
24791 self.write_keyword("MAP[");
24793 self.generate_data_type(key_type)?;
24794 self.write(" => ");
24795 self.generate_data_type(value_type)?;
24796 self.write("]");
24797 }
24798 Some(DialectType::Snowflake)
24799 | Some(DialectType::RisingWave)
24800 | Some(DialectType::DuckDB)
24801 | Some(DialectType::Presto)
24802 | Some(DialectType::Trino)
24803 | Some(DialectType::Athena) => {
24804 self.write_keyword("MAP(");
24805 self.generate_data_type(key_type)?;
24806 self.write(", ");
24807 self.generate_data_type(value_type)?;
24808 self.write(")");
24809 }
24810 Some(DialectType::ClickHouse) => {
24811 self.write("Map(");
24814 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
24816 self.clickhouse_nullable_depth = 0;
24817 self.write(", ");
24818 self.generate_data_type(value_type)?;
24819 self.write(")");
24820 }
24821 _ => {
24822 self.write_keyword("MAP<");
24823 self.generate_data_type(key_type)?;
24824 self.write(", ");
24825 self.generate_data_type(value_type)?;
24826 self.write(">");
24827 }
24828 }
24829 }
24830 DataType::Vector {
24831 element_type,
24832 dimension,
24833 } => {
24834 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
24835 self.write_keyword("VECTOR(");
24837 if let Some(dim) = dimension {
24838 self.write(&dim.to_string());
24839 }
24840 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
24842 DataType::TinyInt { .. } => Some("I8"),
24843 DataType::SmallInt { .. } => Some("I16"),
24844 DataType::Int { .. } => Some("I32"),
24845 DataType::BigInt { .. } => Some("I64"),
24846 DataType::Float { .. } => Some("F32"),
24847 DataType::Double { .. } => Some("F64"),
24848 _ => None,
24849 });
24850 if let Some(alias) = type_alias {
24851 if dimension.is_some() {
24852 self.write(", ");
24853 }
24854 self.write(alias);
24855 }
24856 self.write(")");
24857 } else {
24858 self.write_keyword("VECTOR(");
24860 if let Some(ref et) = element_type {
24861 self.generate_data_type(et)?;
24862 if dimension.is_some() {
24863 self.write(", ");
24864 }
24865 }
24866 if let Some(dim) = dimension {
24867 self.write(&dim.to_string());
24868 }
24869 self.write(")");
24870 }
24871 }
24872 DataType::Object { fields, modifier } => {
24873 self.write_keyword("OBJECT(");
24874 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
24875 if i > 0 {
24876 self.write(", ");
24877 }
24878 self.write(name);
24879 self.write(" ");
24880 self.generate_data_type(dt)?;
24881 if *not_null {
24882 self.write_keyword(" NOT NULL");
24883 }
24884 }
24885 self.write(")");
24886 if let Some(mod_str) = modifier {
24887 self.write(" ");
24888 self.write_keyword(mod_str);
24889 }
24890 }
24891 DataType::Struct { fields, nested } => {
24892 match self.config.dialect {
24894 Some(DialectType::Snowflake) => {
24895 self.write_keyword("OBJECT(");
24897 for (i, field) in fields.iter().enumerate() {
24898 if i > 0 {
24899 self.write(", ");
24900 }
24901 if !field.name.is_empty() {
24902 self.write(&field.name);
24903 self.write(" ");
24904 }
24905 self.generate_data_type(&field.data_type)?;
24906 }
24907 self.write(")");
24908 }
24909 Some(DialectType::Presto) | Some(DialectType::Trino) => {
24910 self.write_keyword("ROW(");
24912 for (i, field) in fields.iter().enumerate() {
24913 if i > 0 {
24914 self.write(", ");
24915 }
24916 if !field.name.is_empty() {
24917 self.write(&field.name);
24918 self.write(" ");
24919 }
24920 self.generate_data_type(&field.data_type)?;
24921 }
24922 self.write(")");
24923 }
24924 Some(DialectType::DuckDB) => {
24925 self.write_keyword("STRUCT(");
24927 for (i, field) in fields.iter().enumerate() {
24928 if i > 0 {
24929 self.write(", ");
24930 }
24931 if !field.name.is_empty() {
24932 self.write(&field.name);
24933 self.write(" ");
24934 }
24935 self.generate_data_type(&field.data_type)?;
24936 }
24937 self.write(")");
24938 }
24939 Some(DialectType::ClickHouse) => {
24940 self.write("Tuple(");
24942 for (i, field) in fields.iter().enumerate() {
24943 if i > 0 {
24944 self.write(", ");
24945 }
24946 if !field.name.is_empty() {
24947 self.write(&field.name);
24948 self.write(" ");
24949 }
24950 self.generate_data_type(&field.data_type)?;
24951 }
24952 self.write(")");
24953 }
24954 Some(DialectType::SingleStore) => {
24955 self.write_keyword("RECORD(");
24957 for (i, field) in fields.iter().enumerate() {
24958 if i > 0 {
24959 self.write(", ");
24960 }
24961 if !field.name.is_empty() {
24962 self.write(&field.name);
24963 self.write(" ");
24964 }
24965 self.generate_data_type(&field.data_type)?;
24966 }
24967 self.write(")");
24968 }
24969 _ => {
24970 let force_angle_brackets = matches!(
24972 self.config.dialect,
24973 Some(DialectType::Hive)
24974 | Some(DialectType::Spark)
24975 | Some(DialectType::Databricks)
24976 );
24977 if *nested && !force_angle_brackets {
24978 self.write_keyword("STRUCT(");
24979 for (i, field) in fields.iter().enumerate() {
24980 if i > 0 {
24981 self.write(", ");
24982 }
24983 if !field.name.is_empty() {
24984 self.write(&field.name);
24985 self.write(" ");
24986 }
24987 self.generate_data_type(&field.data_type)?;
24988 }
24989 self.write(")");
24990 } else {
24991 self.write_keyword("STRUCT<");
24992 for (i, field) in fields.iter().enumerate() {
24993 if i > 0 {
24994 self.write(", ");
24995 }
24996 if !field.name.is_empty() {
24997 self.write(&field.name);
24999 self.write(self.config.struct_field_sep);
25000 }
25001 self.generate_data_type(&field.data_type)?;
25003 if let Some(comment) = &field.comment {
25005 self.write(" COMMENT '");
25006 self.write(comment);
25007 self.write("'");
25008 }
25009 if !field.options.is_empty() {
25011 self.write(" ");
25012 self.generate_options_clause(&field.options)?;
25013 }
25014 }
25015 self.write(">");
25016 }
25017 }
25018 }
25019 }
25020 DataType::Enum {
25021 values,
25022 assignments,
25023 } => {
25024 if self.config.dialect == Some(DialectType::ClickHouse) {
25027 self.write("Enum(");
25028 } else {
25029 self.write_keyword("ENUM(");
25030 }
25031 for (i, val) in values.iter().enumerate() {
25032 if i > 0 {
25033 self.write(", ");
25034 }
25035 self.write("'");
25036 self.write(val);
25037 self.write("'");
25038 if let Some(Some(assignment)) = assignments.get(i) {
25039 self.write(" = ");
25040 self.write(assignment);
25041 }
25042 }
25043 self.write(")");
25044 }
25045 DataType::Set { values } => {
25046 self.write_keyword("SET(");
25048 for (i, val) in values.iter().enumerate() {
25049 if i > 0 {
25050 self.write(", ");
25051 }
25052 self.write("'");
25053 self.write(val);
25054 self.write("'");
25055 }
25056 self.write(")");
25057 }
25058 DataType::Union { fields } => {
25059 self.write_keyword("UNION(");
25061 for (i, (name, dt)) in fields.iter().enumerate() {
25062 if i > 0 {
25063 self.write(", ");
25064 }
25065 if !name.is_empty() {
25066 self.write(name);
25067 self.write(" ");
25068 }
25069 self.generate_data_type(dt)?;
25070 }
25071 self.write(")");
25072 }
25073 DataType::Nullable { inner } => {
25074 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
25076 self.write("Nullable(");
25077 let saved_depth = self.clickhouse_nullable_depth;
25079 self.clickhouse_nullable_depth = -1;
25080 self.generate_data_type(inner)?;
25081 self.clickhouse_nullable_depth = saved_depth;
25082 self.write(")");
25083 } else {
25084 match inner.as_ref() {
25086 DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
25087 self.generate_data_type(&DataType::Timestamp {
25088 precision: None,
25089 timezone: false,
25090 })?;
25091 }
25092 _ => {
25093 self.generate_data_type(inner)?;
25094 }
25095 }
25096 }
25097 }
25098 DataType::Custom { name } => {
25099 let name_upper = name.to_ascii_uppercase();
25101 match self.config.dialect {
25102 Some(DialectType::ClickHouse) => {
25103 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
25104 (name_upper[..idx].to_string(), &name[idx..])
25105 } else {
25106 (name_upper.clone(), "")
25107 };
25108 let mapped = match base_upper.as_str() {
25109 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
25110 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
25111 "DATETIME64" => "DateTime64",
25112 "DATE32" => "Date32",
25113 "INT" => "Int32",
25114 "MEDIUMINT" => "Int32",
25115 "INT8" => "Int8",
25116 "INT16" => "Int16",
25117 "INT32" => "Int32",
25118 "INT64" => "Int64",
25119 "INT128" => "Int128",
25120 "INT256" => "Int256",
25121 "UINT8" => "UInt8",
25122 "UINT16" => "UInt16",
25123 "UINT32" => "UInt32",
25124 "UINT64" => "UInt64",
25125 "UINT128" => "UInt128",
25126 "UINT256" => "UInt256",
25127 "FLOAT32" => "Float32",
25128 "FLOAT64" => "Float64",
25129 "DECIMAL32" => "Decimal32",
25130 "DECIMAL64" => "Decimal64",
25131 "DECIMAL128" => "Decimal128",
25132 "DECIMAL256" => "Decimal256",
25133 "ENUM" => "Enum",
25134 "ENUM8" => "Enum8",
25135 "ENUM16" => "Enum16",
25136 "FIXEDSTRING" => "FixedString",
25137 "NESTED" => "Nested",
25138 "LOWCARDINALITY" => "LowCardinality",
25139 "NULLABLE" => "Nullable",
25140 "IPV4" => "IPv4",
25141 "IPV6" => "IPv6",
25142 "POINT" => "Point",
25143 "RING" => "Ring",
25144 "LINESTRING" => "LineString",
25145 "MULTILINESTRING" => "MultiLineString",
25146 "POLYGON" => "Polygon",
25147 "MULTIPOLYGON" => "MultiPolygon",
25148 "AGGREGATEFUNCTION" => "AggregateFunction",
25149 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
25150 "DYNAMIC" => "Dynamic",
25151 _ => "",
25152 };
25153 if mapped.is_empty() {
25154 self.write(name);
25155 } else {
25156 self.write(mapped);
25157 if matches!(base_upper.as_str(), "ENUM8" | "ENUM16")
25158 && !suffix.is_empty()
25159 {
25160 let escaped_suffix = suffix
25161 .replace('\\', "\\\\")
25162 .replace('\t', "\\t")
25163 .replace('\n', "\\n")
25164 .replace('\r', "\\r");
25165 self.write(&escaped_suffix);
25166 } else {
25167 self.write(suffix);
25168 }
25169 }
25170 }
25171 Some(DialectType::MySQL)
25172 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
25173 {
25174 self.write_keyword("TIMESTAMP");
25176 }
25177 Some(DialectType::Snowflake) => {
25178 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
25179 (name_upper[..idx].to_string(), &name[idx..])
25180 } else {
25181 (name_upper.clone(), "")
25182 };
25183
25184 match base_upper.as_str() {
25185 "TIMESTAMPNTZ" | "TIMESTAMP_NTZ" => {
25186 self.write_keyword("TIMESTAMPNTZ");
25187 self.write(suffix);
25188 }
25189 "TIMESTAMPLTZ" | "TIMESTAMP_LTZ" => {
25190 self.write_keyword("TIMESTAMPLTZ");
25191 self.write(suffix);
25192 }
25193 "TIMESTAMPTZ" | "TIMESTAMP_TZ" => {
25194 self.write_keyword("TIMESTAMPTZ");
25195 self.write(suffix);
25196 }
25197 _ => self.write(name),
25198 }
25199 }
25200 Some(DialectType::Fabric) => {
25201 let (base_upper, args_str) = if let Some(idx) = name.find('(') {
25202 (name_upper[..idx].to_string(), Some(&name[idx..]))
25203 } else {
25204 (name_upper.clone(), None)
25205 };
25206
25207 match base_upper.as_str() {
25208 "NVARCHAR" => {
25209 self.write_keyword("VARCHAR");
25210 if let Some(args) = args_str {
25211 self.write(args);
25212 }
25213 }
25214 "NCHAR" => {
25215 self.write_keyword("CHAR");
25216 if let Some(args) = args_str {
25217 self.write(args);
25218 }
25219 }
25220 _ => self.write(name),
25221 }
25222 }
25223 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
25224 self.write_keyword("SQL_VARIANT");
25225 }
25226 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
25227 self.write_keyword("DECIMAL(38, 5)");
25228 }
25229 Some(DialectType::Exasol) => {
25230 match name_upper.as_str() {
25232 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
25234 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
25236 "MEDIUMINT" => self.write_keyword("INT"),
25238 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
25240 self.write_keyword("DECIMAL")
25241 }
25242 "DATETIME" => self.write_keyword("TIMESTAMP"),
25244 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
25245 _ => self.write(name),
25246 }
25247 }
25248 Some(DialectType::Dremio) => {
25249 match name_upper.as_str() {
25251 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
25252 "ARRAY" => self.write_keyword("LIST"),
25253 "NCHAR" => self.write_keyword("VARCHAR"),
25254 _ => self.write(name),
25255 }
25256 }
25257 _ => {
25259 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
25261 (name_upper[..idx].to_string(), Some(&name[idx..]))
25262 } else {
25263 (name_upper.clone(), None)
25264 };
25265
25266 match base_upper.as_str() {
25267 "INT64"
25268 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25269 {
25270 self.write_keyword("BIGINT");
25271 }
25272 "FLOAT64"
25273 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25274 {
25275 self.write_keyword("DOUBLE");
25276 }
25277 "BOOL"
25278 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25279 {
25280 self.write_keyword("BOOLEAN");
25281 }
25282 "BYTES"
25283 if matches!(
25284 self.config.dialect,
25285 Some(DialectType::Spark)
25286 | Some(DialectType::Hive)
25287 | Some(DialectType::Databricks)
25288 ) =>
25289 {
25290 self.write_keyword("BINARY");
25291 }
25292 "BYTES"
25293 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25294 {
25295 self.write_keyword("VARBINARY");
25296 }
25297 "DATETIME2" | "SMALLDATETIME"
25299 if !matches!(
25300 self.config.dialect,
25301 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25302 ) =>
25303 {
25304 if matches!(
25306 self.config.dialect,
25307 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
25308 ) {
25309 self.write_keyword("TIMESTAMP");
25310 if let Some(args) = _args_str {
25311 self.write(args);
25312 }
25313 } else {
25314 self.write_keyword("TIMESTAMP");
25315 }
25316 }
25317 "DATETIMEOFFSET"
25319 if !matches!(
25320 self.config.dialect,
25321 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25322 ) =>
25323 {
25324 if matches!(
25325 self.config.dialect,
25326 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
25327 ) {
25328 self.write_keyword("TIMESTAMPTZ");
25329 if let Some(args) = _args_str {
25330 self.write(args);
25331 }
25332 } else {
25333 self.write_keyword("TIMESTAMPTZ");
25334 }
25335 }
25336 "UNIQUEIDENTIFIER"
25338 if !matches!(
25339 self.config.dialect,
25340 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25341 ) =>
25342 {
25343 match self.config.dialect {
25344 Some(DialectType::Spark)
25345 | Some(DialectType::Databricks)
25346 | Some(DialectType::Hive) => self.write_keyword("STRING"),
25347 _ => self.write_keyword("UUID"),
25348 }
25349 }
25350 "BIT"
25352 if !matches!(
25353 self.config.dialect,
25354 Some(DialectType::TSQL)
25355 | Some(DialectType::Fabric)
25356 | Some(DialectType::PostgreSQL)
25357 | Some(DialectType::MySQL)
25358 | Some(DialectType::DuckDB)
25359 ) =>
25360 {
25361 self.write_keyword("BOOLEAN");
25362 }
25363 "NVARCHAR"
25365 if !matches!(
25366 self.config.dialect,
25367 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25368 ) =>
25369 {
25370 match self.config.dialect {
25371 Some(DialectType::Oracle) => {
25372 self.write_keyword("NVARCHAR2");
25374 if let Some(args) = _args_str {
25375 self.write(args);
25376 }
25377 }
25378 Some(DialectType::BigQuery) => {
25379 self.write_keyword("STRING");
25381 }
25382 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
25383 self.write_keyword("TEXT");
25384 if let Some(args) = _args_str {
25385 self.write(args);
25386 }
25387 }
25388 Some(DialectType::Hive) => {
25389 self.write_keyword("STRING");
25391 }
25392 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
25393 if _args_str.is_some() {
25394 self.write_keyword("VARCHAR");
25395 self.write(_args_str.unwrap());
25396 } else {
25397 self.write_keyword("STRING");
25398 }
25399 }
25400 _ => {
25401 self.write_keyword("VARCHAR");
25402 if let Some(args) = _args_str {
25403 self.write(args);
25404 }
25405 }
25406 }
25407 }
25408 "NCHAR"
25410 if !matches!(
25411 self.config.dialect,
25412 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25413 ) =>
25414 {
25415 match self.config.dialect {
25416 Some(DialectType::Oracle) => {
25417 self.write_keyword("NCHAR");
25419 if let Some(args) = _args_str {
25420 self.write(args);
25421 }
25422 }
25423 Some(DialectType::BigQuery) => {
25424 self.write_keyword("STRING");
25426 }
25427 Some(DialectType::Hive) => {
25428 self.write_keyword("STRING");
25430 }
25431 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
25432 self.write_keyword("TEXT");
25433 if let Some(args) = _args_str {
25434 self.write(args);
25435 }
25436 }
25437 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
25438 if _args_str.is_some() {
25439 self.write_keyword("CHAR");
25440 self.write(_args_str.unwrap());
25441 } else {
25442 self.write_keyword("STRING");
25443 }
25444 }
25445 _ => {
25446 self.write_keyword("CHAR");
25447 if let Some(args) = _args_str {
25448 self.write(args);
25449 }
25450 }
25451 }
25452 }
25453 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
25456 Some(DialectType::MySQL)
25457 | Some(DialectType::SingleStore)
25458 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
25459 Some(DialectType::Spark)
25460 | Some(DialectType::Databricks)
25461 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
25462 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
25463 Some(DialectType::Presto)
25464 | Some(DialectType::Trino)
25465 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
25466 Some(DialectType::Snowflake)
25467 | Some(DialectType::Redshift)
25468 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
25469 _ => self.write_keyword("TEXT"),
25470 },
25471 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
25474 Some(DialectType::MySQL)
25475 | Some(DialectType::SingleStore)
25476 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
25477 Some(DialectType::Spark)
25478 | Some(DialectType::Databricks)
25479 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
25480 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
25481 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
25482 Some(DialectType::Presto)
25483 | Some(DialectType::Trino)
25484 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
25485 Some(DialectType::Snowflake)
25486 | Some(DialectType::Redshift)
25487 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
25488 _ => self.write_keyword("BLOB"),
25489 },
25490 "LONGVARCHAR" => match self.config.dialect {
25492 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
25493 _ => self.write_keyword("VARCHAR"),
25494 },
25495 "DATETIME" => {
25497 match self.config.dialect {
25498 Some(DialectType::MySQL)
25499 | Some(DialectType::Doris)
25500 | Some(DialectType::StarRocks)
25501 | Some(DialectType::TSQL)
25502 | Some(DialectType::Fabric)
25503 | Some(DialectType::BigQuery)
25504 | Some(DialectType::SQLite)
25505 | Some(DialectType::Snowflake) => {
25506 self.write_keyword("DATETIME");
25507 if let Some(args) = _args_str {
25508 self.write(args);
25509 }
25510 }
25511 Some(_) => {
25512 self.write_keyword("TIMESTAMP");
25514 if let Some(args) = _args_str {
25515 self.write(args);
25516 }
25517 }
25518 None => {
25519 self.write(name);
25521 }
25522 }
25523 }
25524 "VARCHAR2"
25526 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
25527 {
25528 match self.config.dialect {
25529 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
25530 self.write_keyword("TEXT");
25531 }
25532 Some(DialectType::Hive)
25533 | Some(DialectType::Spark)
25534 | Some(DialectType::Databricks)
25535 | Some(DialectType::BigQuery)
25536 | Some(DialectType::ClickHouse)
25537 | Some(DialectType::StarRocks)
25538 | Some(DialectType::Doris) => {
25539 self.write_keyword("STRING");
25540 }
25541 _ => {
25542 self.write_keyword("VARCHAR");
25543 if let Some(args) = _args_str {
25544 self.write(args);
25545 }
25546 }
25547 }
25548 }
25549 "NVARCHAR2"
25550 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
25551 {
25552 match self.config.dialect {
25553 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
25554 self.write_keyword("TEXT");
25555 }
25556 Some(DialectType::Hive)
25557 | Some(DialectType::Spark)
25558 | Some(DialectType::Databricks)
25559 | Some(DialectType::BigQuery)
25560 | Some(DialectType::ClickHouse)
25561 | Some(DialectType::StarRocks)
25562 | Some(DialectType::Doris) => {
25563 self.write_keyword("STRING");
25564 }
25565 _ => {
25566 self.write_keyword("VARCHAR");
25567 if let Some(args) = _args_str {
25568 self.write(args);
25569 }
25570 }
25571 }
25572 }
25573 _ => self.write(name),
25574 }
25575 }
25576 }
25577 }
25578 DataType::Geometry { subtype, srid } => {
25579 match self.config.dialect {
25581 Some(DialectType::MySQL) => {
25582 if let Some(sub) = subtype {
25584 self.write_keyword(sub);
25585 if let Some(s) = srid {
25586 self.write(" SRID ");
25587 self.write(&s.to_string());
25588 }
25589 } else {
25590 self.write_keyword("GEOMETRY");
25591 }
25592 }
25593 Some(DialectType::BigQuery) => {
25594 self.write_keyword("GEOGRAPHY");
25596 }
25597 Some(DialectType::Teradata) => {
25598 self.write_keyword("ST_GEOMETRY");
25600 if subtype.is_some() || srid.is_some() {
25601 self.write("(");
25602 if let Some(sub) = subtype {
25603 self.write_keyword(sub);
25604 }
25605 if let Some(s) = srid {
25606 if subtype.is_some() {
25607 self.write(", ");
25608 }
25609 self.write(&s.to_string());
25610 }
25611 self.write(")");
25612 }
25613 }
25614 _ => {
25615 self.write_keyword("GEOMETRY");
25617 if subtype.is_some() || srid.is_some() {
25618 self.write("(");
25619 if let Some(sub) = subtype {
25620 self.write_keyword(sub);
25621 }
25622 if let Some(s) = srid {
25623 if subtype.is_some() {
25624 self.write(", ");
25625 }
25626 self.write(&s.to_string());
25627 }
25628 self.write(")");
25629 }
25630 }
25631 }
25632 }
25633 DataType::Geography { subtype, srid } => {
25634 match self.config.dialect {
25636 Some(DialectType::MySQL) => {
25637 if let Some(sub) = subtype {
25639 self.write_keyword(sub);
25640 } else {
25641 self.write_keyword("GEOMETRY");
25642 }
25643 let effective_srid = srid.unwrap_or(4326);
25645 self.write(" SRID ");
25646 self.write(&effective_srid.to_string());
25647 }
25648 Some(DialectType::BigQuery) => {
25649 self.write_keyword("GEOGRAPHY");
25651 }
25652 Some(DialectType::Snowflake) => {
25653 self.write_keyword("GEOGRAPHY");
25655 }
25656 _ => {
25657 self.write_keyword("GEOGRAPHY");
25659 if subtype.is_some() || srid.is_some() {
25660 self.write("(");
25661 if let Some(sub) = subtype {
25662 self.write_keyword(sub);
25663 }
25664 if let Some(s) = srid {
25665 if subtype.is_some() {
25666 self.write(", ");
25667 }
25668 self.write(&s.to_string());
25669 }
25670 self.write(")");
25671 }
25672 }
25673 }
25674 }
25675 DataType::CharacterSet { name } => {
25676 self.write_keyword("CHAR CHARACTER SET ");
25678 self.write(name);
25679 }
25680 _ => self.write("UNKNOWN"),
25681 }
25682 Ok(())
25683 }
25684
25685 #[inline]
25688 fn write(&mut self, s: &str) {
25689 self.output.push_str(s);
25690 }
25691
25692 #[inline]
25693 fn write_space(&mut self) {
25694 self.output.push(' ');
25695 }
25696
25697 #[inline]
25698 fn write_keyword(&mut self, keyword: &str) {
25699 if self.config.uppercase_keywords {
25700 self.output.push_str(keyword);
25701 } else {
25702 for b in keyword.bytes() {
25703 self.output.push(b.to_ascii_lowercase() as char);
25704 }
25705 }
25706 }
25707
25708 fn write_func_name(&mut self, name: &str) {
25710 let normalized = self.normalize_func_name(name);
25711 self.output.push_str(normalized.as_ref());
25712 }
25713
25714 fn convert_strptime_to_exasol_format(format: &str) -> String {
25718 let mut result = String::new();
25719 let chars: Vec<char> = format.chars().collect();
25720 let mut i = 0;
25721 while i < chars.len() {
25722 if chars[i] == '%' && i + 1 < chars.len() {
25723 let spec = chars[i + 1];
25724 let exasol_spec = match spec {
25725 'Y' => "YYYY",
25726 'y' => "YY",
25727 'm' => "MM",
25728 'd' => "DD",
25729 'H' => "HH",
25730 'M' => "MI",
25731 'S' => "SS",
25732 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
25744 result.push('%');
25746 result.push(spec);
25747 i += 2;
25748 continue;
25749 }
25750 };
25751 result.push_str(exasol_spec);
25752 i += 2;
25753 } else {
25754 result.push(chars[i]);
25755 i += 1;
25756 }
25757 }
25758 result
25759 }
25760
25761 fn convert_strptime_to_postgres_format(format: &str) -> String {
25765 let mut result = String::new();
25766 let chars: Vec<char> = format.chars().collect();
25767 let mut i = 0;
25768 while i < chars.len() {
25769 if chars[i] == '%' && i + 1 < chars.len() {
25770 if chars[i + 1] == '-' && i + 2 < chars.len() {
25772 let spec = chars[i + 2];
25773 let pg_spec = match spec {
25774 'd' => "FMDD",
25775 'm' => "FMMM",
25776 'H' => "FMHH24",
25777 'M' => "FMMI",
25778 'S' => "FMSS",
25779 _ => {
25780 result.push('%');
25781 result.push('-');
25782 result.push(spec);
25783 i += 3;
25784 continue;
25785 }
25786 };
25787 result.push_str(pg_spec);
25788 i += 3;
25789 continue;
25790 }
25791 let spec = chars[i + 1];
25792 let pg_spec = match spec {
25793 'Y' => "YYYY",
25794 'y' => "YY",
25795 'm' => "MM",
25796 'd' => "DD",
25797 'H' => "HH24",
25798 'I' => "HH12",
25799 'M' => "MI",
25800 'S' => "SS",
25801 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
25812 result.push('%');
25814 result.push(spec);
25815 i += 2;
25816 continue;
25817 }
25818 };
25819 result.push_str(pg_spec);
25820 i += 2;
25821 } else {
25822 result.push(chars[i]);
25823 i += 1;
25824 }
25825 }
25826 result
25827 }
25828
25829 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
25831 if self.config.limit_only_literals {
25832 if let Some(value) = Self::try_evaluate_constant(expr) {
25833 self.write(&value.to_string());
25834 return Ok(());
25835 }
25836 }
25837 self.generate_expression(expr)
25838 }
25839
25840 fn write_formatted_comment(&mut self, comment: &str) {
25844 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
25847 &comment[2..comment.len() - 2]
25850 } else if comment.starts_with("--") {
25851 &comment[2..]
25854 } else {
25855 comment
25857 };
25858 if content.trim().is_empty() {
25860 return;
25861 }
25862 let sanitized = content.replace("*/", "* /").replace("/*", "/ *");
25865 let content = &sanitized;
25866 self.output.push_str("/*");
25868 if !content.starts_with(' ') {
25869 self.output.push(' ');
25870 }
25871 self.output.push_str(content);
25872 if !content.ends_with(' ') {
25873 self.output.push(' ');
25874 }
25875 self.output.push_str("*/");
25876 }
25877
25878 fn escape_block_for_single_quote(&self, block: &str) -> String {
25881 let escape_backslash = matches!(
25882 self.config.dialect,
25883 Some(crate::dialects::DialectType::Snowflake)
25884 );
25885 let mut escaped = String::with_capacity(block.len() + 4);
25886 for ch in block.chars() {
25887 if ch == '\'' {
25888 escaped.push('\\');
25889 escaped.push('\'');
25890 } else if escape_backslash && ch == '\\' {
25891 escaped.push('\\');
25892 escaped.push('\\');
25893 } else {
25894 escaped.push(ch);
25895 }
25896 }
25897 escaped
25898 }
25899
25900 fn write_newline(&mut self) {
25901 self.output.push('\n');
25902 }
25903
25904 fn write_indent(&mut self) {
25905 for _ in 0..self.indent_level {
25906 self.output.push_str(self.config.indent);
25907 }
25908 }
25909
25910 fn too_wide(&self, args: &[String]) -> bool {
25916 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
25917 }
25918
25919 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
25922 let config = GeneratorConfig {
25923 pretty: false,
25924 dialect: self.config.dialect,
25925 ..Default::default()
25926 };
25927 let mut gen = Generator::with_config(config);
25928 gen.generate_expression(expr)?;
25929 Ok(gen.output)
25930 }
25931
25932 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
25935 if self.config.pretty {
25936 self.write_newline();
25937 self.write_indent();
25938 self.write_keyword(keyword);
25939 self.write_newline();
25940 self.indent_level += 1;
25941 self.write_indent();
25942 self.generate_expression(condition)?;
25943 self.indent_level -= 1;
25944 } else {
25945 self.write_space();
25946 self.write_keyword(keyword);
25947 self.write_space();
25948 self.generate_expression(condition)?;
25949 }
25950 Ok(())
25951 }
25952
25953 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
25956 if exprs.is_empty() {
25957 return Ok(());
25958 }
25959
25960 if self.config.pretty {
25961 self.write_newline();
25962 self.write_indent();
25963 self.write_keyword(keyword);
25964 self.write_newline();
25965 self.indent_level += 1;
25966 for (i, expr) in exprs.iter().enumerate() {
25967 if i > 0 {
25968 self.write(",");
25969 self.write_newline();
25970 }
25971 self.write_indent();
25972 self.generate_expression(expr)?;
25973 }
25974 self.indent_level -= 1;
25975 } else {
25976 self.write_space();
25977 self.write_keyword(keyword);
25978 self.write_space();
25979 for (i, expr) in exprs.iter().enumerate() {
25980 if i > 0 {
25981 self.write(", ");
25982 }
25983 self.generate_expression(expr)?;
25984 }
25985 }
25986 Ok(())
25987 }
25988
25989 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
25991 if orderings.is_empty() {
25992 return Ok(());
25993 }
25994
25995 if self.config.pretty {
25996 self.write_newline();
25997 self.write_indent();
25998 self.write_keyword(keyword);
25999 self.write_newline();
26000 self.indent_level += 1;
26001 for (i, ordered) in orderings.iter().enumerate() {
26002 if i > 0 {
26003 self.write(",");
26004 self.write_newline();
26005 }
26006 self.write_indent();
26007 self.generate_ordered(ordered)?;
26008 }
26009 self.indent_level -= 1;
26010 } else {
26011 self.write_space();
26012 self.write_keyword(keyword);
26013 self.write_space();
26014 for (i, ordered) in orderings.iter().enumerate() {
26015 if i > 0 {
26016 self.write(", ");
26017 }
26018 self.generate_ordered(ordered)?;
26019 }
26020 }
26021 Ok(())
26022 }
26023
26024 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
26026 if windows.is_empty() {
26027 return Ok(());
26028 }
26029
26030 if self.config.pretty {
26031 self.write_newline();
26032 self.write_indent();
26033 self.write_keyword("WINDOW");
26034 self.write_newline();
26035 self.indent_level += 1;
26036 for (i, named_window) in windows.iter().enumerate() {
26037 if i > 0 {
26038 self.write(",");
26039 self.write_newline();
26040 }
26041 self.write_indent();
26042 self.generate_identifier(&named_window.name)?;
26043 self.write_space();
26044 self.write_keyword("AS");
26045 self.write(" (");
26046 self.generate_over(&named_window.spec)?;
26047 self.write(")");
26048 }
26049 self.indent_level -= 1;
26050 } else {
26051 self.write_space();
26052 self.write_keyword("WINDOW");
26053 self.write_space();
26054 for (i, named_window) in windows.iter().enumerate() {
26055 if i > 0 {
26056 self.write(", ");
26057 }
26058 self.generate_identifier(&named_window.name)?;
26059 self.write_space();
26060 self.write_keyword("AS");
26061 self.write(" (");
26062 self.generate_over(&named_window.spec)?;
26063 self.write(")");
26064 }
26065 }
26066 Ok(())
26067 }
26068
26069 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
26071 self.write_keyword("AI_AGG");
26073 self.write("(");
26074 self.generate_expression(&e.this)?;
26075 self.write(", ");
26076 self.generate_expression(&e.expression)?;
26077 self.write(")");
26078 Ok(())
26079 }
26080
26081 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
26082 self.write_keyword("AI_CLASSIFY");
26084 self.write("(");
26085 self.generate_expression(&e.this)?;
26086 if let Some(categories) = &e.categories {
26087 self.write(", ");
26088 self.generate_expression(categories)?;
26089 }
26090 if let Some(config) = &e.config {
26091 self.write(", ");
26092 self.generate_expression(config)?;
26093 }
26094 self.write(")");
26095 Ok(())
26096 }
26097
26098 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
26099 self.write_keyword("ADD");
26101 self.write_space();
26102 if e.exists {
26103 self.write_keyword("IF NOT EXISTS");
26104 self.write_space();
26105 }
26106 self.generate_expression(&e.this)?;
26107 if let Some(location) = &e.location {
26108 self.write_space();
26109 self.generate_expression(location)?;
26110 }
26111 Ok(())
26112 }
26113
26114 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
26115 self.write_keyword("ALGORITHM");
26117 self.write("=");
26118 self.generate_expression(&e.this)?;
26119 Ok(())
26120 }
26121
26122 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
26123 self.generate_expression(&e.this)?;
26125 self.write_space();
26126 self.write_keyword("AS");
26127 self.write(" (");
26128 for (i, expr) in e.expressions.iter().enumerate() {
26129 if i > 0 {
26130 self.write(", ");
26131 }
26132 self.generate_expression(expr)?;
26133 }
26134 self.write(")");
26135 Ok(())
26136 }
26137
26138 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
26139 self.write_keyword("ALLOWED_VALUES");
26141 self.write_space();
26142 for (i, expr) in e.expressions.iter().enumerate() {
26143 if i > 0 {
26144 self.write(", ");
26145 }
26146 self.generate_expression(expr)?;
26147 }
26148 Ok(())
26149 }
26150
26151 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
26152 self.write_keyword("ALTER COLUMN");
26154 self.write_space();
26155 self.generate_expression(&e.this)?;
26156
26157 if let Some(dtype) = &e.dtype {
26158 self.write_space();
26159 self.write_keyword("SET DATA TYPE");
26160 self.write_space();
26161 self.generate_expression(dtype)?;
26162 if let Some(collate) = &e.collate {
26163 self.write_space();
26164 self.write_keyword("COLLATE");
26165 self.write_space();
26166 self.generate_expression(collate)?;
26167 }
26168 if let Some(using) = &e.using {
26169 self.write_space();
26170 self.write_keyword("USING");
26171 self.write_space();
26172 self.generate_expression(using)?;
26173 }
26174 } else if let Some(default) = &e.default {
26175 self.write_space();
26176 self.write_keyword("SET DEFAULT");
26177 self.write_space();
26178 self.generate_expression(default)?;
26179 } else if let Some(comment) = &e.comment {
26180 self.write_space();
26181 self.write_keyword("COMMENT");
26182 self.write_space();
26183 self.generate_expression(comment)?;
26184 } else if let Some(drop) = &e.drop {
26185 self.write_space();
26186 self.write_keyword("DROP");
26187 self.write_space();
26188 self.generate_expression(drop)?;
26189 } else if let Some(visible) = &e.visible {
26190 self.write_space();
26191 self.generate_expression(visible)?;
26192 } else if let Some(rename_to) = &e.rename_to {
26193 self.write_space();
26194 self.write_keyword("RENAME TO");
26195 self.write_space();
26196 self.generate_expression(rename_to)?;
26197 } else if let Some(allow_null) = &e.allow_null {
26198 self.write_space();
26199 self.generate_expression(allow_null)?;
26200 }
26201 Ok(())
26202 }
26203
26204 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
26205 self.write_keyword("ALTER SESSION");
26207 self.write_space();
26208 if e.unset.is_some() {
26209 self.write_keyword("UNSET");
26210 } else {
26211 self.write_keyword("SET");
26212 }
26213 self.write_space();
26214 for (i, expr) in e.expressions.iter().enumerate() {
26215 if i > 0 {
26216 self.write(", ");
26217 }
26218 self.generate_expression(expr)?;
26219 }
26220 Ok(())
26221 }
26222
26223 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
26224 self.write_keyword("SET");
26226
26227 if let Some(opt) = &e.option {
26229 self.write_space();
26230 self.generate_expression(opt)?;
26231 }
26232
26233 if !e.expressions.is_empty() {
26236 let is_properties = e
26238 .expressions
26239 .iter()
26240 .any(|expr| matches!(expr, Expression::Eq(_)));
26241 if is_properties && e.option.is_none() {
26242 self.write_space();
26243 self.write_keyword("PROPERTIES");
26244 }
26245 self.write_space();
26246 for (i, expr) in e.expressions.iter().enumerate() {
26247 if i > 0 {
26248 self.write(", ");
26249 }
26250 self.generate_expression(expr)?;
26251 }
26252 }
26253
26254 if let Some(file_format) = &e.file_format {
26256 self.write(" ");
26257 self.write_keyword("STAGE_FILE_FORMAT");
26258 self.write(" = (");
26259 self.generate_space_separated_properties(file_format)?;
26260 self.write(")");
26261 }
26262
26263 if let Some(copy_options) = &e.copy_options {
26265 self.write(" ");
26266 self.write_keyword("STAGE_COPY_OPTIONS");
26267 self.write(" = (");
26268 self.generate_space_separated_properties(copy_options)?;
26269 self.write(")");
26270 }
26271
26272 if let Some(tag) = &e.tag {
26274 self.write(" ");
26275 self.write_keyword("TAG");
26276 self.write(" ");
26277 self.generate_expression(tag)?;
26278 }
26279
26280 Ok(())
26281 }
26282
26283 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
26285 match expr {
26286 Expression::Tuple(t) => {
26287 for (i, prop) in t.expressions.iter().enumerate() {
26288 if i > 0 {
26289 self.write(" ");
26290 }
26291 self.generate_expression(prop)?;
26292 }
26293 }
26294 _ => {
26295 self.generate_expression(expr)?;
26296 }
26297 }
26298 Ok(())
26299 }
26300
26301 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
26302 self.write_keyword("ALTER");
26304 if e.compound.is_some() {
26305 self.write_space();
26306 self.write_keyword("COMPOUND");
26307 }
26308 self.write_space();
26309 self.write_keyword("SORTKEY");
26310 self.write_space();
26311 if let Some(this) = &e.this {
26312 self.generate_expression(this)?;
26313 } else if !e.expressions.is_empty() {
26314 self.write("(");
26315 for (i, expr) in e.expressions.iter().enumerate() {
26316 if i > 0 {
26317 self.write(", ");
26318 }
26319 self.generate_expression(expr)?;
26320 }
26321 self.write(")");
26322 }
26323 Ok(())
26324 }
26325
26326 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
26327 self.write_keyword("ANALYZE");
26329 if !e.options.is_empty() {
26330 self.write_space();
26331 for (i, opt) in e.options.iter().enumerate() {
26332 if i > 0 {
26333 self.write_space();
26334 }
26335 if let Expression::Identifier(id) = opt {
26337 self.write_keyword(&id.name);
26338 } else {
26339 self.generate_expression(opt)?;
26340 }
26341 }
26342 }
26343 if let Some(kind) = &e.kind {
26344 self.write_space();
26345 self.write_keyword(kind);
26346 }
26347 if let Some(this) = &e.this {
26348 self.write_space();
26349 self.generate_expression(this)?;
26350 }
26351 if !e.columns.is_empty() {
26353 self.write("(");
26354 for (i, col) in e.columns.iter().enumerate() {
26355 if i > 0 {
26356 self.write(", ");
26357 }
26358 self.write(col);
26359 }
26360 self.write(")");
26361 }
26362 if let Some(partition) = &e.partition {
26363 self.write_space();
26364 self.generate_expression(partition)?;
26365 }
26366 if let Some(mode) = &e.mode {
26367 self.write_space();
26368 self.generate_expression(mode)?;
26369 }
26370 if let Some(expression) = &e.expression {
26371 self.write_space();
26372 self.generate_expression(expression)?;
26373 }
26374 if !e.properties.is_empty() {
26375 self.write_space();
26376 self.write_keyword(self.config.with_properties_prefix);
26377 self.write(" (");
26378 for (i, prop) in e.properties.iter().enumerate() {
26379 if i > 0 {
26380 self.write(", ");
26381 }
26382 self.generate_expression(prop)?;
26383 }
26384 self.write(")");
26385 }
26386 Ok(())
26387 }
26388
26389 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
26390 self.write_keyword("DELETE");
26392 if let Some(kind) = &e.kind {
26393 self.write_space();
26394 self.write_keyword(kind);
26395 }
26396 self.write_space();
26397 self.write_keyword("STATISTICS");
26398 Ok(())
26399 }
26400
26401 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
26402 if let Expression::Identifier(id) = e.this.as_ref() {
26405 self.write_keyword(&id.name);
26406 } else {
26407 self.generate_expression(&e.this)?;
26408 }
26409 self.write_space();
26410 self.write_keyword("HISTOGRAM ON");
26411 self.write_space();
26412 for (i, expr) in e.expressions.iter().enumerate() {
26413 if i > 0 {
26414 self.write(", ");
26415 }
26416 self.generate_expression(expr)?;
26417 }
26418 if let Some(expression) = &e.expression {
26419 self.write_space();
26420 self.generate_expression(expression)?;
26421 }
26422 if let Some(update_options) = &e.update_options {
26423 self.write_space();
26424 self.generate_expression(update_options)?;
26425 self.write_space();
26426 self.write_keyword("UPDATE");
26427 }
26428 Ok(())
26429 }
26430
26431 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
26432 self.write_keyword("LIST CHAINED ROWS");
26434 if let Some(expression) = &e.expression {
26435 self.write_space();
26436 self.write_keyword("INTO");
26437 self.write_space();
26438 self.generate_expression(expression)?;
26439 }
26440 Ok(())
26441 }
26442
26443 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
26444 self.write_keyword("SAMPLE");
26446 self.write_space();
26447 if let Some(sample) = &e.sample {
26448 self.generate_expression(sample)?;
26449 self.write_space();
26450 }
26451 self.write_keyword(&e.kind);
26452 Ok(())
26453 }
26454
26455 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
26456 self.write_keyword(&e.kind);
26458 if let Some(option) = &e.option {
26459 self.write_space();
26460 self.generate_expression(option)?;
26461 }
26462 self.write_space();
26463 self.write_keyword("STATISTICS");
26464 if let Some(this) = &e.this {
26465 self.write_space();
26466 self.generate_expression(this)?;
26467 }
26468 if !e.expressions.is_empty() {
26469 self.write_space();
26470 for (i, expr) in e.expressions.iter().enumerate() {
26471 if i > 0 {
26472 self.write(", ");
26473 }
26474 self.generate_expression(expr)?;
26475 }
26476 }
26477 Ok(())
26478 }
26479
26480 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
26481 self.write_keyword("VALIDATE");
26483 self.write_space();
26484 self.write_keyword(&e.kind);
26485 if let Some(this) = &e.this {
26486 self.write_space();
26487 if let Expression::Identifier(id) = this.as_ref() {
26489 self.write_keyword(&id.name);
26490 } else {
26491 self.generate_expression(this)?;
26492 }
26493 }
26494 if let Some(expression) = &e.expression {
26495 self.write_space();
26496 self.write_keyword("INTO");
26497 self.write_space();
26498 self.generate_expression(expression)?;
26499 }
26500 Ok(())
26501 }
26502
26503 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
26504 self.write_keyword("WITH");
26506 self.write_space();
26507 for (i, expr) in e.expressions.iter().enumerate() {
26508 if i > 0 {
26509 self.write(", ");
26510 }
26511 self.generate_expression(expr)?;
26512 }
26513 Ok(())
26514 }
26515
26516 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
26517 self.generate_expression(&e.this)?;
26520 self.write("(");
26521 for (i, arg) in e.expressions.iter().enumerate() {
26522 if i > 0 {
26523 self.write(", ");
26524 }
26525 self.generate_expression(arg)?;
26526 }
26527 self.write(")");
26528 Ok(())
26529 }
26530
26531 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
26532 self.generate_expression(&e.this)?;
26534 self.write("(");
26535 for (i, arg) in e.expressions.iter().enumerate() {
26536 if i > 0 {
26537 self.write(", ");
26538 }
26539 self.generate_expression(arg)?;
26540 }
26541 self.write(")");
26542 Ok(())
26543 }
26544
26545 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
26546 self.generate_expression(&e.this)?;
26548 self.write_space();
26549 self.write_keyword("APPLY");
26550 self.write("(");
26551 self.generate_expression(&e.expression)?;
26552 self.write(")");
26553 Ok(())
26554 }
26555
26556 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
26557 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
26559 self.write("(");
26560 self.generate_expression(&e.this)?;
26561 if let Some(percentile) = &e.percentile {
26562 self.write(", ");
26563 self.generate_expression(percentile)?;
26564 }
26565 self.write(")");
26566 Ok(())
26567 }
26568
26569 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
26570 self.write_keyword("APPROX_QUANTILE");
26572 self.write("(");
26573 self.generate_expression(&e.this)?;
26574 if let Some(quantile) = &e.quantile {
26575 self.write(", ");
26576 self.generate_expression(quantile)?;
26577 }
26578 if let Some(accuracy) = &e.accuracy {
26579 self.write(", ");
26580 self.generate_expression(accuracy)?;
26581 }
26582 if let Some(weight) = &e.weight {
26583 self.write(", ");
26584 self.generate_expression(weight)?;
26585 }
26586 self.write(")");
26587 Ok(())
26588 }
26589
26590 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
26591 self.write_keyword("APPROX_QUANTILES");
26593 self.write("(");
26594 self.generate_expression(&e.this)?;
26595 if let Some(expression) = &e.expression {
26596 self.write(", ");
26597 self.generate_expression(expression)?;
26598 }
26599 self.write(")");
26600 Ok(())
26601 }
26602
26603 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
26604 self.write_keyword("APPROX_TOP_K");
26606 self.write("(");
26607 self.generate_expression(&e.this)?;
26608 if let Some(expression) = &e.expression {
26609 self.write(", ");
26610 self.generate_expression(expression)?;
26611 }
26612 if let Some(counters) = &e.counters {
26613 self.write(", ");
26614 self.generate_expression(counters)?;
26615 }
26616 self.write(")");
26617 Ok(())
26618 }
26619
26620 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
26621 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
26623 self.write("(");
26624 self.generate_expression(&e.this)?;
26625 if let Some(expression) = &e.expression {
26626 self.write(", ");
26627 self.generate_expression(expression)?;
26628 }
26629 self.write(")");
26630 Ok(())
26631 }
26632
26633 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
26634 self.write_keyword("APPROX_TOP_K_COMBINE");
26636 self.write("(");
26637 self.generate_expression(&e.this)?;
26638 if let Some(expression) = &e.expression {
26639 self.write(", ");
26640 self.generate_expression(expression)?;
26641 }
26642 self.write(")");
26643 Ok(())
26644 }
26645
26646 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
26647 self.write_keyword("APPROX_TOP_K_ESTIMATE");
26649 self.write("(");
26650 self.generate_expression(&e.this)?;
26651 if let Some(expression) = &e.expression {
26652 self.write(", ");
26653 self.generate_expression(expression)?;
26654 }
26655 self.write(")");
26656 Ok(())
26657 }
26658
26659 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
26660 self.write_keyword("APPROX_TOP_SUM");
26662 self.write("(");
26663 self.generate_expression(&e.this)?;
26664 self.write(", ");
26665 self.generate_expression(&e.expression)?;
26666 if let Some(count) = &e.count {
26667 self.write(", ");
26668 self.generate_expression(count)?;
26669 }
26670 self.write(")");
26671 Ok(())
26672 }
26673
26674 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
26675 self.write_keyword("ARG_MAX");
26677 self.write("(");
26678 self.generate_expression(&e.this)?;
26679 self.write(", ");
26680 self.generate_expression(&e.expression)?;
26681 if let Some(count) = &e.count {
26682 self.write(", ");
26683 self.generate_expression(count)?;
26684 }
26685 self.write(")");
26686 Ok(())
26687 }
26688
26689 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
26690 self.write_keyword("ARG_MIN");
26692 self.write("(");
26693 self.generate_expression(&e.this)?;
26694 self.write(", ");
26695 self.generate_expression(&e.expression)?;
26696 if let Some(count) = &e.count {
26697 self.write(", ");
26698 self.generate_expression(count)?;
26699 }
26700 self.write(")");
26701 Ok(())
26702 }
26703
26704 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
26705 self.write_keyword("ARRAY_ALL");
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_any(&mut self, e: &ArrayAny) -> Result<()> {
26716 self.write_keyword("ARRAY_ANY");
26718 self.write("(");
26719 self.generate_expression(&e.this)?;
26720 self.write(", ");
26721 self.generate_expression(&e.expression)?;
26722 self.write(")");
26723 Ok(())
26724 }
26725
26726 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
26727 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
26729 self.write("(");
26730 for (i, expr) in e.expressions.iter().enumerate() {
26731 if i > 0 {
26732 self.write(", ");
26733 }
26734 self.generate_expression(expr)?;
26735 }
26736 self.write(")");
26737 Ok(())
26738 }
26739
26740 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
26741 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
26743 self.write("arraySum");
26744 } else {
26745 self.write_keyword("ARRAY_SUM");
26746 }
26747 self.write("(");
26748 self.generate_expression(&e.this)?;
26749 if let Some(expression) = &e.expression {
26750 self.write(", ");
26751 self.generate_expression(expression)?;
26752 }
26753 self.write(")");
26754 Ok(())
26755 }
26756
26757 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
26758 self.generate_expression(&e.this)?;
26760 self.write_space();
26761 self.write_keyword("AT");
26762 self.write_space();
26763 self.generate_expression(&e.expression)?;
26764 Ok(())
26765 }
26766
26767 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
26768 self.write_keyword("ATTACH");
26770 if e.exists {
26771 self.write_space();
26772 self.write_keyword("IF NOT EXISTS");
26773 }
26774 self.write_space();
26775 self.generate_expression(&e.this)?;
26776 if !e.expressions.is_empty() {
26777 self.write(" (");
26778 for (i, expr) in e.expressions.iter().enumerate() {
26779 if i > 0 {
26780 self.write(", ");
26781 }
26782 self.generate_expression(expr)?;
26783 }
26784 self.write(")");
26785 }
26786 Ok(())
26787 }
26788
26789 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
26790 self.generate_expression(&e.this)?;
26793 if let Some(expression) = &e.expression {
26794 self.write_space();
26795 self.generate_expression(expression)?;
26796 }
26797 Ok(())
26798 }
26799
26800 fn generate_auto_increment_keyword(
26804 &mut self,
26805 col: &crate::expressions::ColumnDef,
26806 ) -> Result<()> {
26807 use crate::dialects::DialectType;
26808 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
26809 self.write_keyword("IDENTITY");
26810 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26811 self.write("(");
26812 if let Some(ref start) = col.auto_increment_start {
26813 self.generate_expression(start)?;
26814 } else {
26815 self.write("0");
26816 }
26817 self.write(", ");
26818 if let Some(ref inc) = col.auto_increment_increment {
26819 self.generate_expression(inc)?;
26820 } else {
26821 self.write("1");
26822 }
26823 self.write(")");
26824 }
26825 } else if matches!(
26826 self.config.dialect,
26827 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
26828 ) {
26829 self.write_keyword("AUTOINCREMENT");
26830 if let Some(ref start) = col.auto_increment_start {
26831 self.write_space();
26832 self.write_keyword("START");
26833 self.write_space();
26834 self.generate_expression(start)?;
26835 }
26836 if let Some(ref inc) = col.auto_increment_increment {
26837 self.write_space();
26838 self.write_keyword("INCREMENT");
26839 self.write_space();
26840 self.generate_expression(inc)?;
26841 }
26842 if let Some(order) = col.auto_increment_order {
26843 self.write_space();
26844 if order {
26845 self.write_keyword("ORDER");
26846 } else {
26847 self.write_keyword("NOORDER");
26848 }
26849 }
26850 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
26851 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
26852 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26853 self.write(" (");
26854 let mut first = true;
26855 if let Some(ref start) = col.auto_increment_start {
26856 self.write_keyword("START WITH");
26857 self.write_space();
26858 self.generate_expression(start)?;
26859 first = false;
26860 }
26861 if let Some(ref inc) = col.auto_increment_increment {
26862 if !first {
26863 self.write_space();
26864 }
26865 self.write_keyword("INCREMENT BY");
26866 self.write_space();
26867 self.generate_expression(inc)?;
26868 }
26869 self.write(")");
26870 }
26871 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
26872 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26875 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
26876 } else {
26877 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
26878 }
26879 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26880 self.write(" (");
26881 let mut first = true;
26882 if let Some(ref start) = col.auto_increment_start {
26883 self.write_keyword("START WITH");
26884 self.write_space();
26885 self.generate_expression(start)?;
26886 first = false;
26887 }
26888 if let Some(ref inc) = col.auto_increment_increment {
26889 if !first {
26890 self.write_space();
26891 }
26892 self.write_keyword("INCREMENT BY");
26893 self.write_space();
26894 self.generate_expression(inc)?;
26895 }
26896 self.write(")");
26897 }
26898 } else if matches!(
26899 self.config.dialect,
26900 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26901 ) {
26902 self.write_keyword("IDENTITY");
26903 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26904 self.write("(");
26905 if let Some(ref start) = col.auto_increment_start {
26906 self.generate_expression(start)?;
26907 } else {
26908 self.write("0");
26909 }
26910 self.write(", ");
26911 if let Some(ref inc) = col.auto_increment_increment {
26912 self.generate_expression(inc)?;
26913 } else {
26914 self.write("1");
26915 }
26916 self.write(")");
26917 }
26918 } else {
26919 self.write_keyword("AUTO_INCREMENT");
26920 if let Some(ref start) = col.auto_increment_start {
26921 self.write_space();
26922 self.write_keyword("START");
26923 self.write_space();
26924 self.generate_expression(start)?;
26925 }
26926 if let Some(ref inc) = col.auto_increment_increment {
26927 self.write_space();
26928 self.write_keyword("INCREMENT");
26929 self.write_space();
26930 self.generate_expression(inc)?;
26931 }
26932 if let Some(order) = col.auto_increment_order {
26933 self.write_space();
26934 if order {
26935 self.write_keyword("ORDER");
26936 } else {
26937 self.write_keyword("NOORDER");
26938 }
26939 }
26940 }
26941 Ok(())
26942 }
26943
26944 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
26945 self.write_keyword("AUTO_INCREMENT");
26947 self.write("=");
26948 self.generate_expression(&e.this)?;
26949 Ok(())
26950 }
26951
26952 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
26953 self.write_keyword("AUTO_REFRESH");
26955 self.write("=");
26956 self.generate_expression(&e.this)?;
26957 Ok(())
26958 }
26959
26960 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
26961 self.write_keyword("BACKUP");
26963 self.write_space();
26964 self.generate_expression(&e.this)?;
26965 Ok(())
26966 }
26967
26968 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
26969 self.write_keyword("BASE64_DECODE_BINARY");
26971 self.write("(");
26972 self.generate_expression(&e.this)?;
26973 if let Some(alphabet) = &e.alphabet {
26974 self.write(", ");
26975 self.generate_expression(alphabet)?;
26976 }
26977 self.write(")");
26978 Ok(())
26979 }
26980
26981 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
26982 self.write_keyword("BASE64_DECODE_STRING");
26984 self.write("(");
26985 self.generate_expression(&e.this)?;
26986 if let Some(alphabet) = &e.alphabet {
26987 self.write(", ");
26988 self.generate_expression(alphabet)?;
26989 }
26990 self.write(")");
26991 Ok(())
26992 }
26993
26994 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
26995 self.write_keyword("BASE64_ENCODE");
26997 self.write("(");
26998 self.generate_expression(&e.this)?;
26999 if let Some(max_line_length) = &e.max_line_length {
27000 self.write(", ");
27001 self.generate_expression(max_line_length)?;
27002 }
27003 if let Some(alphabet) = &e.alphabet {
27004 self.write(", ");
27005 self.generate_expression(alphabet)?;
27006 }
27007 self.write(")");
27008 Ok(())
27009 }
27010
27011 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
27012 self.write_keyword("BLOCKCOMPRESSION");
27014 self.write("=");
27015 if let Some(autotemp) = &e.autotemp {
27016 self.write_keyword("AUTOTEMP");
27017 self.write("(");
27018 self.generate_expression(autotemp)?;
27019 self.write(")");
27020 }
27021 if let Some(always) = &e.always {
27022 self.generate_expression(always)?;
27023 }
27024 if let Some(default) = &e.default {
27025 self.generate_expression(default)?;
27026 }
27027 if let Some(manual) = &e.manual {
27028 self.generate_expression(manual)?;
27029 }
27030 if let Some(never) = &e.never {
27031 self.generate_expression(never)?;
27032 }
27033 Ok(())
27034 }
27035
27036 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
27037 self.write("((");
27039 self.generate_expression(&e.this)?;
27040 self.write(") ");
27041 self.write_keyword("AND");
27042 self.write(" (");
27043 self.generate_expression(&e.expression)?;
27044 self.write("))");
27045 Ok(())
27046 }
27047
27048 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
27049 self.write("((");
27051 self.generate_expression(&e.this)?;
27052 self.write(") ");
27053 self.write_keyword("OR");
27054 self.write(" (");
27055 self.generate_expression(&e.expression)?;
27056 self.write("))");
27057 Ok(())
27058 }
27059
27060 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
27061 self.write_keyword("BUILD");
27063 self.write_space();
27064 self.generate_expression(&e.this)?;
27065 Ok(())
27066 }
27067
27068 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
27069 self.generate_expression(&e.this)?;
27071 Ok(())
27072 }
27073
27074 fn generate_case_specific_column_constraint(
27075 &mut self,
27076 e: &CaseSpecificColumnConstraint,
27077 ) -> Result<()> {
27078 if e.not_.is_some() {
27080 self.write_keyword("NOT");
27081 self.write_space();
27082 }
27083 self.write_keyword("CASESPECIFIC");
27084 Ok(())
27085 }
27086
27087 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
27088 self.write_keyword("CAST");
27090 self.write("(");
27091 self.generate_expression(&e.this)?;
27092 if self.config.dialect == Some(DialectType::ClickHouse) {
27093 self.write(", ");
27095 } else {
27096 self.write_space();
27097 self.write_keyword("AS");
27098 self.write_space();
27099 }
27100 if let Some(to) = &e.to {
27101 self.generate_expression(to)?;
27102 }
27103 self.write(")");
27104 Ok(())
27105 }
27106
27107 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
27108 self.write_keyword("CHANGES");
27111 self.write(" (");
27112 if let Some(information) = &e.information {
27113 self.write_keyword("INFORMATION");
27114 self.write(" => ");
27115 self.generate_expression(information)?;
27116 }
27117 self.write(")");
27118 if let Some(at_before) = &e.at_before {
27120 self.write(" ");
27121 self.generate_expression(at_before)?;
27122 }
27123 if let Some(end) = &e.end {
27124 self.write(" ");
27125 self.generate_expression(end)?;
27126 }
27127 Ok(())
27128 }
27129
27130 fn generate_character_set_column_constraint(
27131 &mut self,
27132 e: &CharacterSetColumnConstraint,
27133 ) -> Result<()> {
27134 self.write_keyword("CHARACTER SET");
27136 self.write_space();
27137 self.generate_expression(&e.this)?;
27138 Ok(())
27139 }
27140
27141 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
27142 if e.default.is_some() {
27144 self.write_keyword("DEFAULT");
27145 self.write_space();
27146 }
27147 self.write_keyword("CHARACTER SET");
27148 self.write("=");
27149 self.generate_expression(&e.this)?;
27150 Ok(())
27151 }
27152
27153 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
27154 self.write_keyword("CHECK");
27156 self.write(" (");
27157 self.generate_expression(&e.this)?;
27158 self.write(")");
27159 if e.enforced.is_some() {
27160 self.write_space();
27161 self.write_keyword("ENFORCED");
27162 }
27163 Ok(())
27164 }
27165
27166 fn generate_assume_column_constraint(&mut self, e: &AssumeColumnConstraint) -> Result<()> {
27167 self.write_keyword("ASSUME");
27169 self.write(" (");
27170 self.generate_expression(&e.this)?;
27171 self.write(")");
27172 Ok(())
27173 }
27174
27175 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
27176 self.write_keyword("CHECK_JSON");
27178 self.write("(");
27179 self.generate_expression(&e.this)?;
27180 self.write(")");
27181 Ok(())
27182 }
27183
27184 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
27185 self.write_keyword("CHECK_XML");
27187 self.write("(");
27188 self.generate_expression(&e.this)?;
27189 self.write(")");
27190 Ok(())
27191 }
27192
27193 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
27194 self.write_keyword("CHECKSUM");
27196 self.write("=");
27197 if e.on.is_some() {
27198 self.write_keyword("ON");
27199 } else if e.default.is_some() {
27200 self.write_keyword("DEFAULT");
27201 } else {
27202 self.write_keyword("OFF");
27203 }
27204 Ok(())
27205 }
27206
27207 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
27208 if e.shallow.is_some() {
27210 self.write_keyword("SHALLOW");
27211 self.write_space();
27212 }
27213 if e.copy.is_some() {
27214 self.write_keyword("COPY");
27215 } else {
27216 self.write_keyword("CLONE");
27217 }
27218 self.write_space();
27219 self.generate_expression(&e.this)?;
27220 Ok(())
27221 }
27222
27223 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
27224 self.write_keyword("CLUSTER BY");
27226 self.write(" (");
27227 for (i, ord) in e.expressions.iter().enumerate() {
27228 if i > 0 {
27229 self.write(", ");
27230 }
27231 self.generate_ordered(ord)?;
27232 }
27233 self.write(")");
27234 Ok(())
27235 }
27236
27237 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
27238 self.write_keyword("CLUSTER BY");
27240 self.write_space();
27241 for (i, col) in e.columns.iter().enumerate() {
27242 if i > 0 {
27243 self.write(", ");
27244 }
27245 self.generate_identifier(col)?;
27246 }
27247 Ok(())
27248 }
27249
27250 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
27251 self.write_keyword("CLUSTERED BY");
27253 self.write(" (");
27254 for (i, expr) in e.expressions.iter().enumerate() {
27255 if i > 0 {
27256 self.write(", ");
27257 }
27258 self.generate_expression(expr)?;
27259 }
27260 self.write(")");
27261 if let Some(sorted_by) = &e.sorted_by {
27262 self.write_space();
27263 self.write_keyword("SORTED BY");
27264 self.write(" (");
27265 if let Expression::Tuple(t) = sorted_by.as_ref() {
27267 for (i, expr) in t.expressions.iter().enumerate() {
27268 if i > 0 {
27269 self.write(", ");
27270 }
27271 self.generate_expression(expr)?;
27272 }
27273 } else {
27274 self.generate_expression(sorted_by)?;
27275 }
27276 self.write(")");
27277 }
27278 if let Some(buckets) = &e.buckets {
27279 self.write_space();
27280 self.write_keyword("INTO");
27281 self.write_space();
27282 self.generate_expression(buckets)?;
27283 self.write_space();
27284 self.write_keyword("BUCKETS");
27285 }
27286 Ok(())
27287 }
27288
27289 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
27290 if e.default.is_some() {
27294 self.write_keyword("DEFAULT");
27295 self.write_space();
27296 }
27297 self.write_keyword("COLLATE");
27298 match self.config.dialect {
27300 Some(DialectType::BigQuery) => self.write_space(),
27301 _ => self.write("="),
27302 }
27303 self.generate_expression(&e.this)?;
27304 Ok(())
27305 }
27306
27307 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
27308 match e {
27310 ColumnConstraint::NotNull => {
27311 self.write_keyword("NOT NULL");
27312 }
27313 ColumnConstraint::Null => {
27314 self.write_keyword("NULL");
27315 }
27316 ColumnConstraint::Unique => {
27317 self.write_keyword("UNIQUE");
27318 }
27319 ColumnConstraint::PrimaryKey => {
27320 self.write_keyword("PRIMARY KEY");
27321 }
27322 ColumnConstraint::Default(expr) => {
27323 self.write_keyword("DEFAULT");
27324 self.write_space();
27325 self.generate_expression(expr)?;
27326 }
27327 ColumnConstraint::Check(expr) => {
27328 self.write_keyword("CHECK");
27329 self.write(" (");
27330 self.generate_expression(expr)?;
27331 self.write(")");
27332 }
27333 ColumnConstraint::References(fk_ref) => {
27334 if fk_ref.has_foreign_key_keywords {
27335 self.write_keyword("FOREIGN KEY");
27336 self.write_space();
27337 }
27338 self.write_keyword("REFERENCES");
27339 self.write_space();
27340 self.generate_table(&fk_ref.table)?;
27341 if !fk_ref.columns.is_empty() {
27342 self.write(" (");
27343 for (i, col) in fk_ref.columns.iter().enumerate() {
27344 if i > 0 {
27345 self.write(", ");
27346 }
27347 self.generate_identifier(col)?;
27348 }
27349 self.write(")");
27350 }
27351 }
27352 ColumnConstraint::GeneratedAsIdentity(gen) => {
27353 self.write_keyword("GENERATED");
27354 self.write_space();
27355 if gen.always {
27356 self.write_keyword("ALWAYS");
27357 } else {
27358 self.write_keyword("BY DEFAULT");
27359 if gen.on_null {
27360 self.write_space();
27361 self.write_keyword("ON NULL");
27362 }
27363 }
27364 self.write_space();
27365 self.write_keyword("AS IDENTITY");
27366 }
27367 ColumnConstraint::Collate(collation) => {
27368 self.write_keyword("COLLATE");
27369 self.write_space();
27370 self.generate_identifier(collation)?;
27371 }
27372 ColumnConstraint::Comment(comment) => {
27373 self.write_keyword("COMMENT");
27374 self.write(" '");
27375 self.write(comment);
27376 self.write("'");
27377 }
27378 ColumnConstraint::ComputedColumn(cc) => {
27379 self.generate_computed_column_inline(cc)?;
27380 }
27381 ColumnConstraint::GeneratedAsRow(gar) => {
27382 self.generate_generated_as_row_inline(gar)?;
27383 }
27384 ColumnConstraint::Tags(tags) => {
27385 self.write_keyword("TAG");
27386 self.write(" (");
27387 for (i, expr) in tags.expressions.iter().enumerate() {
27388 if i > 0 {
27389 self.write(", ");
27390 }
27391 self.generate_expression(expr)?;
27392 }
27393 self.write(")");
27394 }
27395 ColumnConstraint::Path(path_expr) => {
27396 self.write_keyword("PATH");
27397 self.write_space();
27398 self.generate_expression(path_expr)?;
27399 }
27400 }
27401 Ok(())
27402 }
27403
27404 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
27405 match e {
27407 ColumnPosition::First => {
27408 self.write_keyword("FIRST");
27409 }
27410 ColumnPosition::After(ident) => {
27411 self.write_keyword("AFTER");
27412 self.write_space();
27413 self.generate_identifier(ident)?;
27414 }
27415 }
27416 Ok(())
27417 }
27418
27419 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
27420 self.generate_expression(&e.this)?;
27422 self.write("(");
27423 self.generate_expression(&e.expression)?;
27424 self.write(")");
27425 Ok(())
27426 }
27427
27428 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
27429 if let Some(ref unpack) = e.unpack {
27432 if let Expression::Boolean(b) = unpack.as_ref() {
27433 if b.value {
27434 self.write("*");
27435 }
27436 }
27437 }
27438 self.write_keyword("COLUMNS");
27439 self.write("(");
27440 self.generate_expression(&e.this)?;
27441 self.write(")");
27442 Ok(())
27443 }
27444
27445 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
27446 self.generate_expression(&e.this)?;
27448 self.write("(");
27449 for (i, expr) in e.expressions.iter().enumerate() {
27450 if i > 0 {
27451 self.write(", ");
27452 }
27453 self.generate_expression(expr)?;
27454 }
27455 self.write(")");
27456 Ok(())
27457 }
27458
27459 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
27460 self.generate_expression(&e.this)?;
27462 self.write("(");
27463 for (i, param) in e.params.iter().enumerate() {
27464 if i > 0 {
27465 self.write(", ");
27466 }
27467 self.generate_expression(param)?;
27468 }
27469 self.write(")(");
27470 for (i, expr) in e.expressions.iter().enumerate() {
27471 if i > 0 {
27472 self.write(", ");
27473 }
27474 self.generate_expression(expr)?;
27475 }
27476 self.write(")");
27477 Ok(())
27478 }
27479
27480 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
27481 self.write_keyword("COMMIT");
27483
27484 if e.this.is_none()
27486 && matches!(
27487 self.config.dialect,
27488 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27489 )
27490 {
27491 self.write_space();
27492 self.write_keyword("TRANSACTION");
27493 }
27494
27495 if let Some(this) = &e.this {
27497 let is_transaction_marker = matches!(
27499 this.as_ref(),
27500 Expression::Identifier(id) if id.name == "TRANSACTION"
27501 );
27502
27503 self.write_space();
27504 self.write_keyword("TRANSACTION");
27505
27506 if !is_transaction_marker {
27508 self.write_space();
27509 self.generate_expression(this)?;
27510 }
27511 }
27512
27513 if let Some(durability) = &e.durability {
27515 self.write_space();
27516 self.write_keyword("WITH");
27517 self.write(" (");
27518 self.write_keyword("DELAYED_DURABILITY");
27519 self.write(" = ");
27520 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
27521 self.write_keyword("ON");
27522 } else {
27523 self.write_keyword("OFF");
27524 }
27525 self.write(")");
27526 }
27527
27528 if let Some(chain) = &e.chain {
27530 self.write_space();
27531 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
27532 self.write_keyword("AND NO CHAIN");
27533 } else {
27534 self.write_keyword("AND CHAIN");
27535 }
27536 }
27537 Ok(())
27538 }
27539
27540 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
27541 self.write("[");
27543 self.generate_expression(&e.this)?;
27544 self.write_space();
27545 self.write_keyword("FOR");
27546 self.write_space();
27547 self.generate_expression(&e.expression)?;
27548 if let Some(pos) = &e.position {
27550 self.write(", ");
27551 self.generate_expression(pos)?;
27552 }
27553 if let Some(iterator) = &e.iterator {
27554 self.write_space();
27555 self.write_keyword("IN");
27556 self.write_space();
27557 self.generate_expression(iterator)?;
27558 }
27559 if let Some(condition) = &e.condition {
27560 self.write_space();
27561 self.write_keyword("IF");
27562 self.write_space();
27563 self.generate_expression(condition)?;
27564 }
27565 self.write("]");
27566 Ok(())
27567 }
27568
27569 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
27570 self.write_keyword("COMPRESS");
27572 self.write("(");
27573 self.generate_expression(&e.this)?;
27574 if let Some(method) = &e.method {
27575 self.write(", '");
27576 self.write(method);
27577 self.write("'");
27578 }
27579 self.write(")");
27580 Ok(())
27581 }
27582
27583 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
27584 self.write_keyword("COMPRESS");
27586 if let Some(this) = &e.this {
27587 self.write_space();
27588 self.generate_expression(this)?;
27589 }
27590 Ok(())
27591 }
27592
27593 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
27594 self.write_keyword("AS");
27596 self.write_space();
27597 self.generate_expression(&e.this)?;
27598 if e.not_null.is_some() {
27599 self.write_space();
27600 self.write_keyword("PERSISTED NOT NULL");
27601 } else if e.persisted.is_some() {
27602 self.write_space();
27603 self.write_keyword("PERSISTED");
27604 }
27605 Ok(())
27606 }
27607
27608 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
27612 let computed_expr = if matches!(
27613 self.config.dialect,
27614 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27615 ) {
27616 match &*cc.expression {
27617 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
27618 {
27619 let wrapped = Expression::Cast(Box::new(Cast {
27620 this: y.this.clone(),
27621 to: DataType::Date,
27622 trailing_comments: Vec::new(),
27623 double_colon_syntax: false,
27624 format: None,
27625 default: None,
27626 inferred_type: None,
27627 }));
27628 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
27629 }
27630 Expression::Function(f)
27631 if f.name.eq_ignore_ascii_case("YEAR")
27632 && f.args.len() == 1
27633 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
27634 {
27635 let wrapped = Expression::Cast(Box::new(Cast {
27636 this: f.args[0].clone(),
27637 to: DataType::Date,
27638 trailing_comments: Vec::new(),
27639 double_colon_syntax: false,
27640 format: None,
27641 default: None,
27642 inferred_type: None,
27643 }));
27644 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
27645 }
27646 _ => *cc.expression.clone(),
27647 }
27648 } else {
27649 *cc.expression.clone()
27650 };
27651
27652 match cc.persistence_kind.as_deref() {
27653 Some("STORED") | Some("VIRTUAL") => {
27654 self.write_keyword("GENERATED ALWAYS AS");
27656 self.write(" (");
27657 self.generate_expression(&computed_expr)?;
27658 self.write(")");
27659 self.write_space();
27660 if cc.persisted {
27661 self.write_keyword("STORED");
27662 } else {
27663 self.write_keyword("VIRTUAL");
27664 }
27665 }
27666 Some("PERSISTED") => {
27667 self.write_keyword("AS");
27669 self.write(" (");
27670 self.generate_expression(&computed_expr)?;
27671 self.write(")");
27672 self.write_space();
27673 self.write_keyword("PERSISTED");
27674 if let Some(ref dt) = cc.data_type {
27676 self.write_space();
27677 self.generate_data_type(dt)?;
27678 }
27679 if cc.not_null {
27680 self.write_space();
27681 self.write_keyword("NOT NULL");
27682 }
27683 }
27684 _ => {
27685 if matches!(
27688 self.config.dialect,
27689 Some(DialectType::Spark)
27690 | Some(DialectType::Databricks)
27691 | Some(DialectType::Hive)
27692 ) {
27693 self.write_keyword("GENERATED ALWAYS AS");
27694 self.write(" (");
27695 self.generate_expression(&computed_expr)?;
27696 self.write(")");
27697 } else if matches!(
27698 self.config.dialect,
27699 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27700 ) {
27701 self.write_keyword("AS");
27702 let omit_parens = matches!(computed_expr, Expression::Year(_))
27703 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
27704 if omit_parens {
27705 self.write_space();
27706 self.generate_expression(&computed_expr)?;
27707 } else {
27708 self.write(" (");
27709 self.generate_expression(&computed_expr)?;
27710 self.write(")");
27711 }
27712 } else {
27713 self.write_keyword("AS");
27714 self.write(" (");
27715 self.generate_expression(&computed_expr)?;
27716 self.write(")");
27717 }
27718 }
27719 }
27720 Ok(())
27721 }
27722
27723 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
27726 self.write_keyword("GENERATED ALWAYS AS ROW ");
27727 if gar.start {
27728 self.write_keyword("START");
27729 } else {
27730 self.write_keyword("END");
27731 }
27732 if gar.hidden {
27733 self.write_space();
27734 self.write_keyword("HIDDEN");
27735 }
27736 Ok(())
27737 }
27738
27739 fn generate_system_versioning_content(
27741 &mut self,
27742 e: &WithSystemVersioningProperty,
27743 ) -> Result<()> {
27744 let mut parts = Vec::new();
27745
27746 if let Some(this) = &e.this {
27747 let mut s = String::from("HISTORY_TABLE=");
27748 let mut gen = Generator::with_arc_config(self.config.clone());
27749 gen.generate_expression(this)?;
27750 s.push_str(&gen.output);
27751 parts.push(s);
27752 }
27753
27754 if let Some(data_consistency) = &e.data_consistency {
27755 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
27756 let mut gen = Generator::with_arc_config(self.config.clone());
27757 gen.generate_expression(data_consistency)?;
27758 s.push_str(&gen.output);
27759 parts.push(s);
27760 }
27761
27762 if let Some(retention_period) = &e.retention_period {
27763 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
27764 let mut gen = Generator::with_arc_config(self.config.clone());
27765 gen.generate_expression(retention_period)?;
27766 s.push_str(&gen.output);
27767 parts.push(s);
27768 }
27769
27770 self.write_keyword("SYSTEM_VERSIONING");
27771 self.write("=");
27772
27773 if !parts.is_empty() {
27774 self.write_keyword("ON");
27775 self.write("(");
27776 self.write(&parts.join(", "));
27777 self.write(")");
27778 } else if e.on.is_some() {
27779 self.write_keyword("ON");
27780 } else {
27781 self.write_keyword("OFF");
27782 }
27783
27784 Ok(())
27785 }
27786
27787 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
27788 if e.else_.is_some() {
27791 self.write_keyword("ELSE");
27792 self.write_space();
27793 } else if let Some(expression) = &e.expression {
27794 self.write_keyword("WHEN");
27795 self.write_space();
27796 self.generate_expression(expression)?;
27797 self.write_space();
27798 self.write_keyword("THEN");
27799 self.write_space();
27800 }
27801
27802 if let Expression::Insert(insert) = e.this.as_ref() {
27805 self.write_keyword("INTO");
27806 self.write_space();
27807 self.generate_table(&insert.table)?;
27808
27809 if !insert.columns.is_empty() {
27811 self.write(" (");
27812 for (i, col) in insert.columns.iter().enumerate() {
27813 if i > 0 {
27814 self.write(", ");
27815 }
27816 self.generate_identifier(col)?;
27817 }
27818 self.write(")");
27819 }
27820
27821 if !insert.values.is_empty() {
27823 self.write_space();
27824 self.write_keyword("VALUES");
27825 for (row_idx, row) in insert.values.iter().enumerate() {
27826 if row_idx > 0 {
27827 self.write(", ");
27828 }
27829 self.write(" (");
27830 for (i, val) in row.iter().enumerate() {
27831 if i > 0 {
27832 self.write(", ");
27833 }
27834 self.generate_expression(val)?;
27835 }
27836 self.write(")");
27837 }
27838 }
27839 } else {
27840 self.generate_expression(&e.this)?;
27842 }
27843 Ok(())
27844 }
27845
27846 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
27847 self.write_keyword("CONSTRAINT");
27849 self.write_space();
27850 self.generate_expression(&e.this)?;
27851 if !e.expressions.is_empty() {
27852 self.write_space();
27853 for (i, expr) in e.expressions.iter().enumerate() {
27854 if i > 0 {
27855 self.write_space();
27856 }
27857 self.generate_expression(expr)?;
27858 }
27859 }
27860 Ok(())
27861 }
27862
27863 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
27864 self.write_keyword("CONVERT_TIMEZONE");
27866 self.write("(");
27867 let mut first = true;
27868 if let Some(source_tz) = &e.source_tz {
27869 self.generate_expression(source_tz)?;
27870 first = false;
27871 }
27872 if let Some(target_tz) = &e.target_tz {
27873 if !first {
27874 self.write(", ");
27875 }
27876 self.generate_expression(target_tz)?;
27877 first = false;
27878 }
27879 if let Some(timestamp) = &e.timestamp {
27880 if !first {
27881 self.write(", ");
27882 }
27883 self.generate_expression(timestamp)?;
27884 }
27885 self.write(")");
27886 Ok(())
27887 }
27888
27889 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
27890 self.write_keyword("CONVERT");
27892 self.write("(");
27893 self.generate_expression(&e.this)?;
27894 if let Some(dest) = &e.dest {
27895 self.write_space();
27896 self.write_keyword("USING");
27897 self.write_space();
27898 self.generate_expression(dest)?;
27899 }
27900 self.write(")");
27901 Ok(())
27902 }
27903
27904 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
27905 self.write_keyword("COPY");
27906 if e.is_into {
27907 self.write_space();
27908 self.write_keyword("INTO");
27909 }
27910 self.write_space();
27911
27912 if let Expression::Literal(lit) = &e.this {
27914 if let Literal::String(s) = lit.as_ref() {
27915 if s.starts_with('@') {
27916 self.write(s);
27917 } else {
27918 self.generate_expression(&e.this)?;
27919 }
27920 }
27921 } else {
27922 self.generate_expression(&e.this)?;
27923 }
27924
27925 if e.kind {
27927 if self.config.pretty {
27929 self.write_newline();
27930 } else {
27931 self.write_space();
27932 }
27933 self.write_keyword("FROM");
27934 self.write_space();
27935 } else if !e.files.is_empty() {
27936 if self.config.pretty {
27938 self.write_newline();
27939 } else {
27940 self.write_space();
27941 }
27942 self.write_keyword("TO");
27943 self.write_space();
27944 }
27945
27946 for (i, file) in e.files.iter().enumerate() {
27948 if i > 0 {
27949 self.write_space();
27950 }
27951 if let Expression::Literal(lit) = file {
27953 if let Literal::String(s) = lit.as_ref() {
27954 if s.starts_with('@') {
27955 self.write(s);
27956 } else {
27957 self.generate_expression(file)?;
27958 }
27959 }
27960 } else if let Expression::Identifier(id) = file {
27961 if id.quoted {
27963 self.write("`");
27964 self.write(&id.name);
27965 self.write("`");
27966 } else {
27967 self.generate_expression(file)?;
27968 }
27969 } else {
27970 self.generate_expression(file)?;
27971 }
27972 }
27973
27974 if !e.with_wrapped {
27976 if let Some(ref creds) = e.credentials {
27977 if let Some(ref storage) = creds.storage {
27978 if self.config.pretty {
27979 self.write_newline();
27980 } else {
27981 self.write_space();
27982 }
27983 self.write_keyword("STORAGE_INTEGRATION");
27984 self.write(" = ");
27985 self.write(storage);
27986 }
27987 if creds.credentials.is_empty() {
27988 if self.config.pretty {
27990 self.write_newline();
27991 } else {
27992 self.write_space();
27993 }
27994 self.write_keyword("CREDENTIALS");
27995 self.write(" = ()");
27996 } else {
27997 if self.config.pretty {
27998 self.write_newline();
27999 } else {
28000 self.write_space();
28001 }
28002 self.write_keyword("CREDENTIALS");
28003 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
28006 self.write(" '");
28008 self.write(&creds.credentials[0].1);
28009 self.write("'");
28010 } else {
28011 self.write(" = (");
28013 for (i, (k, v)) in creds.credentials.iter().enumerate() {
28014 if i > 0 {
28015 self.write_space();
28016 }
28017 self.write(k);
28018 self.write("='");
28019 self.write(v);
28020 self.write("'");
28021 }
28022 self.write(")");
28023 }
28024 }
28025 if let Some(ref encryption) = creds.encryption {
28026 self.write_space();
28027 self.write_keyword("ENCRYPTION");
28028 self.write(" = ");
28029 self.write(encryption);
28030 }
28031 }
28032 }
28033
28034 if !e.params.is_empty() {
28036 if e.with_wrapped {
28037 self.write_space();
28039 self.write_keyword("WITH");
28040 self.write(" (");
28041 for (i, param) in e.params.iter().enumerate() {
28042 if i > 0 {
28043 self.write(", ");
28044 }
28045 self.generate_copy_param_with_format(param)?;
28046 }
28047 self.write(")");
28048 } else {
28049 for param in &e.params {
28053 if self.config.pretty {
28054 self.write_newline();
28055 } else {
28056 self.write_space();
28057 }
28058 self.write(¶m.name);
28060 if let Some(ref value) = param.value {
28061 if param.eq {
28063 self.write(" = ");
28064 } else {
28065 self.write(" ");
28066 }
28067 if !param.values.is_empty() {
28068 self.write("(");
28069 for (i, v) in param.values.iter().enumerate() {
28070 if i > 0 {
28071 self.write_space();
28072 }
28073 self.generate_copy_nested_param(v)?;
28074 }
28075 self.write(")");
28076 } else {
28077 self.generate_copy_param_value(value)?;
28079 }
28080 } else if !param.values.is_empty() {
28081 if param.eq {
28083 self.write(" = (");
28084 } else {
28085 self.write(" (");
28086 }
28087 let is_key_value_pairs = param
28092 .values
28093 .first()
28094 .map_or(false, |v| matches!(v, Expression::Eq(_)));
28095 let sep = if is_key_value_pairs && param.eq {
28096 " "
28097 } else {
28098 ", "
28099 };
28100 for (i, v) in param.values.iter().enumerate() {
28101 if i > 0 {
28102 self.write(sep);
28103 }
28104 self.generate_copy_nested_param(v)?;
28105 }
28106 self.write(")");
28107 }
28108 }
28109 }
28110 }
28111
28112 Ok(())
28113 }
28114
28115 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
28118 self.write_keyword(¶m.name);
28119 if !param.values.is_empty() {
28120 self.write(" = (");
28122 for (i, v) in param.values.iter().enumerate() {
28123 if i > 0 {
28124 self.write(", ");
28125 }
28126 self.generate_copy_nested_param(v)?;
28127 }
28128 self.write(")");
28129 } else if let Some(ref value) = param.value {
28130 if param.eq {
28131 self.write(" = ");
28132 } else {
28133 self.write(" ");
28134 }
28135 self.generate_expression(value)?;
28136 }
28137 Ok(())
28138 }
28139
28140 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
28142 match expr {
28143 Expression::Eq(eq) => {
28144 match &eq.left {
28146 Expression::Column(c) => self.write(&c.name.name),
28147 _ => self.generate_expression(&eq.left)?,
28148 }
28149 self.write("=");
28150 match &eq.right {
28152 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
28153 let Literal::String(s) = lit.as_ref() else {
28154 unreachable!()
28155 };
28156 self.write("'");
28157 self.write(s);
28158 self.write("'");
28159 }
28160 Expression::Tuple(t) => {
28161 self.write("(");
28163 if self.config.pretty {
28164 self.write_newline();
28165 self.indent_level += 1;
28166 for (i, item) in t.expressions.iter().enumerate() {
28167 if i > 0 {
28168 self.write(", ");
28169 }
28170 self.write_indent();
28171 self.generate_expression(item)?;
28172 }
28173 self.write_newline();
28174 self.indent_level -= 1;
28175 } else {
28176 for (i, item) in t.expressions.iter().enumerate() {
28177 if i > 0 {
28178 self.write(", ");
28179 }
28180 self.generate_expression(item)?;
28181 }
28182 }
28183 self.write(")");
28184 }
28185 _ => self.generate_expression(&eq.right)?,
28186 }
28187 Ok(())
28188 }
28189 Expression::Column(c) => {
28190 self.write(&c.name.name);
28192 Ok(())
28193 }
28194 _ => self.generate_expression(expr),
28195 }
28196 }
28197
28198 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
28201 match expr {
28202 Expression::Column(c) => {
28203 if c.name.quoted {
28205 self.write("\"");
28206 self.write(&c.name.name);
28207 self.write("\"");
28208 } else {
28209 self.write(&c.name.name);
28210 }
28211 Ok(())
28212 }
28213 Expression::Identifier(id) => {
28214 if id.quoted {
28216 self.write("\"");
28217 self.write(&id.name);
28218 self.write("\"");
28219 } else {
28220 self.write(&id.name);
28221 }
28222 Ok(())
28223 }
28224 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
28225 let Literal::String(s) = lit.as_ref() else {
28226 unreachable!()
28227 };
28228 self.write("'");
28230 self.write(s);
28231 self.write("'");
28232 Ok(())
28233 }
28234 _ => self.generate_expression(expr),
28235 }
28236 }
28237
28238 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
28239 self.write_keyword(&e.name);
28240 if let Some(ref value) = e.value {
28241 if e.eq {
28242 self.write(" = ");
28243 } else {
28244 self.write(" ");
28245 }
28246 self.generate_expression(value)?;
28247 }
28248 if !e.values.is_empty() {
28249 if e.eq {
28250 self.write(" = ");
28251 } else {
28252 self.write(" ");
28253 }
28254 self.write("(");
28255 for (i, v) in e.values.iter().enumerate() {
28256 if i > 0 {
28257 self.write(", ");
28258 }
28259 self.generate_expression(v)?;
28260 }
28261 self.write(")");
28262 }
28263 Ok(())
28264 }
28265
28266 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
28267 self.write_keyword("CORR");
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_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
28278 self.write_keyword("COSINE_DISTANCE");
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_pop(&mut self, e: &CovarPop) -> Result<()> {
28289 self.write_keyword("COVAR_POP");
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_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
28300 self.write_keyword("COVAR_SAMP");
28302 self.write("(");
28303 self.generate_expression(&e.this)?;
28304 self.write(", ");
28305 self.generate_expression(&e.expression)?;
28306 self.write(")");
28307 Ok(())
28308 }
28309
28310 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
28311 self.write_keyword("CREDENTIALS");
28313 self.write(" (");
28314 for (i, (key, value)) in e.credentials.iter().enumerate() {
28315 if i > 0 {
28316 self.write(", ");
28317 }
28318 self.write(key);
28319 self.write("='");
28320 self.write(value);
28321 self.write("'");
28322 }
28323 self.write(")");
28324 Ok(())
28325 }
28326
28327 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
28328 self.write_keyword("CREDENTIALS");
28330 self.write("=(");
28331 for (i, expr) in e.expressions.iter().enumerate() {
28332 if i > 0 {
28333 self.write(", ");
28334 }
28335 self.generate_expression(expr)?;
28336 }
28337 self.write(")");
28338 Ok(())
28339 }
28340
28341 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
28342 use crate::dialects::DialectType;
28343
28344 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
28347 self.generate_expression(&e.this)?;
28348 self.write_space();
28349 self.write_keyword("AS");
28350 self.write_space();
28351 self.generate_identifier(&e.alias)?;
28352 return Ok(());
28353 }
28354 self.write(&e.alias.name);
28355
28356 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
28358
28359 if !e.columns.is_empty() && !skip_cte_columns {
28360 self.write("(");
28361 for (i, col) in e.columns.iter().enumerate() {
28362 if i > 0 {
28363 self.write(", ");
28364 }
28365 self.write(&col.name);
28366 }
28367 self.write(")");
28368 }
28369 if !e.key_expressions.is_empty() {
28371 self.write_space();
28372 self.write_keyword("USING KEY");
28373 self.write(" (");
28374 for (i, key) in e.key_expressions.iter().enumerate() {
28375 if i > 0 {
28376 self.write(", ");
28377 }
28378 self.write(&key.name);
28379 }
28380 self.write(")");
28381 }
28382 self.write_space();
28383 self.write_keyword("AS");
28384 self.write_space();
28385 if let Some(materialized) = e.materialized {
28386 if materialized {
28387 self.write_keyword("MATERIALIZED");
28388 } else {
28389 self.write_keyword("NOT MATERIALIZED");
28390 }
28391 self.write_space();
28392 }
28393 self.write("(");
28394 self.generate_expression(&e.this)?;
28395 self.write(")");
28396 Ok(())
28397 }
28398
28399 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
28400 if e.expressions.is_empty() {
28402 self.write_keyword("WITH CUBE");
28403 } else {
28404 self.write_keyword("CUBE");
28405 self.write("(");
28406 for (i, expr) in e.expressions.iter().enumerate() {
28407 if i > 0 {
28408 self.write(", ");
28409 }
28410 self.generate_expression(expr)?;
28411 }
28412 self.write(")");
28413 }
28414 Ok(())
28415 }
28416
28417 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
28418 self.write_keyword("CURRENT_DATETIME");
28420 if let Some(this) = &e.this {
28421 self.write("(");
28422 self.generate_expression(this)?;
28423 self.write(")");
28424 }
28425 Ok(())
28426 }
28427
28428 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
28429 self.write_keyword("CURRENT_SCHEMA");
28431 Ok(())
28432 }
28433
28434 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
28435 self.write_keyword("CURRENT_SCHEMAS");
28437 self.write("(");
28438 if !matches!(
28440 self.config.dialect,
28441 Some(crate::dialects::DialectType::Snowflake)
28442 ) {
28443 if let Some(this) = &e.this {
28444 self.generate_expression(this)?;
28445 }
28446 }
28447 self.write(")");
28448 Ok(())
28449 }
28450
28451 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
28452 self.write_keyword("CURRENT_USER");
28454 let needs_parens = e.this.is_some()
28456 || matches!(
28457 self.config.dialect,
28458 Some(DialectType::Snowflake)
28459 | Some(DialectType::Spark)
28460 | Some(DialectType::Hive)
28461 | Some(DialectType::DuckDB)
28462 | Some(DialectType::BigQuery)
28463 | Some(DialectType::MySQL)
28464 | Some(DialectType::Databricks)
28465 );
28466 if needs_parens {
28467 self.write("()");
28468 }
28469 Ok(())
28470 }
28471
28472 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
28473 if self.config.dialect == Some(DialectType::Solr) {
28475 self.generate_expression(&e.this)?;
28476 self.write(" ");
28477 self.write_keyword("OR");
28478 self.write(" ");
28479 self.generate_expression(&e.expression)?;
28480 } else if self.config.dialect == Some(DialectType::MySQL) {
28481 self.generate_mysql_concat_from_dpipe(e)?;
28482 } else {
28483 self.generate_expression(&e.this)?;
28485 self.write(" || ");
28486 self.generate_expression(&e.expression)?;
28487 }
28488 Ok(())
28489 }
28490
28491 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
28492 self.write_keyword("DATABLOCKSIZE");
28494 self.write("=");
28495 if let Some(size) = e.size {
28496 self.write(&size.to_string());
28497 if let Some(units) = &e.units {
28498 self.write_space();
28499 self.generate_expression(units)?;
28500 }
28501 } else if e.minimum.is_some() {
28502 self.write_keyword("MINIMUM");
28503 } else if e.maximum.is_some() {
28504 self.write_keyword("MAXIMUM");
28505 } else if e.default.is_some() {
28506 self.write_keyword("DEFAULT");
28507 }
28508 Ok(())
28509 }
28510
28511 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
28512 self.write_keyword("DATA_DELETION");
28514 self.write("=");
28515
28516 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
28517 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
28518
28519 if is_on {
28520 self.write_keyword("ON");
28521 if has_options {
28522 self.write("(");
28523 let mut first = true;
28524 if let Some(filter_column) = &e.filter_column {
28525 self.write_keyword("FILTER_COLUMN");
28526 self.write("=");
28527 self.generate_expression(filter_column)?;
28528 first = false;
28529 }
28530 if let Some(retention_period) = &e.retention_period {
28531 if !first {
28532 self.write(", ");
28533 }
28534 self.write_keyword("RETENTION_PERIOD");
28535 self.write("=");
28536 self.generate_expression(retention_period)?;
28537 }
28538 self.write(")");
28539 }
28540 } else {
28541 self.write_keyword("OFF");
28542 }
28543 Ok(())
28544 }
28545
28546 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
28550 use crate::dialects::DialectType;
28551 use crate::expressions::Literal;
28552
28553 match self.config.dialect {
28554 Some(DialectType::Exasol) => {
28556 self.write_keyword("TO_DATE");
28557 self.write("(");
28558 match &e.this {
28560 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
28561 let Literal::String(s) = lit.as_ref() else {
28562 unreachable!()
28563 };
28564 self.write("'");
28565 self.write(s);
28566 self.write("'");
28567 }
28568 _ => {
28569 self.generate_expression(&e.this)?;
28570 }
28571 }
28572 self.write(")");
28573 }
28574 _ => {
28576 self.write_keyword("DATE");
28577 self.write("(");
28578 self.generate_expression(&e.this)?;
28579 self.write(")");
28580 }
28581 }
28582 Ok(())
28583 }
28584
28585 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
28586 self.write_keyword("DATE_BIN");
28588 self.write("(");
28589 self.generate_expression(&e.this)?;
28590 self.write(", ");
28591 self.generate_expression(&e.expression)?;
28592 if let Some(origin) = &e.origin {
28593 self.write(", ");
28594 self.generate_expression(origin)?;
28595 }
28596 self.write(")");
28597 Ok(())
28598 }
28599
28600 fn generate_date_format_column_constraint(
28601 &mut self,
28602 e: &DateFormatColumnConstraint,
28603 ) -> Result<()> {
28604 self.write_keyword("FORMAT");
28606 self.write_space();
28607 self.generate_expression(&e.this)?;
28608 Ok(())
28609 }
28610
28611 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
28612 self.write_keyword("DATE_FROM_PARTS");
28614 self.write("(");
28615 let mut first = true;
28616 if let Some(year) = &e.year {
28617 self.generate_expression(year)?;
28618 first = false;
28619 }
28620 if let Some(month) = &e.month {
28621 if !first {
28622 self.write(", ");
28623 }
28624 self.generate_expression(month)?;
28625 first = false;
28626 }
28627 if let Some(day) = &e.day {
28628 if !first {
28629 self.write(", ");
28630 }
28631 self.generate_expression(day)?;
28632 }
28633 self.write(")");
28634 Ok(())
28635 }
28636
28637 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
28638 self.write_keyword("DATETIME");
28640 self.write("(");
28641 self.generate_expression(&e.this)?;
28642 if let Some(expr) = &e.expression {
28643 self.write(", ");
28644 self.generate_expression(expr)?;
28645 }
28646 self.write(")");
28647 Ok(())
28648 }
28649
28650 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
28651 self.write_keyword("DATETIME_ADD");
28653 self.write("(");
28654 self.generate_expression(&e.this)?;
28655 self.write(", ");
28656 self.generate_expression(&e.expression)?;
28657 if let Some(unit) = &e.unit {
28658 self.write(", ");
28659 self.write_keyword(unit);
28660 }
28661 self.write(")");
28662 Ok(())
28663 }
28664
28665 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
28666 self.write_keyword("DATETIME_DIFF");
28668 self.write("(");
28669 self.generate_expression(&e.this)?;
28670 self.write(", ");
28671 self.generate_expression(&e.expression)?;
28672 if let Some(unit) = &e.unit {
28673 self.write(", ");
28674 self.write_keyword(unit);
28675 }
28676 self.write(")");
28677 Ok(())
28678 }
28679
28680 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
28681 self.write_keyword("DATETIME_SUB");
28683 self.write("(");
28684 self.generate_expression(&e.this)?;
28685 self.write(", ");
28686 self.generate_expression(&e.expression)?;
28687 if let Some(unit) = &e.unit {
28688 self.write(", ");
28689 self.write_keyword(unit);
28690 }
28691 self.write(")");
28692 Ok(())
28693 }
28694
28695 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
28696 self.write_keyword("DATETIME_TRUNC");
28698 self.write("(");
28699 self.generate_expression(&e.this)?;
28700 self.write(", ");
28701 self.write_keyword(&e.unit);
28702 if let Some(zone) = &e.zone {
28703 self.write(", ");
28704 self.generate_expression(zone)?;
28705 }
28706 self.write(")");
28707 Ok(())
28708 }
28709
28710 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
28711 self.write_keyword("DAYNAME");
28713 self.write("(");
28714 self.generate_expression(&e.this)?;
28715 self.write(")");
28716 Ok(())
28717 }
28718
28719 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
28720 self.write_keyword("DECLARE");
28722 self.write_space();
28723 if e.replace {
28724 self.write_keyword("OR");
28725 self.write_space();
28726 self.write_keyword("REPLACE");
28727 self.write_space();
28728 }
28729 for (i, expr) in e.expressions.iter().enumerate() {
28730 if i > 0 {
28731 self.write(", ");
28732 }
28733 self.generate_expression(expr)?;
28734 }
28735 Ok(())
28736 }
28737
28738 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
28739 use crate::dialects::DialectType;
28740
28741 self.generate_expression(&e.this)?;
28743 for name in &e.additional_names {
28745 self.write(", ");
28746 self.generate_expression(name)?;
28747 }
28748 if let Some(kind) = &e.kind {
28749 self.write_space();
28750 match self.config.dialect {
28754 Some(DialectType::BigQuery) => {
28755 self.write(kind);
28756 }
28757 Some(DialectType::TSQL) => {
28758 let is_complex_table = kind.starts_with("TABLE")
28762 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
28763 if is_complex_table {
28764 self.write(kind);
28765 } else if kind == "INT" {
28766 self.write("INTEGER");
28767 } else if kind.starts_with("TABLE") {
28768 let normalized = kind
28770 .replace(" INT ", " INTEGER ")
28771 .replace(" INT,", " INTEGER,")
28772 .replace(" INT)", " INTEGER)")
28773 .replace("(INT ", "(INTEGER ");
28774 self.write(&normalized);
28775 } else {
28776 self.write(kind);
28777 }
28778 }
28779 _ => {
28780 if e.has_as {
28781 self.write_keyword("AS");
28782 self.write_space();
28783 }
28784 self.write(kind);
28785 }
28786 }
28787 }
28788 if let Some(default) = &e.default {
28789 match self.config.dialect {
28791 Some(DialectType::BigQuery) => {
28792 self.write_space();
28793 self.write_keyword("DEFAULT");
28794 self.write_space();
28795 }
28796 _ => {
28797 self.write(" = ");
28798 }
28799 }
28800 self.generate_expression(default)?;
28801 }
28802 Ok(())
28803 }
28804
28805 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
28806 self.write_keyword("DECODE");
28808 self.write("(");
28809 for (i, expr) in e.expressions.iter().enumerate() {
28810 if i > 0 {
28811 self.write(", ");
28812 }
28813 self.generate_expression(expr)?;
28814 }
28815 self.write(")");
28816 Ok(())
28817 }
28818
28819 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> 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_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
28831 self.write_keyword("DECOMPRESS");
28833 self.write("(");
28834 self.generate_expression(&e.this)?;
28835 self.write(", '");
28836 self.write(&e.method);
28837 self.write("')");
28838 Ok(())
28839 }
28840
28841 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
28842 self.write_keyword("DECRYPT");
28844 self.write("(");
28845 self.generate_expression(&e.this)?;
28846 if let Some(passphrase) = &e.passphrase {
28847 self.write(", ");
28848 self.generate_expression(passphrase)?;
28849 }
28850 if let Some(aad) = &e.aad {
28851 self.write(", ");
28852 self.generate_expression(aad)?;
28853 }
28854 if let Some(method) = &e.encryption_method {
28855 self.write(", ");
28856 self.generate_expression(method)?;
28857 }
28858 self.write(")");
28859 Ok(())
28860 }
28861
28862 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
28863 self.write_keyword("DECRYPT_RAW");
28865 self.write("(");
28866 self.generate_expression(&e.this)?;
28867 if let Some(key) = &e.key {
28868 self.write(", ");
28869 self.generate_expression(key)?;
28870 }
28871 if let Some(iv) = &e.iv {
28872 self.write(", ");
28873 self.generate_expression(iv)?;
28874 }
28875 if let Some(aad) = &e.aad {
28876 self.write(", ");
28877 self.generate_expression(aad)?;
28878 }
28879 if let Some(method) = &e.encryption_method {
28880 self.write(", ");
28881 self.generate_expression(method)?;
28882 }
28883 self.write(")");
28884 Ok(())
28885 }
28886
28887 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
28888 self.write_keyword("DEFINER");
28890 self.write(" = ");
28891 self.generate_expression(&e.this)?;
28892 Ok(())
28893 }
28894
28895 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
28896 self.write_keyword("DETACH");
28898 if e.exists {
28899 self.write_keyword(" DATABASE IF EXISTS");
28900 }
28901 self.write_space();
28902 self.generate_expression(&e.this)?;
28903 Ok(())
28904 }
28905
28906 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
28907 let property_name = match e.this.as_ref() {
28908 Expression::Identifier(id) => id.name.as_str(),
28909 Expression::Var(v) => v.this.as_str(),
28910 _ => "DICTIONARY",
28911 };
28912 self.write_keyword(property_name);
28913 self.write("(");
28914 self.write(&e.kind);
28915 if let Some(settings) = &e.settings {
28916 self.write("(");
28917 if let Expression::Tuple(t) = settings.as_ref() {
28918 if self.config.pretty && !t.expressions.is_empty() {
28919 self.write_newline();
28920 self.indent_level += 1;
28921 for (i, pair) in t.expressions.iter().enumerate() {
28922 if i > 0 {
28923 self.write(",");
28924 self.write_newline();
28925 }
28926 self.write_indent();
28927 if let Expression::Tuple(pair_tuple) = pair {
28928 if let Some(k) = pair_tuple.expressions.first() {
28929 self.generate_expression(k)?;
28930 }
28931 if let Some(v) = pair_tuple.expressions.get(1) {
28932 self.write(" ");
28933 self.generate_expression(v)?;
28934 }
28935 } else {
28936 self.generate_expression(pair)?;
28937 }
28938 }
28939 self.indent_level -= 1;
28940 self.write_newline();
28941 self.write_indent();
28942 } else {
28943 for (i, pair) in t.expressions.iter().enumerate() {
28944 if i > 0 {
28945 self.write(" ");
28947 }
28948 if let Expression::Tuple(pair_tuple) = pair {
28949 if let Some(k) = pair_tuple.expressions.first() {
28950 self.generate_expression(k)?;
28951 }
28952 if let Some(v) = pair_tuple.expressions.get(1) {
28953 self.write(" ");
28954 self.generate_expression(v)?;
28955 }
28956 } else {
28957 self.generate_expression(pair)?;
28958 }
28959 }
28960 }
28961 } else {
28962 self.generate_expression(settings)?;
28963 }
28964 self.write(")");
28965 } else {
28966 self.write("()");
28968 }
28969 self.write(")");
28970 Ok(())
28971 }
28972
28973 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
28974 let property_name = match e.this.as_ref() {
28975 Expression::Identifier(id) => id.name.as_str(),
28976 Expression::Var(v) => v.this.as_str(),
28977 _ => "RANGE",
28978 };
28979 self.write_keyword(property_name);
28980 self.write("(");
28981 if let Some(min) = &e.min {
28982 self.write_keyword("MIN");
28983 self.write_space();
28984 self.generate_expression(min)?;
28985 }
28986 if let Some(max) = &e.max {
28987 self.write_space();
28988 self.write_keyword("MAX");
28989 self.write_space();
28990 self.generate_expression(max)?;
28991 }
28992 self.write(")");
28993 Ok(())
28994 }
28995
28996 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
28997 if e.local.is_some() {
28999 self.write_keyword("LOCAL ");
29000 }
29001 self.write_keyword("DIRECTORY");
29002 self.write_space();
29003 self.generate_expression(&e.this)?;
29004 if let Some(row_format) = &e.row_format {
29005 self.write_space();
29006 self.generate_expression(row_format)?;
29007 }
29008 Ok(())
29009 }
29010
29011 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
29012 self.write_keyword("DISTKEY");
29014 self.write("(");
29015 self.generate_expression(&e.this)?;
29016 self.write(")");
29017 Ok(())
29018 }
29019
29020 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
29021 self.write_keyword("DISTSTYLE");
29023 self.write_space();
29024 self.generate_expression(&e.this)?;
29025 Ok(())
29026 }
29027
29028 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
29029 self.write_keyword("DISTRIBUTE BY");
29031 self.write_space();
29032 for (i, expr) in e.expressions.iter().enumerate() {
29033 if i > 0 {
29034 self.write(", ");
29035 }
29036 self.generate_expression(expr)?;
29037 }
29038 Ok(())
29039 }
29040
29041 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
29042 self.write_keyword("DISTRIBUTED BY");
29044 self.write_space();
29045 self.write(&e.kind);
29046 if !e.expressions.is_empty() {
29047 self.write(" (");
29048 for (i, expr) in e.expressions.iter().enumerate() {
29049 if i > 0 {
29050 self.write(", ");
29051 }
29052 self.generate_expression(expr)?;
29053 }
29054 self.write(")");
29055 }
29056 if let Some(buckets) = &e.buckets {
29057 self.write_space();
29058 self.write_keyword("BUCKETS");
29059 self.write_space();
29060 self.generate_expression(buckets)?;
29061 }
29062 if let Some(order) = &e.order {
29063 self.write_space();
29064 self.generate_expression(order)?;
29065 }
29066 Ok(())
29067 }
29068
29069 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
29070 self.write_keyword("DOT_PRODUCT");
29072 self.write("(");
29073 self.generate_expression(&e.this)?;
29074 self.write(", ");
29075 self.generate_expression(&e.expression)?;
29076 self.write(")");
29077 Ok(())
29078 }
29079
29080 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
29081 self.write_keyword("DROP");
29083 if e.exists {
29084 self.write_keyword(" IF EXISTS ");
29085 } else {
29086 self.write_space();
29087 }
29088 for (i, expr) in e.expressions.iter().enumerate() {
29089 if i > 0 {
29090 self.write(", ");
29091 }
29092 self.generate_expression(expr)?;
29093 }
29094 Ok(())
29095 }
29096
29097 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
29098 self.write_keyword("DUPLICATE KEY");
29100 self.write(" (");
29101 for (i, expr) in e.expressions.iter().enumerate() {
29102 if i > 0 {
29103 self.write(", ");
29104 }
29105 self.generate_expression(expr)?;
29106 }
29107 self.write(")");
29108 Ok(())
29109 }
29110
29111 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
29112 self.write_keyword("ELT");
29114 self.write("(");
29115 self.generate_expression(&e.this)?;
29116 for expr in &e.expressions {
29117 self.write(", ");
29118 self.generate_expression(expr)?;
29119 }
29120 self.write(")");
29121 Ok(())
29122 }
29123
29124 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
29125 self.write_keyword("ENCODE");
29127 self.write("(");
29128 self.generate_expression(&e.this)?;
29129 if let Some(charset) = &e.charset {
29130 self.write(", ");
29131 self.generate_expression(charset)?;
29132 }
29133 self.write(")");
29134 Ok(())
29135 }
29136
29137 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
29138 if e.key.is_some() {
29140 self.write_keyword("KEY ");
29141 }
29142 self.write_keyword("ENCODE");
29143 self.write_space();
29144 self.generate_expression(&e.this)?;
29145 if !e.properties.is_empty() {
29146 self.write(" (");
29147 for (i, prop) in e.properties.iter().enumerate() {
29148 if i > 0 {
29149 self.write(", ");
29150 }
29151 self.generate_expression(prop)?;
29152 }
29153 self.write(")");
29154 }
29155 Ok(())
29156 }
29157
29158 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
29159 self.write_keyword("ENCRYPT");
29161 self.write("(");
29162 self.generate_expression(&e.this)?;
29163 if let Some(passphrase) = &e.passphrase {
29164 self.write(", ");
29165 self.generate_expression(passphrase)?;
29166 }
29167 if let Some(aad) = &e.aad {
29168 self.write(", ");
29169 self.generate_expression(aad)?;
29170 }
29171 if let Some(method) = &e.encryption_method {
29172 self.write(", ");
29173 self.generate_expression(method)?;
29174 }
29175 self.write(")");
29176 Ok(())
29177 }
29178
29179 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
29180 self.write_keyword("ENCRYPT_RAW");
29182 self.write("(");
29183 self.generate_expression(&e.this)?;
29184 if let Some(key) = &e.key {
29185 self.write(", ");
29186 self.generate_expression(key)?;
29187 }
29188 if let Some(iv) = &e.iv {
29189 self.write(", ");
29190 self.generate_expression(iv)?;
29191 }
29192 if let Some(aad) = &e.aad {
29193 self.write(", ");
29194 self.generate_expression(aad)?;
29195 }
29196 if let Some(method) = &e.encryption_method {
29197 self.write(", ");
29198 self.generate_expression(method)?;
29199 }
29200 self.write(")");
29201 Ok(())
29202 }
29203
29204 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
29205 self.write_keyword("ENGINE");
29207 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
29208 self.write("=");
29209 } else {
29210 self.write(" = ");
29211 }
29212 self.generate_expression(&e.this)?;
29213 Ok(())
29214 }
29215
29216 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
29217 self.write_keyword("ENVIRONMENT");
29219 self.write(" (");
29220 for (i, expr) in e.expressions.iter().enumerate() {
29221 if i > 0 {
29222 self.write(", ");
29223 }
29224 self.generate_expression(expr)?;
29225 }
29226 self.write(")");
29227 Ok(())
29228 }
29229
29230 fn generate_ephemeral_column_constraint(
29231 &mut self,
29232 e: &EphemeralColumnConstraint,
29233 ) -> Result<()> {
29234 self.write_keyword("EPHEMERAL");
29236 if let Some(this) = &e.this {
29237 self.write_space();
29238 self.generate_expression(this)?;
29239 }
29240 Ok(())
29241 }
29242
29243 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
29244 self.write_keyword("EQUAL_NULL");
29246 self.write("(");
29247 self.generate_expression(&e.this)?;
29248 self.write(", ");
29249 self.generate_expression(&e.expression)?;
29250 self.write(")");
29251 Ok(())
29252 }
29253
29254 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
29255 use crate::dialects::DialectType;
29256
29257 match self.config.dialect {
29259 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
29260 self.generate_expression(&e.this)?;
29261 self.write(" <-> ");
29262 self.generate_expression(&e.expression)?;
29263 }
29264 _ => {
29265 self.write_keyword("EUCLIDEAN_DISTANCE");
29267 self.write("(");
29268 self.generate_expression(&e.this)?;
29269 self.write(", ");
29270 self.generate_expression(&e.expression)?;
29271 self.write(")");
29272 }
29273 }
29274 Ok(())
29275 }
29276
29277 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
29278 self.write_keyword("EXECUTE AS");
29280 self.write_space();
29281 self.generate_expression(&e.this)?;
29282 Ok(())
29283 }
29284
29285 fn generate_export(&mut self, e: &Export) -> Result<()> {
29286 self.write_keyword("EXPORT DATA");
29288 if let Some(connection) = &e.connection {
29289 self.write_space();
29290 self.write_keyword("WITH CONNECTION");
29291 self.write_space();
29292 self.generate_expression(connection)?;
29293 }
29294 if !e.options.is_empty() {
29295 self.write_space();
29296 self.generate_options_clause(&e.options)?;
29297 }
29298 self.write_space();
29299 self.write_keyword("AS");
29300 self.write_space();
29301 self.generate_expression(&e.this)?;
29302 Ok(())
29303 }
29304
29305 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
29306 self.write_keyword("EXTERNAL");
29308 if let Some(this) = &e.this {
29309 self.write_space();
29310 self.generate_expression(this)?;
29311 }
29312 Ok(())
29313 }
29314
29315 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
29316 if e.no.is_some() {
29318 self.write_keyword("NO ");
29319 }
29320 self.write_keyword("FALLBACK");
29321 if e.protection.is_some() {
29322 self.write_keyword(" PROTECTION");
29323 }
29324 Ok(())
29325 }
29326
29327 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
29328 self.write_keyword("FARM_FINGERPRINT");
29330 self.write("(");
29331 for (i, expr) in e.expressions.iter().enumerate() {
29332 if i > 0 {
29333 self.write(", ");
29334 }
29335 self.generate_expression(expr)?;
29336 }
29337 self.write(")");
29338 Ok(())
29339 }
29340
29341 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
29342 self.write_keyword("FEATURES_AT_TIME");
29344 self.write("(");
29345 self.generate_expression(&e.this)?;
29346 if let Some(time) = &e.time {
29347 self.write(", ");
29348 self.generate_expression(time)?;
29349 }
29350 if let Some(num_rows) = &e.num_rows {
29351 self.write(", ");
29352 self.generate_expression(num_rows)?;
29353 }
29354 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
29355 self.write(", ");
29356 self.generate_expression(ignore_nulls)?;
29357 }
29358 self.write(")");
29359 Ok(())
29360 }
29361
29362 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
29363 let use_limit = !e.percent
29365 && !e.with_ties
29366 && e.count.is_some()
29367 && matches!(
29368 self.config.dialect,
29369 Some(DialectType::Spark)
29370 | Some(DialectType::Hive)
29371 | Some(DialectType::DuckDB)
29372 | Some(DialectType::SQLite)
29373 | Some(DialectType::MySQL)
29374 | Some(DialectType::BigQuery)
29375 | Some(DialectType::Databricks)
29376 | Some(DialectType::StarRocks)
29377 | Some(DialectType::Doris)
29378 | Some(DialectType::Athena)
29379 | Some(DialectType::ClickHouse)
29380 );
29381
29382 if use_limit {
29383 self.write_keyword("LIMIT");
29384 self.write_space();
29385 self.generate_expression(e.count.as_ref().unwrap())?;
29386 return Ok(());
29387 }
29388
29389 self.write_keyword("FETCH");
29391 if !e.direction.is_empty() {
29392 self.write_space();
29393 self.write_keyword(&e.direction);
29394 }
29395 if let Some(count) = &e.count {
29396 self.write_space();
29397 self.generate_expression(count)?;
29398 }
29399 if e.percent {
29401 self.write_keyword(" PERCENT");
29402 }
29403 if e.rows {
29404 self.write_keyword(" ROWS");
29405 }
29406 if e.with_ties {
29407 self.write_keyword(" WITH TIES");
29408 } else if e.rows {
29409 self.write_keyword(" ONLY");
29410 } else {
29411 self.write_keyword(" ROWS ONLY");
29412 }
29413 Ok(())
29414 }
29415
29416 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
29417 if e.hive_format.is_some() {
29421 self.write_keyword("STORED AS");
29423 self.write_space();
29424 if let Some(this) = &e.this {
29425 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!(self.config.dialect, Some(DialectType::Hive)) {
29433 self.write_keyword("STORED AS");
29435 self.write_space();
29436 if let Some(this) = &e.this {
29437 if let Expression::Identifier(id) = this.as_ref() {
29438 self.write_keyword(&id.name.to_ascii_uppercase());
29439 } else {
29440 self.generate_expression(this)?;
29441 }
29442 }
29443 } else if matches!(
29444 self.config.dialect,
29445 Some(DialectType::Spark) | Some(DialectType::Databricks)
29446 ) {
29447 self.write_keyword("USING");
29449 self.write_space();
29450 if let Some(this) = &e.this {
29451 self.generate_expression(this)?;
29452 }
29453 } else {
29454 self.write_keyword("FILE_FORMAT");
29456 self.write(" = ");
29457 if let Some(this) = &e.this {
29458 self.generate_expression(this)?;
29459 } else if !e.expressions.is_empty() {
29460 self.write("(");
29461 for (i, expr) in e.expressions.iter().enumerate() {
29462 if i > 0 {
29463 self.write(", ");
29464 }
29465 self.generate_expression(expr)?;
29466 }
29467 self.write(")");
29468 }
29469 }
29470 Ok(())
29471 }
29472
29473 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
29474 self.generate_expression(&e.this)?;
29476 self.write_space();
29477 self.write_keyword("FILTER");
29478 self.write("(");
29479 self.write_keyword("WHERE");
29480 self.write_space();
29481 self.generate_expression(&e.expression)?;
29482 self.write(")");
29483 Ok(())
29484 }
29485
29486 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
29487 self.write_keyword("FLOAT64");
29489 self.write("(");
29490 self.generate_expression(&e.this)?;
29491 if let Some(expr) = &e.expression {
29492 self.write(", ");
29493 self.generate_expression(expr)?;
29494 }
29495 self.write(")");
29496 Ok(())
29497 }
29498
29499 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
29500 self.write_keyword("FOR");
29502 self.write_space();
29503 self.generate_expression(&e.this)?;
29504 self.write_space();
29505 self.write_keyword("DO");
29506 self.write_space();
29507 self.generate_expression(&e.expression)?;
29508 Ok(())
29509 }
29510
29511 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
29512 self.write_keyword("FOREIGN KEY");
29514 if !e.expressions.is_empty() {
29515 self.write(" (");
29516 for (i, expr) in e.expressions.iter().enumerate() {
29517 if i > 0 {
29518 self.write(", ");
29519 }
29520 self.generate_expression(expr)?;
29521 }
29522 self.write(")");
29523 }
29524 if let Some(reference) = &e.reference {
29525 self.write_space();
29526 self.generate_expression(reference)?;
29527 }
29528 if let Some(delete) = &e.delete {
29529 self.write_space();
29530 self.write_keyword("ON DELETE");
29531 self.write_space();
29532 self.generate_expression(delete)?;
29533 }
29534 if let Some(update) = &e.update {
29535 self.write_space();
29536 self.write_keyword("ON UPDATE");
29537 self.write_space();
29538 self.generate_expression(update)?;
29539 }
29540 if !e.options.is_empty() {
29541 self.write_space();
29542 for (i, opt) in e.options.iter().enumerate() {
29543 if i > 0 {
29544 self.write_space();
29545 }
29546 self.generate_expression(opt)?;
29547 }
29548 }
29549 Ok(())
29550 }
29551
29552 fn generate_format(&mut self, e: &Format) -> Result<()> {
29553 self.write_keyword("FORMAT");
29555 self.write("(");
29556 self.generate_expression(&e.this)?;
29557 for expr in &e.expressions {
29558 self.write(", ");
29559 self.generate_expression(expr)?;
29560 }
29561 self.write(")");
29562 Ok(())
29563 }
29564
29565 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
29566 self.generate_expression(&e.this)?;
29568 self.write(" (");
29569 self.write_keyword("FORMAT");
29570 self.write(" '");
29571 self.write(&e.format);
29572 self.write("')");
29573 Ok(())
29574 }
29575
29576 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
29577 self.write_keyword("FREESPACE");
29579 self.write("=");
29580 self.generate_expression(&e.this)?;
29581 if e.percent.is_some() {
29582 self.write_keyword(" PERCENT");
29583 }
29584 Ok(())
29585 }
29586
29587 fn generate_from(&mut self, e: &From) -> Result<()> {
29588 self.write_keyword("FROM");
29590 self.write_space();
29591
29592 use crate::dialects::DialectType;
29596 let has_tablesample = e
29597 .expressions
29598 .iter()
29599 .any(|expr| matches!(expr, Expression::TableSample(_)));
29600 let is_cross_join_dialect = matches!(
29601 self.config.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 source_is_same_as_target2 = self.config.source_dialect.is_some()
29610 && self.config.source_dialect == self.config.dialect;
29611 let source_is_cross_join_dialect2 = matches!(
29612 self.config.source_dialect,
29613 Some(DialectType::BigQuery)
29614 | Some(DialectType::Hive)
29615 | Some(DialectType::Spark)
29616 | Some(DialectType::Databricks)
29617 | Some(DialectType::SQLite)
29618 | Some(DialectType::ClickHouse)
29619 );
29620 let use_cross_join = !has_tablesample
29621 && is_cross_join_dialect
29622 && (source_is_same_as_target2
29623 || source_is_cross_join_dialect2
29624 || self.config.source_dialect.is_none());
29625
29626 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
29628
29629 for (i, expr) in e.expressions.iter().enumerate() {
29630 if i > 0 {
29631 if use_cross_join {
29632 self.write(" CROSS JOIN ");
29633 } else {
29634 self.write(", ");
29635 }
29636 }
29637 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
29638 self.write("(");
29639 self.generate_expression(expr)?;
29640 self.write(")");
29641 } else {
29642 self.generate_expression(expr)?;
29643 }
29644 let leading = Self::extract_table_leading_comments(expr);
29647 for comment in &leading {
29648 self.write_space();
29649 self.write_formatted_comment(comment);
29650 }
29651 }
29652 Ok(())
29653 }
29654
29655 fn extract_table_leading_comments(expr: &Expression) -> Vec<String> {
29657 match expr {
29658 Expression::Table(t) => t.leading_comments.clone(),
29659 Expression::Pivot(p) => {
29660 if let Expression::Table(t) = &p.this {
29661 t.leading_comments.clone()
29662 } else {
29663 Vec::new()
29664 }
29665 }
29666 _ => Vec::new(),
29667 }
29668 }
29669
29670 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
29671 self.write_keyword("FROM_BASE");
29673 self.write("(");
29674 self.generate_expression(&e.this)?;
29675 self.write(", ");
29676 self.generate_expression(&e.expression)?;
29677 self.write(")");
29678 Ok(())
29679 }
29680
29681 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
29682 self.generate_expression(&e.this)?;
29684 if let Some(zone) = &e.zone {
29685 self.write_space();
29686 self.write_keyword("AT TIME ZONE");
29687 self.write_space();
29688 self.generate_expression(zone)?;
29689 self.write_space();
29690 self.write_keyword("AT TIME ZONE");
29691 self.write(" 'UTC'");
29692 }
29693 Ok(())
29694 }
29695
29696 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
29697 self.write_keyword("GAP_FILL");
29699 self.write("(");
29700 self.generate_expression(&e.this)?;
29701 if let Some(ts_column) = &e.ts_column {
29702 self.write(", ");
29703 self.generate_expression(ts_column)?;
29704 }
29705 if let Some(bucket_width) = &e.bucket_width {
29706 self.write(", ");
29707 self.generate_expression(bucket_width)?;
29708 }
29709 if let Some(partitioning_columns) = &e.partitioning_columns {
29710 self.write(", ");
29711 self.generate_expression(partitioning_columns)?;
29712 }
29713 if let Some(value_columns) = &e.value_columns {
29714 self.write(", ");
29715 self.generate_expression(value_columns)?;
29716 }
29717 self.write(")");
29718 Ok(())
29719 }
29720
29721 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
29722 self.write_keyword("GENERATE_DATE_ARRAY");
29724 self.write("(");
29725 let mut first = true;
29726 if let Some(start) = &e.start {
29727 self.generate_expression(start)?;
29728 first = false;
29729 }
29730 if let Some(end) = &e.end {
29731 if !first {
29732 self.write(", ");
29733 }
29734 self.generate_expression(end)?;
29735 first = false;
29736 }
29737 if let Some(step) = &e.step {
29738 if !first {
29739 self.write(", ");
29740 }
29741 self.generate_expression(step)?;
29742 }
29743 self.write(")");
29744 Ok(())
29745 }
29746
29747 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
29748 self.write_keyword("ML.GENERATE_EMBEDDING");
29750 self.write("(");
29751 self.generate_expression(&e.this)?;
29752 self.write(", ");
29753 self.generate_expression(&e.expression)?;
29754 if let Some(params) = &e.params_struct {
29755 self.write(", ");
29756 self.generate_expression(params)?;
29757 }
29758 self.write(")");
29759 Ok(())
29760 }
29761
29762 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
29763 let fn_name = match self.config.dialect {
29765 Some(DialectType::Presto)
29766 | Some(DialectType::Trino)
29767 | Some(DialectType::Athena)
29768 | Some(DialectType::Spark)
29769 | Some(DialectType::Databricks)
29770 | Some(DialectType::Hive) => "SEQUENCE",
29771 _ => "GENERATE_SERIES",
29772 };
29773 self.write_keyword(fn_name);
29774 self.write("(");
29775 let mut first = true;
29776 if let Some(start) = &e.start {
29777 self.generate_expression(start)?;
29778 first = false;
29779 }
29780 if let Some(end) = &e.end {
29781 if !first {
29782 self.write(", ");
29783 }
29784 self.generate_expression(end)?;
29785 first = false;
29786 }
29787 if let Some(step) = &e.step {
29788 if !first {
29789 self.write(", ");
29790 }
29791 if matches!(
29794 self.config.dialect,
29795 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
29796 ) {
29797 if let Some(converted) = self.convert_week_interval_to_day(step) {
29798 self.generate_expression(&converted)?;
29799 } else {
29800 self.generate_expression(step)?;
29801 }
29802 } else {
29803 self.generate_expression(step)?;
29804 }
29805 }
29806 self.write(")");
29807 Ok(())
29808 }
29809
29810 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
29813 use crate::expressions::*;
29814 if let Expression::Interval(ref iv) = expr {
29815 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
29817 unit: IntervalUnit::Week,
29818 ..
29819 }) = &iv.unit
29820 {
29821 let count = match &iv.this {
29823 Some(Expression::Literal(lit)) => match lit.as_ref() {
29824 Literal::String(s) | Literal::Number(s) => s.clone(),
29825 _ => return None,
29826 },
29827 _ => return None,
29828 };
29829 (true, count)
29830 } else if iv.unit.is_none() {
29831 if let Some(Expression::Literal(lit)) = &iv.this {
29833 if let Literal::String(s) = lit.as_ref() {
29834 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
29835 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
29836 (true, parts[0].to_string())
29837 } else {
29838 (false, String::new())
29839 }
29840 } else {
29841 (false, String::new())
29842 }
29843 } else {
29844 (false, String::new())
29845 }
29846 } else {
29847 (false, String::new())
29848 };
29849
29850 if is_week {
29851 let count_expr = Expression::Literal(Box::new(Literal::Number(count_str)));
29853 let day_interval = Expression::Interval(Box::new(Interval {
29854 this: Some(Expression::Literal(Box::new(Literal::String(
29855 "7".to_string(),
29856 )))),
29857 unit: Some(IntervalUnitSpec::Simple {
29858 unit: IntervalUnit::Day,
29859 use_plural: false,
29860 }),
29861 }));
29862 let mul = Expression::Mul(Box::new(BinaryOp {
29863 left: count_expr,
29864 right: day_interval,
29865 left_comments: vec![],
29866 operator_comments: vec![],
29867 trailing_comments: vec![],
29868 inferred_type: None,
29869 }));
29870 return Some(Expression::Paren(Box::new(Paren {
29871 this: mul,
29872 trailing_comments: vec![],
29873 })));
29874 }
29875 }
29876 None
29877 }
29878
29879 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
29880 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
29882 self.write("(");
29883 let mut first = true;
29884 if let Some(start) = &e.start {
29885 self.generate_expression(start)?;
29886 first = false;
29887 }
29888 if let Some(end) = &e.end {
29889 if !first {
29890 self.write(", ");
29891 }
29892 self.generate_expression(end)?;
29893 first = false;
29894 }
29895 if let Some(step) = &e.step {
29896 if !first {
29897 self.write(", ");
29898 }
29899 self.generate_expression(step)?;
29900 }
29901 self.write(")");
29902 Ok(())
29903 }
29904
29905 fn generate_generated_as_identity_column_constraint(
29906 &mut self,
29907 e: &GeneratedAsIdentityColumnConstraint,
29908 ) -> Result<()> {
29909 use crate::dialects::DialectType;
29910
29911 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
29913 self.write_keyword("AUTOINCREMENT");
29914 if let Some(start) = &e.start {
29915 self.write_keyword(" START ");
29916 self.generate_expression(start)?;
29917 }
29918 if let Some(increment) = &e.increment {
29919 self.write_keyword(" INCREMENT ");
29920 self.generate_expression(increment)?;
29921 }
29922 return Ok(());
29923 }
29924
29925 self.write_keyword("GENERATED");
29927 if let Some(this) = &e.this {
29928 if let Expression::Boolean(b) = this.as_ref() {
29930 if b.value {
29931 self.write_keyword(" ALWAYS");
29932 } else {
29933 self.write_keyword(" BY DEFAULT");
29934 if e.on_null.is_some() {
29935 self.write_keyword(" ON NULL");
29936 }
29937 }
29938 } else {
29939 self.write_keyword(" ALWAYS");
29940 }
29941 }
29942 self.write_keyword(" AS IDENTITY");
29943 let has_options = e.start.is_some()
29945 || e.increment.is_some()
29946 || e.minvalue.is_some()
29947 || e.maxvalue.is_some();
29948 if has_options {
29949 self.write(" (");
29950 let mut first = true;
29951 if let Some(start) = &e.start {
29952 self.write_keyword("START WITH ");
29953 self.generate_expression(start)?;
29954 first = false;
29955 }
29956 if let Some(increment) = &e.increment {
29957 if !first {
29958 self.write(" ");
29959 }
29960 self.write_keyword("INCREMENT BY ");
29961 self.generate_expression(increment)?;
29962 first = false;
29963 }
29964 if let Some(minvalue) = &e.minvalue {
29965 if !first {
29966 self.write(" ");
29967 }
29968 self.write_keyword("MINVALUE ");
29969 self.generate_expression(minvalue)?;
29970 first = false;
29971 }
29972 if let Some(maxvalue) = &e.maxvalue {
29973 if !first {
29974 self.write(" ");
29975 }
29976 self.write_keyword("MAXVALUE ");
29977 self.generate_expression(maxvalue)?;
29978 }
29979 self.write(")");
29980 }
29981 Ok(())
29982 }
29983
29984 fn generate_generated_as_row_column_constraint(
29985 &mut self,
29986 e: &GeneratedAsRowColumnConstraint,
29987 ) -> Result<()> {
29988 self.write_keyword("GENERATED ALWAYS AS ROW ");
29990 if e.start.is_some() {
29991 self.write_keyword("START");
29992 } else {
29993 self.write_keyword("END");
29994 }
29995 if e.hidden.is_some() {
29996 self.write_keyword(" HIDDEN");
29997 }
29998 Ok(())
29999 }
30000
30001 fn generate_get(&mut self, e: &Get) -> Result<()> {
30002 self.write_keyword("GET");
30004 self.write_space();
30005 self.generate_expression(&e.this)?;
30006 if let Some(target) = &e.target {
30007 self.write_space();
30008 self.generate_expression(target)?;
30009 }
30010 for prop in &e.properties {
30011 self.write_space();
30012 self.generate_expression(prop)?;
30013 }
30014 Ok(())
30015 }
30016
30017 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
30018 self.generate_expression(&e.this)?;
30020 self.write("[");
30021 self.generate_expression(&e.expression)?;
30022 self.write("]");
30023 Ok(())
30024 }
30025
30026 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
30027 self.write_keyword("GETBIT");
30029 self.write("(");
30030 self.generate_expression(&e.this)?;
30031 self.write(", ");
30032 self.generate_expression(&e.expression)?;
30033 self.write(")");
30034 Ok(())
30035 }
30036
30037 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
30038 if e.is_role {
30040 self.write_keyword("ROLE");
30041 self.write_space();
30042 } else if e.is_group {
30043 self.write_keyword("GROUP");
30044 self.write_space();
30045 } else if e.is_share {
30046 self.write_keyword("SHARE");
30047 self.write_space();
30048 }
30049 self.write(&e.name.name);
30050 Ok(())
30051 }
30052
30053 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
30054 self.generate_expression(&e.this)?;
30056 if !e.expressions.is_empty() {
30057 self.write("(");
30058 for (i, expr) in e.expressions.iter().enumerate() {
30059 if i > 0 {
30060 self.write(", ");
30061 }
30062 self.generate_expression(expr)?;
30063 }
30064 self.write(")");
30065 }
30066 Ok(())
30067 }
30068
30069 fn generate_group(&mut self, e: &Group) -> Result<()> {
30070 self.write_keyword("GROUP BY");
30072 match e.all {
30074 Some(true) => {
30075 self.write_space();
30076 self.write_keyword("ALL");
30077 }
30078 Some(false) => {
30079 self.write_space();
30080 self.write_keyword("DISTINCT");
30081 }
30082 None => {}
30083 }
30084 if !e.expressions.is_empty() {
30085 self.write_space();
30086 for (i, expr) in e.expressions.iter().enumerate() {
30087 if i > 0 {
30088 self.write(", ");
30089 }
30090 self.generate_expression(expr)?;
30091 }
30092 }
30093 if let Some(cube) = &e.cube {
30095 if !e.expressions.is_empty() {
30096 self.write(", ");
30097 } else {
30098 self.write_space();
30099 }
30100 self.generate_expression(cube)?;
30101 }
30102 if let Some(rollup) = &e.rollup {
30103 if !e.expressions.is_empty() || e.cube.is_some() {
30104 self.write(", ");
30105 } else {
30106 self.write_space();
30107 }
30108 self.generate_expression(rollup)?;
30109 }
30110 if let Some(grouping_sets) = &e.grouping_sets {
30111 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
30112 self.write(", ");
30113 } else {
30114 self.write_space();
30115 }
30116 self.generate_expression(grouping_sets)?;
30117 }
30118 if let Some(totals) = &e.totals {
30119 self.write_space();
30120 self.write_keyword("WITH TOTALS");
30121 self.generate_expression(totals)?;
30122 }
30123 Ok(())
30124 }
30125
30126 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
30127 self.write_keyword("GROUP BY");
30129 match e.all {
30131 Some(true) => {
30132 self.write_space();
30133 self.write_keyword("ALL");
30134 }
30135 Some(false) => {
30136 self.write_space();
30137 self.write_keyword("DISTINCT");
30138 }
30139 None => {}
30140 }
30141
30142 let mut trailing_cube = false;
30145 let mut trailing_rollup = false;
30146 let mut regular_expressions: Vec<&Expression> = Vec::new();
30147
30148 for expr in &e.expressions {
30149 match expr {
30150 Expression::Cube(c) if c.expressions.is_empty() => {
30151 trailing_cube = true;
30152 }
30153 Expression::Rollup(r) if r.expressions.is_empty() => {
30154 trailing_rollup = true;
30155 }
30156 _ => {
30157 regular_expressions.push(expr);
30158 }
30159 }
30160 }
30161
30162 if self.config.pretty {
30164 self.write_newline();
30165 self.indent_level += 1;
30166 for (i, expr) in regular_expressions.iter().enumerate() {
30167 if i > 0 {
30168 self.write(",");
30169 self.write_newline();
30170 }
30171 self.write_indent();
30172 self.generate_expression(expr)?;
30173 }
30174 self.indent_level -= 1;
30175 } else {
30176 self.write_space();
30177 for (i, expr) in regular_expressions.iter().enumerate() {
30178 if i > 0 {
30179 self.write(", ");
30180 }
30181 self.generate_expression(expr)?;
30182 }
30183 }
30184
30185 if trailing_cube {
30187 self.write_space();
30188 self.write_keyword("WITH CUBE");
30189 } else if trailing_rollup {
30190 self.write_space();
30191 self.write_keyword("WITH ROLLUP");
30192 }
30193
30194 if e.totals {
30196 self.write_space();
30197 self.write_keyword("WITH TOTALS");
30198 }
30199
30200 Ok(())
30201 }
30202
30203 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
30204 self.write_keyword("GROUPING");
30206 self.write("(");
30207 for (i, expr) in e.expressions.iter().enumerate() {
30208 if i > 0 {
30209 self.write(", ");
30210 }
30211 self.generate_expression(expr)?;
30212 }
30213 self.write(")");
30214 Ok(())
30215 }
30216
30217 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
30218 self.write_keyword("GROUPING_ID");
30220 self.write("(");
30221 for (i, expr) in e.expressions.iter().enumerate() {
30222 if i > 0 {
30223 self.write(", ");
30224 }
30225 self.generate_expression(expr)?;
30226 }
30227 self.write(")");
30228 Ok(())
30229 }
30230
30231 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
30232 self.write_keyword("GROUPING SETS");
30234 self.write(" (");
30235 for (i, expr) in e.expressions.iter().enumerate() {
30236 if i > 0 {
30237 self.write(", ");
30238 }
30239 self.generate_expression(expr)?;
30240 }
30241 self.write(")");
30242 Ok(())
30243 }
30244
30245 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
30246 self.write_keyword("HASH_AGG");
30248 self.write("(");
30249 self.generate_expression(&e.this)?;
30250 for expr in &e.expressions {
30251 self.write(", ");
30252 self.generate_expression(expr)?;
30253 }
30254 self.write(")");
30255 Ok(())
30256 }
30257
30258 fn generate_having(&mut self, e: &Having) -> Result<()> {
30259 self.write_keyword("HAVING");
30261 self.write_space();
30262 self.generate_expression(&e.this)?;
30263 Ok(())
30264 }
30265
30266 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
30267 self.generate_expression(&e.this)?;
30269 self.write_space();
30270 self.write_keyword("HAVING");
30271 self.write_space();
30272 if e.max.is_some() {
30273 self.write_keyword("MAX");
30274 } else {
30275 self.write_keyword("MIN");
30276 }
30277 self.write_space();
30278 self.generate_expression(&e.expression)?;
30279 Ok(())
30280 }
30281
30282 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
30283 use crate::dialects::DialectType;
30284 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
30286 if let Expression::Literal(ref lit) = *e.this {
30288 if let Literal::String(ref s) = lit.as_ref() {
30289 return self.generate_string_literal(s);
30290 }
30291 }
30292 }
30293 if matches!(
30295 self.config.dialect,
30296 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
30297 ) {
30298 self.write("$");
30299 if let Some(tag) = &e.tag {
30300 self.generate_expression(tag)?;
30301 }
30302 self.write("$");
30303 self.generate_expression(&e.this)?;
30304 self.write("$");
30305 if let Some(tag) = &e.tag {
30306 self.generate_expression(tag)?;
30307 }
30308 self.write("$");
30309 return Ok(());
30310 }
30311 self.write("$");
30313 if let Some(tag) = &e.tag {
30314 self.generate_expression(tag)?;
30315 }
30316 self.write("$");
30317 self.generate_expression(&e.this)?;
30318 self.write("$");
30319 if let Some(tag) = &e.tag {
30320 self.generate_expression(tag)?;
30321 }
30322 self.write("$");
30323 Ok(())
30324 }
30325
30326 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
30327 self.write_keyword("HEX_ENCODE");
30329 self.write("(");
30330 self.generate_expression(&e.this)?;
30331 self.write(")");
30332 Ok(())
30333 }
30334
30335 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
30336 match e.this.as_ref() {
30339 Expression::Identifier(id) => self.write(&id.name),
30340 other => self.generate_expression(other)?,
30341 }
30342 self.write(" (");
30343 self.write(&e.kind);
30344 self.write(" => ");
30345 self.generate_expression(&e.expression)?;
30346 self.write(")");
30347 Ok(())
30348 }
30349
30350 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
30351 self.write_keyword("HLL");
30353 self.write("(");
30354 self.generate_expression(&e.this)?;
30355 for expr in &e.expressions {
30356 self.write(", ");
30357 self.generate_expression(expr)?;
30358 }
30359 self.write(")");
30360 Ok(())
30361 }
30362
30363 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
30364 if e.input_.is_some() && e.output.is_some() {
30366 self.write_keyword("IN OUT");
30367 } else if e.input_.is_some() {
30368 self.write_keyword("IN");
30369 } else if e.output.is_some() {
30370 self.write_keyword("OUT");
30371 }
30372 Ok(())
30373 }
30374
30375 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
30376 self.write_keyword("INCLUDE");
30378 self.write_space();
30379 self.generate_expression(&e.this)?;
30380 if let Some(column_def) = &e.column_def {
30381 self.write_space();
30382 self.generate_expression(column_def)?;
30383 }
30384 if let Some(alias) = &e.alias {
30385 self.write_space();
30386 self.write_keyword("AS");
30387 self.write_space();
30388 self.write(alias);
30389 }
30390 Ok(())
30391 }
30392
30393 fn generate_index(&mut self, e: &Index) -> Result<()> {
30394 if e.unique {
30396 self.write_keyword("UNIQUE");
30397 self.write_space();
30398 }
30399 if e.primary.is_some() {
30400 self.write_keyword("PRIMARY");
30401 self.write_space();
30402 }
30403 if e.amp.is_some() {
30404 self.write_keyword("AMP");
30405 self.write_space();
30406 }
30407 if e.table.is_none() {
30408 self.write_keyword("INDEX");
30409 self.write_space();
30410 }
30411 if let Some(name) = &e.this {
30412 self.generate_expression(name)?;
30413 self.write_space();
30414 }
30415 if let Some(table) = &e.table {
30416 self.write_keyword("ON");
30417 self.write_space();
30418 self.generate_expression(table)?;
30419 }
30420 if !e.params.is_empty() {
30421 self.write("(");
30422 for (i, param) in e.params.iter().enumerate() {
30423 if i > 0 {
30424 self.write(", ");
30425 }
30426 self.generate_expression(param)?;
30427 }
30428 self.write(")");
30429 }
30430 Ok(())
30431 }
30432
30433 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
30434 if let Some(kind) = &e.kind {
30436 self.write(kind);
30437 self.write_space();
30438 }
30439 self.write_keyword("INDEX");
30440 if let Some(this) = &e.this {
30441 self.write_space();
30442 self.generate_expression(this)?;
30443 }
30444 if let Some(index_type) = &e.index_type {
30445 self.write_space();
30446 self.write_keyword("USING");
30447 self.write_space();
30448 self.generate_expression(index_type)?;
30449 }
30450 if !e.expressions.is_empty() {
30451 self.write(" (");
30452 for (i, expr) in e.expressions.iter().enumerate() {
30453 if i > 0 {
30454 self.write(", ");
30455 }
30456 self.generate_expression(expr)?;
30457 }
30458 self.write(")");
30459 }
30460 for opt in &e.options {
30461 self.write_space();
30462 self.generate_expression(opt)?;
30463 }
30464 Ok(())
30465 }
30466
30467 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
30468 if let Some(key_block_size) = &e.key_block_size {
30470 self.write_keyword("KEY_BLOCK_SIZE");
30471 self.write(" = ");
30472 self.generate_expression(key_block_size)?;
30473 } else if let Some(using) = &e.using {
30474 self.write_keyword("USING");
30475 self.write_space();
30476 self.generate_expression(using)?;
30477 } else if let Some(parser) = &e.parser {
30478 self.write_keyword("WITH PARSER");
30479 self.write_space();
30480 self.generate_expression(parser)?;
30481 } else if let Some(comment) = &e.comment {
30482 self.write_keyword("COMMENT");
30483 self.write_space();
30484 self.generate_expression(comment)?;
30485 } else if let Some(visible) = &e.visible {
30486 self.generate_expression(visible)?;
30487 } else if let Some(engine_attr) = &e.engine_attr {
30488 self.write_keyword("ENGINE_ATTRIBUTE");
30489 self.write(" = ");
30490 self.generate_expression(engine_attr)?;
30491 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
30492 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
30493 self.write(" = ");
30494 self.generate_expression(secondary_engine_attr)?;
30495 }
30496 Ok(())
30497 }
30498
30499 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
30500 if let Some(using) = &e.using {
30502 self.write_keyword("USING");
30503 self.write_space();
30504 self.generate_expression(using)?;
30505 }
30506 if !e.columns.is_empty() {
30507 self.write("(");
30508 for (i, col) in e.columns.iter().enumerate() {
30509 if i > 0 {
30510 self.write(", ");
30511 }
30512 self.generate_expression(col)?;
30513 }
30514 self.write(")");
30515 }
30516 if let Some(partition_by) = &e.partition_by {
30517 self.write_space();
30518 self.write_keyword("PARTITION BY");
30519 self.write_space();
30520 self.generate_expression(partition_by)?;
30521 }
30522 if let Some(where_) = &e.where_ {
30523 self.write_space();
30524 self.generate_expression(where_)?;
30525 }
30526 if let Some(include) = &e.include {
30527 self.write_space();
30528 self.write_keyword("INCLUDE");
30529 self.write(" (");
30530 self.generate_expression(include)?;
30531 self.write(")");
30532 }
30533 if let Some(with_storage) = &e.with_storage {
30534 self.write_space();
30535 self.write_keyword("WITH");
30536 self.write(" (");
30537 self.generate_expression(with_storage)?;
30538 self.write(")");
30539 }
30540 if let Some(tablespace) = &e.tablespace {
30541 self.write_space();
30542 self.write_keyword("USING INDEX TABLESPACE");
30543 self.write_space();
30544 self.generate_expression(tablespace)?;
30545 }
30546 Ok(())
30547 }
30548
30549 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
30550 if let Expression::Identifier(id) = &*e.this {
30554 self.write_keyword(&id.name);
30555 } else {
30556 self.generate_expression(&e.this)?;
30557 }
30558 self.write_space();
30559 self.write_keyword("INDEX");
30560 if let Some(target) = &e.target {
30561 self.write_space();
30562 self.write_keyword("FOR");
30563 self.write_space();
30564 if let Expression::Identifier(id) = &**target {
30565 self.write_keyword(&id.name);
30566 } else {
30567 self.generate_expression(target)?;
30568 }
30569 }
30570 self.write(" (");
30572 for (i, expr) in e.expressions.iter().enumerate() {
30573 if i > 0 {
30574 self.write(", ");
30575 }
30576 self.generate_expression(expr)?;
30577 }
30578 self.write(")");
30579 Ok(())
30580 }
30581
30582 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
30583 self.write_keyword("INHERITS");
30585 self.write(" (");
30586 for (i, expr) in e.expressions.iter().enumerate() {
30587 if i > 0 {
30588 self.write(", ");
30589 }
30590 self.generate_expression(expr)?;
30591 }
30592 self.write(")");
30593 Ok(())
30594 }
30595
30596 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
30597 self.write_keyword("INPUT");
30599 self.write("(");
30600 self.generate_expression(&e.this)?;
30601 self.write(")");
30602 Ok(())
30603 }
30604
30605 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
30606 if let Some(input_format) = &e.input_format {
30608 self.write_keyword("INPUTFORMAT");
30609 self.write_space();
30610 self.generate_expression(input_format)?;
30611 }
30612 if let Some(output_format) = &e.output_format {
30613 if e.input_format.is_some() {
30614 self.write(" ");
30615 }
30616 self.write_keyword("OUTPUTFORMAT");
30617 self.write_space();
30618 self.generate_expression(output_format)?;
30619 }
30620 Ok(())
30621 }
30622
30623 fn generate_install(&mut self, e: &Install) -> Result<()> {
30624 if e.force.is_some() {
30626 self.write_keyword("FORCE");
30627 self.write_space();
30628 }
30629 self.write_keyword("INSTALL");
30630 self.write_space();
30631 self.generate_expression(&e.this)?;
30632 if let Some(from) = &e.from_ {
30633 self.write_space();
30634 self.write_keyword("FROM");
30635 self.write_space();
30636 self.generate_expression(from)?;
30637 }
30638 Ok(())
30639 }
30640
30641 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
30642 self.write_keyword("INTERVAL");
30644 self.write_space();
30645 self.generate_expression(&e.expression)?;
30647 if let Some(unit) = &e.unit {
30648 self.write_space();
30649 self.write(unit);
30650 }
30651 Ok(())
30652 }
30653
30654 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
30655 self.write(&format!("{:?}", e.this).to_ascii_uppercase());
30657 self.write_space();
30658 self.write_keyword("TO");
30659 self.write_space();
30660 self.write(&format!("{:?}", e.expression).to_ascii_uppercase());
30661 Ok(())
30662 }
30663
30664 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
30665 self.write_keyword("INTO");
30667 if e.temporary {
30668 self.write_keyword(" TEMPORARY");
30669 }
30670 if e.unlogged.is_some() {
30671 self.write_keyword(" UNLOGGED");
30672 }
30673 if let Some(this) = &e.this {
30674 self.write_space();
30675 self.generate_expression(this)?;
30676 }
30677 if !e.expressions.is_empty() {
30678 self.write(" (");
30679 for (i, expr) in e.expressions.iter().enumerate() {
30680 if i > 0 {
30681 self.write(", ");
30682 }
30683 self.generate_expression(expr)?;
30684 }
30685 self.write(")");
30686 }
30687 Ok(())
30688 }
30689
30690 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
30691 self.generate_expression(&e.this)?;
30693 self.write_space();
30694 self.generate_expression(&e.expression)?;
30695 Ok(())
30696 }
30697
30698 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
30699 self.write_keyword("WITH");
30701 if e.no.is_some() {
30702 self.write_keyword(" NO");
30703 }
30704 if e.concurrent.is_some() {
30705 self.write_keyword(" CONCURRENT");
30706 }
30707 self.write_keyword(" ISOLATED LOADING");
30708 if let Some(target) = &e.target {
30709 self.write_space();
30710 self.generate_expression(target)?;
30711 }
30712 Ok(())
30713 }
30714
30715 fn generate_json(&mut self, e: &JSON) -> Result<()> {
30716 self.write_keyword("JSON");
30718 if let Some(this) = &e.this {
30719 self.write_space();
30720 self.generate_expression(this)?;
30721 }
30722 if let Some(with_) = &e.with_ {
30723 if let Expression::Boolean(b) = with_.as_ref() {
30725 if b.value {
30726 self.write_keyword(" WITH");
30727 } else {
30728 self.write_keyword(" WITHOUT");
30729 }
30730 }
30731 }
30732 if e.unique {
30733 self.write_keyword(" UNIQUE KEYS");
30734 }
30735 Ok(())
30736 }
30737
30738 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
30739 self.write_keyword("JSON_ARRAY");
30741 self.write("(");
30742 for (i, expr) in e.expressions.iter().enumerate() {
30743 if i > 0 {
30744 self.write(", ");
30745 }
30746 self.generate_expression(expr)?;
30747 }
30748 if let Some(null_handling) = &e.null_handling {
30749 self.write_space();
30750 self.generate_expression(null_handling)?;
30751 }
30752 if let Some(return_type) = &e.return_type {
30753 self.write_space();
30754 self.write_keyword("RETURNING");
30755 self.write_space();
30756 self.generate_expression(return_type)?;
30757 }
30758 if e.strict.is_some() {
30759 self.write_space();
30760 self.write_keyword("STRICT");
30761 }
30762 self.write(")");
30763 Ok(())
30764 }
30765
30766 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
30767 self.write_keyword("JSON_ARRAYAGG");
30769 self.write("(");
30770 self.generate_expression(&e.this)?;
30771 if let Some(order) = &e.order {
30772 self.write_space();
30773 if let Expression::OrderBy(ob) = order.as_ref() {
30775 self.write_keyword("ORDER BY");
30776 self.write_space();
30777 for (i, ord) in ob.expressions.iter().enumerate() {
30778 if i > 0 {
30779 self.write(", ");
30780 }
30781 self.generate_ordered(ord)?;
30782 }
30783 } else {
30784 self.generate_expression(order)?;
30786 }
30787 }
30788 if let Some(null_handling) = &e.null_handling {
30789 self.write_space();
30790 self.generate_expression(null_handling)?;
30791 }
30792 if let Some(return_type) = &e.return_type {
30793 self.write_space();
30794 self.write_keyword("RETURNING");
30795 self.write_space();
30796 self.generate_expression(return_type)?;
30797 }
30798 if e.strict.is_some() {
30799 self.write_space();
30800 self.write_keyword("STRICT");
30801 }
30802 self.write(")");
30803 Ok(())
30804 }
30805
30806 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
30807 self.write_keyword("JSON_OBJECTAGG");
30809 self.write("(");
30810 for (i, expr) in e.expressions.iter().enumerate() {
30811 if i > 0 {
30812 self.write(", ");
30813 }
30814 self.generate_expression(expr)?;
30815 }
30816 if let Some(null_handling) = &e.null_handling {
30817 self.write_space();
30818 self.generate_expression(null_handling)?;
30819 }
30820 if let Some(unique_keys) = &e.unique_keys {
30821 self.write_space();
30822 if let Expression::Boolean(b) = unique_keys.as_ref() {
30823 if b.value {
30824 self.write_keyword("WITH UNIQUE KEYS");
30825 } else {
30826 self.write_keyword("WITHOUT UNIQUE KEYS");
30827 }
30828 }
30829 }
30830 if let Some(return_type) = &e.return_type {
30831 self.write_space();
30832 self.write_keyword("RETURNING");
30833 self.write_space();
30834 self.generate_expression(return_type)?;
30835 }
30836 self.write(")");
30837 Ok(())
30838 }
30839
30840 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
30841 self.write_keyword("JSON_ARRAY_APPEND");
30843 self.write("(");
30844 self.generate_expression(&e.this)?;
30845 for expr in &e.expressions {
30846 self.write(", ");
30847 self.generate_expression(expr)?;
30848 }
30849 self.write(")");
30850 Ok(())
30851 }
30852
30853 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
30854 self.write_keyword("JSON_ARRAY_CONTAINS");
30856 self.write("(");
30857 self.generate_expression(&e.this)?;
30858 self.write(", ");
30859 self.generate_expression(&e.expression)?;
30860 self.write(")");
30861 Ok(())
30862 }
30863
30864 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
30865 self.write_keyword("JSON_ARRAY_INSERT");
30867 self.write("(");
30868 self.generate_expression(&e.this)?;
30869 for expr in &e.expressions {
30870 self.write(", ");
30871 self.generate_expression(expr)?;
30872 }
30873 self.write(")");
30874 Ok(())
30875 }
30876
30877 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
30878 self.write_keyword("JSONB_EXISTS");
30880 self.write("(");
30881 self.generate_expression(&e.this)?;
30882 if let Some(path) = &e.path {
30883 self.write(", ");
30884 self.generate_expression(path)?;
30885 }
30886 self.write(")");
30887 Ok(())
30888 }
30889
30890 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
30891 self.write_keyword("JSONB_EXTRACT_SCALAR");
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_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
30902 self.write_keyword("JSONB_OBJECT_AGG");
30904 self.write("(");
30905 self.generate_expression(&e.this)?;
30906 self.write(", ");
30907 self.generate_expression(&e.expression)?;
30908 self.write(")");
30909 Ok(())
30910 }
30911
30912 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
30913 if let Some(nested_schema) = &e.nested_schema {
30915 self.write_keyword("NESTED");
30916 if let Some(path) = &e.path {
30917 self.write_space();
30918 self.write_keyword("PATH");
30919 self.write_space();
30920 self.generate_expression(path)?;
30921 }
30922 self.write_space();
30923 self.generate_expression(nested_schema)?;
30924 } else {
30925 if let Some(this) = &e.this {
30926 self.generate_expression(this)?;
30927 }
30928 if let Some(kind) = &e.kind {
30929 self.write_space();
30930 self.write(kind);
30931 }
30932 if e.format_json {
30933 self.write_space();
30934 self.write_keyword("FORMAT JSON");
30935 }
30936 if let Some(path) = &e.path {
30937 self.write_space();
30938 self.write_keyword("PATH");
30939 self.write_space();
30940 self.generate_expression(path)?;
30941 }
30942 if e.ordinality.is_some() {
30943 self.write_keyword(" FOR ORDINALITY");
30944 }
30945 }
30946 Ok(())
30947 }
30948
30949 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
30950 self.write_keyword("JSON_EXISTS");
30952 self.write("(");
30953 self.generate_expression(&e.this)?;
30954 if let Some(path) = &e.path {
30955 self.write(", ");
30956 self.generate_expression(path)?;
30957 }
30958 if let Some(passing) = &e.passing {
30959 self.write_space();
30960 self.write_keyword("PASSING");
30961 self.write_space();
30962 self.generate_expression(passing)?;
30963 }
30964 if let Some(on_condition) = &e.on_condition {
30965 self.write_space();
30966 self.generate_expression(on_condition)?;
30967 }
30968 self.write(")");
30969 Ok(())
30970 }
30971
30972 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
30973 self.generate_expression(&e.this)?;
30974 self.write(".:");
30975 if Self::data_type_has_nested_expressions(&e.to) {
30979 let saved = std::mem::take(&mut self.output);
30981 self.generate_data_type(&e.to)?;
30982 let type_sql = std::mem::replace(&mut self.output, saved);
30983 self.write("\"");
30984 self.write(&type_sql);
30985 self.write("\"");
30986 } else {
30987 self.generate_data_type(&e.to)?;
30988 }
30989 Ok(())
30990 }
30991
30992 fn data_type_has_nested_expressions(dt: &DataType) -> bool {
30995 matches!(
30996 dt,
30997 DataType::Array { .. } | DataType::Map { .. } | DataType::Struct { .. }
30998 )
30999 }
31000
31001 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
31002 self.write_keyword("JSON_EXTRACT_ARRAY");
31004 self.write("(");
31005 self.generate_expression(&e.this)?;
31006 if let Some(expr) = &e.expression {
31007 self.write(", ");
31008 self.generate_expression(expr)?;
31009 }
31010 self.write(")");
31011 Ok(())
31012 }
31013
31014 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
31015 if let Some(option) = &e.option {
31017 self.generate_expression(option)?;
31018 self.write_space();
31019 }
31020 self.write_keyword("QUOTES");
31021 if e.scalar.is_some() {
31022 self.write_keyword(" SCALAR_ONLY");
31023 }
31024 Ok(())
31025 }
31026
31027 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
31028 self.write_keyword("JSON_EXTRACT_SCALAR");
31030 self.write("(");
31031 self.generate_expression(&e.this)?;
31032 self.write(", ");
31033 self.generate_expression(&e.expression)?;
31034 self.write(")");
31035 Ok(())
31036 }
31037
31038 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
31039 if e.variant_extract.is_some() {
31043 use crate::dialects::DialectType;
31044 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
31045 self.generate_expression(&e.this)?;
31049 self.write(":");
31050 match e.expression.as_ref() {
31051 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
31052 let Literal::String(s) = lit.as_ref() else {
31053 unreachable!()
31054 };
31055 self.write_databricks_json_path(s);
31056 }
31057 _ => {
31058 self.generate_expression(&e.expression)?;
31060 }
31061 }
31062 } else {
31063 self.write_keyword("GET_PATH");
31065 self.write("(");
31066 self.generate_expression(&e.this)?;
31067 self.write(", ");
31068 self.generate_expression(&e.expression)?;
31069 self.write(")");
31070 }
31071 } else {
31072 self.write_keyword("JSON_EXTRACT");
31073 self.write("(");
31074 self.generate_expression(&e.this)?;
31075 self.write(", ");
31076 self.generate_expression(&e.expression)?;
31077 for expr in &e.expressions {
31078 self.write(", ");
31079 self.generate_expression(expr)?;
31080 }
31081 self.write(")");
31082 }
31083 Ok(())
31084 }
31085
31086 fn write_databricks_json_path(&mut self, path: &str) {
31090 if path.starts_with("[\"") || path.starts_with("['") {
31093 self.write(path);
31094 return;
31095 }
31096 let mut first = true;
31100 for segment in path.split('.') {
31101 if !first {
31102 self.write(".");
31103 }
31104 first = false;
31105 if let Some(bracket_pos) = segment.find('[') {
31107 let key = &segment[..bracket_pos];
31108 let subscript = &segment[bracket_pos..];
31109 if key.is_empty() {
31110 self.write(segment);
31112 } else if Self::is_safe_json_path_key(key) {
31113 self.write(key);
31114 self.write(subscript);
31115 } else {
31116 self.write("[\"");
31117 self.write(key);
31118 self.write("\"]");
31119 self.write(subscript);
31120 }
31121 } else if Self::is_safe_json_path_key(segment) {
31122 self.write(segment);
31123 } else {
31124 self.write("[\"");
31125 self.write(segment);
31126 self.write("\"]");
31127 }
31128 }
31129 }
31130
31131 fn is_safe_json_path_key(key: &str) -> bool {
31134 if key.is_empty() {
31135 return false;
31136 }
31137 let mut chars = key.chars();
31138 let first = chars.next().unwrap();
31139 if first != '_' && !first.is_ascii_alphabetic() {
31140 return false;
31141 }
31142 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
31143 }
31144
31145 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
31146 if let Some(this) = &e.this {
31149 self.generate_expression(this)?;
31150 self.write_space();
31151 }
31152 self.write_keyword("FORMAT JSON");
31153 Ok(())
31154 }
31155
31156 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
31157 self.generate_expression(&e.this)?;
31159 self.write(": ");
31160 self.generate_expression(&e.expression)?;
31161 Ok(())
31162 }
31163
31164 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
31165 self.write_keyword("JSON_KEYS");
31167 self.write("(");
31168 self.generate_expression(&e.this)?;
31169 if let Some(expr) = &e.expression {
31170 self.write(", ");
31171 self.generate_expression(expr)?;
31172 }
31173 for expr in &e.expressions {
31174 self.write(", ");
31175 self.generate_expression(expr)?;
31176 }
31177 self.write(")");
31178 Ok(())
31179 }
31180
31181 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
31182 self.write_keyword("JSON_KEYS");
31184 self.write("(");
31185 self.generate_expression(&e.this)?;
31186 if let Some(expr) = &e.expression {
31187 self.write(", ");
31188 self.generate_expression(expr)?;
31189 }
31190 self.write(")");
31191 Ok(())
31192 }
31193
31194 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
31195 let mut path_str = String::new();
31198 for expr in &e.expressions {
31199 match expr {
31200 Expression::JSONPathRoot(_) => {
31201 path_str.push('$');
31202 }
31203 Expression::JSONPathKey(k) => {
31204 if let Expression::Literal(lit) = k.this.as_ref() {
31206 if let crate::expressions::Literal::String(s) = lit.as_ref() {
31207 path_str.push('.');
31208 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
31210 if needs_quoting {
31211 path_str.push('"');
31212 path_str.push_str(s);
31213 path_str.push('"');
31214 } else {
31215 path_str.push_str(s);
31216 }
31217 }
31218 }
31219 }
31220 Expression::JSONPathSubscript(s) => {
31221 if let Expression::Literal(lit) = s.this.as_ref() {
31223 if let crate::expressions::Literal::Number(n) = lit.as_ref() {
31224 path_str.push('[');
31225 path_str.push_str(n);
31226 path_str.push(']');
31227 }
31228 }
31229 }
31230 _ => {
31231 let mut temp_gen = Self::with_arc_config(self.config.clone());
31233 temp_gen.generate_expression(expr)?;
31234 path_str.push_str(&temp_gen.output);
31235 }
31236 }
31237 }
31238 self.write("'");
31240 self.write(&path_str);
31241 self.write("'");
31242 Ok(())
31243 }
31244
31245 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
31246 self.write("?(");
31248 self.generate_expression(&e.this)?;
31249 self.write(")");
31250 Ok(())
31251 }
31252
31253 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
31254 self.write(".");
31256 self.generate_expression(&e.this)?;
31257 Ok(())
31258 }
31259
31260 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
31261 self.write("..");
31263 if let Some(this) = &e.this {
31264 self.generate_expression(this)?;
31265 }
31266 Ok(())
31267 }
31268
31269 fn generate_json_path_root(&mut self) -> Result<()> {
31270 self.write("$");
31272 Ok(())
31273 }
31274
31275 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
31276 self.write("(");
31278 self.generate_expression(&e.this)?;
31279 self.write(")");
31280 Ok(())
31281 }
31282
31283 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
31284 self.generate_expression(&e.this)?;
31286 Ok(())
31287 }
31288
31289 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
31290 self.write("[");
31292 if let Some(start) = &e.start {
31293 self.generate_expression(start)?;
31294 }
31295 self.write(":");
31296 if let Some(end) = &e.end {
31297 self.generate_expression(end)?;
31298 }
31299 if let Some(step) = &e.step {
31300 self.write(":");
31301 self.generate_expression(step)?;
31302 }
31303 self.write("]");
31304 Ok(())
31305 }
31306
31307 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
31308 self.write("[");
31310 self.generate_expression(&e.this)?;
31311 self.write("]");
31312 Ok(())
31313 }
31314
31315 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
31316 self.write("[");
31318 for (i, expr) in e.expressions.iter().enumerate() {
31319 if i > 0 {
31320 self.write(", ");
31321 }
31322 self.generate_expression(expr)?;
31323 }
31324 self.write("]");
31325 Ok(())
31326 }
31327
31328 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
31329 self.write_keyword("JSON_REMOVE");
31331 self.write("(");
31332 self.generate_expression(&e.this)?;
31333 for expr in &e.expressions {
31334 self.write(", ");
31335 self.generate_expression(expr)?;
31336 }
31337 self.write(")");
31338 Ok(())
31339 }
31340
31341 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
31342 self.write_keyword("COLUMNS");
31345 self.write("(");
31346
31347 if self.config.pretty && !e.expressions.is_empty() {
31348 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
31350 for expr in &e.expressions {
31351 let mut temp_gen = Generator::with_arc_config(self.config.clone());
31352 temp_gen.generate_expression(expr)?;
31353 expr_strings.push(temp_gen.output);
31354 }
31355
31356 if self.too_wide(&expr_strings) {
31358 self.write_newline();
31360 self.indent_level += 1;
31361 for (i, expr_str) in expr_strings.iter().enumerate() {
31362 if i > 0 {
31363 self.write(",");
31364 self.write_newline();
31365 }
31366 self.write_indent();
31367 self.write(expr_str);
31368 }
31369 self.write_newline();
31370 self.indent_level -= 1;
31371 self.write_indent();
31372 } else {
31373 for (i, expr_str) in expr_strings.iter().enumerate() {
31375 if i > 0 {
31376 self.write(", ");
31377 }
31378 self.write(expr_str);
31379 }
31380 }
31381 } else {
31382 for (i, expr) in e.expressions.iter().enumerate() {
31384 if i > 0 {
31385 self.write(", ");
31386 }
31387 self.generate_expression(expr)?;
31388 }
31389 }
31390 self.write(")");
31391 Ok(())
31392 }
31393
31394 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
31395 self.write_keyword("JSON_SET");
31397 self.write("(");
31398 self.generate_expression(&e.this)?;
31399 for expr in &e.expressions {
31400 self.write(", ");
31401 self.generate_expression(expr)?;
31402 }
31403 self.write(")");
31404 Ok(())
31405 }
31406
31407 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
31408 self.write_keyword("JSON_STRIP_NULLS");
31410 self.write("(");
31411 self.generate_expression(&e.this)?;
31412 if let Some(expr) = &e.expression {
31413 self.write(", ");
31414 self.generate_expression(expr)?;
31415 }
31416 self.write(")");
31417 Ok(())
31418 }
31419
31420 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
31421 self.write_keyword("JSON_TABLE");
31423 self.write("(");
31424 self.generate_expression(&e.this)?;
31425 if let Some(path) = &e.path {
31426 self.write(", ");
31427 self.generate_expression(path)?;
31428 }
31429 if let Some(error_handling) = &e.error_handling {
31430 self.write_space();
31431 self.generate_expression(error_handling)?;
31432 }
31433 if let Some(empty_handling) = &e.empty_handling {
31434 self.write_space();
31435 self.generate_expression(empty_handling)?;
31436 }
31437 if let Some(schema) = &e.schema {
31438 self.write_space();
31439 self.generate_expression(schema)?;
31440 }
31441 self.write(")");
31442 Ok(())
31443 }
31444
31445 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
31446 self.write_keyword("JSON_TYPE");
31448 self.write("(");
31449 self.generate_expression(&e.this)?;
31450 self.write(")");
31451 Ok(())
31452 }
31453
31454 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
31455 self.write_keyword("JSON_VALUE");
31457 self.write("(");
31458 self.generate_expression(&e.this)?;
31459 if let Some(path) = &e.path {
31460 self.write(", ");
31461 self.generate_expression(path)?;
31462 }
31463 if let Some(returning) = &e.returning {
31464 self.write_space();
31465 self.write_keyword("RETURNING");
31466 self.write_space();
31467 self.generate_expression(returning)?;
31468 }
31469 if let Some(on_condition) = &e.on_condition {
31470 self.write_space();
31471 self.generate_expression(on_condition)?;
31472 }
31473 self.write(")");
31474 Ok(())
31475 }
31476
31477 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
31478 self.write_keyword("JSON_VALUE_ARRAY");
31480 self.write("(");
31481 self.generate_expression(&e.this)?;
31482 self.write(")");
31483 Ok(())
31484 }
31485
31486 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
31487 self.write_keyword("JAROWINKLER_SIMILARITY");
31489 self.write("(");
31490 self.generate_expression(&e.this)?;
31491 self.write(", ");
31492 self.generate_expression(&e.expression)?;
31493 self.write(")");
31494 Ok(())
31495 }
31496
31497 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
31498 self.generate_expression(&e.this)?;
31500 self.write("(");
31501 for (i, expr) in e.expressions.iter().enumerate() {
31502 if i > 0 {
31503 self.write(", ");
31504 }
31505 self.generate_expression(expr)?;
31506 }
31507 self.write(")");
31508 Ok(())
31509 }
31510
31511 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
31512 if e.no.is_some() {
31514 self.write_keyword("NO ");
31515 }
31516 if let Some(local) = &e.local {
31517 self.generate_expression(local)?;
31518 self.write_space();
31519 }
31520 if e.dual.is_some() {
31521 self.write_keyword("DUAL ");
31522 }
31523 if e.before.is_some() {
31524 self.write_keyword("BEFORE ");
31525 }
31526 if e.after.is_some() {
31527 self.write_keyword("AFTER ");
31528 }
31529 self.write_keyword("JOURNAL");
31530 Ok(())
31531 }
31532
31533 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
31534 self.write_keyword("LANGUAGE");
31536 self.write_space();
31537 self.generate_expression(&e.this)?;
31538 Ok(())
31539 }
31540
31541 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
31542 if e.view.is_some() {
31544 self.write_keyword("LATERAL VIEW");
31546 if e.outer.is_some() {
31547 self.write_space();
31548 self.write_keyword("OUTER");
31549 }
31550 self.write_space();
31551 self.generate_expression(&e.this)?;
31552 if let Some(alias) = &e.alias {
31553 self.write_space();
31554 self.write(alias);
31555 }
31556 } else {
31557 self.write_keyword("LATERAL");
31559 self.write_space();
31560 self.generate_expression(&e.this)?;
31561 if e.ordinality.is_some() {
31562 self.write_space();
31563 self.write_keyword("WITH ORDINALITY");
31564 }
31565 if let Some(alias) = &e.alias {
31566 self.write_space();
31567 self.write_keyword("AS");
31568 self.write_space();
31569 self.write(alias);
31570 if !e.column_aliases.is_empty() {
31571 self.write("(");
31572 for (i, col) in e.column_aliases.iter().enumerate() {
31573 if i > 0 {
31574 self.write(", ");
31575 }
31576 self.write(col);
31577 }
31578 self.write(")");
31579 }
31580 }
31581 }
31582 Ok(())
31583 }
31584
31585 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
31586 self.write_keyword("LIKE");
31588 self.write_space();
31589 self.generate_expression(&e.this)?;
31590 for expr in &e.expressions {
31591 self.write_space();
31592 self.generate_expression(expr)?;
31593 }
31594 Ok(())
31595 }
31596
31597 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
31598 self.write_keyword("LIMIT");
31599 self.write_space();
31600 self.write_limit_expr(&e.this)?;
31601 if e.percent {
31602 self.write_space();
31603 self.write_keyword("PERCENT");
31604 }
31605 for comment in &e.comments {
31607 self.write(" ");
31608 self.write_formatted_comment(comment);
31609 }
31610 Ok(())
31611 }
31612
31613 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
31614 if e.percent.is_some() {
31616 self.write_keyword(" PERCENT");
31617 }
31618 if e.rows.is_some() {
31619 self.write_keyword(" ROWS");
31620 }
31621 if e.with_ties.is_some() {
31622 self.write_keyword(" WITH TIES");
31623 } else if e.rows.is_some() {
31624 self.write_keyword(" ONLY");
31625 }
31626 Ok(())
31627 }
31628
31629 fn generate_list(&mut self, e: &List) -> Result<()> {
31630 use crate::dialects::DialectType;
31631 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
31632
31633 if e.expressions.len() == 1 {
31635 if let Expression::Select(_) = &e.expressions[0] {
31636 self.write_keyword("LIST");
31637 self.write("(");
31638 self.generate_expression(&e.expressions[0])?;
31639 self.write(")");
31640 return Ok(());
31641 }
31642 }
31643
31644 if is_materialize {
31646 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 } else {
31656 self.write_keyword("LIST");
31658 self.write("(");
31659 for (i, expr) in e.expressions.iter().enumerate() {
31660 if i > 0 {
31661 self.write(", ");
31662 }
31663 self.generate_expression(expr)?;
31664 }
31665 self.write(")");
31666 }
31667 Ok(())
31668 }
31669
31670 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
31671 if let Expression::Select(_) = &*e.this {
31673 self.write_keyword("MAP");
31674 self.write("(");
31675 self.generate_expression(&e.this)?;
31676 self.write(")");
31677 return Ok(());
31678 }
31679
31680 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
31681
31682 self.write_keyword("MAP");
31684 if is_duckdb {
31685 self.write(" {");
31686 } else {
31687 self.write("[");
31688 }
31689 if let Expression::Struct(s) = &*e.this {
31690 for (i, (_, expr)) in s.fields.iter().enumerate() {
31691 if i > 0 {
31692 self.write(", ");
31693 }
31694 if let Expression::PropertyEQ(op) = expr {
31695 self.generate_expression(&op.left)?;
31696 if is_duckdb {
31697 self.write(": ");
31698 } else {
31699 self.write(" => ");
31700 }
31701 self.generate_expression(&op.right)?;
31702 } else {
31703 self.generate_expression(expr)?;
31704 }
31705 }
31706 }
31707 if is_duckdb {
31708 self.write("}");
31709 } else {
31710 self.write("]");
31711 }
31712 Ok(())
31713 }
31714
31715 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
31716 self.write_keyword("LOCALTIME");
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_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
31727 self.write_keyword("LOCALTIMESTAMP");
31729 if let Some(precision) = &e.this {
31730 self.write("(");
31731 self.generate_expression(precision)?;
31732 self.write(")");
31733 }
31734 Ok(())
31735 }
31736
31737 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
31738 self.write_keyword("LOCATION");
31740 self.write_space();
31741 self.generate_expression(&e.this)?;
31742 Ok(())
31743 }
31744
31745 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
31746 if e.update.is_some() {
31748 if e.key.is_some() {
31749 self.write_keyword("FOR NO KEY UPDATE");
31750 } else {
31751 self.write_keyword("FOR UPDATE");
31752 }
31753 } else {
31754 if e.key.is_some() {
31755 self.write_keyword("FOR KEY SHARE");
31756 } else {
31757 self.write_keyword("FOR SHARE");
31758 }
31759 }
31760 if !e.expressions.is_empty() {
31761 self.write_keyword(" OF ");
31762 for (i, expr) in e.expressions.iter().enumerate() {
31763 if i > 0 {
31764 self.write(", ");
31765 }
31766 self.generate_expression(expr)?;
31767 }
31768 }
31769 if let Some(wait) = &e.wait {
31774 match wait.as_ref() {
31775 Expression::Boolean(b) => {
31776 if b.value {
31777 self.write_keyword(" NOWAIT");
31778 } else {
31779 self.write_keyword(" SKIP LOCKED");
31780 }
31781 }
31782 _ => {
31783 self.write_keyword(" WAIT ");
31785 self.generate_expression(wait)?;
31786 }
31787 }
31788 }
31789 Ok(())
31790 }
31791
31792 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
31793 self.write_keyword("LOCK");
31795 self.write_space();
31796 self.generate_expression(&e.this)?;
31797 Ok(())
31798 }
31799
31800 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
31801 self.write_keyword("LOCKING");
31803 self.write_space();
31804 self.write(&e.kind);
31805 if let Some(this) = &e.this {
31806 self.write_space();
31807 self.generate_expression(this)?;
31808 }
31809 if let Some(for_or_in) = &e.for_or_in {
31810 self.write_space();
31811 self.generate_expression(for_or_in)?;
31812 }
31813 if let Some(lock_type) = &e.lock_type {
31814 self.write_space();
31815 self.generate_expression(lock_type)?;
31816 }
31817 if e.override_.is_some() {
31818 self.write_keyword(" OVERRIDE");
31819 }
31820 Ok(())
31821 }
31822
31823 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
31824 self.generate_expression(&e.this)?;
31826 self.write_space();
31827 self.generate_expression(&e.expression)?;
31828 Ok(())
31829 }
31830
31831 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
31832 if e.no.is_some() {
31834 self.write_keyword("NO ");
31835 }
31836 self.write_keyword("LOG");
31837 Ok(())
31838 }
31839
31840 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
31841 self.write_keyword("MD5");
31843 self.write("(");
31844 self.generate_expression(&e.this)?;
31845 for expr in &e.expressions {
31846 self.write(", ");
31847 self.generate_expression(expr)?;
31848 }
31849 self.write(")");
31850 Ok(())
31851 }
31852
31853 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
31854 self.write_keyword("ML.FORECAST");
31856 self.write("(");
31857 self.generate_expression(&e.this)?;
31858 if let Some(expression) = &e.expression {
31859 self.write(", ");
31860 self.generate_expression(expression)?;
31861 }
31862 if let Some(params) = &e.params_struct {
31863 self.write(", ");
31864 self.generate_expression(params)?;
31865 }
31866 self.write(")");
31867 Ok(())
31868 }
31869
31870 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
31871 self.write_keyword("ML.TRANSLATE");
31873 self.write("(");
31874 self.generate_expression(&e.this)?;
31875 self.write(", ");
31876 self.generate_expression(&e.expression)?;
31877 if let Some(params) = &e.params_struct {
31878 self.write(", ");
31879 self.generate_expression(params)?;
31880 }
31881 self.write(")");
31882 Ok(())
31883 }
31884
31885 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
31886 self.write_keyword("MAKE_INTERVAL");
31888 self.write("(");
31889 let mut first = true;
31890 if let Some(year) = &e.year {
31891 self.write("years => ");
31892 self.generate_expression(year)?;
31893 first = false;
31894 }
31895 if let Some(month) = &e.month {
31896 if !first {
31897 self.write(", ");
31898 }
31899 self.write("months => ");
31900 self.generate_expression(month)?;
31901 first = false;
31902 }
31903 if let Some(week) = &e.week {
31904 if !first {
31905 self.write(", ");
31906 }
31907 self.write("weeks => ");
31908 self.generate_expression(week)?;
31909 first = false;
31910 }
31911 if let Some(day) = &e.day {
31912 if !first {
31913 self.write(", ");
31914 }
31915 self.write("days => ");
31916 self.generate_expression(day)?;
31917 first = false;
31918 }
31919 if let Some(hour) = &e.hour {
31920 if !first {
31921 self.write(", ");
31922 }
31923 self.write("hours => ");
31924 self.generate_expression(hour)?;
31925 first = false;
31926 }
31927 if let Some(minute) = &e.minute {
31928 if !first {
31929 self.write(", ");
31930 }
31931 self.write("mins => ");
31932 self.generate_expression(minute)?;
31933 first = false;
31934 }
31935 if let Some(second) = &e.second {
31936 if !first {
31937 self.write(", ");
31938 }
31939 self.write("secs => ");
31940 self.generate_expression(second)?;
31941 }
31942 self.write(")");
31943 Ok(())
31944 }
31945
31946 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
31947 self.write_keyword("MANHATTAN_DISTANCE");
31949 self.write("(");
31950 self.generate_expression(&e.this)?;
31951 self.write(", ");
31952 self.generate_expression(&e.expression)?;
31953 self.write(")");
31954 Ok(())
31955 }
31956
31957 fn generate_map(&mut self, e: &Map) -> Result<()> {
31958 self.write_keyword("MAP");
31960 self.write("(");
31961 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
31962 if i > 0 {
31963 self.write(", ");
31964 }
31965 self.generate_expression(key)?;
31966 self.write(", ");
31967 self.generate_expression(value)?;
31968 }
31969 self.write(")");
31970 Ok(())
31971 }
31972
31973 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
31974 self.write_keyword("MAP_CAT");
31976 self.write("(");
31977 self.generate_expression(&e.this)?;
31978 self.write(", ");
31979 self.generate_expression(&e.expression)?;
31980 self.write(")");
31981 Ok(())
31982 }
31983
31984 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
31985 self.write_keyword("MAP_DELETE");
31987 self.write("(");
31988 self.generate_expression(&e.this)?;
31989 for expr in &e.expressions {
31990 self.write(", ");
31991 self.generate_expression(expr)?;
31992 }
31993 self.write(")");
31994 Ok(())
31995 }
31996
31997 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
31998 self.write_keyword("MAP_INSERT");
32000 self.write("(");
32001 self.generate_expression(&e.this)?;
32002 if let Some(key) = &e.key {
32003 self.write(", ");
32004 self.generate_expression(key)?;
32005 }
32006 if let Some(value) = &e.value {
32007 self.write(", ");
32008 self.generate_expression(value)?;
32009 }
32010 if let Some(update_flag) = &e.update_flag {
32011 self.write(", ");
32012 self.generate_expression(update_flag)?;
32013 }
32014 self.write(")");
32015 Ok(())
32016 }
32017
32018 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
32019 self.write_keyword("MAP_PICK");
32021 self.write("(");
32022 self.generate_expression(&e.this)?;
32023 for expr in &e.expressions {
32024 self.write(", ");
32025 self.generate_expression(expr)?;
32026 }
32027 self.write(")");
32028 Ok(())
32029 }
32030
32031 fn generate_masking_policy_column_constraint(
32032 &mut self,
32033 e: &MaskingPolicyColumnConstraint,
32034 ) -> Result<()> {
32035 self.write_keyword("MASKING POLICY");
32037 self.write_space();
32038 self.generate_expression(&e.this)?;
32039 if !e.expressions.is_empty() {
32040 self.write_keyword(" USING");
32041 self.write(" (");
32042 for (i, expr) in e.expressions.iter().enumerate() {
32043 if i > 0 {
32044 self.write(", ");
32045 }
32046 self.generate_expression(expr)?;
32047 }
32048 self.write(")");
32049 }
32050 Ok(())
32051 }
32052
32053 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
32054 if matches!(
32055 self.config.dialect,
32056 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
32057 ) {
32058 if e.expressions.len() > 1 {
32059 self.write("(");
32060 }
32061 for (i, expr) in e.expressions.iter().enumerate() {
32062 if i > 0 {
32063 self.write_keyword(" OR ");
32064 }
32065 self.generate_expression(expr)?;
32066 self.write_space();
32067 self.write("@@");
32068 self.write_space();
32069 self.generate_expression(&e.this)?;
32070 }
32071 if e.expressions.len() > 1 {
32072 self.write(")");
32073 }
32074 return Ok(());
32075 }
32076
32077 self.write_keyword("MATCH");
32079 self.write("(");
32080 for (i, expr) in e.expressions.iter().enumerate() {
32081 if i > 0 {
32082 self.write(", ");
32083 }
32084 self.generate_expression(expr)?;
32085 }
32086 self.write(")");
32087 self.write_keyword(" AGAINST");
32088 self.write("(");
32089 self.generate_expression(&e.this)?;
32090 if let Some(modifier) = &e.modifier {
32091 self.write_space();
32092 self.generate_expression(modifier)?;
32093 }
32094 self.write(")");
32095 Ok(())
32096 }
32097
32098 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
32099 if let Some(window_frame) = &e.window_frame {
32101 self.write(&format!("{:?}", window_frame).to_ascii_uppercase());
32102 self.write_space();
32103 }
32104 self.generate_expression(&e.this)?;
32105 Ok(())
32106 }
32107
32108 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
32109 self.write_keyword("MATERIALIZED");
32111 if let Some(this) = &e.this {
32112 self.write_space();
32113 self.generate_expression(this)?;
32114 }
32115 Ok(())
32116 }
32117
32118 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
32119 if let Some(with_) = &e.with_ {
32122 if let Expression::With(with_clause) = with_.as_ref() {
32123 self.generate_with(with_clause)?;
32124 self.write_space();
32125 } else {
32126 self.generate_expression(with_)?;
32127 self.write_space();
32128 }
32129 }
32130 self.write_keyword("MERGE INTO");
32131 self.write_space();
32132 if matches!(self.config.dialect, Some(crate::DialectType::Oracle)) {
32133 if let Expression::Alias(alias) = e.this.as_ref() {
32134 self.generate_expression(&alias.this)?;
32135 self.write_space();
32136 self.generate_identifier(&alias.alias)?;
32137 } else {
32138 self.generate_expression(&e.this)?;
32139 }
32140 } else {
32141 self.generate_expression(&e.this)?;
32142 }
32143
32144 if self.config.pretty {
32146 self.write_newline();
32147 self.write_indent();
32148 } else {
32149 self.write_space();
32150 }
32151 self.write_keyword("USING");
32152 self.write_space();
32153 self.generate_expression(&e.using)?;
32154
32155 if let Some(on) = &e.on {
32157 if self.config.pretty {
32158 self.write_newline();
32159 self.write_indent();
32160 } else {
32161 self.write_space();
32162 }
32163 self.write_keyword("ON");
32164 self.write_space();
32165 self.generate_expression(on)?;
32166 }
32167 if let Some(using_cond) = &e.using_cond {
32169 self.write_space();
32170 self.write_keyword("USING");
32171 self.write_space();
32172 self.write("(");
32173 if let Expression::Tuple(tuple) = using_cond.as_ref() {
32175 for (i, col) in tuple.expressions.iter().enumerate() {
32176 if i > 0 {
32177 self.write(", ");
32178 }
32179 self.generate_expression(col)?;
32180 }
32181 } else {
32182 self.generate_expression(using_cond)?;
32183 }
32184 self.write(")");
32185 }
32186 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
32188 if matches!(
32189 self.config.dialect,
32190 Some(crate::DialectType::PostgreSQL)
32191 | Some(crate::DialectType::Redshift)
32192 | Some(crate::DialectType::Trino)
32193 | Some(crate::DialectType::Presto)
32194 | Some(crate::DialectType::Athena)
32195 ) {
32196 let mut names = Vec::new();
32197 match e.this.as_ref() {
32198 Expression::Alias(a) => {
32199 if let Expression::Table(t) = &a.this {
32201 names.push(t.name.name.clone());
32202 } else if let Expression::Identifier(id) = &a.this {
32203 names.push(id.name.clone());
32204 }
32205 names.push(a.alias.name.clone());
32206 }
32207 Expression::Table(t) => {
32208 names.push(t.name.name.clone());
32209 }
32210 Expression::Identifier(id) => {
32211 names.push(id.name.clone());
32212 }
32213 _ => {}
32214 }
32215 self.merge_strip_qualifiers = names;
32216 }
32217
32218 if let Some(whens) = &e.whens {
32220 if self.config.pretty {
32221 self.write_newline();
32222 self.write_indent();
32223 } else {
32224 self.write_space();
32225 }
32226 self.generate_expression(whens)?;
32227 }
32228
32229 self.merge_strip_qualifiers = saved_merge_strip;
32231
32232 if let Some(returning) = &e.returning {
32234 if self.config.pretty {
32235 self.write_newline();
32236 self.write_indent();
32237 } else {
32238 self.write_space();
32239 }
32240 self.generate_expression(returning)?;
32241 }
32242 Ok(())
32243 }
32244
32245 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
32246 if e.no.is_some() {
32248 self.write_keyword("NO MERGEBLOCKRATIO");
32249 } else if e.default.is_some() {
32250 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
32251 } else {
32252 self.write_keyword("MERGEBLOCKRATIO");
32253 self.write("=");
32254 if let Some(this) = &e.this {
32255 self.generate_expression(this)?;
32256 }
32257 if e.percent.is_some() {
32258 self.write_keyword(" PERCENT");
32259 }
32260 }
32261 Ok(())
32262 }
32263
32264 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
32265 self.write_keyword("TTL");
32267 let pretty_clickhouse = self.config.pretty
32268 && matches!(
32269 self.config.dialect,
32270 Some(crate::dialects::DialectType::ClickHouse)
32271 );
32272
32273 if pretty_clickhouse {
32274 self.write_newline();
32275 self.indent_level += 1;
32276 for (i, expr) in e.expressions.iter().enumerate() {
32277 if i > 0 {
32278 self.write(",");
32279 self.write_newline();
32280 }
32281 self.write_indent();
32282 self.generate_expression(expr)?;
32283 }
32284 self.indent_level -= 1;
32285 } else {
32286 self.write_space();
32287 for (i, expr) in e.expressions.iter().enumerate() {
32288 if i > 0 {
32289 self.write(", ");
32290 }
32291 self.generate_expression(expr)?;
32292 }
32293 }
32294
32295 if let Some(where_) = &e.where_ {
32296 if pretty_clickhouse {
32297 self.write_newline();
32298 if let Expression::Where(w) = where_.as_ref() {
32299 self.write_indent();
32300 self.write_keyword("WHERE");
32301 self.write_newline();
32302 self.indent_level += 1;
32303 self.write_indent();
32304 self.generate_expression(&w.this)?;
32305 self.indent_level -= 1;
32306 } else {
32307 self.write_indent();
32308 self.generate_expression(where_)?;
32309 }
32310 } else {
32311 self.write_space();
32312 self.generate_expression(where_)?;
32313 }
32314 }
32315 if let Some(group) = &e.group {
32316 if pretty_clickhouse {
32317 self.write_newline();
32318 if let Expression::Group(g) = group.as_ref() {
32319 self.write_indent();
32320 self.write_keyword("GROUP BY");
32321 self.write_newline();
32322 self.indent_level += 1;
32323 for (i, expr) in g.expressions.iter().enumerate() {
32324 if i > 0 {
32325 self.write(",");
32326 self.write_newline();
32327 }
32328 self.write_indent();
32329 self.generate_expression(expr)?;
32330 }
32331 self.indent_level -= 1;
32332 } else {
32333 self.write_indent();
32334 self.generate_expression(group)?;
32335 }
32336 } else {
32337 self.write_space();
32338 self.generate_expression(group)?;
32339 }
32340 }
32341 if let Some(aggregates) = &e.aggregates {
32342 if pretty_clickhouse {
32343 self.write_newline();
32344 self.write_indent();
32345 self.write_keyword("SET");
32346 self.write_newline();
32347 self.indent_level += 1;
32348 if let Expression::Tuple(t) = aggregates.as_ref() {
32349 for (i, agg) in t.expressions.iter().enumerate() {
32350 if i > 0 {
32351 self.write(",");
32352 self.write_newline();
32353 }
32354 self.write_indent();
32355 self.generate_expression(agg)?;
32356 }
32357 } else {
32358 self.write_indent();
32359 self.generate_expression(aggregates)?;
32360 }
32361 self.indent_level -= 1;
32362 } else {
32363 self.write_space();
32364 self.write_keyword("SET");
32365 self.write_space();
32366 if let Expression::Tuple(t) = aggregates.as_ref() {
32367 for (i, agg) in t.expressions.iter().enumerate() {
32368 if i > 0 {
32369 self.write(", ");
32370 }
32371 self.generate_expression(agg)?;
32372 }
32373 } else {
32374 self.generate_expression(aggregates)?;
32375 }
32376 }
32377 }
32378 Ok(())
32379 }
32380
32381 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
32382 self.generate_expression(&e.this)?;
32384 if e.delete.is_some() {
32385 self.write_keyword(" DELETE");
32386 }
32387 if let Some(recompress) = &e.recompress {
32388 self.write_keyword(" RECOMPRESS ");
32389 self.generate_expression(recompress)?;
32390 }
32391 if let Some(to_disk) = &e.to_disk {
32392 self.write_keyword(" TO DISK ");
32393 self.generate_expression(to_disk)?;
32394 }
32395 if let Some(to_volume) = &e.to_volume {
32396 self.write_keyword(" TO VOLUME ");
32397 self.generate_expression(to_volume)?;
32398 }
32399 Ok(())
32400 }
32401
32402 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
32403 self.write_keyword("MINHASH");
32405 self.write("(");
32406 self.generate_expression(&e.this)?;
32407 for expr in &e.expressions {
32408 self.write(", ");
32409 self.generate_expression(expr)?;
32410 }
32411 self.write(")");
32412 Ok(())
32413 }
32414
32415 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
32416 self.generate_expression(&e.this)?;
32418 self.write("!");
32419 self.generate_expression(&e.expression)?;
32420 Ok(())
32421 }
32422
32423 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
32424 self.write_keyword("MONTHNAME");
32426 self.write("(");
32427 self.generate_expression(&e.this)?;
32428 self.write(")");
32429 Ok(())
32430 }
32431
32432 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
32433 for comment in &e.leading_comments {
32435 self.write_formatted_comment(comment);
32436 if self.config.pretty {
32437 self.write_newline();
32438 self.write_indent();
32439 } else {
32440 self.write_space();
32441 }
32442 }
32443 self.write_keyword("INSERT");
32445 if e.overwrite {
32446 self.write_space();
32447 self.write_keyword("OVERWRITE");
32448 }
32449 self.write_space();
32450 self.write(&e.kind);
32451 if self.config.pretty {
32452 self.indent_level += 1;
32453 for expr in &e.expressions {
32454 self.write_newline();
32455 self.write_indent();
32456 self.generate_expression(expr)?;
32457 }
32458 self.indent_level -= 1;
32459 } else {
32460 for expr in &e.expressions {
32461 self.write_space();
32462 self.generate_expression(expr)?;
32463 }
32464 }
32465 if let Some(source) = &e.source {
32466 if self.config.pretty {
32467 self.write_newline();
32468 self.write_indent();
32469 } else {
32470 self.write_space();
32471 }
32472 self.generate_expression(source)?;
32473 }
32474 Ok(())
32475 }
32476
32477 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
32478 self.write_keyword("NEXT VALUE FOR");
32480 self.write_space();
32481 self.generate_expression(&e.this)?;
32482 if let Some(order) = &e.order {
32483 self.write_space();
32484 self.write_keyword("OVER");
32485 self.write(" (");
32486 self.generate_expression(order)?;
32487 self.write(")");
32488 }
32489 Ok(())
32490 }
32491
32492 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
32493 self.write_keyword("NORMAL");
32495 self.write("(");
32496 self.generate_expression(&e.this)?;
32497 if let Some(stddev) = &e.stddev {
32498 self.write(", ");
32499 self.generate_expression(stddev)?;
32500 }
32501 if let Some(gen) = &e.gen {
32502 self.write(", ");
32503 self.generate_expression(gen)?;
32504 }
32505 self.write(")");
32506 Ok(())
32507 }
32508
32509 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
32510 if e.is_casefold.is_some() {
32512 self.write_keyword("NORMALIZE_AND_CASEFOLD");
32513 } else {
32514 self.write_keyword("NORMALIZE");
32515 }
32516 self.write("(");
32517 self.generate_expression(&e.this)?;
32518 if let Some(form) = &e.form {
32519 self.write(", ");
32520 self.generate_expression(form)?;
32521 }
32522 self.write(")");
32523 Ok(())
32524 }
32525
32526 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
32527 if e.allow_null.is_none() {
32529 self.write_keyword("NOT ");
32530 }
32531 self.write_keyword("NULL");
32532 Ok(())
32533 }
32534
32535 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
32536 self.write_keyword("NULLIF");
32538 self.write("(");
32539 self.generate_expression(&e.this)?;
32540 self.write(", ");
32541 self.generate_expression(&e.expression)?;
32542 self.write(")");
32543 Ok(())
32544 }
32545
32546 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
32547 self.write_keyword("FORMAT");
32549 self.write("(");
32550 self.generate_expression(&e.this)?;
32551 self.write(", '");
32552 self.write(&e.format);
32553 self.write("'");
32554 if let Some(culture) = &e.culture {
32555 self.write(", ");
32556 self.generate_expression(culture)?;
32557 }
32558 self.write(")");
32559 Ok(())
32560 }
32561
32562 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
32563 self.write_keyword("OBJECT_AGG");
32565 self.write("(");
32566 self.generate_expression(&e.this)?;
32567 self.write(", ");
32568 self.generate_expression(&e.expression)?;
32569 self.write(")");
32570 Ok(())
32571 }
32572
32573 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
32574 self.generate_expression(&e.this)?;
32576 Ok(())
32577 }
32578
32579 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
32580 self.write_keyword("OBJECT_INSERT");
32582 self.write("(");
32583 self.generate_expression(&e.this)?;
32584 if let Some(key) = &e.key {
32585 self.write(", ");
32586 self.generate_expression(key)?;
32587 }
32588 if let Some(value) = &e.value {
32589 self.write(", ");
32590 self.generate_expression(value)?;
32591 }
32592 if let Some(update_flag) = &e.update_flag {
32593 self.write(", ");
32594 self.generate_expression(update_flag)?;
32595 }
32596 self.write(")");
32597 Ok(())
32598 }
32599
32600 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
32601 self.write_keyword("OFFSET");
32603 self.write_space();
32604 self.generate_expression(&e.this)?;
32605 if e.rows == Some(true)
32607 && matches!(
32608 self.config.dialect,
32609 Some(crate::dialects::DialectType::TSQL)
32610 | Some(crate::dialects::DialectType::Oracle)
32611 )
32612 {
32613 self.write_space();
32614 self.write_keyword("ROWS");
32615 }
32616 Ok(())
32617 }
32618
32619 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
32620 self.write_keyword("QUALIFY");
32622 self.write_space();
32623 self.generate_expression(&e.this)?;
32624 Ok(())
32625 }
32626
32627 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
32628 self.write_keyword("ON CLUSTER");
32630 self.write_space();
32631 self.generate_expression(&e.this)?;
32632 Ok(())
32633 }
32634
32635 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
32636 self.write_keyword("ON COMMIT");
32638 if e.delete.is_some() {
32639 self.write_keyword(" DELETE ROWS");
32640 } else {
32641 self.write_keyword(" PRESERVE ROWS");
32642 }
32643 Ok(())
32644 }
32645
32646 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
32647 if let Some(empty) = &e.empty {
32649 self.generate_expression(empty)?;
32650 self.write_keyword(" ON EMPTY");
32651 }
32652 if let Some(error) = &e.error {
32653 if e.empty.is_some() {
32654 self.write_space();
32655 }
32656 self.generate_expression(error)?;
32657 self.write_keyword(" ON ERROR");
32658 }
32659 if let Some(null) = &e.null {
32660 if e.empty.is_some() || e.error.is_some() {
32661 self.write_space();
32662 }
32663 self.generate_expression(null)?;
32664 self.write_keyword(" ON NULL");
32665 }
32666 Ok(())
32667 }
32668
32669 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
32670 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
32672 return Ok(());
32673 }
32674 if e.duplicate.is_some() {
32676 self.write_keyword("ON DUPLICATE KEY UPDATE");
32678 for (i, expr) in e.expressions.iter().enumerate() {
32679 if i > 0 {
32680 self.write(",");
32681 }
32682 self.write_space();
32683 self.generate_expression(expr)?;
32684 }
32685 return Ok(());
32686 } else {
32687 self.write_keyword("ON CONFLICT");
32688 }
32689 if let Some(constraint) = &e.constraint {
32690 self.write_keyword(" ON CONSTRAINT ");
32691 self.generate_expression(constraint)?;
32692 }
32693 if let Some(conflict_keys) = &e.conflict_keys {
32694 if let Expression::Tuple(t) = conflict_keys.as_ref() {
32696 self.write("(");
32697 for (i, expr) in t.expressions.iter().enumerate() {
32698 if i > 0 {
32699 self.write(", ");
32700 }
32701 self.generate_expression(expr)?;
32702 }
32703 self.write(")");
32704 } else {
32705 self.write("(");
32706 self.generate_expression(conflict_keys)?;
32707 self.write(")");
32708 }
32709 }
32710 if let Some(index_predicate) = &e.index_predicate {
32711 self.write_keyword(" WHERE ");
32712 self.generate_expression(index_predicate)?;
32713 }
32714 if let Some(action) = &e.action {
32715 if let Expression::Identifier(id) = action.as_ref() {
32717 if id.name.eq_ignore_ascii_case("NOTHING") {
32718 self.write_keyword(" DO NOTHING");
32719 } else {
32720 self.write_keyword(" DO ");
32721 self.generate_expression(action)?;
32722 }
32723 } else if let Expression::Tuple(t) = action.as_ref() {
32724 self.write_keyword(" DO UPDATE SET ");
32726 for (i, expr) in t.expressions.iter().enumerate() {
32727 if i > 0 {
32728 self.write(", ");
32729 }
32730 self.generate_expression(expr)?;
32731 }
32732 } else {
32733 self.write_keyword(" DO ");
32734 self.generate_expression(action)?;
32735 }
32736 }
32737 if let Some(where_) = &e.where_ {
32739 self.write_keyword(" WHERE ");
32740 self.generate_expression(where_)?;
32741 }
32742 Ok(())
32743 }
32744
32745 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
32746 self.write_keyword("ON");
32748 self.write_space();
32749 self.generate_expression(&e.this)?;
32750 Ok(())
32751 }
32752
32753 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
32754 self.generate_expression(&e.this)?;
32756 self.write_space();
32757 self.generate_expression(&e.expression)?;
32758 Ok(())
32759 }
32760
32761 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
32762 self.write_keyword("OPENJSON");
32764 self.write("(");
32765 self.generate_expression(&e.this)?;
32766 if let Some(path) = &e.path {
32767 self.write(", ");
32768 self.generate_expression(path)?;
32769 }
32770 self.write(")");
32771 if !e.expressions.is_empty() {
32772 self.write_keyword(" WITH");
32773 if self.config.pretty {
32774 self.write(" (\n");
32775 self.indent_level += 2;
32776 for (i, expr) in e.expressions.iter().enumerate() {
32777 if i > 0 {
32778 self.write(",\n");
32779 }
32780 self.write_indent();
32781 self.generate_expression(expr)?;
32782 }
32783 self.write("\n");
32784 self.indent_level -= 2;
32785 self.write(")");
32786 } else {
32787 self.write(" (");
32788 for (i, expr) in e.expressions.iter().enumerate() {
32789 if i > 0 {
32790 self.write(", ");
32791 }
32792 self.generate_expression(expr)?;
32793 }
32794 self.write(")");
32795 }
32796 }
32797 Ok(())
32798 }
32799
32800 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
32801 self.generate_expression(&e.this)?;
32803 self.write_space();
32804 if let Some(ref dt) = e.data_type {
32806 self.generate_data_type(dt)?;
32807 } else if !e.kind.is_empty() {
32808 self.write(&e.kind);
32809 }
32810 if let Some(path) = &e.path {
32811 self.write_space();
32812 self.generate_expression(path)?;
32813 }
32814 if e.as_json.is_some() {
32815 self.write_keyword(" AS JSON");
32816 }
32817 Ok(())
32818 }
32819
32820 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
32821 self.generate_expression(&e.this)?;
32823 self.write_space();
32824 if let Some(op) = &e.operator {
32825 self.write_keyword("OPERATOR");
32826 self.write("(");
32827 self.generate_expression(op)?;
32828 self.write(")");
32829 }
32830 for comment in &e.comments {
32832 self.write_space();
32833 self.write_formatted_comment(comment);
32834 }
32835 self.write_space();
32836 self.generate_expression(&e.expression)?;
32837 Ok(())
32838 }
32839
32840 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
32841 self.write_keyword("ORDER BY");
32843 let pretty_clickhouse_single_paren = self.config.pretty
32844 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
32845 && e.expressions.len() == 1
32846 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
32847 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
32848 && e.expressions.len() == 1
32849 && matches!(e.expressions[0].this, Expression::Tuple(_))
32850 && !e.expressions[0].desc
32851 && e.expressions[0].nulls_first.is_none();
32852
32853 if pretty_clickhouse_single_paren {
32854 self.write_space();
32855 if let Expression::Paren(p) = &e.expressions[0].this {
32856 self.write("(");
32857 self.write_newline();
32858 self.indent_level += 1;
32859 self.write_indent();
32860 self.generate_expression(&p.this)?;
32861 self.indent_level -= 1;
32862 self.write_newline();
32863 self.write(")");
32864 }
32865 return Ok(());
32866 }
32867
32868 if clickhouse_single_tuple {
32869 self.write_space();
32870 if let Expression::Tuple(t) = &e.expressions[0].this {
32871 self.write("(");
32872 for (i, expr) in t.expressions.iter().enumerate() {
32873 if i > 0 {
32874 self.write(", ");
32875 }
32876 self.generate_expression(expr)?;
32877 }
32878 self.write(")");
32879 }
32880 return Ok(());
32881 }
32882
32883 self.write_space();
32884 for (i, ordered) in e.expressions.iter().enumerate() {
32885 if i > 0 {
32886 self.write(", ");
32887 }
32888 self.generate_expression(&ordered.this)?;
32889 if ordered.desc {
32890 self.write_space();
32891 self.write_keyword("DESC");
32892 } else if ordered.explicit_asc {
32893 self.write_space();
32894 self.write_keyword("ASC");
32895 }
32896 if let Some(nulls_first) = ordered.nulls_first {
32897 let skip_nulls_last =
32899 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
32900 if !skip_nulls_last {
32901 self.write_space();
32902 self.write_keyword("NULLS");
32903 self.write_space();
32904 if nulls_first {
32905 self.write_keyword("FIRST");
32906 } else {
32907 self.write_keyword("LAST");
32908 }
32909 }
32910 }
32911 }
32912 Ok(())
32913 }
32914
32915 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
32916 self.write_keyword("OUTPUT");
32918 self.write("(");
32919 if self.config.pretty {
32920 self.indent_level += 1;
32921 self.write_newline();
32922 self.write_indent();
32923 self.generate_expression(&e.this)?;
32924 self.indent_level -= 1;
32925 self.write_newline();
32926 } else {
32927 self.generate_expression(&e.this)?;
32928 }
32929 self.write(")");
32930 Ok(())
32931 }
32932
32933 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
32934 self.write_keyword("TRUNCATE");
32936 if let Some(this) = &e.this {
32937 self.write_space();
32938 self.generate_expression(this)?;
32939 }
32940 if e.with_count.is_some() {
32941 self.write_keyword(" WITH COUNT");
32942 } else {
32943 self.write_keyword(" WITHOUT COUNT");
32944 }
32945 Ok(())
32946 }
32947
32948 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
32949 self.generate_expression(&e.this)?;
32951 self.write("(");
32952 for (i, expr) in e.expressions.iter().enumerate() {
32953 if i > 0 {
32954 self.write(", ");
32955 }
32956 self.generate_expression(expr)?;
32957 }
32958 self.write(")(");
32959 for (i, param) in e.params.iter().enumerate() {
32960 if i > 0 {
32961 self.write(", ");
32962 }
32963 self.generate_expression(param)?;
32964 }
32965 self.write(")");
32966 Ok(())
32967 }
32968
32969 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
32970 self.write_keyword("PARSE_DATETIME");
32972 self.write("(");
32973 if let Some(format) = &e.format {
32974 self.write("'");
32975 self.write(format);
32976 self.write("', ");
32977 }
32978 self.generate_expression(&e.this)?;
32979 if let Some(zone) = &e.zone {
32980 self.write(", ");
32981 self.generate_expression(zone)?;
32982 }
32983 self.write(")");
32984 Ok(())
32985 }
32986
32987 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
32988 self.write_keyword("PARSE_IP");
32990 self.write("(");
32991 self.generate_expression(&e.this)?;
32992 if let Some(type_) = &e.type_ {
32993 self.write(", ");
32994 self.generate_expression(type_)?;
32995 }
32996 if let Some(permissive) = &e.permissive {
32997 self.write(", ");
32998 self.generate_expression(permissive)?;
32999 }
33000 self.write(")");
33001 Ok(())
33002 }
33003
33004 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
33005 self.write_keyword("PARSE_JSON");
33007 self.write("(");
33008 self.generate_expression(&e.this)?;
33009 if let Some(expression) = &e.expression {
33010 self.write(", ");
33011 self.generate_expression(expression)?;
33012 }
33013 self.write(")");
33014 Ok(())
33015 }
33016
33017 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
33018 self.write_keyword("PARSE_TIME");
33020 self.write("(");
33021 self.write(&format!("'{}'", e.format));
33022 self.write(", ");
33023 self.generate_expression(&e.this)?;
33024 self.write(")");
33025 Ok(())
33026 }
33027
33028 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
33029 self.write_keyword("PARSE_URL");
33031 self.write("(");
33032 self.generate_expression(&e.this)?;
33033 if let Some(part) = &e.part_to_extract {
33034 self.write(", ");
33035 self.generate_expression(part)?;
33036 }
33037 if let Some(key) = &e.key {
33038 self.write(", ");
33039 self.generate_expression(key)?;
33040 }
33041 if let Some(permissive) = &e.permissive {
33042 self.write(", ");
33043 self.generate_expression(permissive)?;
33044 }
33045 self.write(")");
33046 Ok(())
33047 }
33048
33049 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
33050 if e.subpartition {
33052 self.write_keyword("SUBPARTITION");
33053 } else {
33054 self.write_keyword("PARTITION");
33055 }
33056 self.write("(");
33057 for (i, expr) in e.expressions.iter().enumerate() {
33058 if i > 0 {
33059 self.write(", ");
33060 }
33061 self.generate_expression(expr)?;
33062 }
33063 self.write(")");
33064 Ok(())
33065 }
33066
33067 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
33068 if let Some(this) = &e.this {
33070 if let Some(expression) = &e.expression {
33071 self.write_keyword("WITH");
33073 self.write(" (");
33074 self.write_keyword("MODULUS");
33075 self.write_space();
33076 self.generate_expression(this)?;
33077 self.write(", ");
33078 self.write_keyword("REMAINDER");
33079 self.write_space();
33080 self.generate_expression(expression)?;
33081 self.write(")");
33082 } else {
33083 self.write_keyword("IN");
33085 self.write(" (");
33086 self.generate_partition_bound_values(this)?;
33087 self.write(")");
33088 }
33089 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
33090 self.write_keyword("FROM");
33092 self.write(" (");
33093 self.generate_partition_bound_values(from)?;
33094 self.write(") ");
33095 self.write_keyword("TO");
33096 self.write(" (");
33097 self.generate_partition_bound_values(to)?;
33098 self.write(")");
33099 }
33100 Ok(())
33101 }
33102
33103 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
33106 if let Expression::Tuple(t) = expr {
33107 for (i, e) in t.expressions.iter().enumerate() {
33108 if i > 0 {
33109 self.write(", ");
33110 }
33111 self.generate_expression(e)?;
33112 }
33113 Ok(())
33114 } else {
33115 self.generate_expression(expr)
33116 }
33117 }
33118
33119 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
33120 self.write_keyword("PARTITION BY LIST");
33122 if let Some(partition_exprs) = &e.partition_expressions {
33123 self.write(" (");
33124 self.generate_doris_partition_expressions(partition_exprs)?;
33126 self.write(")");
33127 }
33128 if let Some(create_exprs) = &e.create_expressions {
33129 self.write(" (");
33130 self.generate_doris_partition_definitions(create_exprs)?;
33132 self.write(")");
33133 }
33134 Ok(())
33135 }
33136
33137 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
33138 self.write_keyword("PARTITION BY RANGE");
33140 if let Some(partition_exprs) = &e.partition_expressions {
33141 self.write(" (");
33142 self.generate_doris_partition_expressions(partition_exprs)?;
33144 self.write(")");
33145 }
33146 if let Some(create_exprs) = &e.create_expressions {
33147 self.write(" (");
33148 self.generate_doris_partition_definitions(create_exprs)?;
33150 self.write(")");
33151 }
33152 Ok(())
33153 }
33154
33155 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
33157 if let Expression::Tuple(t) = expr {
33158 for (i, e) in t.expressions.iter().enumerate() {
33159 if i > 0 {
33160 self.write(", ");
33161 }
33162 self.generate_expression(e)?;
33163 }
33164 } else {
33165 self.generate_expression(expr)?;
33166 }
33167 Ok(())
33168 }
33169
33170 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
33172 match expr {
33173 Expression::Tuple(t) => {
33174 for (i, part) in t.expressions.iter().enumerate() {
33176 if i > 0 {
33177 self.write(", ");
33178 }
33179 if let Expression::Partition(p) = part {
33181 for (j, inner) in p.expressions.iter().enumerate() {
33182 if j > 0 {
33183 self.write(", ");
33184 }
33185 self.generate_expression(inner)?;
33186 }
33187 } else {
33188 self.generate_expression(part)?;
33189 }
33190 }
33191 }
33192 Expression::PartitionByRangePropertyDynamic(_) => {
33193 self.generate_expression(expr)?;
33195 }
33196 _ => {
33197 self.generate_expression(expr)?;
33198 }
33199 }
33200 Ok(())
33201 }
33202
33203 fn generate_partition_by_range_property_dynamic(
33204 &mut self,
33205 e: &PartitionByRangePropertyDynamic,
33206 ) -> Result<()> {
33207 if e.use_start_end {
33208 if let Some(start) = &e.start {
33210 self.write_keyword("START");
33211 self.write(" (");
33212 self.generate_expression(start)?;
33213 self.write(")");
33214 }
33215 if let Some(end) = &e.end {
33216 self.write_space();
33217 self.write_keyword("END");
33218 self.write(" (");
33219 self.generate_expression(end)?;
33220 self.write(")");
33221 }
33222 if let Some(every) = &e.every {
33223 self.write_space();
33224 self.write_keyword("EVERY");
33225 self.write(" (");
33226 self.generate_doris_interval(every)?;
33228 self.write(")");
33229 }
33230 } else {
33231 if let Some(start) = &e.start {
33233 self.write_keyword("FROM");
33234 self.write(" (");
33235 self.generate_expression(start)?;
33236 self.write(")");
33237 }
33238 if let Some(end) = &e.end {
33239 self.write_space();
33240 self.write_keyword("TO");
33241 self.write(" (");
33242 self.generate_expression(end)?;
33243 self.write(")");
33244 }
33245 if let Some(every) = &e.every {
33246 self.write_space();
33247 self.generate_doris_interval(every)?;
33249 }
33250 }
33251 Ok(())
33252 }
33253
33254 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
33256 if let Expression::Interval(interval) = expr {
33257 self.write_keyword("INTERVAL");
33258 if let Some(ref value) = interval.this {
33259 self.write_space();
33260 match value {
33264 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()) => {
33265 if let Literal::String(s) = lit.as_ref() {
33266 self.write(s);
33267 }
33268 }
33269 _ => {
33270 self.generate_expression(value)?;
33271 }
33272 }
33273 }
33274 if let Some(ref unit_spec) = interval.unit {
33275 self.write_space();
33276 self.write_interval_unit_spec(unit_spec)?;
33277 }
33278 Ok(())
33279 } else {
33280 self.generate_expression(expr)
33281 }
33282 }
33283
33284 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
33285 self.write_keyword("TRUNCATE");
33287 self.write("(");
33288 self.generate_expression(&e.expression)?;
33289 self.write(", ");
33290 self.generate_expression(&e.this)?;
33291 self.write(")");
33292 Ok(())
33293 }
33294
33295 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
33296 self.write_keyword("PARTITION");
33298 self.write_space();
33299 self.generate_expression(&e.this)?;
33300 self.write_space();
33301 self.write_keyword("VALUES IN");
33302 self.write(" (");
33303 for (i, expr) in e.expressions.iter().enumerate() {
33304 if i > 0 {
33305 self.write(", ");
33306 }
33307 self.generate_expression(expr)?;
33308 }
33309 self.write(")");
33310 Ok(())
33311 }
33312
33313 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
33314 if e.expressions.is_empty() && e.expression.is_some() {
33317 self.generate_expression(&e.this)?;
33319 self.write_space();
33320 self.write_keyword("TO");
33321 self.write_space();
33322 self.generate_expression(e.expression.as_ref().unwrap())?;
33323 return Ok(());
33324 }
33325
33326 self.write_keyword("PARTITION");
33328 self.write_space();
33329 self.generate_expression(&e.this)?;
33330 self.write_space();
33331
33332 if e.expressions.len() == 1 {
33334 self.write_keyword("VALUES LESS THAN");
33336 self.write(" (");
33337 self.generate_expression(&e.expressions[0])?;
33338 self.write(")");
33339 } else if !e.expressions.is_empty() {
33340 self.write_keyword("VALUES");
33342 self.write(" [");
33343 for (i, expr) in e.expressions.iter().enumerate() {
33344 if i > 0 {
33345 self.write(", ");
33346 }
33347 if let Expression::Tuple(t) = expr {
33349 self.write("(");
33350 for (j, inner) in t.expressions.iter().enumerate() {
33351 if j > 0 {
33352 self.write(", ");
33353 }
33354 self.generate_expression(inner)?;
33355 }
33356 self.write(")");
33357 } else {
33358 self.write("(");
33359 self.generate_expression(expr)?;
33360 self.write(")");
33361 }
33362 }
33363 self.write(")");
33364 }
33365 Ok(())
33366 }
33367
33368 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
33369 self.write_keyword("BUCKET");
33371 self.write("(");
33372 self.generate_expression(&e.this)?;
33373 self.write(", ");
33374 self.generate_expression(&e.expression)?;
33375 self.write(")");
33376 Ok(())
33377 }
33378
33379 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
33380 self.write_keyword("PARTITION BY");
33382 self.write_space();
33383 for (i, expr) in e.expressions.iter().enumerate() {
33384 if i > 0 {
33385 self.write(", ");
33386 }
33387 self.generate_expression(expr)?;
33388 }
33389 Ok(())
33390 }
33391
33392 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
33393 if matches!(
33395 self.config.dialect,
33396 Some(crate::dialects::DialectType::Teradata)
33397 | Some(crate::dialects::DialectType::ClickHouse)
33398 ) {
33399 self.write_keyword("PARTITION BY");
33400 } else {
33401 self.write_keyword("PARTITIONED BY");
33402 }
33403 self.write_space();
33404 if self.config.pretty {
33406 if let Expression::Tuple(ref tuple) = *e.this {
33407 self.write("(");
33408 self.write_newline();
33409 self.indent_level += 1;
33410 for (i, expr) in tuple.expressions.iter().enumerate() {
33411 if i > 0 {
33412 self.write(",");
33413 self.write_newline();
33414 }
33415 self.write_indent();
33416 self.generate_expression(expr)?;
33417 }
33418 self.indent_level -= 1;
33419 self.write_newline();
33420 self.write(")");
33421 } else {
33422 self.generate_expression(&e.this)?;
33423 }
33424 } else {
33425 self.generate_expression(&e.this)?;
33426 }
33427 Ok(())
33428 }
33429
33430 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
33431 self.write_keyword("PARTITION OF");
33433 self.write_space();
33434 self.generate_expression(&e.this)?;
33435 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
33437 self.write_space();
33438 self.write_keyword("FOR VALUES");
33439 self.write_space();
33440 self.generate_expression(&e.expression)?;
33441 } else {
33442 self.write_space();
33443 self.write_keyword("DEFAULT");
33444 }
33445 Ok(())
33446 }
33447
33448 fn generate_period_for_system_time_constraint(
33449 &mut self,
33450 e: &PeriodForSystemTimeConstraint,
33451 ) -> Result<()> {
33452 self.write_keyword("PERIOD FOR SYSTEM_TIME");
33454 self.write(" (");
33455 self.generate_expression(&e.this)?;
33456 self.write(", ");
33457 self.generate_expression(&e.expression)?;
33458 self.write(")");
33459 Ok(())
33460 }
33461
33462 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
33463 self.generate_expression(&e.this)?;
33466 self.write_space();
33467 self.write_keyword("AS");
33468 self.write_space();
33469 if self.config.unpivot_aliases_are_identifiers {
33471 match &e.alias {
33472 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
33473 let Literal::String(s) = lit.as_ref() else {
33474 unreachable!()
33475 };
33476 self.generate_identifier(&Identifier::new(s.clone()))?;
33478 }
33479 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
33480 let Literal::Number(n) = lit.as_ref() else {
33481 unreachable!()
33482 };
33483 let mut id = Identifier::new(n.clone());
33485 id.quoted = true;
33486 self.generate_identifier(&id)?;
33487 }
33488 other => {
33489 self.generate_expression(other)?;
33490 }
33491 }
33492 } else {
33493 self.generate_expression(&e.alias)?;
33494 }
33495 Ok(())
33496 }
33497
33498 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
33499 self.write_keyword("ANY");
33501 if let Some(this) = &e.this {
33502 self.write_space();
33503 self.generate_expression(this)?;
33504 }
33505 Ok(())
33506 }
33507
33508 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
33509 self.write_keyword("ML.PREDICT");
33511 self.write("(");
33512 self.write_keyword("MODEL");
33513 self.write_space();
33514 self.generate_expression(&e.this)?;
33515 self.write(", ");
33516 self.generate_expression(&e.expression)?;
33517 if let Some(params) = &e.params_struct {
33518 self.write(", ");
33519 self.generate_expression(params)?;
33520 }
33521 self.write(")");
33522 Ok(())
33523 }
33524
33525 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
33526 self.write_keyword("PREVIOUS_DAY");
33528 self.write("(");
33529 self.generate_expression(&e.this)?;
33530 self.write(", ");
33531 self.generate_expression(&e.expression)?;
33532 self.write(")");
33533 Ok(())
33534 }
33535
33536 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
33537 self.write_keyword("PRIMARY KEY");
33539 if let Some(name) = &e.this {
33540 self.write_space();
33541 self.generate_expression(name)?;
33542 }
33543 if !e.expressions.is_empty() {
33544 self.write(" (");
33545 for (i, expr) in e.expressions.iter().enumerate() {
33546 if i > 0 {
33547 self.write(", ");
33548 }
33549 self.generate_expression(expr)?;
33550 }
33551 self.write(")");
33552 }
33553 if let Some(include) = &e.include {
33554 self.write_space();
33555 self.generate_expression(include)?;
33556 }
33557 if !e.options.is_empty() {
33558 self.write_space();
33559 for (i, opt) in e.options.iter().enumerate() {
33560 if i > 0 {
33561 self.write_space();
33562 }
33563 self.generate_expression(opt)?;
33564 }
33565 }
33566 Ok(())
33567 }
33568
33569 fn generate_primary_key_column_constraint(
33570 &mut self,
33571 _e: &PrimaryKeyColumnConstraint,
33572 ) -> Result<()> {
33573 self.write_keyword("PRIMARY KEY");
33575 Ok(())
33576 }
33577
33578 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
33579 self.write_keyword("PATH");
33581 self.write_space();
33582 self.generate_expression(&e.this)?;
33583 Ok(())
33584 }
33585
33586 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
33587 self.write_keyword("PROJECTION");
33589 self.write_space();
33590 self.generate_expression(&e.this)?;
33591 self.write(" (");
33592 self.generate_expression(&e.expression)?;
33593 self.write(")");
33594 Ok(())
33595 }
33596
33597 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
33598 for (i, prop) in e.expressions.iter().enumerate() {
33600 if i > 0 {
33601 self.write(", ");
33602 }
33603 self.generate_expression(prop)?;
33604 }
33605 Ok(())
33606 }
33607
33608 fn generate_property(&mut self, e: &Property) -> Result<()> {
33609 self.generate_expression(&e.this)?;
33611 if let Some(value) = &e.value {
33612 self.write("=");
33613 self.generate_expression(value)?;
33614 }
33615 Ok(())
33616 }
33617
33618 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
33619 self.write_keyword("OPTIONS");
33620 if e.entries.is_empty() {
33621 self.write(" ()");
33622 return Ok(());
33623 }
33624
33625 if self.config.pretty {
33626 self.write(" (");
33627 self.write_newline();
33628 self.indent_level += 1;
33629 for (i, entry) in e.entries.iter().enumerate() {
33630 if i > 0 {
33631 self.write(",");
33632 self.write_newline();
33633 }
33634 self.write_indent();
33635 self.generate_identifier(&entry.key)?;
33636 self.write("=");
33637 self.generate_expression(&entry.value)?;
33638 }
33639 self.indent_level -= 1;
33640 self.write_newline();
33641 self.write(")");
33642 } else {
33643 self.write(" (");
33644 for (i, entry) in e.entries.iter().enumerate() {
33645 if i > 0 {
33646 self.write(", ");
33647 }
33648 self.generate_identifier(&entry.key)?;
33649 self.write("=");
33650 self.generate_expression(&entry.value)?;
33651 }
33652 self.write(")");
33653 }
33654 Ok(())
33655 }
33656
33657 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
33659 self.write_keyword("OPTIONS");
33660 self.write(" (");
33661 for (i, opt) in options.iter().enumerate() {
33662 if i > 0 {
33663 self.write(", ");
33664 }
33665 self.generate_option_expression(opt)?;
33666 }
33667 self.write(")");
33668 Ok(())
33669 }
33670
33671 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
33673 self.write_keyword("PROPERTIES");
33674 self.write(" (");
33675 for (i, prop) in properties.iter().enumerate() {
33676 if i > 0 {
33677 self.write(", ");
33678 }
33679 self.generate_option_expression(prop)?;
33680 }
33681 self.write(")");
33682 Ok(())
33683 }
33684
33685 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
33687 self.write_keyword("ENVIRONMENT");
33688 self.write(" (");
33689 for (i, env_item) in environment.iter().enumerate() {
33690 if i > 0 {
33691 self.write(", ");
33692 }
33693 self.generate_environment_expression(env_item)?;
33694 }
33695 self.write(")");
33696 Ok(())
33697 }
33698
33699 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
33701 match expr {
33702 Expression::Eq(eq) => {
33703 self.generate_expression(&eq.left)?;
33705 self.write(" = ");
33706 self.generate_expression(&eq.right)?;
33707 Ok(())
33708 }
33709 _ => self.generate_expression(expr),
33710 }
33711 }
33712
33713 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
33715 self.write_keyword("TBLPROPERTIES");
33716 if self.config.pretty {
33717 self.write(" (");
33718 self.write_newline();
33719 self.indent_level += 1;
33720 for (i, opt) in options.iter().enumerate() {
33721 if i > 0 {
33722 self.write(",");
33723 self.write_newline();
33724 }
33725 self.write_indent();
33726 self.generate_option_expression(opt)?;
33727 }
33728 self.indent_level -= 1;
33729 self.write_newline();
33730 self.write(")");
33731 } else {
33732 self.write(" (");
33733 for (i, opt) in options.iter().enumerate() {
33734 if i > 0 {
33735 self.write(", ");
33736 }
33737 self.generate_option_expression(opt)?;
33738 }
33739 self.write(")");
33740 }
33741 Ok(())
33742 }
33743
33744 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
33746 match expr {
33747 Expression::Eq(eq) => {
33748 self.generate_expression(&eq.left)?;
33750 self.write("=");
33751 self.generate_expression(&eq.right)?;
33752 Ok(())
33753 }
33754 _ => self.generate_expression(expr),
33755 }
33756 }
33757
33758 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
33759 self.generate_expression(&e.this)?;
33761 Ok(())
33762 }
33763
33764 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
33765 self.write_keyword("PUT");
33767 self.write_space();
33768
33769 if e.source_quoted {
33771 self.write("'");
33772 self.write(&e.source);
33773 self.write("'");
33774 } else {
33775 self.write(&e.source);
33776 }
33777
33778 self.write_space();
33779
33780 if let Expression::Literal(lit) = &e.target {
33782 if let Literal::String(s) = lit.as_ref() {
33783 self.write(s);
33784 }
33785 } else {
33786 self.generate_expression(&e.target)?;
33787 }
33788
33789 for param in &e.params {
33791 self.write_space();
33792 self.write(¶m.name);
33793 if let Some(ref value) = param.value {
33794 self.write("=");
33795 self.generate_expression(value)?;
33796 }
33797 }
33798
33799 Ok(())
33800 }
33801
33802 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
33803 self.write_keyword("QUANTILE");
33805 self.write("(");
33806 self.generate_expression(&e.this)?;
33807 if let Some(quantile) = &e.quantile {
33808 self.write(", ");
33809 self.generate_expression(quantile)?;
33810 }
33811 self.write(")");
33812 Ok(())
33813 }
33814
33815 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
33816 if matches!(
33818 self.config.dialect,
33819 Some(crate::dialects::DialectType::Teradata)
33820 ) {
33821 self.write_keyword("SET");
33822 self.write_space();
33823 }
33824 self.write_keyword("QUERY_BAND");
33825 self.write(" = ");
33826 self.generate_expression(&e.this)?;
33827 if e.update.is_some() {
33828 self.write_space();
33829 self.write_keyword("UPDATE");
33830 }
33831 if let Some(scope) = &e.scope {
33832 self.write_space();
33833 self.write_keyword("FOR");
33834 self.write_space();
33835 self.generate_expression(scope)?;
33836 }
33837 Ok(())
33838 }
33839
33840 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
33841 self.generate_expression(&e.this)?;
33843 if let Some(expression) = &e.expression {
33844 self.write(" = ");
33845 self.generate_expression(expression)?;
33846 }
33847 Ok(())
33848 }
33849
33850 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
33851 self.write_keyword("TRANSFORM");
33853 self.write("(");
33854 for (i, expr) in e.expressions.iter().enumerate() {
33855 if i > 0 {
33856 self.write(", ");
33857 }
33858 self.generate_expression(expr)?;
33859 }
33860 self.write(")");
33861 if let Some(row_format_before) = &e.row_format_before {
33862 self.write_space();
33863 self.generate_expression(row_format_before)?;
33864 }
33865 if let Some(record_writer) = &e.record_writer {
33866 self.write_space();
33867 self.write_keyword("RECORDWRITER");
33868 self.write_space();
33869 self.generate_expression(record_writer)?;
33870 }
33871 if let Some(command_script) = &e.command_script {
33872 self.write_space();
33873 self.write_keyword("USING");
33874 self.write_space();
33875 self.generate_expression(command_script)?;
33876 }
33877 if let Some(schema) = &e.schema {
33878 self.write_space();
33879 self.write_keyword("AS");
33880 self.write_space();
33881 self.generate_expression(schema)?;
33882 }
33883 if let Some(row_format_after) = &e.row_format_after {
33884 self.write_space();
33885 self.generate_expression(row_format_after)?;
33886 }
33887 if let Some(record_reader) = &e.record_reader {
33888 self.write_space();
33889 self.write_keyword("RECORDREADER");
33890 self.write_space();
33891 self.generate_expression(record_reader)?;
33892 }
33893 Ok(())
33894 }
33895
33896 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
33897 self.write_keyword("RANDN");
33899 self.write("(");
33900 if let Some(this) = &e.this {
33901 self.generate_expression(this)?;
33902 }
33903 self.write(")");
33904 Ok(())
33905 }
33906
33907 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
33908 self.write_keyword("RANDSTR");
33910 self.write("(");
33911 self.generate_expression(&e.this)?;
33912 if let Some(generator) = &e.generator {
33913 self.write(", ");
33914 self.generate_expression(generator)?;
33915 }
33916 self.write(")");
33917 Ok(())
33918 }
33919
33920 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
33921 self.write_keyword("RANGE_BUCKET");
33923 self.write("(");
33924 self.generate_expression(&e.this)?;
33925 self.write(", ");
33926 self.generate_expression(&e.expression)?;
33927 self.write(")");
33928 Ok(())
33929 }
33930
33931 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
33932 self.write_keyword("RANGE_N");
33934 self.write("(");
33935 self.generate_expression(&e.this)?;
33936 self.write_space();
33937 self.write_keyword("BETWEEN");
33938 self.write_space();
33939 for (i, expr) in e.expressions.iter().enumerate() {
33940 if i > 0 {
33941 self.write(", ");
33942 }
33943 self.generate_expression(expr)?;
33944 }
33945 if let Some(each) = &e.each {
33946 self.write_space();
33947 self.write_keyword("EACH");
33948 self.write_space();
33949 self.generate_expression(each)?;
33950 }
33951 self.write(")");
33952 Ok(())
33953 }
33954
33955 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
33956 self.write_keyword("READ_CSV");
33958 self.write("(");
33959 self.generate_expression(&e.this)?;
33960 for expr in &e.expressions {
33961 self.write(", ");
33962 self.generate_expression(expr)?;
33963 }
33964 self.write(")");
33965 Ok(())
33966 }
33967
33968 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
33969 self.write_keyword("READ_PARQUET");
33971 self.write("(");
33972 for (i, expr) in e.expressions.iter().enumerate() {
33973 if i > 0 {
33974 self.write(", ");
33975 }
33976 self.generate_expression(expr)?;
33977 }
33978 self.write(")");
33979 Ok(())
33980 }
33981
33982 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
33983 if e.kind == "CYCLE" {
33986 self.write_keyword("CYCLE");
33987 } else {
33988 self.write_keyword("SEARCH");
33989 self.write_space();
33990 self.write(&e.kind);
33991 self.write_space();
33992 self.write_keyword("FIRST BY");
33993 }
33994 self.write_space();
33995 self.generate_expression(&e.this)?;
33996 self.write_space();
33997 self.write_keyword("SET");
33998 self.write_space();
33999 self.generate_expression(&e.expression)?;
34000 if let Some(using) = &e.using {
34001 self.write_space();
34002 self.write_keyword("USING");
34003 self.write_space();
34004 self.generate_expression(using)?;
34005 }
34006 Ok(())
34007 }
34008
34009 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
34010 self.write_keyword("REDUCE");
34012 self.write("(");
34013 self.generate_expression(&e.this)?;
34014 if let Some(initial) = &e.initial {
34015 self.write(", ");
34016 self.generate_expression(initial)?;
34017 }
34018 if let Some(merge) = &e.merge {
34019 self.write(", ");
34020 self.generate_expression(merge)?;
34021 }
34022 if let Some(finish) = &e.finish {
34023 self.write(", ");
34024 self.generate_expression(finish)?;
34025 }
34026 self.write(")");
34027 Ok(())
34028 }
34029
34030 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
34031 self.write_keyword("REFERENCES");
34033 self.write_space();
34034 self.generate_expression(&e.this)?;
34035 if !e.expressions.is_empty() {
34036 self.write(" (");
34037 for (i, expr) in e.expressions.iter().enumerate() {
34038 if i > 0 {
34039 self.write(", ");
34040 }
34041 self.generate_expression(expr)?;
34042 }
34043 self.write(")");
34044 }
34045 for opt in &e.options {
34046 self.write_space();
34047 self.generate_expression(opt)?;
34048 }
34049 Ok(())
34050 }
34051
34052 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
34053 self.write_keyword("REFRESH");
34055 if !e.kind.is_empty() {
34056 self.write_space();
34057 self.write_keyword(&e.kind);
34058 }
34059 self.write_space();
34060 self.generate_expression(&e.this)?;
34061 Ok(())
34062 }
34063
34064 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
34065 self.write_keyword("REFRESH");
34067 self.write_space();
34068 self.write_keyword(&e.method);
34069
34070 if let Some(ref kind) = e.kind {
34071 self.write_space();
34072 self.write_keyword("ON");
34073 self.write_space();
34074 self.write_keyword(kind);
34075
34076 if let Some(ref every) = e.every {
34078 self.write_space();
34079 self.write_keyword("EVERY");
34080 self.write_space();
34081 self.generate_expression(every)?;
34082 if let Some(ref unit) = e.unit {
34083 self.write_space();
34084 self.write_keyword(unit);
34085 }
34086 }
34087
34088 if let Some(ref starts) = e.starts {
34090 self.write_space();
34091 self.write_keyword("STARTS");
34092 self.write_space();
34093 self.generate_expression(starts)?;
34094 }
34095 }
34096 Ok(())
34097 }
34098
34099 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
34100 self.write_keyword("REGEXP_COUNT");
34102 self.write("(");
34103 self.generate_expression(&e.this)?;
34104 self.write(", ");
34105 self.generate_expression(&e.expression)?;
34106 if let Some(position) = &e.position {
34107 self.write(", ");
34108 self.generate_expression(position)?;
34109 }
34110 if let Some(parameters) = &e.parameters {
34111 self.write(", ");
34112 self.generate_expression(parameters)?;
34113 }
34114 self.write(")");
34115 Ok(())
34116 }
34117
34118 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
34119 self.write_keyword("REGEXP_EXTRACT_ALL");
34121 self.write("(");
34122 self.generate_expression(&e.this)?;
34123 self.write(", ");
34124 self.generate_expression(&e.expression)?;
34125 if let Some(group) = &e.group {
34126 self.write(", ");
34127 self.generate_expression(group)?;
34128 }
34129 self.write(")");
34130 Ok(())
34131 }
34132
34133 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
34134 self.write_keyword("REGEXP_FULL_MATCH");
34136 self.write("(");
34137 self.generate_expression(&e.this)?;
34138 self.write(", ");
34139 self.generate_expression(&e.expression)?;
34140 self.write(")");
34141 Ok(())
34142 }
34143
34144 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
34145 use crate::dialects::DialectType;
34146 if matches!(
34148 self.config.dialect,
34149 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
34150 ) && e.flag.is_none()
34151 {
34152 self.generate_expression(&e.this)?;
34153 self.write(" ~* ");
34154 self.generate_expression(&e.expression)?;
34155 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
34156 self.write_keyword("REGEXP_LIKE");
34158 self.write("(");
34159 self.generate_expression(&e.this)?;
34160 self.write(", ");
34161 self.generate_expression(&e.expression)?;
34162 self.write(", ");
34163 if let Some(flag) = &e.flag {
34164 self.generate_expression(flag)?;
34165 } else {
34166 self.write("'i'");
34167 }
34168 self.write(")");
34169 } else {
34170 self.generate_expression(&e.this)?;
34172 self.write_space();
34173 self.write_keyword("REGEXP_ILIKE");
34174 self.write_space();
34175 self.generate_expression(&e.expression)?;
34176 if let Some(flag) = &e.flag {
34177 self.write(", ");
34178 self.generate_expression(flag)?;
34179 }
34180 }
34181 Ok(())
34182 }
34183
34184 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
34185 self.write_keyword("REGEXP_INSTR");
34187 self.write("(");
34188 self.generate_expression(&e.this)?;
34189 self.write(", ");
34190 self.generate_expression(&e.expression)?;
34191 if let Some(position) = &e.position {
34192 self.write(", ");
34193 self.generate_expression(position)?;
34194 }
34195 if let Some(occurrence) = &e.occurrence {
34196 self.write(", ");
34197 self.generate_expression(occurrence)?;
34198 }
34199 if let Some(option) = &e.option {
34200 self.write(", ");
34201 self.generate_expression(option)?;
34202 }
34203 if let Some(parameters) = &e.parameters {
34204 self.write(", ");
34205 self.generate_expression(parameters)?;
34206 }
34207 if let Some(group) = &e.group {
34208 self.write(", ");
34209 self.generate_expression(group)?;
34210 }
34211 self.write(")");
34212 Ok(())
34213 }
34214
34215 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
34216 self.write_keyword("REGEXP_SPLIT");
34218 self.write("(");
34219 self.generate_expression(&e.this)?;
34220 self.write(", ");
34221 self.generate_expression(&e.expression)?;
34222 if let Some(limit) = &e.limit {
34223 self.write(", ");
34224 self.generate_expression(limit)?;
34225 }
34226 self.write(")");
34227 Ok(())
34228 }
34229
34230 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
34231 self.write_keyword("REGR_AVGX");
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_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
34242 self.write_keyword("REGR_AVGY");
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_count(&mut self, e: &RegrCount) -> Result<()> {
34253 self.write_keyword("REGR_COUNT");
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_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
34264 self.write_keyword("REGR_INTERCEPT");
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_r2(&mut self, e: &RegrR2) -> Result<()> {
34275 self.write_keyword("REGR_R2");
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_slope(&mut self, e: &RegrSlope) -> Result<()> {
34286 self.write_keyword("REGR_SLOPE");
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_sxx(&mut self, e: &RegrSxx) -> Result<()> {
34297 self.write_keyword("REGR_SXX");
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_sxy(&mut self, e: &RegrSxy) -> Result<()> {
34308 self.write_keyword("REGR_SXY");
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_syy(&mut self, e: &RegrSyy) -> Result<()> {
34319 self.write_keyword("REGR_SYY");
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_valx(&mut self, e: &RegrValx) -> Result<()> {
34330 self.write_keyword("REGR_VALX");
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_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
34341 self.write_keyword("REGR_VALY");
34343 self.write("(");
34344 self.generate_expression(&e.this)?;
34345 self.write(", ");
34346 self.generate_expression(&e.expression)?;
34347 self.write(")");
34348 Ok(())
34349 }
34350
34351 fn generate_remote_with_connection_model_property(
34352 &mut self,
34353 e: &RemoteWithConnectionModelProperty,
34354 ) -> Result<()> {
34355 self.write_keyword("REMOTE WITH CONNECTION");
34357 self.write_space();
34358 self.generate_expression(&e.this)?;
34359 Ok(())
34360 }
34361
34362 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
34363 self.write_keyword("RENAME COLUMN");
34365 if e.exists {
34366 self.write_space();
34367 self.write_keyword("IF EXISTS");
34368 }
34369 self.write_space();
34370 self.generate_expression(&e.this)?;
34371 if let Some(to) = &e.to {
34372 self.write_space();
34373 self.write_keyword("TO");
34374 self.write_space();
34375 self.generate_expression(to)?;
34376 }
34377 Ok(())
34378 }
34379
34380 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
34381 self.write_keyword("REPLACE PARTITION");
34383 self.write_space();
34384 self.generate_expression(&e.expression)?;
34385 if let Some(source) = &e.source {
34386 self.write_space();
34387 self.write_keyword("FROM");
34388 self.write_space();
34389 self.generate_expression(source)?;
34390 }
34391 Ok(())
34392 }
34393
34394 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
34395 let keyword = match self.config.dialect {
34398 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
34399 _ => "RETURNING",
34400 };
34401 self.write_keyword(keyword);
34402 self.write_space();
34403 for (i, expr) in e.expressions.iter().enumerate() {
34404 if i > 0 {
34405 self.write(", ");
34406 }
34407 self.generate_expression(expr)?;
34408 }
34409 if let Some(into) = &e.into {
34410 self.write_space();
34411 self.write_keyword("INTO");
34412 self.write_space();
34413 self.generate_expression(into)?;
34414 }
34415 Ok(())
34416 }
34417
34418 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
34419 self.write_space();
34421 self.write_keyword("OUTPUT");
34422 self.write_space();
34423 for (i, expr) in output.columns.iter().enumerate() {
34424 if i > 0 {
34425 self.write(", ");
34426 }
34427 self.generate_expression(expr)?;
34428 }
34429 if let Some(into_table) = &output.into_table {
34430 self.write_space();
34431 self.write_keyword("INTO");
34432 self.write_space();
34433 self.generate_expression(into_table)?;
34434 }
34435 Ok(())
34436 }
34437
34438 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
34439 self.write_keyword("RETURNS");
34441 if e.is_table.is_some() {
34442 self.write_space();
34443 self.write_keyword("TABLE");
34444 }
34445 if let Some(table) = &e.table {
34446 self.write_space();
34447 self.generate_expression(table)?;
34448 } else if let Some(this) = &e.this {
34449 self.write_space();
34450 self.generate_expression(this)?;
34451 }
34452 if e.null.is_some() {
34453 self.write_space();
34454 self.write_keyword("NULL ON NULL INPUT");
34455 }
34456 Ok(())
34457 }
34458
34459 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
34460 self.write_keyword("ROLLBACK");
34462
34463 if e.this.is_none()
34465 && matches!(
34466 self.config.dialect,
34467 Some(DialectType::TSQL) | Some(DialectType::Fabric)
34468 )
34469 {
34470 self.write_space();
34471 self.write_keyword("TRANSACTION");
34472 }
34473
34474 if let Some(this) = &e.this {
34476 let is_transaction_marker = matches!(
34478 this.as_ref(),
34479 Expression::Identifier(id) if id.name == "TRANSACTION"
34480 );
34481
34482 self.write_space();
34483 self.write_keyword("TRANSACTION");
34484
34485 if !is_transaction_marker {
34487 self.write_space();
34488 self.generate_expression(this)?;
34489 }
34490 }
34491
34492 if let Some(savepoint) = &e.savepoint {
34494 self.write_space();
34495 self.write_keyword("TO");
34496 self.write_space();
34497 self.generate_expression(savepoint)?;
34498 }
34499 Ok(())
34500 }
34501
34502 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
34503 if e.expressions.is_empty() {
34505 self.write_keyword("WITH ROLLUP");
34506 } else {
34507 self.write_keyword("ROLLUP");
34508 self.write("(");
34509 for (i, expr) in e.expressions.iter().enumerate() {
34510 if i > 0 {
34511 self.write(", ");
34512 }
34513 self.generate_expression(expr)?;
34514 }
34515 self.write(")");
34516 }
34517 Ok(())
34518 }
34519
34520 fn generate_row_format_delimited_property(
34521 &mut self,
34522 e: &RowFormatDelimitedProperty,
34523 ) -> Result<()> {
34524 self.write_keyword("ROW FORMAT DELIMITED");
34526 if let Some(fields) = &e.fields {
34527 self.write_space();
34528 self.write_keyword("FIELDS TERMINATED BY");
34529 self.write_space();
34530 self.generate_expression(fields)?;
34531 }
34532 if let Some(escaped) = &e.escaped {
34533 self.write_space();
34534 self.write_keyword("ESCAPED BY");
34535 self.write_space();
34536 self.generate_expression(escaped)?;
34537 }
34538 if let Some(items) = &e.collection_items {
34539 self.write_space();
34540 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
34541 self.write_space();
34542 self.generate_expression(items)?;
34543 }
34544 if let Some(keys) = &e.map_keys {
34545 self.write_space();
34546 self.write_keyword("MAP KEYS TERMINATED BY");
34547 self.write_space();
34548 self.generate_expression(keys)?;
34549 }
34550 if let Some(lines) = &e.lines {
34551 self.write_space();
34552 self.write_keyword("LINES TERMINATED BY");
34553 self.write_space();
34554 self.generate_expression(lines)?;
34555 }
34556 if let Some(null) = &e.null {
34557 self.write_space();
34558 self.write_keyword("NULL DEFINED AS");
34559 self.write_space();
34560 self.generate_expression(null)?;
34561 }
34562 if let Some(serde) = &e.serde {
34563 self.write_space();
34564 self.generate_expression(serde)?;
34565 }
34566 Ok(())
34567 }
34568
34569 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
34570 self.write_keyword("ROW FORMAT");
34572 self.write_space();
34573 self.generate_expression(&e.this)?;
34574 Ok(())
34575 }
34576
34577 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
34578 self.write_keyword("ROW FORMAT SERDE");
34580 self.write_space();
34581 self.generate_expression(&e.this)?;
34582 if let Some(props) = &e.serde_properties {
34583 self.write_space();
34584 self.generate_expression(props)?;
34586 }
34587 Ok(())
34588 }
34589
34590 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
34591 self.write_keyword("SHA2");
34593 self.write("(");
34594 self.generate_expression(&e.this)?;
34595 if let Some(length) = e.length {
34596 self.write(", ");
34597 self.write(&length.to_string());
34598 }
34599 self.write(")");
34600 Ok(())
34601 }
34602
34603 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
34604 self.write_keyword("SHA2_DIGEST");
34606 self.write("(");
34607 self.generate_expression(&e.this)?;
34608 if let Some(length) = e.length {
34609 self.write(", ");
34610 self.write(&length.to_string());
34611 }
34612 self.write(")");
34613 Ok(())
34614 }
34615
34616 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
34617 let name = if matches!(
34618 self.config.dialect,
34619 Some(crate::dialects::DialectType::Spark)
34620 | Some(crate::dialects::DialectType::Databricks)
34621 ) {
34622 "TRY_ADD"
34623 } else {
34624 "SAFE_ADD"
34625 };
34626 self.write_keyword(name);
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_divide(&mut self, e: &SafeDivide) -> Result<()> {
34636 self.write_keyword("SAFE_DIVIDE");
34638 self.write("(");
34639 self.generate_expression(&e.this)?;
34640 self.write(", ");
34641 self.generate_expression(&e.expression)?;
34642 self.write(")");
34643 Ok(())
34644 }
34645
34646 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
34647 let name = if matches!(
34648 self.config.dialect,
34649 Some(crate::dialects::DialectType::Spark)
34650 | Some(crate::dialects::DialectType::Databricks)
34651 ) {
34652 "TRY_MULTIPLY"
34653 } else {
34654 "SAFE_MULTIPLY"
34655 };
34656 self.write_keyword(name);
34657 self.write("(");
34658 self.generate_expression(&e.this)?;
34659 self.write(", ");
34660 self.generate_expression(&e.expression)?;
34661 self.write(")");
34662 Ok(())
34663 }
34664
34665 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
34666 let name = if matches!(
34667 self.config.dialect,
34668 Some(crate::dialects::DialectType::Spark)
34669 | Some(crate::dialects::DialectType::Databricks)
34670 ) {
34671 "TRY_SUBTRACT"
34672 } else {
34673 "SAFE_SUBTRACT"
34674 };
34675 self.write_keyword(name);
34676 self.write("(");
34677 self.generate_expression(&e.this)?;
34678 self.write(", ");
34679 self.generate_expression(&e.expression)?;
34680 self.write(")");
34681 Ok(())
34682 }
34683
34684 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
34687 if matches!(sample.method, SampleMethod::Bucket) {
34689 self.write(" (");
34690 self.write_keyword("BUCKET");
34691 self.write_space();
34692 if let Some(ref num) = sample.bucket_numerator {
34693 self.generate_expression(num)?;
34694 }
34695 self.write_space();
34696 self.write_keyword("OUT OF");
34697 self.write_space();
34698 if let Some(ref denom) = sample.bucket_denominator {
34699 self.generate_expression(denom)?;
34700 }
34701 if let Some(ref field) = sample.bucket_field {
34702 self.write_space();
34703 self.write_keyword("ON");
34704 self.write_space();
34705 self.generate_expression(field)?;
34706 }
34707 self.write(")");
34708 return Ok(());
34709 }
34710
34711 let is_snowflake = matches!(
34713 self.config.dialect,
34714 Some(crate::dialects::DialectType::Snowflake)
34715 );
34716 let is_postgres = matches!(
34717 self.config.dialect,
34718 Some(crate::dialects::DialectType::PostgreSQL)
34719 | Some(crate::dialects::DialectType::Redshift)
34720 );
34721 let is_databricks = matches!(
34723 self.config.dialect,
34724 Some(crate::dialects::DialectType::Databricks)
34725 );
34726 let is_spark = matches!(
34727 self.config.dialect,
34728 Some(crate::dialects::DialectType::Spark)
34729 );
34730 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
34731 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
34733 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
34734 self.write_space();
34735 if !sample.explicit_method && (is_snowflake || force_method) {
34736 self.write_keyword("BERNOULLI");
34738 } else {
34739 match sample.method {
34740 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
34741 SampleMethod::System => self.write_keyword("SYSTEM"),
34742 SampleMethod::Block => self.write_keyword("BLOCK"),
34743 SampleMethod::Row => self.write_keyword("ROW"),
34744 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
34745 SampleMethod::Percent => self.write_keyword("SYSTEM"),
34746 SampleMethod::Bucket => {} }
34748 }
34749 }
34750
34751 let emit_size_no_parens = !self.config.tablesample_requires_parens;
34753 if emit_size_no_parens {
34754 self.write_space();
34755 match &sample.size {
34756 Expression::Tuple(tuple) => {
34757 for (i, expr) in tuple.expressions.iter().enumerate() {
34758 if i > 0 {
34759 self.write(", ");
34760 }
34761 self.generate_expression(expr)?;
34762 }
34763 }
34764 expr => self.generate_expression(expr)?,
34765 }
34766 } else {
34767 self.write(" (");
34768 self.generate_expression(&sample.size)?;
34769 }
34770
34771 let is_rows_method = matches!(
34773 sample.method,
34774 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
34775 );
34776 let is_percent = matches!(
34777 sample.method,
34778 SampleMethod::Percent
34779 | SampleMethod::System
34780 | SampleMethod::Bernoulli
34781 | SampleMethod::Block
34782 );
34783
34784 let is_presto = matches!(
34788 self.config.dialect,
34789 Some(crate::dialects::DialectType::Presto)
34790 | Some(crate::dialects::DialectType::Trino)
34791 | Some(crate::dialects::DialectType::Athena)
34792 );
34793 let should_output_unit = if is_databricks || is_spark {
34794 is_percent || is_rows_method || sample.unit_after_size
34796 } else if is_snowflake || is_postgres || is_presto {
34797 sample.unit_after_size
34798 } else {
34799 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
34800 };
34801
34802 if should_output_unit {
34803 self.write_space();
34804 if sample.is_percent {
34805 self.write_keyword("PERCENT");
34806 } else if is_rows_method && !sample.unit_after_size {
34807 self.write_keyword("ROWS");
34808 } else if sample.unit_after_size {
34809 match sample.method {
34810 SampleMethod::Percent
34811 | SampleMethod::System
34812 | SampleMethod::Bernoulli
34813 | SampleMethod::Block => {
34814 self.write_keyword("PERCENT");
34815 }
34816 SampleMethod::Row | SampleMethod::Reservoir => {
34817 self.write_keyword("ROWS");
34818 }
34819 _ => self.write_keyword("ROWS"),
34820 }
34821 } else {
34822 self.write_keyword("PERCENT");
34823 }
34824 }
34825
34826 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34827 if let Some(ref offset) = sample.offset {
34828 self.write_space();
34829 self.write_keyword("OFFSET");
34830 self.write_space();
34831 self.generate_expression(offset)?;
34832 }
34833 }
34834 if !emit_size_no_parens {
34835 self.write(")");
34836 }
34837
34838 Ok(())
34839 }
34840
34841 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
34842 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34844 self.write_keyword("SAMPLE BY");
34845 } else {
34846 self.write_keyword("SAMPLE");
34847 }
34848 self.write_space();
34849 self.generate_expression(&e.this)?;
34850 Ok(())
34851 }
34852
34853 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
34854 if let Some(this) = &e.this {
34856 self.generate_expression(this)?;
34857 }
34858 if !e.expressions.is_empty() {
34859 if e.this.is_some() {
34861 self.write_space();
34862 }
34863 self.write("(");
34864 for (i, expr) in e.expressions.iter().enumerate() {
34865 if i > 0 {
34866 self.write(", ");
34867 }
34868 self.generate_expression(expr)?;
34869 }
34870 self.write(")");
34871 }
34872 Ok(())
34873 }
34874
34875 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
34876 self.write_keyword("COMMENT");
34878 self.write_space();
34879 self.generate_expression(&e.this)?;
34880 Ok(())
34881 }
34882
34883 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
34884 if let Some(this) = &e.this {
34886 self.generate_expression(this)?;
34887 self.write("::");
34888 }
34889 self.generate_expression(&e.expression)?;
34890 Ok(())
34891 }
34892
34893 fn generate_search(&mut self, e: &Search) -> Result<()> {
34894 self.write_keyword("SEARCH");
34896 self.write("(");
34897 self.generate_expression(&e.this)?;
34898 self.write(", ");
34899 self.generate_expression(&e.expression)?;
34900 if let Some(json_scope) = &e.json_scope {
34901 self.write(", ");
34902 self.generate_expression(json_scope)?;
34903 }
34904 if let Some(analyzer) = &e.analyzer {
34905 self.write(", ");
34906 self.generate_expression(analyzer)?;
34907 }
34908 if let Some(analyzer_options) = &e.analyzer_options {
34909 self.write(", ");
34910 self.generate_expression(analyzer_options)?;
34911 }
34912 if let Some(search_mode) = &e.search_mode {
34913 self.write(", ");
34914 self.generate_expression(search_mode)?;
34915 }
34916 self.write(")");
34917 Ok(())
34918 }
34919
34920 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
34921 self.write_keyword("SEARCH_IP");
34923 self.write("(");
34924 self.generate_expression(&e.this)?;
34925 self.write(", ");
34926 self.generate_expression(&e.expression)?;
34927 self.write(")");
34928 Ok(())
34929 }
34930
34931 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
34932 self.write_keyword("SECURITY");
34934 self.write_space();
34935 self.generate_expression(&e.this)?;
34936 Ok(())
34937 }
34938
34939 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
34940 self.write("SEMANTIC_VIEW(");
34942
34943 if self.config.pretty {
34944 self.write_newline();
34946 self.indent_level += 1;
34947 self.write_indent();
34948 self.generate_expression(&e.this)?;
34949
34950 if let Some(metrics) = &e.metrics {
34951 self.write_newline();
34952 self.write_indent();
34953 self.write_keyword("METRICS");
34954 self.write_space();
34955 self.generate_semantic_view_tuple(metrics)?;
34956 }
34957 if let Some(dimensions) = &e.dimensions {
34958 self.write_newline();
34959 self.write_indent();
34960 self.write_keyword("DIMENSIONS");
34961 self.write_space();
34962 self.generate_semantic_view_tuple(dimensions)?;
34963 }
34964 if let Some(facts) = &e.facts {
34965 self.write_newline();
34966 self.write_indent();
34967 self.write_keyword("FACTS");
34968 self.write_space();
34969 self.generate_semantic_view_tuple(facts)?;
34970 }
34971 if let Some(where_) = &e.where_ {
34972 self.write_newline();
34973 self.write_indent();
34974 self.write_keyword("WHERE");
34975 self.write_space();
34976 self.generate_expression(where_)?;
34977 }
34978 self.write_newline();
34979 self.indent_level -= 1;
34980 self.write_indent();
34981 } else {
34982 self.generate_expression(&e.this)?;
34984 if let Some(metrics) = &e.metrics {
34985 self.write_space();
34986 self.write_keyword("METRICS");
34987 self.write_space();
34988 self.generate_semantic_view_tuple(metrics)?;
34989 }
34990 if let Some(dimensions) = &e.dimensions {
34991 self.write_space();
34992 self.write_keyword("DIMENSIONS");
34993 self.write_space();
34994 self.generate_semantic_view_tuple(dimensions)?;
34995 }
34996 if let Some(facts) = &e.facts {
34997 self.write_space();
34998 self.write_keyword("FACTS");
34999 self.write_space();
35000 self.generate_semantic_view_tuple(facts)?;
35001 }
35002 if let Some(where_) = &e.where_ {
35003 self.write_space();
35004 self.write_keyword("WHERE");
35005 self.write_space();
35006 self.generate_expression(where_)?;
35007 }
35008 }
35009 self.write(")");
35010 Ok(())
35011 }
35012
35013 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
35015 if let Expression::Tuple(t) = expr {
35016 for (i, e) in t.expressions.iter().enumerate() {
35017 if i > 0 {
35018 self.write(", ");
35019 }
35020 self.generate_expression(e)?;
35021 }
35022 } else {
35023 self.generate_expression(expr)?;
35024 }
35025 Ok(())
35026 }
35027
35028 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
35029 if let Some(start) = &e.start {
35031 self.write_keyword("START WITH");
35032 self.write_space();
35033 self.generate_expression(start)?;
35034 }
35035 if let Some(increment) = &e.increment {
35036 self.write_space();
35037 self.write_keyword("INCREMENT BY");
35038 self.write_space();
35039 self.generate_expression(increment)?;
35040 }
35041 if let Some(minvalue) = &e.minvalue {
35042 self.write_space();
35043 self.write_keyword("MINVALUE");
35044 self.write_space();
35045 self.generate_expression(minvalue)?;
35046 }
35047 if let Some(maxvalue) = &e.maxvalue {
35048 self.write_space();
35049 self.write_keyword("MAXVALUE");
35050 self.write_space();
35051 self.generate_expression(maxvalue)?;
35052 }
35053 if let Some(cache) = &e.cache {
35054 self.write_space();
35055 self.write_keyword("CACHE");
35056 self.write_space();
35057 self.generate_expression(cache)?;
35058 }
35059 if let Some(owned) = &e.owned {
35060 self.write_space();
35061 self.write_keyword("OWNED BY");
35062 self.write_space();
35063 self.generate_expression(owned)?;
35064 }
35065 for opt in &e.options {
35066 self.write_space();
35067 self.generate_expression(opt)?;
35068 }
35069 Ok(())
35070 }
35071
35072 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
35073 if e.with_.is_some() {
35075 self.write_keyword("WITH");
35076 self.write_space();
35077 }
35078 self.write_keyword("SERDEPROPERTIES");
35079 self.write(" (");
35080 for (i, expr) in e.expressions.iter().enumerate() {
35081 if i > 0 {
35082 self.write(", ");
35083 }
35084 match expr {
35086 Expression::Eq(eq) => {
35087 self.generate_expression(&eq.left)?;
35088 self.write("=");
35089 self.generate_expression(&eq.right)?;
35090 }
35091 _ => self.generate_expression(expr)?,
35092 }
35093 }
35094 self.write(")");
35095 Ok(())
35096 }
35097
35098 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
35099 self.write("@@");
35101 if let Some(kind) = &e.kind {
35102 self.write(kind);
35103 self.write(".");
35104 }
35105 self.generate_expression(&e.this)?;
35106 Ok(())
35107 }
35108
35109 fn generate_set(&mut self, e: &Set) -> Result<()> {
35110 if e.unset.is_some() {
35112 self.write_keyword("UNSET");
35113 } else {
35114 self.write_keyword("SET");
35115 }
35116 if e.tag.is_some() {
35117 self.write_space();
35118 self.write_keyword("TAG");
35119 }
35120 if !e.expressions.is_empty() {
35121 self.write_space();
35122 for (i, expr) in e.expressions.iter().enumerate() {
35123 if i > 0 {
35124 self.write(", ");
35125 }
35126 self.generate_expression(expr)?;
35127 }
35128 }
35129 Ok(())
35130 }
35131
35132 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
35133 self.write_keyword("SET");
35135 self.write_space();
35136 self.generate_expression(&e.this)?;
35137 Ok(())
35138 }
35139
35140 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
35141 if let Some(kind) = &e.kind {
35143 self.write_keyword(kind);
35144 self.write_space();
35145 }
35146 self.generate_expression(&e.name)?;
35147 self.write(" = ");
35148 self.generate_expression(&e.value)?;
35149 Ok(())
35150 }
35151
35152 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
35153 if let Some(with_) = &e.with_ {
35155 self.generate_expression(with_)?;
35156 self.write_space();
35157 }
35158 self.generate_expression(&e.this)?;
35159 self.write_space();
35160 if let Some(kind) = &e.kind {
35162 self.write_keyword(kind);
35163 }
35164 if e.distinct {
35165 self.write_space();
35166 self.write_keyword("DISTINCT");
35167 } else {
35168 self.write_space();
35169 self.write_keyword("ALL");
35170 }
35171 if e.by_name.is_some() {
35172 self.write_space();
35173 self.write_keyword("BY NAME");
35174 }
35175 self.write_space();
35176 self.generate_expression(&e.expression)?;
35177 Ok(())
35178 }
35179
35180 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
35181 if e.multi.is_some() {
35183 self.write_keyword("MULTISET");
35184 } else {
35185 self.write_keyword("SET");
35186 }
35187 Ok(())
35188 }
35189
35190 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
35191 self.write_keyword("SETTINGS");
35193 if self.config.pretty && e.expressions.len() > 1 {
35194 self.indent_level += 1;
35196 for (i, expr) in e.expressions.iter().enumerate() {
35197 if i > 0 {
35198 self.write(",");
35199 }
35200 self.write_newline();
35201 self.write_indent();
35202 self.generate_expression(expr)?;
35203 }
35204 self.indent_level -= 1;
35205 } else {
35206 self.write_space();
35207 for (i, expr) in e.expressions.iter().enumerate() {
35208 if i > 0 {
35209 self.write(", ");
35210 }
35211 self.generate_expression(expr)?;
35212 }
35213 }
35214 Ok(())
35215 }
35216
35217 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
35218 self.write_keyword("SHARING");
35220 if let Some(this) = &e.this {
35221 self.write(" = ");
35222 self.generate_expression(this)?;
35223 }
35224 Ok(())
35225 }
35226
35227 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
35228 if let Some(begin) = &e.this {
35230 self.generate_expression(begin)?;
35231 }
35232 self.write(":");
35233 if let Some(end) = &e.expression {
35234 self.generate_expression(end)?;
35235 }
35236 if let Some(step) = &e.step {
35237 self.write(":");
35238 self.generate_expression(step)?;
35239 }
35240 Ok(())
35241 }
35242
35243 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
35244 self.write_keyword("SORT_ARRAY");
35246 self.write("(");
35247 self.generate_expression(&e.this)?;
35248 if let Some(asc) = &e.asc {
35249 self.write(", ");
35250 self.generate_expression(asc)?;
35251 }
35252 self.write(")");
35253 Ok(())
35254 }
35255
35256 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
35257 self.write_keyword("SORT BY");
35259 self.write_space();
35260 for (i, expr) in e.expressions.iter().enumerate() {
35261 if i > 0 {
35262 self.write(", ");
35263 }
35264 self.generate_ordered(expr)?;
35265 }
35266 Ok(())
35267 }
35268
35269 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
35270 if e.compound.is_some() {
35272 self.write_keyword("COMPOUND");
35273 self.write_space();
35274 }
35275 self.write_keyword("SORTKEY");
35276 self.write("(");
35277 if let Expression::Tuple(t) = e.this.as_ref() {
35279 for (i, expr) in t.expressions.iter().enumerate() {
35280 if i > 0 {
35281 self.write(", ");
35282 }
35283 self.generate_expression(expr)?;
35284 }
35285 } else {
35286 self.generate_expression(&e.this)?;
35287 }
35288 self.write(")");
35289 Ok(())
35290 }
35291
35292 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
35293 self.write_keyword("SPLIT_PART");
35295 self.write("(");
35296 self.generate_expression(&e.this)?;
35297 if let Some(delimiter) = &e.delimiter {
35298 self.write(", ");
35299 self.generate_expression(delimiter)?;
35300 }
35301 if let Some(part_index) = &e.part_index {
35302 self.write(", ");
35303 self.generate_expression(part_index)?;
35304 }
35305 self.write(")");
35306 Ok(())
35307 }
35308
35309 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
35310 self.generate_expression(&e.this)?;
35312 Ok(())
35313 }
35314
35315 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
35316 self.write_keyword("SQL SECURITY");
35318 self.write_space();
35319 self.generate_expression(&e.this)?;
35320 Ok(())
35321 }
35322
35323 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
35324 self.write_keyword("ST_DISTANCE");
35326 self.write("(");
35327 self.generate_expression(&e.this)?;
35328 self.write(", ");
35329 self.generate_expression(&e.expression)?;
35330 if let Some(use_spheroid) = &e.use_spheroid {
35331 self.write(", ");
35332 self.generate_expression(use_spheroid)?;
35333 }
35334 self.write(")");
35335 Ok(())
35336 }
35337
35338 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
35339 self.write_keyword("ST_POINT");
35341 self.write("(");
35342 self.generate_expression(&e.this)?;
35343 self.write(", ");
35344 self.generate_expression(&e.expression)?;
35345 self.write(")");
35346 Ok(())
35347 }
35348
35349 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
35350 self.generate_expression(&e.this)?;
35352 Ok(())
35353 }
35354
35355 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
35356 self.write_keyword("STANDARD_HASH");
35358 self.write("(");
35359 self.generate_expression(&e.this)?;
35360 if let Some(expression) = &e.expression {
35361 self.write(", ");
35362 self.generate_expression(expression)?;
35363 }
35364 self.write(")");
35365 Ok(())
35366 }
35367
35368 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
35369 self.write_keyword("STORED BY");
35371 self.write_space();
35372 self.generate_expression(&e.this)?;
35373 Ok(())
35374 }
35375
35376 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
35377 use crate::dialects::DialectType;
35380 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35381 self.write_keyword("CHARINDEX");
35383 self.write("(");
35384 if let Some(substr) = &e.substr {
35385 self.generate_expression(substr)?;
35386 self.write(", ");
35387 }
35388 self.generate_expression(&e.this)?;
35389 if let Some(position) = &e.position {
35390 self.write(", ");
35391 self.generate_expression(position)?;
35392 }
35393 self.write(")");
35394 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
35395 self.write_keyword("POSITION");
35396 self.write("(");
35397 self.generate_expression(&e.this)?;
35398 if let Some(substr) = &e.substr {
35399 self.write(", ");
35400 self.generate_expression(substr)?;
35401 }
35402 if let Some(position) = &e.position {
35403 self.write(", ");
35404 self.generate_expression(position)?;
35405 }
35406 if let Some(occurrence) = &e.occurrence {
35407 self.write(", ");
35408 self.generate_expression(occurrence)?;
35409 }
35410 self.write(")");
35411 } else if matches!(
35412 self.config.dialect,
35413 Some(DialectType::SQLite)
35414 | Some(DialectType::Oracle)
35415 | Some(DialectType::BigQuery)
35416 | Some(DialectType::Teradata)
35417 ) {
35418 self.write_keyword("INSTR");
35419 self.write("(");
35420 self.generate_expression(&e.this)?;
35421 if let Some(substr) = &e.substr {
35422 self.write(", ");
35423 self.generate_expression(substr)?;
35424 }
35425 if let Some(position) = &e.position {
35426 self.write(", ");
35427 self.generate_expression(position)?;
35428 } else if e.occurrence.is_some() {
35429 self.write(", 1");
35432 }
35433 if let Some(occurrence) = &e.occurrence {
35434 self.write(", ");
35435 self.generate_expression(occurrence)?;
35436 }
35437 self.write(")");
35438 } else if matches!(
35439 self.config.dialect,
35440 Some(DialectType::MySQL)
35441 | Some(DialectType::SingleStore)
35442 | Some(DialectType::Doris)
35443 | Some(DialectType::StarRocks)
35444 | Some(DialectType::Hive)
35445 | Some(DialectType::Spark)
35446 | Some(DialectType::Databricks)
35447 ) {
35448 self.write_keyword("LOCATE");
35450 self.write("(");
35451 if let Some(substr) = &e.substr {
35452 self.generate_expression(substr)?;
35453 self.write(", ");
35454 }
35455 self.generate_expression(&e.this)?;
35456 if let Some(position) = &e.position {
35457 self.write(", ");
35458 self.generate_expression(position)?;
35459 }
35460 self.write(")");
35461 } else if matches!(
35462 self.config.dialect,
35463 Some(DialectType::TSQL) | Some(DialectType::Fabric)
35464 ) {
35465 self.write_keyword("CHARINDEX");
35467 self.write("(");
35468 if let Some(substr) = &e.substr {
35469 self.generate_expression(substr)?;
35470 self.write(", ");
35471 }
35472 self.generate_expression(&e.this)?;
35473 if let Some(position) = &e.position {
35474 self.write(", ");
35475 self.generate_expression(position)?;
35476 }
35477 self.write(")");
35478 } else if matches!(
35479 self.config.dialect,
35480 Some(DialectType::PostgreSQL)
35481 | Some(DialectType::Materialize)
35482 | Some(DialectType::RisingWave)
35483 | Some(DialectType::Redshift)
35484 ) {
35485 self.write_keyword("POSITION");
35487 self.write("(");
35488 if let Some(substr) = &e.substr {
35489 self.generate_expression(substr)?;
35490 self.write(" IN ");
35491 }
35492 self.generate_expression(&e.this)?;
35493 self.write(")");
35494 } else {
35495 self.write_keyword("STRPOS");
35496 self.write("(");
35497 self.generate_expression(&e.this)?;
35498 if let Some(substr) = &e.substr {
35499 self.write(", ");
35500 self.generate_expression(substr)?;
35501 }
35502 if let Some(position) = &e.position {
35503 self.write(", ");
35504 self.generate_expression(position)?;
35505 }
35506 if let Some(occurrence) = &e.occurrence {
35507 self.write(", ");
35508 self.generate_expression(occurrence)?;
35509 }
35510 self.write(")");
35511 }
35512 Ok(())
35513 }
35514
35515 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
35516 match self.config.dialect {
35517 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
35518 self.write_keyword("TO_DATE");
35520 self.write("(");
35521 self.generate_expression(&e.this)?;
35522 if let Some(format) = &e.format {
35523 self.write(", '");
35524 self.write(&Self::strftime_to_java_format(format));
35525 self.write("'");
35526 }
35527 self.write(")");
35528 }
35529 Some(DialectType::DuckDB) => {
35530 self.write_keyword("CAST");
35532 self.write("(");
35533 self.write_keyword("STRPTIME");
35534 self.write("(");
35535 self.generate_expression(&e.this)?;
35536 if let Some(format) = &e.format {
35537 self.write(", '");
35538 self.write(format);
35539 self.write("'");
35540 }
35541 self.write(")");
35542 self.write_keyword(" AS ");
35543 self.write_keyword("DATE");
35544 self.write(")");
35545 }
35546 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
35547 self.write_keyword("TO_DATE");
35549 self.write("(");
35550 self.generate_expression(&e.this)?;
35551 if let Some(format) = &e.format {
35552 self.write(", '");
35553 self.write(&Self::strftime_to_postgres_format(format));
35554 self.write("'");
35555 }
35556 self.write(")");
35557 }
35558 Some(DialectType::BigQuery) => {
35559 self.write_keyword("PARSE_DATE");
35561 self.write("(");
35562 if let Some(format) = &e.format {
35563 self.write("'");
35564 self.write(format);
35565 self.write("'");
35566 self.write(", ");
35567 }
35568 self.generate_expression(&e.this)?;
35569 self.write(")");
35570 }
35571 Some(DialectType::Teradata) => {
35572 self.write_keyword("CAST");
35574 self.write("(");
35575 self.generate_expression(&e.this)?;
35576 self.write_keyword(" AS ");
35577 self.write_keyword("DATE");
35578 if let Some(format) = &e.format {
35579 self.write_keyword(" FORMAT ");
35580 self.write("'");
35581 self.write(&Self::strftime_to_teradata_format(format));
35582 self.write("'");
35583 }
35584 self.write(")");
35585 }
35586 _ => {
35587 self.write_keyword("STR_TO_DATE");
35589 self.write("(");
35590 self.generate_expression(&e.this)?;
35591 if let Some(format) = &e.format {
35592 self.write(", '");
35593 self.write(format);
35594 self.write("'");
35595 }
35596 self.write(")");
35597 }
35598 }
35599 Ok(())
35600 }
35601
35602 fn strftime_to_teradata_format(fmt: &str) -> String {
35604 let mut result = String::with_capacity(fmt.len() * 2);
35605 let bytes = fmt.as_bytes();
35606 let len = bytes.len();
35607 let mut i = 0;
35608 while i < len {
35609 if bytes[i] == b'%' && i + 1 < len {
35610 let replacement = match bytes[i + 1] {
35611 b'Y' => "YYYY",
35612 b'y' => "YY",
35613 b'm' => "MM",
35614 b'B' => "MMMM",
35615 b'b' => "MMM",
35616 b'd' => "DD",
35617 b'j' => "DDD",
35618 b'H' => "HH",
35619 b'M' => "MI",
35620 b'S' => "SS",
35621 b'f' => "SSSSSS",
35622 b'A' => "EEEE",
35623 b'a' => "EEE",
35624 _ => {
35625 result.push('%');
35626 i += 1;
35627 continue;
35628 }
35629 };
35630 result.push_str(replacement);
35631 i += 2;
35632 } else {
35633 result.push(bytes[i] as char);
35634 i += 1;
35635 }
35636 }
35637 result
35638 }
35639
35640 pub fn strftime_to_java_format_static(fmt: &str) -> String {
35643 Self::strftime_to_java_format(fmt)
35644 }
35645
35646 fn strftime_to_java_format(fmt: &str) -> String {
35648 let mut result = String::with_capacity(fmt.len() * 2);
35649 let bytes = fmt.as_bytes();
35650 let len = bytes.len();
35651 let mut i = 0;
35652 while i < len {
35653 if bytes[i] == b'%' && i + 1 < len {
35654 if bytes[i + 1] == b'-' && i + 2 < len {
35656 let replacement = match bytes[i + 2] {
35657 b'd' => "d",
35658 b'm' => "M",
35659 b'H' => "H",
35660 b'M' => "m",
35661 b'S' => "s",
35662 _ => {
35663 result.push('%');
35664 i += 1;
35665 continue;
35666 }
35667 };
35668 result.push_str(replacement);
35669 i += 3;
35670 } else {
35671 let replacement = match bytes[i + 1] {
35672 b'Y' => "yyyy",
35673 b'y' => "yy",
35674 b'm' => "MM",
35675 b'B' => "MMMM",
35676 b'b' => "MMM",
35677 b'd' => "dd",
35678 b'j' => "DDD",
35679 b'H' => "HH",
35680 b'M' => "mm",
35681 b'S' => "ss",
35682 b'f' => "SSSSSS",
35683 b'A' => "EEEE",
35684 b'a' => "EEE",
35685 _ => {
35686 result.push('%');
35687 i += 1;
35688 continue;
35689 }
35690 };
35691 result.push_str(replacement);
35692 i += 2;
35693 }
35694 } else {
35695 result.push(bytes[i] as char);
35696 i += 1;
35697 }
35698 }
35699 result
35700 }
35701
35702 fn strftime_to_tsql_format(fmt: &str) -> String {
35705 let mut result = String::with_capacity(fmt.len() * 2);
35706 let bytes = fmt.as_bytes();
35707 let len = bytes.len();
35708 let mut i = 0;
35709 while i < len {
35710 if bytes[i] == b'%' && i + 1 < len {
35711 if bytes[i + 1] == b'-' && i + 2 < len {
35713 let replacement = match bytes[i + 2] {
35714 b'd' => "d",
35715 b'm' => "M",
35716 b'H' => "H",
35717 b'M' => "m",
35718 b'S' => "s",
35719 _ => {
35720 result.push('%');
35721 i += 1;
35722 continue;
35723 }
35724 };
35725 result.push_str(replacement);
35726 i += 3;
35727 } else {
35728 let replacement = match bytes[i + 1] {
35729 b'Y' => "yyyy",
35730 b'y' => "yy",
35731 b'm' => "MM",
35732 b'B' => "MMMM",
35733 b'b' => "MMM",
35734 b'd' => "dd",
35735 b'j' => "DDD",
35736 b'H' => "HH",
35737 b'M' => "mm",
35738 b'S' => "ss",
35739 b'f' => "ffffff",
35740 b'A' => "dddd",
35741 b'a' => "ddd",
35742 _ => {
35743 result.push('%');
35744 i += 1;
35745 continue;
35746 }
35747 };
35748 result.push_str(replacement);
35749 i += 2;
35750 }
35751 } else {
35752 result.push(bytes[i] as char);
35753 i += 1;
35754 }
35755 }
35756 result
35757 }
35758
35759 fn decompose_json_path(path: &str) -> Vec<String> {
35762 let mut parts = Vec::new();
35763 let path = if path.starts_with("$.") {
35765 &path[2..]
35766 } else if path.starts_with('$') {
35767 &path[1..]
35768 } else {
35769 path
35770 };
35771 if path.is_empty() {
35772 return parts;
35773 }
35774 let mut current = String::new();
35775 let chars: Vec<char> = path.chars().collect();
35776 let mut i = 0;
35777 while i < chars.len() {
35778 match chars[i] {
35779 '.' => {
35780 if !current.is_empty() {
35781 parts.push(current.clone());
35782 current.clear();
35783 }
35784 i += 1;
35785 }
35786 '[' => {
35787 if !current.is_empty() {
35788 parts.push(current.clone());
35789 current.clear();
35790 }
35791 i += 1;
35792 let mut bracket_content = String::new();
35794 while i < chars.len() && chars[i] != ']' {
35795 if chars[i] == '"' || chars[i] == '\'' {
35797 let quote = chars[i];
35798 i += 1;
35799 while i < chars.len() && chars[i] != quote {
35800 bracket_content.push(chars[i]);
35801 i += 1;
35802 }
35803 if i < chars.len() {
35804 i += 1;
35805 } } else {
35807 bracket_content.push(chars[i]);
35808 i += 1;
35809 }
35810 }
35811 if i < chars.len() {
35812 i += 1;
35813 } if bracket_content != "*" {
35816 parts.push(bracket_content);
35817 }
35818 }
35819 _ => {
35820 current.push(chars[i]);
35821 i += 1;
35822 }
35823 }
35824 }
35825 if !current.is_empty() {
35826 parts.push(current);
35827 }
35828 parts
35829 }
35830
35831 fn strftime_to_postgres_format(fmt: &str) -> String {
35833 let mut result = String::with_capacity(fmt.len() * 2);
35834 let bytes = fmt.as_bytes();
35835 let len = bytes.len();
35836 let mut i = 0;
35837 while i < len {
35838 if bytes[i] == b'%' && i + 1 < len {
35839 if bytes[i + 1] == b'-' && i + 2 < len {
35841 let replacement = match bytes[i + 2] {
35842 b'd' => "FMDD",
35843 b'm' => "FMMM",
35844 b'H' => "FMHH24",
35845 b'M' => "FMMI",
35846 b'S' => "FMSS",
35847 _ => {
35848 result.push('%');
35849 i += 1;
35850 continue;
35851 }
35852 };
35853 result.push_str(replacement);
35854 i += 3;
35855 } else {
35856 let replacement = match bytes[i + 1] {
35857 b'Y' => "YYYY",
35858 b'y' => "YY",
35859 b'm' => "MM",
35860 b'B' => "Month",
35861 b'b' => "Mon",
35862 b'd' => "DD",
35863 b'j' => "DDD",
35864 b'H' => "HH24",
35865 b'M' => "MI",
35866 b'S' => "SS",
35867 b'f' => "US",
35868 b'A' => "Day",
35869 b'a' => "Dy",
35870 _ => {
35871 result.push('%');
35872 i += 1;
35873 continue;
35874 }
35875 };
35876 result.push_str(replacement);
35877 i += 2;
35878 }
35879 } else {
35880 result.push(bytes[i] as char);
35881 i += 1;
35882 }
35883 }
35884 result
35885 }
35886
35887 fn strftime_to_snowflake_format(fmt: &str) -> String {
35889 let mut result = String::with_capacity(fmt.len() * 2);
35890 let bytes = fmt.as_bytes();
35891 let len = bytes.len();
35892 let mut i = 0;
35893 while i < len {
35894 if bytes[i] == b'%' && i + 1 < len {
35895 if bytes[i + 1] == b'-' && i + 2 < len {
35897 let replacement = match bytes[i + 2] {
35898 b'd' => "dd",
35899 b'm' => "mm",
35900 _ => {
35901 result.push('%');
35902 i += 1;
35903 continue;
35904 }
35905 };
35906 result.push_str(replacement);
35907 i += 3;
35908 } else {
35909 let replacement = match bytes[i + 1] {
35910 b'Y' => "yyyy",
35911 b'y' => "yy",
35912 b'm' => "mm",
35913 b'd' => "DD",
35914 b'H' => "hh24",
35915 b'M' => "mi",
35916 b'S' => "ss",
35917 b'f' => "ff",
35918 _ => {
35919 result.push('%');
35920 i += 1;
35921 continue;
35922 }
35923 };
35924 result.push_str(replacement);
35925 i += 2;
35926 }
35927 } else {
35928 result.push(bytes[i] as char);
35929 i += 1;
35930 }
35931 }
35932 result
35933 }
35934
35935 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
35936 self.write_keyword("STR_TO_MAP");
35938 self.write("(");
35939 self.generate_expression(&e.this)?;
35940 let needs_defaults = matches!(
35942 self.config.dialect,
35943 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
35944 );
35945 if let Some(pair_delim) = &e.pair_delim {
35946 self.write(", ");
35947 self.generate_expression(pair_delim)?;
35948 } else if needs_defaults {
35949 self.write(", ','");
35950 }
35951 if let Some(key_value_delim) = &e.key_value_delim {
35952 self.write(", ");
35953 self.generate_expression(key_value_delim)?;
35954 } else if needs_defaults {
35955 self.write(", ':'");
35956 }
35957 self.write(")");
35958 Ok(())
35959 }
35960
35961 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
35962 let is_strftime = e.format.contains('%');
35964 let to_strftime = |f: &str| -> String {
35966 if is_strftime {
35967 f.to_string()
35968 } else {
35969 Self::snowflake_format_to_strftime(f)
35970 }
35971 };
35972 let to_java = |f: &str| -> String {
35974 if is_strftime {
35975 Self::strftime_to_java_format(f)
35976 } else {
35977 Self::snowflake_format_to_spark(f)
35978 }
35979 };
35980 let to_pg = |f: &str| -> String {
35982 if is_strftime {
35983 Self::strftime_to_postgres_format(f)
35984 } else {
35985 Self::convert_strptime_to_postgres_format(f)
35986 }
35987 };
35988
35989 match self.config.dialect {
35990 Some(DialectType::Exasol) => {
35991 self.write_keyword("TO_DATE");
35992 self.write("(");
35993 self.generate_expression(&e.this)?;
35994 self.write(", '");
35995 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
35996 self.write("'");
35997 self.write(")");
35998 }
35999 Some(DialectType::BigQuery) => {
36000 let fmt = to_strftime(&e.format);
36002 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
36004 self.write_keyword("PARSE_TIMESTAMP");
36005 self.write("('");
36006 self.write(&fmt);
36007 self.write("', ");
36008 self.generate_expression(&e.this)?;
36009 self.write(")");
36010 }
36011 Some(DialectType::Hive) => {
36012 let java_fmt = to_java(&e.format);
36015 if java_fmt == "yyyy-MM-dd HH:mm:ss"
36016 || java_fmt == "yyyy-MM-dd"
36017 || e.format == "yyyy-MM-dd HH:mm:ss"
36018 || e.format == "yyyy-MM-dd"
36019 {
36020 self.write_keyword("CAST");
36021 self.write("(");
36022 self.generate_expression(&e.this)?;
36023 self.write(" ");
36024 self.write_keyword("AS TIMESTAMP");
36025 self.write(")");
36026 } else {
36027 self.write_keyword("CAST");
36029 self.write("(");
36030 self.write_keyword("FROM_UNIXTIME");
36031 self.write("(");
36032 self.write_keyword("UNIX_TIMESTAMP");
36033 self.write("(");
36034 self.generate_expression(&e.this)?;
36035 self.write(", '");
36036 self.write(&java_fmt);
36037 self.write("')");
36038 self.write(") ");
36039 self.write_keyword("AS TIMESTAMP");
36040 self.write(")");
36041 }
36042 }
36043 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36044 let java_fmt = to_java(&e.format);
36046 self.write_keyword("TO_TIMESTAMP");
36047 self.write("(");
36048 self.generate_expression(&e.this)?;
36049 self.write(", '");
36050 self.write(&java_fmt);
36051 self.write("')");
36052 }
36053 Some(DialectType::MySQL) => {
36054 let mut fmt = to_strftime(&e.format);
36056 fmt = fmt.replace("%-d", "%e");
36058 fmt = fmt.replace("%-m", "%c");
36059 fmt = fmt.replace("%H:%M:%S", "%T");
36060 self.write_keyword("STR_TO_DATE");
36061 self.write("(");
36062 self.generate_expression(&e.this)?;
36063 self.write(", '");
36064 self.write(&fmt);
36065 self.write("')");
36066 }
36067 Some(DialectType::Drill) => {
36068 let java_fmt = to_java(&e.format);
36070 let java_fmt = java_fmt.replace('T', "''T''");
36072 self.write_keyword("TO_TIMESTAMP");
36073 self.write("(");
36074 self.generate_expression(&e.this)?;
36075 self.write(", '");
36076 self.write(&java_fmt);
36077 self.write("')");
36078 }
36079 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
36080 let mut fmt = to_strftime(&e.format);
36082 fmt = fmt.replace("%-d", "%e");
36084 fmt = fmt.replace("%-m", "%c");
36085 fmt = fmt.replace("%H:%M:%S", "%T");
36086 self.write_keyword("DATE_PARSE");
36087 self.write("(");
36088 self.generate_expression(&e.this)?;
36089 self.write(", '");
36090 self.write(&fmt);
36091 self.write("')");
36092 }
36093 Some(DialectType::DuckDB) => {
36094 let fmt = to_strftime(&e.format);
36096 self.write_keyword("STRPTIME");
36097 self.write("(");
36098 self.generate_expression(&e.this)?;
36099 self.write(", '");
36100 self.write(&fmt);
36101 self.write("')");
36102 }
36103 Some(DialectType::PostgreSQL)
36104 | Some(DialectType::Redshift)
36105 | Some(DialectType::Materialize) => {
36106 let pg_fmt = to_pg(&e.format);
36108 self.write_keyword("TO_TIMESTAMP");
36109 self.write("(");
36110 self.generate_expression(&e.this)?;
36111 self.write(", '");
36112 self.write(&pg_fmt);
36113 self.write("')");
36114 }
36115 Some(DialectType::Oracle) => {
36116 let pg_fmt = to_pg(&e.format);
36118 self.write_keyword("TO_TIMESTAMP");
36119 self.write("(");
36120 self.generate_expression(&e.this)?;
36121 self.write(", '");
36122 self.write(&pg_fmt);
36123 self.write("')");
36124 }
36125 Some(DialectType::Snowflake) => {
36126 self.write_keyword("TO_TIMESTAMP");
36128 self.write("(");
36129 self.generate_expression(&e.this)?;
36130 self.write(", '");
36131 self.write(&e.format);
36132 self.write("')");
36133 }
36134 _ => {
36135 self.write_keyword("STR_TO_TIME");
36137 self.write("(");
36138 self.generate_expression(&e.this)?;
36139 self.write(", '");
36140 self.write(&e.format);
36141 self.write("'");
36142 self.write(")");
36143 }
36144 }
36145 Ok(())
36146 }
36147
36148 fn snowflake_format_to_strftime(format: &str) -> String {
36150 let mut result = String::new();
36151 let chars: Vec<char> = format.chars().collect();
36152 let mut i = 0;
36153 while i < chars.len() {
36154 let remaining = &format[i..];
36155 if remaining.starts_with("yyyy") {
36156 result.push_str("%Y");
36157 i += 4;
36158 } else if remaining.starts_with("yy") {
36159 result.push_str("%y");
36160 i += 2;
36161 } else if remaining.starts_with("mmmm") {
36162 result.push_str("%B"); i += 4;
36164 } else if remaining.starts_with("mon") {
36165 result.push_str("%b"); i += 3;
36167 } else if remaining.starts_with("mm") {
36168 result.push_str("%m");
36169 i += 2;
36170 } else if remaining.starts_with("DD") {
36171 result.push_str("%d");
36172 i += 2;
36173 } else if remaining.starts_with("dy") {
36174 result.push_str("%a"); i += 2;
36176 } else if remaining.starts_with("hh24") {
36177 result.push_str("%H");
36178 i += 4;
36179 } else if remaining.starts_with("hh12") {
36180 result.push_str("%I");
36181 i += 4;
36182 } else if remaining.starts_with("hh") {
36183 result.push_str("%H");
36184 i += 2;
36185 } else if remaining.starts_with("mi") {
36186 result.push_str("%M");
36187 i += 2;
36188 } else if remaining.starts_with("ss") {
36189 result.push_str("%S");
36190 i += 2;
36191 } else if remaining.starts_with("ff") {
36192 result.push_str("%f");
36194 i += 2;
36195 while i < chars.len() && chars[i].is_ascii_digit() {
36197 i += 1;
36198 }
36199 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
36200 result.push_str("%p");
36201 i += 2;
36202 } else if remaining.starts_with("tz") {
36203 result.push_str("%Z");
36204 i += 2;
36205 } else {
36206 result.push(chars[i]);
36207 i += 1;
36208 }
36209 }
36210 result
36211 }
36212
36213 fn snowflake_format_to_spark(format: &str) -> String {
36215 let mut result = String::new();
36216 let chars: Vec<char> = format.chars().collect();
36217 let mut i = 0;
36218 while i < chars.len() {
36219 let remaining = &format[i..];
36220 if remaining.starts_with("yyyy") {
36221 result.push_str("yyyy");
36222 i += 4;
36223 } else if remaining.starts_with("yy") {
36224 result.push_str("yy");
36225 i += 2;
36226 } else if remaining.starts_with("mmmm") {
36227 result.push_str("MMMM"); i += 4;
36229 } else if remaining.starts_with("mon") {
36230 result.push_str("MMM"); i += 3;
36232 } else if remaining.starts_with("mm") {
36233 result.push_str("MM");
36234 i += 2;
36235 } else if remaining.starts_with("DD") {
36236 result.push_str("dd");
36237 i += 2;
36238 } else if remaining.starts_with("dy") {
36239 result.push_str("EEE"); i += 2;
36241 } else if remaining.starts_with("hh24") {
36242 result.push_str("HH");
36243 i += 4;
36244 } else if remaining.starts_with("hh12") {
36245 result.push_str("hh");
36246 i += 4;
36247 } else if remaining.starts_with("hh") {
36248 result.push_str("HH");
36249 i += 2;
36250 } else if remaining.starts_with("mi") {
36251 result.push_str("mm");
36252 i += 2;
36253 } else if remaining.starts_with("ss") {
36254 result.push_str("ss");
36255 i += 2;
36256 } else if remaining.starts_with("ff") {
36257 result.push_str("SSS"); i += 2;
36259 while i < chars.len() && chars[i].is_ascii_digit() {
36261 i += 1;
36262 }
36263 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
36264 result.push_str("a");
36265 i += 2;
36266 } else if remaining.starts_with("tz") {
36267 result.push_str("z");
36268 i += 2;
36269 } else {
36270 result.push(chars[i]);
36271 i += 1;
36272 }
36273 }
36274 result
36275 }
36276
36277 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
36278 match self.config.dialect {
36279 Some(DialectType::DuckDB) => {
36280 self.write_keyword("EPOCH");
36282 self.write("(");
36283 self.write_keyword("STRPTIME");
36284 self.write("(");
36285 if let Some(this) = &e.this {
36286 self.generate_expression(this)?;
36287 }
36288 if let Some(format) = &e.format {
36289 self.write(", '");
36290 self.write(format);
36291 self.write("'");
36292 }
36293 self.write("))");
36294 }
36295 Some(DialectType::Hive) => {
36296 self.write_keyword("UNIX_TIMESTAMP");
36298 self.write("(");
36299 if let Some(this) = &e.this {
36300 self.generate_expression(this)?;
36301 }
36302 if let Some(format) = &e.format {
36303 let java_fmt = Self::strftime_to_java_format(format);
36304 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
36305 self.write(", '");
36306 self.write(&java_fmt);
36307 self.write("'");
36308 }
36309 }
36310 self.write(")");
36311 }
36312 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
36313 self.write_keyword("UNIX_TIMESTAMP");
36315 self.write("(");
36316 if let Some(this) = &e.this {
36317 self.generate_expression(this)?;
36318 }
36319 if let Some(format) = &e.format {
36320 self.write(", '");
36321 self.write(format);
36322 self.write("'");
36323 }
36324 self.write(")");
36325 }
36326 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36327 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
36330 let java_fmt = Self::strftime_to_java_format(c_fmt);
36331 self.write_keyword("TO_UNIXTIME");
36332 self.write("(");
36333 self.write_keyword("COALESCE");
36334 self.write("(");
36335 self.write_keyword("TRY");
36336 self.write("(");
36337 self.write_keyword("DATE_PARSE");
36338 self.write("(");
36339 self.write_keyword("CAST");
36340 self.write("(");
36341 if let Some(this) = &e.this {
36342 self.generate_expression(this)?;
36343 }
36344 self.write(" ");
36345 self.write_keyword("AS VARCHAR");
36346 self.write("), '");
36347 self.write(c_fmt);
36348 self.write("')), ");
36349 self.write_keyword("PARSE_DATETIME");
36350 self.write("(");
36351 self.write_keyword("DATE_FORMAT");
36352 self.write("(");
36353 self.write_keyword("CAST");
36354 self.write("(");
36355 if let Some(this) = &e.this {
36356 self.generate_expression(this)?;
36357 }
36358 self.write(" ");
36359 self.write_keyword("AS TIMESTAMP");
36360 self.write("), '");
36361 self.write(c_fmt);
36362 self.write("'), '");
36363 self.write(&java_fmt);
36364 self.write("')))");
36365 }
36366 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36367 self.write_keyword("UNIX_TIMESTAMP");
36369 self.write("(");
36370 if let Some(this) = &e.this {
36371 self.generate_expression(this)?;
36372 }
36373 if let Some(format) = &e.format {
36374 let java_fmt = Self::strftime_to_java_format(format);
36375 self.write(", '");
36376 self.write(&java_fmt);
36377 self.write("'");
36378 }
36379 self.write(")");
36380 }
36381 _ => {
36382 self.write_keyword("STR_TO_UNIX");
36384 self.write("(");
36385 if let Some(this) = &e.this {
36386 self.generate_expression(this)?;
36387 }
36388 if let Some(format) = &e.format {
36389 self.write(", '");
36390 self.write(format);
36391 self.write("'");
36392 }
36393 self.write(")");
36394 }
36395 }
36396 Ok(())
36397 }
36398
36399 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
36400 self.write_keyword("STRING_TO_ARRAY");
36402 self.write("(");
36403 self.generate_expression(&e.this)?;
36404 if let Some(expression) = &e.expression {
36405 self.write(", ");
36406 self.generate_expression(expression)?;
36407 }
36408 if let Some(null_val) = &e.null {
36409 self.write(", ");
36410 self.generate_expression(null_val)?;
36411 }
36412 self.write(")");
36413 Ok(())
36414 }
36415
36416 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
36417 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
36418 self.write_keyword("OBJECT_CONSTRUCT");
36420 self.write("(");
36421 for (i, (name, expr)) in e.fields.iter().enumerate() {
36422 if i > 0 {
36423 self.write(", ");
36424 }
36425 if let Some(name) = name {
36426 self.write("'");
36427 self.write(name);
36428 self.write("'");
36429 self.write(", ");
36430 } else {
36431 self.write("'_");
36432 self.write(&i.to_string());
36433 self.write("'");
36434 self.write(", ");
36435 }
36436 self.generate_expression(expr)?;
36437 }
36438 self.write(")");
36439 } else if self.config.struct_curly_brace_notation {
36440 self.write("{");
36442 for (i, (name, expr)) in e.fields.iter().enumerate() {
36443 if i > 0 {
36444 self.write(", ");
36445 }
36446 if let Some(name) = name {
36447 self.write("'");
36449 self.write(name);
36450 self.write("'");
36451 self.write(": ");
36452 } else {
36453 self.write("'_");
36455 self.write(&i.to_string());
36456 self.write("'");
36457 self.write(": ");
36458 }
36459 self.generate_expression(expr)?;
36460 }
36461 self.write("}");
36462 } else {
36463 let value_as_name = matches!(
36467 self.config.dialect,
36468 Some(DialectType::BigQuery)
36469 | Some(DialectType::Spark)
36470 | Some(DialectType::Databricks)
36471 | Some(DialectType::Hive)
36472 );
36473 self.write_keyword("STRUCT");
36474 self.write("(");
36475 for (i, (name, expr)) in e.fields.iter().enumerate() {
36476 if i > 0 {
36477 self.write(", ");
36478 }
36479 if let Some(name) = name {
36480 if value_as_name {
36481 self.generate_expression(expr)?;
36483 self.write_space();
36484 self.write_keyword("AS");
36485 self.write_space();
36486 let needs_quoting = name.contains(' ') || name.contains('-');
36488 if needs_quoting {
36489 if matches!(
36490 self.config.dialect,
36491 Some(DialectType::Spark)
36492 | Some(DialectType::Databricks)
36493 | Some(DialectType::Hive)
36494 ) {
36495 self.write("`");
36496 self.write(name);
36497 self.write("`");
36498 } else {
36499 self.write(name);
36500 }
36501 } else {
36502 self.write(name);
36503 }
36504 } else {
36505 self.write(name);
36507 self.write_space();
36508 self.write_keyword("AS");
36509 self.write_space();
36510 self.generate_expression(expr)?;
36511 }
36512 } else {
36513 self.generate_expression(expr)?;
36514 }
36515 }
36516 self.write(")");
36517 }
36518 Ok(())
36519 }
36520
36521 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
36522 self.write_keyword("STUFF");
36524 self.write("(");
36525 self.generate_expression(&e.this)?;
36526 if let Some(start) = &e.start {
36527 self.write(", ");
36528 self.generate_expression(start)?;
36529 }
36530 if let Some(length) = e.length {
36531 self.write(", ");
36532 self.write(&length.to_string());
36533 }
36534 self.write(", ");
36535 self.generate_expression(&e.expression)?;
36536 self.write(")");
36537 Ok(())
36538 }
36539
36540 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
36541 self.write_keyword("SUBSTRING_INDEX");
36543 self.write("(");
36544 self.generate_expression(&e.this)?;
36545 if let Some(delimiter) = &e.delimiter {
36546 self.write(", ");
36547 self.generate_expression(delimiter)?;
36548 }
36549 if let Some(count) = &e.count {
36550 self.write(", ");
36551 self.generate_expression(count)?;
36552 }
36553 self.write(")");
36554 Ok(())
36555 }
36556
36557 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
36558 self.write_keyword("SUMMARIZE");
36560 if e.table.is_some() {
36561 self.write_space();
36562 self.write_keyword("TABLE");
36563 }
36564 self.write_space();
36565 self.generate_expression(&e.this)?;
36566 Ok(())
36567 }
36568
36569 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
36570 self.write_keyword("SYSTIMESTAMP");
36572 Ok(())
36573 }
36574
36575 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
36576 if let Some(this) = &e.this {
36578 self.generate_expression(this)?;
36579 }
36580 if !e.columns.is_empty() {
36581 self.write("(");
36582 for (i, col) in e.columns.iter().enumerate() {
36583 if i > 0 {
36584 self.write(", ");
36585 }
36586 self.generate_expression(col)?;
36587 }
36588 self.write(")");
36589 }
36590 Ok(())
36591 }
36592
36593 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
36594 self.write_keyword("TABLE");
36596 self.write("(");
36597 self.generate_expression(&e.this)?;
36598 self.write(")");
36599 if let Some(alias) = &e.alias {
36600 self.write_space();
36601 self.write_keyword("AS");
36602 self.write_space();
36603 self.write(alias);
36604 }
36605 Ok(())
36606 }
36607
36608 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
36609 self.write_keyword("ROWS FROM");
36611 self.write(" (");
36612 for (i, expr) in e.expressions.iter().enumerate() {
36613 if i > 0 {
36614 self.write(", ");
36615 }
36616 match expr {
36620 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
36621 self.generate_expression(&tuple.expressions[0])?;
36623 self.write_space();
36624 self.write_keyword("AS");
36625 self.write_space();
36626 self.generate_expression(&tuple.expressions[1])?;
36627 }
36628 _ => {
36629 self.generate_expression(expr)?;
36630 }
36631 }
36632 }
36633 self.write(")");
36634 if e.ordinality {
36635 self.write_space();
36636 self.write_keyword("WITH ORDINALITY");
36637 }
36638 if let Some(alias) = &e.alias {
36639 self.write_space();
36640 self.write_keyword("AS");
36641 self.write_space();
36642 self.generate_expression(alias)?;
36643 }
36644 Ok(())
36645 }
36646
36647 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
36648 use crate::dialects::DialectType;
36649
36650 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
36652 if self.config.alias_post_tablesample {
36654 if let Expression::Subquery(ref s) = **this {
36656 if let Some(ref alias) = s.alias {
36657 let mut subquery_no_alias = (**s).clone();
36659 subquery_no_alias.alias = None;
36660 subquery_no_alias.column_aliases = Vec::new();
36661 self.generate_expression(&Expression::Subquery(Box::new(
36662 subquery_no_alias,
36663 )))?;
36664 self.write_space();
36665 self.write_keyword(self.config.tablesample_keywords);
36666 self.generate_sample_body(sample)?;
36667 if let Some(ref seed) = sample.seed {
36668 self.write_space();
36669 let use_seed = sample.use_seed_keyword
36670 && !matches!(
36671 self.config.dialect,
36672 Some(crate::dialects::DialectType::Databricks)
36673 | Some(crate::dialects::DialectType::Spark)
36674 );
36675 if use_seed {
36676 self.write_keyword("SEED");
36677 } else {
36678 self.write_keyword("REPEATABLE");
36679 }
36680 self.write(" (");
36681 self.generate_expression(seed)?;
36682 self.write(")");
36683 }
36684 self.write_space();
36685 self.write_keyword("AS");
36686 self.write_space();
36687 self.generate_identifier(alias)?;
36688 return Ok(());
36689 }
36690 } else if let Expression::Alias(ref a) = **this {
36691 self.generate_expression(&a.this)?;
36693 self.write_space();
36694 self.write_keyword(self.config.tablesample_keywords);
36695 self.generate_sample_body(sample)?;
36696 if let Some(ref seed) = sample.seed {
36697 self.write_space();
36698 let use_seed = sample.use_seed_keyword
36699 && !matches!(
36700 self.config.dialect,
36701 Some(crate::dialects::DialectType::Databricks)
36702 | Some(crate::dialects::DialectType::Spark)
36703 );
36704 if use_seed {
36705 self.write_keyword("SEED");
36706 } else {
36707 self.write_keyword("REPEATABLE");
36708 }
36709 self.write(" (");
36710 self.generate_expression(seed)?;
36711 self.write(")");
36712 }
36713 self.write_space();
36715 self.write_keyword("AS");
36716 self.write_space();
36717 self.generate_identifier(&a.alias)?;
36718 return Ok(());
36719 }
36720 }
36721 self.generate_expression(this)?;
36723 self.write_space();
36724 self.write_keyword(self.config.tablesample_keywords);
36725 self.generate_sample_body(sample)?;
36726 if let Some(ref seed) = sample.seed {
36728 self.write_space();
36729 let use_seed = sample.use_seed_keyword
36731 && !matches!(
36732 self.config.dialect,
36733 Some(crate::dialects::DialectType::Databricks)
36734 | Some(crate::dialects::DialectType::Spark)
36735 );
36736 if use_seed {
36737 self.write_keyword("SEED");
36738 } else {
36739 self.write_keyword("REPEATABLE");
36740 }
36741 self.write(" (");
36742 self.generate_expression(seed)?;
36743 self.write(")");
36744 }
36745 return Ok(());
36746 }
36747
36748 self.write_keyword(self.config.tablesample_keywords);
36750 if let Some(method) = &e.method {
36751 self.write_space();
36752 self.write_keyword(method);
36753 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
36754 self.write_space();
36756 self.write_keyword("BERNOULLI");
36757 }
36758 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
36759 self.write_space();
36760 self.write_keyword("BUCKET");
36761 self.write_space();
36762 self.generate_expression(numerator)?;
36763 self.write_space();
36764 self.write_keyword("OUT OF");
36765 self.write_space();
36766 self.generate_expression(denominator)?;
36767 if let Some(field) = &e.bucket_field {
36768 self.write_space();
36769 self.write_keyword("ON");
36770 self.write_space();
36771 self.generate_expression(field)?;
36772 }
36773 } else if !e.expressions.is_empty() {
36774 self.write(" (");
36775 for (i, expr) in e.expressions.iter().enumerate() {
36776 if i > 0 {
36777 self.write(", ");
36778 }
36779 self.generate_expression(expr)?;
36780 }
36781 self.write(")");
36782 } else if let Some(percent) = &e.percent {
36783 self.write(" (");
36784 self.generate_expression(percent)?;
36785 self.write_space();
36786 self.write_keyword("PERCENT");
36787 self.write(")");
36788 }
36789 Ok(())
36790 }
36791
36792 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
36793 if let Some(prefix) = &e.prefix {
36795 self.generate_expression(prefix)?;
36796 }
36797 if let Some(this) = &e.this {
36798 self.generate_expression(this)?;
36799 }
36800 if let Some(postfix) = &e.postfix {
36801 self.generate_expression(postfix)?;
36802 }
36803 Ok(())
36804 }
36805
36806 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
36807 self.write_keyword("TAG");
36809 self.write(" (");
36810 for (i, expr) in e.expressions.iter().enumerate() {
36811 if i > 0 {
36812 self.write(", ");
36813 }
36814 self.generate_expression(expr)?;
36815 }
36816 self.write(")");
36817 Ok(())
36818 }
36819
36820 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
36821 if let Some(this) = &e.this {
36823 self.generate_expression(this)?;
36824 self.write_space();
36825 }
36826 self.write_keyword("TEMPORARY");
36827 Ok(())
36828 }
36829
36830 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
36833 self.write_keyword("TIME");
36835 self.write("(");
36836 self.generate_expression(&e.this)?;
36837 self.write(")");
36838 Ok(())
36839 }
36840
36841 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
36842 self.write_keyword("TIME_ADD");
36844 self.write("(");
36845 self.generate_expression(&e.this)?;
36846 self.write(", ");
36847 self.generate_expression(&e.expression)?;
36848 if let Some(unit) = &e.unit {
36849 self.write(", ");
36850 self.write_keyword(unit);
36851 }
36852 self.write(")");
36853 Ok(())
36854 }
36855
36856 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
36857 self.write_keyword("TIME_DIFF");
36859 self.write("(");
36860 self.generate_expression(&e.this)?;
36861 self.write(", ");
36862 self.generate_expression(&e.expression)?;
36863 if let Some(unit) = &e.unit {
36864 self.write(", ");
36865 self.write_keyword(unit);
36866 }
36867 self.write(")");
36868 Ok(())
36869 }
36870
36871 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
36872 self.write_keyword("TIME_FROM_PARTS");
36874 self.write("(");
36875 let mut first = true;
36876 if let Some(hour) = &e.hour {
36877 self.generate_expression(hour)?;
36878 first = false;
36879 }
36880 if let Some(minute) = &e.min {
36881 if !first {
36882 self.write(", ");
36883 }
36884 self.generate_expression(minute)?;
36885 first = false;
36886 }
36887 if let Some(second) = &e.sec {
36888 if !first {
36889 self.write(", ");
36890 }
36891 self.generate_expression(second)?;
36892 first = false;
36893 }
36894 if let Some(ns) = &e.nano {
36895 if !first {
36896 self.write(", ");
36897 }
36898 self.generate_expression(ns)?;
36899 }
36900 self.write(")");
36901 Ok(())
36902 }
36903
36904 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
36905 self.write_keyword("TIME_SLICE");
36907 self.write("(");
36908 self.generate_expression(&e.this)?;
36909 self.write(", ");
36910 self.generate_expression(&e.expression)?;
36911 self.write(", ");
36912 self.write_keyword(&e.unit);
36913 self.write(")");
36914 Ok(())
36915 }
36916
36917 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
36918 self.write_keyword("TIME_STR_TO_TIME");
36920 self.write("(");
36921 self.generate_expression(&e.this)?;
36922 self.write(")");
36923 Ok(())
36924 }
36925
36926 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
36927 self.write_keyword("TIME_SUB");
36929 self.write("(");
36930 self.generate_expression(&e.this)?;
36931 self.write(", ");
36932 self.generate_expression(&e.expression)?;
36933 if let Some(unit) = &e.unit {
36934 self.write(", ");
36935 self.write_keyword(unit);
36936 }
36937 self.write(")");
36938 Ok(())
36939 }
36940
36941 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
36942 match self.config.dialect {
36943 Some(DialectType::Exasol) => {
36944 self.write_keyword("TO_CHAR");
36946 self.write("(");
36947 self.generate_expression(&e.this)?;
36948 self.write(", '");
36949 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
36950 self.write("'");
36951 self.write(")");
36952 }
36953 Some(DialectType::PostgreSQL)
36954 | Some(DialectType::Redshift)
36955 | Some(DialectType::Materialize) => {
36956 self.write_keyword("TO_CHAR");
36958 self.write("(");
36959 self.generate_expression(&e.this)?;
36960 self.write(", '");
36961 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
36962 self.write("'");
36963 self.write(")");
36964 }
36965 Some(DialectType::Oracle) => {
36966 self.write_keyword("TO_CHAR");
36968 self.write("(");
36969 self.generate_expression(&e.this)?;
36970 self.write(", '");
36971 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
36972 self.write("'");
36973 self.write(")");
36974 }
36975 Some(DialectType::Drill) => {
36976 self.write_keyword("TO_CHAR");
36978 self.write("(");
36979 self.generate_expression(&e.this)?;
36980 self.write(", '");
36981 self.write(&Self::strftime_to_java_format(&e.format));
36982 self.write("'");
36983 self.write(")");
36984 }
36985 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
36986 self.write_keyword("FORMAT");
36988 self.write("(");
36989 self.generate_expression(&e.this)?;
36990 self.write(", '");
36991 self.write(&Self::strftime_to_tsql_format(&e.format));
36992 self.write("'");
36993 self.write(")");
36994 }
36995 Some(DialectType::DuckDB) => {
36996 self.write_keyword("STRFTIME");
36998 self.write("(");
36999 self.generate_expression(&e.this)?;
37000 self.write(", '");
37001 self.write(&e.format);
37002 self.write("'");
37003 self.write(")");
37004 }
37005 Some(DialectType::BigQuery) => {
37006 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
37009 self.write_keyword("FORMAT_DATE");
37010 self.write("('");
37011 self.write(&fmt);
37012 self.write("', ");
37013 self.generate_expression(&e.this)?;
37014 self.write(")");
37015 }
37016 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
37017 self.write_keyword("DATE_FORMAT");
37019 self.write("(");
37020 self.generate_expression(&e.this)?;
37021 self.write(", '");
37022 self.write(&Self::strftime_to_java_format(&e.format));
37023 self.write("'");
37024 self.write(")");
37025 }
37026 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
37027 self.write_keyword("DATE_FORMAT");
37029 self.write("(");
37030 self.generate_expression(&e.this)?;
37031 self.write(", '");
37032 self.write(&e.format);
37033 self.write("'");
37034 self.write(")");
37035 }
37036 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
37037 self.write_keyword("DATE_FORMAT");
37039 self.write("(");
37040 self.generate_expression(&e.this)?;
37041 self.write(", '");
37042 self.write(&e.format);
37043 self.write("'");
37044 self.write(")");
37045 }
37046 _ => {
37047 self.write_keyword("TIME_TO_STR");
37049 self.write("(");
37050 self.generate_expression(&e.this)?;
37051 self.write(", '");
37052 self.write(&e.format);
37053 self.write("'");
37054 self.write(")");
37055 }
37056 }
37057 Ok(())
37058 }
37059
37060 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
37061 match self.config.dialect {
37062 Some(DialectType::DuckDB) => {
37063 self.write_keyword("EPOCH");
37065 self.write("(");
37066 self.generate_expression(&e.this)?;
37067 self.write(")");
37068 }
37069 Some(DialectType::Hive)
37070 | Some(DialectType::Spark)
37071 | Some(DialectType::Databricks)
37072 | Some(DialectType::Doris)
37073 | Some(DialectType::StarRocks)
37074 | Some(DialectType::Drill) => {
37075 self.write_keyword("UNIX_TIMESTAMP");
37077 self.write("(");
37078 self.generate_expression(&e.this)?;
37079 self.write(")");
37080 }
37081 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37082 self.write_keyword("TO_UNIXTIME");
37084 self.write("(");
37085 self.generate_expression(&e.this)?;
37086 self.write(")");
37087 }
37088 _ => {
37089 self.write_keyword("TIME_TO_UNIX");
37091 self.write("(");
37092 self.generate_expression(&e.this)?;
37093 self.write(")");
37094 }
37095 }
37096 Ok(())
37097 }
37098
37099 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
37100 match self.config.dialect {
37101 Some(DialectType::Hive) => {
37102 self.write_keyword("TO_DATE");
37104 self.write("(");
37105 self.generate_expression(&e.this)?;
37106 self.write(")");
37107 }
37108 _ => {
37109 self.write_keyword("TIME_STR_TO_DATE");
37111 self.write("(");
37112 self.generate_expression(&e.this)?;
37113 self.write(")");
37114 }
37115 }
37116 Ok(())
37117 }
37118
37119 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
37120 self.write_keyword("TIME_TRUNC");
37122 self.write("(");
37123 self.generate_expression(&e.this)?;
37124 self.write(", ");
37125 self.write_keyword(&e.unit);
37126 self.write(")");
37127 Ok(())
37128 }
37129
37130 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
37131 if let Some(unit) = &e.unit {
37133 self.write_keyword(unit);
37134 }
37135 Ok(())
37136 }
37137
37138 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
37142 use crate::dialects::DialectType;
37143 use crate::expressions::Literal;
37144
37145 match self.config.dialect {
37146 Some(DialectType::Exasol) => {
37148 self.write_keyword("TO_TIMESTAMP");
37149 self.write("(");
37150 if let Some(this) = &e.this {
37152 match this.as_ref() {
37153 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
37154 let Literal::String(s) = lit.as_ref() else {
37155 unreachable!()
37156 };
37157 self.write("'");
37158 self.write(s);
37159 self.write("'");
37160 }
37161 _ => {
37162 self.generate_expression(this)?;
37163 }
37164 }
37165 }
37166 self.write(")");
37167 }
37168 _ => {
37170 self.write_keyword("TIMESTAMP");
37171 self.write("(");
37172 if let Some(this) = &e.this {
37173 self.generate_expression(this)?;
37174 }
37175 if let Some(zone) = &e.zone {
37176 self.write(", ");
37177 self.generate_expression(zone)?;
37178 }
37179 self.write(")");
37180 }
37181 }
37182 Ok(())
37183 }
37184
37185 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
37186 self.write_keyword("TIMESTAMP_ADD");
37188 self.write("(");
37189 self.generate_expression(&e.this)?;
37190 self.write(", ");
37191 self.generate_expression(&e.expression)?;
37192 if let Some(unit) = &e.unit {
37193 self.write(", ");
37194 self.write_keyword(unit);
37195 }
37196 self.write(")");
37197 Ok(())
37198 }
37199
37200 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
37201 self.write_keyword("TIMESTAMP_DIFF");
37203 self.write("(");
37204 self.generate_expression(&e.this)?;
37205 self.write(", ");
37206 self.generate_expression(&e.expression)?;
37207 if let Some(unit) = &e.unit {
37208 self.write(", ");
37209 self.write_keyword(unit);
37210 }
37211 self.write(")");
37212 Ok(())
37213 }
37214
37215 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
37216 self.write_keyword("TIMESTAMP_FROM_PARTS");
37218 self.write("(");
37219 if let Some(this) = &e.this {
37220 self.generate_expression(this)?;
37221 }
37222 if let Some(expression) = &e.expression {
37223 self.write(", ");
37224 self.generate_expression(expression)?;
37225 }
37226 if let Some(zone) = &e.zone {
37227 self.write(", ");
37228 self.generate_expression(zone)?;
37229 }
37230 if let Some(milli) = &e.milli {
37231 self.write(", ");
37232 self.generate_expression(milli)?;
37233 }
37234 self.write(")");
37235 Ok(())
37236 }
37237
37238 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
37239 self.write_keyword("TIMESTAMP_SUB");
37241 self.write("(");
37242 self.generate_expression(&e.this)?;
37243 self.write(", ");
37244 self.write_keyword("INTERVAL");
37245 self.write_space();
37246 self.generate_expression(&e.expression)?;
37247 if let Some(unit) = &e.unit {
37248 self.write_space();
37249 self.write_keyword(unit);
37250 }
37251 self.write(")");
37252 Ok(())
37253 }
37254
37255 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
37256 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
37258 self.write("(");
37259 if let Some(zone) = &e.zone {
37260 self.generate_expression(zone)?;
37261 }
37262 self.write(")");
37263 Ok(())
37264 }
37265
37266 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
37267 self.write_keyword("TO_BINARY");
37269 self.write("(");
37270 self.generate_expression(&e.this)?;
37271 if let Some(format) = &e.format {
37272 self.write(", '");
37273 self.write(format);
37274 self.write("'");
37275 }
37276 self.write(")");
37277 Ok(())
37278 }
37279
37280 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
37281 self.write_keyword("TO_BOOLEAN");
37283 self.write("(");
37284 self.generate_expression(&e.this)?;
37285 self.write(")");
37286 Ok(())
37287 }
37288
37289 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
37290 self.write_keyword("TO_CHAR");
37292 self.write("(");
37293 self.generate_expression(&e.this)?;
37294 if let Some(format) = &e.format {
37295 self.write(", '");
37296 self.write(format);
37297 self.write("'");
37298 }
37299 if let Some(nlsparam) = &e.nlsparam {
37300 self.write(", ");
37301 self.generate_expression(nlsparam)?;
37302 }
37303 self.write(")");
37304 Ok(())
37305 }
37306
37307 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
37308 self.write_keyword("TO_DECFLOAT");
37310 self.write("(");
37311 self.generate_expression(&e.this)?;
37312 if let Some(format) = &e.format {
37313 self.write(", '");
37314 self.write(format);
37315 self.write("'");
37316 }
37317 self.write(")");
37318 Ok(())
37319 }
37320
37321 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
37322 self.write_keyword("TO_DOUBLE");
37324 self.write("(");
37325 self.generate_expression(&e.this)?;
37326 if let Some(format) = &e.format {
37327 self.write(", '");
37328 self.write(format);
37329 self.write("'");
37330 }
37331 self.write(")");
37332 Ok(())
37333 }
37334
37335 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
37336 self.write_keyword("TO_FILE");
37338 self.write("(");
37339 self.generate_expression(&e.this)?;
37340 if let Some(path) = &e.path {
37341 self.write(", ");
37342 self.generate_expression(path)?;
37343 }
37344 self.write(")");
37345 Ok(())
37346 }
37347
37348 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
37349 let is_safe = e.safe.is_some();
37352 if is_safe {
37353 self.write_keyword("TRY_TO_NUMBER");
37354 } else {
37355 self.write_keyword("TO_NUMBER");
37356 }
37357 self.write("(");
37358 self.generate_expression(&e.this)?;
37359 let precision_is_snowflake_default = e.precision.is_none()
37360 || matches!(
37361 e.precision.as_deref(),
37362 Some(Expression::Literal(lit))
37363 if matches!(lit.as_ref(), Literal::Number(n) if n == "0")
37364 );
37365 let is_snowflake_default_precision =
37366 matches!(self.config.dialect, Some(DialectType::Snowflake))
37367 && e.nlsparam.is_none()
37368 && e.scale.is_none()
37369 && matches!(
37370 e.format.as_deref(),
37371 Some(Expression::Literal(lit))
37372 if matches!(lit.as_ref(), Literal::Number(n) if n == "38")
37373 )
37374 && precision_is_snowflake_default;
37375
37376 if !is_snowflake_default_precision {
37377 if let Some(format) = &e.format {
37378 self.write(", ");
37379 self.generate_expression(format)?;
37380 }
37381 if let Some(nlsparam) = &e.nlsparam {
37382 self.write(", ");
37383 self.generate_expression(nlsparam)?;
37384 }
37385 if let Some(precision) = &e.precision {
37386 self.write(", ");
37387 self.generate_expression(precision)?;
37388 }
37389 if let Some(scale) = &e.scale {
37390 self.write(", ");
37391 self.generate_expression(scale)?;
37392 }
37393 }
37394 self.write(")");
37395 Ok(())
37396 }
37397
37398 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
37399 self.write_keyword("TO_TABLE");
37401 self.write_space();
37402 self.generate_expression(&e.this)?;
37403 Ok(())
37404 }
37405
37406 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
37407 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
37409 Expression::Identifier(id) => id.name.clone(),
37410 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
37411 let Literal::String(s) = lit.as_ref() else {
37412 unreachable!()
37413 };
37414 s.clone()
37415 }
37416 _ => String::new(),
37417 });
37418
37419 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
37420 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
37421 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
37422 matches!(m.as_ref(), Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)))
37423 });
37424
37425 let use_start_transaction = matches!(
37427 self.config.dialect,
37428 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
37429 );
37430 let strip_transaction = matches!(
37432 self.config.dialect,
37433 Some(DialectType::Snowflake)
37434 | Some(DialectType::PostgreSQL)
37435 | Some(DialectType::Redshift)
37436 | Some(DialectType::MySQL)
37437 | Some(DialectType::Hive)
37438 | Some(DialectType::Spark)
37439 | Some(DialectType::Databricks)
37440 | Some(DialectType::DuckDB)
37441 | Some(DialectType::Oracle)
37442 | Some(DialectType::Doris)
37443 | Some(DialectType::StarRocks)
37444 | Some(DialectType::Materialize)
37445 | Some(DialectType::ClickHouse)
37446 );
37447
37448 if is_start || use_start_transaction {
37449 self.write_keyword("START TRANSACTION");
37451 if let Some(modes) = &e.modes {
37452 self.write_space();
37453 self.generate_expression(modes)?;
37454 }
37455 } else {
37456 self.write_keyword("BEGIN");
37458
37459 let is_kind = e.this.as_ref().map_or(false, |t| {
37461 if let Expression::Identifier(id) = t.as_ref() {
37462 id.name.eq_ignore_ascii_case("DEFERRED")
37463 || id.name.eq_ignore_ascii_case("IMMEDIATE")
37464 || id.name.eq_ignore_ascii_case("EXCLUSIVE")
37465 } else {
37466 false
37467 }
37468 });
37469
37470 if is_kind {
37472 if let Some(this) = &e.this {
37473 self.write_space();
37474 if let Expression::Identifier(id) = this.as_ref() {
37475 self.write_keyword(&id.name);
37476 }
37477 }
37478 }
37479
37480 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
37482 self.write_space();
37483 self.write_keyword("TRANSACTION");
37484 }
37485
37486 if !is_kind {
37488 if let Some(this) = &e.this {
37489 self.write_space();
37490 self.generate_expression(this)?;
37491 }
37492 }
37493
37494 if has_with_mark {
37496 self.write_space();
37497 self.write_keyword("WITH MARK");
37498 if let Some(Expression::Literal(lit)) = e.mark.as_deref() {
37499 if let Literal::String(desc) = lit.as_ref() {
37500 if !desc.is_empty() {
37501 self.write_space();
37502 self.write(&format!("'{}'", desc));
37503 }
37504 }
37505 }
37506 }
37507
37508 if let Some(modes) = &e.modes {
37510 self.write_space();
37511 self.generate_expression(modes)?;
37512 }
37513 }
37514 Ok(())
37515 }
37516
37517 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
37518 self.write_keyword("TRANSFORM");
37520 self.write("(");
37521 self.generate_expression(&e.this)?;
37522 self.write(", ");
37523 self.generate_expression(&e.expression)?;
37524 self.write(")");
37525 Ok(())
37526 }
37527
37528 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
37529 self.write_keyword("TRANSFORM");
37531 self.write("(");
37532 if self.config.pretty && !e.expressions.is_empty() {
37533 self.indent_level += 1;
37534 for (i, expr) in e.expressions.iter().enumerate() {
37535 if i > 0 {
37536 self.write(",");
37537 }
37538 self.write_newline();
37539 self.write_indent();
37540 self.generate_expression(expr)?;
37541 }
37542 self.indent_level -= 1;
37543 self.write_newline();
37544 self.write(")");
37545 } else {
37546 for (i, expr) in e.expressions.iter().enumerate() {
37547 if i > 0 {
37548 self.write(", ");
37549 }
37550 self.generate_expression(expr)?;
37551 }
37552 self.write(")");
37553 }
37554 Ok(())
37555 }
37556
37557 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
37558 use crate::dialects::DialectType;
37559 if let Some(this) = &e.this {
37561 self.generate_expression(this)?;
37562 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
37563 self.write_space();
37564 }
37565 }
37566 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
37567 self.write_keyword("TRANSIENT");
37568 }
37569 Ok(())
37570 }
37571
37572 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
37573 self.write_keyword("TRANSLATE");
37575 self.write("(");
37576 self.generate_expression(&e.this)?;
37577 if let Some(from) = &e.from_ {
37578 self.write(", ");
37579 self.generate_expression(from)?;
37580 }
37581 if let Some(to) = &e.to {
37582 self.write(", ");
37583 self.generate_expression(to)?;
37584 }
37585 self.write(")");
37586 Ok(())
37587 }
37588
37589 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
37590 self.write_keyword("TRANSLATE");
37592 self.write("(");
37593 self.generate_expression(&e.this)?;
37594 self.write_space();
37595 self.write_keyword("USING");
37596 self.write_space();
37597 self.generate_expression(&e.expression)?;
37598 if e.with_error.is_some() {
37599 self.write_space();
37600 self.write_keyword("WITH ERROR");
37601 }
37602 self.write(")");
37603 Ok(())
37604 }
37605
37606 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
37607 self.write_keyword("TRUNCATE TABLE");
37609 self.write_space();
37610 for (i, expr) in e.expressions.iter().enumerate() {
37611 if i > 0 {
37612 self.write(", ");
37613 }
37614 self.generate_expression(expr)?;
37615 }
37616 Ok(())
37617 }
37618
37619 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
37620 self.write_keyword("TRY_BASE64_DECODE_BINARY");
37622 self.write("(");
37623 self.generate_expression(&e.this)?;
37624 if let Some(alphabet) = &e.alphabet {
37625 self.write(", ");
37626 self.generate_expression(alphabet)?;
37627 }
37628 self.write(")");
37629 Ok(())
37630 }
37631
37632 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
37633 self.write_keyword("TRY_BASE64_DECODE_STRING");
37635 self.write("(");
37636 self.generate_expression(&e.this)?;
37637 if let Some(alphabet) = &e.alphabet {
37638 self.write(", ");
37639 self.generate_expression(alphabet)?;
37640 }
37641 self.write(")");
37642 Ok(())
37643 }
37644
37645 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
37646 self.write_keyword("TRY_TO_DECFLOAT");
37648 self.write("(");
37649 self.generate_expression(&e.this)?;
37650 if let Some(format) = &e.format {
37651 self.write(", '");
37652 self.write(format);
37653 self.write("'");
37654 }
37655 self.write(")");
37656 Ok(())
37657 }
37658
37659 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
37660 self.write_keyword("TS_OR_DS_ADD");
37662 self.write("(");
37663 self.generate_expression(&e.this)?;
37664 self.write(", ");
37665 self.generate_expression(&e.expression)?;
37666 if let Some(unit) = &e.unit {
37667 self.write(", ");
37668 self.write_keyword(unit);
37669 }
37670 if let Some(return_type) = &e.return_type {
37671 self.write(", ");
37672 self.generate_expression(return_type)?;
37673 }
37674 self.write(")");
37675 Ok(())
37676 }
37677
37678 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
37679 self.write_keyword("TS_OR_DS_DIFF");
37681 self.write("(");
37682 self.generate_expression(&e.this)?;
37683 self.write(", ");
37684 self.generate_expression(&e.expression)?;
37685 if let Some(unit) = &e.unit {
37686 self.write(", ");
37687 self.write_keyword(unit);
37688 }
37689 self.write(")");
37690 Ok(())
37691 }
37692
37693 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
37694 let default_time_format = "%Y-%m-%d %H:%M:%S";
37695 let default_date_format = "%Y-%m-%d";
37696 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
37697 f != default_time_format && f != default_date_format
37698 });
37699
37700 if has_non_default_format {
37701 let fmt = e.format.as_ref().unwrap();
37703 match self.config.dialect {
37704 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
37705 let str_to_time = crate::expressions::StrToTime {
37708 this: Box::new((*e.this).clone()),
37709 format: fmt.clone(),
37710 zone: None,
37711 safe: None,
37712 target_type: None,
37713 };
37714 self.generate_str_to_time(&str_to_time)?;
37715 }
37716 Some(DialectType::Hive)
37717 | Some(DialectType::Spark)
37718 | Some(DialectType::Databricks) => {
37719 self.write_keyword("TO_DATE");
37721 self.write("(");
37722 self.generate_expression(&e.this)?;
37723 self.write(", '");
37724 self.write(&Self::strftime_to_java_format(fmt));
37725 self.write("')");
37726 }
37727 Some(DialectType::Snowflake) => {
37728 self.write_keyword("TO_DATE");
37730 self.write("(");
37731 self.generate_expression(&e.this)?;
37732 self.write(", '");
37733 self.write(&Self::strftime_to_snowflake_format(fmt));
37734 self.write("')");
37735 }
37736 Some(DialectType::Doris) => {
37737 self.write_keyword("TO_DATE");
37739 self.write("(");
37740 self.generate_expression(&e.this)?;
37741 self.write(")");
37742 }
37743 _ => {
37744 self.write_keyword("CAST");
37746 self.write("(");
37747 let str_to_time = crate::expressions::StrToTime {
37748 this: Box::new((*e.this).clone()),
37749 format: fmt.clone(),
37750 zone: None,
37751 safe: None,
37752 target_type: None,
37753 };
37754 self.generate_str_to_time(&str_to_time)?;
37755 self.write_keyword(" AS ");
37756 self.write_keyword("DATE");
37757 self.write(")");
37758 }
37759 }
37760 } else {
37761 match self.config.dialect {
37763 Some(DialectType::MySQL)
37764 | Some(DialectType::SQLite)
37765 | Some(DialectType::StarRocks) => {
37766 self.write_keyword("DATE");
37768 self.write("(");
37769 self.generate_expression(&e.this)?;
37770 self.write(")");
37771 }
37772 Some(DialectType::Hive)
37773 | Some(DialectType::Spark)
37774 | Some(DialectType::Databricks)
37775 | Some(DialectType::Snowflake)
37776 | Some(DialectType::Doris) => {
37777 self.write_keyword("TO_DATE");
37779 self.write("(");
37780 self.generate_expression(&e.this)?;
37781 self.write(")");
37782 }
37783 Some(DialectType::Presto)
37784 | Some(DialectType::Trino)
37785 | Some(DialectType::Athena) => {
37786 self.write_keyword("CAST");
37788 self.write("(");
37789 self.write_keyword("CAST");
37790 self.write("(");
37791 self.generate_expression(&e.this)?;
37792 self.write_keyword(" AS ");
37793 self.write_keyword("TIMESTAMP");
37794 self.write(")");
37795 self.write_keyword(" AS ");
37796 self.write_keyword("DATE");
37797 self.write(")");
37798 }
37799 Some(DialectType::ClickHouse) => {
37800 self.write_keyword("CAST");
37802 self.write("(");
37803 self.generate_expression(&e.this)?;
37804 self.write_keyword(" AS ");
37805 self.write("Nullable(DATE)");
37806 self.write(")");
37807 }
37808 _ => {
37809 self.write_keyword("CAST");
37811 self.write("(");
37812 self.generate_expression(&e.this)?;
37813 self.write_keyword(" AS ");
37814 self.write_keyword("DATE");
37815 self.write(")");
37816 }
37817 }
37818 }
37819 Ok(())
37820 }
37821
37822 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
37823 self.write_keyword("TS_OR_DS_TO_TIME");
37825 self.write("(");
37826 self.generate_expression(&e.this)?;
37827 if let Some(format) = &e.format {
37828 self.write(", '");
37829 self.write(format);
37830 self.write("'");
37831 }
37832 self.write(")");
37833 Ok(())
37834 }
37835
37836 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
37837 self.write_keyword("UNHEX");
37839 self.write("(");
37840 self.generate_expression(&e.this)?;
37841 if let Some(expression) = &e.expression {
37842 self.write(", ");
37843 self.generate_expression(expression)?;
37844 }
37845 self.write(")");
37846 Ok(())
37847 }
37848
37849 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
37850 self.write("U&");
37852 self.generate_expression(&e.this)?;
37853 if let Some(escape) = &e.escape {
37854 self.write_space();
37855 self.write_keyword("UESCAPE");
37856 self.write_space();
37857 self.generate_expression(escape)?;
37858 }
37859 Ok(())
37860 }
37861
37862 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
37863 self.write_keyword("UNIFORM");
37865 self.write("(");
37866 self.generate_expression(&e.this)?;
37867 self.write(", ");
37868 self.generate_expression(&e.expression)?;
37869 if let Some(gen) = &e.gen {
37870 self.write(", ");
37871 self.generate_expression(gen)?;
37872 }
37873 if let Some(seed) = &e.seed {
37874 self.write(", ");
37875 self.generate_expression(seed)?;
37876 }
37877 self.write(")");
37878 Ok(())
37879 }
37880
37881 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
37882 self.write_keyword("UNIQUE");
37884 if e.nulls.is_some() {
37886 self.write(" NULLS NOT DISTINCT");
37887 }
37888 if let Some(this) = &e.this {
37889 self.write_space();
37890 self.generate_expression(this)?;
37891 }
37892 if let Some(index_type) = &e.index_type {
37893 self.write(" USING ");
37894 self.generate_expression(index_type)?;
37895 }
37896 if let Some(on_conflict) = &e.on_conflict {
37897 self.write_space();
37898 self.generate_expression(on_conflict)?;
37899 }
37900 for opt in &e.options {
37901 self.write_space();
37902 self.generate_expression(opt)?;
37903 }
37904 Ok(())
37905 }
37906
37907 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
37908 self.write_keyword("UNIQUE KEY");
37910 self.write(" (");
37911 for (i, expr) in e.expressions.iter().enumerate() {
37912 if i > 0 {
37913 self.write(", ");
37914 }
37915 self.generate_expression(expr)?;
37916 }
37917 self.write(")");
37918 Ok(())
37919 }
37920
37921 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
37922 self.write_keyword("ROLLUP");
37924 self.write(" (");
37925 for (i, index) in e.expressions.iter().enumerate() {
37926 if i > 0 {
37927 self.write(", ");
37928 }
37929 self.generate_identifier(&index.name)?;
37930 self.write("(");
37931 for (j, col) in index.expressions.iter().enumerate() {
37932 if j > 0 {
37933 self.write(", ");
37934 }
37935 self.generate_identifier(col)?;
37936 }
37937 self.write(")");
37938 }
37939 self.write(")");
37940 Ok(())
37941 }
37942
37943 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
37944 match self.config.dialect {
37945 Some(DialectType::DuckDB) => {
37946 self.write_keyword("STRFTIME");
37948 self.write("(");
37949 self.write_keyword("TO_TIMESTAMP");
37950 self.write("(");
37951 self.generate_expression(&e.this)?;
37952 self.write("), '");
37953 if let Some(format) = &e.format {
37954 self.write(format);
37955 }
37956 self.write("')");
37957 }
37958 Some(DialectType::Hive) => {
37959 self.write_keyword("FROM_UNIXTIME");
37961 self.write("(");
37962 self.generate_expression(&e.this)?;
37963 if let Some(format) = &e.format {
37964 if format != "yyyy-MM-dd HH:mm:ss" {
37965 self.write(", '");
37966 self.write(format);
37967 self.write("'");
37968 }
37969 }
37970 self.write(")");
37971 }
37972 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37973 self.write_keyword("DATE_FORMAT");
37975 self.write("(");
37976 self.write_keyword("FROM_UNIXTIME");
37977 self.write("(");
37978 self.generate_expression(&e.this)?;
37979 self.write("), '");
37980 if let Some(format) = &e.format {
37981 self.write(format);
37982 }
37983 self.write("')");
37984 }
37985 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
37986 self.write_keyword("FROM_UNIXTIME");
37988 self.write("(");
37989 self.generate_expression(&e.this)?;
37990 if let Some(format) = &e.format {
37991 self.write(", '");
37992 self.write(format);
37993 self.write("'");
37994 }
37995 self.write(")");
37996 }
37997 _ => {
37998 self.write_keyword("UNIX_TO_STR");
38000 self.write("(");
38001 self.generate_expression(&e.this)?;
38002 if let Some(format) = &e.format {
38003 self.write(", '");
38004 self.write(format);
38005 self.write("'");
38006 }
38007 self.write(")");
38008 }
38009 }
38010 Ok(())
38011 }
38012
38013 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
38014 use crate::dialects::DialectType;
38015 let scale = e.scale.unwrap_or(0); match self.config.dialect {
38018 Some(DialectType::Snowflake) => {
38019 self.write_keyword("TO_TIMESTAMP");
38021 self.write("(");
38022 self.generate_expression(&e.this)?;
38023 if let Some(s) = e.scale {
38024 if s > 0 {
38025 self.write(", ");
38026 self.write(&s.to_string());
38027 }
38028 }
38029 self.write(")");
38030 }
38031 Some(DialectType::BigQuery) => {
38032 match scale {
38035 0 => {
38036 self.write_keyword("TIMESTAMP_SECONDS");
38037 self.write("(");
38038 self.generate_expression(&e.this)?;
38039 self.write(")");
38040 }
38041 3 => {
38042 self.write_keyword("TIMESTAMP_MILLIS");
38043 self.write("(");
38044 self.generate_expression(&e.this)?;
38045 self.write(")");
38046 }
38047 6 => {
38048 self.write_keyword("TIMESTAMP_MICROS");
38049 self.write("(");
38050 self.generate_expression(&e.this)?;
38051 self.write(")");
38052 }
38053 _ => {
38054 self.write_keyword("TIMESTAMP_SECONDS");
38056 self.write("(CAST(");
38057 self.generate_expression(&e.this)?;
38058 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
38059 }
38060 }
38061 }
38062 Some(DialectType::Spark) => {
38063 match scale {
38068 0 => {
38069 self.write_keyword("CAST");
38070 self.write("(");
38071 self.write_keyword("FROM_UNIXTIME");
38072 self.write("(");
38073 self.generate_expression(&e.this)?;
38074 self.write(") ");
38075 self.write_keyword("AS TIMESTAMP");
38076 self.write(")");
38077 }
38078 3 => {
38079 self.write_keyword("TIMESTAMP_MILLIS");
38080 self.write("(");
38081 self.generate_expression(&e.this)?;
38082 self.write(")");
38083 }
38084 6 => {
38085 self.write_keyword("TIMESTAMP_MICROS");
38086 self.write("(");
38087 self.generate_expression(&e.this)?;
38088 self.write(")");
38089 }
38090 _ => {
38091 self.write_keyword("TIMESTAMP_SECONDS");
38092 self.write("(");
38093 self.generate_expression(&e.this)?;
38094 self.write(&format!(" / POWER(10, {}))", scale));
38095 }
38096 }
38097 }
38098 Some(DialectType::Databricks) => {
38099 match scale {
38103 0 => {
38104 self.write_keyword("CAST");
38105 self.write("(");
38106 self.write_keyword("FROM_UNIXTIME");
38107 self.write("(");
38108 self.generate_expression(&e.this)?;
38109 self.write(") ");
38110 self.write_keyword("AS TIMESTAMP");
38111 self.write(")");
38112 }
38113 3 => {
38114 self.write_keyword("TIMESTAMP_MILLIS");
38115 self.write("(");
38116 self.generate_expression(&e.this)?;
38117 self.write(")");
38118 }
38119 6 => {
38120 self.write_keyword("TIMESTAMP_MICROS");
38121 self.write("(");
38122 self.generate_expression(&e.this)?;
38123 self.write(")");
38124 }
38125 _ => {
38126 self.write_keyword("TIMESTAMP_SECONDS");
38127 self.write("(");
38128 self.generate_expression(&e.this)?;
38129 self.write(&format!(" / POWER(10, {}))", scale));
38130 }
38131 }
38132 }
38133 Some(DialectType::Hive) => {
38134 if scale == 0 {
38136 self.write_keyword("FROM_UNIXTIME");
38137 self.write("(");
38138 self.generate_expression(&e.this)?;
38139 self.write(")");
38140 } else {
38141 self.write_keyword("FROM_UNIXTIME");
38142 self.write("(");
38143 self.generate_expression(&e.this)?;
38144 self.write(&format!(" / POWER(10, {})", scale));
38145 self.write(")");
38146 }
38147 }
38148 Some(DialectType::Presto) | Some(DialectType::Trino) => {
38149 if scale == 0 {
38152 self.write_keyword("FROM_UNIXTIME");
38153 self.write("(");
38154 self.generate_expression(&e.this)?;
38155 self.write(")");
38156 } else {
38157 self.write_keyword("FROM_UNIXTIME");
38158 self.write("(CAST(");
38159 self.generate_expression(&e.this)?;
38160 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
38161 }
38162 }
38163 Some(DialectType::DuckDB) => {
38164 match scale {
38168 0 => {
38169 self.write_keyword("TO_TIMESTAMP");
38170 self.write("(");
38171 self.generate_expression(&e.this)?;
38172 self.write(")");
38173 }
38174 3 => {
38175 self.write_keyword("EPOCH_MS");
38176 self.write("(");
38177 self.generate_expression(&e.this)?;
38178 self.write(")");
38179 }
38180 6 => {
38181 self.write_keyword("MAKE_TIMESTAMP");
38182 self.write("(");
38183 self.generate_expression(&e.this)?;
38184 self.write(")");
38185 }
38186 _ => {
38187 self.write_keyword("TO_TIMESTAMP");
38188 self.write("(");
38189 self.generate_expression(&e.this)?;
38190 self.write(&format!(" / POWER(10, {}))", scale));
38191 self.write_keyword(" AT TIME ZONE");
38192 self.write(" 'UTC'");
38193 }
38194 }
38195 }
38196 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
38197 self.write_keyword("FROM_UNIXTIME");
38199 self.write("(");
38200 self.generate_expression(&e.this)?;
38201 self.write(")");
38202 }
38203 Some(DialectType::Oracle) => {
38204 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
38206 self.generate_expression(&e.this)?;
38207 self.write(" / 86400)");
38208 }
38209 Some(DialectType::Redshift) => {
38210 self.write("(TIMESTAMP 'epoch' + ");
38213 if scale == 0 {
38214 self.generate_expression(&e.this)?;
38215 } else {
38216 self.write("(");
38217 self.generate_expression(&e.this)?;
38218 self.write(&format!(" / POWER(10, {}))", scale));
38219 }
38220 self.write(" * INTERVAL '1 SECOND')");
38221 }
38222 Some(DialectType::Exasol) => {
38223 self.write_keyword("FROM_POSIX_TIME");
38225 self.write("(");
38226 self.generate_expression(&e.this)?;
38227 self.write(")");
38228 }
38229 _ => {
38230 self.write_keyword("TO_TIMESTAMP");
38232 self.write("(");
38233 self.generate_expression(&e.this)?;
38234 if let Some(s) = e.scale {
38235 self.write(", ");
38236 self.write(&s.to_string());
38237 }
38238 self.write(")");
38239 }
38240 }
38241 Ok(())
38242 }
38243
38244 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
38245 if !matches!(&*e.this, Expression::Null(_)) {
38247 self.write_keyword("NAME");
38248 self.write_space();
38249 self.generate_expression(&e.this)?;
38250 }
38251 if !e.expressions.is_empty() {
38252 self.write_space();
38253 self.write_keyword("VALUE");
38254 self.write_space();
38255 for (i, expr) in e.expressions.iter().enumerate() {
38256 if i > 0 {
38257 self.write(", ");
38258 }
38259 self.generate_expression(expr)?;
38260 }
38261 }
38262 Ok(())
38263 }
38264
38265 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
38266 if e.wrapped.is_some() {
38268 self.write("(");
38269 }
38270 self.generate_expression(&e.this)?;
38271 if e.wrapped.is_some() {
38272 self.write(")");
38273 }
38274 self.write("(");
38275 for (i, expr) in e.expressions.iter().enumerate() {
38276 if i > 0 {
38277 self.write(", ");
38278 }
38279 self.generate_expression(expr)?;
38280 }
38281 self.write(")");
38282 Ok(())
38283 }
38284
38285 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
38286 self.write_keyword("USING TEMPLATE");
38288 self.write_space();
38289 self.generate_expression(&e.this)?;
38290 Ok(())
38291 }
38292
38293 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
38294 self.write_keyword("UTC_TIME");
38296 Ok(())
38297 }
38298
38299 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
38300 if matches!(
38301 self.config.dialect,
38302 Some(crate::dialects::DialectType::ClickHouse)
38303 ) {
38304 self.write_keyword("CURRENT_TIMESTAMP");
38305 self.write("('UTC')");
38306 } else {
38307 self.write_keyword("UTC_TIMESTAMP");
38308 }
38309 Ok(())
38310 }
38311
38312 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
38313 use crate::dialects::DialectType;
38314 let func_name = match self.config.dialect {
38316 Some(DialectType::Snowflake) => "UUID_STRING",
38317 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
38318 Some(DialectType::BigQuery) => "GENERATE_UUID",
38319 _ => {
38320 if let Some(name) = &e.name {
38321 name.as_str()
38322 } else {
38323 "UUID"
38324 }
38325 }
38326 };
38327 self.write_keyword(func_name);
38328 self.write("(");
38329 if let Some(this) = &e.this {
38330 self.generate_expression(this)?;
38331 }
38332 self.write(")");
38333 Ok(())
38334 }
38335
38336 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
38337 self.write_keyword("MAP");
38339 self.write("(");
38340 let mut first = true;
38341 for (k, v) in e.keys.iter().zip(e.values.iter()) {
38342 if !first {
38343 self.write(", ");
38344 }
38345 self.generate_expression(k)?;
38346 self.write(", ");
38347 self.generate_expression(v)?;
38348 first = false;
38349 }
38350 self.write(")");
38351 Ok(())
38352 }
38353
38354 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
38355 self.write_keyword("VECTOR_SEARCH");
38357 self.write("(");
38358 self.generate_expression(&e.this)?;
38359 if let Some(col) = &e.column_to_search {
38360 self.write(", ");
38361 self.generate_expression(col)?;
38362 }
38363 if let Some(query_table) = &e.query_table {
38364 self.write(", ");
38365 self.generate_expression(query_table)?;
38366 }
38367 if let Some(query_col) = &e.query_column_to_search {
38368 self.write(", ");
38369 self.generate_expression(query_col)?;
38370 }
38371 if let Some(top_k) = &e.top_k {
38372 self.write(", ");
38373 self.generate_expression(top_k)?;
38374 }
38375 if let Some(dist_type) = &e.distance_type {
38376 self.write(", ");
38377 self.generate_expression(dist_type)?;
38378 }
38379 self.write(")");
38380 Ok(())
38381 }
38382
38383 fn generate_version(&mut self, e: &Version) -> Result<()> {
38384 use crate::dialects::DialectType;
38390 let skip_for = matches!(
38391 self.config.dialect,
38392 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
38393 );
38394 if !skip_for {
38395 self.write_keyword("FOR");
38396 self.write_space();
38397 }
38398 match e.this.as_ref() {
38400 Expression::Identifier(ident) => {
38401 self.write_keyword(&ident.name);
38402 }
38403 _ => {
38404 self.generate_expression(&e.this)?;
38405 }
38406 }
38407 self.write_space();
38408 self.write_keyword(&e.kind);
38409 if let Some(expression) = &e.expression {
38410 self.write_space();
38411 self.generate_expression(expression)?;
38412 }
38413 Ok(())
38414 }
38415
38416 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
38417 self.generate_expression(&e.this)?;
38419 Ok(())
38420 }
38421
38422 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
38423 if e.this.is_some() {
38425 self.write_keyword("NOT VOLATILE");
38426 } else {
38427 self.write_keyword("VOLATILE");
38428 }
38429 Ok(())
38430 }
38431
38432 fn generate_watermark_column_constraint(
38433 &mut self,
38434 e: &WatermarkColumnConstraint,
38435 ) -> Result<()> {
38436 self.write_keyword("WATERMARK FOR");
38438 self.write_space();
38439 self.generate_expression(&e.this)?;
38440 self.write_space();
38441 self.write_keyword("AS");
38442 self.write_space();
38443 self.generate_expression(&e.expression)?;
38444 Ok(())
38445 }
38446
38447 fn generate_week(&mut self, e: &Week) -> Result<()> {
38448 self.write_keyword("WEEK");
38450 self.write("(");
38451 self.generate_expression(&e.this)?;
38452 if let Some(mode) = &e.mode {
38453 self.write(", ");
38454 self.generate_expression(mode)?;
38455 }
38456 self.write(")");
38457 Ok(())
38458 }
38459
38460 fn generate_when(&mut self, e: &When) -> Result<()> {
38461 self.write_keyword("WHEN");
38465 self.write_space();
38466
38467 if let Some(matched) = &e.matched {
38469 match matched.as_ref() {
38471 Expression::Boolean(b) if b.value => {
38472 self.write_keyword("MATCHED");
38473 }
38474 _ => {
38475 self.write_keyword("NOT MATCHED");
38476 }
38477 }
38478 } else {
38479 self.write_keyword("NOT MATCHED");
38480 }
38481
38482 if self.config.matched_by_source {
38487 if let Some(source) = &e.source {
38488 if let Expression::Boolean(b) = source.as_ref() {
38489 if b.value {
38490 self.write_space();
38492 self.write_keyword("BY SOURCE");
38493 }
38494 } else {
38496 self.write_space();
38498 self.write_keyword("BY SOURCE");
38499 }
38500 }
38501 }
38502
38503 if let Some(condition) = &e.condition {
38505 self.write_space();
38506 self.write_keyword("AND");
38507 self.write_space();
38508 self.generate_expression(condition)?;
38509 }
38510
38511 self.write_space();
38512 self.write_keyword("THEN");
38513 self.write_space();
38514
38515 self.generate_merge_action(&e.then)?;
38518
38519 Ok(())
38520 }
38521
38522 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
38523 match action {
38524 Expression::Tuple(tuple) => {
38525 let elements = &tuple.expressions;
38526 if elements.is_empty() {
38527 return self.generate_expression(action);
38528 }
38529 match &elements[0] {
38531 Expression::Var(v) if v.this == "INSERT" => {
38532 self.write_keyword("INSERT");
38533 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
38535 self.write(" *");
38536 if let Some(Expression::Where(w)) = elements.get(2) {
38537 self.write_space();
38538 self.generate_where(w)?;
38539 }
38540 } else {
38541 let mut values_idx = 1;
38542 if elements.len() > 1 {
38544 if let Expression::Tuple(cols) = &elements[1] {
38545 if elements.len() > 2 {
38547 self.write(" (");
38549 for (i, col) in cols.expressions.iter().enumerate() {
38550 if i > 0 {
38551 self.write(", ");
38552 }
38553 if !self.merge_strip_qualifiers.is_empty() {
38555 let stripped = self.strip_merge_qualifier(col);
38556 self.generate_expression(&stripped)?;
38557 } else {
38558 self.generate_expression(col)?;
38559 }
38560 }
38561 self.write(")");
38562 values_idx = 2;
38563 } else {
38564 values_idx = 1;
38566 }
38567 }
38568 }
38569 let mut next_idx = values_idx;
38570 if values_idx < elements.len()
38572 && !matches!(&elements[values_idx], Expression::Where(_))
38573 {
38574 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
38576 if !is_row {
38577 self.write_space();
38578 self.write_keyword("VALUES");
38579 }
38580 self.write(" ");
38581 if let Expression::Tuple(vals) = &elements[values_idx] {
38582 self.write("(");
38583 for (i, val) in vals.expressions.iter().enumerate() {
38584 if i > 0 {
38585 self.write(", ");
38586 }
38587 self.generate_expression(val)?;
38588 }
38589 self.write(")");
38590 } else {
38591 self.generate_expression(&elements[values_idx])?;
38592 }
38593 next_idx += 1;
38594 }
38595 if let Some(Expression::Where(w)) = elements.get(next_idx) {
38596 self.write_space();
38597 self.generate_where(w)?;
38598 }
38599 } }
38601 Expression::Var(v) if v.this == "UPDATE" => {
38602 self.write_keyword("UPDATE");
38603 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
38605 self.write(" *");
38606 if let Some(Expression::Where(w)) = elements.get(2) {
38607 self.write_space();
38608 self.generate_where(w)?;
38609 }
38610 } else if elements.len() > 1 {
38611 self.write_space();
38612 self.write_keyword("SET");
38613 if self.config.pretty {
38615 self.write_newline();
38616 self.indent_level += 1;
38617 self.write_indent();
38618 } else {
38619 self.write_space();
38620 }
38621 if let Expression::Tuple(assignments) = &elements[1] {
38622 for (i, assignment) in assignments.expressions.iter().enumerate() {
38623 if i > 0 {
38624 if self.config.pretty {
38625 self.write(",");
38626 self.write_newline();
38627 self.write_indent();
38628 } else {
38629 self.write(", ");
38630 }
38631 }
38632 if !self.merge_strip_qualifiers.is_empty() {
38634 self.generate_merge_set_assignment(assignment)?;
38635 } else {
38636 self.generate_expression(assignment)?;
38637 }
38638 }
38639 } else {
38640 self.generate_expression(&elements[1])?;
38641 }
38642 if self.config.pretty {
38643 self.indent_level -= 1;
38644 }
38645 if let Some(Expression::Where(w)) = elements.get(2) {
38646 self.write_space();
38647 self.generate_where(w)?;
38648 }
38649 }
38650 }
38651 Expression::Var(v) if v.this == "DELETE" => {
38652 self.write_keyword("DELETE");
38653 if let Some(Expression::Where(w)) = elements.get(1) {
38654 self.write_space();
38655 self.generate_where(w)?;
38656 }
38657 }
38658 _ => {
38659 self.generate_expression(action)?;
38661 }
38662 }
38663 }
38664 Expression::Var(v)
38665 if v.this == "INSERT"
38666 || v.this == "UPDATE"
38667 || v.this == "DELETE"
38668 || v.this == "DO NOTHING" =>
38669 {
38670 self.write_keyword(&v.this);
38671 }
38672 _ => {
38673 self.generate_expression(action)?;
38674 }
38675 }
38676 Ok(())
38677 }
38678
38679 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
38681 match assignment {
38682 Expression::Eq(eq) => {
38683 let stripped_left = self.strip_merge_qualifier(&eq.left);
38685 self.generate_expression(&stripped_left)?;
38686 self.write(" = ");
38687 self.generate_expression(&eq.right)?;
38688 Ok(())
38689 }
38690 other => self.generate_expression(other),
38691 }
38692 }
38693
38694 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
38696 match expr {
38697 Expression::Column(col) => {
38698 if let Some(ref table_ident) = col.table {
38699 if self
38700 .merge_strip_qualifiers
38701 .iter()
38702 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
38703 {
38704 let mut col = col.clone();
38706 col.table = None;
38707 return Expression::Column(col);
38708 }
38709 }
38710 expr.clone()
38711 }
38712 Expression::Dot(dot) => {
38713 if let Expression::Identifier(id) = &dot.this {
38715 if self
38716 .merge_strip_qualifiers
38717 .iter()
38718 .any(|n| n.eq_ignore_ascii_case(&id.name))
38719 {
38720 return Expression::Identifier(dot.field.clone());
38721 }
38722 }
38723 expr.clone()
38724 }
38725 _ => expr.clone(),
38726 }
38727 }
38728
38729 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
38730 for (i, expr) in e.expressions.iter().enumerate() {
38732 if i > 0 {
38733 if self.config.pretty {
38735 self.write_newline();
38736 self.write_indent();
38737 } else {
38738 self.write_space();
38739 }
38740 }
38741 self.generate_expression(expr)?;
38742 }
38743 Ok(())
38744 }
38745
38746 fn generate_where(&mut self, e: &Where) -> Result<()> {
38747 self.write_keyword("WHERE");
38749 self.write_space();
38750 self.generate_expression(&e.this)?;
38751 Ok(())
38752 }
38753
38754 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
38755 self.write_keyword("WIDTH_BUCKET");
38757 self.write("(");
38758 self.generate_expression(&e.this)?;
38759 if let Some(min_value) = &e.min_value {
38760 self.write(", ");
38761 self.generate_expression(min_value)?;
38762 }
38763 if let Some(max_value) = &e.max_value {
38764 self.write(", ");
38765 self.generate_expression(max_value)?;
38766 }
38767 if let Some(num_buckets) = &e.num_buckets {
38768 self.write(", ");
38769 self.generate_expression(num_buckets)?;
38770 }
38771 self.write(")");
38772 Ok(())
38773 }
38774
38775 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
38776 self.generate_window_spec(e)
38778 }
38779
38780 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
38781 let mut has_content = false;
38783
38784 if !e.partition_by.is_empty() {
38786 self.write_keyword("PARTITION BY");
38787 self.write_space();
38788 for (i, expr) in e.partition_by.iter().enumerate() {
38789 if i > 0 {
38790 self.write(", ");
38791 }
38792 self.generate_expression(expr)?;
38793 }
38794 has_content = true;
38795 }
38796
38797 if !e.order_by.is_empty() {
38799 if has_content {
38800 self.write_space();
38801 }
38802 self.write_keyword("ORDER BY");
38803 self.write_space();
38804 for (i, ordered) in e.order_by.iter().enumerate() {
38805 if i > 0 {
38806 self.write(", ");
38807 }
38808 self.generate_expression(&ordered.this)?;
38809 if ordered.desc {
38810 self.write_space();
38811 self.write_keyword("DESC");
38812 } else if ordered.explicit_asc {
38813 self.write_space();
38814 self.write_keyword("ASC");
38815 }
38816 if let Some(nulls_first) = ordered.nulls_first {
38817 self.write_space();
38818 self.write_keyword("NULLS");
38819 self.write_space();
38820 if nulls_first {
38821 self.write_keyword("FIRST");
38822 } else {
38823 self.write_keyword("LAST");
38824 }
38825 }
38826 }
38827 has_content = true;
38828 }
38829
38830 if let Some(frame) = &e.frame {
38832 if has_content {
38833 self.write_space();
38834 }
38835 self.generate_window_frame(frame)?;
38836 }
38837
38838 Ok(())
38839 }
38840
38841 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
38842 self.write_keyword("WITH");
38844 self.write_space();
38845 if e.no.is_some() {
38846 self.write_keyword("NO");
38847 self.write_space();
38848 }
38849 self.write_keyword("DATA");
38850
38851 if let Some(statistics) = &e.statistics {
38853 self.write_space();
38854 self.write_keyword("AND");
38855 self.write_space();
38856 match statistics.as_ref() {
38858 Expression::Boolean(b) if !b.value => {
38859 self.write_keyword("NO");
38860 self.write_space();
38861 }
38862 _ => {}
38863 }
38864 self.write_keyword("STATISTICS");
38865 }
38866 Ok(())
38867 }
38868
38869 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
38870 self.write_keyword("WITH FILL");
38872
38873 if let Some(from_) = &e.from_ {
38874 self.write_space();
38875 self.write_keyword("FROM");
38876 self.write_space();
38877 self.generate_expression(from_)?;
38878 }
38879
38880 if let Some(to) = &e.to {
38881 self.write_space();
38882 self.write_keyword("TO");
38883 self.write_space();
38884 self.generate_expression(to)?;
38885 }
38886
38887 if let Some(step) = &e.step {
38888 self.write_space();
38889 self.write_keyword("STEP");
38890 self.write_space();
38891 self.generate_expression(step)?;
38892 }
38893
38894 if let Some(staleness) = &e.staleness {
38895 self.write_space();
38896 self.write_keyword("STALENESS");
38897 self.write_space();
38898 self.generate_expression(staleness)?;
38899 }
38900
38901 if let Some(interpolate) = &e.interpolate {
38902 self.write_space();
38903 self.write_keyword("INTERPOLATE");
38904 self.write(" (");
38905 self.generate_interpolate_item(interpolate)?;
38907 self.write(")");
38908 }
38909
38910 Ok(())
38911 }
38912
38913 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
38915 match expr {
38916 Expression::Alias(alias) => {
38917 self.generate_identifier(&alias.alias)?;
38919 self.write_space();
38920 self.write_keyword("AS");
38921 self.write_space();
38922 self.generate_expression(&alias.this)?;
38923 }
38924 Expression::Tuple(tuple) => {
38925 for (i, item) in tuple.expressions.iter().enumerate() {
38926 if i > 0 {
38927 self.write(", ");
38928 }
38929 self.generate_interpolate_item(item)?;
38930 }
38931 }
38932 other => {
38933 self.generate_expression(other)?;
38934 }
38935 }
38936 Ok(())
38937 }
38938
38939 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
38940 self.write_keyword("WITH JOURNAL TABLE");
38942 self.write("=");
38943 self.generate_expression(&e.this)?;
38944 Ok(())
38945 }
38946
38947 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
38948 self.generate_expression(&e.this)?;
38950 self.write_space();
38951 self.write_keyword("WITH");
38952 self.write_space();
38953 self.write_keyword(&e.op);
38954 Ok(())
38955 }
38956
38957 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
38958 self.write_keyword("WITH");
38960 self.write_space();
38961 for (i, expr) in e.expressions.iter().enumerate() {
38962 if i > 0 {
38963 self.write(", ");
38964 }
38965 self.generate_expression(expr)?;
38966 }
38967 Ok(())
38968 }
38969
38970 fn generate_with_schema_binding_property(
38971 &mut self,
38972 e: &WithSchemaBindingProperty,
38973 ) -> Result<()> {
38974 self.write_keyword("WITH");
38976 self.write_space();
38977 self.generate_expression(&e.this)?;
38978 Ok(())
38979 }
38980
38981 fn generate_with_system_versioning_property(
38982 &mut self,
38983 e: &WithSystemVersioningProperty,
38984 ) -> Result<()> {
38985 let mut parts = Vec::new();
38991
38992 if let Some(this) = &e.this {
38993 let mut s = String::from("HISTORY_TABLE=");
38995 let mut gen = Generator::new();
38996 gen.generate_expression(this)?;
38997 s.push_str(&gen.output);
38998 parts.push(s);
38999 }
39000
39001 if let Some(data_consistency) = &e.data_consistency {
39002 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
39003 let mut gen = Generator::new();
39004 gen.generate_expression(data_consistency)?;
39005 s.push_str(&gen.output);
39006 parts.push(s);
39007 }
39008
39009 if let Some(retention_period) = &e.retention_period {
39010 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
39011 let mut gen = Generator::new();
39012 gen.generate_expression(retention_period)?;
39013 s.push_str(&gen.output);
39014 parts.push(s);
39015 }
39016
39017 self.write_keyword("SYSTEM_VERSIONING");
39018 self.write("=");
39019
39020 if !parts.is_empty() {
39021 self.write_keyword("ON");
39022 self.write("(");
39023 self.write(&parts.join(", "));
39024 self.write(")");
39025 } else if e.on.is_some() {
39026 self.write_keyword("ON");
39027 } else {
39028 self.write_keyword("OFF");
39029 }
39030
39031 if e.with_.is_some() {
39033 let inner = self.output.clone();
39034 self.output.clear();
39035 self.write("WITH(");
39036 self.write(&inner);
39037 self.write(")");
39038 }
39039
39040 Ok(())
39041 }
39042
39043 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
39044 self.write_keyword("WITH");
39046 self.write(" (");
39047 for (i, expr) in e.expressions.iter().enumerate() {
39048 if i > 0 {
39049 self.write(", ");
39050 }
39051 self.generate_expression(expr)?;
39052 }
39053 self.write(")");
39054 Ok(())
39055 }
39056
39057 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
39058 self.write_keyword("XMLELEMENT");
39061 self.write("(");
39062
39063 if e.evalname.is_some() {
39064 self.write_keyword("EVALNAME");
39065 } else {
39066 self.write_keyword("NAME");
39067 }
39068 self.write_space();
39069 self.generate_expression(&e.this)?;
39070
39071 for expr in &e.expressions {
39072 self.write(", ");
39073 self.generate_expression(expr)?;
39074 }
39075 self.write(")");
39076 Ok(())
39077 }
39078
39079 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
39080 self.write_keyword("XMLGET");
39082 self.write("(");
39083 self.generate_expression(&e.this)?;
39084 self.write(", ");
39085 self.generate_expression(&e.expression)?;
39086 if let Some(instance) = &e.instance {
39087 self.write(", ");
39088 self.generate_expression(instance)?;
39089 }
39090 self.write(")");
39091 Ok(())
39092 }
39093
39094 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
39095 self.generate_expression(&e.this)?;
39097 if let Some(expression) = &e.expression {
39098 self.write("(");
39099 self.generate_expression(expression)?;
39100 self.write(")");
39101 }
39102 Ok(())
39103 }
39104
39105 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
39106 self.write_keyword("XMLTABLE");
39108 self.write("(");
39109
39110 if self.config.pretty {
39111 self.indent_level += 1;
39112 self.write_newline();
39113 self.write_indent();
39114 self.generate_expression(&e.this)?;
39115
39116 if let Some(passing) = &e.passing {
39117 self.write_newline();
39118 self.write_indent();
39119 self.write_keyword("PASSING");
39120 if let Expression::Tuple(tuple) = passing.as_ref() {
39121 for expr in &tuple.expressions {
39122 self.write_newline();
39123 self.indent_level += 1;
39124 self.write_indent();
39125 self.generate_expression(expr)?;
39126 self.indent_level -= 1;
39127 }
39128 } else {
39129 self.write_newline();
39130 self.indent_level += 1;
39131 self.write_indent();
39132 self.generate_expression(passing)?;
39133 self.indent_level -= 1;
39134 }
39135 }
39136
39137 if e.by_ref.is_some() {
39138 self.write_newline();
39139 self.write_indent();
39140 self.write_keyword("RETURNING SEQUENCE BY REF");
39141 }
39142
39143 if !e.columns.is_empty() {
39144 self.write_newline();
39145 self.write_indent();
39146 self.write_keyword("COLUMNS");
39147 for (i, col) in e.columns.iter().enumerate() {
39148 self.write_newline();
39149 self.indent_level += 1;
39150 self.write_indent();
39151 self.generate_expression(col)?;
39152 self.indent_level -= 1;
39153 if i < e.columns.len() - 1 {
39154 self.write(",");
39155 }
39156 }
39157 }
39158
39159 self.indent_level -= 1;
39160 self.write_newline();
39161 self.write_indent();
39162 self.write(")");
39163 return Ok(());
39164 }
39165
39166 if let Some(namespaces) = &e.namespaces {
39168 self.write_keyword("XMLNAMESPACES");
39169 self.write("(");
39170 if let Expression::Tuple(tuple) = namespaces.as_ref() {
39172 for (i, expr) in tuple.expressions.iter().enumerate() {
39173 if i > 0 {
39174 self.write(", ");
39175 }
39176 if !matches!(expr, Expression::Alias(_)) {
39179 self.write_keyword("DEFAULT");
39180 self.write_space();
39181 }
39182 self.generate_expression(expr)?;
39183 }
39184 } else {
39185 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
39187 self.write_keyword("DEFAULT");
39188 self.write_space();
39189 }
39190 self.generate_expression(namespaces)?;
39191 }
39192 self.write("), ");
39193 }
39194
39195 self.generate_expression(&e.this)?;
39197
39198 if let Some(passing) = &e.passing {
39200 self.write_space();
39201 self.write_keyword("PASSING");
39202 self.write_space();
39203 if let Expression::Tuple(tuple) = passing.as_ref() {
39205 for (i, expr) in tuple.expressions.iter().enumerate() {
39206 if i > 0 {
39207 self.write(", ");
39208 }
39209 self.generate_expression(expr)?;
39210 }
39211 } else {
39212 self.generate_expression(passing)?;
39213 }
39214 }
39215
39216 if e.by_ref.is_some() {
39218 self.write_space();
39219 self.write_keyword("RETURNING SEQUENCE BY REF");
39220 }
39221
39222 if !e.columns.is_empty() {
39224 self.write_space();
39225 self.write_keyword("COLUMNS");
39226 self.write_space();
39227 for (i, col) in e.columns.iter().enumerate() {
39228 if i > 0 {
39229 self.write(", ");
39230 }
39231 self.generate_expression(col)?;
39232 }
39233 }
39234
39235 self.write(")");
39236 Ok(())
39237 }
39238
39239 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
39240 if let Some(this) = &e.this {
39243 self.generate_expression(this)?;
39244 if let Some(expression) = &e.expression {
39245 self.write_space();
39246 self.write_keyword("XOR");
39247 self.write_space();
39248 self.generate_expression(expression)?;
39249 }
39250 }
39251
39252 for (i, expr) in e.expressions.iter().enumerate() {
39254 if i > 0 || e.this.is_some() {
39255 self.write_space();
39256 self.write_keyword("XOR");
39257 self.write_space();
39258 }
39259 self.generate_expression(expr)?;
39260 }
39261 Ok(())
39262 }
39263
39264 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
39265 self.write_keyword("ZIPF");
39267 self.write("(");
39268 self.generate_expression(&e.this)?;
39269 if let Some(elementcount) = &e.elementcount {
39270 self.write(", ");
39271 self.generate_expression(elementcount)?;
39272 }
39273 if let Some(gen) = &e.gen {
39274 self.write(", ");
39275 self.generate_expression(gen)?;
39276 }
39277 self.write(")");
39278 Ok(())
39279 }
39280}
39281
39282impl Default for Generator {
39283 fn default() -> Self {
39284 Self::new()
39285 }
39286}
39287
39288#[cfg(test)]
39289mod tests {
39290 use super::*;
39291 use crate::parser::Parser;
39292
39293 fn roundtrip(sql: &str) -> String {
39294 let ast = Parser::parse_sql(sql).unwrap();
39295 Generator::sql(&ast[0]).unwrap()
39296 }
39297
39298 #[test]
39299 fn test_simple_select() {
39300 let result = roundtrip("SELECT 1");
39301 assert_eq!(result, "SELECT 1");
39302 }
39303
39304 #[test]
39305 fn test_select_from() {
39306 let result = roundtrip("SELECT a, b FROM t");
39307 assert_eq!(result, "SELECT a, b FROM t");
39308 }
39309
39310 #[test]
39311 fn test_select_where() {
39312 let result = roundtrip("SELECT * FROM t WHERE x = 1");
39313 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
39314 }
39315
39316 #[test]
39317 fn test_select_join() {
39318 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
39319 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
39320 }
39321
39322 #[test]
39323 fn test_insert() {
39324 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
39325 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
39326 }
39327
39328 #[test]
39329 fn test_pretty_print() {
39330 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
39331 let result = Generator::pretty_sql(&ast[0]).unwrap();
39332 assert!(result.contains('\n'));
39333 }
39334
39335 #[test]
39336 fn test_window_function() {
39337 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
39338 assert_eq!(
39339 result,
39340 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
39341 );
39342 }
39343
39344 #[test]
39345 fn test_window_function_with_frame() {
39346 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
39347 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
39348 }
39349
39350 #[test]
39351 fn test_aggregate_with_filter() {
39352 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
39353 assert_eq!(
39354 result,
39355 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
39356 );
39357 }
39358
39359 #[test]
39360 fn test_subscript() {
39361 let result = roundtrip("SELECT arr[0]");
39362 assert_eq!(result, "SELECT arr[0]");
39363 }
39364
39365 #[test]
39367 fn test_create_table() {
39368 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
39369 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
39370 }
39371
39372 #[test]
39373 fn test_create_table_with_constraints() {
39374 let result = roundtrip(
39375 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
39376 );
39377 assert_eq!(
39378 result,
39379 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
39380 );
39381 }
39382
39383 #[test]
39384 fn test_create_table_if_not_exists() {
39385 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
39386 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
39387 }
39388
39389 #[test]
39390 fn test_drop_table() {
39391 let result = roundtrip("DROP TABLE users");
39392 assert_eq!(result, "DROP TABLE users");
39393 }
39394
39395 #[test]
39396 fn test_drop_table_if_exists_cascade() {
39397 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
39398 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
39399 }
39400
39401 #[test]
39402 fn test_alter_table_add_column() {
39403 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
39404 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
39405 }
39406
39407 #[test]
39408 fn test_alter_table_drop_column() {
39409 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
39410 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
39411 }
39412
39413 #[test]
39414 fn test_create_index() {
39415 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
39416 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
39417 }
39418
39419 #[test]
39420 fn test_create_unique_index() {
39421 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
39422 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
39423 }
39424
39425 #[test]
39426 fn test_drop_index() {
39427 let result = roundtrip("DROP INDEX idx_name");
39428 assert_eq!(result, "DROP INDEX idx_name");
39429
39430 let result = roundtrip(r#"DROP INDEX IF EXISTS "idx_tokenKey__pb_users_auth_""#);
39431 assert_eq!(
39432 result,
39433 r#"DROP INDEX IF EXISTS "idx_tokenKey__pb_users_auth_""#
39434 );
39435
39436 let result = roundtrip(r#"DROP INDEX "public"."IdxMixed""#);
39437 assert_eq!(result, r#"DROP INDEX "public"."IdxMixed""#);
39438 }
39439
39440 #[test]
39441 fn test_create_view() {
39442 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
39443 assert_eq!(
39444 result,
39445 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
39446 );
39447 }
39448
39449 #[test]
39450 fn test_drop_view() {
39451 let result = roundtrip("DROP VIEW active_users");
39452 assert_eq!(result, "DROP VIEW active_users");
39453 }
39454
39455 #[test]
39456 fn test_truncate() {
39457 let result = roundtrip("TRUNCATE TABLE users");
39458 assert_eq!(result, "TRUNCATE TABLE users");
39459 }
39460
39461 #[test]
39462 fn test_string_literal_escaping_default() {
39463 let result = roundtrip("SELECT 'hello'");
39465 assert_eq!(result, "SELECT 'hello'");
39466
39467 let result = roundtrip("SELECT 'it''s a test'");
39469 assert_eq!(result, "SELECT 'it''s a test'");
39470 }
39471
39472 #[test]
39473 fn test_not_in_style_prefix_default_generic() {
39474 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
39475 assert_eq!(
39476 result,
39477 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
39478 );
39479 }
39480
39481 #[test]
39482 fn test_not_in_style_infix_generic_override() {
39483 let ast =
39484 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
39485 .unwrap();
39486 let config = GeneratorConfig {
39487 not_in_style: NotInStyle::Infix,
39488 ..Default::default()
39489 };
39490 let mut gen = Generator::with_config(config);
39491 let result = gen.generate(&ast[0]).unwrap();
39492 assert_eq!(
39493 result,
39494 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
39495 );
39496 }
39497
39498 #[test]
39499 fn test_string_literal_escaping_mysql() {
39500 use crate::dialects::DialectType;
39501
39502 let config = GeneratorConfig {
39503 dialect: Some(DialectType::MySQL),
39504 ..Default::default()
39505 };
39506
39507 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
39508 let mut gen = Generator::with_config(config.clone());
39509 let result = gen.generate(&ast[0]).unwrap();
39510 assert_eq!(result, "SELECT 'hello'");
39511
39512 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
39514 let mut gen = Generator::with_config(config.clone());
39515 let result = gen.generate(&ast[0]).unwrap();
39516 assert_eq!(result, "SELECT 'it''s'");
39517 }
39518
39519 #[test]
39520 fn test_string_literal_escaping_postgres() {
39521 use crate::dialects::DialectType;
39522
39523 let config = GeneratorConfig {
39524 dialect: Some(DialectType::PostgreSQL),
39525 ..Default::default()
39526 };
39527
39528 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
39529 let mut gen = Generator::with_config(config.clone());
39530 let result = gen.generate(&ast[0]).unwrap();
39531 assert_eq!(result, "SELECT 'hello'");
39532
39533 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
39535 let mut gen = Generator::with_config(config.clone());
39536 let result = gen.generate(&ast[0]).unwrap();
39537 assert_eq!(result, "SELECT 'it''s'");
39538 }
39539
39540 #[test]
39541 fn test_string_literal_escaping_bigquery() {
39542 use crate::dialects::DialectType;
39543
39544 let config = GeneratorConfig {
39545 dialect: Some(DialectType::BigQuery),
39546 ..Default::default()
39547 };
39548
39549 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
39550 let mut gen = Generator::with_config(config.clone());
39551 let result = gen.generate(&ast[0]).unwrap();
39552 assert_eq!(result, "SELECT 'hello'");
39553
39554 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
39556 let mut gen = Generator::with_config(config.clone());
39557 let result = gen.generate(&ast[0]).unwrap();
39558 assert_eq!(result, "SELECT 'it\\'s'");
39559 }
39560
39561 #[test]
39562 fn test_generate_deep_and_chain_without_stack_growth() {
39563 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
39564 Expression::column("c0"),
39565 Expression::number(0),
39566 )));
39567
39568 for i in 1..2500 {
39569 let predicate = Expression::Eq(Box::new(BinaryOp::new(
39570 Expression::column(format!("c{i}")),
39571 Expression::number(i as i64),
39572 )));
39573 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
39574 }
39575
39576 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
39577 assert!(sql.contains("c2499 = 2499"), "{}", sql);
39578 }
39579
39580 #[test]
39581 fn test_generate_deep_or_chain_without_stack_growth() {
39582 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
39583 Expression::column("c0"),
39584 Expression::number(0),
39585 )));
39586
39587 for i in 1..2500 {
39588 let predicate = Expression::Eq(Box::new(BinaryOp::new(
39589 Expression::column(format!("c{i}")),
39590 Expression::number(i as i64),
39591 )));
39592 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
39593 }
39594
39595 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
39596 assert!(sql.contains("c2499 = 2499"), "{}", sql);
39597 }
39598}