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 should_handle_tsql_distinct_null_ordering(&self, select: &Select) -> bool {
4068 matches!(
4069 self.config.dialect,
4070 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4071 ) && !self.config.null_ordering_supported
4072 && select.distinct
4073 && select.order_by.as_ref().is_some_and(|order_by| {
4074 order_by
4075 .expressions
4076 .iter()
4077 .any(Self::ordered_requires_tsql_null_ordering_emulation)
4078 })
4079 }
4080
4081 fn ordered_requires_tsql_null_ordering_emulation(ordered: &Ordered) -> bool {
4082 let Some(nulls_first) = ordered.nulls_first else {
4083 return false;
4084 };
4085
4086 let random_ordering = matches!(ordered.this, Expression::Rand(_) | Expression::Random(_));
4087 let target_default_nulls_first = !ordered.desc;
4088
4089 nulls_first != target_default_nulls_first && !random_ordering
4090 }
4091
4092 fn projection_output_identifier(expression: &Expression) -> Option<Identifier> {
4093 match expression {
4094 Expression::Alias(alias) if !alias.alias.name.is_empty() => Some(alias.alias.clone()),
4095 Expression::Column(column) => Some(column.name.clone()),
4096 Expression::Identifier(identifier) => Some(identifier.clone()),
4097 _ => None,
4098 }
4099 }
4100
4101 fn identifier_names_match(left: &Identifier, right: &Identifier) -> bool {
4102 if left.quoted || right.quoted {
4103 left.name == right.name
4104 } else {
4105 left.name.eq_ignore_ascii_case(&right.name)
4106 }
4107 }
4108
4109 fn expression_matches_identifier(expression: &Expression, identifier: &Identifier) -> bool {
4110 match expression {
4111 Expression::Column(column) if column.table.is_none() => {
4112 Self::identifier_names_match(&column.name, identifier)
4113 }
4114 Expression::Identifier(other) => Self::identifier_names_match(other, identifier),
4115 _ => false,
4116 }
4117 }
4118
4119 fn column_expression(identifier: Identifier) -> Expression {
4120 Expression::Column(Box::new(Column {
4121 name: identifier,
4122 table: None,
4123 join_mark: false,
4124 trailing_comments: Vec::new(),
4125 span: None,
4126 inferred_type: None,
4127 }))
4128 }
4129
4130 fn resolve_distinct_order_projection(
4131 projections: &[Expression],
4132 order_expression: &Expression,
4133 ) -> Option<Expression> {
4134 for projection in projections {
4135 if let Expression::Alias(alias) = projection {
4136 if Self::expression_matches_identifier(order_expression, &alias.alias)
4137 || &alias.this == order_expression
4138 {
4139 return Some(alias.this.clone());
4140 }
4141 } else if projection == order_expression {
4142 return Some(projection.clone());
4143 } else if let Some(identifier) = Self::projection_output_identifier(projection) {
4144 if Self::expression_matches_identifier(order_expression, &identifier) {
4145 return Some(projection.clone());
4146 }
4147 }
4148 }
4149
4150 None
4151 }
4152
4153 fn fresh_polyglot_alias(base: &str, index: usize, used_names: &mut Vec<String>) -> String {
4154 let mut suffix = 0;
4155 loop {
4156 let candidate = if suffix == 0 {
4157 format!("{base}_{index}")
4158 } else {
4159 format!("{base}_{index}_{suffix}")
4160 };
4161
4162 if !used_names
4163 .iter()
4164 .any(|name| name.eq_ignore_ascii_case(&candidate))
4165 {
4166 used_names.push(candidate.clone());
4167 return candidate;
4168 }
4169
4170 suffix += 1;
4171 }
4172 }
4173
4174 fn tsql_null_ordering_case(expression: Expression) -> Expression {
4175 Expression::Case(Box::new(Case {
4176 operand: None,
4177 whens: vec![(
4178 Expression::IsNull(Box::new(IsNull {
4179 this: expression,
4180 not: false,
4181 postfix_form: false,
4182 })),
4183 Expression::number(1),
4184 )],
4185 else_: Some(Expression::number(0)),
4186 comments: Vec::new(),
4187 inferred_type: None,
4188 }))
4189 }
4190
4191 fn try_build_tsql_distinct_null_ordering_wrapper(&self, select: &Select) -> Option<Select> {
4192 let order_by = select.order_by.as_ref()?;
4193
4194 if order_by.siblings
4195 || select.distinct_on.is_some()
4196 || select.distribute_by.is_some()
4197 || select.cluster_by.is_some()
4198 || select.sort_by.is_some()
4199 || select.limit.is_some()
4200 || select.offset.is_some()
4201 || select.limit_by.is_some()
4202 || select.fetch.is_some()
4203 || select.top.is_some()
4204 || select.settings.is_some()
4205 || select.format.is_some()
4206 || select.kind.is_some()
4207 || select.hint.is_some()
4208 || select.into.is_some()
4209 || !select.locks.is_empty()
4210 || !select.for_xml.is_empty()
4211 || !select.for_json.is_empty()
4212 || !select.operation_modifiers.is_empty()
4213 || select.option.is_some()
4214 || select.exclude.is_some()
4215 {
4216 return None;
4217 }
4218
4219 let projection_identifiers: Vec<_> = select
4220 .expressions
4221 .iter()
4222 .map(Self::projection_output_identifier)
4223 .collect::<Option<_>>()?;
4224 let mut used_names: Vec<_> = projection_identifiers
4225 .iter()
4226 .map(|identifier| identifier.name.clone())
4227 .collect();
4228
4229 let mut inner = select.clone();
4230 inner.order_by = None;
4231
4232 let outer_with = inner.with.take();
4233 let outer_leading_comments = std::mem::take(&mut inner.leading_comments);
4234 let outer_post_select_comments = std::mem::take(&mut inner.post_select_comments);
4235
4236 let mut outer_order_expressions = Vec::with_capacity(order_by.expressions.len() * 2);
4237 for (index, ordered) in order_by.expressions.iter().enumerate() {
4238 if ordered.with_fill.is_some() {
4239 return None;
4240 }
4241
4242 let sort_expression =
4243 Self::resolve_distinct_order_projection(&select.expressions, &ordered.this)?;
4244
4245 if Self::ordered_requires_tsql_null_ordering_emulation(ordered) {
4246 let null_alias =
4247 Self::fresh_polyglot_alias("_polyglot_order_null", index, &mut used_names);
4248 inner.expressions.push(
4249 Self::tsql_null_ordering_case(sort_expression.clone())
4250 .alias(null_alias.clone()),
4251 );
4252 outer_order_expressions.push(Ordered {
4253 this: Expression::column(null_alias),
4254 desc: ordered.nulls_first == Some(true),
4255 nulls_first: None,
4256 explicit_asc: false,
4257 with_fill: None,
4258 });
4259 }
4260
4261 let key_alias =
4262 Self::fresh_polyglot_alias("_polyglot_order_key", index, &mut used_names);
4263 inner
4264 .expressions
4265 .push(sort_expression.alias(key_alias.clone()));
4266 outer_order_expressions.push(Ordered {
4267 this: Expression::column(key_alias),
4268 desc: ordered.desc,
4269 nulls_first: None,
4270 explicit_asc: ordered.explicit_asc,
4271 with_fill: None,
4272 });
4273 }
4274
4275 let subquery = Subquery {
4276 this: Expression::Select(Box::new(inner)),
4277 alias: Some(Identifier::new("_polyglot_distinct_order")),
4278 column_aliases: Vec::new(),
4279 alias_explicit_as: true,
4280 alias_keyword: None,
4281 order_by: None,
4282 limit: None,
4283 offset: None,
4284 distribute_by: None,
4285 sort_by: None,
4286 cluster_by: None,
4287 lateral: false,
4288 modifiers_inside: false,
4289 trailing_comments: Vec::new(),
4290 inferred_type: None,
4291 };
4292
4293 let mut outer = Select::new();
4294 outer.with = outer_with;
4295 outer.leading_comments = outer_leading_comments;
4296 outer.post_select_comments = outer_post_select_comments;
4297 outer.expressions = projection_identifiers
4298 .into_iter()
4299 .map(Self::column_expression)
4300 .collect();
4301 outer.from = Some(From {
4302 expressions: vec![Expression::Subquery(Box::new(subquery))],
4303 });
4304 outer.order_by = Some(OrderBy {
4305 expressions: outer_order_expressions,
4306 siblings: false,
4307 comments: order_by.comments.clone(),
4308 });
4309
4310 Some(outer)
4311 }
4312
4313 fn generate_select(&mut self, select: &Select) -> Result<()> {
4314 use crate::dialects::DialectType;
4315
4316 if self.should_handle_tsql_distinct_null_ordering(select) {
4317 if let Some(wrapped_select) = self.try_build_tsql_distinct_null_ordering_wrapper(select)
4318 {
4319 return self.generate_select(&wrapped_select);
4320 }
4321
4322 self.unsupported(
4323 "SELECT DISTINCT with emulated NULL ordering is not supported for TSQL/Fabric",
4324 )?;
4325 }
4326
4327 if let Some(exclude) = &select.exclude {
4331 if !exclude.is_empty() && !matches!(self.config.dialect, Some(DialectType::Redshift)) {
4332 let mut inner_select = select.clone();
4334 inner_select.exclude = None;
4335 let inner_expr = Expression::Select(Box::new(inner_select));
4336
4337 let subquery = crate::expressions::Subquery {
4339 this: inner_expr,
4340 alias: None,
4341 column_aliases: Vec::new(),
4342 alias_explicit_as: false,
4343 alias_keyword: None,
4344 order_by: None,
4345 limit: None,
4346 offset: None,
4347 distribute_by: None,
4348 sort_by: None,
4349 cluster_by: None,
4350 lateral: false,
4351 modifiers_inside: false,
4352 trailing_comments: Vec::new(),
4353 inferred_type: None,
4354 };
4355
4356 let star = Expression::Star(crate::expressions::Star {
4358 table: None,
4359 except: Some(
4360 exclude
4361 .iter()
4362 .map(|e| match e {
4363 Expression::Column(col) => col.name.clone(),
4364 Expression::Identifier(id) => id.clone(),
4365 _ => crate::expressions::Identifier::new("unknown".to_string()),
4366 })
4367 .collect(),
4368 ),
4369 replace: None,
4370 rename: None,
4371 trailing_comments: Vec::new(),
4372 span: None,
4373 });
4374
4375 let outer_select = Select {
4376 expressions: vec![star],
4377 from: Some(crate::expressions::From {
4378 expressions: vec![Expression::Subquery(Box::new(subquery))],
4379 }),
4380 ..Select::new()
4381 };
4382
4383 return self.generate_select(&outer_select);
4384 }
4385 }
4386
4387 for comment in &select.leading_comments {
4389 self.write_formatted_comment(comment);
4390 self.write(" ");
4391 }
4392
4393 if let Some(with) = &select.with {
4395 self.generate_with(with)?;
4396 if self.config.pretty {
4397 self.write_newline();
4398 self.write_indent();
4399 } else {
4400 self.write_space();
4401 }
4402 }
4403
4404 for comment in &select.post_select_comments {
4407 self.write_formatted_comment(comment);
4408 self.write(" ");
4409 }
4410
4411 self.write_keyword("SELECT");
4412
4413 if let Some(hint) = &select.hint {
4415 self.generate_hint(hint)?;
4416 }
4417
4418 let use_top_from_limit = matches!(
4422 self.config.dialect,
4423 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4424 ) && select.top.is_none()
4425 && select.limit.is_some()
4426 && select.offset.is_none(); let is_top_dialect = matches!(
4431 self.config.dialect,
4432 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
4433 );
4434 let keep_top_verbatim = !is_top_dialect
4435 && select.limit.is_none()
4436 && select
4437 .top
4438 .as_ref()
4439 .map_or(false, |top| top.percent || top.with_ties);
4440
4441 if select.distinct && (is_top_dialect || select.top.is_some()) {
4442 self.write_space();
4443 self.write_keyword("DISTINCT");
4444 }
4445
4446 if is_top_dialect || keep_top_verbatim {
4447 if let Some(top) = &select.top {
4448 self.write_space();
4449 self.write_keyword("TOP");
4450 if top.parenthesized {
4451 if matches!(&top.this, Expression::Subquery(_) | Expression::Paren(_)) {
4452 self.write_space();
4453 self.generate_expression(&top.this)?;
4454 } else {
4455 self.write(" (");
4456 self.generate_expression(&top.this)?;
4457 self.write(")");
4458 }
4459 } else {
4460 self.write_space();
4461 self.generate_expression(&top.this)?;
4462 }
4463 if top.percent {
4464 self.write_space();
4465 self.write_keyword("PERCENT");
4466 }
4467 if top.with_ties {
4468 self.write_space();
4469 self.write_keyword("WITH TIES");
4470 }
4471 } else if use_top_from_limit {
4472 if let Some(limit) = &select.limit {
4474 self.write_space();
4475 self.write_keyword("TOP");
4476 let is_simple_literal = matches!(&limit.this, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)));
4478 if is_simple_literal {
4479 self.write_space();
4480 self.generate_expression(&limit.this)?;
4481 } else {
4482 self.write(" (");
4483 self.generate_expression(&limit.this)?;
4484 self.write(")");
4485 }
4486 }
4487 }
4488 }
4489
4490 if select.distinct && !is_top_dialect && select.top.is_none() {
4491 self.write_space();
4492 self.write_keyword("DISTINCT");
4493 }
4494
4495 if let Some(distinct_on) = &select.distinct_on {
4497 self.write_space();
4498 self.write_keyword("ON");
4499 self.write(" (");
4500 for (i, expr) in distinct_on.iter().enumerate() {
4501 if i > 0 {
4502 self.write(", ");
4503 }
4504 self.generate_expression(expr)?;
4505 }
4506 self.write(")");
4507 }
4508
4509 for modifier in &select.operation_modifiers {
4511 self.write_space();
4512 self.write_keyword(modifier);
4513 }
4514
4515 if let Some(kind) = &select.kind {
4517 self.write_space();
4518 self.write_keyword("AS");
4519 self.write_space();
4520 self.write_keyword(kind);
4521 }
4522
4523 if !select.expressions.is_empty() {
4525 if self.config.pretty {
4526 self.write_newline();
4527 self.indent_level += 1;
4528 } else {
4529 self.write_space();
4530 }
4531 }
4532
4533 for (i, expr) in select.expressions.iter().enumerate() {
4534 if i > 0 {
4535 self.write(",");
4536 if self.config.pretty {
4537 self.write_newline();
4538 } else {
4539 self.write_space();
4540 }
4541 }
4542 if self.config.pretty {
4543 self.write_indent();
4544 }
4545 self.generate_expression(expr)?;
4546 }
4547
4548 if self.config.pretty && !select.expressions.is_empty() {
4549 self.indent_level -= 1;
4550 }
4551
4552 if let Some(exclude) = &select.exclude {
4557 if !exclude.is_empty() && matches!(self.config.dialect, Some(DialectType::Redshift)) {
4558 self.write_space();
4559 self.write_keyword("EXCLUDE");
4560 self.write(" (");
4561 for (i, col) in exclude.iter().enumerate() {
4562 if i > 0 {
4563 self.write(", ");
4564 }
4565 self.generate_expression(col)?;
4566 }
4567 self.write(")");
4568 }
4569 }
4570
4571 if let Some(into) = &select.into {
4574 if self.config.pretty {
4575 self.write_newline();
4576 self.write_indent();
4577 } else {
4578 self.write_space();
4579 }
4580 if into.bulk_collect {
4581 self.write_keyword("BULK COLLECT INTO");
4582 } else {
4583 self.write_keyword("INTO");
4584 }
4585 if into.temporary {
4586 self.write_space();
4587 self.write_keyword("TEMPORARY");
4588 }
4589 if into.unlogged {
4590 self.write_space();
4591 self.write_keyword("UNLOGGED");
4592 }
4593 self.write_space();
4594 if !into.expressions.is_empty() {
4596 for (i, expr) in into.expressions.iter().enumerate() {
4597 if i > 0 {
4598 self.write(", ");
4599 }
4600 self.generate_expression(expr)?;
4601 }
4602 } else {
4603 self.generate_expression(&into.this)?;
4604 }
4605 }
4606
4607 if let Some(from) = &select.from {
4609 if self.config.pretty {
4610 self.write_newline();
4611 self.write_indent();
4612 } else {
4613 self.write_space();
4614 }
4615 self.write_keyword("FROM");
4616 self.write_space();
4617
4618 let has_tablesample = from
4623 .expressions
4624 .iter()
4625 .any(|e| matches!(e, Expression::TableSample(_)));
4626 let is_cross_join_dialect = matches!(
4627 self.config.dialect,
4628 Some(DialectType::BigQuery)
4629 | Some(DialectType::Hive)
4630 | Some(DialectType::Spark)
4631 | Some(DialectType::Databricks)
4632 | Some(DialectType::SQLite)
4633 | Some(DialectType::ClickHouse)
4634 );
4635 let source_is_same_as_target = self.config.source_dialect.is_some()
4638 && self.config.source_dialect == self.config.dialect;
4639 let source_is_cross_join_dialect = matches!(
4640 self.config.source_dialect,
4641 Some(DialectType::BigQuery)
4642 | Some(DialectType::Hive)
4643 | Some(DialectType::Spark)
4644 | Some(DialectType::Databricks)
4645 | Some(DialectType::SQLite)
4646 | Some(DialectType::ClickHouse)
4647 );
4648 let use_cross_join = !has_tablesample
4649 && is_cross_join_dialect
4650 && (source_is_same_as_target
4651 || source_is_cross_join_dialect
4652 || self.config.source_dialect.is_none());
4653
4654 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4656
4657 for (i, expr) in from.expressions.iter().enumerate() {
4658 if i > 0 {
4659 if use_cross_join {
4660 self.write(" CROSS JOIN ");
4661 } else {
4662 self.write(", ");
4663 }
4664 }
4665 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4666 self.write("(");
4667 self.generate_expression(expr)?;
4668 self.write(")");
4669 } else {
4670 self.generate_expression(expr)?;
4671 }
4672 let leading = Self::extract_table_leading_comments(expr);
4675 for comment in &leading {
4676 self.write_space();
4677 self.write_formatted_comment(comment);
4678 }
4679 }
4680 }
4681
4682 if self.config.pretty {
4686 self.generate_joins_with_nesting(&select.joins)?;
4687 } else {
4688 for join in &select.joins {
4689 self.generate_join(join)?;
4690 }
4691 for join in select.joins.iter().rev() {
4693 if join.deferred_condition {
4694 self.generate_join_condition(join)?;
4695 }
4696 }
4697 }
4698
4699 for (lv_idx, lateral_view) in select.lateral_views.iter().enumerate() {
4701 self.generate_lateral_view(lateral_view, lv_idx)?;
4702 }
4703
4704 if let Some(prewhere) = &select.prewhere {
4706 self.write_clause_condition("PREWHERE", prewhere)?;
4707 }
4708
4709 if let Some(where_clause) = &select.where_clause {
4711 self.write_clause_condition("WHERE", &where_clause.this)?;
4712 }
4713
4714 if let Some(connect) = &select.connect {
4716 self.generate_connect(connect)?;
4717 }
4718
4719 if let Some(group_by) = &select.group_by {
4721 if self.config.pretty {
4722 for comment in &group_by.comments {
4724 self.write_newline();
4725 self.write_indent();
4726 self.write_formatted_comment(comment);
4727 }
4728 self.write_newline();
4729 self.write_indent();
4730 } else {
4731 self.write_space();
4732 for comment in &group_by.comments {
4734 self.write_formatted_comment(comment);
4735 self.write_space();
4736 }
4737 }
4738 let clickhouse_bare_modifiers =
4739 matches!(self.config.dialect, Some(DialectType::ClickHouse))
4740 && group_by.all.is_none()
4741 && (group_by.totals || !group_by.expressions.is_empty())
4742 && group_by.expressions.iter().all(|expr| match expr {
4743 Expression::Cube(c) => c.expressions.is_empty(),
4744 Expression::Rollup(r) => r.expressions.is_empty(),
4745 _ => false,
4746 });
4747
4748 if clickhouse_bare_modifiers {
4749 let trailing_cube = group_by
4750 .expressions
4751 .iter()
4752 .any(|expr| matches!(expr, Expression::Cube(c) if c.expressions.is_empty()));
4753 let trailing_rollup = group_by
4754 .expressions
4755 .iter()
4756 .any(|expr| matches!(expr, Expression::Rollup(r) if r.expressions.is_empty()));
4757
4758 if trailing_cube {
4759 self.write_keyword("WITH CUBE");
4760 } else if trailing_rollup {
4761 self.write_keyword("WITH ROLLUP");
4762 }
4763
4764 if group_by.totals {
4765 if trailing_cube || trailing_rollup {
4766 self.write_space();
4767 }
4768 self.write_keyword("WITH TOTALS");
4769 }
4770 } else {
4771 self.write_keyword("GROUP BY");
4772 match group_by.all {
4774 Some(true) => {
4775 self.write_space();
4776 self.write_keyword("ALL");
4777 }
4778 Some(false) => {
4779 self.write_space();
4780 self.write_keyword("DISTINCT");
4781 }
4782 None => {}
4783 }
4784 if !group_by.expressions.is_empty() {
4785 let mut trailing_cube = false;
4788 let mut trailing_rollup = false;
4789 let mut plain_expressions: Vec<&Expression> = Vec::new();
4790 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4791 let mut cube_expressions: Vec<&Expression> = Vec::new();
4792 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4793
4794 for expr in &group_by.expressions {
4795 match expr {
4796 Expression::Cube(c) if c.expressions.is_empty() => {
4797 trailing_cube = true;
4798 }
4799 Expression::Rollup(r) if r.expressions.is_empty() => {
4800 trailing_rollup = true;
4801 }
4802 Expression::Function(f) if f.name == "CUBE" => {
4803 cube_expressions.push(expr);
4804 }
4805 Expression::Function(f) if f.name == "ROLLUP" => {
4806 rollup_expressions.push(expr);
4807 }
4808 Expression::Function(f) if f.name == "GROUPING SETS" => {
4809 grouping_sets_expressions.push(expr);
4810 }
4811 _ => {
4812 plain_expressions.push(expr);
4813 }
4814 }
4815 }
4816
4817 let mut regular_expressions: Vec<&Expression> = Vec::new();
4819 regular_expressions.extend(plain_expressions);
4820 regular_expressions.extend(grouping_sets_expressions);
4821 regular_expressions.extend(cube_expressions);
4822 regular_expressions.extend(rollup_expressions);
4823
4824 if self.config.pretty {
4825 self.write_newline();
4826 self.indent_level += 1;
4827 self.write_indent();
4828 } else {
4829 self.write_space();
4830 }
4831
4832 for (i, expr) in regular_expressions.iter().enumerate() {
4833 if i > 0 {
4834 if self.config.pretty {
4835 self.write(",");
4836 self.write_newline();
4837 self.write_indent();
4838 } else {
4839 self.write(", ");
4840 }
4841 }
4842 self.generate_expression(expr)?;
4843 }
4844
4845 if self.config.pretty {
4846 self.indent_level -= 1;
4847 }
4848
4849 if trailing_cube {
4851 self.write_space();
4852 self.write_keyword("WITH CUBE");
4853 } else if trailing_rollup {
4854 self.write_space();
4855 self.write_keyword("WITH ROLLUP");
4856 }
4857 }
4858
4859 if group_by.totals {
4861 self.write_space();
4862 self.write_keyword("WITH TOTALS");
4863 }
4864 }
4865 }
4866
4867 if let Some(having) = &select.having {
4869 if self.config.pretty {
4870 for comment in &having.comments {
4872 self.write_newline();
4873 self.write_indent();
4874 self.write_formatted_comment(comment);
4875 }
4876 } else {
4877 for comment in &having.comments {
4878 self.write_space();
4879 self.write_formatted_comment(comment);
4880 }
4881 }
4882 self.write_clause_condition("HAVING", &having.this)?;
4883 }
4884
4885 if select.qualify_after_window {
4887 if let Some(windows) = &select.windows {
4889 self.write_window_clause(windows)?;
4890 }
4891 if let Some(qualify) = &select.qualify {
4892 self.write_clause_condition("QUALIFY", &qualify.this)?;
4893 }
4894 } else {
4895 if let Some(qualify) = &select.qualify {
4897 self.write_clause_condition("QUALIFY", &qualify.this)?;
4898 }
4899 if let Some(windows) = &select.windows {
4900 self.write_window_clause(windows)?;
4901 }
4902 }
4903
4904 if let Some(distribute_by) = &select.distribute_by {
4906 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4907 }
4908
4909 if let Some(cluster_by) = &select.cluster_by {
4911 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4912 }
4913
4914 if let Some(sort_by) = &select.sort_by {
4916 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4917 }
4918
4919 if let Some(order_by) = &select.order_by {
4921 if self.config.pretty {
4922 for comment in &order_by.comments {
4924 self.write_newline();
4925 self.write_indent();
4926 self.write_formatted_comment(comment);
4927 }
4928 } else {
4929 for comment in &order_by.comments {
4930 self.write_space();
4931 self.write_formatted_comment(comment);
4932 }
4933 }
4934 let keyword = if order_by.siblings {
4935 "ORDER SIBLINGS BY"
4936 } else {
4937 "ORDER BY"
4938 };
4939 self.write_order_clause(keyword, &order_by.expressions)?;
4940 }
4941
4942 if select.order_by.is_none()
4944 && select.fetch.is_some()
4945 && matches!(
4946 self.config.dialect,
4947 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4948 )
4949 {
4950 if self.config.pretty {
4951 self.write_newline();
4952 self.write_indent();
4953 } else {
4954 self.write_space();
4955 }
4956 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4957 }
4958
4959 let is_presto_like = matches!(
4964 self.config.dialect,
4965 Some(DialectType::Presto) | Some(DialectType::Trino)
4966 );
4967
4968 if is_presto_like && select.offset.is_some() {
4969 if let Some(offset) = &select.offset {
4971 if self.config.pretty {
4972 self.write_newline();
4973 self.write_indent();
4974 } else {
4975 self.write_space();
4976 }
4977 self.write_keyword("OFFSET");
4978 self.write_space();
4979 self.write_limit_expr(&offset.this)?;
4980 if offset.rows == Some(true) {
4981 self.write_space();
4982 self.write_keyword("ROWS");
4983 }
4984 }
4985 if let Some(limit) = &select.limit {
4986 if self.config.pretty {
4987 self.write_newline();
4988 self.write_indent();
4989 } else {
4990 self.write_space();
4991 }
4992 self.write_keyword("LIMIT");
4993 self.write_space();
4994 self.write_limit_expr(&limit.this)?;
4995 if limit.percent {
4996 self.write_space();
4997 self.write_keyword("PERCENT");
4998 }
4999 for comment in &limit.comments {
5001 self.write(" ");
5002 self.write_formatted_comment(comment);
5003 }
5004 }
5005 } else {
5006 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
5008 !fetch.percent
5009 && !fetch.with_ties
5010 && fetch.count.is_some()
5011 && matches!(
5012 self.config.dialect,
5013 Some(DialectType::Spark)
5014 | Some(DialectType::Hive)
5015 | Some(DialectType::DuckDB)
5016 | Some(DialectType::SQLite)
5017 | Some(DialectType::MySQL)
5018 | Some(DialectType::BigQuery)
5019 | Some(DialectType::Databricks)
5020 | Some(DialectType::StarRocks)
5021 | Some(DialectType::Doris)
5022 | Some(DialectType::Athena)
5023 | Some(DialectType::ClickHouse)
5024 | Some(DialectType::Redshift)
5025 )
5026 });
5027
5028 if let Some(limit) = &select.limit {
5030 if !matches!(
5032 self.config.dialect,
5033 Some(DialectType::TSQL) | Some(DialectType::Fabric)
5034 ) {
5035 if self.config.pretty {
5036 self.write_newline();
5037 self.write_indent();
5038 } else {
5039 self.write_space();
5040 }
5041 self.write_keyword("LIMIT");
5042 self.write_space();
5043 self.write_limit_expr(&limit.this)?;
5044 if limit.percent {
5045 self.write_space();
5046 self.write_keyword("PERCENT");
5047 }
5048 for comment in &limit.comments {
5050 self.write(" ");
5051 self.write_formatted_comment(comment);
5052 }
5053 }
5054 }
5055
5056 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
5058 if let Some(top) = &select.top {
5059 if !top.percent && !top.with_ties {
5060 if self.config.pretty {
5061 self.write_newline();
5062 self.write_indent();
5063 } else {
5064 self.write_space();
5065 }
5066 self.write_keyword("LIMIT");
5067 self.write_space();
5068 self.generate_expression(&top.this)?;
5069 }
5070 }
5071 }
5072
5073 if fetch_as_limit && select.offset.is_some() {
5076 if let Some(fetch) = &select.fetch {
5077 if self.config.pretty {
5078 self.write_newline();
5079 self.write_indent();
5080 } else {
5081 self.write_space();
5082 }
5083 self.write_keyword("LIMIT");
5084 self.write_space();
5085 self.generate_expression(fetch.count.as_ref().unwrap())?;
5086 }
5087 }
5088
5089 if let Some(offset) = &select.offset {
5093 if self.config.pretty {
5094 self.write_newline();
5095 self.write_indent();
5096 } else {
5097 self.write_space();
5098 }
5099 if matches!(
5100 self.config.dialect,
5101 Some(DialectType::TSQL) | Some(DialectType::Fabric)
5102 ) {
5103 self.write_keyword("OFFSET");
5105 self.write_space();
5106 self.write_limit_expr(&offset.this)?;
5107 self.write_space();
5108 self.write_keyword("ROWS");
5109 if let Some(limit) = &select.limit {
5111 self.write_space();
5112 self.write_keyword("FETCH NEXT");
5113 self.write_space();
5114 self.write_limit_expr(&limit.this)?;
5115 self.write_space();
5116 self.write_keyword("ROWS ONLY");
5117 }
5118 } else {
5119 self.write_keyword("OFFSET");
5120 self.write_space();
5121 self.write_limit_expr(&offset.this)?;
5122 if offset.rows == Some(true) {
5124 self.write_space();
5125 self.write_keyword("ROWS");
5126 }
5127 }
5128 }
5129 }
5130
5131 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5133 if let Some(limit_by) = &select.limit_by {
5134 if !limit_by.is_empty() {
5135 self.write_space();
5136 self.write_keyword("BY");
5137 self.write_space();
5138 for (i, expr) in limit_by.iter().enumerate() {
5139 if i > 0 {
5140 self.write(", ");
5141 }
5142 self.generate_expression(expr)?;
5143 }
5144 }
5145 }
5146 }
5147
5148 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5150 if let Some(settings) = &select.settings {
5151 if self.config.pretty {
5152 self.write_newline();
5153 self.write_indent();
5154 } else {
5155 self.write_space();
5156 }
5157 self.write_keyword("SETTINGS");
5158 self.write_space();
5159 for (i, expr) in settings.iter().enumerate() {
5160 if i > 0 {
5161 self.write(", ");
5162 }
5163 self.generate_expression(expr)?;
5164 }
5165 }
5166
5167 if let Some(format_expr) = &select.format {
5168 if self.config.pretty {
5169 self.write_newline();
5170 self.write_indent();
5171 } else {
5172 self.write_space();
5173 }
5174 self.write_keyword("FORMAT");
5175 self.write_space();
5176 self.generate_expression(format_expr)?;
5177 }
5178 }
5179
5180 if let Some(fetch) = &select.fetch {
5182 let fetch_already_as_limit = select.offset.is_some()
5184 && !fetch.percent
5185 && !fetch.with_ties
5186 && fetch.count.is_some()
5187 && matches!(
5188 self.config.dialect,
5189 Some(DialectType::Spark)
5190 | Some(DialectType::Hive)
5191 | Some(DialectType::DuckDB)
5192 | Some(DialectType::SQLite)
5193 | Some(DialectType::MySQL)
5194 | Some(DialectType::BigQuery)
5195 | Some(DialectType::Databricks)
5196 | Some(DialectType::StarRocks)
5197 | Some(DialectType::Doris)
5198 | Some(DialectType::Athena)
5199 | Some(DialectType::ClickHouse)
5200 | Some(DialectType::Redshift)
5201 );
5202
5203 if fetch_already_as_limit {
5204 } else {
5206 if self.config.pretty {
5207 self.write_newline();
5208 self.write_indent();
5209 } else {
5210 self.write_space();
5211 }
5212
5213 let use_limit = !fetch.percent
5215 && !fetch.with_ties
5216 && fetch.count.is_some()
5217 && matches!(
5218 self.config.dialect,
5219 Some(DialectType::Spark)
5220 | Some(DialectType::Hive)
5221 | Some(DialectType::DuckDB)
5222 | Some(DialectType::SQLite)
5223 | Some(DialectType::MySQL)
5224 | Some(DialectType::BigQuery)
5225 | Some(DialectType::Databricks)
5226 | Some(DialectType::StarRocks)
5227 | Some(DialectType::Doris)
5228 | Some(DialectType::Athena)
5229 | Some(DialectType::ClickHouse)
5230 | Some(DialectType::Redshift)
5231 );
5232
5233 if use_limit {
5234 self.write_keyword("LIMIT");
5235 self.write_space();
5236 self.generate_expression(fetch.count.as_ref().unwrap())?;
5237 } else {
5238 self.write_keyword("FETCH");
5239 self.write_space();
5240 self.write_keyword(&fetch.direction);
5241 if let Some(ref count) = fetch.count {
5242 self.write_space();
5243 self.generate_expression(count)?;
5244 }
5245 if fetch.percent {
5246 self.write_space();
5247 self.write_keyword("PERCENT");
5248 }
5249 if fetch.rows {
5250 self.write_space();
5251 self.write_keyword("ROWS");
5252 }
5253 if fetch.with_ties {
5254 self.write_space();
5255 self.write_keyword("WITH TIES");
5256 } else {
5257 self.write_space();
5258 self.write_keyword("ONLY");
5259 }
5260 }
5261 } }
5263
5264 if let Some(sample) = &select.sample {
5266 use crate::dialects::DialectType;
5267 if self.config.pretty {
5268 self.write_newline();
5269 } else {
5270 self.write_space();
5271 }
5272
5273 if sample.is_using_sample {
5274 self.write_keyword("USING SAMPLE");
5276 self.generate_sample_body(sample)?;
5277 } else {
5278 self.write_keyword("TABLESAMPLE");
5279
5280 let snowflake_bernoulli =
5282 matches!(self.config.dialect, Some(DialectType::Snowflake))
5283 && !sample.explicit_method;
5284 if snowflake_bernoulli {
5285 self.write_space();
5286 self.write_keyword("BERNOULLI");
5287 }
5288
5289 if matches!(sample.method, SampleMethod::Bucket) {
5291 self.write_space();
5292 self.write("(");
5293 self.write_keyword("BUCKET");
5294 self.write_space();
5295 if let Some(ref num) = sample.bucket_numerator {
5296 self.generate_expression(num)?;
5297 }
5298 self.write_space();
5299 self.write_keyword("OUT OF");
5300 self.write_space();
5301 if let Some(ref denom) = sample.bucket_denominator {
5302 self.generate_expression(denom)?;
5303 }
5304 if let Some(ref field) = sample.bucket_field {
5305 self.write_space();
5306 self.write_keyword("ON");
5307 self.write_space();
5308 self.generate_expression(field)?;
5309 }
5310 self.write(")");
5311 } else if sample.unit_after_size {
5312 if sample.explicit_method && sample.method_before_size {
5314 self.write_space();
5315 match sample.method {
5316 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5317 SampleMethod::System => self.write_keyword("SYSTEM"),
5318 SampleMethod::Block => self.write_keyword("BLOCK"),
5319 SampleMethod::Row => self.write_keyword("ROW"),
5320 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5321 _ => {}
5322 }
5323 }
5324 self.write(" (");
5325 self.generate_expression(&sample.size)?;
5326 self.write_space();
5327 match sample.method {
5328 SampleMethod::Percent => self.write_keyword("PERCENT"),
5329 SampleMethod::Row => self.write_keyword("ROWS"),
5330 SampleMethod::Reservoir => self.write_keyword("ROWS"),
5331 _ => {
5332 self.write_keyword("PERCENT");
5333 }
5334 }
5335 self.write(")");
5336 } else {
5337 self.write_space();
5339 match sample.method {
5340 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5341 SampleMethod::System => self.write_keyword("SYSTEM"),
5342 SampleMethod::Block => self.write_keyword("BLOCK"),
5343 SampleMethod::Row => self.write_keyword("ROW"),
5344 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
5345 SampleMethod::Bucket => {}
5346 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5347 }
5348 self.write(" (");
5349 self.generate_expression(&sample.size)?;
5350 if matches!(sample.method, SampleMethod::Percent) {
5351 self.write_space();
5352 self.write_keyword("PERCENT");
5353 }
5354 self.write(")");
5355 }
5356 }
5357
5358 if let Some(seed) = &sample.seed {
5359 self.write_space();
5360 let use_seed = sample.use_seed_keyword
5362 && !matches!(
5363 self.config.dialect,
5364 Some(crate::dialects::DialectType::Databricks)
5365 | Some(crate::dialects::DialectType::Spark)
5366 );
5367 if use_seed {
5368 self.write_keyword("SEED");
5369 } else {
5370 self.write_keyword("REPEATABLE");
5371 }
5372 self.write(" (");
5373 self.generate_expression(seed)?;
5374 self.write(")");
5375 }
5376 }
5377
5378 if self.config.locking_reads_supported {
5381 for lock in &select.locks {
5382 if self.config.pretty {
5383 self.write_newline();
5384 self.write_indent();
5385 } else {
5386 self.write_space();
5387 }
5388 self.generate_lock(lock)?;
5389 }
5390 }
5391
5392 if !select.for_xml.is_empty() {
5394 if self.config.pretty {
5395 self.write_newline();
5396 self.write_indent();
5397 } else {
5398 self.write_space();
5399 }
5400 self.write_keyword("FOR XML");
5401 for (i, opt) in select.for_xml.iter().enumerate() {
5402 if self.config.pretty {
5403 if i > 0 {
5404 self.write(",");
5405 }
5406 self.write_newline();
5407 self.write_indent();
5408 self.write(" "); } else {
5410 if i > 0 {
5411 self.write(",");
5412 }
5413 self.write_space();
5414 }
5415 self.generate_for_xml_option(opt)?;
5416 }
5417 }
5418
5419 if !select.for_json.is_empty()
5421 && matches!(
5422 self.config.dialect,
5423 None | Some(DialectType::TSQL) | Some(DialectType::Fabric)
5424 )
5425 {
5426 if self.config.pretty {
5427 self.write_newline();
5428 self.write_indent();
5429 } else {
5430 self.write_space();
5431 }
5432 self.write_keyword("FOR JSON");
5433 for (i, opt) in select.for_json.iter().enumerate() {
5434 if self.config.pretty {
5435 if i > 0 {
5436 self.write(",");
5437 }
5438 self.write_newline();
5439 self.write_indent();
5440 self.write(" "); } else {
5442 if i > 0 {
5443 self.write(",");
5444 }
5445 self.write_space();
5446 }
5447 self.generate_for_xml_option(opt)?;
5448 }
5449 }
5450
5451 if let Some(ref option) = select.option {
5453 if matches!(
5454 self.config.dialect,
5455 Some(crate::dialects::DialectType::TSQL)
5456 | Some(crate::dialects::DialectType::Fabric)
5457 ) {
5458 self.write_space();
5459 self.write(option);
5460 }
5461 }
5462
5463 Ok(())
5464 }
5465
5466 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
5468 match opt {
5469 Expression::QueryOption(qo) => {
5470 if let Expression::Var(var) = &*qo.this {
5472 self.write(&var.this);
5473 } else {
5474 self.generate_expression(&qo.this)?;
5475 }
5476 if let Some(expr) = &qo.expression {
5478 self.write("(");
5479 self.generate_expression(expr)?;
5480 self.write(")");
5481 }
5482 }
5483 _ => {
5484 self.generate_expression(opt)?;
5485 }
5486 }
5487 Ok(())
5488 }
5489
5490 fn generate_with(&mut self, with: &With) -> Result<()> {
5491 use crate::dialects::DialectType;
5492
5493 for comment in &with.leading_comments {
5495 self.write_formatted_comment(comment);
5496 self.write(" ");
5497 }
5498 self.write_keyword("WITH");
5499 if with.recursive && self.config.cte_recursive_keyword_required {
5500 self.write_space();
5501 self.write_keyword("RECURSIVE");
5502 }
5503 self.write_space();
5504
5505 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
5507
5508 for (i, cte) in with.ctes.iter().enumerate() {
5509 if i > 0 {
5510 self.write(",");
5511 if self.config.pretty {
5512 self.write_space();
5513 } else {
5514 self.write(" ");
5515 }
5516 }
5517 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
5518 self.generate_expression(&cte.this)?;
5519 self.write_space();
5520 self.write_keyword("AS");
5521 self.write_space();
5522 self.generate_identifier(&cte.alias)?;
5523 continue;
5524 }
5525 self.generate_identifier(&cte.alias)?;
5526 for comment in &cte.comments {
5528 self.write_space();
5529 self.write_formatted_comment(comment);
5530 }
5531 if !cte.columns.is_empty() && !skip_cte_columns {
5532 self.write("(");
5533 for (j, col) in cte.columns.iter().enumerate() {
5534 if j > 0 {
5535 self.write(", ");
5536 }
5537 self.generate_identifier(col)?;
5538 }
5539 self.write(")");
5540 }
5541 if !cte.key_expressions.is_empty() {
5543 self.write_space();
5544 self.write_keyword("USING KEY");
5545 self.write(" (");
5546 for (i, key) in cte.key_expressions.iter().enumerate() {
5547 if i > 0 {
5548 self.write(", ");
5549 }
5550 self.generate_identifier(key)?;
5551 }
5552 self.write(")");
5553 }
5554 self.write_space();
5555 self.write_keyword("AS");
5556 if let Some(materialized) = cte.materialized {
5558 self.write_space();
5559 if materialized {
5560 self.write_keyword("MATERIALIZED");
5561 } else {
5562 self.write_keyword("NOT MATERIALIZED");
5563 }
5564 }
5565 self.write(" (");
5566 if self.config.pretty {
5567 self.write_newline();
5568 self.indent_level += 1;
5569 self.write_indent();
5570 }
5571 let wrap_values_in_select = matches!(
5574 self.config.dialect,
5575 Some(DialectType::Spark) | Some(DialectType::Databricks)
5576 ) && matches!(&cte.this, Expression::Values(_));
5577
5578 if wrap_values_in_select {
5579 self.write_keyword("SELECT");
5580 self.write(" * ");
5581 self.write_keyword("FROM");
5582 self.write_space();
5583 }
5584 self.generate_expression(&cte.this)?;
5585 if self.config.pretty {
5586 self.write_newline();
5587 self.indent_level -= 1;
5588 self.write_indent();
5589 }
5590 self.write(")");
5591 }
5592
5593 if let Some(search) = &with.search {
5595 self.write_space();
5596 self.generate_expression(search)?;
5597 }
5598
5599 Ok(())
5600 }
5601
5602 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
5606 let mut i = 0;
5607 while i < joins.len() {
5608 if joins[i].deferred_condition {
5609 let parent_group = joins[i].nesting_group;
5610
5611 self.generate_join_without_condition(&joins[i])?;
5614
5615 let child_start = i + 1;
5617 let mut child_end = child_start;
5618 while child_end < joins.len()
5619 && !joins[child_end].deferred_condition
5620 && joins[child_end].nesting_group == parent_group
5621 {
5622 child_end += 1;
5623 }
5624
5625 if child_start < child_end {
5627 self.indent_level += 1;
5628 for j in child_start..child_end {
5629 self.generate_join(&joins[j])?;
5630 }
5631 self.indent_level -= 1;
5632 }
5633
5634 self.generate_join_condition(&joins[i])?;
5636
5637 i = child_end;
5638 } else {
5639 self.generate_join(&joins[i])?;
5641 i += 1;
5642 }
5643 }
5644 Ok(())
5645 }
5646
5647 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5650 let mut join_copy = join.clone();
5653 join_copy.on = None;
5654 join_copy.using = Vec::new();
5655 join_copy.deferred_condition = false;
5656 self.generate_join(&join_copy)
5657 }
5658
5659 fn generate_join(&mut self, join: &Join) -> Result<()> {
5660 if join.kind == JoinKind::Implicit {
5662 self.write(",");
5663 if self.config.pretty {
5664 self.write_newline();
5665 self.write_indent();
5666 } else {
5667 self.write_space();
5668 }
5669 self.generate_expression(&join.this)?;
5670 return Ok(());
5671 }
5672
5673 if self.config.pretty {
5674 self.write_newline();
5675 self.write_indent();
5676 } else {
5677 self.write_space();
5678 }
5679
5680 let hint_str = if self.config.join_hints {
5683 join.join_hint
5684 .as_ref()
5685 .map(|h| format!(" {}", h))
5686 .unwrap_or_default()
5687 } else {
5688 String::new()
5689 };
5690
5691 let clickhouse_join_keyword =
5692 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5693 if let Some(hint) = &join.join_hint {
5694 let mut global = false;
5695 let mut strictness: Option<&'static str> = None;
5696 for part in hint.split_whitespace() {
5697 if part.eq_ignore_ascii_case("GLOBAL") {
5698 global = true;
5699 } else if part.eq_ignore_ascii_case("ALL") {
5700 strictness = Some("ALL");
5701 } else if part.eq_ignore_ascii_case("ANY") {
5702 strictness = Some("ANY");
5703 } else if part.eq_ignore_ascii_case("ASOF") {
5704 strictness = Some("ASOF");
5705 } else if part.eq_ignore_ascii_case("SEMI") {
5706 strictness = Some("SEMI");
5707 } else if part.eq_ignore_ascii_case("ANTI") {
5708 strictness = Some("ANTI");
5709 }
5710 }
5711
5712 if global || strictness.is_some() {
5713 let join_type = match join.kind {
5714 JoinKind::Left => {
5715 if join.use_outer_keyword {
5716 "LEFT OUTER"
5717 } else if join.use_inner_keyword {
5718 "LEFT INNER"
5719 } else {
5720 "LEFT"
5721 }
5722 }
5723 JoinKind::Right => {
5724 if join.use_outer_keyword {
5725 "RIGHT OUTER"
5726 } else if join.use_inner_keyword {
5727 "RIGHT INNER"
5728 } else {
5729 "RIGHT"
5730 }
5731 }
5732 JoinKind::Full => {
5733 if join.use_outer_keyword {
5734 "FULL OUTER"
5735 } else {
5736 "FULL"
5737 }
5738 }
5739 JoinKind::Inner => {
5740 if join.use_inner_keyword {
5741 "INNER"
5742 } else {
5743 ""
5744 }
5745 }
5746 _ => "",
5747 };
5748
5749 let mut parts = Vec::new();
5750 if global {
5751 parts.push("GLOBAL");
5752 }
5753 if !join_type.is_empty() {
5754 parts.push(join_type);
5755 }
5756 if let Some(strict) = strictness {
5757 parts.push(strict);
5758 }
5759 parts.push("JOIN");
5760 Some(parts.join(" "))
5761 } else {
5762 None
5763 }
5764 } else {
5765 None
5766 }
5767 } else {
5768 None
5769 };
5770
5771 if !join.comments.is_empty() {
5775 if self.config.pretty {
5776 let trimmed = self.output.trim_end().len();
5781 self.output.truncate(trimmed);
5782 for comment in &join.comments {
5783 self.write_newline();
5784 self.write_indent();
5785 self.write_formatted_comment(comment);
5786 }
5787 self.write_newline();
5788 self.write_indent();
5789 } else {
5790 for comment in &join.comments {
5791 self.write_formatted_comment(comment);
5792 self.write_space();
5793 }
5794 }
5795 }
5796
5797 let directed_str = if join.directed { " DIRECTED" } else { "" };
5798
5799 if let Some(keyword) = clickhouse_join_keyword {
5800 self.write_keyword(&keyword);
5801 } else {
5802 match join.kind {
5803 JoinKind::Inner => {
5804 if join.use_inner_keyword {
5805 if hint_str.is_empty() && directed_str.is_empty() {
5806 self.write_keyword("INNER JOIN");
5807 } else {
5808 self.write_keyword("INNER");
5809 if !hint_str.is_empty() {
5810 self.write_keyword(&hint_str);
5811 }
5812 if !directed_str.is_empty() {
5813 self.write_keyword(directed_str);
5814 }
5815 self.write_keyword(" JOIN");
5816 }
5817 } else {
5818 if !hint_str.is_empty() {
5819 self.write_keyword(hint_str.trim());
5820 self.write_keyword(" ");
5821 }
5822 if !directed_str.is_empty() {
5823 self.write_keyword("DIRECTED ");
5824 }
5825 self.write_keyword("JOIN");
5826 }
5827 }
5828 JoinKind::Left => {
5829 if join.use_outer_keyword {
5830 if hint_str.is_empty() && directed_str.is_empty() {
5831 self.write_keyword("LEFT OUTER JOIN");
5832 } else {
5833 self.write_keyword("LEFT OUTER");
5834 if !hint_str.is_empty() {
5835 self.write_keyword(&hint_str);
5836 }
5837 if !directed_str.is_empty() {
5838 self.write_keyword(directed_str);
5839 }
5840 self.write_keyword(" JOIN");
5841 }
5842 } else if join.use_inner_keyword {
5843 if hint_str.is_empty() && directed_str.is_empty() {
5844 self.write_keyword("LEFT INNER JOIN");
5845 } else {
5846 self.write_keyword("LEFT INNER");
5847 if !hint_str.is_empty() {
5848 self.write_keyword(&hint_str);
5849 }
5850 if !directed_str.is_empty() {
5851 self.write_keyword(directed_str);
5852 }
5853 self.write_keyword(" JOIN");
5854 }
5855 } else {
5856 if hint_str.is_empty() && directed_str.is_empty() {
5857 self.write_keyword("LEFT JOIN");
5858 } else {
5859 self.write_keyword("LEFT");
5860 if !hint_str.is_empty() {
5861 self.write_keyword(&hint_str);
5862 }
5863 if !directed_str.is_empty() {
5864 self.write_keyword(directed_str);
5865 }
5866 self.write_keyword(" JOIN");
5867 }
5868 }
5869 }
5870 JoinKind::Right => {
5871 if join.use_outer_keyword {
5872 if hint_str.is_empty() && directed_str.is_empty() {
5873 self.write_keyword("RIGHT OUTER JOIN");
5874 } else {
5875 self.write_keyword("RIGHT OUTER");
5876 if !hint_str.is_empty() {
5877 self.write_keyword(&hint_str);
5878 }
5879 if !directed_str.is_empty() {
5880 self.write_keyword(directed_str);
5881 }
5882 self.write_keyword(" JOIN");
5883 }
5884 } else if join.use_inner_keyword {
5885 if hint_str.is_empty() && directed_str.is_empty() {
5886 self.write_keyword("RIGHT INNER JOIN");
5887 } else {
5888 self.write_keyword("RIGHT INNER");
5889 if !hint_str.is_empty() {
5890 self.write_keyword(&hint_str);
5891 }
5892 if !directed_str.is_empty() {
5893 self.write_keyword(directed_str);
5894 }
5895 self.write_keyword(" JOIN");
5896 }
5897 } else {
5898 if hint_str.is_empty() && directed_str.is_empty() {
5899 self.write_keyword("RIGHT JOIN");
5900 } else {
5901 self.write_keyword("RIGHT");
5902 if !hint_str.is_empty() {
5903 self.write_keyword(&hint_str);
5904 }
5905 if !directed_str.is_empty() {
5906 self.write_keyword(directed_str);
5907 }
5908 self.write_keyword(" JOIN");
5909 }
5910 }
5911 }
5912 JoinKind::Full => {
5913 if join.use_outer_keyword {
5914 if hint_str.is_empty() && directed_str.is_empty() {
5915 self.write_keyword("FULL OUTER JOIN");
5916 } else {
5917 self.write_keyword("FULL OUTER");
5918 if !hint_str.is_empty() {
5919 self.write_keyword(&hint_str);
5920 }
5921 if !directed_str.is_empty() {
5922 self.write_keyword(directed_str);
5923 }
5924 self.write_keyword(" JOIN");
5925 }
5926 } else {
5927 if hint_str.is_empty() && directed_str.is_empty() {
5928 self.write_keyword("FULL JOIN");
5929 } else {
5930 self.write_keyword("FULL");
5931 if !hint_str.is_empty() {
5932 self.write_keyword(&hint_str);
5933 }
5934 if !directed_str.is_empty() {
5935 self.write_keyword(directed_str);
5936 }
5937 self.write_keyword(" JOIN");
5938 }
5939 }
5940 }
5941 JoinKind::Outer => {
5942 if directed_str.is_empty() {
5943 self.write_keyword("OUTER JOIN");
5944 } else {
5945 self.write_keyword("OUTER");
5946 self.write_keyword(directed_str);
5947 self.write_keyword(" JOIN");
5948 }
5949 }
5950 JoinKind::Cross => {
5951 if directed_str.is_empty() {
5952 self.write_keyword("CROSS JOIN");
5953 } else {
5954 self.write_keyword("CROSS");
5955 self.write_keyword(directed_str);
5956 self.write_keyword(" JOIN");
5957 }
5958 }
5959 JoinKind::Natural => {
5960 if join.use_inner_keyword {
5961 if directed_str.is_empty() {
5962 self.write_keyword("NATURAL INNER JOIN");
5963 } else {
5964 self.write_keyword("NATURAL INNER");
5965 self.write_keyword(directed_str);
5966 self.write_keyword(" JOIN");
5967 }
5968 } else {
5969 if directed_str.is_empty() {
5970 self.write_keyword("NATURAL JOIN");
5971 } else {
5972 self.write_keyword("NATURAL");
5973 self.write_keyword(directed_str);
5974 self.write_keyword(" JOIN");
5975 }
5976 }
5977 }
5978 JoinKind::NaturalLeft => {
5979 if join.use_outer_keyword {
5980 if directed_str.is_empty() {
5981 self.write_keyword("NATURAL LEFT OUTER JOIN");
5982 } else {
5983 self.write_keyword("NATURAL LEFT OUTER");
5984 self.write_keyword(directed_str);
5985 self.write_keyword(" JOIN");
5986 }
5987 } else {
5988 if directed_str.is_empty() {
5989 self.write_keyword("NATURAL LEFT JOIN");
5990 } else {
5991 self.write_keyword("NATURAL LEFT");
5992 self.write_keyword(directed_str);
5993 self.write_keyword(" JOIN");
5994 }
5995 }
5996 }
5997 JoinKind::NaturalRight => {
5998 if join.use_outer_keyword {
5999 if directed_str.is_empty() {
6000 self.write_keyword("NATURAL RIGHT OUTER JOIN");
6001 } else {
6002 self.write_keyword("NATURAL RIGHT OUTER");
6003 self.write_keyword(directed_str);
6004 self.write_keyword(" JOIN");
6005 }
6006 } else {
6007 if directed_str.is_empty() {
6008 self.write_keyword("NATURAL RIGHT JOIN");
6009 } else {
6010 self.write_keyword("NATURAL RIGHT");
6011 self.write_keyword(directed_str);
6012 self.write_keyword(" JOIN");
6013 }
6014 }
6015 }
6016 JoinKind::NaturalFull => {
6017 if join.use_outer_keyword {
6018 if directed_str.is_empty() {
6019 self.write_keyword("NATURAL FULL OUTER JOIN");
6020 } else {
6021 self.write_keyword("NATURAL FULL OUTER");
6022 self.write_keyword(directed_str);
6023 self.write_keyword(" JOIN");
6024 }
6025 } else {
6026 if directed_str.is_empty() {
6027 self.write_keyword("NATURAL FULL JOIN");
6028 } else {
6029 self.write_keyword("NATURAL FULL");
6030 self.write_keyword(directed_str);
6031 self.write_keyword(" JOIN");
6032 }
6033 }
6034 }
6035 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
6036 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
6037 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
6038 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
6039 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
6040 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
6041 JoinKind::CrossApply => {
6042 if matches!(
6044 self.config.dialect,
6045 Some(DialectType::TSQL) | Some(DialectType::Fabric) | None
6046 ) {
6047 self.write_keyword("CROSS APPLY");
6048 } else {
6049 self.write_keyword("INNER JOIN LATERAL");
6050 }
6051 }
6052 JoinKind::OuterApply => {
6053 if matches!(
6055 self.config.dialect,
6056 Some(DialectType::TSQL) | Some(DialectType::Fabric) | None
6057 ) {
6058 self.write_keyword("OUTER APPLY");
6059 } else {
6060 self.write_keyword("LEFT JOIN LATERAL");
6061 }
6062 }
6063 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
6064 JoinKind::AsOfLeft => {
6065 if join.use_outer_keyword {
6066 self.write_keyword("ASOF LEFT OUTER JOIN");
6067 } else {
6068 self.write_keyword("ASOF LEFT JOIN");
6069 }
6070 }
6071 JoinKind::AsOfRight => {
6072 if join.use_outer_keyword {
6073 self.write_keyword("ASOF RIGHT OUTER JOIN");
6074 } else {
6075 self.write_keyword("ASOF RIGHT JOIN");
6076 }
6077 }
6078 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
6079 JoinKind::LeftLateral => {
6080 if join.use_outer_keyword {
6081 self.write_keyword("LEFT OUTER LATERAL JOIN");
6082 } else {
6083 self.write_keyword("LEFT LATERAL JOIN");
6084 }
6085 }
6086 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
6087 JoinKind::Implicit => {
6088 use crate::dialects::DialectType;
6092 let is_cj_dialect = matches!(
6093 self.config.dialect,
6094 Some(DialectType::BigQuery)
6095 | Some(DialectType::Hive)
6096 | Some(DialectType::Spark)
6097 | Some(DialectType::Databricks)
6098 );
6099 let source_is_same = self.config.source_dialect.is_some()
6100 && self.config.source_dialect == self.config.dialect;
6101 let source_is_cj = matches!(
6102 self.config.source_dialect,
6103 Some(DialectType::BigQuery)
6104 | Some(DialectType::Hive)
6105 | Some(DialectType::Spark)
6106 | Some(DialectType::Databricks)
6107 );
6108 if is_cj_dialect
6109 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
6110 {
6111 self.write_keyword("CROSS JOIN");
6112 } else {
6113 self.output.truncate(self.output.trim_end().len());
6117 self.write(",");
6118 }
6119 }
6120 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
6121 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
6122 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
6123 JoinKind::Positional => self.write_keyword("POSITIONAL JOIN"),
6124 }
6125 }
6126
6127 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
6129 match &join.this {
6130 Expression::Tuple(t) if t.expressions.is_empty() => {}
6131 Expression::Tuple(t) => {
6132 self.write_space();
6133 for (i, item) in t.expressions.iter().enumerate() {
6134 if i > 0 {
6135 self.write(", ");
6136 }
6137 self.generate_expression(item)?;
6138 }
6139 }
6140 other => {
6141 self.write_space();
6142 self.generate_expression(other)?;
6143 }
6144 }
6145 } else {
6146 self.write_space();
6147 self.generate_expression(&join.this)?;
6148 }
6149
6150 if !join.deferred_condition {
6152 if let Some(match_cond) = &join.match_condition {
6154 self.write_space();
6155 self.write_keyword("MATCH_CONDITION");
6156 self.write(" (");
6157 self.generate_expression(match_cond)?;
6158 self.write(")");
6159 }
6160
6161 if let Some(on) = &join.on {
6162 if self.config.pretty {
6163 self.write_newline();
6164 self.indent_level += 1;
6165 self.write_indent();
6166 self.write_keyword("ON");
6167 self.write_space();
6168 self.generate_join_on_condition(on)?;
6169 self.indent_level -= 1;
6170 } else {
6171 self.write_space();
6172 self.write_keyword("ON");
6173 self.write_space();
6174 self.generate_expression(on)?;
6175 }
6176 }
6177
6178 if !join.using.is_empty() {
6179 if self.config.pretty {
6180 self.write_newline();
6181 self.indent_level += 1;
6182 self.write_indent();
6183 self.write_keyword("USING");
6184 self.write(" (");
6185 for (i, col) in join.using.iter().enumerate() {
6186 if i > 0 {
6187 self.write(", ");
6188 }
6189 self.generate_identifier(col)?;
6190 }
6191 self.write(")");
6192 self.indent_level -= 1;
6193 } else {
6194 self.write_space();
6195 self.write_keyword("USING");
6196 self.write(" (");
6197 for (i, col) in join.using.iter().enumerate() {
6198 if i > 0 {
6199 self.write(", ");
6200 }
6201 self.generate_identifier(col)?;
6202 }
6203 self.write(")");
6204 }
6205 }
6206 }
6207
6208 for pivot in &join.pivots {
6210 self.write_space();
6211 self.generate_expression(pivot)?;
6212 }
6213
6214 Ok(())
6215 }
6216
6217 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
6219 if let Some(match_cond) = &join.match_condition {
6221 self.write_space();
6222 self.write_keyword("MATCH_CONDITION");
6223 self.write(" (");
6224 self.generate_expression(match_cond)?;
6225 self.write(")");
6226 }
6227
6228 if let Some(on) = &join.on {
6229 if self.config.pretty {
6230 self.write_newline();
6231 self.indent_level += 1;
6232 self.write_indent();
6233 self.write_keyword("ON");
6234 self.write_space();
6235 self.generate_join_on_condition(on)?;
6237 self.indent_level -= 1;
6238 } else {
6239 self.write_space();
6240 self.write_keyword("ON");
6241 self.write_space();
6242 self.generate_expression(on)?;
6243 }
6244 }
6245
6246 if !join.using.is_empty() {
6247 if self.config.pretty {
6248 self.write_newline();
6249 self.indent_level += 1;
6250 self.write_indent();
6251 self.write_keyword("USING");
6252 self.write(" (");
6253 for (i, col) in join.using.iter().enumerate() {
6254 if i > 0 {
6255 self.write(", ");
6256 }
6257 self.generate_identifier(col)?;
6258 }
6259 self.write(")");
6260 self.indent_level -= 1;
6261 } else {
6262 self.write_space();
6263 self.write_keyword("USING");
6264 self.write(" (");
6265 for (i, col) in join.using.iter().enumerate() {
6266 if i > 0 {
6267 self.write(", ");
6268 }
6269 self.generate_identifier(col)?;
6270 }
6271 self.write(")");
6272 }
6273 }
6274
6275 for pivot in &join.pivots {
6277 self.write_space();
6278 self.generate_expression(pivot)?;
6279 }
6280
6281 Ok(())
6282 }
6283
6284 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
6286 if let Expression::And(and_op) = expr {
6287 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
6288 self.generate_expression(conditions[0])?;
6289 for condition in conditions.iter().skip(1) {
6290 self.write_newline();
6291 self.write_indent();
6292 self.write_keyword("AND");
6293 self.write_space();
6294 self.generate_expression(condition)?;
6295 }
6296 return Ok(());
6297 }
6298 }
6299
6300 self.generate_expression(expr)
6301 }
6302
6303 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
6304 self.write("(");
6306 self.generate_expression(&jt.left)?;
6307
6308 for join in &jt.joins {
6310 self.generate_join(join)?;
6311 }
6312
6313 for (lv_idx, lv) in jt.lateral_views.iter().enumerate() {
6315 self.generate_lateral_view(lv, lv_idx)?;
6316 }
6317
6318 self.write(")");
6319
6320 if let Some(alias) = &jt.alias {
6322 self.write_space();
6323 self.write_keyword("AS");
6324 self.write_space();
6325 self.generate_identifier(alias)?;
6326 }
6327
6328 Ok(())
6329 }
6330
6331 fn generate_lateral_view(&mut self, lv: &LateralView, lv_index: usize) -> Result<()> {
6332 use crate::dialects::DialectType;
6333
6334 if self.config.pretty {
6335 self.write_newline();
6336 self.write_indent();
6337 } else {
6338 self.write_space();
6339 }
6340
6341 let use_lateral_join = matches!(
6344 self.config.dialect,
6345 Some(DialectType::PostgreSQL)
6346 | Some(DialectType::DuckDB)
6347 | Some(DialectType::Snowflake)
6348 | Some(DialectType::TSQL)
6349 | Some(DialectType::Presto)
6350 | Some(DialectType::Trino)
6351 | Some(DialectType::Athena)
6352 );
6353
6354 let use_unnest = matches!(
6356 self.config.dialect,
6357 Some(DialectType::DuckDB)
6358 | Some(DialectType::Presto)
6359 | Some(DialectType::Trino)
6360 | Some(DialectType::Athena)
6361 );
6362
6363 let (is_posexplode, is_inline, func_args) = match &lv.this {
6365 Expression::Explode(uf) => {
6366 (false, false, vec![uf.this.clone()])
6368 }
6369 Expression::Unnest(uf) => {
6370 let mut args = vec![uf.this.clone()];
6371 args.extend(uf.expressions.clone());
6372 (false, false, args)
6373 }
6374 Expression::Function(func) => {
6375 if func.name.eq_ignore_ascii_case("POSEXPLODE")
6376 || func.name.eq_ignore_ascii_case("POSEXPLODE_OUTER")
6377 {
6378 (true, false, func.args.clone())
6379 } else if func.name.eq_ignore_ascii_case("INLINE") {
6380 (false, true, func.args.clone())
6381 } else if func.name.eq_ignore_ascii_case("EXPLODE")
6382 || func.name.eq_ignore_ascii_case("EXPLODE_OUTER")
6383 {
6384 (false, false, func.args.clone())
6385 } else {
6386 (false, false, vec![])
6387 }
6388 }
6389 _ => (false, false, vec![]),
6390 };
6391
6392 if use_lateral_join {
6393 if lv.outer {
6395 self.write_keyword("LEFT JOIN LATERAL");
6396 } else {
6397 self.write_keyword("CROSS JOIN");
6398 }
6399 self.write_space();
6400
6401 if use_unnest && !func_args.is_empty() {
6402 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6405 func_args
6407 .iter()
6408 .map(|a| {
6409 if let Expression::Function(ref f) = a {
6410 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() == 1 {
6411 return Expression::ArrayFunc(Box::new(
6412 crate::expressions::ArrayConstructor {
6413 expressions: f.args.clone(),
6414 bracket_notation: true,
6415 use_list_keyword: false,
6416 },
6417 ));
6418 }
6419 }
6420 a.clone()
6421 })
6422 .collect::<Vec<_>>()
6423 } else if matches!(
6424 self.config.dialect,
6425 Some(DialectType::Presto)
6426 | Some(DialectType::Trino)
6427 | Some(DialectType::Athena)
6428 ) {
6429 func_args
6431 .iter()
6432 .map(|a| {
6433 if let Expression::Function(ref f) = a {
6434 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() >= 1 {
6435 return Expression::ArrayFunc(Box::new(
6436 crate::expressions::ArrayConstructor {
6437 expressions: f.args.clone(),
6438 bracket_notation: true,
6439 use_list_keyword: false,
6440 },
6441 ));
6442 }
6443 }
6444 a.clone()
6445 })
6446 .collect::<Vec<_>>()
6447 } else {
6448 func_args
6449 };
6450
6451 if is_posexplode {
6453 self.write_keyword("LATERAL");
6454 self.write(" (");
6455 self.write_keyword("SELECT");
6456 self.write_space();
6457
6458 let pos_alias = if !lv.column_aliases.is_empty() {
6461 lv.column_aliases[0].clone()
6462 } else {
6463 Identifier::new("pos")
6464 };
6465 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
6466 lv.column_aliases[1..].to_vec()
6467 } else {
6468 vec![Identifier::new("col")]
6469 };
6470
6471 self.generate_identifier(&pos_alias)?;
6473 self.write(" - 1");
6474 self.write_space();
6475 self.write_keyword("AS");
6476 self.write_space();
6477 self.generate_identifier(&pos_alias)?;
6478
6479 for data_col in &data_aliases {
6481 self.write(", ");
6482 self.generate_identifier(data_col)?;
6483 }
6484
6485 self.write_space();
6486 self.write_keyword("FROM");
6487 self.write_space();
6488 self.write_keyword("UNNEST");
6489 self.write("(");
6490 for (i, arg) in unnest_args.iter().enumerate() {
6491 if i > 0 {
6492 self.write(", ");
6493 }
6494 self.generate_expression(arg)?;
6495 }
6496 self.write(")");
6497 self.write_space();
6498 self.write_keyword("WITH ORDINALITY");
6499 self.write_space();
6500 self.write_keyword("AS");
6501 self.write_space();
6502
6503 let table_alias_ident = lv
6505 .table_alias
6506 .clone()
6507 .unwrap_or_else(|| Identifier::new("t"));
6508 self.generate_identifier(&table_alias_ident)?;
6509 self.write("(");
6510 for (i, data_col) in data_aliases.iter().enumerate() {
6511 if i > 0 {
6512 self.write(", ");
6513 }
6514 self.generate_identifier(data_col)?;
6515 }
6516 self.write(", ");
6517 self.generate_identifier(&pos_alias)?;
6518 self.write("))");
6519 } else if is_inline && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6520 self.write_keyword("LATERAL");
6522 self.write(" (");
6523 self.write_keyword("SELECT");
6524 self.write_space();
6525 self.write_keyword("UNNEST");
6526 self.write("(");
6527 for (i, arg) in unnest_args.iter().enumerate() {
6528 if i > 0 {
6529 self.write(", ");
6530 }
6531 self.generate_expression(arg)?;
6532 }
6533 self.write(", ");
6534 self.write_keyword("max_depth");
6535 self.write(" => 2))");
6536
6537 if let Some(alias) = &lv.table_alias {
6539 self.write_space();
6540 self.write_keyword("AS");
6541 self.write_space();
6542 self.generate_identifier(alias)?;
6543 if !lv.column_aliases.is_empty() {
6544 self.write("(");
6545 for (i, col) in lv.column_aliases.iter().enumerate() {
6546 if i > 0 {
6547 self.write(", ");
6548 }
6549 self.generate_identifier(col)?;
6550 }
6551 self.write(")");
6552 }
6553 } else if !lv.column_aliases.is_empty() {
6554 self.write_space();
6556 self.write_keyword("AS");
6557 self.write_space();
6558 self.write(&format!("_u_{}", lv_index));
6559 self.write("(");
6560 for (i, col) in lv.column_aliases.iter().enumerate() {
6561 if i > 0 {
6562 self.write(", ");
6563 }
6564 self.generate_identifier(col)?;
6565 }
6566 self.write(")");
6567 }
6568 } else {
6569 self.write_keyword("UNNEST");
6570 self.write("(");
6571 for (i, arg) in unnest_args.iter().enumerate() {
6572 if i > 0 {
6573 self.write(", ");
6574 }
6575 self.generate_expression(arg)?;
6576 }
6577 self.write(")");
6578
6579 if let Some(alias) = &lv.table_alias {
6581 self.write_space();
6582 self.write_keyword("AS");
6583 self.write_space();
6584 self.generate_identifier(alias)?;
6585 if !lv.column_aliases.is_empty() {
6586 self.write("(");
6587 for (i, col) in lv.column_aliases.iter().enumerate() {
6588 if i > 0 {
6589 self.write(", ");
6590 }
6591 self.generate_identifier(col)?;
6592 }
6593 self.write(")");
6594 }
6595 } else if !lv.column_aliases.is_empty() {
6596 self.write_space();
6597 self.write_keyword("AS");
6598 self.write(" t(");
6599 for (i, col) in lv.column_aliases.iter().enumerate() {
6600 if i > 0 {
6601 self.write(", ");
6602 }
6603 self.generate_identifier(col)?;
6604 }
6605 self.write(")");
6606 }
6607 }
6608 } else {
6609 if !lv.outer {
6611 self.write_keyword("LATERAL");
6612 self.write_space();
6613 }
6614 self.generate_expression(&lv.this)?;
6615
6616 if let Some(alias) = &lv.table_alias {
6618 self.write_space();
6619 self.write_keyword("AS");
6620 self.write_space();
6621 self.generate_identifier(alias)?;
6622 if !lv.column_aliases.is_empty() {
6623 self.write("(");
6624 for (i, col) in lv.column_aliases.iter().enumerate() {
6625 if i > 0 {
6626 self.write(", ");
6627 }
6628 self.generate_identifier(col)?;
6629 }
6630 self.write(")");
6631 }
6632 } else if !lv.column_aliases.is_empty() {
6633 self.write_space();
6634 self.write_keyword("AS");
6635 self.write(" t(");
6636 for (i, col) in lv.column_aliases.iter().enumerate() {
6637 if i > 0 {
6638 self.write(", ");
6639 }
6640 self.generate_identifier(col)?;
6641 }
6642 self.write(")");
6643 }
6644 }
6645
6646 if lv.outer {
6648 self.write_space();
6649 self.write_keyword("ON TRUE");
6650 }
6651 } else {
6652 self.write_keyword("LATERAL VIEW");
6654 if lv.outer {
6655 self.write_space();
6656 self.write_keyword("OUTER");
6657 }
6658 if self.config.pretty {
6659 self.write_newline();
6660 self.write_indent();
6661 } else {
6662 self.write_space();
6663 }
6664 self.generate_expression(&lv.this)?;
6665
6666 if let Some(alias) = &lv.table_alias {
6668 self.write_space();
6669 self.generate_identifier(alias)?;
6670 }
6671
6672 if !lv.column_aliases.is_empty() {
6674 self.write_space();
6675 self.write_keyword("AS");
6676 self.write_space();
6677 for (i, col) in lv.column_aliases.iter().enumerate() {
6678 if i > 0 {
6679 self.write(", ");
6680 }
6681 self.generate_identifier(col)?;
6682 }
6683 }
6684 }
6685
6686 Ok(())
6687 }
6688
6689 fn should_wrap_set_operation_modifiers(
6690 &self,
6691 order_by: &Option<OrderBy>,
6692 limit: &Option<Box<Expression>>,
6693 offset: &Option<Box<Expression>>,
6694 ) -> bool {
6695 let has_row_limit = limit.is_some() || offset.is_some();
6696 let has_emulated_null_ordering = order_by.as_ref().map_or(false, |order_by| {
6697 order_by
6698 .expressions
6699 .iter()
6700 .any(|ordered| ordered.nulls_first.is_some())
6701 });
6702
6703 (has_row_limit || has_emulated_null_ordering)
6704 && matches!(
6705 self.config.dialect,
6706 Some(DialectType::TSQL) | Some(DialectType::Fabric)
6707 )
6708 }
6709
6710 fn generate_tsql_wrapped_set_operation(
6711 &mut self,
6712 inner: Expression,
6713 with: Option<With>,
6714 order_by: Option<OrderBy>,
6715 limit: Option<Box<Expression>>,
6716 offset: Option<Box<Expression>>,
6717 ) -> Result<()> {
6718 let subquery = Subquery {
6719 this: inner,
6720 alias: Some(Identifier::new("_l_0".to_string())),
6721 column_aliases: Vec::new(),
6722 alias_explicit_as: true,
6723 alias_keyword: None,
6724 order_by: None,
6725 limit: None,
6726 offset: None,
6727 lateral: false,
6728 modifiers_inside: false,
6729 trailing_comments: Vec::new(),
6730 distribute_by: None,
6731 sort_by: None,
6732 cluster_by: None,
6733 inferred_type: None,
6734 };
6735
6736 let mut outer_select = Select {
6737 expressions: vec![Expression::Star(Star {
6738 table: None,
6739 except: None,
6740 replace: None,
6741 rename: None,
6742 trailing_comments: Vec::new(),
6743 span: None,
6744 })],
6745 from: Some(From {
6746 expressions: vec![Expression::Subquery(Box::new(subquery))],
6747 }),
6748 with,
6749 order_by,
6750 limit: limit.map(|limit| Limit {
6751 this: *limit,
6752 percent: false,
6753 comments: Vec::new(),
6754 }),
6755 offset: offset.map(|offset| Offset {
6756 this: *offset,
6757 rows: Some(true),
6758 }),
6759 ..Select::new()
6760 };
6761
6762 if outer_select.offset.is_some() && outer_select.order_by.is_none() {
6763 outer_select.order_by = Some(Self::dummy_tsql_order_by());
6764 }
6765
6766 self.generate_select(&outer_select)
6767 }
6768
6769 fn dummy_tsql_order_by() -> OrderBy {
6770 let null_select = Expression::Select(Box::new(Select {
6771 expressions: vec![Expression::Null(Null)],
6772 ..Select::new()
6773 }));
6774
6775 OrderBy {
6776 expressions: vec![Ordered {
6777 this: Expression::Subquery(Box::new(Subquery {
6778 this: null_select,
6779 alias: None,
6780 column_aliases: Vec::new(),
6781 alias_explicit_as: false,
6782 alias_keyword: None,
6783 order_by: None,
6784 limit: None,
6785 offset: None,
6786 lateral: false,
6787 modifiers_inside: false,
6788 trailing_comments: Vec::new(),
6789 distribute_by: None,
6790 sort_by: None,
6791 cluster_by: None,
6792 inferred_type: None,
6793 })),
6794 desc: false,
6795 nulls_first: None,
6796 explicit_asc: false,
6797 with_fill: None,
6798 }],
6799 siblings: false,
6800 comments: Vec::new(),
6801 }
6802 }
6803
6804 fn generate_union(&mut self, outermost: &Union) -> Result<()> {
6805 if self.should_wrap_set_operation_modifiers(
6806 &outermost.order_by,
6807 &outermost.limit,
6808 &outermost.offset,
6809 ) {
6810 let mut inner = outermost.clone();
6811 let with = inner.with.take();
6812 let order_by = inner.order_by.take();
6813 let limit = inner.limit.take();
6814 let offset = inner.offset.take();
6815
6816 return self.generate_tsql_wrapped_set_operation(
6817 Expression::Union(Box::new(inner)),
6818 with,
6819 order_by,
6820 limit,
6821 offset,
6822 );
6823 }
6824
6825 let mut chain: Vec<&Union> = vec![outermost];
6830 let mut leftmost: &Expression = &outermost.left;
6831 while let Expression::Union(inner) = leftmost {
6832 chain.push(inner);
6833 leftmost = &inner.left;
6834 }
6835 if let Some(with) = &outermost.with {
6840 self.generate_with(with)?;
6841 self.write_space();
6842 }
6843
6844 self.generate_expression(leftmost)?;
6846
6847 for union in chain.iter().rev() {
6849 self.generate_union_step(union)?;
6850 }
6851 Ok(())
6852 }
6853
6854 fn generate_union_step(&mut self, union: &Union) -> Result<()> {
6856 if self.config.pretty {
6857 self.write_newline();
6858 self.write_indent();
6859 } else {
6860 self.write_space();
6861 }
6862
6863 if let Some(side) = &union.side {
6865 self.write_keyword(side);
6866 self.write_space();
6867 }
6868 if let Some(kind) = &union.kind {
6869 self.write_keyword(kind);
6870 self.write_space();
6871 }
6872
6873 self.write_keyword("UNION");
6874 if union.all {
6875 self.write_space();
6876 self.write_keyword("ALL");
6877 } else if union.distinct {
6878 self.write_space();
6879 self.write_keyword("DISTINCT");
6880 }
6881
6882 if union.corresponding || union.by_name {
6885 self.write_space();
6886 self.write_keyword("BY NAME");
6887 }
6888 if !union.on_columns.is_empty() {
6889 self.write_space();
6890 self.write_keyword("ON");
6891 self.write(" (");
6892 for (i, col) in union.on_columns.iter().enumerate() {
6893 if i > 0 {
6894 self.write(", ");
6895 }
6896 self.generate_expression(col)?;
6897 }
6898 self.write(")");
6899 }
6900
6901 if self.config.pretty {
6902 self.write_newline();
6903 self.write_indent();
6904 } else {
6905 self.write_space();
6906 }
6907 self.generate_expression(&union.right)?;
6908 if let Some(order_by) = &union.order_by {
6910 if self.config.pretty {
6911 self.write_newline();
6912 } else {
6913 self.write_space();
6914 }
6915 self.write_keyword("ORDER BY");
6916 self.write_space();
6917 for (i, ordered) in order_by.expressions.iter().enumerate() {
6918 if i > 0 {
6919 self.write(", ");
6920 }
6921 self.generate_ordered(ordered)?;
6922 }
6923 }
6924 if let Some(limit) = &union.limit {
6925 if self.config.pretty {
6926 self.write_newline();
6927 } else {
6928 self.write_space();
6929 }
6930 self.write_keyword("LIMIT");
6931 self.write_space();
6932 self.generate_expression(limit)?;
6933 }
6934 if let Some(offset) = &union.offset {
6935 if self.config.pretty {
6936 self.write_newline();
6937 } else {
6938 self.write_space();
6939 }
6940 self.write_keyword("OFFSET");
6941 self.write_space();
6942 self.generate_expression(offset)?;
6943 }
6944 if let Some(distribute_by) = &union.distribute_by {
6946 self.write_space();
6947 self.write_keyword("DISTRIBUTE BY");
6948 self.write_space();
6949 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6950 if i > 0 {
6951 self.write(", ");
6952 }
6953 self.generate_expression(expr)?;
6954 }
6955 }
6956 if let Some(sort_by) = &union.sort_by {
6958 self.write_space();
6959 self.write_keyword("SORT BY");
6960 self.write_space();
6961 for (i, ord) in sort_by.expressions.iter().enumerate() {
6962 if i > 0 {
6963 self.write(", ");
6964 }
6965 self.generate_ordered(ord)?;
6966 }
6967 }
6968 if let Some(cluster_by) = &union.cluster_by {
6970 self.write_space();
6971 self.write_keyword("CLUSTER BY");
6972 self.write_space();
6973 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6974 if i > 0 {
6975 self.write(", ");
6976 }
6977 self.generate_ordered(ord)?;
6978 }
6979 }
6980 Ok(())
6981 }
6982
6983 fn generate_intersect(&mut self, outermost: &Intersect) -> Result<()> {
6984 if self.should_wrap_set_operation_modifiers(
6985 &outermost.order_by,
6986 &outermost.limit,
6987 &outermost.offset,
6988 ) {
6989 let mut inner = outermost.clone();
6990 let with = inner.with.take();
6991 let order_by = inner.order_by.take();
6992 let limit = inner.limit.take();
6993 let offset = inner.offset.take();
6994
6995 return self.generate_tsql_wrapped_set_operation(
6996 Expression::Intersect(Box::new(inner)),
6997 with,
6998 order_by,
6999 limit,
7000 offset,
7001 );
7002 }
7003
7004 let mut chain: Vec<&Intersect> = vec![outermost];
7006 let mut leftmost: &Expression = &outermost.left;
7007 while let Expression::Intersect(inner) = leftmost {
7008 chain.push(inner);
7009 leftmost = &inner.left;
7010 }
7011
7012 if let Some(with) = &outermost.with {
7013 self.generate_with(with)?;
7014 self.write_space();
7015 }
7016
7017 self.generate_expression(leftmost)?;
7018
7019 for intersect in chain.iter().rev() {
7020 self.generate_intersect_step(intersect)?;
7021 }
7022 Ok(())
7023 }
7024
7025 fn generate_intersect_step(&mut self, intersect: &Intersect) -> Result<()> {
7027 if self.config.pretty {
7028 self.write_newline();
7029 self.write_indent();
7030 } else {
7031 self.write_space();
7032 }
7033
7034 if let Some(side) = &intersect.side {
7036 self.write_keyword(side);
7037 self.write_space();
7038 }
7039 if let Some(kind) = &intersect.kind {
7040 self.write_keyword(kind);
7041 self.write_space();
7042 }
7043
7044 self.write_keyword("INTERSECT");
7045 if intersect.all {
7046 if !self.config.except_intersect_support_all_clause {
7047 self.unsupported("INTERSECT ALL is not supported")?;
7048 }
7049 self.write_space();
7050 self.write_keyword("ALL");
7051 } else if intersect.distinct {
7052 self.write_space();
7053 self.write_keyword("DISTINCT");
7054 }
7055
7056 if intersect.corresponding || intersect.by_name {
7059 self.write_space();
7060 self.write_keyword("BY NAME");
7061 }
7062 if !intersect.on_columns.is_empty() {
7063 self.write_space();
7064 self.write_keyword("ON");
7065 self.write(" (");
7066 for (i, col) in intersect.on_columns.iter().enumerate() {
7067 if i > 0 {
7068 self.write(", ");
7069 }
7070 self.generate_expression(col)?;
7071 }
7072 self.write(")");
7073 }
7074
7075 if self.config.pretty {
7076 self.write_newline();
7077 self.write_indent();
7078 } else {
7079 self.write_space();
7080 }
7081 self.generate_expression(&intersect.right)?;
7082 if let Some(order_by) = &intersect.order_by {
7084 if self.config.pretty {
7085 self.write_newline();
7086 } else {
7087 self.write_space();
7088 }
7089 self.write_keyword("ORDER BY");
7090 self.write_space();
7091 for (i, ordered) in order_by.expressions.iter().enumerate() {
7092 if i > 0 {
7093 self.write(", ");
7094 }
7095 self.generate_ordered(ordered)?;
7096 }
7097 }
7098 if let Some(limit) = &intersect.limit {
7099 if self.config.pretty {
7100 self.write_newline();
7101 } else {
7102 self.write_space();
7103 }
7104 self.write_keyword("LIMIT");
7105 self.write_space();
7106 self.generate_expression(limit)?;
7107 }
7108 if let Some(offset) = &intersect.offset {
7109 if self.config.pretty {
7110 self.write_newline();
7111 } else {
7112 self.write_space();
7113 }
7114 self.write_keyword("OFFSET");
7115 self.write_space();
7116 self.generate_expression(offset)?;
7117 }
7118 if let Some(distribute_by) = &intersect.distribute_by {
7120 self.write_space();
7121 self.write_keyword("DISTRIBUTE BY");
7122 self.write_space();
7123 for (i, expr) in distribute_by.expressions.iter().enumerate() {
7124 if i > 0 {
7125 self.write(", ");
7126 }
7127 self.generate_expression(expr)?;
7128 }
7129 }
7130 if let Some(sort_by) = &intersect.sort_by {
7132 self.write_space();
7133 self.write_keyword("SORT BY");
7134 self.write_space();
7135 for (i, ord) in sort_by.expressions.iter().enumerate() {
7136 if i > 0 {
7137 self.write(", ");
7138 }
7139 self.generate_ordered(ord)?;
7140 }
7141 }
7142 if let Some(cluster_by) = &intersect.cluster_by {
7144 self.write_space();
7145 self.write_keyword("CLUSTER BY");
7146 self.write_space();
7147 for (i, ord) in cluster_by.expressions.iter().enumerate() {
7148 if i > 0 {
7149 self.write(", ");
7150 }
7151 self.generate_ordered(ord)?;
7152 }
7153 }
7154 Ok(())
7155 }
7156
7157 fn generate_except(&mut self, outermost: &Except) -> Result<()> {
7158 if self.should_wrap_set_operation_modifiers(
7159 &outermost.order_by,
7160 &outermost.limit,
7161 &outermost.offset,
7162 ) {
7163 let mut inner = outermost.clone();
7164 let with = inner.with.take();
7165 let order_by = inner.order_by.take();
7166 let limit = inner.limit.take();
7167 let offset = inner.offset.take();
7168
7169 return self.generate_tsql_wrapped_set_operation(
7170 Expression::Except(Box::new(inner)),
7171 with,
7172 order_by,
7173 limit,
7174 offset,
7175 );
7176 }
7177
7178 let mut chain: Vec<&Except> = vec![outermost];
7180 let mut leftmost: &Expression = &outermost.left;
7181 while let Expression::Except(inner) = leftmost {
7182 chain.push(inner);
7183 leftmost = &inner.left;
7184 }
7185
7186 if let Some(with) = &outermost.with {
7187 self.generate_with(with)?;
7188 self.write_space();
7189 }
7190
7191 self.generate_expression(leftmost)?;
7192
7193 for except in chain.iter().rev() {
7194 self.generate_except_step(except)?;
7195 }
7196 Ok(())
7197 }
7198
7199 fn generate_except_step(&mut self, except: &Except) -> Result<()> {
7201 use crate::dialects::DialectType;
7202
7203 if self.config.pretty {
7204 self.write_newline();
7205 self.write_indent();
7206 } else {
7207 self.write_space();
7208 }
7209
7210 if let Some(side) = &except.side {
7212 self.write_keyword(side);
7213 self.write_space();
7214 }
7215 if let Some(kind) = &except.kind {
7216 self.write_keyword(kind);
7217 self.write_space();
7218 }
7219
7220 match self.config.dialect {
7222 Some(DialectType::Oracle) if !except.all => {
7223 self.write_keyword("MINUS");
7224 }
7225 Some(DialectType::ClickHouse) => {
7226 self.write_keyword("EXCEPT");
7227 let preserve_all = self.config.source_dialect.is_none()
7228 || matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
7229 if except.all && preserve_all {
7230 self.write_space();
7231 self.write_keyword("ALL");
7232 }
7233 if except.distinct {
7234 self.write_space();
7235 self.write_keyword("DISTINCT");
7236 }
7237 }
7238 Some(DialectType::BigQuery) => {
7239 self.write_keyword("EXCEPT");
7241 if except.all {
7242 self.write_space();
7243 self.write_keyword("ALL");
7244 } else {
7245 self.write_space();
7246 self.write_keyword("DISTINCT");
7247 }
7248 }
7249 _ => {
7250 self.write_keyword("EXCEPT");
7251 if except.all {
7252 if !self.config.except_intersect_support_all_clause {
7253 self.unsupported("EXCEPT ALL is not supported")?;
7254 }
7255 self.write_space();
7256 self.write_keyword("ALL");
7257 } else if except.distinct {
7258 self.write_space();
7259 self.write_keyword("DISTINCT");
7260 }
7261 }
7262 }
7263
7264 if except.corresponding || except.by_name {
7267 self.write_space();
7268 self.write_keyword("BY NAME");
7269 }
7270 if !except.on_columns.is_empty() {
7271 self.write_space();
7272 self.write_keyword("ON");
7273 self.write(" (");
7274 for (i, col) in except.on_columns.iter().enumerate() {
7275 if i > 0 {
7276 self.write(", ");
7277 }
7278 self.generate_expression(col)?;
7279 }
7280 self.write(")");
7281 }
7282
7283 if self.config.pretty {
7284 self.write_newline();
7285 self.write_indent();
7286 } else {
7287 self.write_space();
7288 }
7289 self.generate_expression(&except.right)?;
7290 if let Some(order_by) = &except.order_by {
7292 if self.config.pretty {
7293 self.write_newline();
7294 } else {
7295 self.write_space();
7296 }
7297 self.write_keyword("ORDER BY");
7298 self.write_space();
7299 for (i, ordered) in order_by.expressions.iter().enumerate() {
7300 if i > 0 {
7301 self.write(", ");
7302 }
7303 self.generate_ordered(ordered)?;
7304 }
7305 }
7306 if let Some(limit) = &except.limit {
7307 if self.config.pretty {
7308 self.write_newline();
7309 } else {
7310 self.write_space();
7311 }
7312 self.write_keyword("LIMIT");
7313 self.write_space();
7314 self.generate_expression(limit)?;
7315 }
7316 if let Some(offset) = &except.offset {
7317 if self.config.pretty {
7318 self.write_newline();
7319 } else {
7320 self.write_space();
7321 }
7322 self.write_keyword("OFFSET");
7323 self.write_space();
7324 self.generate_expression(offset)?;
7325 }
7326 if let Some(distribute_by) = &except.distribute_by {
7328 self.write_space();
7329 self.write_keyword("DISTRIBUTE BY");
7330 self.write_space();
7331 for (i, expr) in distribute_by.expressions.iter().enumerate() {
7332 if i > 0 {
7333 self.write(", ");
7334 }
7335 self.generate_expression(expr)?;
7336 }
7337 }
7338 if let Some(sort_by) = &except.sort_by {
7340 self.write_space();
7341 self.write_keyword("SORT BY");
7342 self.write_space();
7343 for (i, ord) in sort_by.expressions.iter().enumerate() {
7344 if i > 0 {
7345 self.write(", ");
7346 }
7347 self.generate_ordered(ord)?;
7348 }
7349 }
7350 if let Some(cluster_by) = &except.cluster_by {
7352 self.write_space();
7353 self.write_keyword("CLUSTER BY");
7354 self.write_space();
7355 for (i, ord) in cluster_by.expressions.iter().enumerate() {
7356 if i > 0 {
7357 self.write(", ");
7358 }
7359 self.generate_ordered(ord)?;
7360 }
7361 }
7362 Ok(())
7363 }
7364
7365 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
7366 let prepend_query_cte = if insert.with.is_none() {
7368 use crate::dialects::DialectType;
7369 let should_prepend = matches!(
7370 self.config.dialect,
7371 Some(DialectType::TSQL)
7372 | Some(DialectType::Fabric)
7373 | Some(DialectType::Spark)
7374 | Some(DialectType::Databricks)
7375 | Some(DialectType::Hive)
7376 );
7377 if should_prepend {
7378 if let Some(Expression::Select(select)) = &insert.query {
7379 select.with.clone()
7380 } else {
7381 None
7382 }
7383 } else {
7384 None
7385 }
7386 } else {
7387 None
7388 };
7389
7390 if let Some(with) = &insert.with {
7392 self.generate_with(with)?;
7393 self.write_space();
7394 } else if let Some(with) = &prepend_query_cte {
7395 self.generate_with(with)?;
7396 self.write_space();
7397 }
7398
7399 for comment in &insert.leading_comments {
7401 self.write_formatted_comment(comment);
7402 self.write(" ");
7403 }
7404
7405 if let Some(dir) = &insert.directory {
7407 self.write_keyword("INSERT OVERWRITE");
7408 if dir.local {
7409 self.write_space();
7410 self.write_keyword("LOCAL");
7411 }
7412 self.write_space();
7413 self.write_keyword("DIRECTORY");
7414 self.write_space();
7415 self.write("'");
7416 self.write(&dir.path);
7417 self.write("'");
7418
7419 if let Some(row_format) = &dir.row_format {
7421 self.write_space();
7422 self.write_keyword("ROW FORMAT");
7423 if row_format.delimited {
7424 self.write_space();
7425 self.write_keyword("DELIMITED");
7426 }
7427 if let Some(val) = &row_format.fields_terminated_by {
7428 self.write_space();
7429 self.write_keyword("FIELDS TERMINATED BY");
7430 self.write_space();
7431 self.generate_string_literal(val)?;
7432 }
7433 if let Some(val) = &row_format.collection_items_terminated_by {
7434 self.write_space();
7435 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
7436 self.write_space();
7437 self.write("'");
7438 self.write(val);
7439 self.write("'");
7440 }
7441 if let Some(val) = &row_format.map_keys_terminated_by {
7442 self.write_space();
7443 self.write_keyword("MAP KEYS TERMINATED BY");
7444 self.write_space();
7445 self.write("'");
7446 self.write(val);
7447 self.write("'");
7448 }
7449 if let Some(val) = &row_format.lines_terminated_by {
7450 self.write_space();
7451 self.write_keyword("LINES TERMINATED BY");
7452 self.write_space();
7453 self.write("'");
7454 self.write(val);
7455 self.write("'");
7456 }
7457 if let Some(val) = &row_format.null_defined_as {
7458 self.write_space();
7459 self.write_keyword("NULL DEFINED AS");
7460 self.write_space();
7461 self.write("'");
7462 self.write(val);
7463 self.write("'");
7464 }
7465 }
7466
7467 if let Some(format) = &dir.stored_as {
7469 self.write_space();
7470 self.write_keyword("STORED AS");
7471 self.write_space();
7472 self.write_keyword(format);
7473 }
7474
7475 if let Some(query) = &insert.query {
7477 self.write_space();
7478 self.generate_expression(query)?;
7479 }
7480
7481 return Ok(());
7482 }
7483
7484 if insert.is_replace {
7485 self.write_keyword("REPLACE INTO");
7487 } else if insert.overwrite {
7488 self.write_keyword("INSERT");
7490 if let Some(ref hint) = insert.hint {
7492 self.generate_hint(hint)?;
7493 }
7494 self.write(&self.config.insert_overwrite.to_ascii_uppercase());
7495 } else if let Some(ref action) = insert.conflict_action {
7496 self.write_keyword("INSERT OR");
7498 self.write_space();
7499 self.write_keyword(action);
7500 self.write_space();
7501 self.write_keyword("INTO");
7502 } else if insert.ignore {
7503 self.write_keyword("INSERT IGNORE INTO");
7505 } else {
7506 self.write_keyword("INSERT");
7507 if let Some(ref hint) = insert.hint {
7509 self.generate_hint(hint)?;
7510 }
7511 self.write_space();
7512 self.write_keyword("INTO");
7513 }
7514 if let Some(ref func) = insert.function_target {
7516 self.write_space();
7517 self.write_keyword("FUNCTION");
7518 self.write_space();
7519 self.generate_expression(func)?;
7520 } else {
7521 self.write_space();
7522 self.generate_table(&insert.table)?;
7523 }
7524
7525 if let Some(ref alias) = insert.alias {
7527 self.write_space();
7528 if insert.alias_explicit_as {
7529 self.write_keyword("AS");
7530 self.write_space();
7531 }
7532 self.generate_identifier(alias)?;
7533 }
7534
7535 if insert.if_exists {
7537 self.write_space();
7538 self.write_keyword("IF EXISTS");
7539 }
7540
7541 if let Some(ref replace_where) = insert.replace_where {
7543 if self.config.pretty {
7544 self.write_newline();
7545 self.write_indent();
7546 } else {
7547 self.write_space();
7548 }
7549 self.write_keyword("REPLACE WHERE");
7550 self.write_space();
7551 self.generate_expression(replace_where)?;
7552 }
7553
7554 if !insert.partition.is_empty() {
7556 self.write_space();
7557 self.write_keyword("PARTITION");
7558 self.write("(");
7559 for (i, (col, val)) in insert.partition.iter().enumerate() {
7560 if i > 0 {
7561 self.write(", ");
7562 }
7563 self.generate_identifier(col)?;
7564 if let Some(v) = val {
7565 self.write(" = ");
7566 self.generate_expression(v)?;
7567 }
7568 }
7569 self.write(")");
7570 }
7571
7572 if let Some(ref partition_by) = insert.partition_by {
7574 self.write_space();
7575 self.write_keyword("PARTITION BY");
7576 self.write_space();
7577 self.generate_expression(partition_by)?;
7578 }
7579
7580 if !insert.settings.is_empty() {
7582 self.write_space();
7583 self.write_keyword("SETTINGS");
7584 self.write_space();
7585 for (i, setting) in insert.settings.iter().enumerate() {
7586 if i > 0 {
7587 self.write(", ");
7588 }
7589 self.generate_expression(setting)?;
7590 }
7591 }
7592
7593 if !insert.columns.is_empty() {
7594 if insert.alias.is_some() && insert.alias_explicit_as {
7595 self.write("(");
7597 } else {
7598 self.write(" (");
7600 }
7601 for (i, col) in insert.columns.iter().enumerate() {
7602 if i > 0 {
7603 self.write(", ");
7604 }
7605 self.generate_identifier(col)?;
7606 }
7607 self.write(")");
7608 }
7609
7610 if let Some(ref output) = insert.output {
7612 self.generate_output_clause(output)?;
7613 }
7614
7615 if insert.by_name {
7617 self.write_space();
7618 self.write_keyword("BY NAME");
7619 }
7620
7621 if insert.default_values {
7622 self.write_space();
7623 self.write_keyword("DEFAULT VALUES");
7624 } else if let Some(query) = &insert.query {
7625 if self.config.pretty {
7626 self.write_newline();
7627 } else {
7628 self.write_space();
7629 }
7630 if prepend_query_cte.is_some() {
7632 if let Expression::Select(select) = query {
7633 let mut select_no_with = select.clone();
7634 select_no_with.with = None;
7635 self.generate_select(&select_no_with)?;
7636 } else {
7637 self.generate_expression(query)?;
7638 }
7639 } else {
7640 self.generate_expression(query)?;
7641 }
7642 } else if !insert.values.is_empty() {
7643 if self.config.pretty {
7644 self.write_newline();
7646 self.write_keyword("VALUES");
7647 self.write_newline();
7648 self.indent_level += 1;
7649 for (i, row) in insert.values.iter().enumerate() {
7650 if i > 0 {
7651 self.write(",");
7652 self.write_newline();
7653 }
7654 self.write_indent();
7655 self.write("(");
7656 for (j, val) in row.iter().enumerate() {
7657 if j > 0 {
7658 self.write(", ");
7659 }
7660 self.generate_expression(val)?;
7661 }
7662 self.write(")");
7663 }
7664 self.indent_level -= 1;
7665 } else {
7666 self.write_space();
7668 self.write_keyword("VALUES");
7669 for (i, row) in insert.values.iter().enumerate() {
7670 if i > 0 {
7671 self.write(",");
7672 }
7673 self.write(" (");
7674 for (j, val) in row.iter().enumerate() {
7675 if j > 0 {
7676 self.write(", ");
7677 }
7678 self.generate_expression(val)?;
7679 }
7680 self.write(")");
7681 }
7682 }
7683 }
7684
7685 if let Some(ref source) = insert.source {
7687 self.write_space();
7688 self.write_keyword("TABLE");
7689 self.write_space();
7690 self.generate_expression(source)?;
7691 }
7692
7693 if let Some(alias) = &insert.source_alias {
7695 self.write_space();
7696 self.write_keyword("AS");
7697 self.write_space();
7698 self.generate_identifier(alias)?;
7699 }
7700
7701 if let Some(on_conflict) = &insert.on_conflict {
7703 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
7704 self.write_space();
7705 self.generate_expression(on_conflict)?;
7706 }
7707 }
7708
7709 if !insert.returning.is_empty() {
7711 self.write_space();
7712 self.write_keyword("RETURNING");
7713 self.write_space();
7714 for (i, expr) in insert.returning.iter().enumerate() {
7715 if i > 0 {
7716 self.write(", ");
7717 }
7718 self.generate_expression(expr)?;
7719 }
7720 }
7721
7722 Ok(())
7723 }
7724
7725 fn generate_update(&mut self, update: &Update) -> Result<()> {
7726 for comment in &update.leading_comments {
7728 self.write_formatted_comment(comment);
7729 self.write(" ");
7730 }
7731
7732 if let Some(ref with) = update.with {
7734 self.generate_with(with)?;
7735 self.write_space();
7736 }
7737
7738 self.write_keyword("UPDATE");
7739 if let Some(hint) = &update.hint {
7740 self.generate_hint(hint)?;
7741 }
7742 self.write_space();
7743 self.generate_table(&update.table)?;
7744
7745 let mysql_like_update_from = matches!(
7746 self.config.dialect,
7747 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
7748 ) && update.from_clause.is_some();
7749
7750 let mut set_pairs = update.set.clone();
7751
7752 let mut pre_set_joins = update.table_joins.clone();
7754 if mysql_like_update_from {
7755 let target_name = update
7756 .table
7757 .alias
7758 .as_ref()
7759 .map(|a| a.name.clone())
7760 .unwrap_or_else(|| update.table.name.name.clone());
7761
7762 for (col, _) in &mut set_pairs {
7763 if !col.name.contains('.') {
7764 col.name = format!("{}.{}", target_name, col.name);
7765 }
7766 }
7767
7768 if let Some(from_clause) = &update.from_clause {
7769 for table_expr in &from_clause.expressions {
7770 pre_set_joins.push(crate::expressions::Join {
7771 this: table_expr.clone(),
7772 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7773 value: true,
7774 })),
7775 using: Vec::new(),
7776 kind: crate::expressions::JoinKind::Inner,
7777 use_inner_keyword: false,
7778 use_outer_keyword: false,
7779 deferred_condition: false,
7780 join_hint: None,
7781 match_condition: None,
7782 pivots: Vec::new(),
7783 comments: Vec::new(),
7784 nesting_group: 0,
7785 directed: false,
7786 });
7787 }
7788 }
7789 for join in &update.from_joins {
7790 let mut join = join.clone();
7791 if join.on.is_none() && join.using.is_empty() {
7792 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7793 value: true,
7794 }));
7795 }
7796 pre_set_joins.push(join);
7797 }
7798 }
7799
7800 for extra_table in &update.extra_tables {
7802 self.write(", ");
7803 self.generate_table(extra_table)?;
7804 }
7805
7806 for join in &pre_set_joins {
7808 self.generate_join(join)?;
7810 }
7811
7812 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
7814 if teradata_from_before_set && !mysql_like_update_from {
7815 if let Some(ref from_clause) = update.from_clause {
7816 self.write_space();
7817 self.write_keyword("FROM");
7818 self.write_space();
7819 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7820 if i > 0 {
7821 self.write(", ");
7822 }
7823 self.generate_expression(table_expr)?;
7824 }
7825 }
7826 for join in &update.from_joins {
7827 self.generate_join(join)?;
7828 }
7829 }
7830
7831 self.write_space();
7832 self.write_keyword("SET");
7833 self.write_space();
7834
7835 for (i, (col, val)) in set_pairs.iter().enumerate() {
7836 if i > 0 {
7837 self.write(", ");
7838 }
7839 self.generate_identifier(col)?;
7840 self.write(" = ");
7841 self.generate_expression(val)?;
7842 }
7843
7844 if let Some(ref output) = update.output {
7846 self.generate_output_clause(output)?;
7847 }
7848
7849 if !mysql_like_update_from && !teradata_from_before_set {
7851 if let Some(ref from_clause) = update.from_clause {
7852 self.write_space();
7853 self.write_keyword("FROM");
7854 self.write_space();
7855 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7857 if i > 0 {
7858 self.write(", ");
7859 }
7860 self.generate_expression(table_expr)?;
7861 }
7862 }
7863 }
7864
7865 if !mysql_like_update_from && !teradata_from_before_set {
7866 for join in &update.from_joins {
7868 self.generate_join(join)?;
7869 }
7870 }
7871
7872 if let Some(where_clause) = &update.where_clause {
7873 self.write_space();
7874 self.write_keyword("WHERE");
7875 self.write_space();
7876 self.generate_expression(&where_clause.this)?;
7877 }
7878
7879 if !update.returning.is_empty() {
7881 self.write_space();
7882 self.write_keyword("RETURNING");
7883 self.write_space();
7884 for (i, expr) in update.returning.iter().enumerate() {
7885 if i > 0 {
7886 self.write(", ");
7887 }
7888 self.generate_expression(expr)?;
7889 }
7890 }
7891
7892 if let Some(ref order_by) = update.order_by {
7894 self.write_space();
7895 self.generate_order_by(order_by)?;
7896 }
7897
7898 if let Some(ref limit) = update.limit {
7900 self.write_space();
7901 self.write_keyword("LIMIT");
7902 self.write_space();
7903 self.generate_expression(limit)?;
7904 }
7905
7906 Ok(())
7907 }
7908
7909 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
7910 if let Some(with) = &delete.with {
7912 self.generate_with(with)?;
7913 self.write_space();
7914 }
7915
7916 for comment in &delete.leading_comments {
7918 self.write_formatted_comment(comment);
7919 self.write(" ");
7920 }
7921
7922 if !delete.tables.is_empty() && !delete.tables_from_using {
7924 self.write_keyword("DELETE");
7926 if let Some(hint) = &delete.hint {
7927 self.generate_hint(hint)?;
7928 }
7929 self.write_space();
7930 for (i, tbl) in delete.tables.iter().enumerate() {
7931 if i > 0 {
7932 self.write(", ");
7933 }
7934 self.generate_table(tbl)?;
7935 }
7936 if let Some(ref output) = delete.output {
7938 self.generate_output_clause(output)?;
7939 }
7940 self.write_space();
7941 self.write_keyword("FROM");
7942 self.write_space();
7943 self.generate_table(&delete.table)?;
7944 } else if !delete.tables.is_empty() && delete.tables_from_using {
7945 self.write_keyword("DELETE");
7947 if let Some(hint) = &delete.hint {
7948 self.generate_hint(hint)?;
7949 }
7950 self.write_space();
7951 self.write_keyword("FROM");
7952 self.write_space();
7953 for (i, tbl) in delete.tables.iter().enumerate() {
7954 if i > 0 {
7955 self.write(", ");
7956 }
7957 self.generate_table(tbl)?;
7958 }
7959 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
7960 self.write_keyword("DELETE");
7962 if let Some(hint) = &delete.hint {
7963 self.generate_hint(hint)?;
7964 }
7965 self.write_space();
7966 self.generate_table(&delete.table)?;
7967 } else {
7968 self.write_keyword("DELETE");
7969 if let Some(hint) = &delete.hint {
7970 self.generate_hint(hint)?;
7971 }
7972 self.write_space();
7973 self.write_keyword("FROM");
7974 self.write_space();
7975 self.generate_table(&delete.table)?;
7976 }
7977
7978 if let Some(ref on_cluster) = delete.on_cluster {
7980 self.write_space();
7981 self.generate_on_cluster(on_cluster)?;
7982 }
7983
7984 if let Some(ref idx) = delete.force_index {
7986 self.write_space();
7987 self.write_keyword("FORCE INDEX");
7988 self.write(" (");
7989 self.write(idx);
7990 self.write(")");
7991 }
7992
7993 if let Some(ref alias) = delete.alias {
7995 self.write_space();
7996 if delete.alias_explicit_as
7997 || matches!(self.config.dialect, Some(DialectType::BigQuery))
7998 {
7999 self.write_keyword("AS");
8000 self.write_space();
8001 }
8002 self.generate_identifier(alias)?;
8003 }
8004
8005 if !delete.tables_from_using {
8007 for join in &delete.joins {
8008 self.generate_join(join)?;
8009 }
8010 }
8011
8012 if !delete.using.is_empty() {
8014 self.write_space();
8015 self.write_keyword("USING");
8016 for (i, table) in delete.using.iter().enumerate() {
8017 if i > 0 {
8018 self.write(",");
8019 }
8020 self.write_space();
8021 if !table.hints.is_empty() && table.name.is_empty() {
8023 self.generate_expression(&table.hints[0])?;
8025 if let Some(ref alias) = table.alias {
8026 self.write_space();
8027 if table.alias_explicit_as {
8028 self.write_keyword("AS");
8029 self.write_space();
8030 }
8031 self.generate_identifier(alias)?;
8032 if !table.column_aliases.is_empty() {
8033 self.write("(");
8034 for (j, col_alias) in table.column_aliases.iter().enumerate() {
8035 if j > 0 {
8036 self.write(", ");
8037 }
8038 self.generate_identifier(col_alias)?;
8039 }
8040 self.write(")");
8041 }
8042 }
8043 } else {
8044 self.generate_table(table)?;
8045 }
8046 }
8047 }
8048
8049 if delete.tables_from_using {
8051 for join in &delete.joins {
8052 self.generate_join(join)?;
8053 }
8054 }
8055
8056 let output_already_emitted =
8058 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
8059 if !output_already_emitted {
8060 if let Some(ref output) = delete.output {
8061 self.generate_output_clause(output)?;
8062 }
8063 }
8064
8065 if let Some(where_clause) = &delete.where_clause {
8066 self.write_space();
8067 self.write_keyword("WHERE");
8068 self.write_space();
8069 self.generate_expression(&where_clause.this)?;
8070 }
8071
8072 if let Some(ref order_by) = delete.order_by {
8074 self.write_space();
8075 self.generate_order_by(order_by)?;
8076 }
8077
8078 if let Some(ref limit) = delete.limit {
8080 self.write_space();
8081 self.write_keyword("LIMIT");
8082 self.write_space();
8083 self.generate_expression(limit)?;
8084 }
8085
8086 if !delete.returning.is_empty() {
8088 self.write_space();
8089 self.write_keyword("RETURNING");
8090 self.write_space();
8091 for (i, expr) in delete.returning.iter().enumerate() {
8092 if i > 0 {
8093 self.write(", ");
8094 }
8095 self.generate_expression(expr)?;
8096 }
8097 }
8098
8099 Ok(())
8100 }
8101
8102 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
8105 let saved_athena_hive_context = self.athena_hive_context;
8109 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
8110 if matches!(
8111 self.config.dialect,
8112 Some(crate::dialects::DialectType::Athena)
8113 ) {
8114 let is_external = ct
8118 .table_modifier
8119 .as_ref()
8120 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
8121 .unwrap_or(false);
8122 let has_as_select = ct.as_select.is_some();
8123 self.athena_hive_context = is_external || !has_as_select;
8124 }
8125
8126 if matches!(
8128 self.config.dialect,
8129 Some(crate::dialects::DialectType::TSQL)
8130 ) {
8131 if let Some(ref query) = ct.as_select {
8132 if let Some(with_cte) = &ct.with_cte {
8134 self.generate_with(with_cte)?;
8135 self.write_space();
8136 }
8137
8138 self.write_keyword("SELECT");
8140 self.write(" * ");
8141 self.write_keyword("INTO");
8142 self.write_space();
8143
8144 if ct.temporary {
8146 self.write("#");
8147 }
8148 self.generate_table(&ct.name)?;
8149
8150 self.write_space();
8151 self.write_keyword("FROM");
8152 self.write(" (");
8153 let aliased_query = Self::add_column_aliases_to_query(query.clone());
8155 self.generate_expression(&aliased_query)?;
8156 self.write(") ");
8157 self.write_keyword("AS");
8158 self.write(" temp");
8159 return Ok(());
8160 }
8161 }
8162
8163 if let Some(with_cte) = &ct.with_cte {
8165 self.generate_with(with_cte)?;
8166 self.write_space();
8167 }
8168
8169 for comment in &ct.leading_comments {
8171 self.write_formatted_comment(comment);
8172 self.write(" ");
8173 }
8174 self.write_keyword("CREATE");
8175
8176 if ct.or_replace {
8177 self.write_space();
8178 self.write_keyword("OR REPLACE");
8179 }
8180
8181 if ct.temporary {
8182 self.write_space();
8183 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
8185 self.write_keyword("GLOBAL TEMPORARY");
8186 } else {
8187 self.write_keyword("TEMPORARY");
8188 }
8189 }
8190
8191 let is_dictionary = ct
8193 .table_modifier
8194 .as_ref()
8195 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
8196 .unwrap_or(false);
8197 if let Some(ref modifier) = ct.table_modifier {
8198 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
8200 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
8201 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
8203 || modifier.eq_ignore_ascii_case("SET")
8204 || modifier.eq_ignore_ascii_case("MULTISET")
8205 || modifier.to_ascii_uppercase().contains("VOLATILE")
8206 || modifier.to_ascii_uppercase().starts_with("SET ")
8207 || modifier.to_ascii_uppercase().starts_with("MULTISET ");
8208 let skip_teradata =
8209 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
8210 if !skip_transient && !skip_teradata {
8211 self.write_space();
8212 self.write_keyword(modifier);
8213 }
8214 }
8215
8216 if !is_dictionary {
8217 self.write_space();
8218 self.write_keyword("TABLE");
8219 }
8220
8221 if ct.if_not_exists {
8222 self.write_space();
8223 self.write_keyword("IF NOT EXISTS");
8224 }
8225
8226 self.write_space();
8227 self.generate_table(&ct.name)?;
8228
8229 if let Some(ref uuid) = ct.uuid {
8231 self.write_space();
8232 self.write_keyword("UUID");
8233 self.write(" '");
8234 self.write(uuid);
8235 self.write("'");
8236 }
8237
8238 if let Some(ref on_cluster) = ct.on_cluster {
8240 self.write_space();
8241 self.generate_on_cluster(on_cluster)?;
8242 }
8243
8244 if matches!(
8246 self.config.dialect,
8247 Some(crate::dialects::DialectType::Teradata)
8248 ) && !ct.teradata_post_name_options.is_empty()
8249 {
8250 for opt in &ct.teradata_post_name_options {
8251 self.write(", ");
8252 self.write(opt);
8253 }
8254 }
8255
8256 if ct.copy_grants {
8258 self.write_space();
8259 self.write_keyword("COPY GRANTS");
8260 }
8261
8262 if let Some(ref using_template) = ct.using_template {
8264 self.write_space();
8265 self.write_keyword("USING TEMPLATE");
8266 self.write_space();
8267 self.generate_expression(using_template)?;
8268 return Ok(());
8269 }
8270
8271 if is_clickhouse {
8275 if let Some(ref clone_source) = ct.clone_source {
8276 if ct.columns.is_empty() && ct.constraints.is_empty() {
8277 self.write_space();
8278 self.write_keyword("AS");
8279 self.write_space();
8280 self.generate_table(clone_source)?;
8281 }
8282 }
8283 }
8284
8285 if !is_clickhouse {
8287 if let Some(ref clone_source) = ct.clone_source {
8288 self.write_space();
8289 if ct.is_copy && self.config.supports_table_copy {
8290 self.write_keyword("COPY");
8292 } else if ct.shallow_clone {
8293 self.write_keyword("SHALLOW CLONE");
8294 } else if ct.deep_clone {
8295 self.write_keyword("DEEP CLONE");
8296 } else {
8297 self.write_keyword("CLONE");
8298 }
8299 self.write_space();
8300 self.generate_table(clone_source)?;
8301 if let Some(ref at_clause) = ct.clone_at_clause {
8303 self.write_space();
8304 self.generate_expression(at_clause)?;
8305 }
8306 return Ok(());
8307 }
8308 }
8309
8310 if let Some(ref partition_of) = ct.partition_of {
8314 self.write_space();
8315
8316 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
8318 self.write_keyword("PARTITION OF");
8320 self.write_space();
8321 self.generate_expression(&pop.this)?;
8322
8323 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
8325 self.write(" (");
8326 let mut first = true;
8327 for col in &ct.columns {
8328 if !first {
8329 self.write(", ");
8330 }
8331 first = false;
8332 self.generate_column_def(col)?;
8333 }
8334 for constraint in &ct.constraints {
8335 if !first {
8336 self.write(", ");
8337 }
8338 first = false;
8339 self.generate_table_constraint(constraint)?;
8340 }
8341 self.write(")");
8342 }
8343
8344 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
8346 self.write_space();
8347 self.write_keyword("FOR VALUES");
8348 self.write_space();
8349 self.generate_expression(&pop.expression)?;
8350 } else {
8351 self.write_space();
8352 self.write_keyword("DEFAULT");
8353 }
8354 } else {
8355 self.generate_expression(partition_of)?;
8357
8358 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
8360 self.write(" (");
8361 let mut first = true;
8362 for col in &ct.columns {
8363 if !first {
8364 self.write(", ");
8365 }
8366 first = false;
8367 self.generate_column_def(col)?;
8368 }
8369 for constraint in &ct.constraints {
8370 if !first {
8371 self.write(", ");
8372 }
8373 first = false;
8374 self.generate_table_constraint(constraint)?;
8375 }
8376 self.write(")");
8377 }
8378 }
8379
8380 for prop in &ct.properties {
8382 self.write_space();
8383 self.generate_expression(prop)?;
8384 }
8385
8386 return Ok(());
8387 }
8388
8389 self.sqlite_inline_pk_columns.clear();
8392 if matches!(
8393 self.config.dialect,
8394 Some(crate::dialects::DialectType::SQLite)
8395 ) {
8396 for constraint in &ct.constraints {
8397 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8398 if columns.len() == 1 && name.is_none() {
8400 let pk_col_name = columns[0].name.to_ascii_lowercase();
8401 if ct
8403 .columns
8404 .iter()
8405 .any(|c| c.name.name.to_ascii_lowercase() == pk_col_name)
8406 {
8407 self.sqlite_inline_pk_columns.insert(pk_col_name);
8408 }
8409 }
8410 }
8411 }
8412 }
8413
8414 if !ct.columns.is_empty() {
8416 if self.config.pretty {
8417 self.write(" (");
8419 self.write_newline();
8420 self.indent_level += 1;
8421 for (i, col) in ct.columns.iter().enumerate() {
8422 if i > 0 {
8423 self.write(",");
8424 self.write_newline();
8425 }
8426 self.write_indent();
8427 self.generate_column_def(col)?;
8428 }
8429 for constraint in &ct.constraints {
8431 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8433 if columns.len() == 1
8434 && name.is_none()
8435 && self
8436 .sqlite_inline_pk_columns
8437 .contains(&columns[0].name.to_ascii_lowercase())
8438 {
8439 continue;
8440 }
8441 }
8442 self.write(",");
8443 self.write_newline();
8444 self.write_indent();
8445 self.generate_table_constraint(constraint)?;
8446 }
8447 self.indent_level -= 1;
8448 self.write_newline();
8449 self.write(")");
8450 } else {
8451 self.write(" (");
8452 for (i, col) in ct.columns.iter().enumerate() {
8453 if i > 0 {
8454 self.write(", ");
8455 }
8456 self.generate_column_def(col)?;
8457 }
8458 let mut first_constraint = true;
8460 for constraint in &ct.constraints {
8461 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8463 if columns.len() == 1
8464 && name.is_none()
8465 && self
8466 .sqlite_inline_pk_columns
8467 .contains(&columns[0].name.to_ascii_lowercase())
8468 {
8469 continue;
8470 }
8471 }
8472 if first_constraint {
8473 self.write(", ");
8474 first_constraint = false;
8475 } else {
8476 self.write(", ");
8477 }
8478 self.generate_table_constraint(constraint)?;
8479 }
8480 self.write(")");
8481 }
8482 } else if !ct.constraints.is_empty() {
8483 let has_like_only = ct
8485 .constraints
8486 .iter()
8487 .all(|c| matches!(c, TableConstraint::Like { .. }));
8488 let has_tags_only = ct
8489 .constraints
8490 .iter()
8491 .all(|c| matches!(c, TableConstraint::Tags(_)));
8492 let is_pg_like = matches!(
8496 self.config.dialect,
8497 Some(crate::dialects::DialectType::PostgreSQL)
8498 | Some(crate::dialects::DialectType::CockroachDB)
8499 | Some(crate::dialects::DialectType::Materialize)
8500 | Some(crate::dialects::DialectType::RisingWave)
8501 | Some(crate::dialects::DialectType::Redshift)
8502 | Some(crate::dialects::DialectType::Presto)
8503 | Some(crate::dialects::DialectType::Trino)
8504 | Some(crate::dialects::DialectType::Athena)
8505 );
8506 let use_parens = if has_like_only {
8507 is_pg_like
8508 } else {
8509 !has_tags_only
8510 };
8511 if self.config.pretty && use_parens {
8512 self.write(" (");
8513 self.write_newline();
8514 self.indent_level += 1;
8515 for (i, constraint) in ct.constraints.iter().enumerate() {
8516 if i > 0 {
8517 self.write(",");
8518 self.write_newline();
8519 }
8520 self.write_indent();
8521 self.generate_table_constraint(constraint)?;
8522 }
8523 self.indent_level -= 1;
8524 self.write_newline();
8525 self.write(")");
8526 } else {
8527 if use_parens {
8528 self.write(" (");
8529 } else {
8530 self.write_space();
8531 }
8532 for (i, constraint) in ct.constraints.iter().enumerate() {
8533 if i > 0 {
8534 self.write(", ");
8535 }
8536 self.generate_table_constraint(constraint)?;
8537 }
8538 if use_parens {
8539 self.write(")");
8540 }
8541 }
8542 }
8543
8544 if is_clickhouse && (!ct.columns.is_empty() || !ct.constraints.is_empty()) {
8545 if let Some(ref clone_source) = ct.clone_source {
8546 self.write_space();
8547 self.write_keyword("AS");
8548 self.write_space();
8549 self.generate_table(clone_source)?;
8550 }
8551 }
8552
8553 if let Some(ref on_prop) = ct.on_property {
8555 self.write(" ");
8556 self.write_keyword("ON");
8557 self.write(" ");
8558 self.generate_expression(&on_prop.this)?;
8559 }
8560
8561 if !ct.with_partition_columns.is_empty() {
8563 if self.config.pretty {
8564 self.write_newline();
8565 } else {
8566 self.write_space();
8567 }
8568 self.write_keyword("WITH PARTITION COLUMNS");
8569 self.write(" (");
8570 if self.config.pretty {
8571 self.write_newline();
8572 self.indent_level += 1;
8573 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8574 if i > 0 {
8575 self.write(",");
8576 self.write_newline();
8577 }
8578 self.write_indent();
8579 self.generate_column_def(col)?;
8580 }
8581 self.indent_level -= 1;
8582 self.write_newline();
8583 } else {
8584 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8585 if i > 0 {
8586 self.write(", ");
8587 }
8588 self.generate_column_def(col)?;
8589 }
8590 }
8591 self.write(")");
8592 }
8593
8594 if let Some(ref conn) = ct.with_connection {
8596 if self.config.pretty {
8597 self.write_newline();
8598 } else {
8599 self.write_space();
8600 }
8601 self.write_keyword("WITH CONNECTION");
8602 self.write_space();
8603 self.generate_table(conn)?;
8604 }
8605
8606 if !is_clickhouse {
8609 for prop in &ct.properties {
8610 if let Expression::SchemaCommentProperty(_) = prop {
8611 if self.config.pretty {
8612 self.write_newline();
8613 } else {
8614 self.write_space();
8615 }
8616 self.generate_expression(prop)?;
8617 }
8618 }
8619 }
8620
8621 if !ct.with_properties.is_empty() {
8623 let is_snowflake_special_table = matches!(
8625 self.config.dialect,
8626 Some(crate::dialects::DialectType::Snowflake)
8627 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
8628 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
8629 if is_snowflake_special_table {
8630 for (key, value) in &ct.with_properties {
8631 self.write_space();
8632 self.write(key);
8633 self.write("=");
8634 self.write(value);
8635 }
8636 } else if self.config.pretty {
8637 self.write_newline();
8638 self.write_keyword("WITH");
8639 self.write(" (");
8640 self.write_newline();
8641 self.indent_level += 1;
8642 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8643 if i > 0 {
8644 self.write(",");
8645 self.write_newline();
8646 }
8647 self.write_indent();
8648 self.write(key);
8649 self.write("=");
8650 self.write(value);
8651 }
8652 self.indent_level -= 1;
8653 self.write_newline();
8654 self.write(")");
8655 } else {
8656 self.write_space();
8657 self.write_keyword("WITH");
8658 self.write(" (");
8659 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8660 if i > 0 {
8661 self.write(", ");
8662 }
8663 self.write(key);
8664 self.write("=");
8665 self.write(value);
8666 }
8667 self.write(")");
8668 }
8669 }
8670
8671 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
8672 if is_clickhouse && ct.as_select.is_some() {
8673 let mut pre = Vec::new();
8674 let mut post = Vec::new();
8675 for prop in &ct.properties {
8676 if matches!(prop, Expression::SchemaCommentProperty(_)) {
8677 post.push(prop);
8678 } else {
8679 pre.push(prop);
8680 }
8681 }
8682 (pre, post)
8683 } else {
8684 (ct.properties.iter().collect(), Vec::new())
8685 };
8686
8687 for prop in pre_as_properties {
8689 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
8691 continue;
8692 }
8693 if self.config.pretty {
8694 self.write_newline();
8695 } else {
8696 self.write_space();
8697 }
8698 if let Expression::Properties(props) = prop {
8702 let is_hive_dialect = matches!(
8703 self.config.dialect,
8704 Some(crate::dialects::DialectType::Hive)
8705 | Some(crate::dialects::DialectType::Spark)
8706 | Some(crate::dialects::DialectType::Databricks)
8707 | Some(crate::dialects::DialectType::Athena)
8708 );
8709 let is_doris_starrocks = matches!(
8710 self.config.dialect,
8711 Some(crate::dialects::DialectType::Doris)
8712 | Some(crate::dialects::DialectType::StarRocks)
8713 );
8714 if is_hive_dialect {
8715 self.generate_tblproperties_clause(&props.expressions)?;
8716 } else if is_doris_starrocks {
8717 self.generate_properties_clause(&props.expressions)?;
8718 } else {
8719 self.generate_options_clause(&props.expressions)?;
8720 }
8721 } else {
8722 self.generate_expression(prop)?;
8723 }
8724 }
8725
8726 for prop in &ct.post_table_properties {
8728 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
8729 self.write(" WITH(");
8730 self.generate_system_versioning_content(svp)?;
8731 self.write(")");
8732 } else if let Expression::Properties(props) = prop {
8733 let is_doris_starrocks = matches!(
8735 self.config.dialect,
8736 Some(crate::dialects::DialectType::Doris)
8737 | Some(crate::dialects::DialectType::StarRocks)
8738 );
8739 self.write_space();
8740 if is_doris_starrocks {
8741 self.generate_properties_clause(&props.expressions)?;
8742 } else {
8743 self.generate_options_clause(&props.expressions)?;
8744 }
8745 } else {
8746 self.write_space();
8747 self.generate_expression(prop)?;
8748 }
8749 }
8750
8751 if let Some(ref rollup) = ct.rollup {
8754 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
8755 self.write_space();
8756 self.generate_rollup_property(rollup)?;
8757 }
8758 }
8759
8760 let is_mysql_compatible = matches!(
8764 self.config.dialect,
8765 Some(DialectType::MySQL)
8766 | Some(DialectType::SingleStore)
8767 | Some(DialectType::Doris)
8768 | Some(DialectType::StarRocks)
8769 | None
8770 );
8771 let is_hive_compatible = matches!(
8772 self.config.dialect,
8773 Some(DialectType::Hive)
8774 | Some(DialectType::Spark)
8775 | Some(DialectType::Databricks)
8776 | Some(DialectType::Athena)
8777 );
8778 let mysql_pretty_options =
8779 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
8780 for (key, value) in &ct.mysql_table_options {
8781 let should_output = if is_mysql_compatible {
8783 true
8784 } else if is_hive_compatible && key == "COMMENT" {
8785 true } else {
8787 false
8788 };
8789 if should_output {
8790 if mysql_pretty_options {
8791 self.write_newline();
8792 self.write_indent();
8793 } else {
8794 self.write_space();
8795 }
8796 self.write_keyword(key);
8797 if key == "COMMENT" && !self.config.schema_comment_with_eq {
8799 self.write_space();
8800 } else {
8801 self.write("=");
8802 }
8803 self.write(value);
8804 }
8805 }
8806
8807 if ct.temporary
8809 && matches!(
8810 self.config.dialect,
8811 Some(DialectType::Spark) | Some(DialectType::Databricks)
8812 )
8813 && ct.as_select.is_none()
8814 {
8815 self.write_space();
8816 self.write_keyword("USING PARQUET");
8817 }
8818
8819 if !ct.inherits.is_empty() {
8821 self.write_space();
8822 self.write_keyword("INHERITS");
8823 self.write(" (");
8824 for (i, parent) in ct.inherits.iter().enumerate() {
8825 if i > 0 {
8826 self.write(", ");
8827 }
8828 self.generate_table(parent)?;
8829 }
8830 self.write(")");
8831 }
8832
8833 if let Some(ref query) = ct.as_select {
8835 self.write_space();
8836 self.write_keyword("AS");
8837 self.write_space();
8838 let source_is_clickhouse =
8839 matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
8840 let wrap_as_select =
8841 ct.as_select_parenthesized && !(is_clickhouse && source_is_clickhouse);
8842 if wrap_as_select {
8843 self.write("(");
8844 }
8845 self.generate_expression(query)?;
8846 if wrap_as_select {
8847 self.write(")");
8848 }
8849
8850 if let Some(with_data) = ct.with_data {
8852 self.write_space();
8853 self.write_keyword("WITH");
8854 if !with_data {
8855 self.write_space();
8856 self.write_keyword("NO");
8857 }
8858 self.write_space();
8859 self.write_keyword("DATA");
8860 }
8861
8862 if let Some(with_statistics) = ct.with_statistics {
8864 self.write_space();
8865 self.write_keyword("AND");
8866 if !with_statistics {
8867 self.write_space();
8868 self.write_keyword("NO");
8869 }
8870 self.write_space();
8871 self.write_keyword("STATISTICS");
8872 }
8873
8874 for index in &ct.teradata_indexes {
8876 self.write_space();
8877 match index.kind {
8878 TeradataIndexKind::NoPrimary => {
8879 self.write_keyword("NO PRIMARY INDEX");
8880 }
8881 TeradataIndexKind::Primary => {
8882 self.write_keyword("PRIMARY INDEX");
8883 }
8884 TeradataIndexKind::PrimaryAmp => {
8885 self.write_keyword("PRIMARY AMP INDEX");
8886 }
8887 TeradataIndexKind::Unique => {
8888 self.write_keyword("UNIQUE INDEX");
8889 }
8890 TeradataIndexKind::UniquePrimary => {
8891 self.write_keyword("UNIQUE PRIMARY INDEX");
8892 }
8893 TeradataIndexKind::Secondary => {
8894 self.write_keyword("INDEX");
8895 }
8896 }
8897 if let Some(ref name) = index.name {
8899 self.write_space();
8900 self.write(name);
8901 }
8902 if !index.columns.is_empty() {
8904 self.write(" (");
8905 for (i, col) in index.columns.iter().enumerate() {
8906 if i > 0 {
8907 self.write(", ");
8908 }
8909 self.write(col);
8910 }
8911 self.write(")");
8912 }
8913 }
8914
8915 if let Some(ref on_commit) = ct.on_commit {
8917 self.write_space();
8918 self.write_keyword("ON COMMIT");
8919 self.write_space();
8920 match on_commit {
8921 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8922 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8923 }
8924 }
8925
8926 if !post_as_properties.is_empty() {
8927 for prop in post_as_properties {
8928 self.write_space();
8929 self.generate_expression(prop)?;
8930 }
8931 }
8932
8933 self.athena_hive_context = saved_athena_hive_context;
8935 return Ok(());
8936 }
8937
8938 if let Some(ref on_commit) = ct.on_commit {
8940 self.write_space();
8941 self.write_keyword("ON COMMIT");
8942 self.write_space();
8943 match on_commit {
8944 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8945 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8946 }
8947 }
8948
8949 self.athena_hive_context = saved_athena_hive_context;
8951
8952 Ok(())
8953 }
8954
8955 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
8958 self.generate_identifier(&col.name)?;
8960 if !matches!(col.data_type, DataType::Unknown) {
8962 self.write_space();
8963 self.generate_data_type(&col.data_type)?;
8964 }
8965 for constraint in &col.constraints {
8967 if let ColumnConstraint::Path(path_expr) = constraint {
8968 self.write_space();
8969 self.write_keyword("PATH");
8970 self.write_space();
8971 self.generate_expression(path_expr)?;
8972 }
8973 }
8974 Ok(())
8975 }
8976
8977 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
8978 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8980 && col
8981 .constraints
8982 .iter()
8983 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8984 let omit_computed_type = !self.config.computed_column_with_type
8986 && col
8987 .constraints
8988 .iter()
8989 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8990
8991 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
8994
8995 let has_no_type = col.no_type
8998 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8999 && col.constraints.is_empty());
9000
9001 self.generate_identifier(&col.name)?;
9002
9003 let serial_expansion = if matches!(
9005 self.config.dialect,
9006 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
9007 ) {
9008 if let DataType::Custom { ref name } = col.data_type {
9009 if name.eq_ignore_ascii_case("SERIAL") {
9010 Some("INT")
9011 } else if name.eq_ignore_ascii_case("BIGSERIAL") {
9012 Some("BIGINT")
9013 } else if name.eq_ignore_ascii_case("SMALLSERIAL") {
9014 Some("SMALLINT")
9015 } else {
9016 None
9017 }
9018 } else {
9019 None
9020 }
9021 } else {
9022 None
9023 };
9024
9025 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
9026 {
9027 self.write_space();
9028 let saved_nullable_depth = self.clickhouse_nullable_depth;
9031 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
9032 self.clickhouse_nullable_depth = -1;
9033 }
9034 if let Some(int_type) = serial_expansion {
9035 self.write_keyword(int_type);
9037 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
9038 let unsigned_type = match &col.data_type {
9040 DataType::Int { .. } => Some("UINTEGER"),
9041 DataType::BigInt { .. } => Some("UBIGINT"),
9042 DataType::SmallInt { .. } => Some("USMALLINT"),
9043 DataType::TinyInt { .. } => Some("UTINYINT"),
9044 _ => None,
9045 };
9046 if let Some(utype) = unsigned_type {
9047 self.write_keyword(utype);
9048 } else {
9049 self.generate_data_type(&col.data_type)?;
9050 }
9051 } else {
9052 self.generate_data_type(&col.data_type)?;
9053 }
9054 self.clickhouse_nullable_depth = saved_nullable_depth;
9055 }
9056
9057 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
9060 self.write_space();
9061 self.write_keyword("UNSIGNED");
9062 }
9063 if col.zerofill {
9064 self.write_space();
9065 self.write_keyword("ZEROFILL");
9066 }
9067
9068 if let Some(ref charset) = col.character_set {
9072 self.write_space();
9073 self.write_keyword("CHARACTER SET");
9074 self.write_space();
9075 self.write(charset);
9076 }
9077
9078 if col.uppercase {
9079 self.write_space();
9080 self.write_keyword("UPPERCASE");
9081 }
9082
9083 if let Some(casespecific) = col.casespecific {
9084 self.write_space();
9085 if casespecific {
9086 self.write_keyword("CASESPECIFIC");
9087 } else {
9088 self.write_keyword("NOT CASESPECIFIC");
9089 }
9090 }
9091
9092 if let Some(ref format) = col.format {
9093 self.write_space();
9094 self.write_keyword("FORMAT");
9095 self.write(" '");
9096 self.write(format);
9097 self.write("'");
9098 }
9099
9100 if let Some(ref title) = col.title {
9101 self.write_space();
9102 self.write_keyword("TITLE");
9103 self.write(" '");
9104 self.write(title);
9105 self.write("'");
9106 }
9107
9108 if let Some(length) = col.inline_length {
9109 self.write_space();
9110 self.write_keyword("INLINE LENGTH");
9111 self.write(" ");
9112 self.write(&length.to_string());
9113 }
9114
9115 if let Some(ref compress) = col.compress {
9116 self.write_space();
9117 self.write_keyword("COMPRESS");
9118 if !compress.is_empty() {
9119 if compress.len() == 1 {
9121 if let Expression::Literal(lit) = &compress[0] {
9122 if let Literal::String(_) = lit.as_ref() {
9123 self.write_space();
9124 self.generate_expression(&compress[0])?;
9125 }
9126 } else {
9127 self.write(" (");
9128 self.generate_expression(&compress[0])?;
9129 self.write(")");
9130 }
9131 } else {
9132 self.write(" (");
9133 for (i, val) in compress.iter().enumerate() {
9134 if i > 0 {
9135 self.write(", ");
9136 }
9137 self.generate_expression(val)?;
9138 }
9139 self.write(")");
9140 }
9141 }
9142 }
9143
9144 if !col.constraint_order.is_empty() {
9147 let mut references_idx = 0;
9150 let mut check_idx = 0;
9151 let mut generated_idx = 0;
9152 let mut collate_idx = 0;
9153 let mut comment_idx = 0;
9154 let defer_not_null_after_identity = false;
9157 let mut pending_not_null_after_identity = false;
9158
9159 for constraint_type in &col.constraint_order {
9160 match constraint_type {
9161 ConstraintType::PrimaryKey => {
9162 if col.primary_key
9164 && !matches!(self.config.dialect, Some(DialectType::Materialize))
9165 {
9166 if let Some(ref cname) = col.primary_key_constraint_name {
9167 self.write_space();
9168 self.write_keyword("CONSTRAINT");
9169 self.write_space();
9170 self.write(cname);
9171 }
9172 self.write_space();
9173 self.write_keyword("PRIMARY KEY");
9174 if let Some(ref order) = col.primary_key_order {
9175 self.write_space();
9176 match order {
9177 SortOrder::Asc => self.write_keyword("ASC"),
9178 SortOrder::Desc => self.write_keyword("DESC"),
9179 }
9180 }
9181 }
9182 }
9183 ConstraintType::Unique => {
9184 if col.unique {
9185 if let Some(ref cname) = col.unique_constraint_name {
9186 self.write_space();
9187 self.write_keyword("CONSTRAINT");
9188 self.write_space();
9189 self.write(cname);
9190 }
9191 self.write_space();
9192 self.write_keyword("UNIQUE");
9193 if col.unique_nulls_not_distinct {
9195 self.write(" NULLS NOT DISTINCT");
9196 }
9197 }
9198 }
9199 ConstraintType::NotNull => {
9200 if col.nullable == Some(false) {
9201 if defer_not_null_after_identity {
9202 pending_not_null_after_identity = true;
9203 continue;
9204 }
9205 if let Some(ref cname) = col.not_null_constraint_name {
9206 self.write_space();
9207 self.write_keyword("CONSTRAINT");
9208 self.write_space();
9209 self.write(cname);
9210 }
9211 self.write_space();
9212 self.write_keyword("NOT NULL");
9213 }
9214 }
9215 ConstraintType::Null => {
9216 if col.nullable == Some(true) {
9217 self.write_space();
9218 self.write_keyword("NULL");
9219 }
9220 }
9221 ConstraintType::Default => {
9222 if let Some(ref default) = col.default {
9223 self.write_space();
9224 self.write_keyword("DEFAULT");
9225 self.write_space();
9226 self.generate_expression(default)?;
9227 }
9228 }
9229 ConstraintType::AutoIncrement => {
9230 if col.auto_increment {
9231 if matches!(
9233 self.config.dialect,
9234 Some(crate::dialects::DialectType::DuckDB)
9235 ) {
9236 } else if matches!(
9238 self.config.dialect,
9239 Some(crate::dialects::DialectType::Materialize)
9240 ) {
9241 if !matches!(col.nullable, Some(false)) {
9243 self.write_space();
9244 self.write_keyword("NOT NULL");
9245 }
9246 } else if matches!(
9247 self.config.dialect,
9248 Some(crate::dialects::DialectType::PostgreSQL)
9249 ) {
9250 self.write_space();
9252 self.generate_auto_increment_keyword(col)?;
9253 } else if matches!(
9254 self.config.dialect,
9255 Some(crate::dialects::DialectType::SQLite)
9256 ) && !col.primary_key
9257 && self
9258 .sqlite_inline_pk_columns
9259 .contains(&col.name.name.to_ascii_lowercase())
9260 {
9261 } else {
9264 self.write_space();
9265 self.generate_auto_increment_keyword(col)?;
9266 if pending_not_null_after_identity {
9267 self.write_space();
9268 self.write_keyword("NOT NULL");
9269 pending_not_null_after_identity = false;
9270 }
9271 }
9272 } }
9274 ConstraintType::References => {
9275 while references_idx < col.constraints.len() {
9277 if let ColumnConstraint::References(fk_ref) =
9278 &col.constraints[references_idx]
9279 {
9280 if let Some(ref name) = fk_ref.constraint_name {
9282 self.write_space();
9283 self.write_keyword("CONSTRAINT");
9284 self.write_space();
9285 self.write(name);
9286 }
9287 self.write_space();
9288 if fk_ref.has_foreign_key_keywords {
9289 self.write_keyword("FOREIGN KEY");
9290 self.write_space();
9291 }
9292 self.write_keyword("REFERENCES");
9293 self.write_space();
9294 self.generate_table(&fk_ref.table)?;
9295 if !fk_ref.columns.is_empty() {
9296 self.write(" (");
9297 for (i, c) in fk_ref.columns.iter().enumerate() {
9298 if i > 0 {
9299 self.write(", ");
9300 }
9301 self.generate_identifier(c)?;
9302 }
9303 self.write(")");
9304 }
9305 self.generate_referential_actions(fk_ref)?;
9306 references_idx += 1;
9307 break;
9308 }
9309 references_idx += 1;
9310 }
9311 }
9312 ConstraintType::Check => {
9313 while check_idx < col.constraints.len() {
9315 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
9316 if check_idx == 0 {
9318 if let Some(ref cname) = col.check_constraint_name {
9319 self.write_space();
9320 self.write_keyword("CONSTRAINT");
9321 self.write_space();
9322 self.write(cname);
9323 }
9324 }
9325 self.write_space();
9326 self.write_keyword("CHECK");
9327 self.write(" (");
9328 self.generate_expression(expr)?;
9329 self.write(")");
9330 check_idx += 1;
9331 break;
9332 }
9333 check_idx += 1;
9334 }
9335 }
9336 ConstraintType::GeneratedAsIdentity => {
9337 while generated_idx < col.constraints.len() {
9339 if let ColumnConstraint::GeneratedAsIdentity(gen) =
9340 &col.constraints[generated_idx]
9341 {
9342 self.write_space();
9343 if matches!(
9345 self.config.dialect,
9346 Some(crate::dialects::DialectType::Redshift)
9347 ) {
9348 self.write_keyword("IDENTITY");
9349 self.write("(");
9350 if let Some(ref start) = gen.start {
9351 self.generate_expression(start)?;
9352 } else {
9353 self.write("0");
9354 }
9355 self.write(", ");
9356 if let Some(ref incr) = gen.increment {
9357 self.generate_expression(incr)?;
9358 } else {
9359 self.write("1");
9360 }
9361 self.write(")");
9362 } else {
9363 self.write_keyword("GENERATED");
9364 if gen.always {
9365 self.write_space();
9366 self.write_keyword("ALWAYS");
9367 } else {
9368 self.write_space();
9369 self.write_keyword("BY DEFAULT");
9370 if gen.on_null {
9371 self.write_space();
9372 self.write_keyword("ON NULL");
9373 }
9374 }
9375 self.write_space();
9376 self.write_keyword("AS IDENTITY");
9377
9378 let has_options = gen.start.is_some()
9379 || gen.increment.is_some()
9380 || gen.minvalue.is_some()
9381 || gen.maxvalue.is_some()
9382 || gen.cycle.is_some();
9383 if has_options {
9384 self.write(" (");
9385 let mut first = true;
9386 if let Some(ref start) = gen.start {
9387 if !first {
9388 self.write(" ");
9389 }
9390 first = false;
9391 self.write_keyword("START WITH");
9392 self.write_space();
9393 self.generate_expression(start)?;
9394 }
9395 if let Some(ref incr) = gen.increment {
9396 if !first {
9397 self.write(" ");
9398 }
9399 first = false;
9400 self.write_keyword("INCREMENT BY");
9401 self.write_space();
9402 self.generate_expression(incr)?;
9403 }
9404 if let Some(ref minv) = gen.minvalue {
9405 if !first {
9406 self.write(" ");
9407 }
9408 first = false;
9409 self.write_keyword("MINVALUE");
9410 self.write_space();
9411 self.generate_expression(minv)?;
9412 }
9413 if let Some(ref maxv) = gen.maxvalue {
9414 if !first {
9415 self.write(" ");
9416 }
9417 first = false;
9418 self.write_keyword("MAXVALUE");
9419 self.write_space();
9420 self.generate_expression(maxv)?;
9421 }
9422 if let Some(cycle) = gen.cycle {
9423 if !first {
9424 self.write(" ");
9425 }
9426 if cycle {
9427 self.write_keyword("CYCLE");
9428 } else {
9429 self.write_keyword("NO CYCLE");
9430 }
9431 }
9432 self.write(")");
9433 }
9434 }
9435 generated_idx += 1;
9436 break;
9437 }
9438 generated_idx += 1;
9439 }
9440 }
9441 ConstraintType::Collate => {
9442 while collate_idx < col.constraints.len() {
9444 if let ColumnConstraint::Collate(collation) =
9445 &col.constraints[collate_idx]
9446 {
9447 self.write_space();
9448 self.write_keyword("COLLATE");
9449 self.write_space();
9450 self.generate_identifier(collation)?;
9451 collate_idx += 1;
9452 break;
9453 }
9454 collate_idx += 1;
9455 }
9456 }
9457 ConstraintType::Comment => {
9458 while comment_idx < col.constraints.len() {
9460 if let ColumnConstraint::Comment(comment) =
9461 &col.constraints[comment_idx]
9462 {
9463 self.write_space();
9464 self.write_keyword("COMMENT");
9465 self.write_space();
9466 self.generate_string_literal(comment)?;
9467 comment_idx += 1;
9468 break;
9469 }
9470 comment_idx += 1;
9471 }
9472 }
9473 ConstraintType::Tags => {
9474 for constraint in &col.constraints {
9476 if let ColumnConstraint::Tags(tags) = constraint {
9477 self.write_space();
9478 self.write_keyword("TAG");
9479 self.write(" (");
9480 for (i, expr) in tags.expressions.iter().enumerate() {
9481 if i > 0 {
9482 self.write(", ");
9483 }
9484 self.generate_expression(expr)?;
9485 }
9486 self.write(")");
9487 break;
9488 }
9489 }
9490 }
9491 ConstraintType::ComputedColumn => {
9492 for constraint in &col.constraints {
9494 if let ColumnConstraint::ComputedColumn(cc) = constraint {
9495 self.write_space();
9496 self.generate_computed_column_inline(cc)?;
9497 break;
9498 }
9499 }
9500 }
9501 ConstraintType::GeneratedAsRow => {
9502 for constraint in &col.constraints {
9504 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
9505 self.write_space();
9506 self.generate_generated_as_row_inline(gar)?;
9507 break;
9508 }
9509 }
9510 }
9511 ConstraintType::OnUpdate => {
9512 if let Some(ref expr) = col.on_update {
9513 self.write_space();
9514 self.write_keyword("ON UPDATE");
9515 self.write_space();
9516 self.generate_expression(expr)?;
9517 }
9518 }
9519 ConstraintType::Encode => {
9520 if let Some(ref encoding) = col.encoding {
9521 self.write_space();
9522 self.write_keyword("ENCODE");
9523 self.write_space();
9524 self.write(encoding);
9525 }
9526 }
9527 ConstraintType::Path => {
9528 for constraint in &col.constraints {
9530 if let ColumnConstraint::Path(path_expr) = constraint {
9531 self.write_space();
9532 self.write_keyword("PATH");
9533 self.write_space();
9534 self.generate_expression(path_expr)?;
9535 break;
9536 }
9537 }
9538 }
9539 }
9540 }
9541 if pending_not_null_after_identity {
9542 self.write_space();
9543 self.write_keyword("NOT NULL");
9544 }
9545 } else {
9546 if col.primary_key {
9548 self.write_space();
9549 self.write_keyword("PRIMARY KEY");
9550 if let Some(ref order) = col.primary_key_order {
9551 self.write_space();
9552 match order {
9553 SortOrder::Asc => self.write_keyword("ASC"),
9554 SortOrder::Desc => self.write_keyword("DESC"),
9555 }
9556 }
9557 }
9558
9559 if col.unique {
9560 self.write_space();
9561 self.write_keyword("UNIQUE");
9562 if col.unique_nulls_not_distinct {
9564 self.write(" NULLS NOT DISTINCT");
9565 }
9566 }
9567
9568 match col.nullable {
9569 Some(false) => {
9570 self.write_space();
9571 self.write_keyword("NOT NULL");
9572 }
9573 Some(true) => {
9574 self.write_space();
9575 self.write_keyword("NULL");
9576 }
9577 None => {}
9578 }
9579
9580 if let Some(ref default) = col.default {
9581 self.write_space();
9582 self.write_keyword("DEFAULT");
9583 self.write_space();
9584 self.generate_expression(default)?;
9585 }
9586
9587 if col.auto_increment {
9588 self.write_space();
9589 self.generate_auto_increment_keyword(col)?;
9590 }
9591
9592 for constraint in &col.constraints {
9594 match constraint {
9595 ColumnConstraint::References(fk_ref) => {
9596 self.write_space();
9597 if fk_ref.has_foreign_key_keywords {
9598 self.write_keyword("FOREIGN KEY");
9599 self.write_space();
9600 }
9601 self.write_keyword("REFERENCES");
9602 self.write_space();
9603 self.generate_table(&fk_ref.table)?;
9604 if !fk_ref.columns.is_empty() {
9605 self.write(" (");
9606 for (i, c) in fk_ref.columns.iter().enumerate() {
9607 if i > 0 {
9608 self.write(", ");
9609 }
9610 self.generate_identifier(c)?;
9611 }
9612 self.write(")");
9613 }
9614 self.generate_referential_actions(fk_ref)?;
9615 }
9616 ColumnConstraint::Check(expr) => {
9617 self.write_space();
9618 self.write_keyword("CHECK");
9619 self.write(" (");
9620 self.generate_expression(expr)?;
9621 self.write(")");
9622 }
9623 ColumnConstraint::GeneratedAsIdentity(gen) => {
9624 self.write_space();
9625 if matches!(
9627 self.config.dialect,
9628 Some(crate::dialects::DialectType::Redshift)
9629 ) {
9630 self.write_keyword("IDENTITY");
9631 self.write("(");
9632 if let Some(ref start) = gen.start {
9633 self.generate_expression(start)?;
9634 } else {
9635 self.write("0");
9636 }
9637 self.write(", ");
9638 if let Some(ref incr) = gen.increment {
9639 self.generate_expression(incr)?;
9640 } else {
9641 self.write("1");
9642 }
9643 self.write(")");
9644 } else {
9645 self.write_keyword("GENERATED");
9646 if gen.always {
9647 self.write_space();
9648 self.write_keyword("ALWAYS");
9649 } else {
9650 self.write_space();
9651 self.write_keyword("BY DEFAULT");
9652 if gen.on_null {
9653 self.write_space();
9654 self.write_keyword("ON NULL");
9655 }
9656 }
9657 self.write_space();
9658 self.write_keyword("AS IDENTITY");
9659
9660 let has_options = gen.start.is_some()
9661 || gen.increment.is_some()
9662 || gen.minvalue.is_some()
9663 || gen.maxvalue.is_some()
9664 || gen.cycle.is_some();
9665 if has_options {
9666 self.write(" (");
9667 let mut first = true;
9668 if let Some(ref start) = gen.start {
9669 if !first {
9670 self.write(" ");
9671 }
9672 first = false;
9673 self.write_keyword("START WITH");
9674 self.write_space();
9675 self.generate_expression(start)?;
9676 }
9677 if let Some(ref incr) = gen.increment {
9678 if !first {
9679 self.write(" ");
9680 }
9681 first = false;
9682 self.write_keyword("INCREMENT BY");
9683 self.write_space();
9684 self.generate_expression(incr)?;
9685 }
9686 if let Some(ref minv) = gen.minvalue {
9687 if !first {
9688 self.write(" ");
9689 }
9690 first = false;
9691 self.write_keyword("MINVALUE");
9692 self.write_space();
9693 self.generate_expression(minv)?;
9694 }
9695 if let Some(ref maxv) = gen.maxvalue {
9696 if !first {
9697 self.write(" ");
9698 }
9699 first = false;
9700 self.write_keyword("MAXVALUE");
9701 self.write_space();
9702 self.generate_expression(maxv)?;
9703 }
9704 if let Some(cycle) = gen.cycle {
9705 if !first {
9706 self.write(" ");
9707 }
9708 if cycle {
9709 self.write_keyword("CYCLE");
9710 } else {
9711 self.write_keyword("NO CYCLE");
9712 }
9713 }
9714 self.write(")");
9715 }
9716 }
9717 }
9718 ColumnConstraint::Collate(collation) => {
9719 self.write_space();
9720 self.write_keyword("COLLATE");
9721 self.write_space();
9722 self.generate_identifier(collation)?;
9723 }
9724 ColumnConstraint::Comment(comment) => {
9725 self.write_space();
9726 self.write_keyword("COMMENT");
9727 self.write_space();
9728 self.generate_string_literal(comment)?;
9729 }
9730 ColumnConstraint::Path(path_expr) => {
9731 self.write_space();
9732 self.write_keyword("PATH");
9733 self.write_space();
9734 self.generate_expression(path_expr)?;
9735 }
9736 _ => {} }
9738 }
9739
9740 if let Some(ref encoding) = col.encoding {
9742 self.write_space();
9743 self.write_keyword("ENCODE");
9744 self.write_space();
9745 self.write(encoding);
9746 }
9747 }
9748
9749 if let Some(ref codec) = col.codec {
9751 self.write_space();
9752 self.write_keyword("CODEC");
9753 self.write("(");
9754 self.write(codec);
9755 self.write(")");
9756 }
9757
9758 if let Some(visible) = col.visible {
9759 self.write_space();
9760 if visible {
9761 self.write_keyword("VISIBLE");
9762 } else {
9763 self.write_keyword("INVISIBLE");
9764 }
9765 }
9766
9767 if let Some(ref ephemeral) = col.ephemeral {
9769 self.write_space();
9770 self.write_keyword("EPHEMERAL");
9771 if let Some(ref expr) = ephemeral {
9772 self.write_space();
9773 self.generate_expression(expr)?;
9774 }
9775 }
9776
9777 if let Some(ref mat_expr) = col.materialized_expr {
9779 self.write_space();
9780 self.write_keyword("MATERIALIZED");
9781 self.write_space();
9782 self.generate_expression(mat_expr)?;
9783 }
9784
9785 if let Some(ref alias_expr) = col.alias_expr {
9787 self.write_space();
9788 self.write_keyword("ALIAS");
9789 self.write_space();
9790 self.generate_expression(alias_expr)?;
9791 }
9792
9793 if let Some(ref ttl_expr) = col.ttl_expr {
9795 self.write_space();
9796 self.write_keyword("TTL");
9797 self.write_space();
9798 self.generate_expression(ttl_expr)?;
9799 }
9800
9801 if col.not_for_replication
9803 && matches!(
9804 self.config.dialect,
9805 Some(crate::dialects::DialectType::TSQL)
9806 | Some(crate::dialects::DialectType::Fabric)
9807 )
9808 {
9809 self.write_space();
9810 self.write_keyword("NOT FOR REPLICATION");
9811 }
9812
9813 if !col.options.is_empty() {
9815 self.write_space();
9816 self.generate_options_clause(&col.options)?;
9817 }
9818
9819 if !col.primary_key
9822 && self
9823 .sqlite_inline_pk_columns
9824 .contains(&col.name.name.to_ascii_lowercase())
9825 {
9826 self.write_space();
9827 self.write_keyword("PRIMARY KEY");
9828 if matches!(self.config.dialect, Some(DialectType::SQLite)) && col.auto_increment {
9829 self.write_space();
9830 self.generate_auto_increment_keyword(col)?;
9831 }
9832 }
9833
9834 if serial_expansion.is_some() {
9837 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
9838 self.write_space();
9839 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
9840 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
9841 self.write_space();
9842 self.write_keyword("NOT NULL");
9843 }
9844 }
9845
9846 Ok(())
9847 }
9848
9849 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
9850 match constraint {
9851 TableConstraint::PrimaryKey {
9852 name,
9853 columns,
9854 include_columns,
9855 modifiers,
9856 has_constraint_keyword,
9857 } => {
9858 if let Some(ref n) = name {
9859 if *has_constraint_keyword {
9860 self.write_keyword("CONSTRAINT");
9861 self.write_space();
9862 self.generate_identifier(n)?;
9863 self.write_space();
9864 }
9865 }
9866 self.write_keyword("PRIMARY KEY");
9867 if let Some(ref clustered) = modifiers.clustered {
9869 self.write_space();
9870 self.write_keyword(clustered);
9871 }
9872 if let Some(ref n) = name {
9874 if !*has_constraint_keyword {
9875 self.write_space();
9876 self.generate_identifier(n)?;
9877 }
9878 }
9879 self.write(" (");
9880 for (i, col) in columns.iter().enumerate() {
9881 if i > 0 {
9882 self.write(", ");
9883 }
9884 self.generate_identifier(col)?;
9885 }
9886 self.write(")");
9887 if !include_columns.is_empty() {
9888 self.write_space();
9889 self.write_keyword("INCLUDE");
9890 self.write(" (");
9891 for (i, col) in include_columns.iter().enumerate() {
9892 if i > 0 {
9893 self.write(", ");
9894 }
9895 self.generate_identifier(col)?;
9896 }
9897 self.write(")");
9898 }
9899 self.generate_constraint_modifiers(modifiers);
9900 }
9901 TableConstraint::Unique {
9902 name,
9903 columns,
9904 columns_parenthesized,
9905 modifiers,
9906 has_constraint_keyword,
9907 nulls_not_distinct,
9908 } => {
9909 if let Some(ref n) = name {
9910 if *has_constraint_keyword {
9911 self.write_keyword("CONSTRAINT");
9912 self.write_space();
9913 self.generate_identifier(n)?;
9914 self.write_space();
9915 }
9916 }
9917 self.write_keyword("UNIQUE");
9918 if let Some(ref clustered) = modifiers.clustered {
9920 self.write_space();
9921 self.write_keyword(clustered);
9922 }
9923 if *nulls_not_distinct {
9925 self.write(" NULLS NOT DISTINCT");
9926 }
9927 if let Some(ref n) = name {
9929 if !*has_constraint_keyword {
9930 self.write_space();
9931 self.generate_identifier(n)?;
9932 }
9933 }
9934 if *columns_parenthesized {
9935 self.write(" (");
9936 for (i, col) in columns.iter().enumerate() {
9937 if i > 0 {
9938 self.write(", ");
9939 }
9940 self.generate_identifier(col)?;
9941 }
9942 self.write(")");
9943 } else {
9944 for col in columns.iter() {
9946 self.write_space();
9947 self.generate_identifier(col)?;
9948 }
9949 }
9950 self.generate_constraint_modifiers(modifiers);
9951 }
9952 TableConstraint::ForeignKey {
9953 name,
9954 columns,
9955 references,
9956 on_delete,
9957 on_update,
9958 modifiers,
9959 } => {
9960 if let Some(ref n) = name {
9961 self.write_keyword("CONSTRAINT");
9962 self.write_space();
9963 self.generate_identifier(n)?;
9964 self.write_space();
9965 }
9966 self.write_keyword("FOREIGN KEY");
9967 self.write(" (");
9968 for (i, col) in columns.iter().enumerate() {
9969 if i > 0 {
9970 self.write(", ");
9971 }
9972 self.generate_identifier(col)?;
9973 }
9974 self.write(")");
9975 if let Some(ref refs) = references {
9976 self.write(" ");
9977 self.write_keyword("REFERENCES");
9978 self.write_space();
9979 self.generate_table(&refs.table)?;
9980 if !refs.columns.is_empty() {
9981 if self.config.pretty {
9982 self.write(" (");
9983 self.write_newline();
9984 self.indent_level += 1;
9985 for (i, col) in refs.columns.iter().enumerate() {
9986 if i > 0 {
9987 self.write(",");
9988 self.write_newline();
9989 }
9990 self.write_indent();
9991 self.generate_identifier(col)?;
9992 }
9993 self.indent_level -= 1;
9994 self.write_newline();
9995 self.write_indent();
9996 self.write(")");
9997 } else {
9998 self.write(" (");
9999 for (i, col) in refs.columns.iter().enumerate() {
10000 if i > 0 {
10001 self.write(", ");
10002 }
10003 self.generate_identifier(col)?;
10004 }
10005 self.write(")");
10006 }
10007 }
10008 self.generate_referential_actions(refs)?;
10009 } else {
10010 if let Some(ref action) = on_delete {
10012 self.write_space();
10013 self.write_keyword("ON DELETE");
10014 self.write_space();
10015 self.generate_referential_action(action);
10016 }
10017 if let Some(ref action) = on_update {
10018 self.write_space();
10019 self.write_keyword("ON UPDATE");
10020 self.write_space();
10021 self.generate_referential_action(action);
10022 }
10023 }
10024 self.generate_constraint_modifiers(modifiers);
10025 }
10026 TableConstraint::Check {
10027 name,
10028 expression,
10029 modifiers,
10030 } => {
10031 if let Some(ref n) = name {
10032 self.write_keyword("CONSTRAINT");
10033 self.write_space();
10034 self.generate_identifier(n)?;
10035 self.write_space();
10036 }
10037 self.write_keyword("CHECK");
10038 self.write(" (");
10039 self.generate_expression(expression)?;
10040 self.write(")");
10041 self.generate_constraint_modifiers(modifiers);
10042 }
10043 TableConstraint::Assume { name, expression } => {
10044 if let Some(ref n) = name {
10045 self.write_keyword("CONSTRAINT");
10046 self.write_space();
10047 self.generate_identifier(n)?;
10048 self.write_space();
10049 }
10050 self.write_keyword("ASSUME");
10051 self.write(" (");
10052 self.generate_expression(expression)?;
10053 self.write(")");
10054 }
10055 TableConstraint::Default {
10056 name,
10057 expression,
10058 column,
10059 } => {
10060 if let Some(ref n) = name {
10061 self.write_keyword("CONSTRAINT");
10062 self.write_space();
10063 self.generate_identifier(n)?;
10064 self.write_space();
10065 }
10066 self.write_keyword("DEFAULT");
10067 self.write_space();
10068 self.generate_expression(expression)?;
10069 self.write_space();
10070 self.write_keyword("FOR");
10071 self.write_space();
10072 self.generate_identifier(column)?;
10073 }
10074 TableConstraint::Index {
10075 name,
10076 columns,
10077 kind,
10078 modifiers,
10079 use_key_keyword,
10080 expression,
10081 index_type,
10082 granularity,
10083 } => {
10084 if expression.is_some() {
10086 self.write_keyword("INDEX");
10087 if let Some(ref n) = name {
10088 self.write_space();
10089 self.generate_identifier(n)?;
10090 }
10091 if let Some(ref expr) = expression {
10092 self.write_space();
10093 self.generate_expression(expr)?;
10094 }
10095 if let Some(ref idx_type) = index_type {
10096 self.write_space();
10097 self.write_keyword("TYPE");
10098 self.write_space();
10099 self.generate_expression(idx_type)?;
10100 }
10101 if let Some(ref gran) = granularity {
10102 self.write_space();
10103 self.write_keyword("GRANULARITY");
10104 self.write_space();
10105 self.generate_expression(gran)?;
10106 }
10107 } else {
10108 use crate::dialects::DialectType;
10112 let index_keyword = if *use_key_keyword
10113 && !matches!(self.config.dialect, Some(DialectType::MySQL))
10114 {
10115 "KEY"
10116 } else {
10117 "INDEX"
10118 };
10119
10120 if let Some(ref k) = kind {
10122 self.write_keyword(k);
10123 if k != "UNIQUE" {
10125 self.write_space();
10126 self.write_keyword(index_keyword);
10127 }
10128 } else {
10129 self.write_keyword(index_keyword);
10130 }
10131
10132 if modifiers.using_before_columns && name.is_none() {
10134 if let Some(ref using) = modifiers.using {
10135 self.write_space();
10136 self.write_keyword("USING");
10137 self.write_space();
10138 self.write_keyword(using);
10139 }
10140 }
10141
10142 if let Some(ref n) = name {
10144 self.write_space();
10145 self.generate_identifier(n)?;
10146 }
10147
10148 if modifiers.using_before_columns && name.is_some() {
10150 if let Some(ref using) = modifiers.using {
10151 self.write_space();
10152 self.write_keyword("USING");
10153 self.write_space();
10154 self.write_keyword(using);
10155 }
10156 }
10157
10158 self.write(" (");
10160 for (i, col) in columns.iter().enumerate() {
10161 if i > 0 {
10162 self.write(", ");
10163 }
10164 self.generate_identifier(col)?;
10165 }
10166 self.write(")");
10167
10168 if !modifiers.using_before_columns {
10170 if let Some(ref using) = modifiers.using {
10171 self.write_space();
10172 self.write_keyword("USING");
10173 self.write_space();
10174 self.write_keyword(using);
10175 }
10176 }
10177
10178 self.generate_constraint_modifiers_without_using(modifiers);
10180 }
10181 }
10182 TableConstraint::Projection { name, expression } => {
10183 self.write_keyword("PROJECTION");
10185 self.write_space();
10186 self.generate_identifier(name)?;
10187 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
10188 if let Expression::Raw(raw) = expression {
10189 if raw
10190 .sql
10191 .trim_start()
10192 .to_ascii_uppercase()
10193 .starts_with("INDEX ")
10194 {
10195 self.write_space();
10196 self.write(raw.sql.trim());
10197 return Ok(());
10198 }
10199 }
10200 }
10201 self.write(" (");
10202 self.generate_expression(expression)?;
10203 self.write(")");
10204 }
10205 TableConstraint::Like { source, options } => {
10206 self.write_keyword("LIKE");
10207 self.write_space();
10208 self.generate_table(source)?;
10209 for (action, prop) in options {
10210 self.write_space();
10211 match action {
10212 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
10213 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
10214 }
10215 self.write_space();
10216 self.write_keyword(prop);
10217 }
10218 }
10219 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
10220 self.write_keyword("PERIOD FOR SYSTEM_TIME");
10221 self.write(" (");
10222 self.generate_identifier(start_col)?;
10223 self.write(", ");
10224 self.generate_identifier(end_col)?;
10225 self.write(")");
10226 }
10227 TableConstraint::Exclude {
10228 name,
10229 using,
10230 elements,
10231 include_columns,
10232 where_clause,
10233 with_params,
10234 using_index_tablespace,
10235 modifiers: _,
10236 } => {
10237 if let Some(ref n) = name {
10238 self.write_keyword("CONSTRAINT");
10239 self.write_space();
10240 self.generate_identifier(n)?;
10241 self.write_space();
10242 }
10243 self.write_keyword("EXCLUDE");
10244 if let Some(ref method) = using {
10245 self.write_space();
10246 self.write_keyword("USING");
10247 self.write_space();
10248 self.write(method);
10249 self.write("(");
10250 } else {
10251 self.write(" (");
10252 }
10253 for (i, elem) in elements.iter().enumerate() {
10254 if i > 0 {
10255 self.write(", ");
10256 }
10257 self.write(&elem.expression);
10258 self.write_space();
10259 self.write_keyword("WITH");
10260 self.write_space();
10261 self.write(&elem.operator);
10262 }
10263 self.write(")");
10264 if !include_columns.is_empty() {
10265 self.write_space();
10266 self.write_keyword("INCLUDE");
10267 self.write(" (");
10268 for (i, col) in include_columns.iter().enumerate() {
10269 if i > 0 {
10270 self.write(", ");
10271 }
10272 self.generate_identifier(col)?;
10273 }
10274 self.write(")");
10275 }
10276 if !with_params.is_empty() {
10277 self.write_space();
10278 self.write_keyword("WITH");
10279 self.write(" (");
10280 for (i, (key, val)) in with_params.iter().enumerate() {
10281 if i > 0 {
10282 self.write(", ");
10283 }
10284 self.write(key);
10285 self.write("=");
10286 self.write(val);
10287 }
10288 self.write(")");
10289 }
10290 if let Some(ref tablespace) = using_index_tablespace {
10291 self.write_space();
10292 self.write_keyword("USING INDEX TABLESPACE");
10293 self.write_space();
10294 self.write(tablespace);
10295 }
10296 if let Some(ref where_expr) = where_clause {
10297 self.write_space();
10298 self.write_keyword("WHERE");
10299 self.write(" (");
10300 self.generate_expression(where_expr)?;
10301 self.write(")");
10302 }
10303 }
10304 TableConstraint::Tags(tags) => {
10305 self.write_keyword("TAG");
10306 self.write(" (");
10307 for (i, expr) in tags.expressions.iter().enumerate() {
10308 if i > 0 {
10309 self.write(", ");
10310 }
10311 self.generate_expression(expr)?;
10312 }
10313 self.write(")");
10314 }
10315 TableConstraint::InitiallyDeferred { deferred } => {
10316 self.write_keyword("INITIALLY");
10317 self.write_space();
10318 if *deferred {
10319 self.write_keyword("DEFERRED");
10320 } else {
10321 self.write_keyword("IMMEDIATE");
10322 }
10323 }
10324 }
10325 Ok(())
10326 }
10327
10328 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
10329 if let Some(using) = &modifiers.using {
10331 self.write_space();
10332 self.write_keyword("USING");
10333 self.write_space();
10334 self.write_keyword(using);
10335 }
10336 if let Some(enforced) = modifiers.enforced {
10338 self.write_space();
10339 if enforced {
10340 self.write_keyword("ENFORCED");
10341 } else {
10342 self.write_keyword("NOT ENFORCED");
10343 }
10344 }
10345 if let Some(deferrable) = modifiers.deferrable {
10347 self.write_space();
10348 if deferrable {
10349 self.write_keyword("DEFERRABLE");
10350 } else {
10351 self.write_keyword("NOT DEFERRABLE");
10352 }
10353 }
10354 if let Some(initially_deferred) = modifiers.initially_deferred {
10356 self.write_space();
10357 if initially_deferred {
10358 self.write_keyword("INITIALLY DEFERRED");
10359 } else {
10360 self.write_keyword("INITIALLY IMMEDIATE");
10361 }
10362 }
10363 if modifiers.norely {
10365 self.write_space();
10366 self.write_keyword("NORELY");
10367 }
10368 if modifiers.rely {
10370 self.write_space();
10371 self.write_keyword("RELY");
10372 }
10373 if modifiers.not_valid {
10375 self.write_space();
10376 self.write_keyword("NOT VALID");
10377 }
10378 if let Some(on_conflict) = &modifiers.on_conflict {
10380 self.write_space();
10381 self.write_keyword("ON CONFLICT");
10382 self.write_space();
10383 self.write_keyword(on_conflict);
10384 }
10385 if !modifiers.with_options.is_empty() {
10387 self.write_space();
10388 self.write_keyword("WITH");
10389 self.write(" (");
10390 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
10391 if i > 0 {
10392 self.write(", ");
10393 }
10394 self.write(key);
10395 self.write("=");
10396 self.write(value);
10397 }
10398 self.write(")");
10399 }
10400 if let Some(ref fg) = modifiers.on_filegroup {
10402 self.write_space();
10403 self.write_keyword("ON");
10404 self.write_space();
10405 let _ = self.generate_identifier(fg);
10406 }
10407 }
10408
10409 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
10411 if let Some(enforced) = modifiers.enforced {
10413 self.write_space();
10414 if enforced {
10415 self.write_keyword("ENFORCED");
10416 } else {
10417 self.write_keyword("NOT ENFORCED");
10418 }
10419 }
10420 if let Some(deferrable) = modifiers.deferrable {
10422 self.write_space();
10423 if deferrable {
10424 self.write_keyword("DEFERRABLE");
10425 } else {
10426 self.write_keyword("NOT DEFERRABLE");
10427 }
10428 }
10429 if let Some(initially_deferred) = modifiers.initially_deferred {
10431 self.write_space();
10432 if initially_deferred {
10433 self.write_keyword("INITIALLY DEFERRED");
10434 } else {
10435 self.write_keyword("INITIALLY IMMEDIATE");
10436 }
10437 }
10438 if modifiers.norely {
10440 self.write_space();
10441 self.write_keyword("NORELY");
10442 }
10443 if modifiers.rely {
10445 self.write_space();
10446 self.write_keyword("RELY");
10447 }
10448 if modifiers.not_valid {
10450 self.write_space();
10451 self.write_keyword("NOT VALID");
10452 }
10453 if let Some(on_conflict) = &modifiers.on_conflict {
10455 self.write_space();
10456 self.write_keyword("ON CONFLICT");
10457 self.write_space();
10458 self.write_keyword(on_conflict);
10459 }
10460 self.generate_index_specific_modifiers(modifiers);
10462 }
10463
10464 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
10466 if let Some(ref comment) = modifiers.comment {
10467 self.write_space();
10468 self.write_keyword("COMMENT");
10469 self.write(" '");
10470 self.write(comment);
10471 self.write("'");
10472 }
10473 if let Some(visible) = modifiers.visible {
10474 self.write_space();
10475 if visible {
10476 self.write_keyword("VISIBLE");
10477 } else {
10478 self.write_keyword("INVISIBLE");
10479 }
10480 }
10481 if let Some(ref attr) = modifiers.engine_attribute {
10482 self.write_space();
10483 self.write_keyword("ENGINE_ATTRIBUTE");
10484 self.write(" = '");
10485 self.write(attr);
10486 self.write("'");
10487 }
10488 if let Some(ref parser) = modifiers.with_parser {
10489 self.write_space();
10490 self.write_keyword("WITH PARSER");
10491 self.write_space();
10492 self.write(parser);
10493 }
10494 }
10495
10496 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
10497 if !fk_ref.match_after_actions {
10499 if let Some(ref match_type) = fk_ref.match_type {
10500 self.write_space();
10501 self.write_keyword("MATCH");
10502 self.write_space();
10503 match match_type {
10504 MatchType::Full => self.write_keyword("FULL"),
10505 MatchType::Partial => self.write_keyword("PARTIAL"),
10506 MatchType::Simple => self.write_keyword("SIMPLE"),
10507 }
10508 }
10509 }
10510
10511 if fk_ref.on_update_first {
10513 if let Some(ref action) = fk_ref.on_update {
10514 self.write_space();
10515 self.write_keyword("ON UPDATE");
10516 self.write_space();
10517 self.generate_referential_action(action);
10518 }
10519 if let Some(ref action) = fk_ref.on_delete {
10520 self.write_space();
10521 self.write_keyword("ON DELETE");
10522 self.write_space();
10523 self.generate_referential_action(action);
10524 }
10525 } else {
10526 if let Some(ref action) = fk_ref.on_delete {
10527 self.write_space();
10528 self.write_keyword("ON DELETE");
10529 self.write_space();
10530 self.generate_referential_action(action);
10531 }
10532 if let Some(ref action) = fk_ref.on_update {
10533 self.write_space();
10534 self.write_keyword("ON UPDATE");
10535 self.write_space();
10536 self.generate_referential_action(action);
10537 }
10538 }
10539
10540 if fk_ref.match_after_actions {
10542 if let Some(ref match_type) = fk_ref.match_type {
10543 self.write_space();
10544 self.write_keyword("MATCH");
10545 self.write_space();
10546 match match_type {
10547 MatchType::Full => self.write_keyword("FULL"),
10548 MatchType::Partial => self.write_keyword("PARTIAL"),
10549 MatchType::Simple => self.write_keyword("SIMPLE"),
10550 }
10551 }
10552 }
10553
10554 if let Some(deferrable) = fk_ref.deferrable {
10556 self.write_space();
10557 if deferrable {
10558 self.write_keyword("DEFERRABLE");
10559 } else {
10560 self.write_keyword("NOT DEFERRABLE");
10561 }
10562 }
10563
10564 Ok(())
10565 }
10566
10567 fn generate_referential_action(&mut self, action: &ReferentialAction) {
10568 match action {
10569 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
10570 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
10571 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
10572 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
10573 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
10574 }
10575 }
10576
10577 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
10578 if let Some(ref object_id_args) = dt.object_id_args {
10580 if matches!(
10581 self.config.dialect,
10582 Some(crate::dialects::DialectType::TSQL)
10583 | Some(crate::dialects::DialectType::Fabric)
10584 ) {
10585 self.write_keyword("IF NOT OBJECT_ID");
10586 self.write("(");
10587 self.write(object_id_args);
10588 self.write(")");
10589 self.write_space();
10590 self.write_keyword("IS NULL BEGIN DROP TABLE");
10591 self.write_space();
10592 for (i, table) in dt.names.iter().enumerate() {
10593 if i > 0 {
10594 self.write(", ");
10595 }
10596 self.generate_table(table)?;
10597 }
10598 self.write("; ");
10599 self.write_keyword("END");
10600 return Ok(());
10601 }
10602 }
10603
10604 let saved_athena_hive_context = self.athena_hive_context;
10606 if matches!(
10607 self.config.dialect,
10608 Some(crate::dialects::DialectType::Athena)
10609 ) {
10610 self.athena_hive_context = true;
10611 }
10612
10613 for comment in &dt.leading_comments {
10615 self.write_formatted_comment(comment);
10616 self.write_space();
10617 }
10618 if dt.iceberg {
10619 self.write_keyword("DROP ICEBERG TABLE");
10620 } else {
10621 self.write_keyword("DROP TABLE");
10622 }
10623
10624 if dt.if_exists {
10625 self.write_space();
10626 self.write_keyword("IF EXISTS");
10627 }
10628
10629 self.write_space();
10630 for (i, table) in dt.names.iter().enumerate() {
10631 if i > 0 {
10632 self.write(", ");
10633 }
10634 self.generate_table(table)?;
10635 }
10636
10637 if dt.cascade_constraints {
10638 self.write_space();
10639 self.write_keyword("CASCADE CONSTRAINTS");
10640 } else if dt.cascade {
10641 self.write_space();
10642 self.write_keyword("CASCADE");
10643 }
10644
10645 if dt.restrict {
10646 self.write_space();
10647 self.write_keyword("RESTRICT");
10648 }
10649
10650 if dt.purge {
10651 self.write_space();
10652 self.write_keyword("PURGE");
10653 }
10654
10655 if dt.sync {
10656 self.write_space();
10657 self.write_keyword("SYNC");
10658 }
10659
10660 self.athena_hive_context = saved_athena_hive_context;
10662
10663 Ok(())
10664 }
10665
10666 fn generate_undrop(&mut self, u: &Undrop) -> Result<()> {
10667 self.write_keyword("UNDROP");
10668 self.write_space();
10669 self.write_keyword(&u.kind);
10670 if u.if_exists {
10671 self.write_space();
10672 self.write_keyword("IF EXISTS");
10673 }
10674 self.write_space();
10675 self.generate_table(&u.name)?;
10676 if let Some(rename_to) = &u.rename_to {
10677 self.write_space();
10678 self.write_keyword("RENAME TO");
10679 self.write_space();
10680 self.generate_table(rename_to)?;
10681 }
10682 Ok(())
10683 }
10684
10685 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
10686 let saved_athena_hive_context = self.athena_hive_context;
10688 if matches!(
10689 self.config.dialect,
10690 Some(crate::dialects::DialectType::Athena)
10691 ) {
10692 self.athena_hive_context = true;
10693 }
10694
10695 self.write_keyword("ALTER");
10696 if let Some(ref modifier) = at.table_modifier {
10698 if !matches!(
10699 self.config.dialect,
10700 Some(crate::dialects::DialectType::DuckDB)
10701 ) {
10702 self.write_space();
10703 self.write_keyword(modifier);
10704 }
10705 }
10706 self.write(" ");
10707 self.write_keyword("TABLE");
10708 if at.if_exists {
10709 self.write_space();
10710 self.write_keyword("IF EXISTS");
10711 }
10712 self.write_space();
10713 self.generate_table(&at.name)?;
10714
10715 if let Some(ref on_cluster) = at.on_cluster {
10717 self.write_space();
10718 self.generate_on_cluster(on_cluster)?;
10719 }
10720
10721 if let Some(ref partition) = at.partition {
10723 self.write_space();
10724 self.write_keyword("PARTITION");
10725 self.write("(");
10726 for (i, (key, value)) in partition.iter().enumerate() {
10727 if i > 0 {
10728 self.write(", ");
10729 }
10730 self.generate_identifier(key)?;
10731 self.write(" = ");
10732 self.generate_expression(value)?;
10733 }
10734 self.write(")");
10735 }
10736
10737 if let Some(ref with_check) = at.with_check {
10739 self.write_space();
10740 self.write_keyword(with_check);
10741 }
10742
10743 if self.config.pretty {
10744 self.write_newline();
10746 self.indent_level += 1;
10747 for (i, action) in at.actions.iter().enumerate() {
10748 let is_continuation = i > 0
10750 && matches!(
10751 (&at.actions[i - 1], action),
10752 (
10753 AlterTableAction::AddColumn { .. },
10754 AlterTableAction::AddColumn { .. }
10755 ) | (
10756 AlterTableAction::AddConstraint(_),
10757 AlterTableAction::AddConstraint(_)
10758 )
10759 );
10760 if i > 0 {
10761 self.write(",");
10762 self.write_newline();
10763 }
10764 self.write_indent();
10765 self.generate_alter_action_with_continuation(action, is_continuation)?;
10766 }
10767 self.indent_level -= 1;
10768 } else {
10769 for (i, action) in at.actions.iter().enumerate() {
10770 let is_continuation = i > 0
10772 && matches!(
10773 (&at.actions[i - 1], action),
10774 (
10775 AlterTableAction::AddColumn { .. },
10776 AlterTableAction::AddColumn { .. }
10777 ) | (
10778 AlterTableAction::AddConstraint(_),
10779 AlterTableAction::AddConstraint(_)
10780 )
10781 );
10782 if i > 0 {
10783 self.write(",");
10784 }
10785 self.write_space();
10786 self.generate_alter_action_with_continuation(action, is_continuation)?;
10787 }
10788 }
10789
10790 if let Some(ref algorithm) = at.algorithm {
10792 self.write(", ");
10793 self.write_keyword("ALGORITHM");
10794 self.write("=");
10795 self.write_keyword(algorithm);
10796 }
10797 if let Some(ref lock) = at.lock {
10798 self.write(", ");
10799 self.write_keyword("LOCK");
10800 self.write("=");
10801 self.write_keyword(lock);
10802 }
10803
10804 self.athena_hive_context = saved_athena_hive_context;
10806
10807 Ok(())
10808 }
10809
10810 fn generate_alter_action_with_continuation(
10811 &mut self,
10812 action: &AlterTableAction,
10813 is_continuation: bool,
10814 ) -> Result<()> {
10815 match action {
10816 AlterTableAction::AddColumn {
10817 column,
10818 if_not_exists,
10819 position,
10820 } => {
10821 use crate::dialects::DialectType;
10822 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
10826 let is_tsql_like = matches!(
10827 self.config.dialect,
10828 Some(DialectType::TSQL) | Some(DialectType::Fabric)
10829 );
10830 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
10832
10833 if is_continuation && (is_snowflake || is_tsql_like) {
10834 } else if is_snowflake {
10836 self.write_keyword("ADD");
10837 self.write_space();
10838 } else if is_athena {
10839 self.write_keyword("ADD COLUMNS");
10841 self.write(" (");
10842 } else if self.config.alter_table_include_column_keyword {
10843 self.write_keyword("ADD COLUMN");
10844 self.write_space();
10845 } else {
10846 self.write_keyword("ADD");
10848 self.write_space();
10849 }
10850
10851 if *if_not_exists {
10852 self.write_keyword("IF NOT EXISTS");
10853 self.write_space();
10854 }
10855 self.generate_column_def(column)?;
10856
10857 if is_athena {
10859 self.write(")");
10860 }
10861
10862 if let Some(pos) = position {
10864 self.write_space();
10865 match pos {
10866 ColumnPosition::First => self.write_keyword("FIRST"),
10867 ColumnPosition::After(col_name) => {
10868 self.write_keyword("AFTER");
10869 self.write_space();
10870 self.generate_identifier(col_name)?;
10871 }
10872 }
10873 }
10874 }
10875 AlterTableAction::DropColumn {
10876 name,
10877 if_exists,
10878 cascade,
10879 } => {
10880 self.write_keyword("DROP COLUMN");
10881 if *if_exists {
10882 self.write_space();
10883 self.write_keyword("IF EXISTS");
10884 }
10885 self.write_space();
10886 self.generate_identifier(name)?;
10887 if *cascade {
10888 self.write_space();
10889 self.write_keyword("CASCADE");
10890 }
10891 }
10892 AlterTableAction::DropColumns { names } => {
10893 self.write_keyword("DROP COLUMNS");
10894 self.write(" (");
10895 for (i, name) in names.iter().enumerate() {
10896 if i > 0 {
10897 self.write(", ");
10898 }
10899 self.generate_identifier(name)?;
10900 }
10901 self.write(")");
10902 }
10903 AlterTableAction::RenameColumn {
10904 old_name,
10905 new_name,
10906 if_exists,
10907 } => {
10908 self.write_keyword("RENAME COLUMN");
10909 if *if_exists {
10910 self.write_space();
10911 self.write_keyword("IF EXISTS");
10912 }
10913 self.write_space();
10914 self.generate_identifier(old_name)?;
10915 self.write_space();
10916 self.write_keyword("TO");
10917 self.write_space();
10918 self.generate_identifier(new_name)?;
10919 }
10920 AlterTableAction::AlterColumn {
10921 name,
10922 action,
10923 use_modify_keyword,
10924 } => {
10925 use crate::dialects::DialectType;
10926 let use_modify = *use_modify_keyword
10929 || (matches!(self.config.dialect, Some(DialectType::MySQL))
10930 && matches!(action, AlterColumnAction::SetDataType { .. }));
10931 if use_modify {
10932 self.write_keyword("MODIFY COLUMN");
10933 self.write_space();
10934 self.generate_identifier(name)?;
10935 if let AlterColumnAction::SetDataType {
10937 data_type,
10938 using: _,
10939 collate,
10940 } = action
10941 {
10942 self.write_space();
10943 self.generate_data_type(data_type)?;
10944 if let Some(collate_name) = collate {
10946 self.write_space();
10947 self.write_keyword("COLLATE");
10948 self.write_space();
10949 self.write(&format!("'{}'", collate_name));
10951 }
10952 } else {
10953 self.write_space();
10954 self.generate_alter_column_action(action)?;
10955 }
10956 } else if matches!(self.config.dialect, Some(DialectType::Hive))
10957 && matches!(action, AlterColumnAction::SetDataType { .. })
10958 {
10959 self.write_keyword("CHANGE COLUMN");
10961 self.write_space();
10962 self.generate_identifier(name)?;
10963 self.write_space();
10964 self.generate_identifier(name)?;
10965 if let AlterColumnAction::SetDataType { data_type, .. } = action {
10966 self.write_space();
10967 self.generate_data_type(data_type)?;
10968 }
10969 } else {
10970 self.write_keyword("ALTER COLUMN");
10971 self.write_space();
10972 self.generate_identifier(name)?;
10973 self.write_space();
10974 self.generate_alter_column_action(action)?;
10975 }
10976 }
10977 AlterTableAction::RenameTable(new_name) => {
10978 let mysql_like = matches!(
10980 self.config.dialect,
10981 Some(DialectType::MySQL)
10982 | Some(DialectType::Doris)
10983 | Some(DialectType::StarRocks)
10984 | Some(DialectType::SingleStore)
10985 );
10986 if mysql_like {
10987 self.write_keyword("RENAME");
10988 } else {
10989 self.write_keyword("RENAME TO");
10990 }
10991 self.write_space();
10992 let rename_table_with_db = !matches!(
10994 self.config.dialect,
10995 Some(DialectType::Doris)
10996 | Some(DialectType::DuckDB)
10997 | Some(DialectType::BigQuery)
10998 | Some(DialectType::PostgreSQL)
10999 );
11000 if !rename_table_with_db {
11001 let mut stripped = new_name.clone();
11002 stripped.schema = None;
11003 stripped.catalog = None;
11004 self.generate_table(&stripped)?;
11005 } else {
11006 self.generate_table(new_name)?;
11007 }
11008 }
11009 AlterTableAction::AddConstraint(constraint) => {
11010 if !is_continuation {
11013 self.write_keyword("ADD");
11014 self.write_space();
11015 }
11016 self.generate_table_constraint(constraint)?;
11017 }
11018 AlterTableAction::DropConstraint { name, if_exists } => {
11019 self.write_keyword("DROP CONSTRAINT");
11020 if *if_exists {
11021 self.write_space();
11022 self.write_keyword("IF EXISTS");
11023 }
11024 self.write_space();
11025 self.generate_identifier(name)?;
11026 }
11027 AlterTableAction::DropForeignKey { name } => {
11028 self.write_keyword("DROP FOREIGN KEY");
11029 self.write_space();
11030 self.generate_identifier(name)?;
11031 }
11032 AlterTableAction::DropPartition {
11033 partitions,
11034 if_exists,
11035 } => {
11036 self.write_keyword("DROP");
11037 if *if_exists {
11038 self.write_space();
11039 self.write_keyword("IF EXISTS");
11040 }
11041 for (i, partition) in partitions.iter().enumerate() {
11042 if i > 0 {
11043 self.write(",");
11044 }
11045 self.write_space();
11046 self.write_keyword("PARTITION");
11047 if partition.len() == 1 && partition[0].0.name == "__expr__" {
11049 self.write_space();
11051 self.generate_expression(&partition[0].1)?;
11052 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
11053 self.write_space();
11055 self.write_keyword("ALL");
11056 } else if partition.len() == 1 && partition[0].0.name == "ID" {
11057 self.write_space();
11059 self.write_keyword("ID");
11060 self.write_space();
11061 self.generate_expression(&partition[0].1)?;
11062 } else {
11063 self.write("(");
11065 for (j, (key, value)) in partition.iter().enumerate() {
11066 if j > 0 {
11067 self.write(", ");
11068 }
11069 self.generate_identifier(key)?;
11070 self.write(" = ");
11071 self.generate_expression(value)?;
11072 }
11073 self.write(")");
11074 }
11075 }
11076 }
11077 AlterTableAction::Delete { where_clause } => {
11078 self.write_keyword("DELETE");
11079 self.write_space();
11080 self.write_keyword("WHERE");
11081 self.write_space();
11082 self.generate_expression(where_clause)?;
11083 }
11084 AlterTableAction::SwapWith(target) => {
11085 self.write_keyword("SWAP WITH");
11086 self.write_space();
11087 self.generate_table(target)?;
11088 }
11089 AlterTableAction::SetProperty { properties } => {
11090 use crate::dialects::DialectType;
11091 self.write_keyword("SET");
11092 let is_trino_presto = matches!(
11094 self.config.dialect,
11095 Some(DialectType::Trino) | Some(DialectType::Presto)
11096 );
11097 if is_trino_presto {
11098 self.write_space();
11099 self.write_keyword("PROPERTIES");
11100 }
11101 let eq = if is_trino_presto { " = " } else { "=" };
11102 for (i, (key, value)) in properties.iter().enumerate() {
11103 if i > 0 {
11104 self.write(",");
11105 }
11106 self.write_space();
11107 if key.contains(' ') {
11109 self.generate_string_literal(key)?;
11110 } else {
11111 self.write(key);
11112 }
11113 self.write(eq);
11114 self.generate_expression(value)?;
11115 }
11116 }
11117 AlterTableAction::UnsetProperty { properties } => {
11118 self.write_keyword("UNSET");
11119 for (i, name) in properties.iter().enumerate() {
11120 if i > 0 {
11121 self.write(",");
11122 }
11123 self.write_space();
11124 self.write(name);
11125 }
11126 }
11127 AlterTableAction::ClusterBy { expressions } => {
11128 self.write_keyword("CLUSTER BY");
11129 self.write(" (");
11130 for (i, expr) in expressions.iter().enumerate() {
11131 if i > 0 {
11132 self.write(", ");
11133 }
11134 self.generate_expression(expr)?;
11135 }
11136 self.write(")");
11137 }
11138 AlterTableAction::SetTag { expressions } => {
11139 self.write_keyword("SET TAG");
11140 for (i, (key, value)) in expressions.iter().enumerate() {
11141 if i > 0 {
11142 self.write(",");
11143 }
11144 self.write_space();
11145 self.write(key);
11146 self.write(" = ");
11147 self.generate_expression(value)?;
11148 }
11149 }
11150 AlterTableAction::UnsetTag { names } => {
11151 self.write_keyword("UNSET TAG");
11152 for (i, name) in names.iter().enumerate() {
11153 if i > 0 {
11154 self.write(",");
11155 }
11156 self.write_space();
11157 self.write(name);
11158 }
11159 }
11160 AlterTableAction::SetOptions { expressions } => {
11161 self.write_keyword("SET");
11162 self.write(" (");
11163 for (i, expr) in expressions.iter().enumerate() {
11164 if i > 0 {
11165 self.write(", ");
11166 }
11167 self.generate_expression(expr)?;
11168 }
11169 self.write(")");
11170 }
11171 AlterTableAction::AlterIndex { name, visible } => {
11172 self.write_keyword("ALTER INDEX");
11173 self.write_space();
11174 self.generate_identifier(name)?;
11175 self.write_space();
11176 if *visible {
11177 self.write_keyword("VISIBLE");
11178 } else {
11179 self.write_keyword("INVISIBLE");
11180 }
11181 }
11182 AlterTableAction::SetAttribute { attribute } => {
11183 self.write_keyword("SET");
11184 self.write_space();
11185 self.write_keyword(attribute);
11186 }
11187 AlterTableAction::SetStageFileFormat { options } => {
11188 self.write_keyword("SET");
11189 self.write_space();
11190 self.write_keyword("STAGE_FILE_FORMAT");
11191 self.write(" = (");
11192 if let Some(opts) = options {
11193 self.generate_space_separated_properties(opts)?;
11194 }
11195 self.write(")");
11196 }
11197 AlterTableAction::SetStageCopyOptions { options } => {
11198 self.write_keyword("SET");
11199 self.write_space();
11200 self.write_keyword("STAGE_COPY_OPTIONS");
11201 self.write(" = (");
11202 if let Some(opts) = options {
11203 self.generate_space_separated_properties(opts)?;
11204 }
11205 self.write(")");
11206 }
11207 AlterTableAction::AddColumns { columns, cascade } => {
11208 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
11211 if is_oracle {
11212 self.write_keyword("ADD");
11213 } else {
11214 self.write_keyword("ADD COLUMNS");
11215 }
11216 self.write(" (");
11217 for (i, col) in columns.iter().enumerate() {
11218 if i > 0 {
11219 self.write(", ");
11220 }
11221 self.generate_column_def(col)?;
11222 }
11223 self.write(")");
11224 if *cascade {
11225 self.write_space();
11226 self.write_keyword("CASCADE");
11227 }
11228 }
11229 AlterTableAction::ChangeColumn {
11230 old_name,
11231 new_name,
11232 data_type,
11233 comment,
11234 cascade,
11235 } => {
11236 use crate::dialects::DialectType;
11237 let is_spark = matches!(
11238 self.config.dialect,
11239 Some(DialectType::Spark) | Some(DialectType::Databricks)
11240 );
11241 let is_rename = old_name.name != new_name.name;
11242
11243 if is_spark {
11244 if is_rename {
11245 self.write_keyword("RENAME COLUMN");
11247 self.write_space();
11248 self.generate_identifier(old_name)?;
11249 self.write_space();
11250 self.write_keyword("TO");
11251 self.write_space();
11252 self.generate_identifier(new_name)?;
11253 } else if comment.is_some() {
11254 self.write_keyword("ALTER COLUMN");
11256 self.write_space();
11257 self.generate_identifier(old_name)?;
11258 self.write_space();
11259 self.write_keyword("COMMENT");
11260 self.write_space();
11261 self.write("'");
11262 self.write(comment.as_ref().unwrap());
11263 self.write("'");
11264 } else if data_type.is_some() {
11265 self.write_keyword("ALTER COLUMN");
11267 self.write_space();
11268 self.generate_identifier(old_name)?;
11269 self.write_space();
11270 self.write_keyword("TYPE");
11271 self.write_space();
11272 self.generate_data_type(data_type.as_ref().unwrap())?;
11273 } else {
11274 self.write_keyword("CHANGE COLUMN");
11276 self.write_space();
11277 self.generate_identifier(old_name)?;
11278 self.write_space();
11279 self.generate_identifier(new_name)?;
11280 }
11281 } else {
11282 if data_type.is_some() {
11284 self.write_keyword("CHANGE COLUMN");
11285 } else {
11286 self.write_keyword("CHANGE");
11287 }
11288 self.write_space();
11289 self.generate_identifier(old_name)?;
11290 self.write_space();
11291 self.generate_identifier(new_name)?;
11292 if let Some(ref dt) = data_type {
11293 self.write_space();
11294 self.generate_data_type(dt)?;
11295 }
11296 if let Some(ref c) = comment {
11297 self.write_space();
11298 self.write_keyword("COMMENT");
11299 self.write_space();
11300 self.write("'");
11301 self.write(c);
11302 self.write("'");
11303 }
11304 if *cascade {
11305 self.write_space();
11306 self.write_keyword("CASCADE");
11307 }
11308 }
11309 }
11310 AlterTableAction::AddPartition {
11311 partition,
11312 if_not_exists,
11313 location,
11314 } => {
11315 self.write_keyword("ADD");
11316 self.write_space();
11317 if *if_not_exists {
11318 self.write_keyword("IF NOT EXISTS");
11319 self.write_space();
11320 }
11321 self.generate_expression(partition)?;
11322 if let Some(ref loc) = location {
11323 self.write_space();
11324 self.write_keyword("LOCATION");
11325 self.write_space();
11326 self.generate_expression(loc)?;
11327 }
11328 }
11329 AlterTableAction::AlterSortKey {
11330 this,
11331 expressions,
11332 compound,
11333 } => {
11334 self.write_keyword("ALTER");
11336 if *compound {
11337 self.write_space();
11338 self.write_keyword("COMPOUND");
11339 }
11340 self.write_space();
11341 self.write_keyword("SORTKEY");
11342 self.write_space();
11343 if let Some(style) = this {
11344 self.write_keyword(style);
11345 } else if !expressions.is_empty() {
11346 self.write("(");
11347 for (i, expr) in expressions.iter().enumerate() {
11348 if i > 0 {
11349 self.write(", ");
11350 }
11351 self.generate_expression(expr)?;
11352 }
11353 self.write(")");
11354 }
11355 }
11356 AlterTableAction::AlterDistStyle { style, distkey } => {
11357 self.write_keyword("ALTER");
11359 self.write_space();
11360 self.write_keyword("DISTSTYLE");
11361 self.write_space();
11362 self.write_keyword(style);
11363 if let Some(col) = distkey {
11364 self.write_space();
11365 self.write_keyword("DISTKEY");
11366 self.write_space();
11367 self.generate_identifier(col)?;
11368 }
11369 }
11370 AlterTableAction::SetTableProperties { properties } => {
11371 self.write_keyword("SET TABLE PROPERTIES");
11373 self.write(" (");
11374 for (i, (key, value)) in properties.iter().enumerate() {
11375 if i > 0 {
11376 self.write(", ");
11377 }
11378 self.generate_expression(key)?;
11379 self.write(" = ");
11380 self.generate_expression(value)?;
11381 }
11382 self.write(")");
11383 }
11384 AlterTableAction::SetLocation { location } => {
11385 self.write_keyword("SET LOCATION");
11387 self.write_space();
11388 self.write("'");
11389 self.write(location);
11390 self.write("'");
11391 }
11392 AlterTableAction::SetFileFormat { format } => {
11393 self.write_keyword("SET FILE FORMAT");
11395 self.write_space();
11396 self.write_keyword(format);
11397 }
11398 AlterTableAction::ReplacePartition { partition, source } => {
11399 self.write_keyword("REPLACE PARTITION");
11401 self.write_space();
11402 self.generate_expression(partition)?;
11403 if let Some(src) = source {
11404 self.write_space();
11405 self.write_keyword("FROM");
11406 self.write_space();
11407 self.generate_expression(src)?;
11408 }
11409 }
11410 AlterTableAction::Raw { sql } => {
11411 self.write(sql);
11412 }
11413 }
11414 Ok(())
11415 }
11416
11417 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
11418 match action {
11419 AlterColumnAction::SetDataType {
11420 data_type,
11421 using,
11422 collate,
11423 } => {
11424 use crate::dialects::DialectType;
11425 let is_no_prefix = matches!(
11430 self.config.dialect,
11431 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
11432 );
11433 let is_type_only = matches!(
11434 self.config.dialect,
11435 Some(DialectType::Redshift)
11436 | Some(DialectType::Spark)
11437 | Some(DialectType::Databricks)
11438 );
11439 if is_type_only {
11440 self.write_keyword("TYPE");
11441 self.write_space();
11442 } else if !is_no_prefix {
11443 self.write_keyword("SET DATA TYPE");
11444 self.write_space();
11445 }
11446 self.generate_data_type(data_type)?;
11447 if let Some(ref collation) = collate {
11448 self.write_space();
11449 self.write_keyword("COLLATE");
11450 self.write_space();
11451 self.write(collation);
11452 }
11453 if let Some(ref using_expr) = using {
11454 self.write_space();
11455 self.write_keyword("USING");
11456 self.write_space();
11457 self.generate_expression(using_expr)?;
11458 }
11459 }
11460 AlterColumnAction::SetDefault(expr) => {
11461 self.write_keyword("SET DEFAULT");
11462 self.write_space();
11463 self.generate_expression(expr)?;
11464 }
11465 AlterColumnAction::DropDefault => {
11466 self.write_keyword("DROP DEFAULT");
11467 }
11468 AlterColumnAction::SetNotNull => {
11469 self.write_keyword("SET NOT NULL");
11470 }
11471 AlterColumnAction::DropNotNull => {
11472 self.write_keyword("DROP NOT NULL");
11473 }
11474 AlterColumnAction::Comment(comment) => {
11475 self.write_keyword("COMMENT");
11476 self.write_space();
11477 self.generate_string_literal(comment)?;
11478 }
11479 AlterColumnAction::SetVisible => {
11480 self.write_keyword("SET VISIBLE");
11481 }
11482 AlterColumnAction::SetInvisible => {
11483 self.write_keyword("SET INVISIBLE");
11484 }
11485 }
11486 Ok(())
11487 }
11488
11489 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
11490 self.write_keyword("CREATE");
11491
11492 if ci.unique {
11493 self.write_space();
11494 self.write_keyword("UNIQUE");
11495 }
11496
11497 if let Some(ref clustered) = ci.clustered {
11499 self.write_space();
11500 self.write_keyword(clustered);
11501 }
11502
11503 self.write_space();
11504 self.write_keyword("INDEX");
11505
11506 if ci.concurrently {
11508 self.write_space();
11509 self.write_keyword("CONCURRENTLY");
11510 }
11511
11512 if ci.if_not_exists {
11513 self.write_space();
11514 self.write_keyword("IF NOT EXISTS");
11515 }
11516
11517 if !ci.name.name.is_empty() {
11519 self.write_space();
11520 self.generate_identifier(&ci.name)?;
11521 }
11522 self.write_space();
11523 self.write_keyword("ON");
11524 if matches!(self.config.dialect, Some(DialectType::Hive)) {
11526 self.write_space();
11527 self.write_keyword("TABLE");
11528 }
11529 self.write_space();
11530 self.generate_table(&ci.table)?;
11531
11532 if !ci.columns.is_empty() || ci.using.is_some() {
11535 let space_before_paren = false;
11536
11537 if let Some(ref using) = ci.using {
11538 self.write_space();
11539 self.write_keyword("USING");
11540 self.write_space();
11541 self.write(using);
11542 if space_before_paren {
11543 self.write(" (");
11544 } else {
11545 self.write("(");
11546 }
11547 } else {
11548 if space_before_paren {
11549 self.write(" (");
11550 } else {
11551 self.write("(");
11552 }
11553 }
11554 for (i, col) in ci.columns.iter().enumerate() {
11555 if i > 0 {
11556 self.write(", ");
11557 }
11558 self.generate_identifier(&col.column)?;
11559 if let Some(ref opclass) = col.opclass {
11560 self.write_space();
11561 self.write(opclass);
11562 }
11563 if col.desc {
11564 self.write_space();
11565 self.write_keyword("DESC");
11566 } else if col.asc {
11567 self.write_space();
11568 self.write_keyword("ASC");
11569 }
11570 if let Some(nulls_first) = col.nulls_first {
11571 self.write_space();
11572 self.write_keyword("NULLS");
11573 self.write_space();
11574 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
11575 }
11576 }
11577 self.write(")");
11578 }
11579
11580 if !ci.include_columns.is_empty() {
11582 self.write_space();
11583 self.write_keyword("INCLUDE");
11584 self.write(" (");
11585 for (i, col) in ci.include_columns.iter().enumerate() {
11586 if i > 0 {
11587 self.write(", ");
11588 }
11589 self.generate_identifier(col)?;
11590 }
11591 self.write(")");
11592 }
11593
11594 if !ci.with_options.is_empty() {
11596 self.write_space();
11597 self.write_keyword("WITH");
11598 self.write(" (");
11599 for (i, (key, value)) in ci.with_options.iter().enumerate() {
11600 if i > 0 {
11601 self.write(", ");
11602 }
11603 self.write(key);
11604 self.write("=");
11605 self.write(value);
11606 }
11607 self.write(")");
11608 }
11609
11610 if let Some(ref where_clause) = ci.where_clause {
11612 self.write_space();
11613 self.write_keyword("WHERE");
11614 self.write_space();
11615 self.generate_expression(where_clause)?;
11616 }
11617
11618 if let Some(ref on_fg) = ci.on_filegroup {
11620 self.write_space();
11621 self.write_keyword("ON");
11622 self.write_space();
11623 self.write(on_fg);
11624 }
11625
11626 Ok(())
11627 }
11628
11629 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
11630 self.write_keyword("DROP INDEX");
11631
11632 if di.concurrently {
11633 self.write_space();
11634 self.write_keyword("CONCURRENTLY");
11635 }
11636
11637 if di.if_exists {
11638 self.write_space();
11639 self.write_keyword("IF EXISTS");
11640 }
11641
11642 self.write_space();
11643 self.generate_table(&di.name)?;
11644
11645 if let Some(ref table) = di.table {
11646 self.write_space();
11647 self.write_keyword("ON");
11648 self.write_space();
11649 self.generate_table(table)?;
11650 }
11651
11652 Ok(())
11653 }
11654
11655 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
11656 self.write_keyword("CREATE");
11657
11658 if let Some(ref algorithm) = cv.algorithm {
11660 self.write_space();
11661 self.write_keyword("ALGORITHM");
11662 self.write("=");
11663 self.write_keyword(algorithm);
11664 }
11665
11666 if let Some(ref definer) = cv.definer {
11668 self.write_space();
11669 self.write_keyword("DEFINER");
11670 self.write("=");
11671 self.write(definer);
11672 }
11673
11674 if cv.security_sql_style && !cv.security_after_name {
11676 if let Some(ref security) = cv.security {
11677 self.write_space();
11678 self.write_keyword("SQL SECURITY");
11679 self.write_space();
11680 match security {
11681 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11682 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11683 FunctionSecurity::None => self.write_keyword("NONE"),
11684 }
11685 }
11686 }
11687
11688 if cv.or_alter {
11689 self.write_space();
11690 self.write_keyword("OR ALTER");
11691 } else if cv.or_replace {
11692 self.write_space();
11693 self.write_keyword("OR REPLACE");
11694 }
11695
11696 if cv.temporary {
11697 self.write_space();
11698 self.write_keyword("TEMPORARY");
11699 }
11700
11701 if cv.materialized {
11702 self.write_space();
11703 self.write_keyword("MATERIALIZED");
11704 }
11705
11706 if cv.secure {
11708 self.write_space();
11709 self.write_keyword("SECURE");
11710 }
11711
11712 self.write_space();
11713 self.write_keyword("VIEW");
11714
11715 if cv.if_not_exists {
11716 self.write_space();
11717 self.write_keyword("IF NOT EXISTS");
11718 }
11719
11720 self.write_space();
11721 self.generate_table(&cv.name)?;
11722
11723 if let Some(ref on_cluster) = cv.on_cluster {
11725 self.write_space();
11726 self.generate_on_cluster(on_cluster)?;
11727 }
11728
11729 if let Some(ref to_table) = cv.to_table {
11731 self.write_space();
11732 self.write_keyword("TO");
11733 self.write_space();
11734 self.generate_table(to_table)?;
11735 }
11736
11737 if !cv.materialized {
11740 if let Some(ref schema) = cv.schema {
11742 self.write(" (");
11743 for (i, expr) in schema.expressions.iter().enumerate() {
11744 if i > 0 {
11745 self.write(", ");
11746 }
11747 self.generate_expression(expr)?;
11748 }
11749 self.write(")");
11750 } else if !cv.columns.is_empty() {
11751 self.write(" (");
11752 for (i, col) in cv.columns.iter().enumerate() {
11753 if i > 0 {
11754 self.write(", ");
11755 }
11756 self.generate_identifier(&col.name)?;
11757 if !col.options.is_empty() {
11759 self.write_space();
11760 self.generate_options_clause(&col.options)?;
11761 }
11762 if let Some(ref comment) = col.comment {
11763 self.write_space();
11764 self.write_keyword("COMMENT");
11765 self.write_space();
11766 self.generate_string_literal(comment)?;
11767 }
11768 }
11769 self.write(")");
11770 }
11771
11772 if !cv.security_sql_style || cv.security_after_name {
11775 if let Some(ref security) = cv.security {
11776 self.write_space();
11777 if cv.security_sql_style {
11778 self.write_keyword("SQL SECURITY");
11779 } else {
11780 self.write_keyword("SECURITY");
11781 }
11782 self.write_space();
11783 match security {
11784 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11785 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11786 FunctionSecurity::None => self.write_keyword("NONE"),
11787 }
11788 }
11789 }
11790
11791 if cv.copy_grants {
11793 self.write_space();
11794 self.write_keyword("COPY GRANTS");
11795 }
11796 } else {
11797 if cv.copy_grants {
11799 self.write_space();
11800 self.write_keyword("COPY GRANTS");
11801 }
11802
11803 if let Some(ref schema) = cv.schema {
11805 self.write(" (");
11806 for (i, expr) in schema.expressions.iter().enumerate() {
11807 if i > 0 {
11808 self.write(", ");
11809 }
11810 self.generate_expression(expr)?;
11811 }
11812 self.write(")");
11813 } else if !cv.columns.is_empty() {
11814 self.write(" (");
11816 for (i, col) in cv.columns.iter().enumerate() {
11817 if i > 0 {
11818 self.write(", ");
11819 }
11820 self.generate_identifier(&col.name)?;
11821 if !col.options.is_empty() {
11823 self.write_space();
11824 self.generate_options_clause(&col.options)?;
11825 }
11826 if let Some(ref comment) = col.comment {
11827 self.write_space();
11828 self.write_keyword("COMMENT");
11829 self.write_space();
11830 self.generate_string_literal(comment)?;
11831 }
11832 }
11833 self.write(")");
11834 }
11835
11836 if let Some(ref unique_key) = cv.unique_key {
11838 self.write_space();
11839 self.write_keyword("KEY");
11840 self.write(" (");
11841 for (i, expr) in unique_key.expressions.iter().enumerate() {
11842 if i > 0 {
11843 self.write(", ");
11844 }
11845 self.generate_expression(expr)?;
11846 }
11847 self.write(")");
11848 }
11849 }
11850
11851 if let Some(ref row_access_policy) = cv.row_access_policy {
11852 self.write_space();
11853 self.write_keyword("WITH");
11854 self.write_space();
11855 self.write(row_access_policy);
11856 }
11857
11858 if let Some(ref comment) = cv.comment {
11860 self.write_space();
11861 self.write_keyword("COMMENT");
11862 self.write("=");
11863 self.generate_string_literal(comment)?;
11864 }
11865
11866 if !cv.tags.is_empty() {
11868 self.write_space();
11869 self.write_keyword("TAG");
11870 self.write(" (");
11871 for (i, (name, value)) in cv.tags.iter().enumerate() {
11872 if i > 0 {
11873 self.write(", ");
11874 }
11875 self.write(name);
11876 self.write("='");
11877 self.write(value);
11878 self.write("'");
11879 }
11880 self.write(")");
11881 }
11882
11883 if !cv.options.is_empty() {
11885 self.write_space();
11886 self.generate_options_clause(&cv.options)?;
11887 }
11888
11889 if let Some(ref build) = cv.build {
11891 self.write_space();
11892 self.write_keyword("BUILD");
11893 self.write_space();
11894 self.write_keyword(build);
11895 }
11896
11897 if let Some(ref refresh) = cv.refresh {
11899 self.write_space();
11900 self.generate_refresh_trigger_property(refresh)?;
11901 }
11902
11903 if let Some(auto_refresh) = cv.auto_refresh {
11905 self.write_space();
11906 self.write_keyword("AUTO REFRESH");
11907 self.write_space();
11908 if auto_refresh {
11909 self.write_keyword("YES");
11910 } else {
11911 self.write_keyword("NO");
11912 }
11913 }
11914
11915 for prop in &cv.table_properties {
11917 self.write_space();
11918 self.generate_expression(prop)?;
11919 }
11920
11921 if let Some(ref population) = cv.clickhouse_population {
11923 self.write_space();
11924 self.write_keyword(population);
11925 }
11926
11927 if !matches!(&cv.query, Expression::Null(_)) {
11929 self.write_space();
11930 self.write_keyword("AS");
11931 self.write_space();
11932
11933 if let Some(ref mode) = cv.locking_mode {
11935 self.write_keyword("LOCKING");
11936 self.write_space();
11937 self.write_keyword(mode);
11938 if let Some(ref access) = cv.locking_access {
11939 self.write_space();
11940 self.write_keyword("FOR");
11941 self.write_space();
11942 self.write_keyword(access);
11943 }
11944 self.write_space();
11945 }
11946
11947 if cv.query_parenthesized {
11948 self.write("(");
11949 }
11950 self.generate_expression(&cv.query)?;
11951 if cv.query_parenthesized {
11952 self.write(")");
11953 }
11954 }
11955
11956 if cv.no_schema_binding {
11958 self.write_space();
11959 self.write_keyword("WITH NO SCHEMA BINDING");
11960 }
11961
11962 Ok(())
11963 }
11964
11965 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
11966 self.write_keyword("DROP");
11967
11968 if dv.materialized {
11969 self.write_space();
11970 self.write_keyword("MATERIALIZED");
11971 }
11972
11973 self.write_space();
11974 self.write_keyword("VIEW");
11975
11976 if dv.if_exists {
11977 self.write_space();
11978 self.write_keyword("IF EXISTS");
11979 }
11980
11981 self.write_space();
11982 self.generate_table(&dv.name)?;
11983
11984 Ok(())
11985 }
11986
11987 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
11988 match tr.target {
11989 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
11990 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
11991 }
11992 if tr.if_exists {
11993 self.write_space();
11994 self.write_keyword("IF EXISTS");
11995 }
11996 self.write_space();
11997 self.generate_table(&tr.table)?;
11998
11999 if let Some(ref on_cluster) = tr.on_cluster {
12001 self.write_space();
12002 self.generate_on_cluster(on_cluster)?;
12003 }
12004
12005 if !tr.extra_tables.is_empty() {
12007 let skip_first = if let Some(first) = tr.extra_tables.first() {
12009 first.table.name == tr.table.name && first.star
12010 } else {
12011 false
12012 };
12013
12014 let strip_star = matches!(
12016 self.config.dialect,
12017 Some(crate::dialects::DialectType::PostgreSQL)
12018 | Some(crate::dialects::DialectType::Redshift)
12019 );
12020 if skip_first && !strip_star {
12021 self.write("*");
12022 }
12023
12024 for (i, entry) in tr.extra_tables.iter().enumerate() {
12026 if i == 0 && skip_first {
12027 continue; }
12029 self.write(", ");
12030 self.generate_table(&entry.table)?;
12031 if entry.star && !strip_star {
12032 self.write("*");
12033 }
12034 }
12035 }
12036
12037 if let Some(identity) = &tr.identity {
12039 self.write_space();
12040 match identity {
12041 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
12042 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
12043 }
12044 }
12045
12046 if tr.cascade {
12047 self.write_space();
12048 self.write_keyword("CASCADE");
12049 }
12050
12051 if tr.restrict {
12052 self.write_space();
12053 self.write_keyword("RESTRICT");
12054 }
12055
12056 if let Some(ref partition) = tr.partition {
12058 self.write_space();
12059 self.generate_expression(partition)?;
12060 }
12061
12062 Ok(())
12063 }
12064
12065 fn generate_use(&mut self, u: &Use) -> Result<()> {
12066 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
12068 self.write_keyword("DATABASE");
12069 self.write_space();
12070 self.generate_identifier(&u.this)?;
12071 return Ok(());
12072 }
12073
12074 self.write_keyword("USE");
12075
12076 if let Some(kind) = &u.kind {
12077 self.write_space();
12078 match kind {
12079 UseKind::Database => self.write_keyword("DATABASE"),
12080 UseKind::Schema => self.write_keyword("SCHEMA"),
12081 UseKind::Role => self.write_keyword("ROLE"),
12082 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
12083 UseKind::Catalog => self.write_keyword("CATALOG"),
12084 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
12085 }
12086 }
12087
12088 self.write_space();
12089 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
12092 self.write(&u.this.name);
12093 } else {
12094 self.generate_identifier(&u.this)?;
12095 }
12096 Ok(())
12097 }
12098
12099 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
12100 self.write_keyword("CACHE");
12101 if c.lazy {
12102 self.write_space();
12103 self.write_keyword("LAZY");
12104 }
12105 self.write_space();
12106 self.write_keyword("TABLE");
12107 self.write_space();
12108 self.generate_identifier(&c.table)?;
12109
12110 if !c.options.is_empty() {
12112 self.write_space();
12113 self.write_keyword("OPTIONS");
12114 self.write("(");
12115 for (i, (key, value)) in c.options.iter().enumerate() {
12116 if i > 0 {
12117 self.write(", ");
12118 }
12119 self.generate_expression(key)?;
12120 self.write(" = ");
12121 self.generate_expression(value)?;
12122 }
12123 self.write(")");
12124 }
12125
12126 if let Some(query) = &c.query {
12128 self.write_space();
12129 self.write_keyword("AS");
12130 self.write_space();
12131 self.generate_expression(query)?;
12132 }
12133
12134 Ok(())
12135 }
12136
12137 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
12138 self.write_keyword("UNCACHE TABLE");
12139 if u.if_exists {
12140 self.write_space();
12141 self.write_keyword("IF EXISTS");
12142 }
12143 self.write_space();
12144 self.generate_identifier(&u.table)?;
12145 Ok(())
12146 }
12147
12148 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
12149 self.write_keyword("LOAD DATA");
12150 if l.local {
12151 self.write_space();
12152 self.write_keyword("LOCAL");
12153 }
12154 self.write_space();
12155 self.write_keyword("INPATH");
12156 self.write_space();
12157 self.write("'");
12158 self.write(&l.inpath);
12159 self.write("'");
12160
12161 if l.overwrite {
12162 self.write_space();
12163 self.write_keyword("OVERWRITE");
12164 }
12165
12166 self.write_space();
12167 self.write_keyword("INTO TABLE");
12168 self.write_space();
12169 self.generate_expression(&l.table)?;
12170
12171 if !l.partition.is_empty() {
12173 self.write_space();
12174 self.write_keyword("PARTITION");
12175 self.write("(");
12176 for (i, (col, val)) in l.partition.iter().enumerate() {
12177 if i > 0 {
12178 self.write(", ");
12179 }
12180 self.generate_identifier(col)?;
12181 self.write(" = ");
12182 self.generate_expression(val)?;
12183 }
12184 self.write(")");
12185 }
12186
12187 if let Some(fmt) = &l.input_format {
12189 self.write_space();
12190 self.write_keyword("INPUTFORMAT");
12191 self.write_space();
12192 self.write("'");
12193 self.write(fmt);
12194 self.write("'");
12195 }
12196
12197 if let Some(serde) = &l.serde {
12199 self.write_space();
12200 self.write_keyword("SERDE");
12201 self.write_space();
12202 self.write("'");
12203 self.write(serde);
12204 self.write("'");
12205 }
12206
12207 Ok(())
12208 }
12209
12210 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
12211 self.write_keyword("PRAGMA");
12212 self.write_space();
12213
12214 if let Some(schema) = &p.schema {
12216 self.generate_identifier(schema)?;
12217 self.write(".");
12218 }
12219
12220 self.generate_identifier(&p.name)?;
12222
12223 if p.use_assignment_syntax {
12225 self.write(" = ");
12226 if let Some(value) = &p.value {
12227 self.generate_expression(value)?;
12228 } else if let Some(arg) = p.args.first() {
12229 self.generate_expression(arg)?;
12230 }
12231 } else if !p.args.is_empty() {
12232 self.write("(");
12233 for (i, arg) in p.args.iter().enumerate() {
12234 if i > 0 {
12235 self.write(", ");
12236 }
12237 self.generate_expression(arg)?;
12238 }
12239 self.write(")");
12240 }
12241
12242 Ok(())
12243 }
12244
12245 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
12246 self.write_keyword("GRANT");
12247 self.write_space();
12248
12249 for (i, privilege) in g.privileges.iter().enumerate() {
12251 if i > 0 {
12252 self.write(", ");
12253 }
12254 self.write_keyword(&privilege.name);
12255 if !privilege.columns.is_empty() {
12257 self.write("(");
12258 for (j, col) in privilege.columns.iter().enumerate() {
12259 if j > 0 {
12260 self.write(", ");
12261 }
12262 self.write(col);
12263 }
12264 self.write(")");
12265 }
12266 }
12267
12268 self.write_space();
12269 self.write_keyword("ON");
12270 self.write_space();
12271
12272 if let Some(kind) = &g.kind {
12274 self.write_keyword(kind);
12275 self.write_space();
12276 }
12277
12278 {
12280 use crate::dialects::DialectType;
12281 let should_upper = matches!(
12282 self.config.dialect,
12283 Some(DialectType::PostgreSQL)
12284 | Some(DialectType::CockroachDB)
12285 | Some(DialectType::Materialize)
12286 | Some(DialectType::RisingWave)
12287 ) && (g.kind.as_deref() == Some("FUNCTION")
12288 || g.kind.as_deref() == Some("PROCEDURE"));
12289 if should_upper {
12290 use crate::expressions::Identifier;
12291 let upper_id = Identifier {
12292 name: g.securable.name.to_ascii_uppercase(),
12293 quoted: g.securable.quoted,
12294 ..g.securable.clone()
12295 };
12296 self.generate_identifier(&upper_id)?;
12297 } else {
12298 self.generate_identifier(&g.securable)?;
12299 }
12300 }
12301
12302 if !g.function_params.is_empty() {
12304 self.write("(");
12305 for (i, param) in g.function_params.iter().enumerate() {
12306 if i > 0 {
12307 self.write(", ");
12308 }
12309 self.write(param);
12310 }
12311 self.write(")");
12312 }
12313
12314 self.write_space();
12315 self.write_keyword("TO");
12316 self.write_space();
12317
12318 for (i, principal) in g.principals.iter().enumerate() {
12320 if i > 0 {
12321 self.write(", ");
12322 }
12323 if principal.is_role {
12324 self.write_keyword("ROLE");
12325 self.write_space();
12326 } else if principal.is_group {
12327 self.write_keyword("GROUP");
12328 self.write_space();
12329 } else if principal.is_share {
12330 self.write_keyword("SHARE");
12331 self.write_space();
12332 }
12333 self.generate_identifier(&principal.name)?;
12334 }
12335
12336 if g.grant_option {
12338 self.write_space();
12339 self.write_keyword("WITH GRANT OPTION");
12340 }
12341
12342 if let Some(ref principal) = g.as_principal {
12344 self.write_space();
12345 self.write_keyword("AS");
12346 self.write_space();
12347 self.generate_identifier(principal)?;
12348 }
12349
12350 Ok(())
12351 }
12352
12353 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
12354 self.write_keyword("REVOKE");
12355 self.write_space();
12356
12357 if r.grant_option {
12359 self.write_keyword("GRANT OPTION FOR");
12360 self.write_space();
12361 }
12362
12363 for (i, privilege) in r.privileges.iter().enumerate() {
12365 if i > 0 {
12366 self.write(", ");
12367 }
12368 self.write_keyword(&privilege.name);
12369 if !privilege.columns.is_empty() {
12371 self.write("(");
12372 for (j, col) in privilege.columns.iter().enumerate() {
12373 if j > 0 {
12374 self.write(", ");
12375 }
12376 self.write(col);
12377 }
12378 self.write(")");
12379 }
12380 }
12381
12382 self.write_space();
12383 self.write_keyword("ON");
12384 self.write_space();
12385
12386 if let Some(kind) = &r.kind {
12388 self.write_keyword(kind);
12389 self.write_space();
12390 }
12391
12392 {
12394 use crate::dialects::DialectType;
12395 let should_upper = matches!(
12396 self.config.dialect,
12397 Some(DialectType::PostgreSQL)
12398 | Some(DialectType::CockroachDB)
12399 | Some(DialectType::Materialize)
12400 | Some(DialectType::RisingWave)
12401 ) && (r.kind.as_deref() == Some("FUNCTION")
12402 || r.kind.as_deref() == Some("PROCEDURE"));
12403 if should_upper {
12404 use crate::expressions::Identifier;
12405 let upper_id = Identifier {
12406 name: r.securable.name.to_ascii_uppercase(),
12407 quoted: r.securable.quoted,
12408 ..r.securable.clone()
12409 };
12410 self.generate_identifier(&upper_id)?;
12411 } else {
12412 self.generate_identifier(&r.securable)?;
12413 }
12414 }
12415
12416 if !r.function_params.is_empty() {
12418 self.write("(");
12419 for (i, param) in r.function_params.iter().enumerate() {
12420 if i > 0 {
12421 self.write(", ");
12422 }
12423 self.write(param);
12424 }
12425 self.write(")");
12426 }
12427
12428 self.write_space();
12429 self.write_keyword("FROM");
12430 self.write_space();
12431
12432 for (i, principal) in r.principals.iter().enumerate() {
12434 if i > 0 {
12435 self.write(", ");
12436 }
12437 if principal.is_role {
12438 self.write_keyword("ROLE");
12439 self.write_space();
12440 } else if principal.is_group {
12441 self.write_keyword("GROUP");
12442 self.write_space();
12443 } else if principal.is_share {
12444 self.write_keyword("SHARE");
12445 self.write_space();
12446 }
12447 self.generate_identifier(&principal.name)?;
12448 }
12449
12450 if r.cascade {
12452 self.write_space();
12453 self.write_keyword("CASCADE");
12454 } else if r.restrict {
12455 self.write_space();
12456 self.write_keyword("RESTRICT");
12457 }
12458
12459 Ok(())
12460 }
12461
12462 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
12463 self.write_keyword("COMMENT");
12464
12465 if c.exists {
12467 self.write_space();
12468 self.write_keyword("IF EXISTS");
12469 }
12470
12471 self.write_space();
12472 self.write_keyword("ON");
12473
12474 if c.materialized {
12476 self.write_space();
12477 self.write_keyword("MATERIALIZED");
12478 }
12479
12480 self.write_space();
12481 self.write_keyword(&c.kind);
12482 self.write_space();
12483
12484 self.generate_expression(&c.this)?;
12486
12487 self.write_space();
12488 self.write_keyword("IS");
12489 self.write_space();
12490
12491 self.generate_expression(&c.expression)?;
12493
12494 Ok(())
12495 }
12496
12497 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
12498 self.write_keyword("SET");
12499
12500 for (i, item) in s.items.iter().enumerate() {
12501 if i > 0 {
12502 self.write(",");
12503 }
12504 self.write_space();
12505
12506 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
12508 if let Some(ref kind) = item.kind {
12509 if has_variable_kind {
12513 if matches!(
12514 self.config.dialect,
12515 Some(DialectType::Spark | DialectType::Databricks | DialectType::DuckDB)
12516 ) {
12517 self.write_keyword("VARIABLE");
12518 self.write_space();
12519 }
12520 } else {
12521 self.write_keyword(kind);
12522 self.write_space();
12523 }
12524 }
12525
12526 let name_str = match &item.name {
12528 Expression::Identifier(id) => Some(id.name.as_str()),
12529 _ => None,
12530 };
12531
12532 let is_transaction = name_str == Some("TRANSACTION");
12533 let is_character_set = name_str == Some("CHARACTER SET");
12534 let is_names = name_str == Some("NAMES");
12535 let is_collate = name_str == Some("COLLATE");
12536 let is_identity_insert = name_str == Some("IDENTITY_INSERT");
12537 let is_value_only =
12538 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
12539
12540 if is_transaction {
12541 self.write_keyword("TRANSACTION");
12543 if let Expression::Identifier(id) = &item.value {
12544 if !id.name.is_empty() {
12545 self.write_space();
12546 self.write(&id.name);
12547 }
12548 }
12549 } else if is_character_set {
12550 self.write_keyword("CHARACTER SET");
12552 self.write_space();
12553 self.generate_set_value(&item.value)?;
12554 } else if is_names {
12555 self.write_keyword("NAMES");
12557 self.write_space();
12558 self.generate_set_value(&item.value)?;
12559 } else if is_collate {
12560 self.write_keyword("COLLATE");
12562 self.write_space();
12563 self.generate_set_value(&item.value)?;
12564 } else if is_identity_insert {
12565 self.write_keyword("IDENTITY_INSERT");
12567 self.write_space();
12568 self.generate_identity_insert_value(&item.value)?;
12569 } else if has_variable_kind {
12570 if let Some(ns) = name_str {
12573 self.write(ns);
12574 } else {
12575 self.generate_expression(&item.name)?;
12576 }
12577 self.write(" = ");
12578 self.generate_set_value(&item.value)?;
12579 } else if is_value_only {
12580 self.generate_expression(&item.name)?;
12582 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
12583 self.generate_expression(&item.name)?;
12585 self.write_space();
12586 self.generate_set_value(&item.value)?;
12587 } else {
12588 match &item.name {
12591 Expression::Identifier(id) => {
12592 self.write(&id.name);
12593 }
12594 _ => {
12595 self.generate_expression(&item.name)?;
12596 }
12597 }
12598 self.write(" = ");
12599 self.generate_set_value(&item.value)?;
12600 }
12601 }
12602
12603 Ok(())
12604 }
12605
12606 fn generate_identity_insert_value(&mut self, value: &Expression) -> Result<()> {
12607 if let Expression::Tuple(tuple) = value {
12608 if tuple.expressions.len() == 2 {
12609 self.generate_expression(&tuple.expressions[0])?;
12610 self.write_space();
12611 self.generate_set_value(&tuple.expressions[1])?;
12612 return Ok(());
12613 }
12614 }
12615
12616 self.generate_set_value(value)
12617 }
12618
12619 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
12622 if let Expression::Identifier(id) = value {
12623 match id.name.as_str() {
12624 "DEFAULT" | "ON" | "OFF" => {
12625 self.write_keyword(&id.name);
12626 return Ok(());
12627 }
12628 _ => {}
12629 }
12630 }
12631 self.generate_expression(value)
12632 }
12633
12634 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
12637 self.write_keyword("ALTER");
12638 if let Some(ref algorithm) = av.algorithm {
12640 self.write_space();
12641 self.write_keyword("ALGORITHM");
12642 self.write(" = ");
12643 self.write_keyword(algorithm);
12644 }
12645 if let Some(ref definer) = av.definer {
12646 self.write_space();
12647 self.write_keyword("DEFINER");
12648 self.write(" = ");
12649 self.write(definer);
12650 }
12651 if let Some(ref sql_security) = av.sql_security {
12652 self.write_space();
12653 self.write_keyword("SQL SECURITY");
12654 self.write(" = ");
12655 self.write_keyword(sql_security);
12656 }
12657 self.write_space();
12658 self.write_keyword("VIEW");
12659 self.write_space();
12660 self.generate_table(&av.name)?;
12661
12662 if !av.columns.is_empty() {
12664 self.write(" (");
12665 for (i, col) in av.columns.iter().enumerate() {
12666 if i > 0 {
12667 self.write(", ");
12668 }
12669 self.generate_identifier(&col.name)?;
12670 if let Some(ref comment) = col.comment {
12671 self.write_space();
12672 self.write_keyword("COMMENT");
12673 self.write(" ");
12674 self.generate_string_literal(comment)?;
12675 }
12676 }
12677 self.write(")");
12678 }
12679
12680 if let Some(ref opt) = av.with_option {
12682 self.write_space();
12683 self.write_keyword("WITH");
12684 self.write_space();
12685 self.write_keyword(opt);
12686 }
12687
12688 for action in &av.actions {
12689 self.write_space();
12690 match action {
12691 AlterViewAction::Rename(new_name) => {
12692 self.write_keyword("RENAME TO");
12693 self.write_space();
12694 self.generate_table(new_name)?;
12695 }
12696 AlterViewAction::OwnerTo(owner) => {
12697 self.write_keyword("OWNER TO");
12698 self.write_space();
12699 self.generate_identifier(owner)?;
12700 }
12701 AlterViewAction::SetSchema(schema) => {
12702 self.write_keyword("SET SCHEMA");
12703 self.write_space();
12704 self.generate_identifier(schema)?;
12705 }
12706 AlterViewAction::SetAuthorization(auth) => {
12707 self.write_keyword("SET AUTHORIZATION");
12708 self.write_space();
12709 self.write(auth);
12710 }
12711 AlterViewAction::AlterColumn { name, action } => {
12712 self.write_keyword("ALTER COLUMN");
12713 self.write_space();
12714 self.generate_identifier(name)?;
12715 self.write_space();
12716 self.generate_alter_column_action(action)?;
12717 }
12718 AlterViewAction::AsSelect(query) => {
12719 self.write_keyword("AS");
12720 self.write_space();
12721 self.generate_expression(query)?;
12722 }
12723 AlterViewAction::SetTblproperties(props) => {
12724 self.write_keyword("SET TBLPROPERTIES");
12725 self.write(" (");
12726 for (i, (key, value)) in props.iter().enumerate() {
12727 if i > 0 {
12728 self.write(", ");
12729 }
12730 self.generate_string_literal(key)?;
12731 self.write("=");
12732 self.generate_string_literal(value)?;
12733 }
12734 self.write(")");
12735 }
12736 AlterViewAction::UnsetTblproperties(keys) => {
12737 self.write_keyword("UNSET TBLPROPERTIES");
12738 self.write(" (");
12739 for (i, key) in keys.iter().enumerate() {
12740 if i > 0 {
12741 self.write(", ");
12742 }
12743 self.generate_string_literal(key)?;
12744 }
12745 self.write(")");
12746 }
12747 }
12748 }
12749
12750 Ok(())
12751 }
12752
12753 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
12754 self.write_keyword("ALTER INDEX");
12755 self.write_space();
12756 self.generate_identifier(&ai.name)?;
12757
12758 if let Some(table) = &ai.table {
12759 self.write_space();
12760 self.write_keyword("ON");
12761 self.write_space();
12762 self.generate_table(table)?;
12763 }
12764
12765 for action in &ai.actions {
12766 self.write_space();
12767 match action {
12768 AlterIndexAction::Rename(new_name) => {
12769 self.write_keyword("RENAME TO");
12770 self.write_space();
12771 self.generate_identifier(new_name)?;
12772 }
12773 AlterIndexAction::SetTablespace(tablespace) => {
12774 self.write_keyword("SET TABLESPACE");
12775 self.write_space();
12776 self.generate_identifier(tablespace)?;
12777 }
12778 AlterIndexAction::Visible(visible) => {
12779 if *visible {
12780 self.write_keyword("VISIBLE");
12781 } else {
12782 self.write_keyword("INVISIBLE");
12783 }
12784 }
12785 }
12786 }
12787
12788 Ok(())
12789 }
12790
12791 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
12792 for comment in &cs.leading_comments {
12794 self.write_formatted_comment(comment);
12795 self.write_space();
12796 }
12797
12798 let saved_athena_hive_context = self.athena_hive_context;
12800 if matches!(
12801 self.config.dialect,
12802 Some(crate::dialects::DialectType::Athena)
12803 ) {
12804 self.athena_hive_context = true;
12805 }
12806
12807 self.write_keyword("CREATE SCHEMA");
12808
12809 if cs.if_not_exists {
12810 self.write_space();
12811 self.write_keyword("IF NOT EXISTS");
12812 }
12813
12814 self.write_space();
12815 for (i, part) in cs.name.iter().enumerate() {
12816 if i > 0 {
12817 self.write(".");
12818 }
12819 self.generate_identifier(part)?;
12820 }
12821
12822 if let Some(ref clone_parts) = cs.clone_from {
12823 self.write_keyword(" CLONE ");
12824 for (i, part) in clone_parts.iter().enumerate() {
12825 if i > 0 {
12826 self.write(".");
12827 }
12828 self.generate_identifier(part)?;
12829 }
12830 }
12831
12832 if let Some(ref at_clause) = cs.at_clause {
12833 self.write_space();
12834 self.generate_expression(at_clause)?;
12835 }
12836
12837 if let Some(auth) = &cs.authorization {
12838 self.write_space();
12839 self.write_keyword("AUTHORIZATION");
12840 self.write_space();
12841 self.generate_identifier(auth)?;
12842 }
12843
12844 let with_properties: Vec<_> = cs
12847 .properties
12848 .iter()
12849 .filter(|p| matches!(p, Expression::Property(_)))
12850 .collect();
12851 let other_properties: Vec<_> = cs
12852 .properties
12853 .iter()
12854 .filter(|p| !matches!(p, Expression::Property(_)))
12855 .collect();
12856
12857 if !with_properties.is_empty() {
12859 self.write_space();
12860 self.write_keyword("WITH");
12861 self.write(" (");
12862 for (i, prop) in with_properties.iter().enumerate() {
12863 if i > 0 {
12864 self.write(", ");
12865 }
12866 self.generate_expression(prop)?;
12867 }
12868 self.write(")");
12869 }
12870
12871 for prop in other_properties {
12873 self.write_space();
12874 self.generate_expression(prop)?;
12875 }
12876
12877 self.athena_hive_context = saved_athena_hive_context;
12879
12880 Ok(())
12881 }
12882
12883 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
12884 self.write_keyword("DROP SCHEMA");
12885
12886 if ds.if_exists {
12887 self.write_space();
12888 self.write_keyword("IF EXISTS");
12889 }
12890
12891 self.write_space();
12892 self.generate_identifier(&ds.name)?;
12893
12894 if ds.cascade {
12895 self.write_space();
12896 self.write_keyword("CASCADE");
12897 }
12898
12899 Ok(())
12900 }
12901
12902 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
12903 self.write_keyword("DROP NAMESPACE");
12904
12905 if dn.if_exists {
12906 self.write_space();
12907 self.write_keyword("IF EXISTS");
12908 }
12909
12910 self.write_space();
12911 self.generate_identifier(&dn.name)?;
12912
12913 if dn.cascade {
12914 self.write_space();
12915 self.write_keyword("CASCADE");
12916 }
12917
12918 Ok(())
12919 }
12920
12921 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
12922 self.write_keyword("CREATE DATABASE");
12923
12924 if cd.if_not_exists {
12925 self.write_space();
12926 self.write_keyword("IF NOT EXISTS");
12927 }
12928
12929 self.write_space();
12930 self.generate_identifier(&cd.name)?;
12931
12932 if let Some(ref clone_src) = cd.clone_from {
12933 self.write_keyword(" CLONE ");
12934 self.generate_identifier(clone_src)?;
12935 }
12936
12937 if let Some(ref at_clause) = cd.at_clause {
12939 self.write_space();
12940 self.generate_expression(at_clause)?;
12941 }
12942
12943 for option in &cd.options {
12944 self.write_space();
12945 match option {
12946 DatabaseOption::CharacterSet(charset) => {
12947 self.write_keyword("CHARACTER SET");
12948 self.write(" = ");
12949 self.write(&format!("'{}'", charset));
12950 }
12951 DatabaseOption::Collate(collate) => {
12952 self.write_keyword("COLLATE");
12953 self.write(" = ");
12954 self.write(&format!("'{}'", collate));
12955 }
12956 DatabaseOption::Owner(owner) => {
12957 self.write_keyword("OWNER");
12958 self.write(" = ");
12959 self.generate_identifier(owner)?;
12960 }
12961 DatabaseOption::Template(template) => {
12962 self.write_keyword("TEMPLATE");
12963 self.write(" = ");
12964 self.generate_identifier(template)?;
12965 }
12966 DatabaseOption::Encoding(encoding) => {
12967 self.write_keyword("ENCODING");
12968 self.write(" = ");
12969 self.write(&format!("'{}'", encoding));
12970 }
12971 DatabaseOption::Location(location) => {
12972 self.write_keyword("LOCATION");
12973 self.write(" = ");
12974 self.write(&format!("'{}'", location));
12975 }
12976 }
12977 }
12978
12979 Ok(())
12980 }
12981
12982 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
12983 self.write_keyword("DROP DATABASE");
12984
12985 if dd.if_exists {
12986 self.write_space();
12987 self.write_keyword("IF EXISTS");
12988 }
12989
12990 self.write_space();
12991 self.generate_identifier(&dd.name)?;
12992
12993 if dd.sync {
12994 self.write_space();
12995 self.write_keyword("SYNC");
12996 }
12997
12998 Ok(())
12999 }
13000
13001 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
13002 self.write_keyword("CREATE");
13003
13004 if cf.or_alter {
13005 self.write_space();
13006 self.write_keyword("OR ALTER");
13007 } else if cf.or_replace {
13008 self.write_space();
13009 self.write_keyword("OR REPLACE");
13010 }
13011
13012 if cf.temporary {
13013 self.write_space();
13014 self.write_keyword("TEMPORARY");
13015 }
13016
13017 self.write_space();
13018 if cf.is_table_function {
13019 self.write_keyword("TABLE FUNCTION");
13020 } else {
13021 self.write_keyword("FUNCTION");
13022 }
13023
13024 if cf.if_not_exists {
13025 self.write_space();
13026 self.write_keyword("IF NOT EXISTS");
13027 }
13028
13029 self.write_space();
13030 self.generate_table(&cf.name)?;
13031 if cf.has_parens {
13032 let func_multiline = self.config.pretty
13033 && matches!(
13034 self.config.dialect,
13035 Some(crate::dialects::DialectType::TSQL)
13036 | Some(crate::dialects::DialectType::Fabric)
13037 )
13038 && !cf.parameters.is_empty();
13039 if func_multiline {
13040 self.write("(\n");
13041 self.indent_level += 2;
13042 self.write_indent();
13043 self.generate_function_parameters(&cf.parameters)?;
13044 self.write("\n");
13045 self.indent_level -= 2;
13046 self.write(")");
13047 } else {
13048 self.write("(");
13049 self.generate_function_parameters(&cf.parameters)?;
13050 self.write(")");
13051 }
13052 }
13053
13054 let use_multiline = self.config.pretty
13057 && matches!(
13058 self.config.dialect,
13059 Some(crate::dialects::DialectType::BigQuery)
13060 | Some(crate::dialects::DialectType::TSQL)
13061 | Some(crate::dialects::DialectType::Fabric)
13062 );
13063
13064 if cf.language_first {
13065 if let Some(lang) = &cf.language {
13067 if use_multiline {
13068 self.write_newline();
13069 } else {
13070 self.write_space();
13071 }
13072 self.write_keyword("LANGUAGE");
13073 self.write_space();
13074 self.write(lang);
13075 }
13076
13077 if let Some(sql_data) = &cf.sql_data_access {
13079 self.write_space();
13080 match sql_data {
13081 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
13082 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
13083 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
13084 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
13085 }
13086 }
13087
13088 if let Some(ref rtb) = cf.returns_table_body {
13089 if use_multiline {
13090 self.write_newline();
13091 } else {
13092 self.write_space();
13093 }
13094 self.write_keyword("RETURNS");
13095 self.write_space();
13096 self.write(rtb);
13097 } else if let Some(return_type) = &cf.return_type {
13098 if use_multiline {
13099 self.write_newline();
13100 } else {
13101 self.write_space();
13102 }
13103 self.write_keyword("RETURNS");
13104 self.write_space();
13105 self.generate_function_return_type(return_type)?;
13106 }
13107 } else {
13108 let is_duckdb = matches!(
13111 self.config.dialect,
13112 Some(crate::dialects::DialectType::DuckDB)
13113 );
13114 if let Some(ref rtb) = cf.returns_table_body {
13115 if !(is_duckdb && rtb.is_empty()) {
13116 if use_multiline {
13117 self.write_newline();
13118 } else {
13119 self.write_space();
13120 }
13121 self.write_keyword("RETURNS");
13122 self.write_space();
13123 self.write(rtb);
13124 }
13125 } else if let Some(return_type) = &cf.return_type {
13126 if !is_duckdb {
13128 let is_table_return = matches!(return_type, crate::expressions::DataType::Custom { ref name } if name.eq_ignore_ascii_case("TABLE"));
13129 if use_multiline {
13130 self.write_newline();
13131 } else {
13132 self.write_space();
13133 }
13134 self.write_keyword("RETURNS");
13135 self.write_space();
13136 if is_table_return {
13137 self.write_keyword("TABLE");
13138 } else {
13139 self.generate_function_return_type(return_type)?;
13140 }
13141 }
13142 }
13143 }
13144
13145 if !cf.property_order.is_empty() {
13147 let is_bigquery = matches!(
13149 self.config.dialect,
13150 Some(crate::dialects::DialectType::BigQuery)
13151 );
13152 let is_postgres = matches!(
13153 self.config.dialect,
13154 Some(crate::dialects::DialectType::PostgreSQL)
13155 );
13156 let property_order = if is_bigquery {
13157 let mut reordered = Vec::new();
13159 let mut has_as = false;
13160 let mut has_options = false;
13161 for prop in &cf.property_order {
13162 match prop {
13163 FunctionPropertyKind::As => has_as = true,
13164 FunctionPropertyKind::Options => has_options = true,
13165 _ => {}
13166 }
13167 }
13168 if has_as && has_options {
13169 for prop in &cf.property_order {
13171 if *prop != FunctionPropertyKind::As
13172 && *prop != FunctionPropertyKind::Options
13173 {
13174 reordered.push(*prop);
13175 }
13176 }
13177 reordered.push(FunctionPropertyKind::Options);
13178 reordered.push(FunctionPropertyKind::As);
13179 reordered
13180 } else {
13181 cf.property_order.clone()
13182 }
13183 } else if is_postgres
13184 && cf.property_order.contains(&FunctionPropertyKind::As)
13185 && cf.property_order.contains(&FunctionPropertyKind::NullInput)
13186 {
13187 let mut reordered: Vec<_> = cf
13188 .property_order
13189 .iter()
13190 .copied()
13191 .filter(|prop| *prop != FunctionPropertyKind::As)
13192 .collect();
13193 reordered.push(FunctionPropertyKind::As);
13194 reordered
13195 } else {
13196 cf.property_order.clone()
13197 };
13198
13199 for prop in &property_order {
13200 match prop {
13201 FunctionPropertyKind::Set => {
13202 self.generate_function_set_options(cf)?;
13203 }
13204 FunctionPropertyKind::As => {
13205 self.generate_function_body(cf)?;
13206 }
13207 FunctionPropertyKind::Using => {
13208 self.generate_function_using_resources(cf)?;
13209 }
13210 FunctionPropertyKind::Language => {
13211 if !cf.language_first {
13212 if let Some(lang) = &cf.language {
13214 let use_multiline = self.config.pretty
13216 && matches!(
13217 self.config.dialect,
13218 Some(crate::dialects::DialectType::BigQuery)
13219 );
13220 if use_multiline {
13221 self.write_newline();
13222 } else {
13223 self.write_space();
13224 }
13225 self.write_keyword("LANGUAGE");
13226 self.write_space();
13227 self.write(lang);
13228 }
13229 }
13230 }
13231 FunctionPropertyKind::Determinism => {
13232 self.generate_function_determinism(cf)?;
13233 }
13234 FunctionPropertyKind::NullInput => {
13235 self.generate_function_null_input(cf)?;
13236 }
13237 FunctionPropertyKind::Security => {
13238 self.generate_function_security(cf)?;
13239 }
13240 FunctionPropertyKind::SqlDataAccess => {
13241 if !cf.language_first {
13242 self.generate_function_sql_data_access(cf)?;
13244 }
13245 }
13246 FunctionPropertyKind::Options => {
13247 if !cf.options.is_empty() {
13248 self.write_space();
13249 self.generate_options_clause(&cf.options)?;
13250 }
13251 }
13252 FunctionPropertyKind::Environment => {
13253 if !cf.environment.is_empty() {
13254 self.write_space();
13255 self.generate_environment_clause(&cf.environment)?;
13256 }
13257 }
13258 FunctionPropertyKind::Handler => {
13259 if let Some(ref h) = cf.handler {
13260 self.write_space();
13261 self.write_keyword("HANDLER");
13262 if cf.handler_uses_eq {
13263 self.write(" = ");
13264 } else {
13265 self.write_space();
13266 }
13267 self.write("'");
13268 self.write(h);
13269 self.write("'");
13270 }
13271 }
13272 FunctionPropertyKind::RuntimeVersion => {
13273 if let Some(ref runtime_version) = cf.runtime_version {
13274 self.write_space();
13275 self.write_keyword("RUNTIME_VERSION");
13276 self.write("='");
13277 self.write(runtime_version);
13278 self.write("'");
13279 }
13280 }
13281 FunctionPropertyKind::Packages => {
13282 if let Some(ref packages) = cf.packages {
13283 self.write_space();
13284 self.write_keyword("PACKAGES");
13285 self.write("=(");
13286 for (i, package) in packages.iter().enumerate() {
13287 if i > 0 {
13288 self.write(", ");
13289 }
13290 self.write("'");
13291 self.write(package);
13292 self.write("'");
13293 }
13294 self.write(")");
13295 }
13296 }
13297 FunctionPropertyKind::ParameterStyle => {
13298 if let Some(ref ps) = cf.parameter_style {
13299 self.write_space();
13300 self.write_keyword("PARAMETER STYLE");
13301 self.write_space();
13302 self.write_keyword(ps);
13303 }
13304 }
13305 }
13306 }
13307
13308 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
13310 {
13311 self.write_space();
13312 self.generate_options_clause(&cf.options)?;
13313 }
13314
13315 if !cf.environment.is_empty()
13317 && !cf
13318 .property_order
13319 .contains(&FunctionPropertyKind::Environment)
13320 {
13321 self.write_space();
13322 self.generate_environment_clause(&cf.environment)?;
13323 }
13324 } else {
13325 if matches!(
13328 self.config.dialect,
13329 Some(crate::dialects::DialectType::BigQuery)
13330 ) {
13331 self.generate_function_determinism(cf)?;
13332 }
13333
13334 let use_multiline = self.config.pretty
13336 && matches!(
13337 self.config.dialect,
13338 Some(crate::dialects::DialectType::BigQuery)
13339 );
13340
13341 if !cf.language_first {
13342 if let Some(lang) = &cf.language {
13343 if use_multiline {
13344 self.write_newline();
13345 } else {
13346 self.write_space();
13347 }
13348 self.write_keyword("LANGUAGE");
13349 self.write_space();
13350 self.write(lang);
13351 }
13352
13353 self.generate_function_sql_data_access(cf)?;
13355 }
13356
13357 if !matches!(
13359 self.config.dialect,
13360 Some(crate::dialects::DialectType::BigQuery)
13361 ) {
13362 self.generate_function_determinism(cf)?;
13363 }
13364
13365 self.generate_function_null_input(cf)?;
13366 self.generate_function_security(cf)?;
13367 self.generate_function_set_options(cf)?;
13368
13369 if !cf.options.is_empty() {
13371 self.write_space();
13372 self.generate_options_clause(&cf.options)?;
13373 }
13374
13375 if !cf.environment.is_empty() {
13377 self.write_space();
13378 self.generate_environment_clause(&cf.environment)?;
13379 }
13380
13381 if let Some(ref h) = cf.handler {
13382 self.write_space();
13383 self.write_keyword("HANDLER");
13384 if cf.handler_uses_eq {
13385 self.write(" = ");
13386 } else {
13387 self.write_space();
13388 }
13389 self.write("'");
13390 self.write(h);
13391 self.write("'");
13392 }
13393
13394 if let Some(ref runtime_version) = cf.runtime_version {
13395 self.write_space();
13396 self.write_keyword("RUNTIME_VERSION");
13397 self.write("='");
13398 self.write(runtime_version);
13399 self.write("'");
13400 }
13401
13402 if let Some(ref packages) = cf.packages {
13403 self.write_space();
13404 self.write_keyword("PACKAGES");
13405 self.write("=(");
13406 for (i, package) in packages.iter().enumerate() {
13407 if i > 0 {
13408 self.write(", ");
13409 }
13410 self.write("'");
13411 self.write(package);
13412 self.write("'");
13413 }
13414 self.write(")");
13415 }
13416
13417 self.generate_function_body(cf)?;
13418 self.generate_function_using_resources(cf)?;
13419 }
13420
13421 Ok(())
13422 }
13423
13424 fn generate_function_return_type(&mut self, return_type: &DataType) -> Result<()> {
13425 if matches!(
13426 self.config.dialect,
13427 Some(crate::dialects::DialectType::PostgreSQL)
13428 ) {
13429 if let DataType::Custom { name } = return_type {
13430 if name.eq_ignore_ascii_case("integer") {
13431 self.write_keyword("INT");
13432 return Ok(());
13433 }
13434 }
13435 }
13436
13437 self.generate_data_type(return_type)
13438 }
13439
13440 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
13442 for opt in &cf.set_options {
13443 self.write_space();
13444 self.write_keyword("SET");
13445 self.write_space();
13446 self.write(&opt.name);
13447 match &opt.value {
13448 FunctionSetValue::Value { value, use_to } => {
13449 if *use_to {
13450 self.write(" TO ");
13451 } else {
13452 self.write(" = ");
13453 }
13454 self.write(value);
13455 }
13456 FunctionSetValue::FromCurrent => {
13457 self.write_space();
13458 self.write_keyword("FROM CURRENT");
13459 }
13460 }
13461 }
13462 Ok(())
13463 }
13464
13465 fn generate_function_using_resources(&mut self, cf: &CreateFunction) -> Result<()> {
13466 if cf.using_resources.is_empty() {
13467 return Ok(());
13468 }
13469
13470 self.write_space();
13471 self.write_keyword("USING");
13472 for resource in &cf.using_resources {
13473 self.write_space();
13474 self.write_keyword(&resource.kind);
13475 self.write_space();
13476 self.generate_string_literal(&resource.uri)?;
13477 }
13478 Ok(())
13479 }
13480
13481 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
13483 if let Some(body) = &cf.body {
13484 self.write_space();
13486 let use_multiline = self.config.pretty
13488 && matches!(
13489 self.config.dialect,
13490 Some(crate::dialects::DialectType::BigQuery)
13491 );
13492 match body {
13493 FunctionBody::Block(block) => {
13494 self.write_keyword("AS");
13495 if matches!(
13496 self.config.dialect,
13497 Some(crate::dialects::DialectType::TSQL)
13498 ) {
13499 self.write(" BEGIN ");
13500 self.write(block);
13501 self.write(" END");
13502 } else if matches!(
13503 self.config.dialect,
13504 Some(crate::dialects::DialectType::PostgreSQL)
13505 ) {
13506 self.write(" $$");
13507 self.write(block);
13508 self.write("$$");
13509 } else {
13510 let escaped = self.escape_block_for_single_quote(block);
13512 if use_multiline {
13514 self.write_newline();
13515 } else {
13516 self.write(" ");
13517 }
13518 self.write("'");
13519 self.write(&escaped);
13520 self.write("'");
13521 }
13522 }
13523 FunctionBody::StringLiteral(s) => {
13524 self.write_keyword("AS");
13525 if use_multiline {
13527 self.write_newline();
13528 } else {
13529 self.write(" ");
13530 }
13531 self.write("'");
13532 self.write(s);
13533 self.write("'");
13534 }
13535 FunctionBody::Expression(expr) => {
13536 self.write_keyword("AS");
13537 self.write_space();
13538 self.generate_expression(expr)?;
13539 }
13540 FunctionBody::External(name) => {
13541 self.write_keyword("EXTERNAL NAME");
13542 self.write(" '");
13543 self.write(name);
13544 self.write("'");
13545 }
13546 FunctionBody::Return(expr) => {
13547 if matches!(
13548 self.config.dialect,
13549 Some(crate::dialects::DialectType::DuckDB)
13550 ) {
13551 self.write_keyword("AS");
13553 self.write_space();
13554 let is_table_return = cf.returns_table_body.is_some()
13556 || matches!(&cf.return_type, Some(crate::expressions::DataType::Custom { ref name }) if name.eq_ignore_ascii_case("TABLE"));
13557 if is_table_return {
13558 self.write_keyword("TABLE");
13559 self.write_space();
13560 }
13561 self.generate_expression(expr)?;
13562 } else {
13563 if self.config.create_function_return_as {
13564 self.write_keyword("AS");
13565 if self.config.pretty
13567 && matches!(
13568 self.config.dialect,
13569 Some(crate::dialects::DialectType::TSQL)
13570 | Some(crate::dialects::DialectType::Fabric)
13571 )
13572 {
13573 self.write_newline();
13574 } else {
13575 self.write_space();
13576 }
13577 }
13578 self.write_keyword("RETURN");
13579 self.write_space();
13580 self.generate_expression(expr)?;
13581 }
13582 }
13583 FunctionBody::Statements(stmts) => {
13584 self.write_keyword("AS");
13585 self.write(" BEGIN ");
13586 for (i, stmt) in stmts.iter().enumerate() {
13587 if i > 0 {
13588 self.write(" ");
13589 }
13590 self.generate_expression(stmt)?;
13591 self.write(";");
13592 }
13593 self.write(" END");
13594 }
13595 FunctionBody::RawBlock(text) => {
13596 self.write_newline();
13597 self.write(text);
13598 }
13599 FunctionBody::DollarQuoted { content, tag } => {
13600 self.write_keyword("AS");
13601 self.write(" ");
13602 let supports_dollar_quoting = matches!(
13604 self.config.dialect,
13605 Some(crate::dialects::DialectType::PostgreSQL)
13606 | Some(crate::dialects::DialectType::Databricks)
13607 | Some(crate::dialects::DialectType::Redshift)
13608 | Some(crate::dialects::DialectType::DuckDB)
13609 );
13610 if supports_dollar_quoting {
13611 self.write("$");
13613 if let Some(t) = tag {
13614 self.write(t);
13615 }
13616 self.write("$");
13617 self.write(content);
13618 self.write("$");
13619 if let Some(t) = tag {
13620 self.write(t);
13621 }
13622 self.write("$");
13623 } else {
13624 let escaped = self.escape_block_for_single_quote(content);
13626 self.write("'");
13627 self.write(&escaped);
13628 self.write("'");
13629 }
13630 }
13631 }
13632 }
13633 Ok(())
13634 }
13635
13636 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
13638 if let Some(det) = cf.deterministic {
13639 self.write_space();
13640 if matches!(
13641 self.config.dialect,
13642 Some(crate::dialects::DialectType::BigQuery)
13643 ) {
13644 if det {
13646 self.write_keyword("DETERMINISTIC");
13647 } else {
13648 self.write_keyword("NOT DETERMINISTIC");
13649 }
13650 } else {
13651 if det {
13653 self.write_keyword("IMMUTABLE");
13654 } else {
13655 self.write_keyword("VOLATILE");
13656 }
13657 }
13658 }
13659 Ok(())
13660 }
13661
13662 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
13664 if let Some(returns_null) = cf.returns_null_on_null_input {
13665 self.write_space();
13666 if returns_null {
13667 if cf.strict {
13668 self.write_keyword("STRICT");
13669 } else {
13670 self.write_keyword("RETURNS NULL ON NULL INPUT");
13671 }
13672 } else {
13673 self.write_keyword("CALLED ON NULL INPUT");
13674 }
13675 }
13676 Ok(())
13677 }
13678
13679 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
13681 if let Some(security) = &cf.security {
13682 self.write_space();
13683 if matches!(
13685 self.config.dialect,
13686 Some(crate::dialects::DialectType::MySQL)
13687 ) {
13688 self.write_keyword("SQL SECURITY");
13689 } else {
13690 self.write_keyword("SECURITY");
13691 }
13692 self.write_space();
13693 match security {
13694 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13695 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13696 FunctionSecurity::None => self.write_keyword("NONE"),
13697 }
13698 }
13699 Ok(())
13700 }
13701
13702 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
13704 if let Some(sql_data) = &cf.sql_data_access {
13705 self.write_space();
13706 match sql_data {
13707 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
13708 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
13709 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
13710 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
13711 }
13712 }
13713 Ok(())
13714 }
13715
13716 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
13717 for (i, param) in params.iter().enumerate() {
13718 if i > 0 {
13719 self.write(", ");
13720 }
13721
13722 if let Some(mode) = ¶m.mode {
13723 if let Some(text) = ¶m.mode_text {
13724 self.write(text);
13725 } else {
13726 match mode {
13727 ParameterMode::In => self.write_keyword("IN"),
13728 ParameterMode::Out => self.write_keyword("OUT"),
13729 ParameterMode::InOut => self.write_keyword("INOUT"),
13730 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
13731 }
13732 }
13733 self.write_space();
13734 }
13735
13736 if let Some(name) = ¶m.name {
13737 self.generate_identifier(name)?;
13738 let skip_type =
13740 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
13741 if !skip_type {
13742 self.write_space();
13743 self.generate_data_type(¶m.data_type)?;
13744 }
13745 } else {
13746 self.generate_data_type(¶m.data_type)?;
13747 }
13748
13749 if let Some(default) = ¶m.default {
13750 if self.config.parameter_default_equals {
13751 self.write(" = ");
13752 } else {
13753 self.write(" DEFAULT ");
13754 }
13755 self.generate_expression(default)?;
13756 }
13757 }
13758
13759 Ok(())
13760 }
13761
13762 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
13763 self.write_keyword("DROP FUNCTION");
13764
13765 if df.if_exists {
13766 self.write_space();
13767 self.write_keyword("IF EXISTS");
13768 }
13769
13770 self.write_space();
13771 self.generate_table(&df.name)?;
13772
13773 if let Some(params) = &df.parameters {
13774 self.write(" (");
13775 for (i, dt) in params.iter().enumerate() {
13776 if i > 0 {
13777 self.write(", ");
13778 }
13779 self.generate_data_type(dt)?;
13780 }
13781 self.write(")");
13782 }
13783
13784 if df.cascade {
13785 self.write_space();
13786 self.write_keyword("CASCADE");
13787 }
13788
13789 Ok(())
13790 }
13791
13792 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
13793 self.write_keyword("CREATE");
13794
13795 if cp.or_alter {
13796 self.write_space();
13797 self.write_keyword("OR ALTER");
13798 } else if cp.or_replace {
13799 self.write_space();
13800 self.write_keyword("OR REPLACE");
13801 }
13802
13803 self.write_space();
13804 if cp.use_proc_keyword {
13805 self.write_keyword("PROC");
13806 } else {
13807 self.write_keyword("PROCEDURE");
13808 }
13809
13810 if cp.if_not_exists {
13811 self.write_space();
13812 self.write_keyword("IF NOT EXISTS");
13813 }
13814
13815 self.write_space();
13816 self.generate_table(&cp.name)?;
13817 if cp.has_parens {
13818 self.write("(");
13819 self.generate_function_parameters(&cp.parameters)?;
13820 self.write(")");
13821 } else if !cp.parameters.is_empty() {
13822 self.write_space();
13824 self.generate_function_parameters(&cp.parameters)?;
13825 }
13826
13827 if let Some(return_type) = &cp.return_type {
13829 self.write_space();
13830 self.write_keyword("RETURNS");
13831 self.write_space();
13832 self.generate_data_type(return_type)?;
13833 }
13834
13835 if let Some(execute_as) = &cp.execute_as {
13837 self.write_space();
13838 self.write_keyword("EXECUTE AS");
13839 self.write_space();
13840 self.write_keyword(execute_as);
13841 }
13842
13843 if let Some(lang) = &cp.language {
13844 self.write_space();
13845 self.write_keyword("LANGUAGE");
13846 self.write_space();
13847 self.write(lang);
13848 }
13849
13850 if let Some(security) = &cp.security {
13851 self.write_space();
13852 self.write_keyword("SECURITY");
13853 self.write_space();
13854 match security {
13855 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13856 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13857 FunctionSecurity::None => self.write_keyword("NONE"),
13858 }
13859 }
13860
13861 if !cp.with_options.is_empty() {
13863 self.write_space();
13864 self.write_keyword("WITH");
13865 self.write_space();
13866 for (i, opt) in cp.with_options.iter().enumerate() {
13867 if i > 0 {
13868 self.write(", ");
13869 }
13870 self.write(opt);
13871 }
13872 }
13873
13874 if let Some(body) = &cp.body {
13875 self.write_space();
13876 match body {
13877 FunctionBody::Block(block) => {
13878 self.write_keyword("AS");
13879 if matches!(
13880 self.config.dialect,
13881 Some(crate::dialects::DialectType::TSQL)
13882 ) {
13883 self.write(" BEGIN ");
13884 self.write(block);
13885 self.write(" END");
13886 } else if matches!(
13887 self.config.dialect,
13888 Some(crate::dialects::DialectType::PostgreSQL)
13889 ) {
13890 self.write(" $$");
13891 self.write(block);
13892 self.write("$$");
13893 } else {
13894 let escaped = self.escape_block_for_single_quote(block);
13896 self.write(" '");
13897 self.write(&escaped);
13898 self.write("'");
13899 }
13900 }
13901 FunctionBody::StringLiteral(s) => {
13902 self.write_keyword("AS");
13903 self.write(" '");
13904 self.write(s);
13905 self.write("'");
13906 }
13907 FunctionBody::Expression(expr) => {
13908 self.write_keyword("AS");
13909 self.write_space();
13910 self.generate_expression(expr)?;
13911 }
13912 FunctionBody::External(name) => {
13913 self.write_keyword("EXTERNAL NAME");
13914 self.write(" '");
13915 self.write(name);
13916 self.write("'");
13917 }
13918 FunctionBody::Return(expr) => {
13919 self.write_keyword("RETURN");
13920 self.write_space();
13921 self.generate_expression(expr)?;
13922 }
13923 FunctionBody::Statements(stmts) => {
13924 self.write_keyword("AS");
13925 self.write(" BEGIN ");
13926 for (i, stmt) in stmts.iter().enumerate() {
13927 if i > 0 {
13928 self.write(" ");
13929 }
13930 self.generate_expression(stmt)?;
13931 self.write(";");
13932 }
13933 self.write(" END");
13934 }
13935 FunctionBody::RawBlock(text) => {
13936 self.write_newline();
13937 self.write(text);
13938 }
13939 FunctionBody::DollarQuoted { content, tag } => {
13940 self.write_keyword("AS");
13941 self.write(" ");
13942 let supports_dollar_quoting = matches!(
13944 self.config.dialect,
13945 Some(crate::dialects::DialectType::PostgreSQL)
13946 | Some(crate::dialects::DialectType::Databricks)
13947 | Some(crate::dialects::DialectType::Redshift)
13948 | Some(crate::dialects::DialectType::DuckDB)
13949 );
13950 if supports_dollar_quoting {
13951 self.write("$");
13953 if let Some(t) = tag {
13954 self.write(t);
13955 }
13956 self.write("$");
13957 self.write(content);
13958 self.write("$");
13959 if let Some(t) = tag {
13960 self.write(t);
13961 }
13962 self.write("$");
13963 } else {
13964 let escaped = self.escape_block_for_single_quote(content);
13966 self.write("'");
13967 self.write(&escaped);
13968 self.write("'");
13969 }
13970 }
13971 }
13972 }
13973
13974 Ok(())
13975 }
13976
13977 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
13978 self.write_keyword("DROP PROCEDURE");
13979
13980 if dp.if_exists {
13981 self.write_space();
13982 self.write_keyword("IF EXISTS");
13983 }
13984
13985 self.write_space();
13986 self.generate_table(&dp.name)?;
13987
13988 if let Some(params) = &dp.parameters {
13989 self.write(" (");
13990 for (i, dt) in params.iter().enumerate() {
13991 if i > 0 {
13992 self.write(", ");
13993 }
13994 self.generate_data_type(dt)?;
13995 }
13996 self.write(")");
13997 }
13998
13999 if dp.cascade {
14000 self.write_space();
14001 self.write_keyword("CASCADE");
14002 }
14003
14004 Ok(())
14005 }
14006
14007 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
14008 self.write_keyword("CREATE");
14009
14010 if cs.or_replace {
14011 self.write_space();
14012 self.write_keyword("OR REPLACE");
14013 }
14014
14015 if cs.temporary {
14016 self.write_space();
14017 self.write_keyword("TEMPORARY");
14018 }
14019
14020 self.write_space();
14021 self.write_keyword("SEQUENCE");
14022
14023 if cs.if_not_exists {
14024 self.write_space();
14025 self.write_keyword("IF NOT EXISTS");
14026 }
14027
14028 self.write_space();
14029 self.generate_table(&cs.name)?;
14030
14031 if let Some(as_type) = &cs.as_type {
14033 self.write_space();
14034 self.write_keyword("AS");
14035 self.write_space();
14036 self.generate_data_type(as_type)?;
14037 }
14038
14039 if let Some(comment) = &cs.comment {
14041 self.write_space();
14042 self.write_keyword("COMMENT");
14043 self.write("=");
14044 self.generate_string_literal(comment)?;
14045 }
14046
14047 if !cs.property_order.is_empty() {
14049 for prop in &cs.property_order {
14050 match prop {
14051 SeqPropKind::Start => {
14052 if let Some(start) = cs.start {
14053 self.write_space();
14054 self.write_keyword("START WITH");
14055 self.write(&format!(" {}", start));
14056 }
14057 }
14058 SeqPropKind::Increment => {
14059 if let Some(inc) = cs.increment {
14060 self.write_space();
14061 self.write_keyword("INCREMENT BY");
14062 self.write(&format!(" {}", inc));
14063 }
14064 }
14065 SeqPropKind::Minvalue => {
14066 if let Some(min) = &cs.minvalue {
14067 self.write_space();
14068 match min {
14069 SequenceBound::Value(v) => {
14070 self.write_keyword("MINVALUE");
14071 self.write(&format!(" {}", v));
14072 }
14073 SequenceBound::None => {
14074 self.write_keyword("NO MINVALUE");
14075 }
14076 }
14077 }
14078 }
14079 SeqPropKind::Maxvalue => {
14080 if let Some(max) = &cs.maxvalue {
14081 self.write_space();
14082 match max {
14083 SequenceBound::Value(v) => {
14084 self.write_keyword("MAXVALUE");
14085 self.write(&format!(" {}", v));
14086 }
14087 SequenceBound::None => {
14088 self.write_keyword("NO MAXVALUE");
14089 }
14090 }
14091 }
14092 }
14093 SeqPropKind::Cache => {
14094 if let Some(cache) = cs.cache {
14095 self.write_space();
14096 self.write_keyword("CACHE");
14097 self.write(&format!(" {}", cache));
14098 }
14099 }
14100 SeqPropKind::NoCache => {
14101 self.write_space();
14102 self.write_keyword("NO CACHE");
14103 }
14104 SeqPropKind::NoCacheWord => {
14105 self.write_space();
14106 self.write_keyword("NOCACHE");
14107 }
14108 SeqPropKind::Cycle => {
14109 self.write_space();
14110 self.write_keyword("CYCLE");
14111 }
14112 SeqPropKind::NoCycle => {
14113 self.write_space();
14114 self.write_keyword("NO CYCLE");
14115 }
14116 SeqPropKind::NoCycleWord => {
14117 self.write_space();
14118 self.write_keyword("NOCYCLE");
14119 }
14120 SeqPropKind::OwnedBy => {
14121 if !cs.owned_by_none {
14123 if let Some(owned) = &cs.owned_by {
14124 self.write_space();
14125 self.write_keyword("OWNED BY");
14126 self.write_space();
14127 self.generate_table(owned)?;
14128 }
14129 }
14130 }
14131 SeqPropKind::Order => {
14132 self.write_space();
14133 self.write_keyword("ORDER");
14134 }
14135 SeqPropKind::NoOrder => {
14136 self.write_space();
14137 self.write_keyword("NOORDER");
14138 }
14139 SeqPropKind::Comment => {
14140 }
14142 SeqPropKind::Sharing => {
14143 if let Some(val) = &cs.sharing {
14144 self.write_space();
14145 self.write(&format!("SHARING={}", val));
14146 }
14147 }
14148 SeqPropKind::Keep => {
14149 self.write_space();
14150 self.write_keyword("KEEP");
14151 }
14152 SeqPropKind::NoKeep => {
14153 self.write_space();
14154 self.write_keyword("NOKEEP");
14155 }
14156 SeqPropKind::Scale => {
14157 self.write_space();
14158 self.write_keyword("SCALE");
14159 if let Some(modifier) = &cs.scale_modifier {
14160 if !modifier.is_empty() {
14161 self.write_space();
14162 self.write_keyword(modifier);
14163 }
14164 }
14165 }
14166 SeqPropKind::NoScale => {
14167 self.write_space();
14168 self.write_keyword("NOSCALE");
14169 }
14170 SeqPropKind::Shard => {
14171 self.write_space();
14172 self.write_keyword("SHARD");
14173 if let Some(modifier) = &cs.shard_modifier {
14174 if !modifier.is_empty() {
14175 self.write_space();
14176 self.write_keyword(modifier);
14177 }
14178 }
14179 }
14180 SeqPropKind::NoShard => {
14181 self.write_space();
14182 self.write_keyword("NOSHARD");
14183 }
14184 SeqPropKind::Session => {
14185 self.write_space();
14186 self.write_keyword("SESSION");
14187 }
14188 SeqPropKind::Global => {
14189 self.write_space();
14190 self.write_keyword("GLOBAL");
14191 }
14192 SeqPropKind::NoMinvalueWord => {
14193 self.write_space();
14194 self.write_keyword("NOMINVALUE");
14195 }
14196 SeqPropKind::NoMaxvalueWord => {
14197 self.write_space();
14198 self.write_keyword("NOMAXVALUE");
14199 }
14200 }
14201 }
14202 } else {
14203 if let Some(inc) = cs.increment {
14205 self.write_space();
14206 self.write_keyword("INCREMENT BY");
14207 self.write(&format!(" {}", inc));
14208 }
14209
14210 if let Some(min) = &cs.minvalue {
14211 self.write_space();
14212 match min {
14213 SequenceBound::Value(v) => {
14214 self.write_keyword("MINVALUE");
14215 self.write(&format!(" {}", v));
14216 }
14217 SequenceBound::None => {
14218 self.write_keyword("NO MINVALUE");
14219 }
14220 }
14221 }
14222
14223 if let Some(max) = &cs.maxvalue {
14224 self.write_space();
14225 match max {
14226 SequenceBound::Value(v) => {
14227 self.write_keyword("MAXVALUE");
14228 self.write(&format!(" {}", v));
14229 }
14230 SequenceBound::None => {
14231 self.write_keyword("NO MAXVALUE");
14232 }
14233 }
14234 }
14235
14236 if let Some(start) = cs.start {
14237 self.write_space();
14238 self.write_keyword("START WITH");
14239 self.write(&format!(" {}", start));
14240 }
14241
14242 if let Some(cache) = cs.cache {
14243 self.write_space();
14244 self.write_keyword("CACHE");
14245 self.write(&format!(" {}", cache));
14246 }
14247
14248 if cs.cycle {
14249 self.write_space();
14250 self.write_keyword("CYCLE");
14251 }
14252
14253 if let Some(owned) = &cs.owned_by {
14254 self.write_space();
14255 self.write_keyword("OWNED BY");
14256 self.write_space();
14257 self.generate_table(owned)?;
14258 }
14259 }
14260
14261 Ok(())
14262 }
14263
14264 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
14265 self.write_keyword("DROP SEQUENCE");
14266
14267 if ds.if_exists {
14268 self.write_space();
14269 self.write_keyword("IF EXISTS");
14270 }
14271
14272 self.write_space();
14273 self.generate_table(&ds.name)?;
14274
14275 if ds.cascade {
14276 self.write_space();
14277 self.write_keyword("CASCADE");
14278 }
14279
14280 Ok(())
14281 }
14282
14283 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
14284 self.write_keyword("ALTER SEQUENCE");
14285
14286 if als.if_exists {
14287 self.write_space();
14288 self.write_keyword("IF EXISTS");
14289 }
14290
14291 self.write_space();
14292 self.generate_table(&als.name)?;
14293
14294 if let Some(inc) = als.increment {
14295 self.write_space();
14296 self.write_keyword("INCREMENT BY");
14297 self.write(&format!(" {}", inc));
14298 }
14299
14300 if let Some(min) = &als.minvalue {
14301 self.write_space();
14302 match min {
14303 SequenceBound::Value(v) => {
14304 self.write_keyword("MINVALUE");
14305 self.write(&format!(" {}", v));
14306 }
14307 SequenceBound::None => {
14308 self.write_keyword("NO MINVALUE");
14309 }
14310 }
14311 }
14312
14313 if let Some(max) = &als.maxvalue {
14314 self.write_space();
14315 match max {
14316 SequenceBound::Value(v) => {
14317 self.write_keyword("MAXVALUE");
14318 self.write(&format!(" {}", v));
14319 }
14320 SequenceBound::None => {
14321 self.write_keyword("NO MAXVALUE");
14322 }
14323 }
14324 }
14325
14326 if let Some(start) = als.start {
14327 self.write_space();
14328 self.write_keyword("START WITH");
14329 self.write(&format!(" {}", start));
14330 }
14331
14332 if let Some(restart) = &als.restart {
14333 self.write_space();
14334 self.write_keyword("RESTART");
14335 if let Some(val) = restart {
14336 self.write_keyword(" WITH");
14337 self.write(&format!(" {}", val));
14338 }
14339 }
14340
14341 if let Some(cache) = als.cache {
14342 self.write_space();
14343 self.write_keyword("CACHE");
14344 self.write(&format!(" {}", cache));
14345 }
14346
14347 if let Some(cycle) = als.cycle {
14348 self.write_space();
14349 if cycle {
14350 self.write_keyword("CYCLE");
14351 } else {
14352 self.write_keyword("NO CYCLE");
14353 }
14354 }
14355
14356 if let Some(owned) = &als.owned_by {
14357 self.write_space();
14358 self.write_keyword("OWNED BY");
14359 self.write_space();
14360 if let Some(table) = owned {
14361 self.generate_table(table)?;
14362 } else {
14363 self.write_keyword("NONE");
14364 }
14365 }
14366
14367 Ok(())
14368 }
14369
14370 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
14371 self.write_keyword("CREATE");
14372
14373 if ct.or_alter {
14374 self.write_space();
14375 self.write_keyword("OR ALTER");
14376 } else if ct.or_replace {
14377 self.write_space();
14378 self.write_keyword("OR REPLACE");
14379 }
14380
14381 if ct.constraint {
14382 self.write_space();
14383 self.write_keyword("CONSTRAINT");
14384 }
14385
14386 self.write_space();
14387 self.write_keyword("TRIGGER");
14388 self.write_space();
14389 self.generate_identifier(&ct.name)?;
14390
14391 self.write_space();
14392 match ct.timing {
14393 TriggerTiming::Before => self.write_keyword("BEFORE"),
14394 TriggerTiming::After => self.write_keyword("AFTER"),
14395 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
14396 }
14397
14398 for (i, event) in ct.events.iter().enumerate() {
14400 if i > 0 {
14401 self.write_keyword(" OR");
14402 }
14403 self.write_space();
14404 match event {
14405 TriggerEvent::Insert => self.write_keyword("INSERT"),
14406 TriggerEvent::Update(cols) => {
14407 self.write_keyword("UPDATE");
14408 if let Some(cols) = cols {
14409 self.write_space();
14410 self.write_keyword("OF");
14411 for (j, col) in cols.iter().enumerate() {
14412 if j > 0 {
14413 self.write(",");
14414 }
14415 self.write_space();
14416 self.generate_identifier(col)?;
14417 }
14418 }
14419 }
14420 TriggerEvent::Delete => self.write_keyword("DELETE"),
14421 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
14422 }
14423 }
14424
14425 self.write_space();
14426 self.write_keyword("ON");
14427 self.write_space();
14428 self.generate_table(&ct.table)?;
14429
14430 if let Some(ref_clause) = &ct.referencing {
14432 self.write_space();
14433 self.write_keyword("REFERENCING");
14434 if let Some(old_table) = &ref_clause.old_table {
14435 self.write_space();
14436 self.write_keyword("OLD TABLE AS");
14437 self.write_space();
14438 self.generate_identifier(old_table)?;
14439 }
14440 if let Some(new_table) = &ref_clause.new_table {
14441 self.write_space();
14442 self.write_keyword("NEW TABLE AS");
14443 self.write_space();
14444 self.generate_identifier(new_table)?;
14445 }
14446 if let Some(old_row) = &ref_clause.old_row {
14447 self.write_space();
14448 self.write_keyword("OLD ROW AS");
14449 self.write_space();
14450 self.generate_identifier(old_row)?;
14451 }
14452 if let Some(new_row) = &ref_clause.new_row {
14453 self.write_space();
14454 self.write_keyword("NEW ROW AS");
14455 self.write_space();
14456 self.generate_identifier(new_row)?;
14457 }
14458 }
14459
14460 if let Some(deferrable) = ct.deferrable {
14462 self.write_space();
14463 if deferrable {
14464 self.write_keyword("DEFERRABLE");
14465 } else {
14466 self.write_keyword("NOT DEFERRABLE");
14467 }
14468 }
14469
14470 if let Some(initially) = ct.initially_deferred {
14471 self.write_space();
14472 self.write_keyword("INITIALLY");
14473 self.write_space();
14474 if initially {
14475 self.write_keyword("DEFERRED");
14476 } else {
14477 self.write_keyword("IMMEDIATE");
14478 }
14479 }
14480
14481 if let Some(for_each) = ct.for_each {
14482 self.write_space();
14483 self.write_keyword("FOR EACH");
14484 self.write_space();
14485 match for_each {
14486 TriggerForEach::Row => self.write_keyword("ROW"),
14487 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
14488 }
14489 }
14490
14491 if let Some(when) = &ct.when {
14493 self.write_space();
14494 self.write_keyword("WHEN");
14495 if ct.when_paren {
14496 self.write(" (");
14497 self.generate_expression(when)?;
14498 self.write(")");
14499 } else {
14500 self.write_space();
14501 self.generate_expression(when)?;
14502 }
14503 }
14504
14505 self.write_space();
14507 match &ct.body {
14508 TriggerBody::Execute { function, args } => {
14509 self.write_keyword("EXECUTE FUNCTION");
14510 self.write_space();
14511 self.generate_table(function)?;
14512 self.write("(");
14513 for (i, arg) in args.iter().enumerate() {
14514 if i > 0 {
14515 self.write(", ");
14516 }
14517 self.generate_expression(arg)?;
14518 }
14519 self.write(")");
14520 }
14521 TriggerBody::Block(block) => {
14522 self.write_keyword("BEGIN");
14523 self.write_space();
14524 self.write(block);
14525 self.write_space();
14526 self.write_keyword("END");
14527 }
14528 }
14529
14530 Ok(())
14531 }
14532
14533 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
14534 self.write_keyword("DROP TRIGGER");
14535
14536 if dt.if_exists {
14537 self.write_space();
14538 self.write_keyword("IF EXISTS");
14539 }
14540
14541 self.write_space();
14542 self.generate_identifier(&dt.name)?;
14543
14544 if let Some(table) = &dt.table {
14545 self.write_space();
14546 self.write_keyword("ON");
14547 self.write_space();
14548 self.generate_table(table)?;
14549 }
14550
14551 if dt.cascade {
14552 self.write_space();
14553 self.write_keyword("CASCADE");
14554 }
14555
14556 Ok(())
14557 }
14558
14559 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
14560 self.write_keyword("CREATE TYPE");
14561
14562 if ct.if_not_exists {
14563 self.write_space();
14564 self.write_keyword("IF NOT EXISTS");
14565 }
14566
14567 self.write_space();
14568 self.generate_table(&ct.name)?;
14569
14570 if let TypeDefinition::Base {
14571 input,
14572 output,
14573 internallength,
14574 } = &ct.definition
14575 {
14576 if input.is_empty() && output.is_empty() && internallength.is_none() {
14577 return Ok(());
14578 }
14579 }
14580
14581 self.write_space();
14582 self.write_keyword("AS");
14583 self.write_space();
14584
14585 match &ct.definition {
14586 TypeDefinition::Enum(values) => {
14587 self.write_keyword("ENUM");
14588 self.write(" (");
14589 for (i, val) in values.iter().enumerate() {
14590 if i > 0 {
14591 self.write(", ");
14592 }
14593 self.write(&format!("'{}'", val));
14594 }
14595 self.write(")");
14596 }
14597 TypeDefinition::Composite(attrs) => {
14598 self.write("(");
14599 for (i, attr) in attrs.iter().enumerate() {
14600 if i > 0 {
14601 self.write(", ");
14602 }
14603 self.generate_identifier(&attr.name)?;
14604 self.write_space();
14605 self.generate_data_type(&attr.data_type)?;
14606 if let Some(collate) = &attr.collate {
14607 self.write_space();
14608 self.write_keyword("COLLATE");
14609 self.write_space();
14610 self.generate_identifier(collate)?;
14611 }
14612 }
14613 self.write(")");
14614 }
14615 TypeDefinition::Range {
14616 subtype,
14617 subtype_diff,
14618 canonical,
14619 } => {
14620 self.write_keyword("RANGE");
14621 self.write(" (");
14622 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
14623 self.write("subtype");
14624 } else {
14625 self.write_keyword("SUBTYPE");
14626 }
14627 self.write(" = ");
14628 self.generate_data_type(subtype)?;
14629 if let Some(diff) = subtype_diff {
14630 self.write(", ");
14631 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
14632 self.write("subtype_diff");
14633 } else {
14634 self.write_keyword("SUBTYPE_DIFF");
14635 }
14636 self.write(" = ");
14637 self.write(diff);
14638 }
14639 if let Some(canon) = canonical {
14640 self.write(", ");
14641 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
14642 self.write("canonical");
14643 } else {
14644 self.write_keyword("CANONICAL");
14645 }
14646 self.write(" = ");
14647 self.write(canon);
14648 }
14649 self.write(")");
14650 }
14651 TypeDefinition::Base {
14652 input,
14653 output,
14654 internallength,
14655 } => {
14656 self.write("(");
14657 self.write_keyword("INPUT");
14658 self.write(" = ");
14659 self.write(input);
14660 self.write(", ");
14661 self.write_keyword("OUTPUT");
14662 self.write(" = ");
14663 self.write(output);
14664 if let Some(len) = internallength {
14665 self.write(", ");
14666 self.write_keyword("INTERNALLENGTH");
14667 self.write(" = ");
14668 self.write(&len.to_string());
14669 }
14670 self.write(")");
14671 }
14672 TypeDefinition::Domain {
14673 base_type,
14674 default,
14675 constraints,
14676 } => {
14677 self.generate_data_type(base_type)?;
14678 if let Some(def) = default {
14679 self.write_space();
14680 self.write_keyword("DEFAULT");
14681 self.write_space();
14682 self.generate_expression(def)?;
14683 }
14684 for constr in constraints {
14685 self.write_space();
14686 if let Some(name) = &constr.name {
14687 self.write_keyword("CONSTRAINT");
14688 self.write_space();
14689 self.generate_identifier(name)?;
14690 self.write_space();
14691 }
14692 self.write_keyword("CHECK");
14693 self.write(" (");
14694 self.generate_expression(&constr.check)?;
14695 self.write(")");
14696 }
14697 }
14698 }
14699
14700 Ok(())
14701 }
14702
14703 fn generate_create_task(&mut self, task: &crate::expressions::CreateTask) -> Result<()> {
14704 self.write_keyword("CREATE");
14705 if task.or_replace {
14706 self.write_space();
14707 self.write_keyword("OR REPLACE");
14708 }
14709 self.write_space();
14710 self.write_keyword("TASK");
14711 if task.if_not_exists {
14712 self.write_space();
14713 self.write_keyword("IF NOT EXISTS");
14714 }
14715 self.write_space();
14716 self.write(&task.name);
14717 if !task.properties.is_empty() {
14718 if !task.properties.starts_with('\n') && !task.properties.starts_with(' ') {
14720 self.write_space();
14721 }
14722 self.write(&task.properties);
14723 }
14724 self.write_space();
14725 self.write_keyword("AS");
14726 self.write_space();
14727 self.generate_expression(&task.body)?;
14728 Ok(())
14729 }
14730
14731 fn generate_try_catch(&mut self, try_catch: &TryCatch) -> Result<()> {
14732 self.write_keyword("BEGIN TRY");
14733 self.generate_tsql_block_statements(&try_catch.try_body)?;
14734 self.write_keyword("END TRY");
14735
14736 if let Some(catch_body) = &try_catch.catch_body {
14737 if self.config.pretty {
14738 self.write_newline();
14739 self.write_indent();
14740 } else {
14741 self.write_space();
14742 }
14743 self.write_keyword("BEGIN CATCH");
14744 self.generate_tsql_block_statements(catch_body)?;
14745 self.write_keyword("END CATCH");
14746 }
14747
14748 Ok(())
14749 }
14750
14751 fn generate_tsql_block_statements(&mut self, statements: &[Expression]) -> Result<()> {
14752 if statements.is_empty() {
14753 self.write_space();
14754 return Ok(());
14755 }
14756
14757 if self.config.pretty {
14758 self.indent_level += 1;
14759 for stmt in statements {
14760 self.write_newline();
14761 self.write_indent();
14762 self.generate_expression(stmt)?;
14763 self.write(";");
14764 }
14765 self.indent_level -= 1;
14766 self.write_newline();
14767 self.write_indent();
14768 } else {
14769 self.write_space();
14770 for (i, stmt) in statements.iter().enumerate() {
14771 if i > 0 {
14772 self.write_space();
14773 }
14774 self.generate_expression(stmt)?;
14775 self.write(";");
14776 }
14777 self.write_space();
14778 }
14779
14780 Ok(())
14781 }
14782
14783 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
14784 self.write_keyword("DROP TYPE");
14785
14786 if dt.if_exists {
14787 self.write_space();
14788 self.write_keyword("IF EXISTS");
14789 }
14790
14791 self.write_space();
14792 self.generate_table(&dt.name)?;
14793
14794 if dt.cascade {
14795 self.write_space();
14796 self.write_keyword("CASCADE");
14797 }
14798
14799 Ok(())
14800 }
14801
14802 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
14803 let saved_athena_hive_context = self.athena_hive_context;
14805 if matches!(
14806 self.config.dialect,
14807 Some(crate::dialects::DialectType::Athena)
14808 ) {
14809 self.athena_hive_context = true;
14810 }
14811
14812 for comment in &d.leading_comments {
14814 self.write_formatted_comment(comment);
14815 self.write(" ");
14816 }
14817
14818 self.write_keyword("DESCRIBE");
14819
14820 if d.extended {
14821 self.write_space();
14822 self.write_keyword("EXTENDED");
14823 } else if d.formatted {
14824 self.write_space();
14825 self.write_keyword("FORMATTED");
14826 }
14827
14828 if let Some(ref style) = d.style {
14830 self.write_space();
14831 self.write_keyword(style);
14832 }
14833
14834 let should_output_kind = match self.config.dialect {
14836 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
14838 false
14839 }
14840 Some(DialectType::Snowflake) => true,
14842 _ => d.kind.is_some(),
14843 };
14844 if should_output_kind {
14845 if let Some(ref kind) = d.kind {
14846 self.write_space();
14847 self.write_keyword(kind);
14848 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
14849 self.write_space();
14850 self.write_keyword("TABLE");
14851 }
14852 }
14853
14854 self.write_space();
14855 self.generate_expression(&d.target)?;
14856
14857 if !d.params.is_empty() {
14859 self.write("(");
14860 for (i, param) in d.params.iter().enumerate() {
14861 if i > 0 {
14862 self.write(", ");
14863 }
14864 self.write(param);
14865 }
14866 self.write(")");
14867 }
14868
14869 if let Some(ref partition) = d.partition {
14871 self.write_space();
14872 self.generate_expression(partition)?;
14873 }
14874
14875 if d.as_json {
14877 self.write_space();
14878 self.write_keyword("AS JSON");
14879 }
14880
14881 for (name, value) in &d.properties {
14883 self.write_space();
14884 self.write(name);
14885 self.write("=");
14886 self.write(value);
14887 }
14888
14889 self.athena_hive_context = saved_athena_hive_context;
14891
14892 Ok(())
14893 }
14894
14895 fn generate_show(&mut self, s: &Show) -> Result<()> {
14898 self.write_keyword("SHOW");
14899 self.write_space();
14900
14901 let show_terse = s.terse
14904 && !matches!(
14905 s.this.as_str(),
14906 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
14907 );
14908 if show_terse {
14909 self.write_keyword("TERSE");
14910 self.write_space();
14911 }
14912
14913 self.write_keyword(&s.this);
14915
14916 if let Some(ref target_expr) = s.target {
14918 self.write_space();
14919 self.generate_expression(target_expr)?;
14920 }
14921
14922 if s.history {
14924 self.write_space();
14925 self.write_keyword("HISTORY");
14926 }
14927
14928 if let Some(ref for_target) = s.for_target {
14930 self.write_space();
14931 self.write_keyword("FOR");
14932 self.write_space();
14933 self.generate_expression(for_target)?;
14934 }
14935
14936 use crate::dialects::DialectType;
14940 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
14941 let is_mysql = matches!(self.config.dialect, Some(DialectType::MySQL));
14942 let mysql_tables_scope_as_from = is_mysql
14943 && matches!(s.this.as_str(), "TABLES" | "FULL TABLES")
14944 && s.scope_kind.as_deref() == Some("SCHEMA")
14945 && s.scope.is_some()
14946 && s.from.is_none();
14947
14948 if !is_snowflake && s.from.is_some() {
14949 if let Some(ref scope_kind) = s.scope_kind {
14953 self.write_space();
14954 self.write_keyword("IN");
14955 self.write_space();
14956 self.write_keyword(scope_kind);
14957 if let Some(ref scope) = s.scope {
14958 self.write_space();
14959 self.generate_expression(scope)?;
14960 }
14961 } else if let Some(ref scope) = s.scope {
14962 self.write_space();
14963 self.write_keyword("IN");
14964 self.write_space();
14965 self.generate_expression(scope)?;
14966 }
14967
14968 if let Some(ref from) = s.from {
14970 self.write_space();
14971 self.write_keyword("FROM");
14972 self.write_space();
14973 self.generate_expression(from)?;
14974 }
14975
14976 if let Some(ref db) = s.db {
14978 self.write_space();
14979 self.write_keyword("FROM");
14980 self.write_space();
14981 self.generate_expression(db)?;
14982 }
14983
14984 if let Some(ref like) = s.like {
14986 self.write_space();
14987 self.write_keyword("LIKE");
14988 self.write_space();
14989 self.generate_expression(like)?;
14990 }
14991 } else {
14992 if let Some(ref like) = s.like {
14996 self.write_space();
14997 self.write_keyword("LIKE");
14998 self.write_space();
14999 self.generate_expression(like)?;
15000 }
15001
15002 if mysql_tables_scope_as_from {
15004 self.write_space();
15005 self.write_keyword("FROM");
15006 self.write_space();
15007 self.generate_expression(s.scope.as_ref().unwrap())?;
15008 } else if let Some(ref scope_kind) = s.scope_kind {
15009 self.write_space();
15010 self.write_keyword("IN");
15011 self.write_space();
15012 self.write_keyword(scope_kind);
15013 if let Some(ref scope) = s.scope {
15014 self.write_space();
15015 self.generate_expression(scope)?;
15016 }
15017 } else if let Some(ref scope) = s.scope {
15018 self.write_space();
15019 self.write_keyword("IN");
15020 self.write_space();
15021 self.generate_expression(scope)?;
15022 }
15023 }
15024
15025 if let Some(ref starts_with) = s.starts_with {
15027 self.write_space();
15028 self.write_keyword("STARTS WITH");
15029 self.write_space();
15030 self.generate_expression(starts_with)?;
15031 }
15032
15033 if let Some(ref limit) = s.limit {
15035 self.write_space();
15036 self.generate_limit(limit)?;
15037 }
15038
15039 if is_snowflake {
15041 if let Some(ref from) = s.from {
15042 self.write_space();
15043 self.write_keyword("FROM");
15044 self.write_space();
15045 self.generate_expression(from)?;
15046 }
15047 }
15048
15049 if let Some(ref where_clause) = s.where_clause {
15051 self.write_space();
15052 self.write_keyword("WHERE");
15053 self.write_space();
15054 self.generate_expression(where_clause)?;
15055 }
15056
15057 if let Some(is_mutex) = s.mutex {
15059 self.write_space();
15060 if is_mutex {
15061 self.write_keyword("MUTEX");
15062 } else {
15063 self.write_keyword("STATUS");
15064 }
15065 }
15066
15067 if !s.privileges.is_empty() {
15069 self.write_space();
15070 self.write_keyword("WITH PRIVILEGES");
15071 self.write_space();
15072 for (i, priv_name) in s.privileges.iter().enumerate() {
15073 if i > 0 {
15074 self.write(", ");
15075 }
15076 self.write_keyword(priv_name);
15077 }
15078 }
15079
15080 Ok(())
15081 }
15082
15083 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
15086 use crate::dialects::DialectType;
15087 match lit {
15088 Literal::String(s) => {
15089 self.generate_string_literal(s)?;
15090 }
15091 Literal::Number(n) => {
15092 if matches!(self.config.dialect, Some(DialectType::MySQL))
15093 && n.len() > 2
15094 && (n.starts_with("0x") || n.starts_with("0X"))
15095 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
15096 {
15097 return self.generate_identifier(&Identifier {
15098 name: n.clone(),
15099 quoted: true,
15100 trailing_comments: Vec::new(),
15101 span: None,
15102 });
15103 }
15104 let n = if n.contains('_')
15108 && !matches!(
15109 self.config.dialect,
15110 Some(DialectType::ClickHouse)
15111 | Some(DialectType::DuckDB)
15112 | Some(DialectType::PostgreSQL)
15113 | Some(DialectType::Hive)
15114 | Some(DialectType::Spark)
15115 | Some(DialectType::Databricks)
15116 ) {
15117 std::borrow::Cow::Owned(n.replace('_', ""))
15118 } else {
15119 std::borrow::Cow::Borrowed(n.as_str())
15120 };
15121 if n.starts_with('.') {
15124 self.write("0");
15125 self.write(&n);
15126 } else if n.starts_with("-.") {
15127 self.write("-0");
15129 self.write(&n[1..]);
15130 } else {
15131 self.write(&n);
15132 }
15133 }
15134 Literal::HexString(h) => {
15135 match self.config.dialect {
15137 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
15138 self.write("0x");
15139 self.write(h);
15140 return Ok(());
15141 }
15142 Some(DialectType::Spark)
15143 | Some(DialectType::Databricks)
15144 | Some(DialectType::Teradata) => self.write("X'"),
15145 _ => self.write("x'"),
15146 }
15147 self.write(h);
15148 self.write("'");
15149 }
15150 Literal::HexNumber(h) => {
15151 match self.config.dialect {
15155 Some(DialectType::BigQuery)
15156 | Some(DialectType::ClickHouse)
15157 | Some(DialectType::TSQL)
15158 | Some(DialectType::Fabric) => {
15159 self.write("0x");
15160 self.write(h);
15161 }
15162 _ => {
15163 if let Ok(val) = u64::from_str_radix(h, 16) {
15165 self.write(&val.to_string());
15166 } else {
15167 self.write("0x");
15169 self.write(h);
15170 }
15171 }
15172 }
15173 }
15174 Literal::BitString(b) => {
15175 self.write("B'");
15177 self.write(b);
15178 self.write("'");
15179 }
15180 Literal::ByteString(b) => {
15181 self.write("b'");
15183 self.write_escaped_byte_string(b);
15185 self.write("'");
15186 }
15187 Literal::NationalString(s) => {
15188 let keep_n_prefix = matches!(
15191 self.config.dialect,
15192 Some(DialectType::TSQL)
15193 | Some(DialectType::Oracle)
15194 | Some(DialectType::MySQL)
15195 | None
15196 );
15197 if keep_n_prefix {
15198 self.write("N'");
15199 } else {
15200 self.write("'");
15201 }
15202 self.write(s);
15203 self.write("'");
15204 }
15205 Literal::Date(d) => {
15206 self.generate_date_literal(d)?;
15207 }
15208 Literal::Time(t) => {
15209 self.generate_time_literal(t)?;
15210 }
15211 Literal::Timestamp(ts) => {
15212 self.generate_timestamp_literal(ts)?;
15213 }
15214 Literal::Datetime(dt) => {
15215 self.generate_datetime_literal(dt)?;
15216 }
15217 Literal::TripleQuotedString(s, _quote_char) => {
15218 if matches!(
15220 self.config.dialect,
15221 Some(crate::dialects::DialectType::BigQuery)
15222 | Some(crate::dialects::DialectType::DuckDB)
15223 | Some(crate::dialects::DialectType::Snowflake)
15224 | Some(crate::dialects::DialectType::Spark)
15225 | Some(crate::dialects::DialectType::Hive)
15226 | Some(crate::dialects::DialectType::Presto)
15227 | Some(crate::dialects::DialectType::Trino)
15228 | Some(crate::dialects::DialectType::PostgreSQL)
15229 | Some(crate::dialects::DialectType::MySQL)
15230 | Some(crate::dialects::DialectType::Redshift)
15231 | Some(crate::dialects::DialectType::TSQL)
15232 | Some(crate::dialects::DialectType::Oracle)
15233 | Some(crate::dialects::DialectType::ClickHouse)
15234 | Some(crate::dialects::DialectType::Databricks)
15235 | Some(crate::dialects::DialectType::SQLite)
15236 ) {
15237 self.generate_string_literal(s)?;
15238 } else {
15239 let quotes = format!("{0}{0}{0}", _quote_char);
15241 self.write("es);
15242 self.write(s);
15243 self.write("es);
15244 }
15245 }
15246 Literal::EscapeString(s) => {
15247 use crate::dialects::DialectType;
15251 let content = if let Some(c) = s.strip_prefix("e:") {
15252 c
15253 } else if let Some(c) = s.strip_prefix("E:") {
15254 c
15255 } else {
15256 s.as_str()
15257 };
15258
15259 if matches!(
15261 self.config.dialect,
15262 Some(DialectType::MySQL) | Some(DialectType::TiDB)
15263 ) {
15264 self.write("'");
15265 self.write(&content.replace('\'', "''"));
15266 self.write("'");
15267 } else {
15268 let prefix = if matches!(
15270 self.config.dialect,
15271 Some(DialectType::SingleStore)
15272 | Some(DialectType::DuckDB)
15273 | Some(DialectType::PostgreSQL)
15274 | Some(DialectType::CockroachDB)
15275 | Some(DialectType::Materialize)
15276 | Some(DialectType::RisingWave)
15277 ) {
15278 "e'"
15279 } else {
15280 "E'"
15281 };
15282
15283 let normalized = content.replace("\\'", "''");
15285 self.write(prefix);
15286 self.write(&normalized);
15287 self.write("'");
15288 }
15289 }
15290 Literal::DollarString(s) => {
15291 use crate::dialects::DialectType;
15294 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
15296 let escape_backslash = matches!(
15298 self.config.dialect,
15299 Some(DialectType::ClickHouse) | Some(DialectType::Snowflake)
15300 );
15301 let use_backslash_quote =
15305 matches!(self.config.dialect, Some(DialectType::Snowflake));
15306
15307 let mut escaped = String::with_capacity(content.len() + 4);
15308 for ch in content.chars() {
15309 if escape_backslash && ch == '\\' {
15310 escaped.push('\\');
15312 escaped.push('\\');
15313 } else if ch == '\'' {
15314 if use_backslash_quote {
15315 escaped.push('\\');
15316 escaped.push('\'');
15317 } else {
15318 escaped.push('\'');
15319 escaped.push('\'');
15320 }
15321 } else {
15322 escaped.push(ch);
15323 }
15324 }
15325 self.write("'");
15326 self.write(&escaped);
15327 self.write("'");
15328 }
15329 Literal::RawString(s) => {
15330 use crate::dialects::DialectType;
15336
15337 let escape_backslash = matches!(
15339 self.config.dialect,
15340 Some(DialectType::BigQuery)
15341 | Some(DialectType::MySQL)
15342 | Some(DialectType::SingleStore)
15343 | Some(DialectType::TiDB)
15344 | Some(DialectType::Hive)
15345 | Some(DialectType::Spark)
15346 | Some(DialectType::Databricks)
15347 | Some(DialectType::Drill)
15348 | Some(DialectType::Snowflake)
15349 | Some(DialectType::Redshift)
15350 | Some(DialectType::ClickHouse)
15351 );
15352
15353 let backslash_escapes_quote = matches!(
15356 self.config.dialect,
15357 Some(DialectType::BigQuery)
15358 | Some(DialectType::Hive)
15359 | Some(DialectType::Spark)
15360 | Some(DialectType::Databricks)
15361 | Some(DialectType::Drill)
15362 | Some(DialectType::Snowflake)
15363 | Some(DialectType::Redshift)
15364 );
15365
15366 let supports_escape_sequences = escape_backslash;
15369
15370 let mut escaped = String::with_capacity(s.len() + 4);
15371 for ch in s.chars() {
15372 if escape_backslash && ch == '\\' {
15373 escaped.push('\\');
15375 escaped.push('\\');
15376 } else if ch == '\'' {
15377 if backslash_escapes_quote {
15378 escaped.push('\\');
15380 escaped.push('\'');
15381 } else {
15382 escaped.push('\'');
15384 escaped.push('\'');
15385 }
15386 } else if supports_escape_sequences {
15387 match ch {
15390 '\n' => {
15391 escaped.push('\\');
15392 escaped.push('n');
15393 }
15394 '\r' => {
15395 escaped.push('\\');
15396 escaped.push('r');
15397 }
15398 '\t' => {
15399 escaped.push('\\');
15400 escaped.push('t');
15401 }
15402 '\x07' => {
15403 escaped.push('\\');
15404 escaped.push('a');
15405 }
15406 '\x08' => {
15407 escaped.push('\\');
15408 escaped.push('b');
15409 }
15410 '\x0C' => {
15411 escaped.push('\\');
15412 escaped.push('f');
15413 }
15414 '\x0B' => {
15415 escaped.push('\\');
15416 escaped.push('v');
15417 }
15418 _ => escaped.push(ch),
15419 }
15420 } else {
15421 escaped.push(ch);
15422 }
15423 }
15424 self.write("'");
15425 self.write(&escaped);
15426 self.write("'");
15427 }
15428 }
15429 Ok(())
15430 }
15431
15432 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
15434 use crate::dialects::DialectType;
15435
15436 match self.config.dialect {
15437 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
15439 self.write("CAST('");
15440 self.write(d);
15441 self.write("' AS DATE)");
15442 }
15443 Some(DialectType::BigQuery) => {
15446 self.write("CAST('");
15447 self.write(d);
15448 self.write("' AS DATE)");
15449 }
15450 Some(DialectType::Exasol) => {
15453 self.write("CAST('");
15454 self.write(d);
15455 self.write("' AS DATE)");
15456 }
15457 Some(DialectType::Snowflake) => {
15460 self.write("CAST('");
15461 self.write(d);
15462 self.write("' AS DATE)");
15463 }
15464 Some(DialectType::PostgreSQL)
15466 | Some(DialectType::MySQL)
15467 | Some(DialectType::SingleStore)
15468 | Some(DialectType::TiDB)
15469 | Some(DialectType::Redshift) => {
15470 self.write("CAST('");
15471 self.write(d);
15472 self.write("' AS DATE)");
15473 }
15474 Some(DialectType::DuckDB)
15476 | Some(DialectType::Presto)
15477 | Some(DialectType::Trino)
15478 | Some(DialectType::Athena)
15479 | Some(DialectType::Spark)
15480 | Some(DialectType::Databricks)
15481 | Some(DialectType::Hive) => {
15482 self.write("CAST('");
15483 self.write(d);
15484 self.write("' AS DATE)");
15485 }
15486 Some(DialectType::Oracle) => {
15488 self.write("TO_DATE('");
15489 self.write(d);
15490 self.write("', 'YYYY-MM-DD')");
15491 }
15492 _ => {
15494 self.write_keyword("DATE");
15495 self.write(" '");
15496 self.write(d);
15497 self.write("'");
15498 }
15499 }
15500 Ok(())
15501 }
15502
15503 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
15505 use crate::dialects::DialectType;
15506
15507 match self.config.dialect {
15508 Some(DialectType::TSQL) => {
15510 self.write("CAST('");
15511 self.write(t);
15512 self.write("' AS TIME)");
15513 }
15514 _ => {
15516 self.write_keyword("TIME");
15517 self.write(" '");
15518 self.write(t);
15519 self.write("'");
15520 }
15521 }
15522 Ok(())
15523 }
15524
15525 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
15527 use crate::expressions::Literal;
15528
15529 match expr {
15530 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
15531 let Literal::Date(d) = lit.as_ref() else {
15532 unreachable!()
15533 };
15534 self.write("CAST('");
15536 self.write(d);
15537 self.write("' AS DATE)");
15538 }
15539 _ => {
15540 self.generate_expression(expr)?;
15542 }
15543 }
15544 Ok(())
15545 }
15546
15547 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
15549 use crate::dialects::DialectType;
15550
15551 match self.config.dialect {
15552 Some(DialectType::TSQL) => {
15554 self.write("CAST('");
15555 self.write(ts);
15556 self.write("' AS DATETIME2)");
15557 }
15558 Some(DialectType::BigQuery) => {
15561 self.write("CAST('");
15562 self.write(ts);
15563 self.write("' AS TIMESTAMP)");
15564 }
15565 Some(DialectType::Snowflake) => {
15568 self.write("CAST('");
15569 self.write(ts);
15570 self.write("' AS TIMESTAMP)");
15571 }
15572 Some(DialectType::Dremio) => {
15575 self.write("CAST('");
15576 self.write(ts);
15577 self.write("' AS TIMESTAMP)");
15578 }
15579 Some(DialectType::Exasol) => {
15582 self.write("CAST('");
15583 self.write(ts);
15584 self.write("' AS TIMESTAMP)");
15585 }
15586 Some(DialectType::Oracle) => {
15589 self.write("TO_TIMESTAMP('");
15590 self.write(ts);
15591 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
15592 }
15593 Some(DialectType::Presto) | Some(DialectType::Trino) => {
15595 if Self::timestamp_has_timezone(ts) {
15596 self.write("CAST('");
15597 self.write(ts);
15598 self.write("' AS TIMESTAMP WITH TIME ZONE)");
15599 } else {
15600 self.write("CAST('");
15601 self.write(ts);
15602 self.write("' AS TIMESTAMP)");
15603 }
15604 }
15605 Some(DialectType::ClickHouse) => {
15607 self.write("CAST('");
15608 self.write(ts);
15609 self.write("' AS Nullable(DateTime))");
15610 }
15611 Some(DialectType::Spark) => {
15613 self.write("CAST('");
15614 self.write(ts);
15615 self.write("' AS TIMESTAMP)");
15616 }
15617 Some(DialectType::Redshift) => {
15620 if ts == "epoch" {
15621 self.write_keyword("TIMESTAMP");
15622 self.write(" '");
15623 self.write(ts);
15624 self.write("'");
15625 } else {
15626 self.write("CAST('");
15627 self.write(ts);
15628 self.write("' AS TIMESTAMP)");
15629 }
15630 }
15631 Some(DialectType::PostgreSQL)
15633 | Some(DialectType::Hive)
15634 | Some(DialectType::SQLite)
15635 | Some(DialectType::DuckDB)
15636 | Some(DialectType::Athena)
15637 | Some(DialectType::Drill)
15638 | Some(DialectType::Teradata) => {
15639 self.write("CAST('");
15640 self.write(ts);
15641 self.write("' AS TIMESTAMP)");
15642 }
15643 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
15645 self.write("CAST('");
15646 self.write(ts);
15647 self.write("' AS DATETIME)");
15648 }
15649 Some(DialectType::Databricks) => {
15651 self.write("CAST('");
15652 self.write(ts);
15653 self.write("' AS TIMESTAMP_NTZ)");
15654 }
15655 _ => {
15657 self.write_keyword("TIMESTAMP");
15658 self.write(" '");
15659 self.write(ts);
15660 self.write("'");
15661 }
15662 }
15663 Ok(())
15664 }
15665
15666 fn timestamp_has_timezone(ts: &str) -> bool {
15669 let ts_lower = ts.to_ascii_lowercase();
15673
15674 let continent_prefixes = [
15676 "africa/",
15677 "america/",
15678 "antarctica/",
15679 "arctic/",
15680 "asia/",
15681 "atlantic/",
15682 "australia/",
15683 "europe/",
15684 "indian/",
15685 "pacific/",
15686 "etc/",
15687 "brazil/",
15688 "canada/",
15689 "chile/",
15690 "mexico/",
15691 "us/",
15692 ];
15693
15694 for prefix in &continent_prefixes {
15695 if ts_lower.contains(prefix) {
15696 return true;
15697 }
15698 }
15699
15700 let tz_abbrevs = [
15703 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
15704 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
15705 " sgt", " aest", " aedt", " acst", " acdt", " awst",
15706 ];
15707
15708 for abbrev in &tz_abbrevs {
15709 if ts_lower.ends_with(abbrev) {
15710 return true;
15711 }
15712 }
15713
15714 let trimmed = ts.trim();
15718 if let Some(last_space) = trimmed.rfind(' ') {
15719 let suffix = &trimmed[last_space + 1..];
15720 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
15721 let rest = &suffix[1..];
15723 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
15724 return true;
15725 }
15726 }
15727 }
15728
15729 false
15730 }
15731
15732 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
15734 use crate::dialects::DialectType;
15735
15736 match self.config.dialect {
15737 Some(DialectType::BigQuery) => {
15740 self.write("CAST('");
15741 self.write(dt);
15742 self.write("' AS DATETIME)");
15743 }
15744 Some(DialectType::DuckDB) => {
15746 self.write("CAST('");
15747 self.write(dt);
15748 self.write("' AS TIMESTAMP)");
15749 }
15750 _ => {
15753 self.write_keyword("DATETIME");
15754 self.write(" '");
15755 self.write(dt);
15756 self.write("'");
15757 }
15758 }
15759 Ok(())
15760 }
15761
15762 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
15764 use crate::dialects::DialectType;
15765
15766 match self.config.dialect {
15767 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
15771 self.write("'");
15773 for c in s.chars() {
15774 match c {
15775 '\'' => self.write("\\'"),
15776 '\\' => self.write("\\\\"),
15777 '\n' => self.write("\\n"),
15778 '\r' => self.write("\\r"),
15779 '\t' => self.write("\\t"),
15780 '\0' => self.write("\\0"),
15781 _ => self.output.push(c),
15782 }
15783 }
15784 self.write("'");
15785 }
15786 Some(DialectType::Drill) => {
15787 self.write("'");
15790 for c in s.chars() {
15791 match c {
15792 '\'' => self.write("''"),
15793 '\\' => self.write("\\\\"),
15794 '\n' => self.write("\\n"),
15795 '\r' => self.write("\\r"),
15796 '\t' => self.write("\\t"),
15797 '\0' => self.write("\\0"),
15798 _ => self.output.push(c),
15799 }
15800 }
15801 self.write("'");
15802 }
15803 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
15804 self.write("'");
15805 for c in s.chars() {
15806 match c {
15807 '\'' => self.write("''"),
15809 '\\' => self.write("\\\\"),
15810 '\n' => self.write("\\n"),
15811 '\r' => self.write("\\r"),
15812 '\t' => self.write("\\t"),
15813 '\0' => self.output.push('\0'),
15815 _ => self.output.push(c),
15816 }
15817 }
15818 self.write("'");
15819 }
15820 Some(DialectType::BigQuery) => {
15822 self.write("'");
15823 for c in s.chars() {
15824 match c {
15825 '\'' => self.write("\\'"),
15826 '\\' => self.write("\\\\"),
15827 '\n' => self.write("\\n"),
15828 '\r' => self.write("\\r"),
15829 '\t' => self.write("\\t"),
15830 '\0' => self.write("\\0"),
15831 '\x07' => self.write("\\a"),
15832 '\x08' => self.write("\\b"),
15833 '\x0C' => self.write("\\f"),
15834 '\x0B' => self.write("\\v"),
15835 _ => self.output.push(c),
15836 }
15837 }
15838 self.write("'");
15839 }
15840 Some(DialectType::Athena) => {
15844 if self.athena_hive_context {
15845 self.write("'");
15847 for c in s.chars() {
15848 match c {
15849 '\'' => self.write("\\'"),
15850 '\\' => self.write("\\\\"),
15851 '\n' => self.write("\\n"),
15852 '\r' => self.write("\\r"),
15853 '\t' => self.write("\\t"),
15854 '\0' => self.write("\\0"),
15855 _ => self.output.push(c),
15856 }
15857 }
15858 self.write("'");
15859 } else {
15860 self.write("'");
15862 for c in s.chars() {
15863 match c {
15864 '\'' => self.write("''"),
15865 _ => self.output.push(c),
15867 }
15868 }
15869 self.write("'");
15870 }
15871 }
15872 Some(DialectType::Snowflake) => {
15877 self.write("'");
15878 for c in s.chars() {
15879 match c {
15880 '\'' => self.write("\\'"),
15881 '\n' => self.write("\\n"),
15884 '\r' => self.write("\\r"),
15885 '\t' => self.write("\\t"),
15886 _ => self.output.push(c),
15887 }
15888 }
15889 self.write("'");
15890 }
15891 Some(DialectType::PostgreSQL) => {
15893 self.write("'");
15894 for c in s.chars() {
15895 match c {
15896 '\'' => self.write("''"),
15897 _ => self.output.push(c),
15898 }
15899 }
15900 self.write("'");
15901 }
15902 Some(DialectType::Redshift) => {
15904 self.write("'");
15905 for c in s.chars() {
15906 match c {
15907 '\'' => self.write("\\'"),
15908 _ => self.output.push(c),
15909 }
15910 }
15911 self.write("'");
15912 }
15913 Some(DialectType::Oracle) => {
15915 self.write("'");
15916 for ch in s.chars() {
15917 if ch == '\'' {
15918 self.output.push_str("''");
15919 } else {
15920 self.output.push(ch);
15921 }
15922 }
15923 self.write("'");
15924 }
15925 Some(DialectType::ClickHouse) => {
15928 self.write("'");
15929 for c in s.chars() {
15930 match c {
15931 '\'' => self.write("''"),
15932 '\\' => self.write("\\\\"),
15933 '\n' => self.write("\\n"),
15934 '\r' => self.write("\\r"),
15935 '\t' => self.write("\\t"),
15936 '\0' => self.write("\\0"),
15937 '\x07' => self.write("\\a"),
15938 '\x08' => self.write("\\b"),
15939 '\x0C' => self.write("\\f"),
15940 '\x0B' => self.write("\\v"),
15941 c if c.is_control() || (c as u32) < 0x20 => {
15943 let byte = c as u32;
15944 if byte < 256 {
15945 self.write(&format!("\\x{:02X}", byte));
15946 } else {
15947 self.output.push(c);
15948 }
15949 }
15950 _ => self.output.push(c),
15951 }
15952 }
15953 self.write("'");
15954 }
15955 _ => {
15958 self.write("'");
15959 for ch in s.chars() {
15960 if ch == '\'' {
15961 self.output.push_str("''");
15962 } else {
15963 self.output.push(ch);
15964 }
15965 }
15966 self.write("'");
15967 }
15968 }
15969 Ok(())
15970 }
15971
15972 fn write_escaped_byte_string(&mut self, s: &str) {
15975 for c in s.chars() {
15976 match c {
15977 '\'' => self.write("\\'"),
15979 '\\' => self.write("\\\\"),
15981 _ if !c.is_control() => self.output.push(c),
15983 _ => {
15985 let byte = c as u32;
15986 if byte < 256 {
15987 self.write(&format!("\\x{:02x}", byte));
15988 } else {
15989 for b in c.to_string().as_bytes() {
15991 self.write(&format!("\\x{:02x}", b));
15992 }
15993 }
15994 }
15995 }
15996 }
15997 }
15998
15999 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
16000 use crate::dialects::DialectType;
16001
16002 match self.config.dialect {
16004 Some(DialectType::TSQL) => {
16007 self.write(if b.value { "1" } else { "0" });
16008 }
16009 Some(DialectType::Oracle) => {
16011 self.write(if b.value { "1" } else { "0" });
16012 }
16013 Some(DialectType::MySQL) => {
16015 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
16016 }
16017 _ => {
16019 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
16020 }
16021 }
16022 Ok(())
16023 }
16024
16025 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
16028 let name = &id.name;
16029 let quote_style = &self.config.identifier_quote_style;
16030
16031 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
16035
16036 let output_name = if self.config.normalize_identifiers && !id.quoted {
16038 name.to_ascii_lowercase()
16039 } else {
16040 name.to_string()
16041 };
16042
16043 if needs_quoting {
16044 let quote_style = if matches!(self.config.dialect, Some(DialectType::ClickHouse))
16045 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
16046 && quote_style.start == '"'
16047 && output_name.contains('"')
16048 {
16049 &IdentifierQuoteStyle::BACKTICK
16050 } else {
16051 quote_style
16052 };
16053 let escaped_name = if quote_style.start == quote_style.end {
16055 output_name.replace(
16056 quote_style.end,
16057 &format!("{}{}", quote_style.end, quote_style.end),
16058 )
16059 } else {
16060 output_name.replace(
16061 quote_style.end,
16062 &format!("{}{}", quote_style.end, quote_style.end),
16063 )
16064 };
16065 self.write(&format!(
16066 "{}{}{}",
16067 quote_style.start, escaped_name, quote_style.end
16068 ));
16069 } else {
16070 self.write(&output_name);
16071 }
16072
16073 for comment in &id.trailing_comments {
16075 self.write(" ");
16076 self.write_formatted_comment(comment);
16077 }
16078 Ok(())
16079 }
16080
16081 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
16082 use crate::dialects::DialectType;
16083
16084 let name = &id.name;
16085
16086 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
16088 && self.athena_hive_context
16089 {
16090 &IdentifierQuoteStyle::BACKTICK
16091 } else {
16092 &self.config.identifier_quote_style
16093 };
16094
16095 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
16102 let needs_digit_quoting = starts_with_digit
16103 && !self.config.identifiers_can_start_with_digit
16104 && self.config.dialect.is_some();
16105 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
16106 && name.len() > 2
16107 && (name.starts_with("0x") || name.starts_with("0X"))
16108 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
16109 let clickhouse_unsafe_identifier =
16110 matches!(self.config.dialect, Some(DialectType::ClickHouse))
16111 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
16112 && !name.starts_with('{')
16113 && !name.contains('(')
16114 && !name.contains(')')
16115 && name != "?"
16116 && name
16117 .chars()
16118 .any(|c| !(c.is_ascii_alphanumeric() || c == '_'));
16119 let needs_quoting = id.quoted
16120 || self.is_reserved_keyword(name)
16121 || self.config.always_quote_identifiers
16122 || needs_digit_quoting
16123 || mysql_invalid_hex_identifier
16124 || clickhouse_unsafe_identifier;
16125
16126 let (base_name, suffix) = if needs_quoting {
16129 if let Some(paren_pos) = name.find('(') {
16131 let base = &name[..paren_pos];
16132 let rest = &name[paren_pos..];
16133 if rest.starts_with('(')
16135 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
16136 {
16137 let close_paren = rest.find(')').unwrap_or(rest.len());
16139 let inside = &rest[1..close_paren];
16140 if inside.chars().all(|c| c.is_ascii_digit()) {
16141 (base.to_string(), rest.to_string())
16142 } else {
16143 (name.to_string(), String::new())
16144 }
16145 } else {
16146 (name.to_string(), String::new())
16147 }
16148 } else if name.ends_with(" ASC") {
16149 let base = &name[..name.len() - 4];
16150 (base.to_string(), " ASC".to_string())
16151 } else if name.ends_with(" DESC") {
16152 let base = &name[..name.len() - 5];
16153 (base.to_string(), " DESC".to_string())
16154 } else {
16155 (name.to_string(), String::new())
16156 }
16157 } else {
16158 (name.to_string(), String::new())
16159 };
16160
16161 let output_name = if self.config.normalize_identifiers && !id.quoted {
16165 base_name.to_ascii_lowercase()
16166 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
16167 && !id.quoted
16168 && self.is_reserved_keyword(name)
16169 {
16170 base_name.to_ascii_uppercase()
16173 } else {
16174 base_name
16175 };
16176
16177 if needs_quoting {
16178 let escaped_name = if quote_style.start == quote_style.end {
16180 output_name.replace(
16182 quote_style.end,
16183 &format!("{}{}", quote_style.end, quote_style.end),
16184 )
16185 } else {
16186 output_name.replace(
16188 quote_style.end,
16189 &format!("{}{}", quote_style.end, quote_style.end),
16190 )
16191 };
16192 self.write(&format!(
16193 "{}{}{}{}",
16194 quote_style.start, escaped_name, quote_style.end, suffix
16195 ));
16196 } else {
16197 self.write(&output_name);
16198 }
16199
16200 for comment in &id.trailing_comments {
16202 self.write(" ");
16203 self.write_formatted_comment(comment);
16204 }
16205 Ok(())
16206 }
16207
16208 fn generate_column(&mut self, col: &Column) -> Result<()> {
16209 use crate::dialects::DialectType;
16210
16211 if let Some(table) = &col.table {
16212 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
16216 && !table.quoted
16217 && table.name.eq_ignore_ascii_case("LOCAL");
16218
16219 if is_exasol_local_prefix {
16220 self.write("LOCAL");
16222 } else {
16223 self.generate_identifier(table)?;
16224 }
16225 self.write(".");
16226 }
16227 self.generate_identifier(&col.name)?;
16228 if col.join_mark && self.config.supports_column_join_marks {
16231 self.write(" (+)");
16232 }
16233 for comment in &col.trailing_comments {
16235 self.write_space();
16236 self.write_formatted_comment(comment);
16237 }
16238 Ok(())
16239 }
16240
16241 fn generate_prepare(&mut self, prepare: &PrepareStatement) -> Result<()> {
16242 self.write_keyword("PREPARE");
16243 self.write_space();
16244 self.generate_identifier(&prepare.name)?;
16245
16246 if !prepare.parameter_types.is_empty() {
16247 self.write(" (");
16248 for (i, data_type) in prepare.parameter_types.iter().enumerate() {
16249 if i > 0 {
16250 self.write(", ");
16251 }
16252 self.generate_data_type(data_type)?;
16253 }
16254 self.write(")");
16255 }
16256
16257 self.write_space();
16258 self.write_keyword("AS");
16259 self.write_space();
16260 self.generate_expression(&prepare.statement)
16261 }
16262
16263 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
16266 use crate::dialects::DialectType;
16267 use crate::expressions::PseudocolumnType;
16268
16269 if pc.kind == PseudocolumnType::Sysdate
16271 && !matches!(
16272 self.config.dialect,
16273 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
16274 )
16275 {
16276 self.write_keyword("CURRENT_TIMESTAMP");
16277 if matches!(
16279 self.config.dialect,
16280 Some(DialectType::MySQL)
16281 | Some(DialectType::ClickHouse)
16282 | Some(DialectType::Spark)
16283 | Some(DialectType::Databricks)
16284 | Some(DialectType::Hive)
16285 ) {
16286 self.write("()");
16287 }
16288 } else {
16289 self.write(pc.kind.as_str());
16290 }
16291 Ok(())
16292 }
16293
16294 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
16296 use crate::dialects::DialectType;
16297
16298 let supports_connect_by = matches!(
16301 self.config.dialect,
16302 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
16303 );
16304
16305 if !supports_connect_by && self.config.dialect.is_some() {
16306 if self.config.pretty {
16308 self.write_newline();
16309 } else {
16310 self.write_space();
16311 }
16312 self.write_unsupported_comment(
16313 "CONNECT BY requires manual conversion to recursive CTE",
16314 )?;
16315 }
16316
16317 if let Some(start) = &connect.start {
16319 if self.config.pretty {
16320 self.write_newline();
16321 } else {
16322 self.write_space();
16323 }
16324 self.write_keyword("START WITH");
16325 self.write_space();
16326 self.generate_expression(start)?;
16327 }
16328
16329 if self.config.pretty {
16331 self.write_newline();
16332 } else {
16333 self.write_space();
16334 }
16335 self.write_keyword("CONNECT BY");
16336 if connect.nocycle {
16337 self.write_space();
16338 self.write_keyword("NOCYCLE");
16339 }
16340 self.write_space();
16341 self.generate_expression(&connect.connect)?;
16342
16343 Ok(())
16344 }
16345
16346 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
16348 self.generate_connect(connect)
16349 }
16350
16351 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
16353 self.write_keyword("PRIOR");
16354 self.write_space();
16355 self.generate_expression(&prior.this)?;
16356 Ok(())
16357 }
16358
16359 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
16362 self.write_keyword("CONNECT_BY_ROOT");
16363 self.write_space();
16364 self.generate_expression(&cbr.this)?;
16365 Ok(())
16366 }
16367
16368 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
16370 use crate::dialects::DialectType;
16371
16372 let supports_match_recognize = matches!(
16374 self.config.dialect,
16375 Some(DialectType::Oracle)
16376 | Some(DialectType::Snowflake)
16377 | Some(DialectType::Presto)
16378 | Some(DialectType::Trino)
16379 );
16380
16381 if let Some(source) = &mr.this {
16383 self.generate_expression(source)?;
16384 }
16385
16386 if !supports_match_recognize {
16387 self.write_unsupported_comment("MATCH_RECOGNIZE not supported in this dialect")?;
16388 return Ok(());
16389 }
16390
16391 if self.config.pretty {
16393 self.write_newline();
16394 } else {
16395 self.write_space();
16396 }
16397
16398 self.write_keyword("MATCH_RECOGNIZE");
16399 self.write(" (");
16400
16401 if self.config.pretty {
16402 self.indent_level += 1;
16403 }
16404
16405 let mut needs_separator = false;
16406
16407 if let Some(partition_by) = &mr.partition_by {
16409 if !partition_by.is_empty() {
16410 if self.config.pretty {
16411 self.write_newline();
16412 self.write_indent();
16413 }
16414 self.write_keyword("PARTITION BY");
16415 self.write_space();
16416 for (i, expr) in partition_by.iter().enumerate() {
16417 if i > 0 {
16418 self.write(", ");
16419 }
16420 self.generate_expression(expr)?;
16421 }
16422 needs_separator = true;
16423 }
16424 }
16425
16426 if let Some(order_by) = &mr.order_by {
16428 if !order_by.is_empty() {
16429 if needs_separator {
16430 if self.config.pretty {
16431 self.write_newline();
16432 self.write_indent();
16433 } else {
16434 self.write_space();
16435 }
16436 } else if self.config.pretty {
16437 self.write_newline();
16438 self.write_indent();
16439 }
16440 self.write_keyword("ORDER BY");
16441 if self.config.pretty {
16443 self.indent_level += 1;
16444 for (i, ordered) in order_by.iter().enumerate() {
16445 if i > 0 {
16446 self.write(",");
16447 }
16448 self.write_newline();
16449 self.write_indent();
16450 self.generate_ordered(ordered)?;
16451 }
16452 self.indent_level -= 1;
16453 } else {
16454 self.write_space();
16455 for (i, ordered) in order_by.iter().enumerate() {
16456 if i > 0 {
16457 self.write(", ");
16458 }
16459 self.generate_ordered(ordered)?;
16460 }
16461 }
16462 needs_separator = true;
16463 }
16464 }
16465
16466 if let Some(measures) = &mr.measures {
16468 if !measures.is_empty() {
16469 if needs_separator {
16470 if self.config.pretty {
16471 self.write_newline();
16472 self.write_indent();
16473 } else {
16474 self.write_space();
16475 }
16476 } else if self.config.pretty {
16477 self.write_newline();
16478 self.write_indent();
16479 }
16480 self.write_keyword("MEASURES");
16481 if self.config.pretty {
16483 self.indent_level += 1;
16484 for (i, measure) in measures.iter().enumerate() {
16485 if i > 0 {
16486 self.write(",");
16487 }
16488 self.write_newline();
16489 self.write_indent();
16490 if let Some(semantics) = &measure.window_frame {
16492 match semantics {
16493 MatchRecognizeSemantics::Running => {
16494 self.write_keyword("RUNNING");
16495 self.write_space();
16496 }
16497 MatchRecognizeSemantics::Final => {
16498 self.write_keyword("FINAL");
16499 self.write_space();
16500 }
16501 }
16502 }
16503 self.generate_expression(&measure.this)?;
16504 }
16505 self.indent_level -= 1;
16506 } else {
16507 self.write_space();
16508 for (i, measure) in measures.iter().enumerate() {
16509 if i > 0 {
16510 self.write(", ");
16511 }
16512 if let Some(semantics) = &measure.window_frame {
16514 match semantics {
16515 MatchRecognizeSemantics::Running => {
16516 self.write_keyword("RUNNING");
16517 self.write_space();
16518 }
16519 MatchRecognizeSemantics::Final => {
16520 self.write_keyword("FINAL");
16521 self.write_space();
16522 }
16523 }
16524 }
16525 self.generate_expression(&measure.this)?;
16526 }
16527 }
16528 needs_separator = true;
16529 }
16530 }
16531
16532 if let Some(rows) = &mr.rows {
16534 if needs_separator {
16535 if self.config.pretty {
16536 self.write_newline();
16537 self.write_indent();
16538 } else {
16539 self.write_space();
16540 }
16541 } else if self.config.pretty {
16542 self.write_newline();
16543 self.write_indent();
16544 }
16545 match rows {
16546 MatchRecognizeRows::OneRowPerMatch => {
16547 self.write_keyword("ONE ROW PER MATCH");
16548 }
16549 MatchRecognizeRows::AllRowsPerMatch => {
16550 self.write_keyword("ALL ROWS PER MATCH");
16551 }
16552 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
16553 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
16554 }
16555 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
16556 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
16557 }
16558 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
16559 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
16560 }
16561 }
16562 needs_separator = true;
16563 }
16564
16565 if let Some(after) = &mr.after {
16567 if needs_separator {
16568 if self.config.pretty {
16569 self.write_newline();
16570 self.write_indent();
16571 } else {
16572 self.write_space();
16573 }
16574 } else if self.config.pretty {
16575 self.write_newline();
16576 self.write_indent();
16577 }
16578 match after {
16579 MatchRecognizeAfter::PastLastRow => {
16580 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
16581 }
16582 MatchRecognizeAfter::ToNextRow => {
16583 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
16584 }
16585 MatchRecognizeAfter::ToFirst(ident) => {
16586 self.write_keyword("AFTER MATCH SKIP TO FIRST");
16587 self.write_space();
16588 self.generate_identifier(ident)?;
16589 }
16590 MatchRecognizeAfter::ToLast(ident) => {
16591 self.write_keyword("AFTER MATCH SKIP TO LAST");
16592 self.write_space();
16593 self.generate_identifier(ident)?;
16594 }
16595 }
16596 needs_separator = true;
16597 }
16598
16599 if let Some(pattern) = &mr.pattern {
16601 if needs_separator {
16602 if self.config.pretty {
16603 self.write_newline();
16604 self.write_indent();
16605 } else {
16606 self.write_space();
16607 }
16608 } else if self.config.pretty {
16609 self.write_newline();
16610 self.write_indent();
16611 }
16612 self.write_keyword("PATTERN");
16613 self.write_space();
16614 self.write("(");
16615 self.write(pattern);
16616 self.write(")");
16617 needs_separator = true;
16618 }
16619
16620 if let Some(define) = &mr.define {
16622 if !define.is_empty() {
16623 if needs_separator {
16624 if self.config.pretty {
16625 self.write_newline();
16626 self.write_indent();
16627 } else {
16628 self.write_space();
16629 }
16630 } else if self.config.pretty {
16631 self.write_newline();
16632 self.write_indent();
16633 }
16634 self.write_keyword("DEFINE");
16635 if self.config.pretty {
16637 self.indent_level += 1;
16638 for (i, (name, expr)) in define.iter().enumerate() {
16639 if i > 0 {
16640 self.write(",");
16641 }
16642 self.write_newline();
16643 self.write_indent();
16644 self.generate_identifier(name)?;
16645 self.write(" AS ");
16646 self.generate_expression(expr)?;
16647 }
16648 self.indent_level -= 1;
16649 } else {
16650 self.write_space();
16651 for (i, (name, expr)) in define.iter().enumerate() {
16652 if i > 0 {
16653 self.write(", ");
16654 }
16655 self.generate_identifier(name)?;
16656 self.write(" AS ");
16657 self.generate_expression(expr)?;
16658 }
16659 }
16660 }
16661 }
16662
16663 if self.config.pretty {
16664 self.indent_level -= 1;
16665 self.write_newline();
16666 }
16667 self.write(")");
16668
16669 if let Some(alias) = &mr.alias {
16671 self.write(" ");
16672 if mr.alias_explicit_as {
16673 self.write_keyword("AS");
16674 self.write(" ");
16675 }
16676 self.generate_identifier(alias)?;
16677 }
16678
16679 Ok(())
16680 }
16681
16682 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
16684 use crate::dialects::DialectType;
16685
16686 let supports_hints = matches!(
16688 self.config.dialect,
16689 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
16691 Some(DialectType::Spark) | Some(DialectType::Hive) |
16692 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
16693 );
16694
16695 if !supports_hints || hint.expressions.is_empty() {
16696 return Ok(());
16697 }
16698
16699 let mut hint_strings: Vec<String> = Vec::new();
16702 for expr in &hint.expressions {
16703 match expr {
16704 HintExpression::Raw(text) => {
16705 let parsed = self.parse_raw_hint_text(text);
16707 hint_strings.extend(parsed);
16708 }
16709 _ => {
16710 hint_strings.push(self.hint_expression_to_string(expr)?);
16711 }
16712 }
16713 }
16714
16715 let use_multiline = self.config.pretty && hint_strings.len() > 1;
16719
16720 if use_multiline {
16721 self.write(" /*+ ");
16723 for (i, hint_str) in hint_strings.iter().enumerate() {
16724 if i > 0 {
16725 self.write_newline();
16726 self.write(" "); }
16728 self.write(hint_str);
16729 }
16730 self.write(" */");
16731 } else {
16732 self.write(" /*+ ");
16734 let sep = match self.config.dialect {
16735 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
16736 _ => " ",
16737 };
16738 for (i, hint_str) in hint_strings.iter().enumerate() {
16739 if i > 0 {
16740 self.write(sep);
16741 }
16742 self.write(hint_str);
16743 }
16744 self.write(" */");
16745 }
16746
16747 Ok(())
16748 }
16749
16750 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
16754 let mut results = Vec::new();
16755 let mut chars = text.chars().peekable();
16756 let mut current = String::new();
16757 let mut paren_depth = 0;
16758 let mut has_unparseable_content = false;
16759 let mut position_after_last_function = 0;
16760 let mut char_position = 0;
16761
16762 while let Some(c) = chars.next() {
16763 char_position += c.len_utf8();
16764 match c {
16765 '(' => {
16766 paren_depth += 1;
16767 current.push(c);
16768 }
16769 ')' => {
16770 paren_depth -= 1;
16771 current.push(c);
16772 if paren_depth == 0 {
16774 let trimmed = current.trim().to_string();
16775 if !trimmed.is_empty() {
16776 let formatted = self.format_hint_function(&trimmed);
16778 results.push(formatted);
16779 }
16780 current.clear();
16781 position_after_last_function = char_position;
16782 }
16783 }
16784 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
16785 }
16787 _ if paren_depth == 0 => {
16788 current.push(c);
16790 }
16791 _ => {
16792 current.push(c);
16793 }
16794 }
16795 }
16796
16797 let remaining_text = text[position_after_last_function..].trim();
16799 if !remaining_text.is_empty() {
16800 let words: Vec<&str> = remaining_text.split_whitespace().collect();
16804 let looks_like_hint_functions = words.iter().all(|word| {
16805 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
16807 });
16808
16809 if !looks_like_hint_functions && words.len() > 1 {
16810 has_unparseable_content = true;
16811 }
16812 }
16813
16814 if has_unparseable_content {
16816 return vec![text.trim().to_string()];
16817 }
16818
16819 if results.is_empty() {
16821 results.push(text.trim().to_string());
16822 }
16823
16824 results
16825 }
16826
16827 fn format_hint_function(&self, hint: &str) -> String {
16830 if !self.config.pretty {
16831 return hint.to_string();
16832 }
16833
16834 if let Some(paren_pos) = hint.find('(') {
16836 if hint.ends_with(')') {
16837 let name = &hint[..paren_pos];
16838 let args_str = &hint[paren_pos + 1..hint.len() - 1];
16839
16840 let args: Vec<&str> = args_str.split_whitespace().collect();
16842
16843 let total_args_width: usize =
16845 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() {
16849 let mut result = format!("{}(\n", name);
16850 for arg in &args {
16851 result.push_str(" "); result.push_str(arg);
16853 result.push('\n');
16854 }
16855 result.push_str(" )"); return result;
16857 }
16858 }
16859 }
16860
16861 hint.to_string()
16862 }
16863
16864 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
16866 match expr {
16867 HintExpression::Function { name, args } => {
16868 let arg_strings: Vec<String> = args
16870 .iter()
16871 .map(|arg| {
16872 let mut gen = Generator::with_arc_config(self.config.clone());
16873 gen.generate_expression(arg)?;
16874 Ok(gen.output)
16875 })
16876 .collect::<Result<Vec<_>>>()?;
16877
16878 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
16880 + arg_strings.len().saturating_sub(1); let args_multiline =
16885 self.config.pretty && total_args_width > self.config.max_text_width;
16886
16887 if args_multiline && !arg_strings.is_empty() {
16888 let mut result = format!("{}(\n", name);
16890 for arg_str in &arg_strings {
16891 result.push_str(" "); result.push_str(arg_str);
16893 result.push('\n');
16894 }
16895 result.push_str(" )"); Ok(result)
16897 } else {
16898 let args_str = arg_strings.join(" ");
16900 Ok(format!("{}({})", name, args_str))
16901 }
16902 }
16903 HintExpression::Identifier(name) => Ok(name.clone()),
16904 HintExpression::Raw(text) => {
16905 if self.config.pretty {
16907 Ok(self.format_hint_function(text))
16908 } else {
16909 Ok(text.clone())
16910 }
16911 }
16912 }
16913 }
16914
16915 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
16916 if table.only {
16918 self.write_keyword("ONLY");
16919 self.write_space();
16920 }
16921
16922 if let Some(ref identifier_func) = table.identifier_func {
16924 self.generate_expression(identifier_func)?;
16925 if !table.name.name.is_empty() {
16927 if let Some(catalog) = &table.catalog {
16928 self.write(".");
16929 self.generate_identifier(catalog)?;
16930 }
16931 if let Some(schema) = &table.schema {
16932 self.write(".");
16933 self.generate_identifier(schema)?;
16934 }
16935 self.write(".");
16936 self.generate_identifier(&table.name)?;
16937 }
16938 } else {
16939 if let Some(catalog) = &table.catalog {
16940 self.generate_identifier(catalog)?;
16941 self.write(".");
16942 }
16943 if let Some(schema) = &table.schema {
16944 self.generate_identifier(schema)?;
16945 self.write(".");
16946 }
16947 self.generate_identifier(&table.name)?;
16948 }
16949
16950 if let Some(changes) = &table.changes {
16952 self.write(" ");
16953 self.generate_changes(changes)?;
16954 }
16955
16956 if !table.partitions.is_empty() {
16958 self.write_space();
16959 self.write_keyword("PARTITION");
16960 self.write("(");
16961 for (i, partition) in table.partitions.iter().enumerate() {
16962 if i > 0 {
16963 self.write(", ");
16964 }
16965 self.generate_identifier(partition)?;
16966 }
16967 self.write(")");
16968 }
16969
16970 if table.changes.is_none() {
16973 if let Some(when) = &table.when {
16974 self.write_space();
16975 self.generate_historical_data(when)?;
16976 }
16977 }
16978
16979 let system_time_post_alias = matches!(self.config.dialect, Some(DialectType::BigQuery));
16981 if !system_time_post_alias {
16982 if let Some(ref system_time) = table.system_time {
16983 self.write_space();
16984 self.write(system_time);
16985 }
16986 }
16987
16988 if let Some(ref version) = table.version {
16990 self.write_space();
16991 self.generate_version(version)?;
16992 }
16993
16994 let alias_post_tablesample = self.config.alias_post_tablesample;
16998
16999 if alias_post_tablesample {
17000 self.generate_table_sample_clause(table)?;
17002 }
17003
17004 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
17007 && table.hints.iter().any(|h| {
17008 if let Expression::Identifier(id) = h {
17009 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
17010 } else {
17011 false
17012 }
17013 });
17014 if !table.hints.is_empty() && !is_sqlite_hint {
17015 for hint in &table.hints {
17016 self.write_space();
17017 self.generate_expression(hint)?;
17018 }
17019 }
17020
17021 if let Some(alias) = &table.alias {
17022 self.write_space();
17023 let always_use_as = self.config.dialect.is_none()
17026 || matches!(
17027 self.config.dialect,
17028 Some(DialectType::Generic)
17029 | Some(DialectType::PostgreSQL)
17030 | Some(DialectType::Redshift)
17031 | Some(DialectType::Snowflake)
17032 | Some(DialectType::BigQuery)
17033 | Some(DialectType::DuckDB)
17034 | Some(DialectType::Presto)
17035 | Some(DialectType::Trino)
17036 | Some(DialectType::TSQL)
17037 | Some(DialectType::Fabric)
17038 | Some(DialectType::MySQL)
17039 | Some(DialectType::Spark)
17040 | Some(DialectType::Hive)
17041 | Some(DialectType::SQLite)
17042 | Some(DialectType::Drill)
17043 );
17044 let is_stage_ref = table.name.name.starts_with('@');
17045 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
17047 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
17048 self.write_keyword("AS");
17049 self.write_space();
17050 }
17051 self.generate_identifier(alias)?;
17052
17053 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
17056 self.write("(");
17057 for (i, col_alias) in table.column_aliases.iter().enumerate() {
17058 if i > 0 {
17059 self.write(", ");
17060 }
17061 self.generate_identifier(col_alias)?;
17062 }
17063 self.write(")");
17064 }
17065 }
17066
17067 if system_time_post_alias {
17069 if let Some(ref system_time) = table.system_time {
17070 self.write_space();
17071 self.write(system_time);
17072 }
17073 }
17074
17075 if !alias_post_tablesample {
17077 self.generate_table_sample_clause(table)?;
17078 }
17079
17080 if is_sqlite_hint {
17082 for hint in &table.hints {
17083 self.write_space();
17084 self.generate_expression(hint)?;
17085 }
17086 }
17087
17088 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
17090 self.write_space();
17091 self.write_keyword("FINAL");
17092 }
17093
17094 for comment in &table.trailing_comments {
17096 self.write_space();
17097 self.write_formatted_comment(comment);
17098 }
17099 Ok(())
17103 }
17104
17105 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
17107 if let Some(ref ts) = table.table_sample {
17108 self.write_space();
17109 if ts.is_using_sample {
17110 self.write_keyword("USING SAMPLE");
17111 } else {
17112 self.write_keyword(self.config.tablesample_keywords);
17114 }
17115 self.generate_sample_body(ts)?;
17116 if let Some(ref seed) = ts.seed {
17118 self.write_space();
17119 self.write_keyword(self.config.tablesample_seed_keyword);
17120 self.write(" (");
17121 self.generate_expression(seed)?;
17122 self.write(")");
17123 }
17124 }
17125 Ok(())
17126 }
17127
17128 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
17129 if sr.quoted {
17133 self.write("'");
17134 }
17135
17136 self.write(&sr.name);
17137 if let Some(path) = &sr.path {
17138 self.write(path);
17139 }
17140
17141 if sr.quoted {
17142 self.write("'");
17143 }
17144
17145 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
17147 if has_options {
17148 self.write(" (");
17149 let mut first = true;
17150
17151 if let Some(file_format) = &sr.file_format {
17152 if !first {
17153 self.write(", ");
17154 }
17155 self.write_keyword("FILE_FORMAT");
17156 self.write(" => ");
17157 self.generate_expression(file_format)?;
17158 first = false;
17159 }
17160
17161 if let Some(pattern) = &sr.pattern {
17162 if !first {
17163 self.write(", ");
17164 }
17165 self.write_keyword("PATTERN");
17166 self.write(" => '");
17167 self.write(pattern);
17168 self.write("'");
17169 }
17170
17171 self.write(")");
17172 }
17173 Ok(())
17174 }
17175
17176 fn generate_star(&mut self, star: &Star) -> Result<()> {
17177 use crate::dialects::DialectType;
17178
17179 if let Some(table) = &star.table {
17180 self.generate_identifier(table)?;
17181 self.write(".");
17182 }
17183 self.write("*");
17184
17185 if let Some(except) = &star.except {
17187 if !except.is_empty() {
17188 self.write_space();
17189 match self.config.dialect {
17191 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
17192 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
17193 self.write_keyword("EXCLUDE")
17194 }
17195 _ => self.write_keyword("EXCEPT"), }
17197 self.write(" (");
17198 for (i, col) in except.iter().enumerate() {
17199 if i > 0 {
17200 self.write(", ");
17201 }
17202 self.generate_identifier(col)?;
17203 }
17204 self.write(")");
17205 }
17206 }
17207
17208 if let Some(replace) = &star.replace {
17210 if !replace.is_empty() {
17211 self.write_space();
17212 self.write_keyword("REPLACE");
17213 self.write(" (");
17214 for (i, alias) in replace.iter().enumerate() {
17215 if i > 0 {
17216 self.write(", ");
17217 }
17218 self.generate_expression(&alias.this)?;
17219 self.write_space();
17220 self.write_keyword("AS");
17221 self.write_space();
17222 self.generate_identifier(&alias.alias)?;
17223 }
17224 self.write(")");
17225 }
17226 }
17227
17228 if let Some(rename) = &star.rename {
17230 if !rename.is_empty() {
17231 self.write_space();
17232 self.write_keyword("RENAME");
17233 self.write(" (");
17234 for (i, (old_name, new_name)) in rename.iter().enumerate() {
17235 if i > 0 {
17236 self.write(", ");
17237 }
17238 self.generate_identifier(old_name)?;
17239 self.write_space();
17240 self.write_keyword("AS");
17241 self.write_space();
17242 self.generate_identifier(new_name)?;
17243 }
17244 self.write(")");
17245 }
17246 }
17247
17248 for comment in &star.trailing_comments {
17250 self.write_space();
17251 self.write_formatted_comment(comment);
17252 }
17253
17254 Ok(())
17255 }
17256
17257 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
17259 self.write("{");
17260 match expr {
17261 Expression::Star(star) => {
17262 self.generate_star(star)?;
17264 }
17265 Expression::ILike(ilike) => {
17266 self.generate_expression(&ilike.left)?;
17268 self.write_space();
17269 self.write_keyword("ILIKE");
17270 self.write_space();
17271 self.generate_expression(&ilike.right)?;
17272 }
17273 _ => {
17274 self.generate_expression(expr)?;
17275 }
17276 }
17277 self.write("}");
17278 Ok(())
17279 }
17280
17281 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
17282 match &alias.this {
17286 Expression::Column(col) => {
17287 if let Some(table) = &col.table {
17289 self.generate_identifier(table)?;
17290 self.write(".");
17291 }
17292 self.generate_identifier(&col.name)?;
17293 }
17294 _ => {
17295 self.generate_expression(&alias.this)?;
17296 }
17297 }
17298
17299 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
17303 for comment in &alias.pre_alias_comments {
17304 self.write_space();
17305 self.write_formatted_comment(comment);
17306 }
17307 }
17308
17309 use crate::dialects::DialectType;
17310
17311 let is_table_source = matches!(
17317 &alias.this,
17318 Expression::JSONTable(_)
17319 | Expression::XMLTable(_)
17320 | Expression::TableFromRows(_)
17321 | Expression::Unnest(_)
17322 | Expression::MatchRecognize(_)
17323 | Expression::Select(_)
17324 | Expression::Subquery(_)
17325 | Expression::Paren(_)
17326 );
17327 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
17328 let skip_as = is_table_source && dialect_skips_table_alias_as;
17329
17330 self.write_space();
17331 if !skip_as {
17332 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
17333 if let Some(ref alias_keyword) = alias.alias_keyword {
17334 self.write(alias_keyword);
17335 } else {
17336 self.write_keyword("AS");
17337 }
17338 } else {
17339 self.write_keyword("AS");
17340 }
17341 self.write_space();
17342 }
17343
17344 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
17346
17347 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
17349 self.write("(");
17351 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
17352 if i > 0 {
17353 self.write(", ");
17354 }
17355 self.generate_alias_identifier(col_alias)?;
17356 }
17357 self.write(")");
17358 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
17359 self.generate_alias_identifier(&alias.alias)?;
17361 self.write("(");
17362 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
17363 if i > 0 {
17364 self.write(", ");
17365 }
17366 self.generate_alias_identifier(col_alias)?;
17367 }
17368 self.write(")");
17369 } else {
17370 self.generate_alias_identifier(&alias.alias)?;
17372 }
17373
17374 for comment in &alias.trailing_comments {
17376 self.write_space();
17377 self.write_formatted_comment(comment);
17378 }
17379
17380 if alias.trailing_comments.is_empty() {
17385 for comment in &alias.pre_alias_comments {
17386 self.write_space();
17387 self.write_formatted_comment(comment);
17388 }
17389 }
17390
17391 Ok(())
17392 }
17393
17394 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
17395 use crate::dialects::DialectType;
17396
17397 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
17399 self.generate_expression(&cast.this)?;
17400 self.write(" :> ");
17401 self.generate_data_type(&cast.to)?;
17402 return Ok(());
17403 }
17404
17405 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
17407 let is_unknown_type = matches!(cast.to, DataType::Unknown)
17408 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
17409 if is_unknown_type {
17410 if let Some(format) = &cast.format {
17411 self.write_keyword("CAST");
17412 self.write("(");
17413 self.generate_expression(&cast.this)?;
17414 self.write_space();
17415 self.write_keyword("AS");
17416 self.write_space();
17417 self.write_keyword("FORMAT");
17418 self.write_space();
17419 self.generate_expression(format)?;
17420 self.write(")");
17421 return Ok(());
17422 }
17423 }
17424 }
17425
17426 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
17429 if let Some(format) = &cast.format {
17430 let is_date = matches!(cast.to, DataType::Date);
17432 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
17433
17434 if is_date || is_timestamp {
17435 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
17436 self.write_keyword(func_name);
17437 self.write("(");
17438 self.generate_expression(&cast.this)?;
17439 self.write(", ");
17440
17441 if let Expression::Literal(lit) = format.as_ref() {
17444 if let Literal::String(fmt_str) = lit.as_ref() {
17445 let normalized = self.normalize_oracle_format(fmt_str);
17446 self.write("'");
17447 self.write(&normalized);
17448 self.write("'");
17449 }
17450 } else {
17451 self.generate_expression(format)?;
17452 }
17453
17454 self.write(")");
17455 return Ok(());
17456 }
17457 }
17458 }
17459
17460 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
17463 if let Expression::Array(arr) = &cast.this {
17464 self.generate_data_type(&cast.to)?;
17465 self.write("[");
17467 for (i, expr) in arr.expressions.iter().enumerate() {
17468 if i > 0 {
17469 self.write(", ");
17470 }
17471 self.generate_expression(expr)?;
17472 }
17473 self.write("]");
17474 return Ok(());
17475 }
17476 if matches!(&cast.this, Expression::ArrayFunc(_)) {
17477 self.generate_data_type(&cast.to)?;
17478 self.generate_expression(&cast.this)?;
17479 return Ok(());
17480 }
17481 }
17482
17483 if matches!(
17486 self.config.dialect,
17487 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
17488 ) {
17489 if let Expression::Struct(ref s) = cast.this {
17490 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
17491 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
17492 self.write_keyword("CAST");
17493 self.write("(");
17494 self.generate_struct_as_row(s)?;
17495 self.write_space();
17496 self.write_keyword("AS");
17497 self.write_space();
17498 self.generate_data_type(&cast.to)?;
17499 self.write(")");
17500 return Ok(());
17501 }
17502 }
17503 }
17504
17505 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
17508
17509 if use_double_colon {
17510 self.generate_expression(&cast.this)?;
17512 self.write("::");
17513 self.generate_data_type(&cast.to)?;
17514 } else {
17515 self.write_keyword("CAST");
17517 self.write("(");
17518 self.generate_expression(&cast.this)?;
17519 self.write_space();
17520 self.write_keyword("AS");
17521 self.write_space();
17522 if matches!(
17525 self.config.dialect,
17526 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
17527 ) {
17528 match &cast.to {
17529 DataType::Custom { ref name } => {
17530 if name.eq_ignore_ascii_case("LONGTEXT")
17531 || name.eq_ignore_ascii_case("MEDIUMTEXT")
17532 || name.eq_ignore_ascii_case("TINYTEXT")
17533 || name.eq_ignore_ascii_case("LONGBLOB")
17534 || name.eq_ignore_ascii_case("MEDIUMBLOB")
17535 || name.eq_ignore_ascii_case("TINYBLOB")
17536 {
17537 self.write_keyword("CHAR");
17538 } else {
17539 self.generate_data_type(&cast.to)?;
17540 }
17541 }
17542 DataType::VarChar { length, .. } => {
17543 self.write_keyword("CHAR");
17545 if let Some(n) = length {
17546 self.write(&format!("({})", n));
17547 }
17548 }
17549 DataType::Text => {
17550 self.write_keyword("CHAR");
17552 }
17553 DataType::Timestamp {
17554 precision,
17555 timezone: false,
17556 } => {
17557 self.write_keyword("DATETIME");
17559 if let Some(p) = precision {
17560 self.write(&format!("({})", p));
17561 }
17562 }
17563 _ => {
17564 self.generate_data_type(&cast.to)?;
17565 }
17566 }
17567 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
17568 match &cast.to {
17570 DataType::String { length } => {
17571 self.write_keyword("VARCHAR");
17572 if let Some(n) = length {
17573 self.write(&format!("({})", n));
17574 }
17575 }
17576 _ => {
17577 self.generate_data_type(&cast.to)?;
17578 }
17579 }
17580 } else {
17581 self.generate_data_type(&cast.to)?;
17582 }
17583
17584 if let Some(default) = &cast.default {
17586 self.write_space();
17587 self.write_keyword("DEFAULT");
17588 self.write_space();
17589 self.generate_expression(default)?;
17590 self.write_space();
17591 self.write_keyword("ON");
17592 self.write_space();
17593 self.write_keyword("CONVERSION");
17594 self.write_space();
17595 self.write_keyword("ERROR");
17596 }
17597
17598 if let Some(format) = &cast.format {
17601 if matches!(
17603 self.config.dialect,
17604 Some(crate::dialects::DialectType::Oracle)
17605 ) {
17606 self.write(", ");
17607 } else {
17608 self.write_space();
17609 self.write_keyword("FORMAT");
17610 self.write_space();
17611 }
17612 self.generate_expression(format)?;
17613 }
17614
17615 self.write(")");
17616 for comment in &cast.trailing_comments {
17618 self.write_space();
17619 self.write_formatted_comment(comment);
17620 }
17621 }
17622 Ok(())
17623 }
17624
17625 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
17628 self.write_keyword("ROW");
17629 self.write("(");
17630 for (i, (_, expr)) in s.fields.iter().enumerate() {
17631 if i > 0 {
17632 self.write(", ");
17633 }
17634 if let Expression::Struct(ref inner_s) = expr {
17636 self.generate_struct_as_row(inner_s)?;
17637 } else {
17638 self.generate_expression(expr)?;
17639 }
17640 }
17641 self.write(")");
17642 Ok(())
17643 }
17644
17645 fn normalize_oracle_format(&self, format: &str) -> String {
17648 let mut result = String::new();
17651 let chars: Vec<char> = format.chars().collect();
17652 let mut i = 0;
17653
17654 while i < chars.len() {
17655 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
17656 if i + 2 < chars.len() {
17658 let next = chars[i + 2];
17659 if next == '1' || next == '2' {
17660 result.push('H');
17662 result.push('H');
17663 i += 2;
17664 continue;
17665 }
17666 }
17667 result.push_str("HH12");
17669 i += 2;
17670 } else {
17671 result.push(chars[i]);
17672 i += 1;
17673 }
17674 }
17675
17676 result
17677 }
17678
17679 fn dialect_prefers_double_colon(&self) -> bool {
17682 matches!(self.config.dialect, Some(DialectType::ClickHouse))
17683 }
17684
17685 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17687 use crate::dialects::DialectType;
17688
17689 let use_percent_operator = matches!(
17691 self.config.dialect,
17692 Some(DialectType::Snowflake)
17693 | Some(DialectType::MySQL)
17694 | Some(DialectType::Presto)
17695 | Some(DialectType::Trino)
17696 | Some(DialectType::PostgreSQL)
17697 | Some(DialectType::DuckDB)
17698 | Some(DialectType::Hive)
17699 | Some(DialectType::Spark)
17700 | Some(DialectType::Databricks)
17701 | Some(DialectType::Athena)
17702 | Some(DialectType::TSQL)
17703 | Some(DialectType::Fabric)
17704 );
17705
17706 if use_percent_operator {
17707 let needs_paren = |e: &Expression| {
17710 matches!(
17711 e,
17712 Expression::Add(_)
17713 | Expression::Sub(_)
17714 | Expression::Mul(_)
17715 | Expression::Div(_)
17716 | Expression::Mod(_)
17717 | Expression::ModFunc(_)
17718 )
17719 };
17720 if needs_paren(&f.this) {
17721 self.write("(");
17722 self.generate_expression(&f.this)?;
17723 self.write(")");
17724 } else {
17725 self.generate_expression(&f.this)?;
17726 }
17727 self.write(" % ");
17728 if needs_paren(&f.expression) {
17729 self.write("(");
17730 self.generate_expression(&f.expression)?;
17731 self.write(")");
17732 } else {
17733 self.generate_expression(&f.expression)?;
17734 }
17735 Ok(())
17736 } else {
17737 self.generate_binary_func("MOD", &f.this, &f.expression)
17738 }
17739 }
17740
17741 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17743 use crate::dialects::DialectType;
17744
17745 let func_name = match self.config.dialect {
17747 Some(DialectType::Snowflake) => "COALESCE",
17748 _ => "IFNULL",
17749 };
17750
17751 self.generate_binary_func(func_name, &f.this, &f.expression)
17752 }
17753
17754 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17756 if let Some(ref original_name) = f.original_name {
17758 return self.generate_binary_func(original_name, &f.this, &f.expression);
17759 }
17760
17761 use crate::dialects::DialectType;
17763 let func_name = match self.config.dialect {
17764 Some(DialectType::Snowflake)
17765 | Some(DialectType::ClickHouse)
17766 | Some(DialectType::PostgreSQL)
17767 | Some(DialectType::Presto)
17768 | Some(DialectType::Trino)
17769 | Some(DialectType::Athena)
17770 | Some(DialectType::DuckDB)
17771 | Some(DialectType::BigQuery)
17772 | Some(DialectType::Spark)
17773 | Some(DialectType::Databricks)
17774 | Some(DialectType::Hive) => "COALESCE",
17775 Some(DialectType::MySQL)
17776 | Some(DialectType::Doris)
17777 | Some(DialectType::StarRocks)
17778 | Some(DialectType::SingleStore)
17779 | Some(DialectType::TiDB) => "IFNULL",
17780 _ => "NVL",
17781 };
17782
17783 self.generate_binary_func(func_name, &f.this, &f.expression)
17784 }
17785
17786 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
17788 use crate::dialects::DialectType;
17789
17790 let func_name = match self.config.dialect {
17792 Some(DialectType::Snowflake) => "STDDEV",
17793 _ => "STDDEV_SAMP",
17794 };
17795
17796 self.generate_agg_func(func_name, f)
17797 }
17798
17799 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
17800 self.generate_expression(&coll.this)?;
17801 self.write_space();
17802 self.write_keyword("COLLATE");
17803 self.write_space();
17804 if coll.quoted {
17805 self.write("'");
17807 self.write(&coll.collation);
17808 self.write("'");
17809 } else if coll.double_quoted {
17810 self.write("\"");
17812 self.write(&coll.collation);
17813 self.write("\"");
17814 } else {
17815 self.write(&coll.collation);
17817 }
17818 Ok(())
17819 }
17820
17821 fn generate_case(&mut self, case: &Case) -> Result<()> {
17822 let multiline_case = if self.config.pretty {
17824 let mut statements: Vec<String> = Vec::new();
17826 let operand_str = if let Some(operand) = &case.operand {
17827 let s = self.generate_to_string(operand)?;
17828 statements.push(format!("CASE {}", s));
17829 s
17830 } else {
17831 statements.push("CASE".to_string());
17832 String::new()
17833 };
17834 let _ = operand_str;
17835 for (condition, result) in &case.whens {
17836 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
17837 statements.push(format!("THEN {}", self.generate_to_string(result)?));
17838 }
17839 if let Some(else_) = &case.else_ {
17840 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
17841 }
17842 statements.push("END".to_string());
17843 self.too_wide(&statements)
17844 } else {
17845 false
17846 };
17847
17848 self.write_keyword("CASE");
17849 if let Some(operand) = &case.operand {
17850 self.write_space();
17851 self.generate_expression(operand)?;
17852 }
17853 if multiline_case {
17854 self.indent_level += 1;
17855 }
17856 for (condition, result) in &case.whens {
17857 if multiline_case {
17858 self.write_newline();
17859 self.write_indent();
17860 } else {
17861 self.write_space();
17862 }
17863 self.write_keyword("WHEN");
17864 self.write_space();
17865 self.generate_expression(condition)?;
17866 if multiline_case {
17867 self.write_newline();
17868 self.write_indent();
17869 } else {
17870 self.write_space();
17871 }
17872 self.write_keyword("THEN");
17873 self.write_space();
17874 self.generate_expression(result)?;
17875 }
17876 if let Some(else_) = &case.else_ {
17877 if multiline_case {
17878 self.write_newline();
17879 self.write_indent();
17880 } else {
17881 self.write_space();
17882 }
17883 self.write_keyword("ELSE");
17884 self.write_space();
17885 self.generate_expression(else_)?;
17886 }
17887 if multiline_case {
17888 self.indent_level -= 1;
17889 self.write_newline();
17890 self.write_indent();
17891 } else {
17892 self.write_space();
17893 }
17894 self.write_keyword("END");
17895 for comment in &case.comments {
17897 self.write(" ");
17898 self.write_formatted_comment(comment);
17899 }
17900 Ok(())
17901 }
17902
17903 fn generate_function(&mut self, func: &Function) -> Result<()> {
17904 let normalized_name = if matches!(self.config.dialect, Some(DialectType::Snowflake))
17906 && func.name.to_ascii_uppercase().starts_with("IDENTIFIER(")
17907 {
17908 Cow::Borrowed(func.name.as_str())
17909 } else {
17910 self.normalize_func_name(&func.name)
17911 };
17912
17913 if matches!(self.config.dialect, Some(DialectType::DuckDB))
17915 && func.name.eq_ignore_ascii_case("ARRAY_CONSTRUCT_COMPACT")
17916 {
17917 self.write("LIST_FILTER(");
17918 self.write("[");
17919 for (i, arg) in func.args.iter().enumerate() {
17920 if i > 0 {
17921 self.write(", ");
17922 }
17923 self.generate_expression(arg)?;
17924 }
17925 self.write("], _u -> NOT _u IS NULL)");
17926 return Ok(());
17927 }
17928
17929 if matches!(self.config.dialect, Some(DialectType::Snowflake))
17932 && func.name.eq_ignore_ascii_case("TO_VARIANT")
17933 && func.args.len() == 1
17934 {
17935 let array_expressions = match &func.args[0] {
17936 Expression::ArrayFunc(arr) => Some(&arr.expressions),
17937 Expression::Array(arr) => Some(&arr.expressions),
17938 _ => None,
17939 };
17940 if let Some(expressions) = array_expressions {
17941 self.write_keyword("TO_VARIANT");
17942 self.write("(");
17943 self.write_keyword("ARRAY_CONSTRUCT");
17944 self.write("(");
17945 for (i, arg) in expressions.iter().enumerate() {
17946 if i > 0 {
17947 self.write(", ");
17948 }
17949 self.generate_expression(arg)?;
17950 }
17951 self.write(")");
17952 self.write(")");
17953 return Ok(());
17954 }
17955 }
17956
17957 if func.name.eq_ignore_ascii_case("STRUCT")
17959 && !matches!(
17960 self.config.dialect,
17961 Some(DialectType::BigQuery)
17962 | Some(DialectType::Spark)
17963 | Some(DialectType::Databricks)
17964 | Some(DialectType::Hive)
17965 | None
17966 )
17967 {
17968 return self.generate_struct_function_cross_dialect(func);
17969 }
17970
17971 if func.name.eq_ignore_ascii_case("__SS_JSON_PATH_QMARK__") && func.args.len() == 2 {
17974 self.generate_expression(&func.args[0])?;
17975 self.write("::?");
17976 if let Expression::Literal(lit) = &func.args[1] {
17978 if let crate::expressions::Literal::String(key) = lit.as_ref() {
17979 self.write(key);
17980 }
17981 } else {
17982 self.generate_expression(&func.args[1])?;
17983 }
17984 return Ok(());
17985 }
17986
17987 if func.name.eq_ignore_ascii_case("__PG_BITWISE_XOR__") && func.args.len() == 2 {
17989 self.generate_expression(&func.args[0])?;
17990 self.write(" # ");
17991 self.generate_expression(&func.args[1])?;
17992 return Ok(());
17993 }
17994
17995 if matches!(
17997 self.config.dialect,
17998 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
17999 ) && func.name.eq_ignore_ascii_case("TRY")
18000 && func.args.len() == 1
18001 {
18002 self.generate_expression(&func.args[0])?;
18003 return Ok(());
18004 }
18005
18006 if self.config.dialect == Some(DialectType::ClickHouse)
18008 && func.name.eq_ignore_ascii_case("TOSTARTOFDAY")
18009 && func.args.len() == 1
18010 {
18011 self.write("dateTrunc('DAY', ");
18012 self.generate_expression(&func.args[0])?;
18013 self.write(")");
18014 return Ok(());
18015 }
18016
18017 if self.config.dialect == Some(DialectType::ClickHouse)
18019 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
18020 && func.args.len() == 2
18021 {
18022 self.write("dateTrunc(");
18023 self.generate_expression(&func.args[0])?;
18024 self.write(", ");
18025 self.generate_expression(&func.args[1])?;
18026 self.write(")");
18027 return Ok(());
18028 }
18029
18030 if matches!(
18032 self.config.dialect,
18033 Some(DialectType::Presto | DialectType::Trino | DialectType::Athena)
18034 ) && func.name.eq_ignore_ascii_case("SUBSTRING")
18035 {
18036 self.write_keyword("SUBSTR");
18037 self.write("(");
18038 for (i, arg) in func.args.iter().enumerate() {
18039 if i > 0 {
18040 self.write(", ");
18041 }
18042 self.generate_expression(arg)?;
18043 }
18044 self.write(")");
18045 return Ok(());
18046 }
18047
18048 if self.config.dialect == Some(DialectType::Snowflake)
18049 && func.name.eq_ignore_ascii_case("LIST_DISTINCT")
18050 && func.args.len() == 1
18051 {
18052 self.write_keyword("ARRAY_DISTINCT");
18053 self.write("(");
18054 self.write_keyword("ARRAY_COMPACT");
18055 self.write("(");
18056 self.generate_expression(&func.args[0])?;
18057 self.write("))");
18058 return Ok(());
18059 }
18060
18061 if self.config.dialect == Some(DialectType::Snowflake)
18062 && func.name.eq_ignore_ascii_case("LIST")
18063 && func.args.len() == 1
18064 && !matches!(func.args.first(), Some(Expression::Select(_)))
18065 {
18066 self.write_keyword("ARRAY_AGG");
18067 self.write("(");
18068 self.generate_expression(&func.args[0])?;
18069 self.write(")");
18070 return Ok(());
18071 }
18072
18073 if self.config.dialect == Some(DialectType::Redshift)
18075 && func.name.eq_ignore_ascii_case("CONCAT")
18076 && func.args.len() >= 2
18077 {
18078 for (i, arg) in func.args.iter().enumerate() {
18079 if i > 0 {
18080 self.write(" || ");
18081 }
18082 self.generate_expression(arg)?;
18083 }
18084 return Ok(());
18085 }
18086
18087 if self.config.dialect == Some(DialectType::Redshift)
18089 && func.name.eq_ignore_ascii_case("CONCAT_WS")
18090 && func.args.len() >= 2
18091 {
18092 let sep = &func.args[0];
18093 for (i, arg) in func.args.iter().skip(1).enumerate() {
18094 if i > 0 {
18095 self.write(" || ");
18096 self.generate_expression(sep)?;
18097 self.write(" || ");
18098 }
18099 self.generate_expression(arg)?;
18100 }
18101 return Ok(());
18102 }
18103
18104 if self.config.dialect == Some(DialectType::Redshift)
18107 && (func.name.eq_ignore_ascii_case("DATEDIFF")
18108 || func.name.eq_ignore_ascii_case("DATE_DIFF"))
18109 && func.args.len() == 3
18110 {
18111 self.write_keyword("DATEDIFF");
18112 self.write("(");
18113 self.write_redshift_date_part(&func.args[0]);
18115 self.write(", ");
18116 self.generate_expression(&func.args[1])?;
18117 self.write(", ");
18118 self.generate_expression(&func.args[2])?;
18119 self.write(")");
18120 return Ok(());
18121 }
18122
18123 if self.config.dialect == Some(DialectType::Redshift)
18126 && (func.name.eq_ignore_ascii_case("DATEADD")
18127 || func.name.eq_ignore_ascii_case("DATE_ADD"))
18128 && func.args.len() == 3
18129 {
18130 self.write_keyword("DATEADD");
18131 self.write("(");
18132 self.write_redshift_date_part(&func.args[0]);
18134 self.write(", ");
18135 self.generate_expression(&func.args[1])?;
18136 self.write(", ");
18137 self.generate_expression(&func.args[2])?;
18138 self.write(")");
18139 return Ok(());
18140 }
18141
18142 if func.name.eq_ignore_ascii_case("UUID_STRING")
18144 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
18145 {
18146 if matches!(
18147 self.config.dialect,
18148 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
18149 ) {
18150 self.write_keyword("CAST");
18151 self.write("(");
18152 self.write_keyword("UUID");
18153 self.write("() ");
18154 self.write_keyword("AS");
18155 self.write(" ");
18156 self.write_keyword("STRING");
18157 self.write(")");
18158 return Ok(());
18159 }
18160
18161 if matches!(
18162 self.config.dialect,
18163 Some(DialectType::Presto | DialectType::Trino)
18164 ) {
18165 self.write_keyword("CAST");
18166 self.write("(");
18167 self.write_keyword("UUID");
18168 self.write("() ");
18169 self.write_keyword("AS");
18170 self.write(" ");
18171 self.write_keyword("VARCHAR");
18172 self.write(")");
18173 return Ok(());
18174 }
18175
18176 if self.config.dialect == Some(DialectType::DuckDB) && func.args.len() == 2 {
18177 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(");
18178 self.generate_expression(&func.args[0])?;
18179 self.write(", '-', '')) || ENCODE(");
18180 self.generate_expression(&func.args[1])?;
18181 self.write(")), 1, 32) AS h))");
18182 return Ok(());
18183 }
18184
18185 let func_name = match self.config.dialect {
18186 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
18187 Some(DialectType::BigQuery) => "GENERATE_UUID",
18188 _ => "UUID",
18189 };
18190 self.write_keyword(func_name);
18191 self.write("()");
18192 return Ok(());
18193 }
18194
18195 if matches!(self.config.dialect, Some(DialectType::Snowflake))
18199 && func.name.eq_ignore_ascii_case("GENERATOR")
18200 {
18201 let has_positional_args =
18202 !func.args.is_empty() && !matches!(&func.args[0], Expression::NamedArgument(_));
18203 if has_positional_args {
18204 let param_names = ["ROWCOUNT", "TIMELIMIT"];
18205 self.write_keyword("GENERATOR");
18206 self.write("(");
18207 for (i, arg) in func.args.iter().enumerate() {
18208 if i > 0 {
18209 self.write(", ");
18210 }
18211 if i < param_names.len() {
18212 self.write_keyword(param_names[i]);
18213 self.write(" => ");
18214 self.generate_expression(arg)?;
18215 } else {
18216 self.generate_expression(arg)?;
18217 }
18218 }
18219 self.write(")");
18220 return Ok(());
18221 }
18222 }
18223
18224 if self.config.dialect == Some(DialectType::Redshift)
18227 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
18228 && func.args.len() == 2
18229 {
18230 self.write_keyword("DATE_TRUNC");
18231 self.write("(");
18232 self.write_redshift_date_part_quoted(&func.args[0]);
18234 self.write(", ");
18235 self.generate_expression(&func.args[1])?;
18236 self.write(")");
18237 return Ok(());
18238 }
18239
18240 if matches!(
18242 self.config.dialect,
18243 Some(DialectType::TSQL) | Some(DialectType::Fabric)
18244 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
18245 || func.name.eq_ignore_ascii_case("DATEPART"))
18246 && func.args.len() == 2
18247 {
18248 self.write_keyword("DATEPART");
18249 self.write("(");
18250 self.write_tsql_date_part(&func.args[0])?;
18251 self.write(", ");
18252 self.generate_expression(&func.args[1])?;
18253 self.write(")");
18254 return Ok(());
18255 }
18256
18257 if matches!(
18259 self.config.dialect,
18260 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
18261 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
18262 || func.name.eq_ignore_ascii_case("DATEPART"))
18263 && func.args.len() == 2
18264 {
18265 self.write_keyword("EXTRACT");
18266 self.write("(");
18267 match &func.args[0] {
18269 Expression::Literal(lit)
18270 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
18271 {
18272 let crate::expressions::Literal::String(s) = lit.as_ref() else {
18273 unreachable!()
18274 };
18275 self.write(&s.to_ascii_lowercase());
18276 }
18277 _ => self.generate_expression(&func.args[0])?,
18278 }
18279 self.write_space();
18280 self.write_keyword("FROM");
18281 self.write_space();
18282 self.generate_expression(&func.args[1])?;
18283 self.write(")");
18284 return Ok(());
18285 }
18286
18287 if self.config.dialect == Some(DialectType::PostgreSQL)
18289 && matches!(
18290 func.name.to_ascii_uppercase().as_str(),
18291 "DATE_ADD" | "DATE_SUB"
18292 )
18293 && func.args.len() == 2
18294 && matches!(func.args[1], Expression::Interval(_))
18295 {
18296 self.generate_expression(&func.args[0])?;
18297 self.write_space();
18298 if func.name.eq_ignore_ascii_case("DATE_SUB") {
18299 self.write("-");
18300 } else {
18301 self.write("+");
18302 }
18303 self.write_space();
18304 self.generate_expression(&func.args[1])?;
18305 return Ok(());
18306 }
18307
18308 if self.config.dialect == Some(DialectType::Dremio)
18311 && (func.name.eq_ignore_ascii_case("DATE_PART")
18312 || func.name.eq_ignore_ascii_case("DATEPART"))
18313 && func.args.len() == 2
18314 {
18315 self.write_keyword("EXTRACT");
18316 self.write("(");
18317 self.generate_expression(&func.args[0])?;
18318 self.write_space();
18319 self.write_keyword("FROM");
18320 self.write_space();
18321 self.generate_dremio_date_expression(&func.args[1])?;
18323 self.write(")");
18324 return Ok(());
18325 }
18326
18327 if self.config.dialect == Some(DialectType::Dremio)
18329 && func.name.eq_ignore_ascii_case("CURRENT_DATE_UTC")
18330 && func.args.is_empty()
18331 {
18332 self.write_keyword("CURRENT_DATE_UTC");
18333 return Ok(());
18334 }
18335
18336 if self.config.dialect == Some(DialectType::Dremio)
18340 && func.name.eq_ignore_ascii_case("DATETYPE")
18341 && func.args.len() == 3
18342 {
18343 fn get_int_literal(expr: &Expression) -> Option<i64> {
18345 if let Expression::Literal(lit) = expr {
18346 if let crate::expressions::Literal::Number(s) = lit.as_ref() {
18347 s.parse::<i64>().ok()
18348 } else {
18349 None
18350 }
18351 } else {
18352 None
18353 }
18354 }
18355
18356 if let (Some(year), Some(month), Some(day)) = (
18358 get_int_literal(&func.args[0]),
18359 get_int_literal(&func.args[1]),
18360 get_int_literal(&func.args[2]),
18361 ) {
18362 self.write_keyword("DATE");
18364 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
18365 return Ok(());
18366 }
18367
18368 self.write_keyword("CAST");
18370 self.write("(");
18371 self.write_keyword("CONCAT");
18372 self.write("(");
18373 self.generate_expression(&func.args[0])?;
18374 self.write(", '-', ");
18375 self.generate_expression(&func.args[1])?;
18376 self.write(", '-', ");
18377 self.generate_expression(&func.args[2])?;
18378 self.write(")");
18379 self.write_space();
18380 self.write_keyword("AS");
18381 self.write_space();
18382 self.write_keyword("DATE");
18383 self.write(")");
18384 return Ok(());
18385 }
18386
18387 let is_presto_like = matches!(
18390 self.config.dialect,
18391 Some(DialectType::Presto) | Some(DialectType::Trino)
18392 );
18393 if is_presto_like && func.name.eq_ignore_ascii_case("DATE_ADD") && func.args.len() == 3 {
18394 self.write_keyword("DATE_ADD");
18395 self.write("(");
18396 self.generate_expression(&func.args[0])?;
18398 self.write(", ");
18399 let interval = &func.args[1];
18401 let needs_cast = !self.returns_integer_type(interval);
18402 if needs_cast {
18403 self.write_keyword("CAST");
18404 self.write("(");
18405 }
18406 self.generate_expression(interval)?;
18407 if needs_cast {
18408 self.write_space();
18409 self.write_keyword("AS");
18410 self.write_space();
18411 self.write_keyword("BIGINT");
18412 self.write(")");
18413 }
18414 self.write(", ");
18415 self.generate_expression(&func.args[2])?;
18417 self.write(")");
18418 return Ok(());
18419 }
18420
18421 let use_brackets = func.use_bracket_syntax;
18423
18424 let has_ordinality = func.name.len() >= 16
18429 && func.name[func.name.len() - 16..].eq_ignore_ascii_case(" WITH ORDINALITY");
18430 let output_name = if has_ordinality {
18431 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
18432 self.normalize_func_name(base_name)
18433 } else {
18434 normalized_name.clone()
18435 };
18436
18437 let quote_source_clickhouse_function =
18440 matches!(self.config.dialect, Some(DialectType::ClickHouse))
18441 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
18442 && func.quoted;
18443
18444 if quote_source_clickhouse_function {
18445 self.generate_identifier(&Identifier {
18446 name: func.name.clone(),
18447 quoted: true,
18448 trailing_comments: Vec::new(),
18449 span: None,
18450 })?;
18451 } else if func.name.contains('.') && !has_ordinality {
18452 if func.quoted {
18455 self.write("`");
18456 self.write(&func.name);
18457 self.write("`");
18458 } else {
18459 self.write(&func.name);
18460 }
18461 } else {
18462 self.write(&output_name);
18463 }
18464
18465 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
18468 let needs_parens = if func.name.eq_ignore_ascii_case("CURRENT_USER")
18469 || func.name.eq_ignore_ascii_case("SESSION_USER")
18470 || func.name.eq_ignore_ascii_case("SYSTEM_USER")
18471 {
18472 matches!(
18473 self.config.dialect,
18474 Some(DialectType::Snowflake)
18475 | Some(DialectType::Spark)
18476 | Some(DialectType::Databricks)
18477 | Some(DialectType::Hive)
18478 )
18479 } else {
18480 false
18481 };
18482 !needs_parens
18483 };
18484 if force_parens {
18485 for comment in &func.trailing_comments {
18487 self.write_space();
18488 self.write_formatted_comment(comment);
18489 }
18490 return Ok(());
18491 }
18492
18493 if func.name.eq_ignore_ascii_case("CUBE")
18495 || func.name.eq_ignore_ascii_case("ROLLUP")
18496 || func.name.eq_ignore_ascii_case("GROUPING SETS")
18497 {
18498 self.write(" (");
18499 } else if use_brackets {
18500 self.write("[");
18501 } else {
18502 self.write("(");
18503 }
18504 if func.distinct {
18505 self.write_keyword("DISTINCT");
18506 self.write_space();
18507 }
18508
18509 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
18511 && (func.name.eq_ignore_ascii_case("TABLE")
18512 || func.name.eq_ignore_ascii_case("FLATTEN"));
18513 let is_grouping_func = func.name.eq_ignore_ascii_case("GROUPING SETS")
18515 || func.name.eq_ignore_ascii_case("CUBE")
18516 || func.name.eq_ignore_ascii_case("ROLLUP");
18517 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
18518 if is_grouping_func {
18519 true
18520 } else {
18521 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
18523 for arg in &func.args {
18524 let mut temp_gen = Generator::with_arc_config(self.config.clone());
18525 Arc::make_mut(&mut temp_gen.config).pretty = false; temp_gen.generate_expression(arg)?;
18527 expr_strings.push(temp_gen.output);
18528 }
18529 self.too_wide(&expr_strings)
18530 }
18531 } else {
18532 false
18533 };
18534
18535 if should_split {
18536 self.write_newline();
18538 self.indent_level += 1;
18539 for (i, arg) in func.args.iter().enumerate() {
18540 self.write_indent();
18541 self.generate_expression(arg)?;
18542 if i + 1 < func.args.len() {
18543 self.write(",");
18544 }
18545 self.write_newline();
18546 }
18547 self.indent_level -= 1;
18548 self.write_indent();
18549 } else {
18550 for (i, arg) in func.args.iter().enumerate() {
18552 if i > 0 {
18553 self.write(", ");
18554 }
18555 self.generate_expression(arg)?;
18556 }
18557 }
18558
18559 if use_brackets {
18560 self.write("]");
18561 } else {
18562 self.write(")");
18563 }
18564 if has_ordinality {
18566 self.write_space();
18567 self.write_keyword("WITH ORDINALITY");
18568 }
18569 for comment in &func.trailing_comments {
18571 self.write_space();
18572 self.write_formatted_comment(comment);
18573 }
18574 Ok(())
18575 }
18576
18577 fn generate_function_emits(&mut self, fe: &FunctionEmits) -> Result<()> {
18578 self.generate_expression(&fe.this)?;
18579 self.write_keyword(" EMITS ");
18580 self.generate_expression(&fe.emits)?;
18581 Ok(())
18582 }
18583
18584 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
18585 let mut normalized_name = self.normalize_func_name(&func.name);
18587
18588 if func.name.eq_ignore_ascii_case("MAX_BY") || func.name.eq_ignore_ascii_case("MIN_BY") {
18590 let is_max = func.name.eq_ignore_ascii_case("MAX_BY");
18591 match self.config.dialect {
18592 Some(DialectType::ClickHouse) => {
18593 normalized_name = if is_max {
18594 Cow::Borrowed("argMax")
18595 } else {
18596 Cow::Borrowed("argMin")
18597 };
18598 }
18599 Some(DialectType::DuckDB) => {
18600 normalized_name = if is_max {
18601 Cow::Borrowed("ARG_MAX")
18602 } else {
18603 Cow::Borrowed("ARG_MIN")
18604 };
18605 }
18606 _ => {}
18607 }
18608 }
18609 self.write(normalized_name.as_ref());
18610 self.write("(");
18611 if func.distinct {
18612 self.write_keyword("DISTINCT");
18613 self.write_space();
18614 }
18615
18616 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
18620 let needs_multi_arg_transform =
18621 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
18622
18623 if needs_multi_arg_transform {
18624 self.write_keyword("CASE");
18626 for arg in &func.args {
18627 self.write_space();
18628 self.write_keyword("WHEN");
18629 self.write_space();
18630 self.generate_expression(arg)?;
18631 self.write_space();
18632 self.write_keyword("IS NULL THEN NULL");
18633 }
18634 self.write_space();
18635 self.write_keyword("ELSE");
18636 self.write(" (");
18637 for (i, arg) in func.args.iter().enumerate() {
18638 if i > 0 {
18639 self.write(", ");
18640 }
18641 self.generate_expression(arg)?;
18642 }
18643 self.write(")");
18644 self.write_space();
18645 self.write_keyword("END");
18646 } else {
18647 for (i, arg) in func.args.iter().enumerate() {
18648 if i > 0 {
18649 self.write(", ");
18650 }
18651 self.generate_expression(arg)?;
18652 }
18653 }
18654
18655 let clickhouse_ignore_nulls_outside =
18657 matches!(self.config.dialect, Some(DialectType::ClickHouse));
18658 if self.config.ignore_nulls_in_func
18659 && !matches!(
18660 self.config.dialect,
18661 Some(DialectType::DuckDB) | Some(DialectType::ClickHouse)
18662 )
18663 {
18664 if let Some(ignore) = func.ignore_nulls {
18665 self.write_space();
18666 if ignore {
18667 self.write_keyword("IGNORE NULLS");
18668 } else {
18669 self.write_keyword("RESPECT NULLS");
18670 }
18671 }
18672 }
18673
18674 if !func.order_by.is_empty() {
18676 self.write_space();
18677 self.write_keyword("ORDER BY");
18678 self.write_space();
18679 for (i, ord) in func.order_by.iter().enumerate() {
18680 if i > 0 {
18681 self.write(", ");
18682 }
18683 self.generate_ordered(ord)?;
18684 }
18685 }
18686
18687 if let Some(limit) = &func.limit {
18689 self.write_space();
18690 self.write_keyword("LIMIT");
18691 self.write_space();
18692 if let Expression::Tuple(t) = limit.as_ref() {
18694 if t.expressions.len() == 2 {
18695 self.generate_expression(&t.expressions[0])?;
18696 self.write(", ");
18697 self.generate_expression(&t.expressions[1])?;
18698 } else {
18699 self.generate_expression(limit)?;
18700 }
18701 } else {
18702 self.generate_expression(limit)?;
18703 }
18704 }
18705
18706 self.write(")");
18707
18708 if (!self.config.ignore_nulls_in_func || clickhouse_ignore_nulls_outside)
18710 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18711 {
18712 if let Some(ignore) = func.ignore_nulls {
18713 self.write_space();
18714 if ignore {
18715 self.write_keyword("IGNORE NULLS");
18716 } else {
18717 self.write_keyword("RESPECT NULLS");
18718 }
18719 }
18720 }
18721
18722 if let Some(filter) = &func.filter {
18723 self.write_space();
18724 self.write_keyword("FILTER");
18725 self.write("(");
18726 self.write_keyword("WHERE");
18727 self.write_space();
18728 self.generate_expression(filter)?;
18729 self.write(")");
18730 }
18731
18732 Ok(())
18733 }
18734
18735 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
18736 self.generate_expression(&wf.this)?;
18737
18738 if let Some(keep) = &wf.keep {
18740 self.write_space();
18741 self.write_keyword("KEEP");
18742 self.write(" (");
18743 self.write_keyword("DENSE_RANK");
18744 self.write_space();
18745 if keep.first {
18746 self.write_keyword("FIRST");
18747 } else {
18748 self.write_keyword("LAST");
18749 }
18750 self.write_space();
18751 self.write_keyword("ORDER BY");
18752 self.write_space();
18753 for (i, ord) in keep.order_by.iter().enumerate() {
18754 if i > 0 {
18755 self.write(", ");
18756 }
18757 self.generate_ordered(ord)?;
18758 }
18759 self.write(")");
18760 }
18761
18762 let has_over = !wf.over.partition_by.is_empty()
18764 || !wf.over.order_by.is_empty()
18765 || wf.over.frame.is_some()
18766 || wf.over.window_name.is_some();
18767
18768 if has_over {
18770 self.write_space();
18771 self.write_keyword("OVER");
18772
18773 let has_specs = !wf.over.partition_by.is_empty()
18775 || !wf.over.order_by.is_empty()
18776 || wf.over.frame.is_some();
18777
18778 if wf.over.window_name.is_some() && !has_specs {
18779 self.write_space();
18781 self.write(&wf.over.window_name.as_ref().unwrap().name);
18782 } else {
18783 self.write(" (");
18785 self.generate_over(&wf.over)?;
18786 self.write(")");
18787 }
18788 } else if wf.keep.is_none() {
18789 self.write_space();
18791 self.write_keyword("OVER");
18792 self.write(" ()");
18793 }
18794
18795 Ok(())
18796 }
18797
18798 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
18800 self.generate_expression(&wg.this)?;
18801 self.write_space();
18802 self.write_keyword("WITHIN GROUP");
18803 self.write(" (");
18804 self.write_keyword("ORDER BY");
18805 self.write_space();
18806 for (i, ord) in wg.order_by.iter().enumerate() {
18807 if i > 0 {
18808 self.write(", ");
18809 }
18810 self.generate_ordered(ord)?;
18811 }
18812 self.write(")");
18813 Ok(())
18814 }
18815
18816 fn generate_over(&mut self, over: &Over) -> Result<()> {
18818 let mut has_content = false;
18819
18820 if let Some(name) = &over.window_name {
18822 self.write(&name.name);
18823 has_content = true;
18824 }
18825
18826 if !over.partition_by.is_empty() {
18828 if has_content {
18829 self.write_space();
18830 }
18831 self.write_keyword("PARTITION BY");
18832 self.write_space();
18833 for (i, expr) in over.partition_by.iter().enumerate() {
18834 if i > 0 {
18835 self.write(", ");
18836 }
18837 self.generate_expression(expr)?;
18838 }
18839 has_content = true;
18840 }
18841
18842 if !over.order_by.is_empty() {
18844 if has_content {
18845 self.write_space();
18846 }
18847 self.write_keyword("ORDER BY");
18848 self.write_space();
18849 for (i, ordered) in over.order_by.iter().enumerate() {
18850 if i > 0 {
18851 self.write(", ");
18852 }
18853 self.generate_ordered(ordered)?;
18854 }
18855 has_content = true;
18856 }
18857
18858 if let Some(frame) = &over.frame {
18860 if has_content {
18861 self.write_space();
18862 }
18863 self.generate_window_frame(frame)?;
18864 }
18865
18866 Ok(())
18867 }
18868
18869 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
18870 let lowercase_frame = self.config.lowercase_window_frame_keywords;
18872
18873 if !lowercase_frame {
18875 if let Some(kind_text) = &frame.kind_text {
18876 self.write(kind_text);
18877 } else {
18878 match frame.kind {
18879 WindowFrameKind::Rows => self.write_keyword("ROWS"),
18880 WindowFrameKind::Range => self.write_keyword("RANGE"),
18881 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
18882 }
18883 }
18884 } else {
18885 match frame.kind {
18886 WindowFrameKind::Rows => self.write("rows"),
18887 WindowFrameKind::Range => self.write("range"),
18888 WindowFrameKind::Groups => self.write("groups"),
18889 }
18890 }
18891
18892 self.write_space();
18895 let should_normalize = self.config.normalize_window_frame_between
18896 && frame.end.is_none()
18897 && matches!(
18898 frame.start,
18899 WindowFrameBound::Preceding(_)
18900 | WindowFrameBound::Following(_)
18901 | WindowFrameBound::UnboundedPreceding
18902 | WindowFrameBound::UnboundedFollowing
18903 );
18904
18905 if let Some(end) = &frame.end {
18906 self.write_keyword("BETWEEN");
18908 self.write_space();
18909 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18910 self.write_space();
18911 self.write_keyword("AND");
18912 self.write_space();
18913 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
18914 } else if should_normalize {
18915 self.write_keyword("BETWEEN");
18917 self.write_space();
18918 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18919 self.write_space();
18920 self.write_keyword("AND");
18921 self.write_space();
18922 self.write_keyword("CURRENT ROW");
18923 } else {
18924 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18926 }
18927
18928 if let Some(exclude) = &frame.exclude {
18930 self.write_space();
18931 self.write_keyword("EXCLUDE");
18932 self.write_space();
18933 match exclude {
18934 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
18935 WindowFrameExclude::Group => self.write_keyword("GROUP"),
18936 WindowFrameExclude::Ties => self.write_keyword("TIES"),
18937 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
18938 }
18939 }
18940
18941 Ok(())
18942 }
18943
18944 fn generate_window_frame_bound(
18945 &mut self,
18946 bound: &WindowFrameBound,
18947 side_text: Option<&str>,
18948 ) -> Result<()> {
18949 let lowercase_frame = self.config.lowercase_window_frame_keywords;
18951
18952 match bound {
18953 WindowFrameBound::CurrentRow => {
18954 self.write_keyword("CURRENT ROW");
18955 }
18956 WindowFrameBound::UnboundedPreceding => {
18957 self.write_keyword("UNBOUNDED");
18958 self.write_space();
18959 if lowercase_frame {
18960 self.write("preceding");
18961 } else if let Some(text) = side_text {
18962 self.write(text);
18963 } else {
18964 self.write_keyword("PRECEDING");
18965 }
18966 }
18967 WindowFrameBound::UnboundedFollowing => {
18968 self.write_keyword("UNBOUNDED");
18969 self.write_space();
18970 if lowercase_frame {
18971 self.write("following");
18972 } else if let Some(text) = side_text {
18973 self.write(text);
18974 } else {
18975 self.write_keyword("FOLLOWING");
18976 }
18977 }
18978 WindowFrameBound::Preceding(expr) => {
18979 self.generate_expression(expr)?;
18980 self.write_space();
18981 if lowercase_frame {
18982 self.write("preceding");
18983 } else if let Some(text) = side_text {
18984 self.write(text);
18985 } else {
18986 self.write_keyword("PRECEDING");
18987 }
18988 }
18989 WindowFrameBound::Following(expr) => {
18990 self.generate_expression(expr)?;
18991 self.write_space();
18992 if lowercase_frame {
18993 self.write("following");
18994 } else if let Some(text) = side_text {
18995 self.write(text);
18996 } else {
18997 self.write_keyword("FOLLOWING");
18998 }
18999 }
19000 WindowFrameBound::BarePreceding => {
19001 if lowercase_frame {
19002 self.write("preceding");
19003 } else if let Some(text) = side_text {
19004 self.write(text);
19005 } else {
19006 self.write_keyword("PRECEDING");
19007 }
19008 }
19009 WindowFrameBound::BareFollowing => {
19010 if lowercase_frame {
19011 self.write("following");
19012 } else if let Some(text) = side_text {
19013 self.write(text);
19014 } else {
19015 self.write_keyword("FOLLOWING");
19016 }
19017 }
19018 WindowFrameBound::Value(expr) => {
19019 self.generate_expression(expr)?;
19021 }
19022 }
19023 Ok(())
19024 }
19025
19026 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
19027 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
19030 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
19031 && !matches!(&interval.this, Some(Expression::Literal(_)));
19032
19033 if self.config.single_string_interval {
19036 if let (
19037 Some(Expression::Literal(lit)),
19038 Some(IntervalUnitSpec::Simple {
19039 ref unit,
19040 ref use_plural,
19041 }),
19042 ) = (&interval.this, &interval.unit)
19043 {
19044 if let Literal::String(ref val) = lit.as_ref() {
19045 self.write_keyword("INTERVAL");
19046 self.write_space();
19047 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
19048 let unit_str = self.interval_unit_str(unit, effective_plural);
19049 self.write("'");
19050 self.write(val);
19051 self.write(" ");
19052 self.write(&unit_str);
19053 self.write("'");
19054 return Ok(());
19055 }
19056 }
19057 }
19058
19059 if !skip_interval_keyword {
19060 self.write_keyword("INTERVAL");
19061 }
19062
19063 if let Some(ref value) = interval.this {
19065 if !skip_interval_keyword {
19066 self.write_space();
19067 }
19068 let needs_parens = interval.unit.is_some()
19072 && matches!(
19073 value,
19074 Expression::Add(_)
19075 | Expression::Sub(_)
19076 | Expression::Mul(_)
19077 | Expression::Div(_)
19078 | Expression::Mod(_)
19079 | Expression::BitwiseAnd(_)
19080 | Expression::BitwiseOr(_)
19081 | Expression::BitwiseXor(_)
19082 );
19083 if needs_parens {
19084 self.write("(");
19085 }
19086 self.generate_expression(value)?;
19087 if needs_parens {
19088 self.write(")");
19089 }
19090 }
19091
19092 if let Some(ref unit_spec) = interval.unit {
19094 self.write_space();
19095 self.write_interval_unit_spec(unit_spec)?;
19096 }
19097
19098 Ok(())
19099 }
19100
19101 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
19103 match (unit, use_plural) {
19104 (IntervalUnit::Year, false) => "YEAR",
19105 (IntervalUnit::Year, true) => "YEARS",
19106 (IntervalUnit::Quarter, false) => "QUARTER",
19107 (IntervalUnit::Quarter, true) => "QUARTERS",
19108 (IntervalUnit::Month, false) => "MONTH",
19109 (IntervalUnit::Month, true) => "MONTHS",
19110 (IntervalUnit::Week, false) => "WEEK",
19111 (IntervalUnit::Week, true) => "WEEKS",
19112 (IntervalUnit::Day, false) => "DAY",
19113 (IntervalUnit::Day, true) => "DAYS",
19114 (IntervalUnit::Hour, false) => "HOUR",
19115 (IntervalUnit::Hour, true) => "HOURS",
19116 (IntervalUnit::Minute, false) => "MINUTE",
19117 (IntervalUnit::Minute, true) => "MINUTES",
19118 (IntervalUnit::Second, false) => "SECOND",
19119 (IntervalUnit::Second, true) => "SECONDS",
19120 (IntervalUnit::Millisecond, false) => "MILLISECOND",
19121 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
19122 (IntervalUnit::Microsecond, false) => "MICROSECOND",
19123 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
19124 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
19125 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
19126 }
19127 }
19128
19129 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
19130 match unit_spec {
19131 IntervalUnitSpec::Simple { unit, use_plural } => {
19132 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
19134 self.write_simple_interval_unit(unit, effective_plural);
19135 }
19136 IntervalUnitSpec::Span(span) => {
19137 self.write_simple_interval_unit(&span.this, false);
19138 self.write_space();
19139 self.write_keyword("TO");
19140 self.write_space();
19141 self.write_simple_interval_unit(&span.expression, false);
19142 }
19143 IntervalUnitSpec::ExprSpan(span) => {
19144 self.generate_expression(&span.this)?;
19146 self.write_space();
19147 self.write_keyword("TO");
19148 self.write_space();
19149 self.generate_expression(&span.expression)?;
19150 }
19151 IntervalUnitSpec::Expr(expr) => {
19152 self.generate_expression(expr)?;
19153 }
19154 }
19155 Ok(())
19156 }
19157
19158 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
19159 match (unit, use_plural) {
19161 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
19162 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
19163 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
19164 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
19165 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
19166 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
19167 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
19168 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
19169 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
19170 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
19171 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
19172 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
19173 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
19174 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
19175 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
19176 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
19177 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
19178 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
19179 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
19180 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
19181 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
19182 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
19183 }
19184 }
19185
19186 fn write_redshift_date_part(&mut self, expr: &Expression) {
19189 let part_str = self.extract_date_part_string(expr);
19190 if let Some(part) = part_str {
19191 let normalized = self.normalize_date_part(&part);
19192 self.write_keyword(&normalized);
19193 } else {
19194 let _ = self.generate_expression(expr);
19196 }
19197 }
19198
19199 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
19202 let part_str = self.extract_date_part_string(expr);
19203 if let Some(part) = part_str {
19204 let normalized = self.normalize_date_part(&part);
19205 self.write("'");
19206 self.write(&normalized);
19207 self.write("'");
19208 } else {
19209 let _ = self.generate_expression(expr);
19211 }
19212 }
19213
19214 fn write_tsql_date_part(&mut self, expr: &Expression) -> Result<()> {
19215 if let Some(part) = self.extract_date_part_string(expr) {
19216 let upper = part.to_ascii_uppercase();
19217 let unmapped = match upper.as_str() {
19218 "DAYOFWEEK" => "WEEKDAY",
19219 "WEEKISO" => "ISO_WEEK",
19220 "TIMEZONE_MINUTE" => "TZOFFSET",
19221 _ => part.as_str(),
19222 };
19223 self.write_keyword(unmapped);
19224 } else {
19225 self.generate_expression(expr)?;
19226 }
19227 Ok(())
19228 }
19229
19230 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
19232 match expr {
19233 Expression::Literal(lit)
19234 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
19235 {
19236 let crate::expressions::Literal::String(s) = lit.as_ref() else {
19237 unreachable!()
19238 };
19239 Some(s.clone())
19240 }
19241 Expression::Identifier(id) => Some(id.name.clone()),
19242 Expression::Var(v) => Some(v.this.clone()),
19243 Expression::Column(col) if col.table.is_none() => {
19244 Some(col.name.name.clone())
19246 }
19247 _ => None,
19248 }
19249 }
19250
19251 fn normalize_date_part(&self, part: &str) -> String {
19254 let mut buf = [0u8; 64];
19255 let lower: &str = if part.len() <= 64 {
19256 for (i, b) in part.bytes().enumerate() {
19257 buf[i] = b.to_ascii_lowercase();
19258 }
19259 std::str::from_utf8(&buf[..part.len()]).unwrap_or(part)
19260 } else {
19261 return part.to_ascii_uppercase();
19262 };
19263 match lower {
19264 "day" | "days" | "d" => "DAY".to_string(),
19265 "month" | "months" | "mon" | "mons" | "mm" => "MONTH".to_string(),
19266 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
19267 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
19268 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
19269 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
19270 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
19271 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
19272 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
19273 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
19274 _ => part.to_ascii_uppercase(),
19275 }
19276 }
19277
19278 fn write_datetime_field(&mut self, field: &DateTimeField) {
19279 match field {
19280 DateTimeField::Year => self.write_keyword("YEAR"),
19281 DateTimeField::Month => self.write_keyword("MONTH"),
19282 DateTimeField::Day => self.write_keyword("DAY"),
19283 DateTimeField::Hour => self.write_keyword("HOUR"),
19284 DateTimeField::Minute => self.write_keyword("MINUTE"),
19285 DateTimeField::Second => self.write_keyword("SECOND"),
19286 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
19287 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
19288 DateTimeField::DayOfWeek => {
19289 let name = match self.config.dialect {
19290 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
19291 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "WEEKDAY",
19292 _ => "DOW",
19293 };
19294 self.write_keyword(name);
19295 }
19296 DateTimeField::DayOfYear => {
19297 let name = match self.config.dialect {
19298 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
19299 _ => "DOY",
19300 };
19301 self.write_keyword(name);
19302 }
19303 DateTimeField::Week => self.write_keyword("WEEK"),
19304 DateTimeField::WeekWithModifier(modifier) => {
19305 self.write_keyword("WEEK");
19306 self.write("(");
19307 self.write(modifier);
19308 self.write(")");
19309 }
19310 DateTimeField::Quarter => self.write_keyword("QUARTER"),
19311 DateTimeField::Epoch => self.write_keyword("EPOCH"),
19312 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
19313 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
19314 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
19315 DateTimeField::Date => self.write_keyword("DATE"),
19316 DateTimeField::Time => self.write_keyword("TIME"),
19317 DateTimeField::Custom(name) => self.write(name),
19318 }
19319 }
19320
19321 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
19323 match field {
19324 DateTimeField::Year => self.write("year"),
19325 DateTimeField::Month => self.write("month"),
19326 DateTimeField::Day => self.write("day"),
19327 DateTimeField::Hour => self.write("hour"),
19328 DateTimeField::Minute => self.write("minute"),
19329 DateTimeField::Second => self.write("second"),
19330 DateTimeField::Millisecond => self.write("millisecond"),
19331 DateTimeField::Microsecond => self.write("microsecond"),
19332 DateTimeField::DayOfWeek => self.write("dow"),
19333 DateTimeField::DayOfYear => self.write("doy"),
19334 DateTimeField::Week => self.write("week"),
19335 DateTimeField::WeekWithModifier(modifier) => {
19336 self.write("week(");
19337 self.write(modifier);
19338 self.write(")");
19339 }
19340 DateTimeField::Quarter => self.write("quarter"),
19341 DateTimeField::Epoch => self.write("epoch"),
19342 DateTimeField::Timezone => self.write("timezone"),
19343 DateTimeField::TimezoneHour => self.write("timezone_hour"),
19344 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
19345 DateTimeField::Date => self.write("date"),
19346 DateTimeField::Time => self.write("time"),
19347 DateTimeField::Custom(name) => self.write(name),
19348 }
19349 }
19350
19351 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
19354 self.write_keyword(name);
19355 self.write("(");
19356 self.generate_expression(arg)?;
19357 self.write(")");
19358 Ok(())
19359 }
19360
19361 fn generate_unary_func(
19363 &mut self,
19364 default_name: &str,
19365 f: &crate::expressions::UnaryFunc,
19366 ) -> Result<()> {
19367 let name = f.original_name.as_deref().unwrap_or(default_name);
19368 self.write_keyword(name);
19369 self.write("(");
19370 self.generate_expression(&f.this)?;
19371 self.write(")");
19372 Ok(())
19373 }
19374
19375 fn generate_sqrt_cbrt(
19377 &mut self,
19378 f: &crate::expressions::UnaryFunc,
19379 func_name: &str,
19380 _op: &str,
19381 ) -> Result<()> {
19382 self.write_keyword(func_name);
19385 self.write("(");
19386 self.generate_expression(&f.this)?;
19387 self.write(")");
19388 Ok(())
19389 }
19390
19391 fn generate_binary_func(
19392 &mut self,
19393 name: &str,
19394 arg1: &Expression,
19395 arg2: &Expression,
19396 ) -> Result<()> {
19397 self.write_keyword(name);
19398 self.write("(");
19399 self.generate_expression(arg1)?;
19400 self.write(", ");
19401 self.generate_expression(arg2)?;
19402 self.write(")");
19403 Ok(())
19404 }
19405
19406 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
19410 let func_name = f.name.as_deref().unwrap_or("CHAR");
19412 self.write_keyword(func_name);
19413 self.write("(");
19414 for (i, arg) in f.args.iter().enumerate() {
19415 if i > 0 {
19416 self.write(", ");
19417 }
19418 self.generate_expression(arg)?;
19419 }
19420 if let Some(ref charset) = f.charset {
19421 self.write(" ");
19422 self.write_keyword("USING");
19423 self.write(" ");
19424 self.write(charset);
19425 }
19426 self.write(")");
19427 Ok(())
19428 }
19429
19430 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
19431 use crate::dialects::DialectType;
19432
19433 match self.config.dialect {
19434 Some(DialectType::Teradata) => {
19435 self.generate_expression(&f.this)?;
19437 self.write(" ** ");
19438 self.generate_expression(&f.expression)?;
19439 Ok(())
19440 }
19441 _ => {
19442 self.generate_binary_func("POWER", &f.this, &f.expression)
19444 }
19445 }
19446 }
19447
19448 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
19449 self.write_func_name(name);
19450 self.write("(");
19451 for (i, arg) in args.iter().enumerate() {
19452 if i > 0 {
19453 self.write(", ");
19454 }
19455 self.generate_expression(arg)?;
19456 }
19457 self.write(")");
19458 Ok(())
19459 }
19460
19461 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
19464 self.write_keyword("CONCAT_WS");
19465 self.write("(");
19466 self.generate_expression(&f.separator)?;
19467 for expr in &f.expressions {
19468 self.write(", ");
19469 self.generate_expression(expr)?;
19470 }
19471 self.write(")");
19472 Ok(())
19473 }
19474
19475 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
19476 if let Expression::Concat(op) = expr {
19477 Self::collect_concat_operands(&op.left, out);
19478 Self::collect_concat_operands(&op.right, out);
19479 } else {
19480 out.push(expr);
19481 }
19482 }
19483
19484 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
19485 let mut operands = Vec::new();
19486 Self::collect_concat_operands(&op.left, &mut operands);
19487 Self::collect_concat_operands(&op.right, &mut operands);
19488
19489 self.write_keyword("CONCAT");
19490 self.write("(");
19491 for (i, operand) in operands.iter().enumerate() {
19492 if i > 0 {
19493 self.write(", ");
19494 }
19495 self.generate_expression(operand)?;
19496 }
19497 self.write(")");
19498 Ok(())
19499 }
19500
19501 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
19502 if let Expression::DPipe(dpipe) = expr {
19503 Self::collect_dpipe_operands(&dpipe.this, out);
19504 Self::collect_dpipe_operands(&dpipe.expression, out);
19505 } else {
19506 out.push(expr);
19507 }
19508 }
19509
19510 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
19511 let mut operands = Vec::new();
19512 Self::collect_dpipe_operands(&e.this, &mut operands);
19513 Self::collect_dpipe_operands(&e.expression, &mut operands);
19514
19515 self.write_keyword("CONCAT");
19516 self.write("(");
19517 for (i, operand) in operands.iter().enumerate() {
19518 if i > 0 {
19519 self.write(", ");
19520 }
19521 self.generate_expression(operand)?;
19522 }
19523 self.write(")");
19524 Ok(())
19525 }
19526
19527 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
19528 let use_substr = matches!(
19530 self.config.dialect,
19531 Some(
19532 DialectType::Oracle
19533 | DialectType::Presto
19534 | DialectType::Trino
19535 | DialectType::Athena
19536 )
19537 );
19538 if use_substr {
19539 self.write_keyword("SUBSTR");
19540 } else {
19541 self.write_keyword("SUBSTRING");
19542 }
19543 self.write("(");
19544 self.generate_expression(&f.this)?;
19545 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
19547 let use_comma_syntax = matches!(
19549 self.config.dialect,
19550 Some(DialectType::Spark)
19551 | Some(DialectType::Hive)
19552 | Some(DialectType::Databricks)
19553 | Some(DialectType::TSQL)
19554 | Some(DialectType::Fabric)
19555 );
19556 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
19557 self.write_space();
19559 self.write_keyword("FROM");
19560 self.write_space();
19561 self.generate_expression(&f.start)?;
19562 if let Some(length) = &f.length {
19563 self.write_space();
19564 self.write_keyword("FOR");
19565 self.write_space();
19566 self.generate_expression(length)?;
19567 }
19568 } else {
19569 self.write(", ");
19571 self.generate_expression(&f.start)?;
19572 if let Some(length) = &f.length {
19573 self.write(", ");
19574 self.generate_expression(length)?;
19575 }
19576 }
19577 self.write(")");
19578 Ok(())
19579 }
19580
19581 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
19582 self.write_keyword("OVERLAY");
19583 self.write("(");
19584 self.generate_expression(&f.this)?;
19585 self.write_space();
19586 self.write_keyword("PLACING");
19587 self.write_space();
19588 self.generate_expression(&f.replacement)?;
19589 self.write_space();
19590 self.write_keyword("FROM");
19591 self.write_space();
19592 self.generate_expression(&f.from)?;
19593 if let Some(length) = &f.length {
19594 self.write_space();
19595 self.write_keyword("FOR");
19596 self.write_space();
19597 self.generate_expression(length)?;
19598 }
19599 self.write(")");
19600 Ok(())
19601 }
19602
19603 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
19604 if f.position_explicit && f.characters.is_none() {
19607 match f.position {
19608 TrimPosition::Leading => {
19609 self.write_keyword("LTRIM");
19610 self.write("(");
19611 self.generate_expression(&f.this)?;
19612 self.write(")");
19613 return Ok(());
19614 }
19615 TrimPosition::Trailing => {
19616 self.write_keyword("RTRIM");
19617 self.write("(");
19618 self.generate_expression(&f.this)?;
19619 self.write(")");
19620 return Ok(());
19621 }
19622 TrimPosition::Both => {
19623 }
19626 }
19627 }
19628
19629 self.write_keyword("TRIM");
19630 self.write("(");
19631 let force_standard = f.characters.is_some()
19634 && !f.sql_standard_syntax
19635 && matches!(
19636 self.config.dialect,
19637 Some(DialectType::Hive)
19638 | Some(DialectType::Spark)
19639 | Some(DialectType::Databricks)
19640 | Some(DialectType::ClickHouse)
19641 );
19642 let use_standard = (f.sql_standard_syntax || force_standard)
19643 && !(f.position_explicit
19644 && f.characters.is_none()
19645 && matches!(f.position, TrimPosition::Both));
19646 if use_standard {
19647 if f.position_explicit {
19650 match f.position {
19651 TrimPosition::Both => self.write_keyword("BOTH"),
19652 TrimPosition::Leading => self.write_keyword("LEADING"),
19653 TrimPosition::Trailing => self.write_keyword("TRAILING"),
19654 }
19655 self.write_space();
19656 }
19657 if let Some(chars) = &f.characters {
19658 self.generate_expression(chars)?;
19659 self.write_space();
19660 }
19661 self.write_keyword("FROM");
19662 self.write_space();
19663 self.generate_expression(&f.this)?;
19664 } else {
19665 self.generate_expression(&f.this)?;
19667 if let Some(chars) = &f.characters {
19668 self.write(", ");
19669 self.generate_expression(chars)?;
19670 }
19671 }
19672 self.write(")");
19673 Ok(())
19674 }
19675
19676 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
19677 self.write_keyword("REPLACE");
19678 self.write("(");
19679 self.generate_expression(&f.this)?;
19680 self.write(", ");
19681 self.generate_expression(&f.old)?;
19682 self.write(", ");
19683 self.generate_expression(&f.new)?;
19684 self.write(")");
19685 Ok(())
19686 }
19687
19688 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
19689 self.write_keyword(name);
19690 self.write("(");
19691 self.generate_expression(&f.this)?;
19692 self.write(", ");
19693 self.generate_expression(&f.length)?;
19694 self.write(")");
19695 Ok(())
19696 }
19697
19698 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
19699 self.write_keyword("REPEAT");
19700 self.write("(");
19701 self.generate_expression(&f.this)?;
19702 self.write(", ");
19703 self.generate_expression(&f.times)?;
19704 self.write(")");
19705 Ok(())
19706 }
19707
19708 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
19709 self.write_keyword(name);
19710 self.write("(");
19711 self.generate_expression(&f.this)?;
19712 self.write(", ");
19713 self.generate_expression(&f.length)?;
19714 if let Some(fill) = &f.fill {
19715 self.write(", ");
19716 self.generate_expression(fill)?;
19717 }
19718 self.write(")");
19719 Ok(())
19720 }
19721
19722 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
19723 self.write_keyword("SPLIT");
19724 self.write("(");
19725 self.generate_expression(&f.this)?;
19726 self.write(", ");
19727 self.generate_expression(&f.delimiter)?;
19728 self.write(")");
19729 Ok(())
19730 }
19731
19732 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
19733 use crate::dialects::DialectType;
19734 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
19736 self.generate_expression(&f.this)?;
19737 self.write(" ~ ");
19738 self.generate_expression(&f.pattern)?;
19739 } else if matches!(self.config.dialect, Some(DialectType::Exasol)) && f.flags.is_none() {
19740 self.generate_expression(&f.this)?;
19742 self.write_keyword(" REGEXP_LIKE ");
19743 self.generate_expression(&f.pattern)?;
19744 } else if matches!(
19745 self.config.dialect,
19746 Some(DialectType::SingleStore)
19747 | Some(DialectType::Spark)
19748 | Some(DialectType::Hive)
19749 | Some(DialectType::Databricks)
19750 ) && f.flags.is_none()
19751 {
19752 self.generate_expression(&f.this)?;
19754 self.write_keyword(" RLIKE ");
19755 self.generate_expression(&f.pattern)?;
19756 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
19757 self.write_keyword("REGEXP");
19759 self.write("(");
19760 self.generate_expression(&f.this)?;
19761 self.write(", ");
19762 self.generate_expression(&f.pattern)?;
19763 if let Some(flags) = &f.flags {
19764 self.write(", ");
19765 self.generate_expression(flags)?;
19766 }
19767 self.write(")");
19768 } else {
19769 self.write_keyword("REGEXP_LIKE");
19770 self.write("(");
19771 self.generate_expression(&f.this)?;
19772 self.write(", ");
19773 self.generate_expression(&f.pattern)?;
19774 if let Some(flags) = &f.flags {
19775 self.write(", ");
19776 self.generate_expression(flags)?;
19777 }
19778 self.write(")");
19779 }
19780 Ok(())
19781 }
19782
19783 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
19784 self.write_keyword("REGEXP_REPLACE");
19785 self.write("(");
19786 self.generate_expression(&f.this)?;
19787 self.write(", ");
19788 self.generate_expression(&f.pattern)?;
19789 self.write(", ");
19790 self.generate_expression(&f.replacement)?;
19791 if let Some(flags) = &f.flags {
19792 self.write(", ");
19793 self.generate_expression(flags)?;
19794 }
19795 self.write(")");
19796 Ok(())
19797 }
19798
19799 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
19800 self.write_keyword("REGEXP_EXTRACT");
19801 self.write("(");
19802 self.generate_expression(&f.this)?;
19803 self.write(", ");
19804 self.generate_expression(&f.pattern)?;
19805 if let Some(group) = &f.group {
19806 self.write(", ");
19807 self.generate_expression(group)?;
19808 }
19809 self.write(")");
19810 Ok(())
19811 }
19812
19813 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
19816 self.write_keyword("ROUND");
19817 self.write("(");
19818 self.generate_expression(&f.this)?;
19819 if let Some(decimals) = &f.decimals {
19820 self.write(", ");
19821 self.generate_expression(decimals)?;
19822 }
19823 self.write(")");
19824 Ok(())
19825 }
19826
19827 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
19828 self.write_keyword("FLOOR");
19829 self.write("(");
19830 self.generate_expression(&f.this)?;
19831 if let Some(to) = &f.to {
19833 self.write(" ");
19834 self.write_keyword("TO");
19835 self.write(" ");
19836 self.generate_expression(to)?;
19837 } else if let Some(scale) = &f.scale {
19838 self.write(", ");
19839 self.generate_expression(scale)?;
19840 }
19841 self.write(")");
19842 Ok(())
19843 }
19844
19845 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
19846 self.write_keyword("CEIL");
19847 self.write("(");
19848 self.generate_expression(&f.this)?;
19849 if let Some(to) = &f.to {
19851 self.write(" ");
19852 self.write_keyword("TO");
19853 self.write(" ");
19854 self.generate_expression(to)?;
19855 } else if let Some(decimals) = &f.decimals {
19856 self.write(", ");
19857 self.generate_expression(decimals)?;
19858 }
19859 self.write(")");
19860 Ok(())
19861 }
19862
19863 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
19864 use crate::expressions::Literal;
19865
19866 if let Some(base) = &f.base {
19867 if self.is_log_base_none() {
19870 if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "2"))
19871 {
19872 self.write_func_name("LOG2");
19873 self.write("(");
19874 self.generate_expression(&f.this)?;
19875 self.write(")");
19876 return Ok(());
19877 } else if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "10"))
19878 {
19879 self.write_func_name("LOG10");
19880 self.write("(");
19881 self.generate_expression(&f.this)?;
19882 self.write(")");
19883 return Ok(());
19884 }
19885 }
19887
19888 self.write_func_name("LOG");
19889 self.write("(");
19890 if self.is_log_value_first() {
19891 self.generate_expression(&f.this)?;
19893 self.write(", ");
19894 self.generate_expression(base)?;
19895 } else {
19896 self.generate_expression(base)?;
19898 self.write(", ");
19899 self.generate_expression(&f.this)?;
19900 }
19901 self.write(")");
19902 } else {
19903 self.write_func_name("LOG");
19905 self.write("(");
19906 self.generate_expression(&f.this)?;
19907 self.write(")");
19908 }
19909 Ok(())
19910 }
19911
19912 fn is_log_value_first(&self) -> bool {
19915 use crate::dialects::DialectType;
19916 matches!(
19917 self.config.dialect,
19918 Some(DialectType::BigQuery)
19919 | Some(DialectType::TSQL)
19920 | Some(DialectType::Tableau)
19921 | Some(DialectType::Fabric)
19922 )
19923 }
19924
19925 fn is_log_base_none(&self) -> bool {
19928 use crate::dialects::DialectType;
19929 matches!(
19930 self.config.dialect,
19931 Some(DialectType::Presto)
19932 | Some(DialectType::Trino)
19933 | Some(DialectType::ClickHouse)
19934 | Some(DialectType::Athena)
19935 )
19936 }
19937
19938 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
19941 self.write_keyword("CURRENT_TIME");
19942 if let Some(precision) = f.precision {
19943 self.write(&format!("({})", precision));
19944 } else if matches!(
19945 self.config.dialect,
19946 Some(crate::dialects::DialectType::MySQL)
19947 | Some(crate::dialects::DialectType::SingleStore)
19948 | Some(crate::dialects::DialectType::TiDB)
19949 ) {
19950 self.write("()");
19951 }
19952 Ok(())
19953 }
19954
19955 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
19956 use crate::dialects::DialectType;
19957
19958 if f.sysdate {
19960 match self.config.dialect {
19961 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
19962 self.write_keyword("SYSDATE");
19963 return Ok(());
19964 }
19965 Some(DialectType::Snowflake) => {
19966 self.write_keyword("SYSDATE");
19968 self.write("()");
19969 return Ok(());
19970 }
19971 _ => {
19972 }
19974 }
19975 }
19976
19977 self.write_keyword("CURRENT_TIMESTAMP");
19978 if let Some(precision) = f.precision {
19980 self.write(&format!("({})", precision));
19981 } else if matches!(
19982 self.config.dialect,
19983 Some(crate::dialects::DialectType::MySQL)
19984 | Some(crate::dialects::DialectType::SingleStore)
19985 | Some(crate::dialects::DialectType::TiDB)
19986 | Some(crate::dialects::DialectType::Spark)
19987 | Some(crate::dialects::DialectType::Hive)
19988 | Some(crate::dialects::DialectType::Databricks)
19989 | Some(crate::dialects::DialectType::ClickHouse)
19990 | Some(crate::dialects::DialectType::BigQuery)
19991 | Some(crate::dialects::DialectType::Snowflake)
19992 | Some(crate::dialects::DialectType::Exasol)
19993 ) {
19994 self.write("()");
19995 }
19996 Ok(())
19997 }
19998
19999 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
20000 if self.config.dialect == Some(DialectType::Exasol) {
20002 self.write_keyword("CONVERT_TZ");
20003 self.write("(");
20004 self.generate_expression(&f.this)?;
20005 self.write(", 'UTC', ");
20006 self.generate_expression(&f.zone)?;
20007 self.write(")");
20008 return Ok(());
20009 }
20010
20011 self.generate_expression(&f.this)?;
20012 self.write_space();
20013 self.write_keyword("AT TIME ZONE");
20014 self.write_space();
20015 self.generate_expression(&f.zone)?;
20016 Ok(())
20017 }
20018
20019 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
20020 use crate::dialects::DialectType;
20021
20022 let is_presto_like = matches!(
20025 self.config.dialect,
20026 Some(DialectType::Presto) | Some(DialectType::Trino)
20027 );
20028
20029 if is_presto_like {
20030 self.write_keyword(name);
20031 self.write("(");
20032 self.write("'");
20034 self.write_simple_interval_unit(&f.unit, false);
20035 self.write("'");
20036 self.write(", ");
20037 let needs_cast = !self.returns_integer_type(&f.interval);
20039 if needs_cast {
20040 self.write_keyword("CAST");
20041 self.write("(");
20042 }
20043 self.generate_expression(&f.interval)?;
20044 if needs_cast {
20045 self.write_space();
20046 self.write_keyword("AS");
20047 self.write_space();
20048 self.write_keyword("BIGINT");
20049 self.write(")");
20050 }
20051 self.write(", ");
20052 self.generate_expression(&f.this)?;
20053 self.write(")");
20054 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
20055 self.generate_expression(&f.this)?;
20056 self.write_space();
20057 if name.eq_ignore_ascii_case("DATE_SUB") {
20058 self.write("-");
20059 } else {
20060 self.write("+");
20061 }
20062 self.write_space();
20063 self.write_keyword("INTERVAL");
20064 self.write_space();
20065 self.write("'");
20066 let mut interval_gen = Generator::with_arc_config(self.config.clone());
20067 let interval_sql = interval_gen.generate(&f.interval)?;
20068 self.write(&interval_sql);
20069 self.write(" ");
20070 self.write_simple_interval_unit(&f.unit, false);
20071 self.write("'");
20072 } else {
20073 self.write_keyword(name);
20074 self.write("(");
20075 self.generate_expression(&f.this)?;
20076 self.write(", ");
20077 self.write_keyword("INTERVAL");
20078 self.write_space();
20079 self.generate_expression(&f.interval)?;
20080 self.write_space();
20081 self.write_simple_interval_unit(&f.unit, false); self.write(")");
20083 }
20084 Ok(())
20085 }
20086
20087 fn returns_integer_type(&self, expr: &Expression) -> bool {
20090 use crate::expressions::{DataType, Literal};
20091 match expr {
20092 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
20094 let Literal::Number(n) = lit.as_ref() else {
20095 unreachable!()
20096 };
20097 !n.contains('.')
20098 }
20099
20100 Expression::Floor(f) => self.returns_integer_type(&f.this),
20102
20103 Expression::Round(f) => {
20105 f.decimals.is_none() && self.returns_integer_type(&f.this)
20107 }
20108
20109 Expression::Sign(f) => self.returns_integer_type(&f.this),
20111
20112 Expression::Abs(f) => self.returns_integer_type(&f.this),
20114
20115 Expression::Mul(op) => {
20117 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
20118 }
20119 Expression::Add(op) => {
20120 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
20121 }
20122 Expression::Sub(op) => {
20123 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
20124 }
20125 Expression::Mod(op) => self.returns_integer_type(&op.left),
20126
20127 Expression::Cast(c) => matches!(
20129 &c.to,
20130 DataType::BigInt { .. }
20131 | DataType::Int { .. }
20132 | DataType::SmallInt { .. }
20133 | DataType::TinyInt { .. }
20134 ),
20135
20136 Expression::Neg(op) => self.returns_integer_type(&op.this),
20138
20139 Expression::Paren(p) => self.returns_integer_type(&p.this),
20141
20142 _ => false,
20145 }
20146 }
20147
20148 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
20149 self.write_keyword("DATEDIFF");
20150 self.write("(");
20151 if let Some(unit) = &f.unit {
20152 self.write_simple_interval_unit(unit, false); self.write(", ");
20154 }
20155 if self.config.dialect == Some(DialectType::Snowflake) {
20156 self.generate_expression(&f.expression)?;
20157 self.write(", ");
20158 self.generate_expression(&f.this)?;
20159 } else {
20160 self.generate_expression(&f.this)?;
20161 self.write(", ");
20162 self.generate_expression(&f.expression)?;
20163 }
20164 self.write(")");
20165 Ok(())
20166 }
20167
20168 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
20169 if self.config.dialect == Some(DialectType::ClickHouse) {
20170 self.write("dateTrunc");
20171 } else {
20172 self.write_keyword("DATE_TRUNC");
20173 }
20174 self.write("('");
20175 self.write_datetime_field(&f.unit);
20176 self.write("', ");
20177 self.generate_expression(&f.this)?;
20178 self.write(")");
20179 Ok(())
20180 }
20181
20182 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
20183 use crate::dialects::DialectType;
20184 use crate::expressions::DateTimeField;
20185
20186 self.write_keyword("LAST_DAY");
20187 self.write("(");
20188 self.generate_expression(&f.this)?;
20189 if let Some(unit) = &f.unit {
20190 self.write(", ");
20191 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
20194 if let DateTimeField::WeekWithModifier(_) = unit {
20195 self.write_keyword("WEEK");
20196 } else {
20197 self.write_datetime_field(unit);
20198 }
20199 } else {
20200 self.write_datetime_field(unit);
20201 }
20202 }
20203 self.write(")");
20204 Ok(())
20205 }
20206
20207 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
20208 if matches!(
20210 self.config.dialect,
20211 Some(DialectType::TSQL) | Some(DialectType::Fabric)
20212 ) {
20213 self.write_keyword("DATEPART");
20214 self.write("(");
20215 self.write_datetime_field(&f.field);
20216 self.write(", ");
20217 self.generate_expression(&f.this)?;
20218 self.write(")");
20219 return Ok(());
20220 }
20221 self.write_keyword("EXTRACT");
20222 self.write("(");
20223 if matches!(
20225 self.config.dialect,
20226 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
20227 ) {
20228 self.write_datetime_field_lower(&f.field);
20229 } else {
20230 self.write_datetime_field(&f.field);
20231 }
20232 self.write_space();
20233 self.write_keyword("FROM");
20234 self.write_space();
20235 self.generate_expression(&f.this)?;
20236 self.write(")");
20237 Ok(())
20238 }
20239
20240 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
20241 self.write_keyword("TO_DATE");
20242 self.write("(");
20243 self.generate_expression(&f.this)?;
20244 if let Some(format) = &f.format {
20245 self.write(", ");
20246 self.generate_expression(format)?;
20247 }
20248 self.write(")");
20249 Ok(())
20250 }
20251
20252 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
20253 self.write_keyword("TO_TIMESTAMP");
20254 self.write("(");
20255 self.generate_expression(&f.this)?;
20256 if let Some(format) = &f.format {
20257 self.write(", ");
20258 self.generate_expression(format)?;
20259 }
20260 self.write(")");
20261 Ok(())
20262 }
20263
20264 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
20267 use crate::dialects::DialectType;
20268
20269 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
20271 self.write_keyword("CASE WHEN");
20272 self.write_space();
20273 self.generate_expression(&f.condition)?;
20274 self.write_space();
20275 self.write_keyword("THEN");
20276 self.write_space();
20277 self.generate_expression(&f.true_value)?;
20278 if let Some(false_val) = &f.false_value {
20279 self.write_space();
20280 self.write_keyword("ELSE");
20281 self.write_space();
20282 self.generate_expression(false_val)?;
20283 }
20284 self.write_space();
20285 self.write_keyword("END");
20286 return Ok(());
20287 }
20288
20289 if self.config.dialect == Some(DialectType::Exasol) {
20291 self.write_keyword("IF");
20292 self.write_space();
20293 self.generate_expression(&f.condition)?;
20294 self.write_space();
20295 self.write_keyword("THEN");
20296 self.write_space();
20297 self.generate_expression(&f.true_value)?;
20298 if let Some(false_val) = &f.false_value {
20299 self.write_space();
20300 self.write_keyword("ELSE");
20301 self.write_space();
20302 self.generate_expression(false_val)?;
20303 }
20304 self.write_space();
20305 self.write_keyword("ENDIF");
20306 return Ok(());
20307 }
20308
20309 let func_name = match self.config.dialect {
20311 Some(DialectType::ClickHouse) => f.original_name.as_deref().unwrap_or("IF"),
20312 Some(DialectType::Snowflake) => "IFF",
20313 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
20314 Some(DialectType::Drill) => "`IF`",
20315 _ => "IF",
20316 };
20317 self.write(func_name);
20318 self.write("(");
20319 self.generate_expression(&f.condition)?;
20320 self.write(", ");
20321 self.generate_expression(&f.true_value)?;
20322 if let Some(false_val) = &f.false_value {
20323 self.write(", ");
20324 self.generate_expression(false_val)?;
20325 }
20326 self.write(")");
20327 Ok(())
20328 }
20329
20330 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
20331 self.write_keyword("NVL2");
20332 self.write("(");
20333 self.generate_expression(&f.this)?;
20334 self.write(", ");
20335 self.generate_expression(&f.true_value)?;
20336 self.write(", ");
20337 self.generate_expression(&f.false_value)?;
20338 self.write(")");
20339 Ok(())
20340 }
20341
20342 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
20345 let count_name = match self.config.normalize_functions {
20347 NormalizeFunctions::Upper => "COUNT".to_string(),
20348 NormalizeFunctions::Lower => "count".to_string(),
20349 NormalizeFunctions::None => f
20350 .original_name
20351 .clone()
20352 .unwrap_or_else(|| "COUNT".to_string()),
20353 };
20354 self.write(&count_name);
20355 self.write("(");
20356 if f.distinct {
20357 self.write_keyword("DISTINCT");
20358 self.write_space();
20359 }
20360 if f.star {
20361 self.write("*");
20362 } else if let Some(ref expr) = f.this {
20363 if let Expression::Tuple(tuple) = expr {
20365 let needs_transform =
20369 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
20370
20371 if needs_transform {
20372 self.write_keyword("CASE");
20374 for e in &tuple.expressions {
20375 self.write_space();
20376 self.write_keyword("WHEN");
20377 self.write_space();
20378 self.generate_expression(e)?;
20379 self.write_space();
20380 self.write_keyword("IS NULL THEN NULL");
20381 }
20382 self.write_space();
20383 self.write_keyword("ELSE");
20384 self.write(" (");
20385 for (i, e) in tuple.expressions.iter().enumerate() {
20386 if i > 0 {
20387 self.write(", ");
20388 }
20389 self.generate_expression(e)?;
20390 }
20391 self.write(")");
20392 self.write_space();
20393 self.write_keyword("END");
20394 } else {
20395 for (i, e) in tuple.expressions.iter().enumerate() {
20396 if i > 0 {
20397 self.write(", ");
20398 }
20399 self.generate_expression(e)?;
20400 }
20401 }
20402 } else {
20403 self.generate_expression(expr)?;
20404 }
20405 }
20406 let clickhouse_ignore_nulls_outside =
20407 matches!(self.config.dialect, Some(DialectType::ClickHouse));
20408 if let Some(ignore) = f.ignore_nulls.filter(|_| !clickhouse_ignore_nulls_outside) {
20409 self.write_space();
20410 if ignore {
20411 self.write_keyword("IGNORE NULLS");
20412 } else {
20413 self.write_keyword("RESPECT NULLS");
20414 }
20415 }
20416 self.write(")");
20417 if let Some(ignore) = f.ignore_nulls.filter(|_| clickhouse_ignore_nulls_outside) {
20418 self.write_space();
20419 if ignore {
20420 self.write_keyword("IGNORE NULLS");
20421 } else {
20422 self.write_keyword("RESPECT NULLS");
20423 }
20424 }
20425 if let Some(ref filter) = f.filter {
20426 self.write_space();
20427 self.write_keyword("FILTER");
20428 self.write("(");
20429 self.write_keyword("WHERE");
20430 self.write_space();
20431 self.generate_expression(filter)?;
20432 self.write(")");
20433 }
20434 Ok(())
20435 }
20436
20437 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
20438 let func_name: Cow<'_, str> = match self.config.normalize_functions {
20440 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
20441 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
20442 NormalizeFunctions::None => {
20443 if let Some(ref original) = f.name {
20446 Cow::Owned(original.clone())
20447 } else {
20448 Cow::Owned(name.to_ascii_lowercase())
20449 }
20450 }
20451 };
20452 self.write(func_name.as_ref());
20453 self.write("(");
20454 if f.distinct {
20455 self.write_keyword("DISTINCT");
20456 self.write_space();
20457 }
20458 let is_zero_arg_mode =
20461 name.eq_ignore_ascii_case("MODE") && matches!(f.this, Expression::Null(_));
20462 if !is_zero_arg_mode {
20463 self.generate_expression(&f.this)?;
20464 }
20465 if self.config.ignore_nulls_in_func
20468 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
20469 {
20470 match f.ignore_nulls {
20471 Some(true) => {
20472 self.write_space();
20473 self.write_keyword("IGNORE NULLS");
20474 }
20475 Some(false) => {
20476 self.write_space();
20477 self.write_keyword("RESPECT NULLS");
20478 }
20479 None => {}
20480 }
20481 }
20482 if let Some((ref expr, is_max)) = f.having_max {
20485 self.write_space();
20486 self.write_keyword("HAVING");
20487 self.write_space();
20488 if is_max {
20489 self.write_keyword("MAX");
20490 } else {
20491 self.write_keyword("MIN");
20492 }
20493 self.write_space();
20494 self.generate_expression(expr)?;
20495 }
20496 if !f.order_by.is_empty() {
20498 self.write_space();
20499 self.write_keyword("ORDER BY");
20500 self.write_space();
20501 for (i, ord) in f.order_by.iter().enumerate() {
20502 if i > 0 {
20503 self.write(", ");
20504 }
20505 self.generate_ordered(ord)?;
20506 }
20507 }
20508 if let Some(ref limit) = f.limit {
20510 self.write_space();
20511 self.write_keyword("LIMIT");
20512 self.write_space();
20513 if let Expression::Tuple(t) = limit.as_ref() {
20515 if t.expressions.len() == 2 {
20516 self.generate_expression(&t.expressions[0])?;
20517 self.write(", ");
20518 self.generate_expression(&t.expressions[1])?;
20519 } else {
20520 self.generate_expression(limit)?;
20521 }
20522 } else {
20523 self.generate_expression(limit)?;
20524 }
20525 }
20526 self.write(")");
20527 if !self.config.ignore_nulls_in_func
20530 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
20531 {
20532 match f.ignore_nulls {
20533 Some(true) => {
20534 self.write_space();
20535 self.write_keyword("IGNORE NULLS");
20536 }
20537 Some(false) => {
20538 self.write_space();
20539 self.write_keyword("RESPECT NULLS");
20540 }
20541 None => {}
20542 }
20543 }
20544 if let Some(ref filter) = f.filter {
20545 self.write_space();
20546 self.write_keyword("FILTER");
20547 self.write("(");
20548 self.write_keyword("WHERE");
20549 self.write_space();
20550 self.generate_expression(filter)?;
20551 self.write(")");
20552 }
20553 Ok(())
20554 }
20555
20556 fn generate_agg_func_with_ignore_nulls_bool(&mut self, name: &str, f: &AggFunc) -> Result<()> {
20559 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
20561 let func_name: Cow<'_, str> = match self.config.normalize_functions {
20563 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
20564 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
20565 NormalizeFunctions::None => {
20566 if let Some(ref original) = f.name {
20567 Cow::Owned(original.clone())
20568 } else {
20569 Cow::Owned(name.to_ascii_lowercase())
20570 }
20571 }
20572 };
20573 self.write(func_name.as_ref());
20574 self.write("(");
20575 if f.distinct {
20576 self.write_keyword("DISTINCT");
20577 self.write_space();
20578 }
20579 if !matches!(f.this, Expression::Null(_)) {
20580 self.generate_expression(&f.this)?;
20581 }
20582 self.write(", ");
20583 self.write_keyword("TRUE");
20584 self.write(")");
20585 return Ok(());
20586 }
20587 self.generate_agg_func(name, f)
20588 }
20589
20590 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
20591 self.write_keyword("GROUP_CONCAT");
20592 self.write("(");
20593 if f.distinct {
20594 self.write_keyword("DISTINCT");
20595 self.write_space();
20596 }
20597 self.generate_expression(&f.this)?;
20598 if let Some(ref order_by) = f.order_by {
20599 self.write_space();
20600 self.write_keyword("ORDER BY");
20601 self.write_space();
20602 for (i, ord) in order_by.iter().enumerate() {
20603 if i > 0 {
20604 self.write(", ");
20605 }
20606 self.generate_ordered(ord)?;
20607 }
20608 }
20609 if let Some(ref sep) = f.separator {
20610 if matches!(
20613 self.config.dialect,
20614 Some(crate::dialects::DialectType::SQLite)
20615 ) {
20616 self.write(", ");
20617 self.generate_expression(sep)?;
20618 } else {
20619 self.write_space();
20620 self.write_keyword("SEPARATOR");
20621 self.write_space();
20622 self.generate_expression(sep)?;
20623 }
20624 }
20625 if let Some(ref limit) = f.limit {
20626 self.write_space();
20627 self.write_keyword("LIMIT");
20628 self.write_space();
20629 self.generate_expression(limit)?;
20630 }
20631 self.write(")");
20632 if let Some(ref filter) = f.filter {
20633 self.write_space();
20634 self.write_keyword("FILTER");
20635 self.write("(");
20636 self.write_keyword("WHERE");
20637 self.write_space();
20638 self.generate_expression(filter)?;
20639 self.write(")");
20640 }
20641 Ok(())
20642 }
20643
20644 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
20645 let uses_within_group_order = matches!(
20646 self.config.dialect,
20647 Some(crate::dialects::DialectType::TSQL | crate::dialects::DialectType::Fabric)
20648 );
20649 self.write_keyword("STRING_AGG");
20650 self.write("(");
20651 if f.distinct {
20652 self.write_keyword("DISTINCT");
20653 self.write_space();
20654 }
20655 self.generate_expression(&f.this)?;
20656 if let Some(ref separator) = f.separator {
20657 self.write(", ");
20658 self.generate_expression(separator)?;
20659 }
20660 if !uses_within_group_order {
20662 if let Some(ref order_by) = f.order_by {
20663 self.write_space();
20664 self.write_keyword("ORDER BY");
20665 self.write_space();
20666 for (i, ord) in order_by.iter().enumerate() {
20667 if i > 0 {
20668 self.write(", ");
20669 }
20670 self.generate_ordered(ord)?;
20671 }
20672 }
20673 }
20674 if let Some(ref limit) = f.limit {
20675 self.write_space();
20676 self.write_keyword("LIMIT");
20677 self.write_space();
20678 self.generate_expression(limit)?;
20679 }
20680 self.write(")");
20681 if uses_within_group_order {
20682 if let Some(ref order_by) = f.order_by {
20683 self.write_space();
20684 self.write_keyword("WITHIN GROUP");
20685 self.write(" (");
20686 self.write_keyword("ORDER BY");
20687 self.write_space();
20688 for (i, ord) in order_by.iter().enumerate() {
20689 if i > 0 {
20690 self.write(", ");
20691 }
20692 self.generate_ordered(ord)?;
20693 }
20694 self.write(")");
20695 }
20696 }
20697 if let Some(ref filter) = f.filter {
20698 self.write_space();
20699 self.write_keyword("FILTER");
20700 self.write("(");
20701 self.write_keyword("WHERE");
20702 self.write_space();
20703 self.generate_expression(filter)?;
20704 self.write(")");
20705 }
20706 Ok(())
20707 }
20708
20709 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
20710 use crate::dialects::DialectType;
20711 let order_inside_args = matches!(self.config.dialect, Some(DialectType::DuckDB));
20712 self.write_keyword("LISTAGG");
20713 self.write("(");
20714 if f.distinct {
20715 self.write_keyword("DISTINCT");
20716 self.write_space();
20717 }
20718 self.generate_expression(&f.this)?;
20719 if let Some(ref sep) = f.separator {
20720 self.write(", ");
20721 self.generate_expression(sep)?;
20722 } else if matches!(
20723 self.config.dialect,
20724 Some(DialectType::Trino) | Some(DialectType::Presto)
20725 ) {
20726 self.write(", ','");
20728 }
20729 if let Some(ref overflow) = f.on_overflow {
20730 self.write_space();
20731 self.write_keyword("ON OVERFLOW");
20732 self.write_space();
20733 match overflow {
20734 ListAggOverflow::Error => self.write_keyword("ERROR"),
20735 ListAggOverflow::Truncate { filler, with_count } => {
20736 self.write_keyword("TRUNCATE");
20737 if let Some(ref fill) = filler {
20738 self.write_space();
20739 self.generate_expression(fill)?;
20740 }
20741 if *with_count {
20742 self.write_space();
20743 self.write_keyword("WITH COUNT");
20744 } else {
20745 self.write_space();
20746 self.write_keyword("WITHOUT COUNT");
20747 }
20748 }
20749 }
20750 }
20751 if order_inside_args {
20752 if let Some(ref order_by) = f.order_by {
20753 self.write_space();
20754 self.write_keyword("ORDER BY");
20755 self.write_space();
20756 for (i, ord) in order_by.iter().enumerate() {
20757 if i > 0 {
20758 self.write(", ");
20759 }
20760 self.generate_ordered(ord)?;
20761 }
20762 }
20763 }
20764 self.write(")");
20765 if !order_inside_args {
20766 if let Some(ref order_by) = f.order_by {
20767 self.write_space();
20768 self.write_keyword("WITHIN GROUP");
20769 self.write(" (");
20770 self.write_keyword("ORDER BY");
20771 self.write_space();
20772 for (i, ord) in order_by.iter().enumerate() {
20773 if i > 0 {
20774 self.write(", ");
20775 }
20776 self.generate_ordered(ord)?;
20777 }
20778 self.write(")");
20779 }
20780 }
20781 if let Some(ref filter) = f.filter {
20782 self.write_space();
20783 self.write_keyword("FILTER");
20784 self.write("(");
20785 self.write_keyword("WHERE");
20786 self.write_space();
20787 self.generate_expression(filter)?;
20788 self.write(")");
20789 }
20790 Ok(())
20791 }
20792
20793 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
20794 self.write_keyword("SUM_IF");
20795 self.write("(");
20796 self.generate_expression(&f.this)?;
20797 self.write(", ");
20798 self.generate_expression(&f.condition)?;
20799 self.write(")");
20800 if let Some(ref filter) = f.filter {
20801 self.write_space();
20802 self.write_keyword("FILTER");
20803 self.write("(");
20804 self.write_keyword("WHERE");
20805 self.write_space();
20806 self.generate_expression(filter)?;
20807 self.write(")");
20808 }
20809 Ok(())
20810 }
20811
20812 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
20813 self.write_keyword("APPROX_PERCENTILE");
20814 self.write("(");
20815 self.generate_expression(&f.this)?;
20816 self.write(", ");
20817 self.generate_expression(&f.percentile)?;
20818 if let Some(ref acc) = f.accuracy {
20819 self.write(", ");
20820 self.generate_expression(acc)?;
20821 }
20822 self.write(")");
20823 if let Some(ref filter) = f.filter {
20824 self.write_space();
20825 self.write_keyword("FILTER");
20826 self.write("(");
20827 self.write_keyword("WHERE");
20828 self.write_space();
20829 self.generate_expression(filter)?;
20830 self.write(")");
20831 }
20832 Ok(())
20833 }
20834
20835 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
20836 self.write_keyword(name);
20837 self.write("(");
20838 self.generate_expression(&f.percentile)?;
20839 self.write(")");
20840 if let Some(ref order_by) = f.order_by {
20841 self.write_space();
20842 self.write_keyword("WITHIN GROUP");
20843 self.write(" (");
20844 self.write_keyword("ORDER BY");
20845 self.write_space();
20846 self.generate_expression(&f.this)?;
20847 for ord in order_by.iter() {
20848 if ord.desc {
20849 self.write_space();
20850 self.write_keyword("DESC");
20851 }
20852 }
20853 self.write(")");
20854 }
20855 if let Some(ref filter) = f.filter {
20856 self.write_space();
20857 self.write_keyword("FILTER");
20858 self.write("(");
20859 self.write_keyword("WHERE");
20860 self.write_space();
20861 self.generate_expression(filter)?;
20862 self.write(")");
20863 }
20864 Ok(())
20865 }
20866
20867 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
20870 self.write_keyword("NTILE");
20871 self.write("(");
20872 if let Some(num_buckets) = &f.num_buckets {
20873 self.generate_expression(num_buckets)?;
20874 }
20875 if let Some(order_by) = &f.order_by {
20876 self.write_keyword(" ORDER BY ");
20877 for (i, ob) in order_by.iter().enumerate() {
20878 if i > 0 {
20879 self.write(", ");
20880 }
20881 self.generate_ordered(ob)?;
20882 }
20883 }
20884 self.write(")");
20885 Ok(())
20886 }
20887
20888 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
20889 self.write_keyword(name);
20890 self.write("(");
20891 self.generate_expression(&f.this)?;
20892 if let Some(ref offset) = f.offset {
20893 self.write(", ");
20894 self.generate_expression(offset)?;
20895 if let Some(ref default) = f.default {
20896 self.write(", ");
20897 self.generate_expression(default)?;
20898 }
20899 }
20900 if self.config.ignore_nulls_in_func {
20902 match f.ignore_nulls {
20903 Some(true) => {
20904 self.write_space();
20905 self.write_keyword("IGNORE NULLS");
20906 }
20907 Some(false) => {
20908 self.write_space();
20909 self.write_keyword("RESPECT NULLS");
20910 }
20911 None => {}
20912 }
20913 }
20914 self.write(")");
20915 if !self.config.ignore_nulls_in_func {
20917 match f.ignore_nulls {
20918 Some(true) => {
20919 self.write_space();
20920 self.write_keyword("IGNORE NULLS");
20921 }
20922 Some(false) => {
20923 self.write_space();
20924 self.write_keyword("RESPECT NULLS");
20925 }
20926 None => {}
20927 }
20928 }
20929 Ok(())
20930 }
20931
20932 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
20933 self.write_keyword(name);
20934 self.write("(");
20935 self.generate_expression(&f.this)?;
20936 if !f.order_by.is_empty() {
20938 self.write_space();
20939 self.write_keyword("ORDER BY");
20940 self.write_space();
20941 for (i, ordered) in f.order_by.iter().enumerate() {
20942 if i > 0 {
20943 self.write(", ");
20944 }
20945 self.generate_ordered(ordered)?;
20946 }
20947 }
20948 if self.config.ignore_nulls_in_func {
20950 match f.ignore_nulls {
20951 Some(true) => {
20952 self.write_space();
20953 self.write_keyword("IGNORE NULLS");
20954 }
20955 Some(false) => {
20956 self.write_space();
20957 self.write_keyword("RESPECT NULLS");
20958 }
20959 None => {}
20960 }
20961 }
20962 self.write(")");
20963 if !self.config.ignore_nulls_in_func {
20965 match f.ignore_nulls {
20966 Some(true) => {
20967 self.write_space();
20968 self.write_keyword("IGNORE NULLS");
20969 }
20970 Some(false) => {
20971 self.write_space();
20972 self.write_keyword("RESPECT NULLS");
20973 }
20974 None => {}
20975 }
20976 }
20977 Ok(())
20978 }
20979
20980 fn generate_value_func_with_ignore_nulls_bool(
20983 &mut self,
20984 name: &str,
20985 f: &ValueFunc,
20986 ) -> Result<()> {
20987 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
20988 self.write_keyword(name);
20989 self.write("(");
20990 self.generate_expression(&f.this)?;
20991 self.write(", ");
20992 self.write_keyword("TRUE");
20993 self.write(")");
20994 return Ok(());
20995 }
20996 self.generate_value_func(name, f)
20997 }
20998
20999 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
21000 self.write_keyword("NTH_VALUE");
21001 self.write("(");
21002 self.generate_expression(&f.this)?;
21003 self.write(", ");
21004 self.generate_expression(&f.offset)?;
21005 if self.config.ignore_nulls_in_func {
21007 match f.ignore_nulls {
21008 Some(true) => {
21009 self.write_space();
21010 self.write_keyword("IGNORE NULLS");
21011 }
21012 Some(false) => {
21013 self.write_space();
21014 self.write_keyword("RESPECT NULLS");
21015 }
21016 None => {}
21017 }
21018 }
21019 self.write(")");
21020 if matches!(
21022 self.config.dialect,
21023 Some(crate::dialects::DialectType::Snowflake)
21024 ) {
21025 match f.from_first {
21026 Some(true) => {
21027 self.write_space();
21028 self.write_keyword("FROM FIRST");
21029 }
21030 Some(false) => {
21031 self.write_space();
21032 self.write_keyword("FROM LAST");
21033 }
21034 None => {}
21035 }
21036 }
21037 if !self.config.ignore_nulls_in_func {
21039 match f.ignore_nulls {
21040 Some(true) => {
21041 self.write_space();
21042 self.write_keyword("IGNORE NULLS");
21043 }
21044 Some(false) => {
21045 self.write_space();
21046 self.write_keyword("RESPECT NULLS");
21047 }
21048 None => {}
21049 }
21050 }
21051 Ok(())
21052 }
21053
21054 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
21057 if matches!(
21060 self.config.dialect,
21061 Some(crate::dialects::DialectType::ClickHouse)
21062 ) {
21063 self.write_keyword("POSITION");
21064 self.write("(");
21065 self.generate_expression(&f.string)?;
21066 self.write(", ");
21067 self.generate_expression(&f.substring)?;
21068 if let Some(ref start) = f.start {
21069 self.write(", ");
21070 self.generate_expression(start)?;
21071 }
21072 self.write(")");
21073 return Ok(());
21074 }
21075
21076 self.write_keyword("POSITION");
21077 self.write("(");
21078 self.generate_expression(&f.substring)?;
21079 self.write_space();
21080 self.write_keyword("IN");
21081 self.write_space();
21082 self.generate_expression(&f.string)?;
21083 if let Some(ref start) = f.start {
21084 self.write(", ");
21085 self.generate_expression(start)?;
21086 }
21087 self.write(")");
21088 Ok(())
21089 }
21090
21091 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
21094 if f.lower.is_some() || f.upper.is_some() {
21096 self.write_keyword("RANDOM");
21097 self.write("(");
21098 if let Some(ref lower) = f.lower {
21099 self.generate_expression(lower)?;
21100 }
21101 if let Some(ref upper) = f.upper {
21102 self.write(", ");
21103 self.generate_expression(upper)?;
21104 }
21105 self.write(")");
21106 return Ok(());
21107 }
21108 let func_name = match self.config.dialect {
21110 Some(crate::dialects::DialectType::Snowflake)
21111 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
21112 _ => "RAND",
21113 };
21114 self.write_keyword(func_name);
21115 self.write("(");
21116 if !matches!(
21118 self.config.dialect,
21119 Some(crate::dialects::DialectType::DuckDB)
21120 ) {
21121 if let Some(ref seed) = f.seed {
21122 self.generate_expression(seed)?;
21123 }
21124 }
21125 self.write(")");
21126 Ok(())
21127 }
21128
21129 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
21130 self.write_keyword("TRUNCATE");
21131 self.write("(");
21132 self.generate_expression(&f.this)?;
21133 if let Some(ref decimals) = f.decimals {
21134 self.write(", ");
21135 self.generate_expression(decimals)?;
21136 }
21137 self.write(")");
21138 Ok(())
21139 }
21140
21141 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
21144 self.write_keyword("DECODE");
21145 self.write("(");
21146 self.generate_expression(&f.this)?;
21147 for (search, result) in &f.search_results {
21148 self.write(", ");
21149 self.generate_expression(search)?;
21150 self.write(", ");
21151 self.generate_expression(result)?;
21152 }
21153 if let Some(ref default) = f.default {
21154 self.write(", ");
21155 self.generate_expression(default)?;
21156 }
21157 self.write(")");
21158 Ok(())
21159 }
21160
21161 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
21164 self.write_keyword(name);
21165 self.write("(");
21166 self.generate_expression(&f.this)?;
21167 self.write(", ");
21168 self.generate_expression(&f.format)?;
21169 self.write(")");
21170 Ok(())
21171 }
21172
21173 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
21174 self.write_keyword("FROM_UNIXTIME");
21175 self.write("(");
21176 self.generate_expression(&f.this)?;
21177 if let Some(ref format) = f.format {
21178 self.write(", ");
21179 self.generate_expression(format)?;
21180 }
21181 self.write(")");
21182 Ok(())
21183 }
21184
21185 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
21186 self.write_keyword("UNIX_TIMESTAMP");
21187 self.write("(");
21188 if let Some(ref expr) = f.this {
21189 self.generate_expression(expr)?;
21190 if let Some(ref format) = f.format {
21191 self.write(", ");
21192 self.generate_expression(format)?;
21193 }
21194 } else if matches!(
21195 self.config.dialect,
21196 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
21197 ) {
21198 self.write_keyword("CURRENT_TIMESTAMP");
21200 self.write("()");
21201 }
21202 self.write(")");
21203 Ok(())
21204 }
21205
21206 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
21207 self.write_keyword("MAKE_DATE");
21208 self.write("(");
21209 self.generate_expression(&f.year)?;
21210 self.write(", ");
21211 self.generate_expression(&f.month)?;
21212 self.write(", ");
21213 self.generate_expression(&f.day)?;
21214 self.write(")");
21215 Ok(())
21216 }
21217
21218 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
21219 self.write_keyword("MAKE_TIMESTAMP");
21220 self.write("(");
21221 self.generate_expression(&f.year)?;
21222 self.write(", ");
21223 self.generate_expression(&f.month)?;
21224 self.write(", ");
21225 self.generate_expression(&f.day)?;
21226 self.write(", ");
21227 self.generate_expression(&f.hour)?;
21228 self.write(", ");
21229 self.generate_expression(&f.minute)?;
21230 self.write(", ");
21231 self.generate_expression(&f.second)?;
21232 if let Some(ref tz) = f.timezone {
21233 self.write(", ");
21234 self.generate_expression(tz)?;
21235 }
21236 self.write(")");
21237 Ok(())
21238 }
21239
21240 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
21242 match expr {
21243 Expression::Struct(s) => {
21244 if s.fields.iter().all(|(name, _)| name.is_some()) {
21245 Some(
21246 s.fields
21247 .iter()
21248 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
21249 .collect(),
21250 )
21251 } else {
21252 None
21253 }
21254 }
21255 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
21256 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
21258 Some(
21259 f.args
21260 .iter()
21261 .filter_map(|a| {
21262 if let Expression::Alias(alias) = a {
21263 Some(alias.alias.name.clone())
21264 } else {
21265 None
21266 }
21267 })
21268 .collect(),
21269 )
21270 } else {
21271 None
21272 }
21273 }
21274 _ => None,
21275 }
21276 }
21277
21278 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
21280 match expr {
21281 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
21282 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
21283 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
21284 }
21285 _ => false,
21286 }
21287 }
21288
21289 fn struct_field_count(expr: &Expression) -> usize {
21291 match expr {
21292 Expression::Struct(s) => s.fields.len(),
21293 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => f.args.len(),
21294 _ => 0,
21295 }
21296 }
21297
21298 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
21300 match expr {
21301 Expression::Struct(s) => {
21302 let mut new_fields = Vec::with_capacity(s.fields.len());
21303 for (i, (name, value)) in s.fields.iter().enumerate() {
21304 if name.is_none() && i < field_names.len() {
21305 new_fields.push((Some(field_names[i].clone()), value.clone()));
21306 } else {
21307 new_fields.push((name.clone(), value.clone()));
21308 }
21309 }
21310 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
21311 }
21312 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
21313 let mut new_args = Vec::with_capacity(f.args.len());
21314 for (i, arg) in f.args.iter().enumerate() {
21315 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
21316 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
21318 this: arg.clone(),
21319 alias: crate::expressions::Identifier::new(field_names[i].clone()),
21320 column_aliases: Vec::new(),
21321 alias_explicit_as: false,
21322 alias_keyword: None,
21323 pre_alias_comments: Vec::new(),
21324 trailing_comments: Vec::new(),
21325 inferred_type: None,
21326 })));
21327 } else {
21328 new_args.push(arg.clone());
21329 }
21330 }
21331 Expression::Function(Box::new(crate::expressions::Function {
21332 name: f.name.clone(),
21333 args: new_args,
21334 distinct: f.distinct,
21335 trailing_comments: f.trailing_comments.clone(),
21336 use_bracket_syntax: f.use_bracket_syntax,
21337 no_parens: f.no_parens,
21338 quoted: f.quoted,
21339 span: None,
21340 inferred_type: None,
21341 }))
21342 }
21343 _ => expr.clone(),
21344 }
21345 }
21346
21347 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
21351 let first = match expressions.first() {
21352 Some(e) => e,
21353 None => return expressions.to_vec(),
21354 };
21355
21356 let field_names = match Self::extract_struct_field_names(first) {
21357 Some(names) if !names.is_empty() => names,
21358 _ => return expressions.to_vec(),
21359 };
21360
21361 let mut result = Vec::with_capacity(expressions.len());
21362 for (idx, expr) in expressions.iter().enumerate() {
21363 if idx == 0 {
21364 result.push(expr.clone());
21365 continue;
21366 }
21367 if Self::struct_field_count(expr) == field_names.len()
21369 && Self::struct_has_unnamed_fields(expr)
21370 {
21371 result.push(Self::apply_struct_field_names(expr, &field_names));
21372 } else {
21373 result.push(expr.clone());
21374 }
21375 }
21376 result
21377 }
21378
21379 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
21382 let needs_inheritance = matches!(
21385 self.config.dialect,
21386 Some(DialectType::DuckDB)
21387 | Some(DialectType::Spark)
21388 | Some(DialectType::Databricks)
21389 | Some(DialectType::Hive)
21390 | Some(DialectType::Snowflake)
21391 | Some(DialectType::Presto)
21392 | Some(DialectType::Trino)
21393 );
21394 let propagated: Vec<Expression>;
21395 let expressions = if needs_inheritance && f.expressions.len() > 1 {
21396 propagated = Self::inherit_struct_field_names(&f.expressions);
21397 &propagated
21398 } else {
21399 &f.expressions
21400 };
21401
21402 let should_split = if self.config.pretty && !expressions.is_empty() {
21404 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
21405 for expr in expressions {
21406 let mut temp_gen = Generator::with_arc_config(self.config.clone());
21407 Arc::make_mut(&mut temp_gen.config).pretty = false;
21408 temp_gen.generate_expression(expr)?;
21409 expr_strings.push(temp_gen.output);
21410 }
21411 self.too_wide(&expr_strings)
21412 } else {
21413 false
21414 };
21415
21416 if f.bracket_notation {
21417 let (open, close) = match self.config.dialect {
21421 None
21422 | Some(DialectType::Generic)
21423 | Some(DialectType::Spark)
21424 | Some(DialectType::Databricks)
21425 | Some(DialectType::Hive) => {
21426 self.write_keyword("ARRAY");
21427 ("(", ")")
21428 }
21429 Some(DialectType::Presto)
21430 | Some(DialectType::Trino)
21431 | Some(DialectType::PostgreSQL)
21432 | Some(DialectType::Redshift)
21433 | Some(DialectType::Materialize)
21434 | Some(DialectType::RisingWave)
21435 | Some(DialectType::CockroachDB) => {
21436 self.write_keyword("ARRAY");
21437 ("[", "]")
21438 }
21439 _ => ("[", "]"),
21440 };
21441 self.write(open);
21442 if should_split {
21443 self.write_newline();
21444 self.indent_level += 1;
21445 for (i, expr) in expressions.iter().enumerate() {
21446 self.write_indent();
21447 self.generate_expression(expr)?;
21448 if i + 1 < expressions.len() {
21449 self.write(",");
21450 }
21451 self.write_newline();
21452 }
21453 self.indent_level -= 1;
21454 self.write_indent();
21455 } else {
21456 for (i, expr) in expressions.iter().enumerate() {
21457 if i > 0 {
21458 self.write(", ");
21459 }
21460 self.generate_expression(expr)?;
21461 }
21462 }
21463 self.write(close);
21464 } else {
21465 if f.use_list_keyword {
21467 self.write_keyword("LIST");
21468 } else {
21469 self.write_keyword("ARRAY");
21470 }
21471 let has_subquery = expressions
21474 .iter()
21475 .any(|e| matches!(e, Expression::Select(_)));
21476 let (open, close) = if matches!(
21477 self.config.dialect,
21478 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
21479 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
21480 && has_subquery)
21481 {
21482 ("(", ")")
21483 } else {
21484 ("[", "]")
21485 };
21486 self.write(open);
21487 if should_split {
21488 self.write_newline();
21489 self.indent_level += 1;
21490 for (i, expr) in expressions.iter().enumerate() {
21491 self.write_indent();
21492 self.generate_expression(expr)?;
21493 if i + 1 < expressions.len() {
21494 self.write(",");
21495 }
21496 self.write_newline();
21497 }
21498 self.indent_level -= 1;
21499 self.write_indent();
21500 } else {
21501 for (i, expr) in expressions.iter().enumerate() {
21502 if i > 0 {
21503 self.write(", ");
21504 }
21505 self.generate_expression(expr)?;
21506 }
21507 }
21508 self.write(close);
21509 }
21510 Ok(())
21511 }
21512
21513 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
21514 self.write_keyword("ARRAY_SORT");
21515 self.write("(");
21516 self.generate_expression(&f.this)?;
21517 if let Some(ref comp) = f.comparator {
21518 self.write(", ");
21519 self.generate_expression(comp)?;
21520 }
21521 self.write(")");
21522 Ok(())
21523 }
21524
21525 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
21526 self.write_keyword(name);
21527 self.write("(");
21528 self.generate_expression(&f.this)?;
21529 self.write(", ");
21530 self.generate_expression(&f.separator)?;
21531 if let Some(ref null_rep) = f.null_replacement {
21532 self.write(", ");
21533 self.generate_expression(null_rep)?;
21534 }
21535 self.write(")");
21536 Ok(())
21537 }
21538
21539 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
21540 self.write_keyword("UNNEST");
21541 self.write("(");
21542 self.generate_expression(&f.this)?;
21543 for extra in &f.expressions {
21544 self.write(", ");
21545 self.generate_expression(extra)?;
21546 }
21547 self.write(")");
21548 if f.with_ordinality {
21549 self.write_space();
21550 if self.config.unnest_with_ordinality {
21551 self.write_keyword("WITH ORDINALITY");
21553 } else if f.offset_alias.is_some() {
21554 if let Some(ref alias) = f.alias {
21557 self.write_keyword("AS");
21558 self.write_space();
21559 self.generate_identifier(alias)?;
21560 self.write_space();
21561 }
21562 self.write_keyword("WITH OFFSET");
21563 if let Some(ref offset_alias) = f.offset_alias {
21564 self.write_space();
21565 self.write_keyword("AS");
21566 self.write_space();
21567 self.generate_identifier(offset_alias)?;
21568 }
21569 } else {
21570 self.write_keyword("WITH OFFSET");
21572 if f.alias.is_none() {
21573 self.write(" AS offset");
21574 }
21575 }
21576 }
21577 if let Some(ref alias) = f.alias {
21578 let should_add_alias = if !f.with_ordinality {
21580 true
21581 } else if self.config.unnest_with_ordinality {
21582 true
21584 } else if f.offset_alias.is_some() {
21585 false
21587 } else {
21588 true
21590 };
21591 if should_add_alias {
21592 self.write_space();
21593 self.write_keyword("AS");
21594 self.write_space();
21595 self.generate_identifier(alias)?;
21596 }
21597 }
21598 Ok(())
21599 }
21600
21601 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
21602 self.write_keyword("FILTER");
21603 self.write("(");
21604 self.generate_expression(&f.this)?;
21605 self.write(", ");
21606 self.generate_expression(&f.filter)?;
21607 self.write(")");
21608 Ok(())
21609 }
21610
21611 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
21612 self.write_keyword("TRANSFORM");
21613 self.write("(");
21614 self.generate_expression(&f.this)?;
21615 self.write(", ");
21616 self.generate_expression(&f.transform)?;
21617 self.write(")");
21618 Ok(())
21619 }
21620
21621 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
21622 self.write_keyword(name);
21623 self.write("(");
21624 self.generate_expression(&f.start)?;
21625 self.write(", ");
21626 self.generate_expression(&f.stop)?;
21627 if let Some(ref step) = f.step {
21628 self.write(", ");
21629 self.generate_expression(step)?;
21630 }
21631 self.write(")");
21632 Ok(())
21633 }
21634
21635 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
21638 self.write_keyword("STRUCT");
21639 self.write("(");
21640 for (i, (name, expr)) in f.fields.iter().enumerate() {
21641 if i > 0 {
21642 self.write(", ");
21643 }
21644 if let Some(ref id) = name {
21645 self.generate_identifier(id)?;
21646 self.write(" ");
21647 self.write_keyword("AS");
21648 self.write(" ");
21649 }
21650 self.generate_expression(expr)?;
21651 }
21652 self.write(")");
21653 Ok(())
21654 }
21655
21656 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
21658 let mut names: Vec<Option<String>> = Vec::new();
21661 let mut values: Vec<&Expression> = Vec::new();
21662 let mut all_named = true;
21663
21664 for arg in &func.args {
21665 match arg {
21666 Expression::Alias(a) => {
21667 names.push(Some(a.alias.name.clone()));
21668 values.push(&a.this);
21669 }
21670 _ => {
21671 names.push(None);
21672 values.push(arg);
21673 all_named = false;
21674 }
21675 }
21676 }
21677
21678 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
21679 self.write("{");
21681 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
21682 if i > 0 {
21683 self.write(", ");
21684 }
21685 if let Some(n) = name {
21686 self.write("'");
21687 self.write(n);
21688 self.write("'");
21689 } else {
21690 self.write("'_");
21691 self.write(&i.to_string());
21692 self.write("'");
21693 }
21694 self.write(": ");
21695 self.generate_expression(value)?;
21696 }
21697 self.write("}");
21698 return Ok(());
21699 }
21700
21701 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
21702 self.write_keyword("OBJECT_CONSTRUCT");
21704 self.write("(");
21705 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
21706 if i > 0 {
21707 self.write(", ");
21708 }
21709 if let Some(n) = name {
21710 self.write("'");
21711 self.write(n);
21712 self.write("'");
21713 } else {
21714 self.write("'_");
21715 self.write(&i.to_string());
21716 self.write("'");
21717 }
21718 self.write(", ");
21719 self.generate_expression(value)?;
21720 }
21721 self.write(")");
21722 return Ok(());
21723 }
21724
21725 if matches!(
21726 self.config.dialect,
21727 Some(DialectType::Presto) | Some(DialectType::Trino)
21728 ) {
21729 if all_named && !names.is_empty() {
21730 self.write_keyword("CAST");
21733 self.write("(");
21734 self.write_keyword("ROW");
21735 self.write("(");
21736 for (i, value) in values.iter().enumerate() {
21737 if i > 0 {
21738 self.write(", ");
21739 }
21740 self.generate_expression(value)?;
21741 }
21742 self.write(")");
21743 self.write(" ");
21744 self.write_keyword("AS");
21745 self.write(" ");
21746 self.write_keyword("ROW");
21747 self.write("(");
21748 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
21749 if i > 0 {
21750 self.write(", ");
21751 }
21752 if let Some(n) = name {
21753 self.write(n);
21754 }
21755 self.write(" ");
21756 let type_str = Self::infer_sql_type_for_presto(value);
21757 self.write_keyword(&type_str);
21758 }
21759 self.write(")");
21760 self.write(")");
21761 } else {
21762 self.write_keyword("ROW");
21764 self.write("(");
21765 for (i, value) in values.iter().enumerate() {
21766 if i > 0 {
21767 self.write(", ");
21768 }
21769 self.generate_expression(value)?;
21770 }
21771 self.write(")");
21772 }
21773 return Ok(());
21774 }
21775
21776 self.write_keyword("ROW");
21778 self.write("(");
21779 for (i, value) in values.iter().enumerate() {
21780 if i > 0 {
21781 self.write(", ");
21782 }
21783 self.generate_expression(value)?;
21784 }
21785 self.write(")");
21786 Ok(())
21787 }
21788
21789 fn infer_sql_type_for_presto(expr: &Expression) -> String {
21791 match expr {
21792 Expression::Literal(lit)
21793 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
21794 {
21795 "VARCHAR".to_string()
21796 }
21797 Expression::Literal(lit)
21798 if matches!(lit.as_ref(), crate::expressions::Literal::Number(_)) =>
21799 {
21800 let crate::expressions::Literal::Number(n) = lit.as_ref() else {
21801 unreachable!()
21802 };
21803 if n.contains('.') {
21804 "DOUBLE".to_string()
21805 } else {
21806 "INTEGER".to_string()
21807 }
21808 }
21809 Expression::Boolean(_) => "BOOLEAN".to_string(),
21810 Expression::Literal(lit)
21811 if matches!(lit.as_ref(), crate::expressions::Literal::Date(_)) =>
21812 {
21813 "DATE".to_string()
21814 }
21815 Expression::Literal(lit)
21816 if matches!(lit.as_ref(), crate::expressions::Literal::Timestamp(_)) =>
21817 {
21818 "TIMESTAMP".to_string()
21819 }
21820 Expression::Literal(lit)
21821 if matches!(lit.as_ref(), crate::expressions::Literal::Datetime(_)) =>
21822 {
21823 "TIMESTAMP".to_string()
21824 }
21825 Expression::Array(_) | Expression::ArrayFunc(_) => {
21826 "ARRAY(VARCHAR)".to_string()
21828 }
21829 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
21831 Expression::Function(f) => {
21832 if f.name.eq_ignore_ascii_case("STRUCT") {
21833 "ROW".to_string()
21834 } else if f.name.eq_ignore_ascii_case("CURRENT_DATE") {
21835 "DATE".to_string()
21836 } else if f.name.eq_ignore_ascii_case("CURRENT_TIMESTAMP")
21837 || f.name.eq_ignore_ascii_case("NOW")
21838 {
21839 "TIMESTAMP".to_string()
21840 } else {
21841 "VARCHAR".to_string()
21842 }
21843 }
21844 _ => "VARCHAR".to_string(),
21845 }
21846 }
21847
21848 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
21849 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
21851 self.write_keyword("STRUCT_EXTRACT");
21852 self.write("(");
21853 self.generate_expression(&f.this)?;
21854 self.write(", ");
21855 self.write("'");
21857 self.write(&f.field.name);
21858 self.write("'");
21859 self.write(")");
21860 return Ok(());
21861 }
21862 self.generate_expression(&f.this)?;
21863 self.write(".");
21864 self.generate_identifier(&f.field)
21865 }
21866
21867 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
21868 if matches!(
21869 self.config.dialect,
21870 Some(DialectType::Spark | DialectType::Databricks)
21871 ) {
21872 self.write_keyword("STRUCT");
21873 self.write("(");
21874 for (i, (name, value)) in f.pairs.iter().enumerate() {
21875 if i > 0 {
21876 self.write(", ");
21877 }
21878 self.generate_expression(value)?;
21879 self.write(" ");
21880 self.write_keyword("AS");
21881 self.write(" ");
21882 if let Expression::Literal(lit) = name {
21883 if let Literal::String(field_name) = lit.as_ref() {
21884 self.generate_identifier(&Identifier::new(field_name))?;
21885 } else {
21886 self.generate_expression(name)?;
21887 }
21888 } else {
21889 self.generate_expression(name)?;
21890 }
21891 }
21892 self.write(")");
21893 return Ok(());
21894 }
21895
21896 self.write_keyword("NAMED_STRUCT");
21897 self.write("(");
21898 for (i, (name, value)) in f.pairs.iter().enumerate() {
21899 if i > 0 {
21900 self.write(", ");
21901 }
21902 self.generate_expression(name)?;
21903 self.write(", ");
21904 self.generate_expression(value)?;
21905 }
21906 self.write(")");
21907 Ok(())
21908 }
21909
21910 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
21913 if f.curly_brace_syntax {
21914 if f.with_map_keyword {
21916 self.write_keyword("MAP");
21917 self.write(" ");
21918 }
21919 self.write("{");
21920 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
21921 if i > 0 {
21922 self.write(", ");
21923 }
21924 self.generate_expression(key)?;
21925 self.write(": ");
21926 self.generate_expression(val)?;
21927 }
21928 self.write("}");
21929 } else {
21930 self.write_keyword("MAP");
21932 self.write("(");
21933 self.write_keyword("ARRAY");
21934 self.write("[");
21935 for (i, key) in f.keys.iter().enumerate() {
21936 if i > 0 {
21937 self.write(", ");
21938 }
21939 self.generate_expression(key)?;
21940 }
21941 self.write("], ");
21942 self.write_keyword("ARRAY");
21943 self.write("[");
21944 for (i, val) in f.values.iter().enumerate() {
21945 if i > 0 {
21946 self.write(", ");
21947 }
21948 self.generate_expression(val)?;
21949 }
21950 self.write("])");
21951 }
21952 Ok(())
21953 }
21954
21955 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
21956 self.write_keyword(name);
21957 self.write("(");
21958 self.generate_expression(&f.this)?;
21959 self.write(", ");
21960 self.generate_expression(&f.transform)?;
21961 self.write(")");
21962 Ok(())
21963 }
21964
21965 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
21968 use crate::dialects::DialectType;
21969
21970 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
21972
21973 if use_arrow {
21974 self.generate_expression(&f.this)?;
21976 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
21977 self.write(" ->> ");
21978 } else {
21979 self.write(" -> ");
21980 }
21981 self.generate_expression(&f.path)?;
21982 return Ok(());
21983 }
21984
21985 if f.hash_arrow_syntax
21987 && matches!(
21988 self.config.dialect,
21989 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21990 )
21991 {
21992 self.generate_expression(&f.this)?;
21993 self.write(" #>> ");
21994 self.generate_expression(&f.path)?;
21995 return Ok(());
21996 }
21997
21998 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
22001 match name {
22002 "JSON_EXTRACT_SCALAR"
22003 | "JSON_EXTRACT_PATH_TEXT"
22004 | "JSON_EXTRACT"
22005 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
22006 _ => name,
22007 }
22008 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
22009 match name {
22010 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
22011 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
22012 _ => name,
22013 }
22014 } else {
22015 name
22016 };
22017
22018 self.write_keyword(func_name);
22019 self.write("(");
22020 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
22022 if let Expression::Cast(ref cast) = f.this {
22023 if matches!(cast.to, crate::expressions::DataType::Json) {
22024 self.generate_expression(&cast.this)?;
22025 } else {
22026 self.generate_expression(&f.this)?;
22027 }
22028 } else {
22029 self.generate_expression(&f.this)?;
22030 }
22031 } else {
22032 self.generate_expression(&f.this)?;
22033 }
22034 if matches!(
22037 self.config.dialect,
22038 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22039 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
22040 {
22041 if let Expression::Literal(ref lit) = f.path {
22042 if let Literal::String(ref s) = lit.as_ref() {
22043 let parts = Self::decompose_json_path(s);
22044 for part in &parts {
22045 self.write(", '");
22046 self.write(part);
22047 self.write("'");
22048 }
22049 }
22050 } else {
22051 self.write(", ");
22052 self.generate_expression(&f.path)?;
22053 }
22054 } else {
22055 self.write(", ");
22056 self.generate_expression(&f.path)?;
22057 }
22058
22059 if let Some(ref wrapper) = f.wrapper_option {
22062 self.write_space();
22063 self.write_keyword(wrapper);
22064 }
22065 if let Some(ref quotes) = f.quotes_option {
22066 self.write_space();
22067 self.write_keyword(quotes);
22068 if f.on_scalar_string {
22069 self.write_space();
22070 self.write_keyword("ON SCALAR STRING");
22071 }
22072 }
22073 if let Some(ref on_err) = f.on_error {
22074 self.write_space();
22075 self.write_keyword(on_err);
22076 }
22077 if let Some(ref ret_type) = f.returning {
22078 self.write_space();
22079 self.write_keyword("RETURNING");
22080 self.write_space();
22081 self.generate_data_type(ret_type)?;
22082 }
22083
22084 self.write(")");
22085 Ok(())
22086 }
22087
22088 fn dialect_supports_json_arrow(&self) -> bool {
22090 use crate::dialects::DialectType;
22091 match self.config.dialect {
22092 Some(DialectType::PostgreSQL) => true,
22094 Some(DialectType::MySQL) => true,
22095 Some(DialectType::DuckDB) => true,
22096 Some(DialectType::CockroachDB) => true,
22097 Some(DialectType::StarRocks) => true,
22098 Some(DialectType::SQLite) => true,
22099 _ => false,
22101 }
22102 }
22103
22104 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
22105 use crate::dialects::DialectType;
22106
22107 if matches!(
22109 self.config.dialect,
22110 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22111 ) && name == "JSON_EXTRACT_PATH"
22112 {
22113 self.generate_expression(&f.this)?;
22114 self.write(" #> ");
22115 if f.paths.len() == 1 {
22116 self.generate_expression(&f.paths[0])?;
22117 } else {
22118 self.write_keyword("ARRAY");
22120 self.write("[");
22121 for (i, path) in f.paths.iter().enumerate() {
22122 if i > 0 {
22123 self.write(", ");
22124 }
22125 self.generate_expression(path)?;
22126 }
22127 self.write("]");
22128 }
22129 return Ok(());
22130 }
22131
22132 self.write_keyword(name);
22133 self.write("(");
22134 self.generate_expression(&f.this)?;
22135 for path in &f.paths {
22136 self.write(", ");
22137 self.generate_expression(path)?;
22138 }
22139 self.write(")");
22140 Ok(())
22141 }
22142
22143 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
22144 use crate::dialects::DialectType;
22145
22146 self.write_keyword("JSON_OBJECT");
22147 self.write("(");
22148 if f.star {
22149 self.write("*");
22150 } else {
22151 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
22155 || matches!(
22156 self.config.dialect,
22157 Some(DialectType::BigQuery)
22158 | Some(DialectType::MySQL)
22159 | Some(DialectType::SQLite)
22160 );
22161
22162 for (i, (key, value)) in f.pairs.iter().enumerate() {
22163 if i > 0 {
22164 self.write(", ");
22165 }
22166 self.generate_expression(key)?;
22167 if use_comma_syntax {
22168 self.write(", ");
22169 } else {
22170 self.write(": ");
22171 }
22172 self.generate_expression(value)?;
22173 }
22174 }
22175 if let Some(null_handling) = f.null_handling {
22176 self.write_space();
22177 match null_handling {
22178 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
22179 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
22180 }
22181 }
22182 if f.with_unique_keys {
22183 self.write_space();
22184 self.write_keyword("WITH UNIQUE KEYS");
22185 }
22186 if let Some(ref ret_type) = f.returning_type {
22187 self.write_space();
22188 self.write_keyword("RETURNING");
22189 self.write_space();
22190 self.generate_data_type(ret_type)?;
22191 if f.format_json {
22192 self.write_space();
22193 self.write_keyword("FORMAT JSON");
22194 }
22195 if let Some(ref enc) = f.encoding {
22196 self.write_space();
22197 self.write_keyword("ENCODING");
22198 self.write_space();
22199 self.write(enc);
22200 }
22201 }
22202 self.write(")");
22203 Ok(())
22204 }
22205
22206 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
22207 self.write_keyword(name);
22208 self.write("(");
22209 self.generate_expression(&f.this)?;
22210 for (path, value) in &f.path_values {
22211 self.write(", ");
22212 self.generate_expression(path)?;
22213 self.write(", ");
22214 self.generate_expression(value)?;
22215 }
22216 self.write(")");
22217 Ok(())
22218 }
22219
22220 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
22221 self.write_keyword("JSON_ARRAYAGG");
22222 self.write("(");
22223 self.generate_expression(&f.this)?;
22224 if let Some(ref order_by) = f.order_by {
22225 self.write_space();
22226 self.write_keyword("ORDER BY");
22227 self.write_space();
22228 for (i, ord) in order_by.iter().enumerate() {
22229 if i > 0 {
22230 self.write(", ");
22231 }
22232 self.generate_ordered(ord)?;
22233 }
22234 }
22235 if let Some(null_handling) = f.null_handling {
22236 self.write_space();
22237 match null_handling {
22238 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
22239 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
22240 }
22241 }
22242 self.write(")");
22243 if let Some(ref filter) = f.filter {
22244 self.write_space();
22245 self.write_keyword("FILTER");
22246 self.write("(");
22247 self.write_keyword("WHERE");
22248 self.write_space();
22249 self.generate_expression(filter)?;
22250 self.write(")");
22251 }
22252 Ok(())
22253 }
22254
22255 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
22256 self.write_keyword("JSON_OBJECTAGG");
22257 self.write("(");
22258 self.generate_expression(&f.key)?;
22259 self.write(": ");
22260 self.generate_expression(&f.value)?;
22261 if let Some(null_handling) = f.null_handling {
22262 self.write_space();
22263 match null_handling {
22264 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
22265 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
22266 }
22267 }
22268 self.write(")");
22269 if let Some(ref filter) = f.filter {
22270 self.write_space();
22271 self.write_keyword("FILTER");
22272 self.write("(");
22273 self.write_keyword("WHERE");
22274 self.write_space();
22275 self.generate_expression(filter)?;
22276 self.write(")");
22277 }
22278 Ok(())
22279 }
22280
22281 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
22284 use crate::dialects::DialectType;
22285
22286 if self.config.dialect == Some(DialectType::Redshift) {
22288 self.write_keyword("CAST");
22289 self.write("(");
22290 self.generate_expression(&f.this)?;
22291 self.write_space();
22292 self.write_keyword("AS");
22293 self.write_space();
22294 self.generate_data_type(&f.to)?;
22295 self.write(")");
22296 return Ok(());
22297 }
22298
22299 self.write_keyword("CONVERT");
22300 self.write("(");
22301 self.generate_data_type(&f.to)?;
22302 self.write(", ");
22303 self.generate_expression(&f.this)?;
22304 if let Some(ref style) = f.style {
22305 self.write(", ");
22306 self.generate_expression(style)?;
22307 }
22308 self.write(")");
22309 Ok(())
22310 }
22311
22312 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
22315 if f.colon {
22316 self.write_keyword("LAMBDA");
22318 self.write_space();
22319 for (i, param) in f.parameters.iter().enumerate() {
22320 if i > 0 {
22321 self.write(", ");
22322 }
22323 self.generate_identifier(param)?;
22324 }
22325 self.write(" : ");
22326 } else {
22327 if f.parameters.len() == 1 {
22329 self.generate_identifier(&f.parameters[0])?;
22330 } else {
22331 self.write("(");
22332 for (i, param) in f.parameters.iter().enumerate() {
22333 if i > 0 {
22334 self.write(", ");
22335 }
22336 self.generate_identifier(param)?;
22337 }
22338 self.write(")");
22339 }
22340 self.write(" -> ");
22341 }
22342 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22343 if let Expression::Lambda(inner) = &f.body {
22344 self.generate_lambda_with_parenthesized_single_param(inner)?;
22345 return Ok(());
22346 }
22347 }
22348
22349 self.generate_expression(&f.body)
22350 }
22351
22352 fn generate_lambda_with_parenthesized_single_param(&mut self, f: &LambdaExpr) -> Result<()> {
22353 if f.colon {
22354 return self.generate_lambda(f);
22355 }
22356
22357 self.write("(");
22358 for (i, param) in f.parameters.iter().enumerate() {
22359 if i > 0 {
22360 self.write(", ");
22361 }
22362 self.generate_identifier(param)?;
22363 }
22364 self.write(") -> ");
22365 self.generate_expression(&f.body)
22366 }
22367
22368 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
22369 self.generate_identifier(&f.name)?;
22370 match f.separator {
22371 NamedArgSeparator::DArrow => self.write(" => "),
22372 NamedArgSeparator::ColonEq => self.write(" := "),
22373 NamedArgSeparator::Eq => self.write(" = "),
22374 }
22375 self.generate_expression(&f.value)
22376 }
22377
22378 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
22379 self.write_keyword(&f.prefix);
22380 self.write(" ");
22381 self.generate_expression(&f.this)
22382 }
22383
22384 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
22385 match f.style {
22386 ParameterStyle::Question => self.write("?"),
22387 ParameterStyle::Dollar => {
22388 if let Some(idx) = f.index {
22389 if matches!(
22390 self.config.dialect,
22391 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22392 ) {
22393 self.write("@P");
22394 self.write(&idx.to_string());
22395 } else {
22396 self.write("$");
22397 self.write(&idx.to_string());
22398 }
22399 } else {
22400 self.write("$");
22401 if let Some(ref name) = f.name {
22402 self.write(name);
22404 }
22405 }
22406 }
22407 ParameterStyle::DollarBrace => {
22408 self.write("${");
22410 if let Some(ref name) = f.name {
22411 self.write(name);
22412 }
22413 if let Some(ref expr) = f.expression {
22414 self.write(":");
22415 self.write(expr);
22416 }
22417 self.write("}");
22418 }
22419 ParameterStyle::Colon => {
22420 self.write(":");
22421 if let Some(idx) = f.index {
22422 self.write(&idx.to_string());
22423 } else if let Some(ref name) = f.name {
22424 self.write(name);
22425 }
22426 }
22427 ParameterStyle::At => {
22428 self.write("@");
22429 if let Some(ref name) = f.name {
22430 if f.string_quoted {
22431 self.write("'");
22432 self.write(name);
22433 self.write("'");
22434 } else if f.quoted {
22435 self.write("\"");
22436 self.write(name);
22437 self.write("\"");
22438 } else {
22439 self.write(name);
22440 }
22441 }
22442 }
22443 ParameterStyle::DoubleAt => {
22444 self.write("@@");
22445 if let Some(ref name) = f.name {
22446 self.write(name);
22447 }
22448 }
22449 ParameterStyle::DoubleDollar => {
22450 self.write("$$");
22451 if let Some(ref name) = f.name {
22452 self.write(name);
22453 }
22454 }
22455 ParameterStyle::Percent => {
22456 if let Some(ref name) = f.name {
22457 self.write("%(");
22459 self.write(name);
22460 self.write(")s");
22461 } else {
22462 self.write("%s");
22464 }
22465 }
22466 ParameterStyle::Brace => {
22467 self.write("{");
22470 if let Some(ref name) = f.name {
22471 self.write(name);
22472 }
22473 if let Some(ref expr) = f.expression {
22474 self.write(": ");
22475 self.write(expr);
22476 }
22477 self.write("}");
22478 }
22479 }
22480 Ok(())
22481 }
22482
22483 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
22484 self.write("?");
22485 if let Some(idx) = f.index {
22486 self.write(&idx.to_string());
22487 }
22488 Ok(())
22489 }
22490
22491 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
22492 if f.is_block {
22493 self.write("/*");
22494 self.write(&f.text);
22495 self.write("*/");
22496 } else {
22497 self.write("--");
22498 self.write(&f.text);
22499 }
22500 Ok(())
22501 }
22502
22503 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
22506 self.generate_expression(&f.this)?;
22507 if f.not {
22508 self.write_space();
22509 self.write_keyword("NOT");
22510 }
22511 self.write_space();
22512 self.write_keyword("SIMILAR TO");
22513 self.write_space();
22514 self.generate_expression(&f.pattern)?;
22515 if let Some(ref escape) = f.escape {
22516 self.write_space();
22517 self.write_keyword("ESCAPE");
22518 self.write_space();
22519 self.generate_expression(escape)?;
22520 }
22521 Ok(())
22522 }
22523
22524 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
22525 self.generate_expression(&f.this)?;
22526 self.write_space();
22527 if let Some(op) = &f.op {
22529 match op {
22530 QuantifiedOp::Eq => self.write("="),
22531 QuantifiedOp::Neq => self.write("<>"),
22532 QuantifiedOp::Lt => self.write("<"),
22533 QuantifiedOp::Lte => self.write("<="),
22534 QuantifiedOp::Gt => self.write(">"),
22535 QuantifiedOp::Gte => self.write(">="),
22536 }
22537 self.write_space();
22538 }
22539 self.write_keyword(name);
22540
22541 if matches!(&f.subquery, Expression::Subquery(_)) {
22543 self.write_space();
22544 self.generate_expression(&f.subquery)?;
22545 } else {
22546 let is_statement = matches!(
22547 &f.subquery,
22548 Expression::Select(_)
22549 | Expression::Union(_)
22550 | Expression::Intersect(_)
22551 | Expression::Except(_)
22552 );
22553 if is_statement
22554 && !self.config.quantified_no_paren_space
22555 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
22556 {
22557 self.write_space();
22558 }
22559 self.write("(");
22560
22561 if self.config.pretty && is_statement {
22562 self.write_newline();
22563 self.indent_level += 1;
22564 self.write_indent();
22565 }
22566 self.generate_expression(&f.subquery)?;
22567 if self.config.pretty && is_statement {
22568 self.write_newline();
22569 self.indent_level -= 1;
22570 self.write_indent();
22571 }
22572 self.write(")");
22573 }
22574 Ok(())
22575 }
22576
22577 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
22578 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
22580 self.generate_expression(this)?;
22581 self.write_space();
22582 self.write_keyword("OVERLAPS");
22583 self.write_space();
22584 self.generate_expression(expr)?;
22585 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
22586 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
22587 {
22588 self.write("(");
22590 self.generate_expression(ls)?;
22591 self.write(", ");
22592 self.generate_expression(le)?;
22593 self.write(")");
22594 self.write_space();
22595 self.write_keyword("OVERLAPS");
22596 self.write_space();
22597 self.write("(");
22598 self.generate_expression(rs)?;
22599 self.write(", ");
22600 self.generate_expression(re)?;
22601 self.write(")");
22602 }
22603 Ok(())
22604 }
22605
22606 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
22609 use crate::dialects::DialectType;
22610
22611 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
22613 self.generate_expression(&cast.this)?;
22614 self.write(" !:> ");
22615 self.generate_data_type(&cast.to)?;
22616 return Ok(());
22617 }
22618
22619 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
22621 self.write_keyword("TRYCAST");
22622 self.write("(");
22623 self.generate_expression(&cast.this)?;
22624 self.write_space();
22625 self.write_keyword("AS");
22626 self.write_space();
22627 self.generate_data_type(&cast.to)?;
22628 self.write(")");
22629 return Ok(());
22630 }
22631
22632 let keyword = if matches!(
22634 self.config.dialect,
22635 Some(DialectType::Hive)
22636 | Some(DialectType::MySQL)
22637 | Some(DialectType::SQLite)
22638 | Some(DialectType::Oracle)
22639 | Some(DialectType::ClickHouse)
22640 | Some(DialectType::Redshift)
22641 | Some(DialectType::PostgreSQL)
22642 | Some(DialectType::StarRocks)
22643 | Some(DialectType::Doris)
22644 ) {
22645 "CAST"
22646 } else {
22647 "TRY_CAST"
22648 };
22649
22650 self.write_keyword(keyword);
22651 self.write("(");
22652 self.generate_expression(&cast.this)?;
22653 self.write_space();
22654 self.write_keyword("AS");
22655 self.write_space();
22656 self.generate_data_type(&cast.to)?;
22657
22658 if let Some(format) = &cast.format {
22660 self.write_space();
22661 self.write_keyword("FORMAT");
22662 self.write_space();
22663 self.generate_expression(format)?;
22664 }
22665
22666 self.write(")");
22667 Ok(())
22668 }
22669
22670 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
22671 self.write_keyword("SAFE_CAST");
22672 self.write("(");
22673 self.generate_expression(&cast.this)?;
22674 self.write_space();
22675 self.write_keyword("AS");
22676 self.write_space();
22677 self.generate_data_type(&cast.to)?;
22678
22679 if let Some(format) = &cast.format {
22681 self.write_space();
22682 self.write_keyword("FORMAT");
22683 self.write_space();
22684 self.generate_expression(format)?;
22685 }
22686
22687 self.write(")");
22688 Ok(())
22689 }
22690
22691 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
22694 let needs_parens = matches!(&s.this, Expression::JsonExtract(ref f) if f.arrow_syntax);
22698 if needs_parens {
22699 self.write("(");
22700 }
22701 self.generate_expression(&s.this)?;
22702 if needs_parens {
22703 self.write(")");
22704 }
22705 self.write("[");
22706 self.generate_expression(&s.index)?;
22707 self.write("]");
22708 Ok(())
22709 }
22710
22711 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
22712 self.generate_expression(&d.this)?;
22713 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
22716 && matches!(
22717 &d.this,
22718 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
22719 );
22720 if use_colon {
22721 self.write(":");
22722 } else {
22723 self.write(".");
22724 }
22725 self.generate_identifier(&d.field)
22726 }
22727
22728 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
22729 self.generate_expression(&m.this)?;
22730 self.write(".");
22731 if m.method.quoted {
22734 let q = self.config.identifier_quote;
22735 self.write(&format!("{}{}{}", q, m.method.name, q));
22736 } else {
22737 self.write(&m.method.name);
22738 }
22739 self.write("(");
22740 for (i, arg) in m.args.iter().enumerate() {
22741 if i > 0 {
22742 self.write(", ");
22743 }
22744 self.generate_expression(arg)?;
22745 }
22746 self.write(")");
22747 Ok(())
22748 }
22749
22750 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
22751 let needs_parens = matches!(
22754 &s.this,
22755 Expression::JsonExtract(f) if f.arrow_syntax
22756 ) || matches!(
22757 &s.this,
22758 Expression::JsonExtractScalar(f) if f.arrow_syntax
22759 );
22760
22761 if needs_parens {
22762 self.write("(");
22763 }
22764 self.generate_expression(&s.this)?;
22765 if needs_parens {
22766 self.write(")");
22767 }
22768 self.write("[");
22769 if let Some(start) = &s.start {
22770 self.generate_expression(start)?;
22771 }
22772 self.write(":");
22773 if let Some(end) = &s.end {
22774 self.generate_expression(end)?;
22775 }
22776 self.write("]");
22777 Ok(())
22778 }
22779
22780 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
22781 match &op.left {
22785 Expression::Column(col) => {
22786 if let Some(table) = &col.table {
22789 self.generate_identifier(table)?;
22790 self.write(".");
22791 }
22792 self.generate_identifier(&col.name)?;
22793 if col.join_mark && self.config.supports_column_join_marks {
22795 self.write(" (+)");
22796 }
22797 if op.left_comments.is_empty() {
22799 for comment in &col.trailing_comments {
22800 self.write_space();
22801 self.write_formatted_comment(comment);
22802 }
22803 }
22804 }
22805 Expression::Add(inner_op)
22806 | Expression::Sub(inner_op)
22807 | Expression::Mul(inner_op)
22808 | Expression::Div(inner_op)
22809 | Expression::Concat(inner_op) => {
22810 self.generate_binary_op_no_trailing(inner_op, match &op.left {
22812 Expression::Add(_) => "+",
22813 Expression::Sub(_) => "-",
22814 Expression::Mul(_) => "*",
22815 Expression::Div(_) => "/",
22816 Expression::Concat(_) => "||",
22817 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
22818 })?;
22819 }
22820 _ => {
22821 self.generate_expression(&op.left)?;
22822 }
22823 }
22824 for comment in &op.left_comments {
22826 self.write_space();
22827 self.write_formatted_comment(comment);
22828 }
22829 if self.config.pretty
22830 && matches!(self.config.dialect, Some(DialectType::Snowflake))
22831 && (operator == "AND" || operator == "OR")
22832 {
22833 self.write_newline();
22834 self.write_indent();
22835 self.write_keyword(operator);
22836 } else {
22837 self.write_space();
22838 if operator.chars().all(|c| c.is_alphabetic()) {
22839 self.write_keyword(operator);
22840 } else {
22841 self.write(operator);
22842 }
22843 }
22844 for comment in &op.operator_comments {
22846 self.write_space();
22847 self.write_formatted_comment(comment);
22848 }
22849 self.write_space();
22850 self.generate_expression(&op.right)?;
22851 for comment in &op.trailing_comments {
22853 self.write_space();
22854 self.write_formatted_comment(comment);
22855 }
22856 Ok(())
22857 }
22858
22859 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
22860 let keyword = connector.keyword();
22861 let Some(terms) = self.flatten_connector_terms(op, connector) else {
22862 return self.generate_binary_op(op, keyword);
22863 };
22864
22865 let wrap_clickhouse_or_term = |generator: &mut Self, term: &Expression| -> Result<()> {
22866 let should_wrap = matches!(connector, ConnectorOperator::Or)
22867 && matches!(generator.config.dialect, Some(DialectType::ClickHouse))
22868 && matches!(
22869 generator.config.source_dialect,
22870 Some(DialectType::ClickHouse)
22871 )
22872 && matches!(term, Expression::And(_));
22873 if should_wrap {
22874 generator.write("(");
22875 generator.generate_expression(term)?;
22876 generator.write(")");
22877 } else {
22878 generator.generate_expression(term)?;
22879 }
22880 Ok(())
22881 };
22882
22883 wrap_clickhouse_or_term(self, terms[0])?;
22884 for term in terms.iter().skip(1) {
22885 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
22886 self.write_newline();
22887 self.write_indent();
22888 self.write_keyword(keyword);
22889 } else {
22890 self.write_space();
22891 self.write_keyword(keyword);
22892 }
22893 self.write_space();
22894 wrap_clickhouse_or_term(self, term)?;
22895 }
22896
22897 Ok(())
22898 }
22899
22900 fn flatten_connector_terms<'a>(
22901 &self,
22902 root: &'a BinaryOp,
22903 connector: ConnectorOperator,
22904 ) -> Option<Vec<&'a Expression>> {
22905 if !root.left_comments.is_empty()
22906 || !root.operator_comments.is_empty()
22907 || !root.trailing_comments.is_empty()
22908 {
22909 return None;
22910 }
22911
22912 let mut terms = Vec::new();
22913 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
22914
22915 while let Some(expr) = stack.pop() {
22916 match (connector, expr) {
22917 (ConnectorOperator::And, Expression::And(inner))
22918 if inner.left_comments.is_empty()
22919 && inner.operator_comments.is_empty()
22920 && inner.trailing_comments.is_empty() =>
22921 {
22922 stack.push(&inner.right);
22923 stack.push(&inner.left);
22924 }
22925 (ConnectorOperator::Or, Expression::Or(inner))
22926 if inner.left_comments.is_empty()
22927 && inner.operator_comments.is_empty()
22928 && inner.trailing_comments.is_empty() =>
22929 {
22930 stack.push(&inner.right);
22931 stack.push(&inner.left);
22932 }
22933 _ => terms.push(expr),
22934 }
22935 }
22936
22937 if terms.len() > 1 {
22938 Some(terms)
22939 } else {
22940 None
22941 }
22942 }
22943
22944 fn missing_closing_parens_outside_quotes(sql: &str) -> usize {
22945 let mut depth = 0usize;
22946 let mut quote: Option<char> = None;
22947 let mut chars = sql.chars().peekable();
22948
22949 while let Some(ch) = chars.next() {
22950 if let Some(quote_char) = quote {
22951 if ch == '\\' {
22952 chars.next();
22953 } else if ch == quote_char {
22954 if quote_char == '\'' && chars.peek() == Some(&'\'') {
22955 chars.next();
22956 } else {
22957 quote = None;
22958 }
22959 }
22960 continue;
22961 }
22962
22963 match ch {
22964 '\'' | '"' | '`' => quote = Some(ch),
22965 '(' => depth += 1,
22966 ')' => depth = depth.saturating_sub(1),
22967 _ => {}
22968 }
22969 }
22970
22971 depth
22972 }
22973
22974 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
22976 self.generate_like_op_inner(op, operator, false)
22977 }
22978
22979 fn generate_like_op_negated(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
22980 self.generate_like_op_inner(op, operator, true)
22981 }
22982
22983 fn generate_like_op_inner(&mut self, op: &LikeOp, operator: &str, negated: bool) -> Result<()> {
22984 if negated
22985 && matches!(
22986 self.config.dialect,
22987 Some(DialectType::ClickHouse)
22988 | Some(DialectType::DataFusion)
22989 | Some(DialectType::TSQL)
22990 | Some(DialectType::Fabric)
22991 )
22992 {
22993 self.write_keyword("NOT");
22994 self.write_space();
22995 return self.generate_like_op_inner(op, operator, false);
22996 }
22997
22998 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22999 if let Expression::Star(star) = &op.left {
23000 if star
23001 .except
23002 .as_ref()
23003 .is_some_and(|except| !except.is_empty())
23004 {
23005 if let Some(table) = &star.table {
23006 self.generate_identifier(table)?;
23007 self.write(".");
23008 }
23009 self.write("*");
23010 self.write_space();
23011 self.write_keyword(operator);
23012 if let Some(quantifier) = &op.quantifier {
23013 self.write_space();
23014 self.write_keyword(quantifier);
23015 self.write_space();
23016 } else {
23017 self.write_space();
23018 }
23019 self.generate_expression(&op.right)?;
23020 if let Some(escape) = &op.escape {
23021 self.write_space();
23022 self.write_keyword("ESCAPE");
23023 self.write_space();
23024 self.generate_expression(escape)?;
23025 }
23026 if let Some(except) = &star.except {
23027 self.write_space();
23028 self.write_keyword("EXCEPT");
23029 self.write(" (");
23030 for (i, col) in except.iter().enumerate() {
23031 if i > 0 {
23032 self.write(", ");
23033 }
23034 self.generate_identifier(col)?;
23035 }
23036 self.write(")");
23037 }
23038 return Ok(());
23039 }
23040 }
23041 }
23042
23043 self.generate_expression(&op.left)?;
23044 self.write_space();
23045 if negated {
23046 self.write_keyword("NOT");
23047 self.write_space();
23048 }
23049 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
23051 self.write("`ILIKE`");
23052 } else {
23053 self.write_keyword(operator);
23054 }
23055 if let Some(quantifier) = &op.quantifier {
23056 self.write_space();
23057 self.write_keyword(quantifier);
23058 let is_any =
23063 quantifier.eq_ignore_ascii_case("ANY") || quantifier.eq_ignore_ascii_case("SOME");
23064 if !(is_any && matches!(&op.right, Expression::Paren(_))) {
23065 self.write_space();
23066 }
23067 } else {
23068 self.write_space();
23069 }
23070 self.generate_expression(&op.right)?;
23071 if let Some(escape) = &op.escape {
23072 self.write_space();
23073 self.write_keyword("ESCAPE");
23074 self.write_space();
23075 self.generate_expression(escape)?;
23076 }
23077 Ok(())
23078 }
23079
23080 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
23083 use crate::dialects::DialectType;
23084 self.generate_expression(&op.left)?;
23085 self.write_space();
23086 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
23087 self.write("<=>");
23088 } else {
23089 self.write_keyword("IS NOT DISTINCT FROM");
23090 }
23091 self.write_space();
23092 self.generate_expression(&op.right)?;
23093 Ok(())
23094 }
23095
23096 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
23098 self.generate_expression(&op.left)?;
23099 self.write_space();
23100 self.write_keyword("IS DISTINCT FROM");
23101 self.write_space();
23102 self.generate_expression(&op.right)?;
23103 Ok(())
23104 }
23105
23106 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
23108 match &op.left {
23110 Expression::Column(col) => {
23111 if let Some(table) = &col.table {
23112 self.generate_identifier(table)?;
23113 self.write(".");
23114 }
23115 self.generate_identifier(&col.name)?;
23116 if col.join_mark && self.config.supports_column_join_marks {
23118 self.write(" (+)");
23119 }
23120 }
23121 Expression::Add(inner_op)
23122 | Expression::Sub(inner_op)
23123 | Expression::Mul(inner_op)
23124 | Expression::Div(inner_op)
23125 | Expression::Concat(inner_op) => {
23126 self.generate_binary_op_no_trailing(inner_op, match &op.left {
23127 Expression::Add(_) => "+",
23128 Expression::Sub(_) => "-",
23129 Expression::Mul(_) => "*",
23130 Expression::Div(_) => "/",
23131 Expression::Concat(_) => "||",
23132 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
23133 })?;
23134 }
23135 _ => {
23136 self.generate_expression(&op.left)?;
23137 }
23138 }
23139 for comment in &op.left_comments {
23141 self.write_space();
23142 self.write_formatted_comment(comment);
23143 }
23144 self.write_space();
23145 if operator.chars().all(|c| c.is_alphabetic()) {
23146 self.write_keyword(operator);
23147 } else {
23148 self.write(operator);
23149 }
23150 for comment in &op.operator_comments {
23152 self.write_space();
23153 self.write_formatted_comment(comment);
23154 }
23155 self.write_space();
23156 match &op.right {
23159 Expression::Column(col) => {
23160 if let Some(table) = &col.table {
23161 self.generate_identifier(table)?;
23162 self.write(".");
23163 }
23164 self.generate_identifier(&col.name)?;
23165 if col.join_mark && self.config.supports_column_join_marks {
23167 self.write(" (+)");
23168 }
23169 }
23170 _ => {
23171 self.generate_expression(&op.right)?;
23172 }
23173 }
23174 Ok(())
23176 }
23177
23178 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
23179 if operator.chars().all(|c| c.is_alphabetic()) {
23180 self.write_keyword(operator);
23181 self.write_space();
23182 } else {
23183 self.write(operator);
23184 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
23186 self.write_space();
23187 }
23188 }
23189 self.generate_expression(&op.this)
23190 }
23191
23192 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
23193 let is_generic =
23197 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
23198 let use_prefix_not =
23199 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
23200 if use_prefix_not {
23201 self.write_keyword("NOT");
23202 self.write_space();
23203 }
23204 self.generate_expression(&in_expr.this)?;
23205 if in_expr.global {
23206 self.write_space();
23207 self.write_keyword("GLOBAL");
23208 }
23209 if in_expr.not && !use_prefix_not {
23210 self.write_space();
23211 self.write_keyword("NOT");
23212 }
23213 self.write_space();
23214 self.write_keyword("IN");
23215
23216 if let Some(unnest_expr) = &in_expr.unnest {
23218 self.write_space();
23219 self.write_keyword("UNNEST");
23220 self.write("(");
23221 self.generate_expression(unnest_expr)?;
23222 self.write(")");
23223 return Ok(());
23224 }
23225
23226 if let Some(query) = &in_expr.query {
23227 let is_bare = in_expr.expressions.is_empty()
23230 && !matches!(
23231 query,
23232 Expression::Select(_)
23233 | Expression::Union(_)
23234 | Expression::Intersect(_)
23235 | Expression::Except(_)
23236 | Expression::Subquery(_)
23237 );
23238 if is_bare {
23239 self.write_space();
23241 self.generate_expression(query)?;
23242 } else {
23243 self.write(" (");
23245 let is_statement = matches!(
23246 query,
23247 Expression::Select(_)
23248 | Expression::Union(_)
23249 | Expression::Intersect(_)
23250 | Expression::Except(_)
23251 | Expression::Subquery(_)
23252 );
23253 if self.config.pretty && is_statement {
23254 self.write_newline();
23255 self.indent_level += 1;
23256 self.write_indent();
23257 }
23258 self.generate_expression(query)?;
23259 if self.config.pretty && is_statement {
23260 self.write_newline();
23261 self.indent_level -= 1;
23262 self.write_indent();
23263 }
23264 self.write(")");
23265 }
23266 } else {
23267 let is_duckdb = matches!(
23271 self.config.dialect,
23272 Some(crate::dialects::DialectType::DuckDB)
23273 );
23274 let is_clickhouse = matches!(
23275 self.config.dialect,
23276 Some(crate::dialects::DialectType::ClickHouse)
23277 );
23278 let single_expr = in_expr.expressions.len() == 1;
23279 if is_clickhouse && single_expr {
23280 if let Expression::Array(arr) = &in_expr.expressions[0] {
23281 self.write(" (");
23283 for (i, expr) in arr.expressions.iter().enumerate() {
23284 if i > 0 {
23285 self.write(", ");
23286 }
23287 self.generate_expression(expr)?;
23288 }
23289 self.write(")");
23290 } else if in_expr.is_field {
23291 self.write_space();
23292 self.generate_expression(&in_expr.expressions[0])?;
23293 } else {
23294 self.write(" (");
23295 self.generate_expression(&in_expr.expressions[0])?;
23296 self.write(")");
23297 }
23298 } else {
23299 let is_bare_ref = single_expr
23300 && matches!(
23301 &in_expr.expressions[0],
23302 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
23303 );
23304 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
23305 self.write_space();
23308 self.generate_expression(&in_expr.expressions[0])?;
23309 } else {
23310 self.write(" (");
23312 for (i, expr) in in_expr.expressions.iter().enumerate() {
23313 if i > 0 {
23314 self.write(", ");
23315 }
23316 self.generate_expression(expr)?;
23317 }
23318 self.write(")");
23319 }
23320 }
23321 }
23322
23323 Ok(())
23324 }
23325
23326 fn generate_between(&mut self, between: &Between) -> Result<()> {
23327 let use_prefix_not = between.not
23329 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
23330 if use_prefix_not {
23331 self.write_keyword("NOT");
23332 self.write_space();
23333 }
23334 self.generate_expression(&between.this)?;
23335 if between.not && !use_prefix_not {
23336 self.write_space();
23337 self.write_keyword("NOT");
23338 }
23339 self.write_space();
23340 self.write_keyword("BETWEEN");
23341 if let Some(sym) = between.symmetric {
23343 if sym {
23344 self.write(" SYMMETRIC");
23345 } else {
23346 self.write(" ASYMMETRIC");
23347 }
23348 }
23349 self.write_space();
23350 self.generate_expression(&between.low)?;
23351 self.write_space();
23352 self.write_keyword("AND");
23353 self.write_space();
23354 self.generate_expression(&between.high)
23355 }
23356
23357 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
23358 let use_prefix_not = is_null.not
23360 && (self.config.dialect.is_none()
23361 || self.config.dialect == Some(DialectType::Generic)
23362 || is_null.postfix_form);
23363 if use_prefix_not {
23364 self.write_keyword("NOT");
23366 self.write_space();
23367 self.generate_expression(&is_null.this)?;
23368 self.write_space();
23369 self.write_keyword("IS");
23370 self.write_space();
23371 self.write_keyword("NULL");
23372 } else {
23373 self.generate_expression(&is_null.this)?;
23374 self.write_space();
23375 self.write_keyword("IS");
23376 if is_null.not {
23377 self.write_space();
23378 self.write_keyword("NOT");
23379 }
23380 self.write_space();
23381 self.write_keyword("NULL");
23382 }
23383 Ok(())
23384 }
23385
23386 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
23387 self.generate_expression(&is_true.this)?;
23388 self.write_space();
23389 self.write_keyword("IS");
23390 if is_true.not {
23391 self.write_space();
23392 self.write_keyword("NOT");
23393 }
23394 self.write_space();
23395 self.write_keyword("TRUE");
23396 Ok(())
23397 }
23398
23399 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
23400 self.generate_expression(&is_false.this)?;
23401 self.write_space();
23402 self.write_keyword("IS");
23403 if is_false.not {
23404 self.write_space();
23405 self.write_keyword("NOT");
23406 }
23407 self.write_space();
23408 self.write_keyword("FALSE");
23409 Ok(())
23410 }
23411
23412 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
23413 self.generate_expression(&is_json.this)?;
23414 self.write_space();
23415 self.write_keyword("IS");
23416 if is_json.negated {
23417 self.write_space();
23418 self.write_keyword("NOT");
23419 }
23420 self.write_space();
23421 self.write_keyword("JSON");
23422
23423 if let Some(ref json_type) = is_json.json_type {
23425 self.write_space();
23426 self.write_keyword(json_type);
23427 }
23428
23429 match &is_json.unique_keys {
23431 Some(JsonUniqueKeys::With) => {
23432 self.write_space();
23433 self.write_keyword("WITH UNIQUE KEYS");
23434 }
23435 Some(JsonUniqueKeys::Without) => {
23436 self.write_space();
23437 self.write_keyword("WITHOUT UNIQUE KEYS");
23438 }
23439 Some(JsonUniqueKeys::Shorthand) => {
23440 self.write_space();
23441 self.write_keyword("UNIQUE KEYS");
23442 }
23443 None => {}
23444 }
23445
23446 Ok(())
23447 }
23448
23449 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
23450 self.generate_expression(&is_expr.left)?;
23451 self.write_space();
23452 self.write_keyword("IS");
23453 self.write_space();
23454 self.generate_expression(&is_expr.right)
23455 }
23456
23457 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
23458 if exists.not {
23459 self.write_keyword("NOT");
23460 self.write_space();
23461 }
23462 self.write_keyword("EXISTS");
23463 self.write("(");
23464 let is_statement = matches!(
23465 &exists.this,
23466 Expression::Select(_)
23467 | Expression::Union(_)
23468 | Expression::Intersect(_)
23469 | Expression::Except(_)
23470 );
23471 if self.config.pretty && is_statement {
23472 self.write_newline();
23473 self.indent_level += 1;
23474 self.write_indent();
23475 self.generate_expression(&exists.this)?;
23476 self.write_newline();
23477 self.indent_level -= 1;
23478 self.write_indent();
23479 self.write(")");
23480 } else {
23481 self.generate_expression(&exists.this)?;
23482 self.write(")");
23483 }
23484 Ok(())
23485 }
23486
23487 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
23488 self.generate_expression(&op.left)?;
23489 self.write_space();
23490 self.write_keyword("MEMBER OF");
23491 self.write("(");
23492 self.generate_expression(&op.right)?;
23493 self.write(")");
23494 Ok(())
23495 }
23496
23497 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
23498 if subquery.lateral {
23499 self.write_keyword("LATERAL");
23500 self.write_space();
23501 }
23502
23503 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
23507 matches!(
23508 &p.this,
23509 Expression::Select(_)
23510 | Expression::Union(_)
23511 | Expression::Intersect(_)
23512 | Expression::Except(_)
23513 | Expression::Subquery(_)
23514 )
23515 } else {
23516 false
23517 };
23518
23519 let is_statement = matches!(
23521 &subquery.this,
23522 Expression::Select(_)
23523 | Expression::Union(_)
23524 | Expression::Intersect(_)
23525 | Expression::Except(_)
23526 | Expression::Merge(_)
23527 );
23528
23529 if !skip_outer_parens {
23530 self.write("(");
23531 if self.config.pretty && is_statement {
23532 self.write_newline();
23533 self.indent_level += 1;
23534 self.write_indent();
23535 }
23536 }
23537 self.generate_expression(&subquery.this)?;
23538
23539 if subquery.modifiers_inside {
23541 if let Some(order_by) = &subquery.order_by {
23543 self.write_space();
23544 self.write_keyword("ORDER BY");
23545 self.write_space();
23546 for (i, ord) in order_by.expressions.iter().enumerate() {
23547 if i > 0 {
23548 self.write(", ");
23549 }
23550 self.generate_ordered(ord)?;
23551 }
23552 }
23553
23554 if let Some(limit) = &subquery.limit {
23555 self.write_space();
23556 self.write_keyword("LIMIT");
23557 self.write_space();
23558 self.generate_expression(&limit.this)?;
23559 if limit.percent {
23560 self.write_space();
23561 self.write_keyword("PERCENT");
23562 }
23563 }
23564
23565 if let Some(offset) = &subquery.offset {
23566 self.write_space();
23567 self.write_keyword("OFFSET");
23568 self.write_space();
23569 self.generate_expression(&offset.this)?;
23570 }
23571 }
23572
23573 if !skip_outer_parens {
23574 if self.config.pretty && is_statement {
23575 self.write_newline();
23576 self.indent_level -= 1;
23577 self.write_indent();
23578 }
23579 self.write(")");
23580 }
23581
23582 if !subquery.modifiers_inside {
23584 if let Some(order_by) = &subquery.order_by {
23585 self.write_space();
23586 self.write_keyword("ORDER BY");
23587 self.write_space();
23588 for (i, ord) in order_by.expressions.iter().enumerate() {
23589 if i > 0 {
23590 self.write(", ");
23591 }
23592 self.generate_ordered(ord)?;
23593 }
23594 }
23595
23596 if let Some(limit) = &subquery.limit {
23597 self.write_space();
23598 self.write_keyword("LIMIT");
23599 self.write_space();
23600 self.generate_expression(&limit.this)?;
23601 if limit.percent {
23602 self.write_space();
23603 self.write_keyword("PERCENT");
23604 }
23605 }
23606
23607 if let Some(offset) = &subquery.offset {
23608 self.write_space();
23609 self.write_keyword("OFFSET");
23610 self.write_space();
23611 self.generate_expression(&offset.this)?;
23612 }
23613
23614 if let Some(distribute_by) = &subquery.distribute_by {
23616 self.write_space();
23617 self.write_keyword("DISTRIBUTE BY");
23618 self.write_space();
23619 for (i, expr) in distribute_by.expressions.iter().enumerate() {
23620 if i > 0 {
23621 self.write(", ");
23622 }
23623 self.generate_expression(expr)?;
23624 }
23625 }
23626
23627 if let Some(sort_by) = &subquery.sort_by {
23629 self.write_space();
23630 self.write_keyword("SORT BY");
23631 self.write_space();
23632 for (i, ord) in sort_by.expressions.iter().enumerate() {
23633 if i > 0 {
23634 self.write(", ");
23635 }
23636 self.generate_ordered(ord)?;
23637 }
23638 }
23639
23640 if let Some(cluster_by) = &subquery.cluster_by {
23642 self.write_space();
23643 self.write_keyword("CLUSTER BY");
23644 self.write_space();
23645 for (i, ord) in cluster_by.expressions.iter().enumerate() {
23646 if i > 0 {
23647 self.write(", ");
23648 }
23649 self.generate_ordered(ord)?;
23650 }
23651 }
23652 }
23653
23654 if let Some(alias) = &subquery.alias {
23655 self.write_space();
23656 let skip_as = matches!(self.config.dialect, Some(DialectType::Oracle))
23657 || (matches!(self.config.dialect, Some(DialectType::ClickHouse))
23658 && !subquery.alias_explicit_as);
23659 if !skip_as {
23660 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23661 self.write(subquery.alias_keyword.as_deref().unwrap_or("AS"));
23662 } else {
23663 self.write_keyword("AS");
23664 }
23665 self.write_space();
23666 }
23667 self.generate_identifier(alias)?;
23668 if !subquery.column_aliases.is_empty() {
23669 self.write("(");
23670 for (i, col) in subquery.column_aliases.iter().enumerate() {
23671 if i > 0 {
23672 self.write(", ");
23673 }
23674 self.generate_identifier(col)?;
23675 }
23676 self.write(")");
23677 }
23678 }
23679 for comment in &subquery.trailing_comments {
23681 self.write(" ");
23682 self.write_formatted_comment(comment);
23683 }
23684 Ok(())
23685 }
23686
23687 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
23688 if let Some(ref with) = pivot.with {
23690 self.generate_with(with)?;
23691 self.write_space();
23692 }
23693
23694 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
23695
23696 let is_redshift_unpivot = pivot.unpivot
23700 && pivot.expressions.is_empty()
23701 && pivot.fields.is_empty()
23702 && pivot.using.is_empty()
23703 && pivot.into.is_none()
23704 && !matches!(&pivot.this, Expression::Null(_));
23705
23706 if is_redshift_unpivot {
23707 self.write_keyword("UNPIVOT");
23709 self.write_space();
23710 self.generate_expression(&pivot.this)?;
23711 if let Some(alias) = &pivot.alias {
23713 self.write_space();
23714 self.write_keyword("AS");
23715 self.write_space();
23716 self.write(&alias.name);
23718 }
23719 return Ok(());
23720 }
23721
23722 let is_simplified = !pivot.using.is_empty()
23724 || pivot.into.is_some()
23725 || (pivot.fields.is_empty()
23726 && !pivot.expressions.is_empty()
23727 && !matches!(&pivot.this, Expression::Null(_)));
23728
23729 if is_simplified {
23730 self.write_keyword(direction);
23734 self.write_space();
23735 self.generate_expression(&pivot.this)?;
23736
23737 if !pivot.expressions.is_empty() {
23738 self.write_space();
23739 self.write_keyword("ON");
23740 self.write_space();
23741 for (i, expr) in pivot.expressions.iter().enumerate() {
23742 if i > 0 {
23743 self.write(", ");
23744 }
23745 self.generate_expression(expr)?;
23746 }
23747 }
23748
23749 if let Some(into) = &pivot.into {
23751 self.write_space();
23752 self.write_keyword("INTO");
23753 self.write_space();
23754 self.generate_expression(into)?;
23755 }
23756
23757 if !pivot.using.is_empty() {
23759 self.write_space();
23760 self.write_keyword("USING");
23761 self.write_space();
23762 for (i, expr) in pivot.using.iter().enumerate() {
23763 if i > 0 {
23764 self.write(", ");
23765 }
23766 self.generate_expression(expr)?;
23767 }
23768 }
23769
23770 if let Some(group) = &pivot.group {
23772 self.write_space();
23773 self.generate_expression(group)?;
23774 }
23775 } else {
23776 if !matches!(&pivot.this, Expression::Null(_)) {
23781 self.generate_expression(&pivot.this)?;
23782 self.write_space();
23783 }
23784 self.write_keyword(direction);
23785 self.write("(");
23786
23787 for (i, expr) in pivot.expressions.iter().enumerate() {
23789 if i > 0 {
23790 self.write(", ");
23791 }
23792 self.generate_expression(expr)?;
23793 }
23794
23795 if !pivot.fields.is_empty() {
23797 if !pivot.expressions.is_empty() {
23798 self.write_space();
23799 }
23800 self.write_keyword("FOR");
23801 self.write_space();
23802 for (i, field) in pivot.fields.iter().enumerate() {
23803 if i > 0 {
23804 self.write_space();
23805 }
23806 self.generate_expression(field)?;
23808 }
23809 }
23810
23811 if let Some(default_val) = &pivot.default_on_null {
23813 self.write_space();
23814 self.write_keyword("DEFAULT ON NULL");
23815 self.write(" (");
23816 self.generate_expression(default_val)?;
23817 self.write(")");
23818 }
23819
23820 if let Some(group) = &pivot.group {
23822 self.write_space();
23823 self.generate_expression(group)?;
23824 }
23825
23826 self.write(")");
23827 }
23828
23829 if let Some(alias) = &pivot.alias {
23831 self.write_space();
23832 self.write_keyword("AS");
23833 self.write_space();
23834 self.generate_identifier(alias)?;
23835 self.generate_alias_column_list(&pivot.alias_columns)?;
23836 }
23837
23838 Ok(())
23839 }
23840
23841 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
23842 self.generate_expression(&unpivot.this)?;
23843 self.write_space();
23844 self.write_keyword("UNPIVOT");
23845 if let Some(include) = unpivot.include_nulls {
23847 self.write_space();
23848 if include {
23849 self.write_keyword("INCLUDE NULLS");
23850 } else {
23851 self.write_keyword("EXCLUDE NULLS");
23852 }
23853 self.write_space();
23854 }
23855 self.write("(");
23856 if unpivot.value_column_parenthesized {
23857 self.write("(");
23858 }
23859 self.generate_identifier(&unpivot.value_column)?;
23860 for extra_col in &unpivot.extra_value_columns {
23862 self.write(", ");
23863 self.generate_identifier(extra_col)?;
23864 }
23865 if unpivot.value_column_parenthesized {
23866 self.write(")");
23867 }
23868 self.write_space();
23869 self.write_keyword("FOR");
23870 self.write_space();
23871 self.generate_identifier(&unpivot.name_column)?;
23872 self.write_space();
23873 self.write_keyword("IN");
23874 self.write(" (");
23875 for (i, col) in unpivot.columns.iter().enumerate() {
23876 if i > 0 {
23877 self.write(", ");
23878 }
23879 self.generate_expression(col)?;
23880 }
23881 self.write("))");
23882 if let Some(alias) = &unpivot.alias {
23883 self.write_space();
23884 self.write_keyword("AS");
23885 self.write_space();
23886 self.generate_identifier(alias)?;
23887 self.generate_alias_column_list(&unpivot.alias_columns)?;
23888 }
23889 Ok(())
23890 }
23891
23892 fn generate_alias_column_list(&mut self, columns: &[Identifier]) -> Result<()> {
23893 if columns.is_empty() {
23894 return Ok(());
23895 }
23896
23897 self.write("(");
23898 for (i, column) in columns.iter().enumerate() {
23899 if i > 0 {
23900 self.write(", ");
23901 }
23902 self.generate_identifier(column)?;
23903 }
23904 self.write(")");
23905 Ok(())
23906 }
23907
23908 fn generate_values(&mut self, values: &Values) -> Result<()> {
23909 self.write_keyword("VALUES");
23910 for (i, row) in values.expressions.iter().enumerate() {
23911 if i > 0 {
23912 self.write(",");
23913 }
23914 self.write(" (");
23915 for (j, expr) in row.expressions.iter().enumerate() {
23916 if j > 0 {
23917 self.write(", ");
23918 }
23919 self.generate_expression(expr)?;
23920 }
23921 self.write(")");
23922 }
23923 if let Some(alias) = &values.alias {
23924 self.write_space();
23925 self.write_keyword("AS");
23926 self.write_space();
23927 self.generate_identifier(alias)?;
23928 if !values.column_aliases.is_empty() {
23929 self.write("(");
23930 for (i, col) in values.column_aliases.iter().enumerate() {
23931 if i > 0 {
23932 self.write(", ");
23933 }
23934 self.generate_identifier(col)?;
23935 }
23936 self.write(")");
23937 }
23938 }
23939 Ok(())
23940 }
23941
23942 fn generate_array(&mut self, arr: &Array) -> Result<()> {
23943 let needs_inheritance = matches!(
23945 self.config.dialect,
23946 Some(DialectType::DuckDB)
23947 | Some(DialectType::Spark)
23948 | Some(DialectType::Databricks)
23949 | Some(DialectType::Hive)
23950 | Some(DialectType::Snowflake)
23951 | Some(DialectType::Presto)
23952 | Some(DialectType::Trino)
23953 );
23954 let propagated: Vec<Expression>;
23955 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
23956 propagated = Self::inherit_struct_field_names(&arr.expressions);
23957 &propagated
23958 } else {
23959 &arr.expressions
23960 };
23961
23962 let use_parens =
23965 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
23966 if !self.config.array_bracket_only {
23967 self.write_keyword("ARRAY");
23968 }
23969 if use_parens {
23970 self.write("(");
23971 } else {
23972 self.write("[");
23973 }
23974 for (i, expr) in expressions.iter().enumerate() {
23975 if i > 0 {
23976 self.write(", ");
23977 }
23978 self.generate_expression(expr)?;
23979 }
23980 if use_parens {
23981 self.write(")");
23982 } else {
23983 self.write("]");
23984 }
23985 Ok(())
23986 }
23987
23988 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
23989 if tuple.expressions.len() == 2 {
23992 if let Expression::TableAlias(_) = &tuple.expressions[1] {
23993 self.generate_expression(&tuple.expressions[0])?;
23995 self.write_space();
23996 self.write_keyword("AS");
23997 self.write_space();
23998 self.generate_expression(&tuple.expressions[1])?;
23999 return Ok(());
24000 }
24001 }
24002
24003 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
24006 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
24007 for expr in &tuple.expressions {
24008 expr_strings.push(self.generate_to_string(expr)?);
24009 }
24010 self.too_wide(&expr_strings)
24011 } else {
24012 false
24013 };
24014
24015 if expand_tuple {
24016 self.write("(");
24017 self.write_newline();
24018 self.indent_level += 1;
24019 for (i, expr) in tuple.expressions.iter().enumerate() {
24020 if i > 0 {
24021 self.write(",");
24022 self.write_newline();
24023 }
24024 self.write_indent();
24025 self.generate_expression(expr)?;
24026 }
24027 self.indent_level -= 1;
24028 self.write_newline();
24029 self.write_indent();
24030 self.write(")");
24031 } else {
24032 self.write("(");
24033 for (i, expr) in tuple.expressions.iter().enumerate() {
24034 if i > 0 {
24035 self.write(", ");
24036 }
24037 self.generate_expression(expr)?;
24038 }
24039 self.write(")");
24040 }
24041 Ok(())
24042 }
24043
24044 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
24045 self.generate_expression(&pipe.this)?;
24046 self.write(" |> ");
24047 self.generate_expression(&pipe.expression)?;
24048 Ok(())
24049 }
24050
24051 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
24052 let unsupported_tsql_null_ordering = ordered.nulls_first.is_some()
24053 && !self.config.null_ordering_supported
24054 && matches!(
24055 self.config.dialect,
24056 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24057 );
24058 let random_ordering = matches!(ordered.this, Expression::Rand(_) | Expression::Random(_));
24059 let emulate_tsql_null_ordering = if let Some(nulls_first) = ordered.nulls_first {
24060 let target_default_nulls_first = !ordered.desc;
24061
24062 unsupported_tsql_null_ordering
24063 && nulls_first != target_default_nulls_first
24064 && !random_ordering
24065 } else {
24066 false
24067 };
24068
24069 if emulate_tsql_null_ordering {
24070 if Self::is_integer_ordering_literal(&ordered.this) {
24071 let nulls_order = if ordered.nulls_first == Some(true) {
24072 "NULLS FIRST"
24073 } else {
24074 "NULLS LAST"
24075 };
24076 self.unsupported(format!(
24077 "'{nulls_order}' translation not supported with positional ordering"
24078 ))?;
24079 } else {
24080 self.write_keyword("CASE WHEN");
24081 self.write_space();
24082 self.generate_expression(&ordered.this)?;
24083 self.write_space();
24084 self.write_keyword("IS NULL THEN 1 ELSE 0 END");
24085 if ordered.nulls_first == Some(true) {
24086 self.write_space();
24087 self.write_keyword("DESC");
24088 }
24089 self.write(", ");
24090 }
24091 }
24092
24093 self.generate_expression(&ordered.this)?;
24094 if ordered.desc {
24095 self.write_space();
24096 self.write_keyword("DESC");
24097 } else if ordered.explicit_asc {
24098 self.write_space();
24099 self.write_keyword("ASC");
24100 }
24101 if let Some(nulls_first) = ordered.nulls_first {
24102 if !unsupported_tsql_null_ordering
24103 && (self.config.null_ordering_supported
24104 || !matches!(self.config.dialect, Some(DialectType::Fabric)))
24105 {
24106 let is_asc = !ordered.desc;
24120 let is_nulls_are_large = matches!(
24121 self.config.dialect,
24122 Some(DialectType::Oracle)
24123 | Some(DialectType::PostgreSQL)
24124 | Some(DialectType::Redshift)
24125 | Some(DialectType::Snowflake)
24126 );
24127 let is_nulls_are_last = matches!(
24128 self.config.dialect,
24129 Some(DialectType::Dremio)
24130 | Some(DialectType::DuckDB)
24131 | Some(DialectType::Presto)
24132 | Some(DialectType::Trino)
24133 | Some(DialectType::Athena)
24134 | Some(DialectType::ClickHouse)
24135 | Some(DialectType::Drill)
24136 | Some(DialectType::Exasol)
24137 );
24138
24139 let is_default_nulls = if is_nulls_are_large {
24141 (is_asc && !nulls_first) || (!is_asc && nulls_first)
24143 } else if is_nulls_are_last {
24144 !nulls_first
24146 } else {
24147 false
24148 };
24149
24150 if !is_default_nulls {
24151 self.write_space();
24152 self.write_keyword("NULLS");
24153 self.write_space();
24154 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
24155 }
24156 }
24157 }
24158 if let Some(ref with_fill) = ordered.with_fill {
24160 self.write_space();
24161 self.generate_with_fill(with_fill)?;
24162 }
24163 Ok(())
24164 }
24165
24166 fn is_integer_ordering_literal(expr: &Expression) -> bool {
24167 matches!(
24168 expr,
24169 Expression::Literal(lit)
24170 if matches!(lit.as_ref(), Literal::Number(n) if n.parse::<u64>().is_ok())
24171 )
24172 }
24173
24174 fn write_clickhouse_type(&mut self, type_str: &str) {
24176 if self.clickhouse_nullable_depth < 0 {
24177 self.write(type_str);
24179 } else {
24180 self.write(&format!("Nullable({})", type_str));
24181 }
24182 }
24183
24184 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
24185 use crate::dialects::DialectType;
24186
24187 match dt {
24188 DataType::Boolean => {
24189 match self.config.dialect {
24191 Some(DialectType::TSQL) => self.write_keyword("BIT"),
24192 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
24194 self.write_keyword("NUMBER(1)")
24196 }
24197 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
24199 }
24200 }
24201 DataType::TinyInt { length } => {
24202 match self.config.dialect {
24206 Some(DialectType::PostgreSQL)
24207 | Some(DialectType::Redshift)
24208 | Some(DialectType::Oracle)
24209 | Some(DialectType::Exasol) => {
24210 self.write_keyword("SMALLINT");
24211 }
24212 Some(DialectType::Teradata) => {
24213 self.write_keyword("BYTEINT");
24215 }
24216 Some(DialectType::Dremio) => {
24217 self.write_keyword("INT");
24219 }
24220 Some(DialectType::ClickHouse) => {
24221 self.write_clickhouse_type("Int8");
24222 }
24223 _ => {
24224 self.write_keyword("TINYINT");
24225 }
24226 }
24227 if let Some(n) = length {
24228 if !matches!(
24229 self.config.dialect,
24230 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
24231 ) {
24232 self.write(&format!("({})", n));
24233 }
24234 }
24235 }
24236 DataType::SmallInt { length } => {
24237 match self.config.dialect {
24239 Some(DialectType::Dremio) => {
24240 self.write_keyword("INT");
24241 }
24242 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
24243 self.write_keyword("INTEGER");
24244 }
24245 Some(DialectType::BigQuery) => {
24246 self.write_keyword("INT64");
24247 }
24248 Some(DialectType::ClickHouse) => {
24249 self.write_clickhouse_type("Int16");
24250 }
24251 _ => {
24252 self.write_keyword("SMALLINT");
24253 if let Some(n) = length {
24254 self.write(&format!("({})", n));
24255 }
24256 }
24257 }
24258 }
24259 DataType::Int {
24260 length,
24261 integer_spelling: _,
24262 } => {
24263 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
24265 self.write_keyword("INT64");
24266 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24267 self.write_clickhouse_type("Int32");
24268 } else {
24269 let use_integer = match self.config.dialect {
24271 Some(DialectType::TSQL)
24272 | Some(DialectType::Fabric)
24273 | Some(DialectType::Presto)
24274 | Some(DialectType::Trino)
24275 | Some(DialectType::SQLite)
24276 | Some(DialectType::Redshift) => true,
24277 _ => false,
24278 };
24279 if use_integer {
24280 self.write_keyword("INTEGER");
24281 } else {
24282 self.write_keyword("INT");
24283 }
24284 if let Some(n) = length {
24285 self.write(&format!("({})", n));
24286 }
24287 }
24288 }
24289 DataType::BigInt { length } => {
24290 match self.config.dialect {
24292 Some(DialectType::Oracle) => {
24293 self.write_keyword("INT");
24295 }
24296 Some(DialectType::ClickHouse) => {
24297 self.write_clickhouse_type("Int64");
24298 }
24299 _ => {
24300 self.write_keyword("BIGINT");
24301 if let Some(n) = length {
24302 self.write(&format!("({})", n));
24303 }
24304 }
24305 }
24306 }
24307 DataType::Float {
24308 precision,
24309 scale,
24310 real_spelling,
24311 } => {
24312 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24316 self.write_clickhouse_type("Float32");
24317 } else if *real_spelling
24318 && !matches!(
24319 self.config.dialect,
24320 Some(DialectType::Spark)
24321 | Some(DialectType::Databricks)
24322 | Some(DialectType::Hive)
24323 | Some(DialectType::Snowflake)
24324 | Some(DialectType::MySQL)
24325 | Some(DialectType::BigQuery)
24326 )
24327 {
24328 self.write_keyword("REAL")
24329 } else {
24330 match self.config.dialect {
24331 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
24332 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
24333 _ => self.write_keyword("FLOAT"),
24334 }
24335 }
24336 if !matches!(
24339 self.config.dialect,
24340 Some(DialectType::Spark)
24341 | Some(DialectType::Databricks)
24342 | Some(DialectType::Hive)
24343 | Some(DialectType::Presto)
24344 | Some(DialectType::Trino)
24345 ) {
24346 if let Some(p) = precision {
24347 self.write(&format!("({}", p));
24348 if let Some(s) = scale {
24349 self.write(&format!(", {})", s));
24350 } else {
24351 self.write(")");
24352 }
24353 }
24354 }
24355 }
24356 DataType::Double { precision, scale } => {
24357 match self.config.dialect {
24359 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24360 self.write_keyword("FLOAT")
24361 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
24363 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
24364 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
24365 Some(DialectType::SQLite) => self.write_keyword("REAL"),
24366 Some(DialectType::PostgreSQL)
24367 | Some(DialectType::Redshift)
24368 | Some(DialectType::Teradata)
24369 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
24370 _ => self.write_keyword("DOUBLE"),
24371 }
24372 if let Some(p) = precision {
24374 self.write(&format!("({}", p));
24375 if let Some(s) = scale {
24376 self.write(&format!(", {})", s));
24377 } else {
24378 self.write(")");
24379 }
24380 }
24381 }
24382 DataType::Decimal { precision, scale } => {
24383 match self.config.dialect {
24385 Some(DialectType::ClickHouse) => {
24386 self.write("Decimal");
24387 if let Some(p) = precision {
24388 self.write(&format!("({}", p));
24389 if let Some(s) = scale {
24390 self.write(&format!(", {}", s));
24391 }
24392 self.write(")");
24393 }
24394 }
24395 Some(DialectType::Oracle) => {
24396 self.write_keyword("NUMBER");
24398 if let Some(p) = precision {
24399 self.write(&format!("({}", p));
24400 if let Some(s) = scale {
24401 self.write(&format!(", {}", s));
24402 }
24403 self.write(")");
24404 }
24405 }
24406 Some(DialectType::BigQuery) => {
24407 self.write_keyword("NUMERIC");
24409 if let Some(p) = precision {
24410 self.write(&format!("({}", p));
24411 if let Some(s) = scale {
24412 self.write(&format!(", {}", s));
24413 }
24414 self.write(")");
24415 }
24416 }
24417 _ => {
24418 self.write_keyword("DECIMAL");
24419 if let Some(p) = precision {
24420 self.write(&format!("({}", p));
24421 if let Some(s) = scale {
24422 self.write(&format!(", {}", s));
24423 }
24424 self.write(")");
24425 }
24426 }
24427 }
24428 }
24429 DataType::Char { length } => {
24430 match self.config.dialect {
24432 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24433 self.write_keyword("TEXT");
24435 }
24436 Some(DialectType::Hive)
24437 | Some(DialectType::Spark)
24438 | Some(DialectType::Databricks) => {
24439 if length.is_some()
24442 && !matches!(self.config.dialect, Some(DialectType::Hive))
24443 {
24444 self.write_keyword("CHAR");
24445 if let Some(n) = length {
24446 self.write(&format!("({})", n));
24447 }
24448 } else {
24449 self.write_keyword("STRING");
24450 }
24451 }
24452 Some(DialectType::Dremio) => {
24453 self.write_keyword("VARCHAR");
24455 if let Some(n) = length {
24456 self.write(&format!("({})", n));
24457 }
24458 }
24459 _ => {
24460 self.write_keyword("CHAR");
24461 if let Some(n) = length {
24462 self.write(&format!("({})", n));
24463 }
24464 }
24465 }
24466 }
24467 DataType::VarChar {
24468 length,
24469 parenthesized_length,
24470 } => {
24471 match self.config.dialect {
24473 Some(DialectType::Oracle) => {
24474 self.write_keyword("VARCHAR2");
24475 if let Some(n) = length {
24476 self.write(&format!("({})", n));
24477 }
24478 }
24479 Some(DialectType::DuckDB) => {
24480 self.write_keyword("TEXT");
24482 if let Some(n) = length {
24483 self.write(&format!("({})", n));
24484 }
24485 }
24486 Some(DialectType::SQLite) => {
24487 self.write_keyword("TEXT");
24489 if let Some(n) = length {
24490 self.write(&format!("({})", n));
24491 }
24492 }
24493 Some(DialectType::MySQL) if length.is_none() => {
24494 self.write_keyword("TEXT");
24496 }
24497 Some(DialectType::Hive)
24498 | Some(DialectType::Spark)
24499 | Some(DialectType::Databricks)
24500 if length.is_none() =>
24501 {
24502 self.write_keyword("STRING");
24504 }
24505 _ => {
24506 self.write_keyword("VARCHAR");
24507 if let Some(n) = length {
24508 if *parenthesized_length {
24510 self.write(&format!("(({}))", n));
24511 } else {
24512 self.write(&format!("({})", n));
24513 }
24514 }
24515 }
24516 }
24517 }
24518 DataType::Text => {
24519 match self.config.dialect {
24521 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
24522 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24523 self.write_keyword("VARCHAR(MAX)")
24524 }
24525 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
24526 Some(DialectType::Snowflake)
24527 | Some(DialectType::Dremio)
24528 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
24529 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
24530 Some(DialectType::Presto)
24531 | Some(DialectType::Trino)
24532 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
24533 Some(DialectType::Spark)
24534 | Some(DialectType::Databricks)
24535 | Some(DialectType::Hive) => self.write_keyword("STRING"),
24536 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
24537 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
24538 self.write_keyword("STRING")
24539 }
24540 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
24541 _ => self.write_keyword("TEXT"),
24542 }
24543 }
24544 DataType::TextWithLength { length } => {
24545 match self.config.dialect {
24547 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
24548 Some(DialectType::Hive)
24549 | Some(DialectType::Spark)
24550 | Some(DialectType::Databricks) => {
24551 self.write(&format!("VARCHAR({})", length));
24552 }
24553 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
24554 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
24555 Some(DialectType::Snowflake)
24556 | Some(DialectType::Presto)
24557 | Some(DialectType::Trino)
24558 | Some(DialectType::Athena)
24559 | Some(DialectType::Drill)
24560 | Some(DialectType::Dremio) => {
24561 self.write(&format!("VARCHAR({})", length));
24562 }
24563 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24564 self.write(&format!("VARCHAR({})", length))
24565 }
24566 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
24567 self.write(&format!("STRING({})", length))
24568 }
24569 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
24570 _ => self.write(&format!("TEXT({})", length)),
24571 }
24572 }
24573 DataType::String { length } => {
24574 match self.config.dialect {
24576 Some(DialectType::ClickHouse) => {
24577 self.write("String");
24579 if let Some(n) = length {
24580 self.write(&format!("({})", n));
24581 }
24582 }
24583 Some(DialectType::BigQuery)
24584 | Some(DialectType::Hive)
24585 | Some(DialectType::Spark)
24586 | Some(DialectType::Databricks)
24587 | Some(DialectType::StarRocks)
24588 | Some(DialectType::Doris) => {
24589 self.write_keyword("STRING");
24590 if let Some(n) = length {
24591 self.write(&format!("({})", n));
24592 }
24593 }
24594 Some(DialectType::PostgreSQL) => {
24595 if let Some(n) = length {
24597 self.write_keyword("VARCHAR");
24598 self.write(&format!("({})", n));
24599 } else {
24600 self.write_keyword("TEXT");
24601 }
24602 }
24603 Some(DialectType::Redshift) => {
24604 if let Some(n) = length {
24606 self.write_keyword("VARCHAR");
24607 self.write(&format!("({})", n));
24608 } else {
24609 self.write_keyword("VARCHAR(MAX)");
24610 }
24611 }
24612 Some(DialectType::MySQL) => {
24613 if let Some(n) = length {
24615 self.write_keyword("VARCHAR");
24616 self.write(&format!("({})", n));
24617 } else {
24618 self.write_keyword("TEXT");
24619 }
24620 }
24621 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24622 if let Some(n) = length {
24624 self.write_keyword("VARCHAR");
24625 self.write(&format!("({})", n));
24626 } else {
24627 self.write_keyword("VARCHAR(MAX)");
24628 }
24629 }
24630 Some(DialectType::Oracle) => {
24631 self.write_keyword("CLOB");
24633 }
24634 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
24635 self.write_keyword("TEXT");
24637 if let Some(n) = length {
24638 self.write(&format!("({})", n));
24639 }
24640 }
24641 Some(DialectType::Presto)
24642 | Some(DialectType::Trino)
24643 | Some(DialectType::Drill)
24644 | Some(DialectType::Dremio) => {
24645 self.write_keyword("VARCHAR");
24647 if let Some(n) = length {
24648 self.write(&format!("({})", n));
24649 }
24650 }
24651 Some(DialectType::Snowflake) => {
24652 self.write_keyword("STRING");
24655 if let Some(n) = length {
24656 self.write(&format!("({})", n));
24657 }
24658 }
24659 _ => {
24660 self.write_keyword("STRING");
24662 if let Some(n) = length {
24663 self.write(&format!("({})", n));
24664 }
24665 }
24666 }
24667 }
24668 DataType::Binary { length } => {
24669 match self.config.dialect {
24671 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
24672 self.write_keyword("BYTEA");
24673 if let Some(n) = length {
24674 self.write(&format!("({})", n));
24675 }
24676 }
24677 Some(DialectType::Redshift) => {
24678 self.write_keyword("VARBYTE");
24679 if let Some(n) = length {
24680 self.write(&format!("({})", n));
24681 }
24682 }
24683 Some(DialectType::DuckDB)
24684 | Some(DialectType::SQLite)
24685 | Some(DialectType::Oracle) => {
24686 self.write_keyword("BLOB");
24688 if let Some(n) = length {
24689 self.write(&format!("({})", n));
24690 }
24691 }
24692 Some(DialectType::Presto)
24693 | Some(DialectType::Trino)
24694 | Some(DialectType::Athena)
24695 | Some(DialectType::Drill)
24696 | Some(DialectType::Dremio) => {
24697 self.write_keyword("VARBINARY");
24699 if let Some(n) = length {
24700 self.write(&format!("({})", n));
24701 }
24702 }
24703 Some(DialectType::ClickHouse) => {
24704 if self.clickhouse_nullable_depth < 0 {
24706 self.write("BINARY");
24707 } else {
24708 self.write("Nullable(BINARY");
24709 }
24710 if let Some(n) = length {
24711 self.write(&format!("({})", n));
24712 }
24713 if self.clickhouse_nullable_depth >= 0 {
24714 self.write(")");
24715 }
24716 }
24717 _ => {
24718 self.write_keyword("BINARY");
24719 if let Some(n) = length {
24720 self.write(&format!("({})", n));
24721 }
24722 }
24723 }
24724 }
24725 DataType::VarBinary { length } => {
24726 match self.config.dialect {
24728 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
24729 self.write_keyword("BYTEA");
24730 if let Some(n) = length {
24731 self.write(&format!("({})", n));
24732 }
24733 }
24734 Some(DialectType::Redshift) => {
24735 self.write_keyword("VARBYTE");
24736 if let Some(n) = length {
24737 self.write(&format!("({})", n));
24738 }
24739 }
24740 Some(DialectType::DuckDB)
24741 | Some(DialectType::SQLite)
24742 | Some(DialectType::Oracle) => {
24743 self.write_keyword("BLOB");
24745 if let Some(n) = length {
24746 self.write(&format!("({})", n));
24747 }
24748 }
24749 Some(DialectType::Exasol) => {
24750 self.write_keyword("VARCHAR");
24752 }
24753 Some(DialectType::Spark)
24754 | Some(DialectType::Hive)
24755 | Some(DialectType::Databricks) => {
24756 self.write_keyword("BINARY");
24758 if let Some(n) = length {
24759 self.write(&format!("({})", n));
24760 }
24761 }
24762 Some(DialectType::ClickHouse) => {
24763 self.write_clickhouse_type("String");
24765 }
24766 _ => {
24767 self.write_keyword("VARBINARY");
24768 if let Some(n) = length {
24769 self.write(&format!("({})", n));
24770 }
24771 }
24772 }
24773 }
24774 DataType::Blob => {
24775 match self.config.dialect {
24777 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
24778 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
24779 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24780 self.write_keyword("VARBINARY")
24781 }
24782 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
24783 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
24784 Some(DialectType::Presto)
24785 | Some(DialectType::Trino)
24786 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
24787 Some(DialectType::DuckDB) => {
24788 self.write_keyword("VARBINARY");
24791 }
24792 Some(DialectType::Spark)
24793 | Some(DialectType::Databricks)
24794 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
24795 Some(DialectType::ClickHouse) => {
24796 self.write("Nullable(String)");
24800 }
24801 _ => self.write_keyword("BLOB"),
24802 }
24803 }
24804 DataType::Bit { length } => {
24805 match self.config.dialect {
24807 Some(DialectType::Dremio)
24808 | Some(DialectType::Spark)
24809 | Some(DialectType::Databricks)
24810 | Some(DialectType::Hive)
24811 | Some(DialectType::Snowflake)
24812 | Some(DialectType::BigQuery)
24813 | Some(DialectType::Presto)
24814 | Some(DialectType::Trino)
24815 | Some(DialectType::ClickHouse)
24816 | Some(DialectType::Redshift) => {
24817 self.write_keyword("BOOLEAN");
24819 }
24820 _ => {
24821 self.write_keyword("BIT");
24822 if let Some(n) = length {
24823 self.write(&format!("({})", n));
24824 }
24825 }
24826 }
24827 }
24828 DataType::VarBit { length } => {
24829 self.write_keyword("VARBIT");
24830 if let Some(n) = length {
24831 self.write(&format!("({})", n));
24832 }
24833 }
24834 DataType::Date => self.write_keyword("DATE"),
24835 DataType::Time {
24836 precision,
24837 timezone,
24838 } => {
24839 if *timezone {
24840 match self.config.dialect {
24842 Some(DialectType::DuckDB) => {
24843 self.write_keyword("TIMETZ");
24845 }
24846 Some(DialectType::PostgreSQL) => {
24847 self.write_keyword("TIMETZ");
24849 if let Some(p) = precision {
24850 self.write(&format!("({})", p));
24851 }
24852 }
24853 _ => {
24854 self.write_keyword("TIME");
24856 if let Some(p) = precision {
24857 self.write(&format!("({})", p));
24858 }
24859 self.write_keyword(" WITH TIME ZONE");
24860 }
24861 }
24862 } else {
24863 if matches!(
24865 self.config.dialect,
24866 Some(DialectType::Spark)
24867 | Some(DialectType::Databricks)
24868 | Some(DialectType::Hive)
24869 ) {
24870 self.write_keyword("TIMESTAMP");
24871 } else {
24872 self.write_keyword("TIME");
24873 if let Some(p) = precision {
24874 self.write(&format!("({})", p));
24875 }
24876 }
24877 }
24878 }
24879 DataType::Timestamp {
24880 precision,
24881 timezone,
24882 } => {
24883 match self.config.dialect {
24885 Some(DialectType::Snowflake) if *timezone => {
24886 self.write_keyword("TIMESTAMPTZ");
24887 if let Some(p) = precision {
24888 self.write(&format!("({})", p));
24889 }
24890 }
24891 Some(DialectType::ClickHouse) => {
24892 self.write("DateTime");
24893 if let Some(p) = precision {
24894 self.write(&format!("({})", p));
24895 }
24896 }
24897 Some(DialectType::TSQL) => {
24898 if *timezone {
24899 self.write_keyword("DATETIMEOFFSET");
24900 } else {
24901 self.write_keyword("DATETIME2");
24902 }
24903 if let Some(p) = precision {
24904 self.write(&format!("({})", p));
24905 }
24906 }
24907 Some(DialectType::MySQL) => {
24908 self.write_keyword("TIMESTAMP");
24910 if let Some(p) = precision {
24911 self.write(&format!("({})", p));
24912 }
24913 }
24914 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
24915 self.write_keyword("DATETIME");
24917 if let Some(p) = precision {
24918 self.write(&format!("({})", p));
24919 }
24920 }
24921 Some(DialectType::BigQuery) => {
24922 if *timezone {
24924 self.write_keyword("TIMESTAMP");
24925 } else {
24926 self.write_keyword("DATETIME");
24927 }
24928 }
24929 Some(DialectType::DuckDB) => {
24930 if *timezone {
24932 self.write_keyword("TIMESTAMPTZ");
24933 } else {
24934 self.write_keyword("TIMESTAMP");
24935 if let Some(p) = precision {
24936 self.write(&format!("({})", p));
24937 }
24938 }
24939 }
24940 _ => {
24941 if *timezone && !self.config.tz_to_with_time_zone {
24942 self.write_keyword("TIMESTAMPTZ");
24944 if let Some(p) = precision {
24945 self.write(&format!("({})", p));
24946 }
24947 } else {
24948 self.write_keyword("TIMESTAMP");
24949 if let Some(p) = precision {
24950 self.write(&format!("({})", p));
24951 }
24952 if *timezone {
24953 self.write_space();
24954 self.write_keyword("WITH TIME ZONE");
24955 }
24956 }
24957 }
24958 }
24959 }
24960 DataType::Interval { unit, to } => {
24961 self.write_keyword("INTERVAL");
24962 if let Some(u) = unit {
24963 self.write_space();
24964 self.write_keyword(u);
24965 }
24966 if let Some(t) = to {
24968 self.write_space();
24969 self.write_keyword("TO");
24970 self.write_space();
24971 self.write_keyword(t);
24972 }
24973 }
24974 DataType::Json => {
24975 match self.config.dialect {
24977 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
24980 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
24981 _ => self.write_keyword("JSON"),
24982 }
24983 }
24984 DataType::JsonB => {
24985 match self.config.dialect {
24987 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
24988 Some(DialectType::Doris) => self.write_keyword("JSONB"),
24989 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
24990 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
24991 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
24994 }
24995 DataType::Uuid => {
24996 match self.config.dialect {
24998 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
24999 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
25000 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
25001 Some(DialectType::BigQuery)
25002 | Some(DialectType::Spark)
25003 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
25004 _ => self.write_keyword("UUID"),
25005 }
25006 }
25007 DataType::Array {
25008 element_type,
25009 dimension,
25010 } => {
25011 match self.config.dialect {
25013 Some(DialectType::PostgreSQL)
25014 | Some(DialectType::Redshift)
25015 | Some(DialectType::DuckDB) => {
25016 self.generate_data_type(element_type)?;
25018 if let Some(dim) = dimension {
25019 self.write(&format!("[{}]", dim));
25020 } else {
25021 self.write("[]");
25022 }
25023 }
25024 Some(DialectType::BigQuery) => {
25025 self.write_keyword("ARRAY<");
25026 self.generate_data_type(element_type)?;
25027 self.write(">");
25028 }
25029 Some(DialectType::Snowflake)
25030 | Some(DialectType::Presto)
25031 | Some(DialectType::Trino)
25032 | Some(DialectType::ClickHouse) => {
25033 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
25035 self.write("Array(");
25036 } else {
25037 self.write_keyword("ARRAY(");
25038 }
25039 self.generate_data_type(element_type)?;
25040 self.write(")");
25041 }
25042 Some(DialectType::TSQL)
25043 | Some(DialectType::MySQL)
25044 | Some(DialectType::Oracle) => {
25045 match self.config.dialect {
25048 Some(DialectType::MySQL) => self.write_keyword("JSON"),
25049 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
25050 _ => self.write_keyword("JSON"),
25051 }
25052 }
25053 _ => {
25054 self.write_keyword("ARRAY<");
25056 self.generate_data_type(element_type)?;
25057 self.write(">");
25058 }
25059 }
25060 }
25061 DataType::List { element_type } => {
25062 self.generate_data_type(element_type)?;
25064 self.write_keyword(" LIST");
25065 }
25066 DataType::Map {
25067 key_type,
25068 value_type,
25069 } => {
25070 match self.config.dialect {
25072 Some(DialectType::Materialize) => {
25073 self.write_keyword("MAP[");
25075 self.generate_data_type(key_type)?;
25076 self.write(" => ");
25077 self.generate_data_type(value_type)?;
25078 self.write("]");
25079 }
25080 Some(DialectType::Snowflake)
25081 | Some(DialectType::RisingWave)
25082 | Some(DialectType::DuckDB)
25083 | Some(DialectType::Presto)
25084 | Some(DialectType::Trino)
25085 | Some(DialectType::Athena) => {
25086 self.write_keyword("MAP(");
25087 self.generate_data_type(key_type)?;
25088 self.write(", ");
25089 self.generate_data_type(value_type)?;
25090 self.write(")");
25091 }
25092 Some(DialectType::ClickHouse) => {
25093 self.write("Map(");
25096 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
25098 self.clickhouse_nullable_depth = 0;
25099 self.write(", ");
25100 self.generate_data_type(value_type)?;
25101 self.write(")");
25102 }
25103 _ => {
25104 self.write_keyword("MAP<");
25105 self.generate_data_type(key_type)?;
25106 self.write(", ");
25107 self.generate_data_type(value_type)?;
25108 self.write(">");
25109 }
25110 }
25111 }
25112 DataType::Vector {
25113 element_type,
25114 dimension,
25115 } => {
25116 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
25117 self.write_keyword("VECTOR(");
25119 if let Some(dim) = dimension {
25120 self.write(&dim.to_string());
25121 }
25122 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
25124 DataType::TinyInt { .. } => Some("I8"),
25125 DataType::SmallInt { .. } => Some("I16"),
25126 DataType::Int { .. } => Some("I32"),
25127 DataType::BigInt { .. } => Some("I64"),
25128 DataType::Float { .. } => Some("F32"),
25129 DataType::Double { .. } => Some("F64"),
25130 _ => None,
25131 });
25132 if let Some(alias) = type_alias {
25133 if dimension.is_some() {
25134 self.write(", ");
25135 }
25136 self.write(alias);
25137 }
25138 self.write(")");
25139 } else {
25140 self.write_keyword("VECTOR(");
25142 if let Some(ref et) = element_type {
25143 self.generate_data_type(et)?;
25144 if dimension.is_some() {
25145 self.write(", ");
25146 }
25147 }
25148 if let Some(dim) = dimension {
25149 self.write(&dim.to_string());
25150 }
25151 self.write(")");
25152 }
25153 }
25154 DataType::Object { fields, modifier } => {
25155 self.write_keyword("OBJECT(");
25156 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
25157 if i > 0 {
25158 self.write(", ");
25159 }
25160 self.write(name);
25161 self.write(" ");
25162 self.generate_data_type(dt)?;
25163 if *not_null {
25164 self.write_keyword(" NOT NULL");
25165 }
25166 }
25167 self.write(")");
25168 if let Some(mod_str) = modifier {
25169 self.write(" ");
25170 self.write_keyword(mod_str);
25171 }
25172 }
25173 DataType::Struct { fields, nested } => {
25174 match self.config.dialect {
25176 Some(DialectType::Snowflake) => {
25177 self.write_keyword("OBJECT(");
25179 for (i, field) in fields.iter().enumerate() {
25180 if i > 0 {
25181 self.write(", ");
25182 }
25183 if !field.name.is_empty() {
25184 self.write(&field.name);
25185 self.write(" ");
25186 }
25187 self.generate_data_type(&field.data_type)?;
25188 }
25189 self.write(")");
25190 }
25191 Some(DialectType::Presto) | Some(DialectType::Trino) => {
25192 self.write_keyword("ROW(");
25194 for (i, field) in fields.iter().enumerate() {
25195 if i > 0 {
25196 self.write(", ");
25197 }
25198 if !field.name.is_empty() {
25199 self.write(&field.name);
25200 self.write(" ");
25201 }
25202 self.generate_data_type(&field.data_type)?;
25203 }
25204 self.write(")");
25205 }
25206 Some(DialectType::DuckDB) => {
25207 self.write_keyword("STRUCT(");
25209 for (i, field) in fields.iter().enumerate() {
25210 if i > 0 {
25211 self.write(", ");
25212 }
25213 if !field.name.is_empty() {
25214 self.write(&field.name);
25215 self.write(" ");
25216 }
25217 self.generate_data_type(&field.data_type)?;
25218 }
25219 self.write(")");
25220 }
25221 Some(DialectType::ClickHouse) => {
25222 self.write("Tuple(");
25224 for (i, field) in fields.iter().enumerate() {
25225 if i > 0 {
25226 self.write(", ");
25227 }
25228 if !field.name.is_empty() {
25229 self.write(&field.name);
25230 self.write(" ");
25231 }
25232 self.generate_data_type(&field.data_type)?;
25233 }
25234 self.write(")");
25235 }
25236 Some(DialectType::SingleStore) => {
25237 self.write_keyword("RECORD(");
25239 for (i, field) in fields.iter().enumerate() {
25240 if i > 0 {
25241 self.write(", ");
25242 }
25243 if !field.name.is_empty() {
25244 self.write(&field.name);
25245 self.write(" ");
25246 }
25247 self.generate_data_type(&field.data_type)?;
25248 }
25249 self.write(")");
25250 }
25251 _ => {
25252 let force_angle_brackets = matches!(
25254 self.config.dialect,
25255 Some(DialectType::Hive)
25256 | Some(DialectType::Spark)
25257 | Some(DialectType::Databricks)
25258 );
25259 if *nested && !force_angle_brackets {
25260 self.write_keyword("STRUCT(");
25261 for (i, field) in fields.iter().enumerate() {
25262 if i > 0 {
25263 self.write(", ");
25264 }
25265 if !field.name.is_empty() {
25266 self.write(&field.name);
25267 self.write(" ");
25268 }
25269 self.generate_data_type(&field.data_type)?;
25270 }
25271 self.write(")");
25272 } else {
25273 self.write_keyword("STRUCT<");
25274 for (i, field) in fields.iter().enumerate() {
25275 if i > 0 {
25276 self.write(", ");
25277 }
25278 if !field.name.is_empty() {
25279 self.write(&field.name);
25281 self.write(self.config.struct_field_sep);
25282 }
25283 self.generate_data_type(&field.data_type)?;
25285 if let Some(comment) = &field.comment {
25287 self.write(" COMMENT '");
25288 self.write(comment);
25289 self.write("'");
25290 }
25291 if !field.options.is_empty() {
25293 self.write(" ");
25294 self.generate_options_clause(&field.options)?;
25295 }
25296 }
25297 self.write(">");
25298 }
25299 }
25300 }
25301 }
25302 DataType::Enum {
25303 values,
25304 assignments,
25305 } => {
25306 if self.config.dialect == Some(DialectType::ClickHouse) {
25309 self.write("Enum(");
25310 } else {
25311 self.write_keyword("ENUM(");
25312 }
25313 for (i, val) in values.iter().enumerate() {
25314 if i > 0 {
25315 self.write(", ");
25316 }
25317 self.write("'");
25318 self.write(val);
25319 self.write("'");
25320 if let Some(Some(assignment)) = assignments.get(i) {
25321 self.write(" = ");
25322 self.write(assignment);
25323 }
25324 }
25325 self.write(")");
25326 }
25327 DataType::Set { values } => {
25328 self.write_keyword("SET(");
25330 for (i, val) in values.iter().enumerate() {
25331 if i > 0 {
25332 self.write(", ");
25333 }
25334 self.write("'");
25335 self.write(val);
25336 self.write("'");
25337 }
25338 self.write(")");
25339 }
25340 DataType::Union { fields } => {
25341 self.write_keyword("UNION(");
25343 for (i, (name, dt)) in fields.iter().enumerate() {
25344 if i > 0 {
25345 self.write(", ");
25346 }
25347 if !name.is_empty() {
25348 self.write(name);
25349 self.write(" ");
25350 }
25351 self.generate_data_type(dt)?;
25352 }
25353 self.write(")");
25354 }
25355 DataType::Nullable { inner } => {
25356 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
25358 self.write("Nullable(");
25359 let saved_depth = self.clickhouse_nullable_depth;
25361 self.clickhouse_nullable_depth = -1;
25362 self.generate_data_type(inner)?;
25363 self.clickhouse_nullable_depth = saved_depth;
25364 self.write(")");
25365 } else {
25366 match inner.as_ref() {
25368 DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
25369 self.generate_data_type(&DataType::Timestamp {
25370 precision: None,
25371 timezone: false,
25372 })?;
25373 }
25374 _ => {
25375 self.generate_data_type(inner)?;
25376 }
25377 }
25378 }
25379 }
25380 DataType::Custom { name } => {
25381 let name_upper = name.to_ascii_uppercase();
25383 match self.config.dialect {
25384 Some(DialectType::ClickHouse) => {
25385 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
25386 (name_upper[..idx].to_string(), &name[idx..])
25387 } else {
25388 (name_upper.clone(), "")
25389 };
25390 let mapped = match base_upper.as_str() {
25391 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
25392 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
25393 "DATETIME64" => "DateTime64",
25394 "DATE32" => "Date32",
25395 "INT" => "Int32",
25396 "MEDIUMINT" => "Int32",
25397 "INT8" => "Int8",
25398 "INT16" => "Int16",
25399 "INT32" => "Int32",
25400 "INT64" => "Int64",
25401 "INT128" => "Int128",
25402 "INT256" => "Int256",
25403 "UINT8" => "UInt8",
25404 "UINT16" => "UInt16",
25405 "UINT32" => "UInt32",
25406 "UINT64" => "UInt64",
25407 "UINT128" => "UInt128",
25408 "UINT256" => "UInt256",
25409 "FLOAT32" => "Float32",
25410 "FLOAT64" => "Float64",
25411 "DECIMAL32" => "Decimal32",
25412 "DECIMAL64" => "Decimal64",
25413 "DECIMAL128" => "Decimal128",
25414 "DECIMAL256" => "Decimal256",
25415 "ENUM" => "Enum",
25416 "ENUM8" => "Enum8",
25417 "ENUM16" => "Enum16",
25418 "FIXEDSTRING" => "FixedString",
25419 "NESTED" => "Nested",
25420 "LOWCARDINALITY" => "LowCardinality",
25421 "NULLABLE" => "Nullable",
25422 "IPV4" => "IPv4",
25423 "IPV6" => "IPv6",
25424 "POINT" => "Point",
25425 "RING" => "Ring",
25426 "LINESTRING" => "LineString",
25427 "MULTILINESTRING" => "MultiLineString",
25428 "POLYGON" => "Polygon",
25429 "MULTIPOLYGON" => "MultiPolygon",
25430 "AGGREGATEFUNCTION" => "AggregateFunction",
25431 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
25432 "DYNAMIC" => "Dynamic",
25433 _ => "",
25434 };
25435 if mapped.is_empty() {
25436 self.write(name);
25437 } else {
25438 self.write(mapped);
25439 if matches!(base_upper.as_str(), "ENUM8" | "ENUM16")
25440 && !suffix.is_empty()
25441 {
25442 let escaped_suffix = suffix
25443 .replace('\\', "\\\\")
25444 .replace('\t', "\\t")
25445 .replace('\n', "\\n")
25446 .replace('\r', "\\r");
25447 self.write(&escaped_suffix);
25448 } else {
25449 self.write(suffix);
25450 }
25451 }
25452 }
25453 Some(DialectType::MySQL)
25454 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
25455 {
25456 self.write_keyword("TIMESTAMP");
25458 }
25459 Some(DialectType::Snowflake) => {
25460 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
25461 (name_upper[..idx].to_string(), &name[idx..])
25462 } else {
25463 (name_upper.clone(), "")
25464 };
25465
25466 match base_upper.as_str() {
25467 "TIMESTAMPNTZ" | "TIMESTAMP_NTZ" => {
25468 self.write_keyword("TIMESTAMPNTZ");
25469 self.write(suffix);
25470 }
25471 "TIMESTAMPLTZ" | "TIMESTAMP_LTZ" => {
25472 self.write_keyword("TIMESTAMPLTZ");
25473 self.write(suffix);
25474 }
25475 "TIMESTAMPTZ" | "TIMESTAMP_TZ" => {
25476 self.write_keyword("TIMESTAMPTZ");
25477 self.write(suffix);
25478 }
25479 _ => self.write(name),
25480 }
25481 }
25482 Some(DialectType::Fabric) => {
25483 let (base_upper, args_str) = if let Some(idx) = name.find('(') {
25484 (name_upper[..idx].to_string(), Some(&name[idx..]))
25485 } else {
25486 (name_upper.clone(), None)
25487 };
25488
25489 match base_upper.as_str() {
25490 "NVARCHAR" => {
25491 self.write_keyword("VARCHAR");
25492 if let Some(args) = args_str {
25493 self.write(args);
25494 }
25495 }
25496 "NCHAR" => {
25497 self.write_keyword("CHAR");
25498 if let Some(args) = args_str {
25499 self.write(args);
25500 }
25501 }
25502 _ => self.write(name),
25503 }
25504 }
25505 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
25506 self.write_keyword("SQL_VARIANT");
25507 }
25508 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
25509 self.write_keyword("DECIMAL(38, 5)");
25510 }
25511 Some(DialectType::Exasol) => {
25512 match name_upper.as_str() {
25514 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
25516 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
25518 "MEDIUMINT" => self.write_keyword("INT"),
25520 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
25522 self.write_keyword("DECIMAL")
25523 }
25524 "DATETIME" => self.write_keyword("TIMESTAMP"),
25526 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
25527 _ => self.write(name),
25528 }
25529 }
25530 Some(DialectType::Dremio) => {
25531 match name_upper.as_str() {
25533 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
25534 "ARRAY" => self.write_keyword("LIST"),
25535 "NCHAR" => self.write_keyword("VARCHAR"),
25536 _ => self.write(name),
25537 }
25538 }
25539 _ => {
25541 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
25543 (name_upper[..idx].to_string(), Some(&name[idx..]))
25544 } else {
25545 (name_upper.clone(), None)
25546 };
25547
25548 match base_upper.as_str() {
25549 "INT64"
25550 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25551 {
25552 self.write_keyword("BIGINT");
25553 }
25554 "FLOAT64"
25555 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25556 {
25557 self.write_keyword("DOUBLE");
25558 }
25559 "BOOL"
25560 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25561 {
25562 self.write_keyword("BOOLEAN");
25563 }
25564 "BYTES"
25565 if matches!(
25566 self.config.dialect,
25567 Some(DialectType::Spark)
25568 | Some(DialectType::Hive)
25569 | Some(DialectType::Databricks)
25570 ) =>
25571 {
25572 self.write_keyword("BINARY");
25573 }
25574 "BYTES"
25575 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25576 {
25577 self.write_keyword("VARBINARY");
25578 }
25579 "DATETIME2" | "SMALLDATETIME"
25581 if !matches!(
25582 self.config.dialect,
25583 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25584 ) =>
25585 {
25586 if matches!(
25588 self.config.dialect,
25589 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
25590 ) {
25591 self.write_keyword("TIMESTAMP");
25592 if let Some(args) = _args_str {
25593 self.write(args);
25594 }
25595 } else {
25596 self.write_keyword("TIMESTAMP");
25597 }
25598 }
25599 "DATETIMEOFFSET"
25601 if !matches!(
25602 self.config.dialect,
25603 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25604 ) =>
25605 {
25606 if matches!(
25607 self.config.dialect,
25608 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
25609 ) {
25610 self.write_keyword("TIMESTAMPTZ");
25611 if let Some(args) = _args_str {
25612 self.write(args);
25613 }
25614 } else {
25615 self.write_keyword("TIMESTAMPTZ");
25616 }
25617 }
25618 "UNIQUEIDENTIFIER"
25620 if !matches!(
25621 self.config.dialect,
25622 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25623 ) =>
25624 {
25625 match self.config.dialect {
25626 Some(DialectType::Spark)
25627 | Some(DialectType::Databricks)
25628 | Some(DialectType::Hive) => self.write_keyword("STRING"),
25629 _ => self.write_keyword("UUID"),
25630 }
25631 }
25632 "BIT"
25634 if !matches!(
25635 self.config.dialect,
25636 Some(DialectType::TSQL)
25637 | Some(DialectType::Fabric)
25638 | Some(DialectType::PostgreSQL)
25639 | Some(DialectType::MySQL)
25640 | Some(DialectType::DuckDB)
25641 ) =>
25642 {
25643 self.write_keyword("BOOLEAN");
25644 }
25645 "NVARCHAR"
25647 if !matches!(
25648 self.config.dialect,
25649 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25650 ) =>
25651 {
25652 match self.config.dialect {
25653 Some(DialectType::Oracle) => {
25654 self.write_keyword("NVARCHAR2");
25656 if let Some(args) = _args_str {
25657 self.write(args);
25658 }
25659 }
25660 Some(DialectType::BigQuery) => {
25661 self.write_keyword("STRING");
25663 }
25664 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
25665 self.write_keyword("TEXT");
25666 if let Some(args) = _args_str {
25667 self.write(args);
25668 }
25669 }
25670 Some(DialectType::Hive) => {
25671 self.write_keyword("STRING");
25673 }
25674 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
25675 if _args_str.is_some() {
25676 self.write_keyword("VARCHAR");
25677 self.write(_args_str.unwrap());
25678 } else {
25679 self.write_keyword("STRING");
25680 }
25681 }
25682 _ => {
25683 self.write_keyword("VARCHAR");
25684 if let Some(args) = _args_str {
25685 self.write(args);
25686 }
25687 }
25688 }
25689 }
25690 "NCHAR"
25692 if !matches!(
25693 self.config.dialect,
25694 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25695 ) =>
25696 {
25697 match self.config.dialect {
25698 Some(DialectType::Oracle) => {
25699 self.write_keyword("NCHAR");
25701 if let Some(args) = _args_str {
25702 self.write(args);
25703 }
25704 }
25705 Some(DialectType::BigQuery) => {
25706 self.write_keyword("STRING");
25708 }
25709 Some(DialectType::Hive) => {
25710 self.write_keyword("STRING");
25712 }
25713 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
25714 self.write_keyword("TEXT");
25715 if let Some(args) = _args_str {
25716 self.write(args);
25717 }
25718 }
25719 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
25720 if _args_str.is_some() {
25721 self.write_keyword("CHAR");
25722 self.write(_args_str.unwrap());
25723 } else {
25724 self.write_keyword("STRING");
25725 }
25726 }
25727 _ => {
25728 self.write_keyword("CHAR");
25729 if let Some(args) = _args_str {
25730 self.write(args);
25731 }
25732 }
25733 }
25734 }
25735 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
25738 Some(DialectType::MySQL)
25739 | Some(DialectType::SingleStore)
25740 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
25741 Some(DialectType::Spark)
25742 | Some(DialectType::Databricks)
25743 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
25744 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
25745 Some(DialectType::Presto)
25746 | Some(DialectType::Trino)
25747 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
25748 Some(DialectType::Snowflake)
25749 | Some(DialectType::Redshift)
25750 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
25751 _ => self.write_keyword("TEXT"),
25752 },
25753 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
25756 Some(DialectType::MySQL)
25757 | Some(DialectType::SingleStore)
25758 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
25759 Some(DialectType::Spark)
25760 | Some(DialectType::Databricks)
25761 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
25762 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
25763 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
25764 Some(DialectType::Presto)
25765 | Some(DialectType::Trino)
25766 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
25767 Some(DialectType::Snowflake)
25768 | Some(DialectType::Redshift)
25769 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
25770 _ => self.write_keyword("BLOB"),
25771 },
25772 "LONGVARCHAR" => match self.config.dialect {
25774 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
25775 _ => self.write_keyword("VARCHAR"),
25776 },
25777 "DATETIME" => {
25779 match self.config.dialect {
25780 Some(DialectType::MySQL)
25781 | Some(DialectType::Doris)
25782 | Some(DialectType::StarRocks)
25783 | Some(DialectType::TSQL)
25784 | Some(DialectType::Fabric)
25785 | Some(DialectType::BigQuery)
25786 | Some(DialectType::SQLite)
25787 | Some(DialectType::Snowflake) => {
25788 self.write_keyword("DATETIME");
25789 if let Some(args) = _args_str {
25790 self.write(args);
25791 }
25792 }
25793 Some(_) => {
25794 self.write_keyword("TIMESTAMP");
25796 if let Some(args) = _args_str {
25797 self.write(args);
25798 }
25799 }
25800 None => {
25801 self.write(name);
25803 }
25804 }
25805 }
25806 "VARCHAR2"
25808 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
25809 {
25810 match self.config.dialect {
25811 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
25812 self.write_keyword("TEXT");
25813 }
25814 Some(DialectType::Hive)
25815 | Some(DialectType::Spark)
25816 | Some(DialectType::Databricks)
25817 | Some(DialectType::BigQuery)
25818 | Some(DialectType::ClickHouse)
25819 | Some(DialectType::StarRocks)
25820 | Some(DialectType::Doris) => {
25821 self.write_keyword("STRING");
25822 }
25823 _ => {
25824 self.write_keyword("VARCHAR");
25825 if let Some(args) = _args_str {
25826 self.write(args);
25827 }
25828 }
25829 }
25830 }
25831 "NVARCHAR2"
25832 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
25833 {
25834 match self.config.dialect {
25835 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
25836 self.write_keyword("TEXT");
25837 }
25838 Some(DialectType::Hive)
25839 | Some(DialectType::Spark)
25840 | Some(DialectType::Databricks)
25841 | Some(DialectType::BigQuery)
25842 | Some(DialectType::ClickHouse)
25843 | Some(DialectType::StarRocks)
25844 | Some(DialectType::Doris) => {
25845 self.write_keyword("STRING");
25846 }
25847 _ => {
25848 self.write_keyword("VARCHAR");
25849 if let Some(args) = _args_str {
25850 self.write(args);
25851 }
25852 }
25853 }
25854 }
25855 _ => self.write(name),
25856 }
25857 }
25858 }
25859 }
25860 DataType::Geometry { subtype, srid } => {
25861 match self.config.dialect {
25863 Some(DialectType::MySQL) => {
25864 if let Some(sub) = subtype {
25866 self.write_keyword(sub);
25867 if let Some(s) = srid {
25868 self.write(" SRID ");
25869 self.write(&s.to_string());
25870 }
25871 } else {
25872 self.write_keyword("GEOMETRY");
25873 }
25874 }
25875 Some(DialectType::BigQuery) => {
25876 self.write_keyword("GEOGRAPHY");
25878 }
25879 Some(DialectType::Teradata) => {
25880 self.write_keyword("ST_GEOMETRY");
25882 if subtype.is_some() || srid.is_some() {
25883 self.write("(");
25884 if let Some(sub) = subtype {
25885 self.write_keyword(sub);
25886 }
25887 if let Some(s) = srid {
25888 if subtype.is_some() {
25889 self.write(", ");
25890 }
25891 self.write(&s.to_string());
25892 }
25893 self.write(")");
25894 }
25895 }
25896 _ => {
25897 self.write_keyword("GEOMETRY");
25899 if subtype.is_some() || srid.is_some() {
25900 self.write("(");
25901 if let Some(sub) = subtype {
25902 self.write_keyword(sub);
25903 }
25904 if let Some(s) = srid {
25905 if subtype.is_some() {
25906 self.write(", ");
25907 }
25908 self.write(&s.to_string());
25909 }
25910 self.write(")");
25911 }
25912 }
25913 }
25914 }
25915 DataType::Geography { subtype, srid } => {
25916 match self.config.dialect {
25918 Some(DialectType::MySQL) => {
25919 if let Some(sub) = subtype {
25921 self.write_keyword(sub);
25922 } else {
25923 self.write_keyword("GEOMETRY");
25924 }
25925 let effective_srid = srid.unwrap_or(4326);
25927 self.write(" SRID ");
25928 self.write(&effective_srid.to_string());
25929 }
25930 Some(DialectType::BigQuery) => {
25931 self.write_keyword("GEOGRAPHY");
25933 }
25934 Some(DialectType::Snowflake) => {
25935 self.write_keyword("GEOGRAPHY");
25937 }
25938 _ => {
25939 self.write_keyword("GEOGRAPHY");
25941 if subtype.is_some() || srid.is_some() {
25942 self.write("(");
25943 if let Some(sub) = subtype {
25944 self.write_keyword(sub);
25945 }
25946 if let Some(s) = srid {
25947 if subtype.is_some() {
25948 self.write(", ");
25949 }
25950 self.write(&s.to_string());
25951 }
25952 self.write(")");
25953 }
25954 }
25955 }
25956 }
25957 DataType::CharacterSet { name } => {
25958 self.write_keyword("CHAR CHARACTER SET ");
25960 self.write(name);
25961 }
25962 _ => self.write("UNKNOWN"),
25963 }
25964 Ok(())
25965 }
25966
25967 #[inline]
25970 fn write(&mut self, s: &str) {
25971 self.output.push_str(s);
25972 }
25973
25974 #[inline]
25975 fn write_space(&mut self) {
25976 self.output.push(' ');
25977 }
25978
25979 #[inline]
25980 fn write_keyword(&mut self, keyword: &str) {
25981 if self.config.uppercase_keywords {
25982 self.output.push_str(keyword);
25983 } else {
25984 for b in keyword.bytes() {
25985 self.output.push(b.to_ascii_lowercase() as char);
25986 }
25987 }
25988 }
25989
25990 fn write_func_name(&mut self, name: &str) {
25992 let normalized = self.normalize_func_name(name);
25993 self.output.push_str(normalized.as_ref());
25994 }
25995
25996 fn convert_strptime_to_exasol_format(format: &str) -> String {
26000 let mut result = String::new();
26001 let chars: Vec<char> = format.chars().collect();
26002 let mut i = 0;
26003 while i < chars.len() {
26004 if chars[i] == '%' && i + 1 < chars.len() {
26005 let spec = chars[i + 1];
26006 let exasol_spec = match spec {
26007 'Y' => "YYYY",
26008 'y' => "YY",
26009 'm' => "MM",
26010 'd' => "DD",
26011 'H' => "HH",
26012 'M' => "MI",
26013 'S' => "SS",
26014 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
26026 result.push('%');
26028 result.push(spec);
26029 i += 2;
26030 continue;
26031 }
26032 };
26033 result.push_str(exasol_spec);
26034 i += 2;
26035 } else {
26036 result.push(chars[i]);
26037 i += 1;
26038 }
26039 }
26040 result
26041 }
26042
26043 fn convert_strptime_to_postgres_format(format: &str) -> String {
26047 let mut result = String::new();
26048 let chars: Vec<char> = format.chars().collect();
26049 let mut i = 0;
26050 while i < chars.len() {
26051 if chars[i] == '%' && i + 1 < chars.len() {
26052 if chars[i + 1] == '-' && i + 2 < chars.len() {
26054 let spec = chars[i + 2];
26055 let pg_spec = match spec {
26056 'd' => "FMDD",
26057 'm' => "FMMM",
26058 'H' => "FMHH24",
26059 'M' => "FMMI",
26060 'S' => "FMSS",
26061 _ => {
26062 result.push('%');
26063 result.push('-');
26064 result.push(spec);
26065 i += 3;
26066 continue;
26067 }
26068 };
26069 result.push_str(pg_spec);
26070 i += 3;
26071 continue;
26072 }
26073 let spec = chars[i + 1];
26074 let pg_spec = match spec {
26075 'Y' => "YYYY",
26076 'y' => "YY",
26077 'm' => "MM",
26078 'd' => "DD",
26079 'H' => "HH24",
26080 'I' => "HH12",
26081 'M' => "MI",
26082 'S' => "SS",
26083 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
26094 result.push('%');
26096 result.push(spec);
26097 i += 2;
26098 continue;
26099 }
26100 };
26101 result.push_str(pg_spec);
26102 i += 2;
26103 } else {
26104 result.push(chars[i]);
26105 i += 1;
26106 }
26107 }
26108 result
26109 }
26110
26111 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
26113 if self.config.limit_only_literals {
26114 if let Some(value) = Self::try_evaluate_constant(expr) {
26115 self.write(&value.to_string());
26116 return Ok(());
26117 }
26118 }
26119 self.generate_expression(expr)
26120 }
26121
26122 fn write_formatted_comment(&mut self, comment: &str) {
26126 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
26129 &comment[2..comment.len() - 2]
26132 } else if comment.starts_with("--") {
26133 &comment[2..]
26136 } else {
26137 comment
26139 };
26140 if content.trim().is_empty() {
26142 return;
26143 }
26144 let sanitized = content.replace("*/", "* /").replace("/*", "/ *");
26147 let content = &sanitized;
26148 self.output.push_str("/*");
26150 if !content.starts_with(' ') {
26151 self.output.push(' ');
26152 }
26153 self.output.push_str(content);
26154 if !content.ends_with(' ') {
26155 self.output.push(' ');
26156 }
26157 self.output.push_str("*/");
26158 }
26159
26160 fn escape_block_for_single_quote(&self, block: &str) -> String {
26163 let escape_backslash = matches!(
26164 self.config.dialect,
26165 Some(crate::dialects::DialectType::Snowflake)
26166 );
26167 let mut escaped = String::with_capacity(block.len() + 4);
26168 for ch in block.chars() {
26169 if ch == '\'' {
26170 escaped.push('\\');
26171 escaped.push('\'');
26172 } else if escape_backslash && ch == '\\' {
26173 escaped.push('\\');
26174 escaped.push('\\');
26175 } else {
26176 escaped.push(ch);
26177 }
26178 }
26179 escaped
26180 }
26181
26182 fn write_newline(&mut self) {
26183 self.output.push('\n');
26184 }
26185
26186 fn write_indent(&mut self) {
26187 for _ in 0..self.indent_level {
26188 self.output.push_str(self.config.indent);
26189 }
26190 }
26191
26192 fn too_wide(&self, args: &[String]) -> bool {
26198 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
26199 }
26200
26201 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
26204 let config = GeneratorConfig {
26205 pretty: false,
26206 dialect: self.config.dialect,
26207 ..Default::default()
26208 };
26209 let mut gen = Generator::with_config(config);
26210 gen.generate_expression(expr)?;
26211 Ok(gen.output)
26212 }
26213
26214 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
26217 if self.config.pretty {
26218 self.write_newline();
26219 self.write_indent();
26220 self.write_keyword(keyword);
26221 self.write_newline();
26222 self.indent_level += 1;
26223 self.write_indent();
26224 self.generate_expression(condition)?;
26225 self.indent_level -= 1;
26226 } else {
26227 self.write_space();
26228 self.write_keyword(keyword);
26229 self.write_space();
26230 self.generate_expression(condition)?;
26231 }
26232 Ok(())
26233 }
26234
26235 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
26238 if exprs.is_empty() {
26239 return Ok(());
26240 }
26241
26242 if self.config.pretty {
26243 self.write_newline();
26244 self.write_indent();
26245 self.write_keyword(keyword);
26246 self.write_newline();
26247 self.indent_level += 1;
26248 for (i, expr) in exprs.iter().enumerate() {
26249 if i > 0 {
26250 self.write(",");
26251 self.write_newline();
26252 }
26253 self.write_indent();
26254 self.generate_expression(expr)?;
26255 }
26256 self.indent_level -= 1;
26257 } else {
26258 self.write_space();
26259 self.write_keyword(keyword);
26260 self.write_space();
26261 for (i, expr) in exprs.iter().enumerate() {
26262 if i > 0 {
26263 self.write(", ");
26264 }
26265 self.generate_expression(expr)?;
26266 }
26267 }
26268 Ok(())
26269 }
26270
26271 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
26273 if orderings.is_empty() {
26274 return Ok(());
26275 }
26276
26277 if self.config.pretty {
26278 self.write_newline();
26279 self.write_indent();
26280 self.write_keyword(keyword);
26281 self.write_newline();
26282 self.indent_level += 1;
26283 for (i, ordered) in orderings.iter().enumerate() {
26284 if i > 0 {
26285 self.write(",");
26286 self.write_newline();
26287 }
26288 self.write_indent();
26289 self.generate_ordered(ordered)?;
26290 }
26291 self.indent_level -= 1;
26292 } else {
26293 self.write_space();
26294 self.write_keyword(keyword);
26295 self.write_space();
26296 for (i, ordered) in orderings.iter().enumerate() {
26297 if i > 0 {
26298 self.write(", ");
26299 }
26300 self.generate_ordered(ordered)?;
26301 }
26302 }
26303 Ok(())
26304 }
26305
26306 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
26308 if windows.is_empty() {
26309 return Ok(());
26310 }
26311
26312 if self.config.pretty {
26313 self.write_newline();
26314 self.write_indent();
26315 self.write_keyword("WINDOW");
26316 self.write_newline();
26317 self.indent_level += 1;
26318 for (i, named_window) in windows.iter().enumerate() {
26319 if i > 0 {
26320 self.write(",");
26321 self.write_newline();
26322 }
26323 self.write_indent();
26324 self.generate_identifier(&named_window.name)?;
26325 self.write_space();
26326 self.write_keyword("AS");
26327 self.write(" (");
26328 self.generate_over(&named_window.spec)?;
26329 self.write(")");
26330 }
26331 self.indent_level -= 1;
26332 } else {
26333 self.write_space();
26334 self.write_keyword("WINDOW");
26335 self.write_space();
26336 for (i, named_window) in windows.iter().enumerate() {
26337 if i > 0 {
26338 self.write(", ");
26339 }
26340 self.generate_identifier(&named_window.name)?;
26341 self.write_space();
26342 self.write_keyword("AS");
26343 self.write(" (");
26344 self.generate_over(&named_window.spec)?;
26345 self.write(")");
26346 }
26347 }
26348 Ok(())
26349 }
26350
26351 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
26353 self.write_keyword("AI_AGG");
26355 self.write("(");
26356 self.generate_expression(&e.this)?;
26357 self.write(", ");
26358 self.generate_expression(&e.expression)?;
26359 self.write(")");
26360 Ok(())
26361 }
26362
26363 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
26364 self.write_keyword("AI_CLASSIFY");
26366 self.write("(");
26367 self.generate_expression(&e.this)?;
26368 if let Some(categories) = &e.categories {
26369 self.write(", ");
26370 self.generate_expression(categories)?;
26371 }
26372 if let Some(config) = &e.config {
26373 self.write(", ");
26374 self.generate_expression(config)?;
26375 }
26376 self.write(")");
26377 Ok(())
26378 }
26379
26380 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
26381 self.write_keyword("ADD");
26383 self.write_space();
26384 if e.exists {
26385 self.write_keyword("IF NOT EXISTS");
26386 self.write_space();
26387 }
26388 self.generate_expression(&e.this)?;
26389 if let Some(location) = &e.location {
26390 self.write_space();
26391 self.generate_expression(location)?;
26392 }
26393 Ok(())
26394 }
26395
26396 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
26397 self.write_keyword("ALGORITHM");
26399 self.write("=");
26400 self.generate_expression(&e.this)?;
26401 Ok(())
26402 }
26403
26404 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
26405 self.generate_expression(&e.this)?;
26407 self.write_space();
26408 self.write_keyword("AS");
26409 self.write(" (");
26410 for (i, expr) in e.expressions.iter().enumerate() {
26411 if i > 0 {
26412 self.write(", ");
26413 }
26414 self.generate_expression(expr)?;
26415 }
26416 self.write(")");
26417 Ok(())
26418 }
26419
26420 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
26421 self.write_keyword("ALLOWED_VALUES");
26423 self.write_space();
26424 for (i, expr) in e.expressions.iter().enumerate() {
26425 if i > 0 {
26426 self.write(", ");
26427 }
26428 self.generate_expression(expr)?;
26429 }
26430 Ok(())
26431 }
26432
26433 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
26434 self.write_keyword("ALTER COLUMN");
26436 self.write_space();
26437 self.generate_expression(&e.this)?;
26438
26439 if let Some(dtype) = &e.dtype {
26440 self.write_space();
26441 self.write_keyword("SET DATA TYPE");
26442 self.write_space();
26443 self.generate_expression(dtype)?;
26444 if let Some(collate) = &e.collate {
26445 self.write_space();
26446 self.write_keyword("COLLATE");
26447 self.write_space();
26448 self.generate_expression(collate)?;
26449 }
26450 if let Some(using) = &e.using {
26451 self.write_space();
26452 self.write_keyword("USING");
26453 self.write_space();
26454 self.generate_expression(using)?;
26455 }
26456 } else if let Some(default) = &e.default {
26457 self.write_space();
26458 self.write_keyword("SET DEFAULT");
26459 self.write_space();
26460 self.generate_expression(default)?;
26461 } else if let Some(comment) = &e.comment {
26462 self.write_space();
26463 self.write_keyword("COMMENT");
26464 self.write_space();
26465 self.generate_expression(comment)?;
26466 } else if let Some(drop) = &e.drop {
26467 self.write_space();
26468 self.write_keyword("DROP");
26469 self.write_space();
26470 self.generate_expression(drop)?;
26471 } else if let Some(visible) = &e.visible {
26472 self.write_space();
26473 self.generate_expression(visible)?;
26474 } else if let Some(rename_to) = &e.rename_to {
26475 self.write_space();
26476 self.write_keyword("RENAME TO");
26477 self.write_space();
26478 self.generate_expression(rename_to)?;
26479 } else if let Some(allow_null) = &e.allow_null {
26480 self.write_space();
26481 self.generate_expression(allow_null)?;
26482 }
26483 Ok(())
26484 }
26485
26486 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
26487 self.write_keyword("ALTER SESSION");
26489 self.write_space();
26490 if e.unset.is_some() {
26491 self.write_keyword("UNSET");
26492 } else {
26493 self.write_keyword("SET");
26494 }
26495 self.write_space();
26496 for (i, expr) in e.expressions.iter().enumerate() {
26497 if i > 0 {
26498 self.write(", ");
26499 }
26500 self.generate_expression(expr)?;
26501 }
26502 Ok(())
26503 }
26504
26505 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
26506 self.write_keyword("SET");
26508
26509 if let Some(opt) = &e.option {
26511 self.write_space();
26512 self.generate_expression(opt)?;
26513 }
26514
26515 if !e.expressions.is_empty() {
26518 let is_properties = e
26520 .expressions
26521 .iter()
26522 .any(|expr| matches!(expr, Expression::Eq(_)));
26523 if is_properties && e.option.is_none() {
26524 self.write_space();
26525 self.write_keyword("PROPERTIES");
26526 }
26527 self.write_space();
26528 for (i, expr) in e.expressions.iter().enumerate() {
26529 if i > 0 {
26530 self.write(", ");
26531 }
26532 self.generate_expression(expr)?;
26533 }
26534 }
26535
26536 if let Some(file_format) = &e.file_format {
26538 self.write(" ");
26539 self.write_keyword("STAGE_FILE_FORMAT");
26540 self.write(" = (");
26541 self.generate_space_separated_properties(file_format)?;
26542 self.write(")");
26543 }
26544
26545 if let Some(copy_options) = &e.copy_options {
26547 self.write(" ");
26548 self.write_keyword("STAGE_COPY_OPTIONS");
26549 self.write(" = (");
26550 self.generate_space_separated_properties(copy_options)?;
26551 self.write(")");
26552 }
26553
26554 if let Some(tag) = &e.tag {
26556 self.write(" ");
26557 self.write_keyword("TAG");
26558 self.write(" ");
26559 self.generate_expression(tag)?;
26560 }
26561
26562 Ok(())
26563 }
26564
26565 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
26567 match expr {
26568 Expression::Tuple(t) => {
26569 for (i, prop) in t.expressions.iter().enumerate() {
26570 if i > 0 {
26571 self.write(" ");
26572 }
26573 self.generate_expression(prop)?;
26574 }
26575 }
26576 _ => {
26577 self.generate_expression(expr)?;
26578 }
26579 }
26580 Ok(())
26581 }
26582
26583 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
26584 self.write_keyword("ALTER");
26586 if e.compound.is_some() {
26587 self.write_space();
26588 self.write_keyword("COMPOUND");
26589 }
26590 self.write_space();
26591 self.write_keyword("SORTKEY");
26592 self.write_space();
26593 if let Some(this) = &e.this {
26594 self.generate_expression(this)?;
26595 } else if !e.expressions.is_empty() {
26596 self.write("(");
26597 for (i, expr) in e.expressions.iter().enumerate() {
26598 if i > 0 {
26599 self.write(", ");
26600 }
26601 self.generate_expression(expr)?;
26602 }
26603 self.write(")");
26604 }
26605 Ok(())
26606 }
26607
26608 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
26609 self.write_keyword("ANALYZE");
26611 if !e.options.is_empty() {
26612 self.write_space();
26613 for (i, opt) in e.options.iter().enumerate() {
26614 if i > 0 {
26615 self.write_space();
26616 }
26617 if let Expression::Identifier(id) = opt {
26619 self.write_keyword(&id.name);
26620 } else {
26621 self.generate_expression(opt)?;
26622 }
26623 }
26624 }
26625 if let Some(kind) = &e.kind {
26626 self.write_space();
26627 self.write_keyword(kind);
26628 }
26629 if let Some(this) = &e.this {
26630 self.write_space();
26631 self.generate_expression(this)?;
26632 }
26633 if !e.columns.is_empty() {
26635 self.write("(");
26636 for (i, col) in e.columns.iter().enumerate() {
26637 if i > 0 {
26638 self.write(", ");
26639 }
26640 self.write(col);
26641 }
26642 self.write(")");
26643 }
26644 if let Some(partition) = &e.partition {
26645 self.write_space();
26646 self.generate_expression(partition)?;
26647 }
26648 if let Some(mode) = &e.mode {
26649 self.write_space();
26650 self.generate_expression(mode)?;
26651 }
26652 if let Some(expression) = &e.expression {
26653 self.write_space();
26654 self.generate_expression(expression)?;
26655 }
26656 if !e.properties.is_empty() {
26657 self.write_space();
26658 self.write_keyword(self.config.with_properties_prefix);
26659 self.write(" (");
26660 for (i, prop) in e.properties.iter().enumerate() {
26661 if i > 0 {
26662 self.write(", ");
26663 }
26664 self.generate_expression(prop)?;
26665 }
26666 self.write(")");
26667 }
26668 Ok(())
26669 }
26670
26671 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
26672 self.write_keyword("DELETE");
26674 if let Some(kind) = &e.kind {
26675 self.write_space();
26676 self.write_keyword(kind);
26677 }
26678 self.write_space();
26679 self.write_keyword("STATISTICS");
26680 Ok(())
26681 }
26682
26683 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
26684 if let Expression::Identifier(id) = e.this.as_ref() {
26687 self.write_keyword(&id.name);
26688 } else {
26689 self.generate_expression(&e.this)?;
26690 }
26691 self.write_space();
26692 self.write_keyword("HISTOGRAM ON");
26693 self.write_space();
26694 for (i, expr) in e.expressions.iter().enumerate() {
26695 if i > 0 {
26696 self.write(", ");
26697 }
26698 self.generate_expression(expr)?;
26699 }
26700 if let Some(expression) = &e.expression {
26701 self.write_space();
26702 self.generate_expression(expression)?;
26703 }
26704 if let Some(update_options) = &e.update_options {
26705 self.write_space();
26706 self.generate_expression(update_options)?;
26707 self.write_space();
26708 self.write_keyword("UPDATE");
26709 }
26710 Ok(())
26711 }
26712
26713 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
26714 self.write_keyword("LIST CHAINED ROWS");
26716 if let Some(expression) = &e.expression {
26717 self.write_space();
26718 self.write_keyword("INTO");
26719 self.write_space();
26720 self.generate_expression(expression)?;
26721 }
26722 Ok(())
26723 }
26724
26725 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
26726 self.write_keyword("SAMPLE");
26728 self.write_space();
26729 if let Some(sample) = &e.sample {
26730 self.generate_expression(sample)?;
26731 self.write_space();
26732 }
26733 self.write_keyword(&e.kind);
26734 Ok(())
26735 }
26736
26737 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
26738 self.write_keyword(&e.kind);
26740 if let Some(option) = &e.option {
26741 self.write_space();
26742 self.generate_expression(option)?;
26743 }
26744 self.write_space();
26745 self.write_keyword("STATISTICS");
26746 if let Some(this) = &e.this {
26747 self.write_space();
26748 self.generate_expression(this)?;
26749 }
26750 if !e.expressions.is_empty() {
26751 self.write_space();
26752 for (i, expr) in e.expressions.iter().enumerate() {
26753 if i > 0 {
26754 self.write(", ");
26755 }
26756 self.generate_expression(expr)?;
26757 }
26758 }
26759 Ok(())
26760 }
26761
26762 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
26763 self.write_keyword("VALIDATE");
26765 self.write_space();
26766 self.write_keyword(&e.kind);
26767 if let Some(this) = &e.this {
26768 self.write_space();
26769 if let Expression::Identifier(id) = this.as_ref() {
26771 self.write_keyword(&id.name);
26772 } else {
26773 self.generate_expression(this)?;
26774 }
26775 }
26776 if let Some(expression) = &e.expression {
26777 self.write_space();
26778 self.write_keyword("INTO");
26779 self.write_space();
26780 self.generate_expression(expression)?;
26781 }
26782 Ok(())
26783 }
26784
26785 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
26786 self.write_keyword("WITH");
26788 self.write_space();
26789 for (i, expr) in e.expressions.iter().enumerate() {
26790 if i > 0 {
26791 self.write(", ");
26792 }
26793 self.generate_expression(expr)?;
26794 }
26795 Ok(())
26796 }
26797
26798 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
26799 self.generate_expression(&e.this)?;
26802 self.write("(");
26803 for (i, arg) in e.expressions.iter().enumerate() {
26804 if i > 0 {
26805 self.write(", ");
26806 }
26807 self.generate_expression(arg)?;
26808 }
26809 self.write(")");
26810 Ok(())
26811 }
26812
26813 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
26814 self.generate_expression(&e.this)?;
26816 self.write("(");
26817 for (i, arg) in e.expressions.iter().enumerate() {
26818 if i > 0 {
26819 self.write(", ");
26820 }
26821 self.generate_expression(arg)?;
26822 }
26823 self.write(")");
26824 Ok(())
26825 }
26826
26827 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
26828 self.generate_expression(&e.this)?;
26830 self.write_space();
26831 self.write_keyword("APPLY");
26832 self.write("(");
26833 self.generate_expression(&e.expression)?;
26834 self.write(")");
26835 Ok(())
26836 }
26837
26838 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
26839 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
26841 self.write("(");
26842 self.generate_expression(&e.this)?;
26843 if let Some(percentile) = &e.percentile {
26844 self.write(", ");
26845 self.generate_expression(percentile)?;
26846 }
26847 self.write(")");
26848 Ok(())
26849 }
26850
26851 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
26852 self.write_keyword("APPROX_QUANTILE");
26854 self.write("(");
26855 self.generate_expression(&e.this)?;
26856 if let Some(quantile) = &e.quantile {
26857 self.write(", ");
26858 self.generate_expression(quantile)?;
26859 }
26860 if let Some(accuracy) = &e.accuracy {
26861 self.write(", ");
26862 self.generate_expression(accuracy)?;
26863 }
26864 if let Some(weight) = &e.weight {
26865 self.write(", ");
26866 self.generate_expression(weight)?;
26867 }
26868 self.write(")");
26869 Ok(())
26870 }
26871
26872 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
26873 self.write_keyword("APPROX_QUANTILES");
26875 self.write("(");
26876 self.generate_expression(&e.this)?;
26877 if let Some(expression) = &e.expression {
26878 self.write(", ");
26879 self.generate_expression(expression)?;
26880 }
26881 self.write(")");
26882 Ok(())
26883 }
26884
26885 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
26886 self.write_keyword("APPROX_TOP_K");
26888 self.write("(");
26889 self.generate_expression(&e.this)?;
26890 if let Some(expression) = &e.expression {
26891 self.write(", ");
26892 self.generate_expression(expression)?;
26893 }
26894 if let Some(counters) = &e.counters {
26895 self.write(", ");
26896 self.generate_expression(counters)?;
26897 }
26898 self.write(")");
26899 Ok(())
26900 }
26901
26902 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
26903 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
26905 self.write("(");
26906 self.generate_expression(&e.this)?;
26907 if let Some(expression) = &e.expression {
26908 self.write(", ");
26909 self.generate_expression(expression)?;
26910 }
26911 self.write(")");
26912 Ok(())
26913 }
26914
26915 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
26916 self.write_keyword("APPROX_TOP_K_COMBINE");
26918 self.write("(");
26919 self.generate_expression(&e.this)?;
26920 if let Some(expression) = &e.expression {
26921 self.write(", ");
26922 self.generate_expression(expression)?;
26923 }
26924 self.write(")");
26925 Ok(())
26926 }
26927
26928 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
26929 self.write_keyword("APPROX_TOP_K_ESTIMATE");
26931 self.write("(");
26932 self.generate_expression(&e.this)?;
26933 if let Some(expression) = &e.expression {
26934 self.write(", ");
26935 self.generate_expression(expression)?;
26936 }
26937 self.write(")");
26938 Ok(())
26939 }
26940
26941 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
26942 self.write_keyword("APPROX_TOP_SUM");
26944 self.write("(");
26945 self.generate_expression(&e.this)?;
26946 self.write(", ");
26947 self.generate_expression(&e.expression)?;
26948 if let Some(count) = &e.count {
26949 self.write(", ");
26950 self.generate_expression(count)?;
26951 }
26952 self.write(")");
26953 Ok(())
26954 }
26955
26956 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
26957 self.write_keyword("ARG_MAX");
26959 self.write("(");
26960 self.generate_expression(&e.this)?;
26961 self.write(", ");
26962 self.generate_expression(&e.expression)?;
26963 if let Some(count) = &e.count {
26964 self.write(", ");
26965 self.generate_expression(count)?;
26966 }
26967 self.write(")");
26968 Ok(())
26969 }
26970
26971 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
26972 self.write_keyword("ARG_MIN");
26974 self.write("(");
26975 self.generate_expression(&e.this)?;
26976 self.write(", ");
26977 self.generate_expression(&e.expression)?;
26978 if let Some(count) = &e.count {
26979 self.write(", ");
26980 self.generate_expression(count)?;
26981 }
26982 self.write(")");
26983 Ok(())
26984 }
26985
26986 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
26987 self.write_keyword("ARRAY_ALL");
26989 self.write("(");
26990 self.generate_expression(&e.this)?;
26991 self.write(", ");
26992 self.generate_expression(&e.expression)?;
26993 self.write(")");
26994 Ok(())
26995 }
26996
26997 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
26998 self.write_keyword("ARRAY_ANY");
27000 self.write("(");
27001 self.generate_expression(&e.this)?;
27002 self.write(", ");
27003 self.generate_expression(&e.expression)?;
27004 self.write(")");
27005 Ok(())
27006 }
27007
27008 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
27009 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
27011 self.write("(");
27012 for (i, expr) in e.expressions.iter().enumerate() {
27013 if i > 0 {
27014 self.write(", ");
27015 }
27016 self.generate_expression(expr)?;
27017 }
27018 self.write(")");
27019 Ok(())
27020 }
27021
27022 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
27023 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
27025 self.write("arraySum");
27026 } else {
27027 self.write_keyword("ARRAY_SUM");
27028 }
27029 self.write("(");
27030 self.generate_expression(&e.this)?;
27031 if let Some(expression) = &e.expression {
27032 self.write(", ");
27033 self.generate_expression(expression)?;
27034 }
27035 self.write(")");
27036 Ok(())
27037 }
27038
27039 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
27040 self.generate_expression(&e.this)?;
27042 self.write_space();
27043 self.write_keyword("AT");
27044 self.write_space();
27045 self.generate_expression(&e.expression)?;
27046 Ok(())
27047 }
27048
27049 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
27050 self.write_keyword("ATTACH");
27052 if e.exists {
27053 self.write_space();
27054 self.write_keyword("IF NOT EXISTS");
27055 }
27056 self.write_space();
27057 self.generate_expression(&e.this)?;
27058 if !e.expressions.is_empty() {
27059 self.write(" (");
27060 for (i, expr) in e.expressions.iter().enumerate() {
27061 if i > 0 {
27062 self.write(", ");
27063 }
27064 self.generate_expression(expr)?;
27065 }
27066 self.write(")");
27067 }
27068 Ok(())
27069 }
27070
27071 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
27072 self.generate_expression(&e.this)?;
27075 if let Some(expression) = &e.expression {
27076 self.write_space();
27077 self.generate_expression(expression)?;
27078 }
27079 Ok(())
27080 }
27081
27082 fn generate_auto_increment_keyword(
27086 &mut self,
27087 col: &crate::expressions::ColumnDef,
27088 ) -> Result<()> {
27089 use crate::dialects::DialectType;
27090 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
27091 self.write_keyword("IDENTITY");
27092 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
27093 self.write("(");
27094 if let Some(ref start) = col.auto_increment_start {
27095 self.generate_expression(start)?;
27096 } else {
27097 self.write("0");
27098 }
27099 self.write(", ");
27100 if let Some(ref inc) = col.auto_increment_increment {
27101 self.generate_expression(inc)?;
27102 } else {
27103 self.write("1");
27104 }
27105 self.write(")");
27106 }
27107 } else if matches!(
27108 self.config.dialect,
27109 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
27110 ) {
27111 self.write_keyword("AUTOINCREMENT");
27112 if let Some(ref start) = col.auto_increment_start {
27113 self.write_space();
27114 self.write_keyword("START");
27115 self.write_space();
27116 self.generate_expression(start)?;
27117 }
27118 if let Some(ref inc) = col.auto_increment_increment {
27119 self.write_space();
27120 self.write_keyword("INCREMENT");
27121 self.write_space();
27122 self.generate_expression(inc)?;
27123 }
27124 if let Some(order) = col.auto_increment_order {
27125 self.write_space();
27126 if order {
27127 self.write_keyword("ORDER");
27128 } else {
27129 self.write_keyword("NOORDER");
27130 }
27131 }
27132 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
27133 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
27134 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
27135 self.write(" (");
27136 let mut first = true;
27137 if let Some(ref start) = col.auto_increment_start {
27138 self.write_keyword("START WITH");
27139 self.write_space();
27140 self.generate_expression(start)?;
27141 first = false;
27142 }
27143 if let Some(ref inc) = col.auto_increment_increment {
27144 if !first {
27145 self.write_space();
27146 }
27147 self.write_keyword("INCREMENT BY");
27148 self.write_space();
27149 self.generate_expression(inc)?;
27150 }
27151 self.write(")");
27152 }
27153 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
27154 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
27157 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
27158 } else {
27159 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
27160 }
27161 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
27162 self.write(" (");
27163 let mut first = true;
27164 if let Some(ref start) = col.auto_increment_start {
27165 self.write_keyword("START WITH");
27166 self.write_space();
27167 self.generate_expression(start)?;
27168 first = false;
27169 }
27170 if let Some(ref inc) = col.auto_increment_increment {
27171 if !first {
27172 self.write_space();
27173 }
27174 self.write_keyword("INCREMENT BY");
27175 self.write_space();
27176 self.generate_expression(inc)?;
27177 }
27178 self.write(")");
27179 }
27180 } else if matches!(
27181 self.config.dialect,
27182 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27183 ) {
27184 self.write_keyword("IDENTITY");
27185 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
27186 self.write("(");
27187 if let Some(ref start) = col.auto_increment_start {
27188 self.generate_expression(start)?;
27189 } else {
27190 self.write("0");
27191 }
27192 self.write(", ");
27193 if let Some(ref inc) = col.auto_increment_increment {
27194 self.generate_expression(inc)?;
27195 } else {
27196 self.write("1");
27197 }
27198 self.write(")");
27199 }
27200 } else {
27201 self.write_keyword("AUTO_INCREMENT");
27202 if let Some(ref start) = col.auto_increment_start {
27203 self.write_space();
27204 self.write_keyword("START");
27205 self.write_space();
27206 self.generate_expression(start)?;
27207 }
27208 if let Some(ref inc) = col.auto_increment_increment {
27209 self.write_space();
27210 self.write_keyword("INCREMENT");
27211 self.write_space();
27212 self.generate_expression(inc)?;
27213 }
27214 if let Some(order) = col.auto_increment_order {
27215 self.write_space();
27216 if order {
27217 self.write_keyword("ORDER");
27218 } else {
27219 self.write_keyword("NOORDER");
27220 }
27221 }
27222 }
27223 Ok(())
27224 }
27225
27226 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
27227 self.write_keyword("AUTO_INCREMENT");
27229 self.write("=");
27230 self.generate_expression(&e.this)?;
27231 Ok(())
27232 }
27233
27234 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
27235 self.write_keyword("AUTO_REFRESH");
27237 self.write("=");
27238 self.generate_expression(&e.this)?;
27239 Ok(())
27240 }
27241
27242 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
27243 self.write_keyword("BACKUP");
27245 self.write_space();
27246 self.generate_expression(&e.this)?;
27247 Ok(())
27248 }
27249
27250 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
27251 self.write_keyword("BASE64_DECODE_BINARY");
27253 self.write("(");
27254 self.generate_expression(&e.this)?;
27255 if let Some(alphabet) = &e.alphabet {
27256 self.write(", ");
27257 self.generate_expression(alphabet)?;
27258 }
27259 self.write(")");
27260 Ok(())
27261 }
27262
27263 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
27264 self.write_keyword("BASE64_DECODE_STRING");
27266 self.write("(");
27267 self.generate_expression(&e.this)?;
27268 if let Some(alphabet) = &e.alphabet {
27269 self.write(", ");
27270 self.generate_expression(alphabet)?;
27271 }
27272 self.write(")");
27273 Ok(())
27274 }
27275
27276 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
27277 self.write_keyword("BASE64_ENCODE");
27279 self.write("(");
27280 self.generate_expression(&e.this)?;
27281 if let Some(max_line_length) = &e.max_line_length {
27282 self.write(", ");
27283 self.generate_expression(max_line_length)?;
27284 }
27285 if let Some(alphabet) = &e.alphabet {
27286 self.write(", ");
27287 self.generate_expression(alphabet)?;
27288 }
27289 self.write(")");
27290 Ok(())
27291 }
27292
27293 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
27294 self.write_keyword("BLOCKCOMPRESSION");
27296 self.write("=");
27297 if let Some(autotemp) = &e.autotemp {
27298 self.write_keyword("AUTOTEMP");
27299 self.write("(");
27300 self.generate_expression(autotemp)?;
27301 self.write(")");
27302 }
27303 if let Some(always) = &e.always {
27304 self.generate_expression(always)?;
27305 }
27306 if let Some(default) = &e.default {
27307 self.generate_expression(default)?;
27308 }
27309 if let Some(manual) = &e.manual {
27310 self.generate_expression(manual)?;
27311 }
27312 if let Some(never) = &e.never {
27313 self.generate_expression(never)?;
27314 }
27315 Ok(())
27316 }
27317
27318 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
27319 self.write("((");
27321 self.generate_expression(&e.this)?;
27322 self.write(") ");
27323 self.write_keyword("AND");
27324 self.write(" (");
27325 self.generate_expression(&e.expression)?;
27326 self.write("))");
27327 Ok(())
27328 }
27329
27330 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
27331 self.write("((");
27333 self.generate_expression(&e.this)?;
27334 self.write(") ");
27335 self.write_keyword("OR");
27336 self.write(" (");
27337 self.generate_expression(&e.expression)?;
27338 self.write("))");
27339 Ok(())
27340 }
27341
27342 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
27343 self.write_keyword("BUILD");
27345 self.write_space();
27346 self.generate_expression(&e.this)?;
27347 Ok(())
27348 }
27349
27350 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
27351 self.generate_expression(&e.this)?;
27353 Ok(())
27354 }
27355
27356 fn generate_case_specific_column_constraint(
27357 &mut self,
27358 e: &CaseSpecificColumnConstraint,
27359 ) -> Result<()> {
27360 if e.not_.is_some() {
27362 self.write_keyword("NOT");
27363 self.write_space();
27364 }
27365 self.write_keyword("CASESPECIFIC");
27366 Ok(())
27367 }
27368
27369 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
27370 self.write_keyword("CAST");
27372 self.write("(");
27373 self.generate_expression(&e.this)?;
27374 if self.config.dialect == Some(DialectType::ClickHouse) {
27375 self.write(", ");
27377 } else {
27378 self.write_space();
27379 self.write_keyword("AS");
27380 self.write_space();
27381 }
27382 if let Some(to) = &e.to {
27383 self.generate_expression(to)?;
27384 }
27385 self.write(")");
27386 Ok(())
27387 }
27388
27389 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
27390 self.write_keyword("CHANGES");
27393 self.write(" (");
27394 if let Some(information) = &e.information {
27395 self.write_keyword("INFORMATION");
27396 self.write(" => ");
27397 self.generate_expression(information)?;
27398 }
27399 self.write(")");
27400 if let Some(at_before) = &e.at_before {
27402 self.write(" ");
27403 self.generate_expression(at_before)?;
27404 }
27405 if let Some(end) = &e.end {
27406 self.write(" ");
27407 self.generate_expression(end)?;
27408 }
27409 Ok(())
27410 }
27411
27412 fn generate_character_set_column_constraint(
27413 &mut self,
27414 e: &CharacterSetColumnConstraint,
27415 ) -> Result<()> {
27416 self.write_keyword("CHARACTER SET");
27418 self.write_space();
27419 self.generate_expression(&e.this)?;
27420 Ok(())
27421 }
27422
27423 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
27424 if e.default.is_some() {
27426 self.write_keyword("DEFAULT");
27427 self.write_space();
27428 }
27429 self.write_keyword("CHARACTER SET");
27430 self.write("=");
27431 self.generate_expression(&e.this)?;
27432 Ok(())
27433 }
27434
27435 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
27436 self.write_keyword("CHECK");
27438 self.write(" (");
27439 self.generate_expression(&e.this)?;
27440 self.write(")");
27441 if e.enforced.is_some() {
27442 self.write_space();
27443 self.write_keyword("ENFORCED");
27444 }
27445 Ok(())
27446 }
27447
27448 fn generate_assume_column_constraint(&mut self, e: &AssumeColumnConstraint) -> Result<()> {
27449 self.write_keyword("ASSUME");
27451 self.write(" (");
27452 self.generate_expression(&e.this)?;
27453 self.write(")");
27454 Ok(())
27455 }
27456
27457 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
27458 self.write_keyword("CHECK_JSON");
27460 self.write("(");
27461 self.generate_expression(&e.this)?;
27462 self.write(")");
27463 Ok(())
27464 }
27465
27466 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
27467 self.write_keyword("CHECK_XML");
27469 self.write("(");
27470 self.generate_expression(&e.this)?;
27471 self.write(")");
27472 Ok(())
27473 }
27474
27475 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
27476 self.write_keyword("CHECKSUM");
27478 self.write("=");
27479 if e.on.is_some() {
27480 self.write_keyword("ON");
27481 } else if e.default.is_some() {
27482 self.write_keyword("DEFAULT");
27483 } else {
27484 self.write_keyword("OFF");
27485 }
27486 Ok(())
27487 }
27488
27489 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
27490 if e.shallow.is_some() {
27492 self.write_keyword("SHALLOW");
27493 self.write_space();
27494 }
27495 if e.copy.is_some() {
27496 self.write_keyword("COPY");
27497 } else {
27498 self.write_keyword("CLONE");
27499 }
27500 self.write_space();
27501 self.generate_expression(&e.this)?;
27502 Ok(())
27503 }
27504
27505 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
27506 self.write_keyword("CLUSTER BY");
27508 self.write(" (");
27509 for (i, ord) in e.expressions.iter().enumerate() {
27510 if i > 0 {
27511 self.write(", ");
27512 }
27513 self.generate_ordered(ord)?;
27514 }
27515 self.write(")");
27516 Ok(())
27517 }
27518
27519 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
27520 self.write_keyword("CLUSTER BY");
27522 self.write_space();
27523 for (i, col) in e.columns.iter().enumerate() {
27524 if i > 0 {
27525 self.write(", ");
27526 }
27527 self.generate_identifier(col)?;
27528 }
27529 Ok(())
27530 }
27531
27532 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
27533 self.write_keyword("CLUSTERED BY");
27535 self.write(" (");
27536 for (i, expr) in e.expressions.iter().enumerate() {
27537 if i > 0 {
27538 self.write(", ");
27539 }
27540 self.generate_expression(expr)?;
27541 }
27542 self.write(")");
27543 if let Some(sorted_by) = &e.sorted_by {
27544 self.write_space();
27545 self.write_keyword("SORTED BY");
27546 self.write(" (");
27547 if let Expression::Tuple(t) = sorted_by.as_ref() {
27549 for (i, expr) in t.expressions.iter().enumerate() {
27550 if i > 0 {
27551 self.write(", ");
27552 }
27553 self.generate_expression(expr)?;
27554 }
27555 } else {
27556 self.generate_expression(sorted_by)?;
27557 }
27558 self.write(")");
27559 }
27560 if let Some(buckets) = &e.buckets {
27561 self.write_space();
27562 self.write_keyword("INTO");
27563 self.write_space();
27564 self.generate_expression(buckets)?;
27565 self.write_space();
27566 self.write_keyword("BUCKETS");
27567 }
27568 Ok(())
27569 }
27570
27571 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
27572 if e.default.is_some() {
27576 self.write_keyword("DEFAULT");
27577 self.write_space();
27578 }
27579 self.write_keyword("COLLATE");
27580 match self.config.dialect {
27582 Some(DialectType::BigQuery) => self.write_space(),
27583 _ => self.write("="),
27584 }
27585 self.generate_expression(&e.this)?;
27586 Ok(())
27587 }
27588
27589 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
27590 match e {
27592 ColumnConstraint::NotNull => {
27593 self.write_keyword("NOT NULL");
27594 }
27595 ColumnConstraint::Null => {
27596 self.write_keyword("NULL");
27597 }
27598 ColumnConstraint::Unique => {
27599 self.write_keyword("UNIQUE");
27600 }
27601 ColumnConstraint::PrimaryKey => {
27602 self.write_keyword("PRIMARY KEY");
27603 }
27604 ColumnConstraint::Default(expr) => {
27605 self.write_keyword("DEFAULT");
27606 self.write_space();
27607 self.generate_expression(expr)?;
27608 }
27609 ColumnConstraint::Check(expr) => {
27610 self.write_keyword("CHECK");
27611 self.write(" (");
27612 self.generate_expression(expr)?;
27613 self.write(")");
27614 }
27615 ColumnConstraint::References(fk_ref) => {
27616 if fk_ref.has_foreign_key_keywords {
27617 self.write_keyword("FOREIGN KEY");
27618 self.write_space();
27619 }
27620 self.write_keyword("REFERENCES");
27621 self.write_space();
27622 self.generate_table(&fk_ref.table)?;
27623 if !fk_ref.columns.is_empty() {
27624 self.write(" (");
27625 for (i, col) in fk_ref.columns.iter().enumerate() {
27626 if i > 0 {
27627 self.write(", ");
27628 }
27629 self.generate_identifier(col)?;
27630 }
27631 self.write(")");
27632 }
27633 }
27634 ColumnConstraint::GeneratedAsIdentity(gen) => {
27635 self.write_keyword("GENERATED");
27636 self.write_space();
27637 if gen.always {
27638 self.write_keyword("ALWAYS");
27639 } else {
27640 self.write_keyword("BY DEFAULT");
27641 if gen.on_null {
27642 self.write_space();
27643 self.write_keyword("ON NULL");
27644 }
27645 }
27646 self.write_space();
27647 self.write_keyword("AS IDENTITY");
27648 }
27649 ColumnConstraint::Collate(collation) => {
27650 self.write_keyword("COLLATE");
27651 self.write_space();
27652 self.generate_identifier(collation)?;
27653 }
27654 ColumnConstraint::Comment(comment) => {
27655 self.write_keyword("COMMENT");
27656 self.write(" '");
27657 self.write(comment);
27658 self.write("'");
27659 }
27660 ColumnConstraint::ComputedColumn(cc) => {
27661 self.generate_computed_column_inline(cc)?;
27662 }
27663 ColumnConstraint::GeneratedAsRow(gar) => {
27664 self.generate_generated_as_row_inline(gar)?;
27665 }
27666 ColumnConstraint::Tags(tags) => {
27667 self.write_keyword("TAG");
27668 self.write(" (");
27669 for (i, expr) in tags.expressions.iter().enumerate() {
27670 if i > 0 {
27671 self.write(", ");
27672 }
27673 self.generate_expression(expr)?;
27674 }
27675 self.write(")");
27676 }
27677 ColumnConstraint::Path(path_expr) => {
27678 self.write_keyword("PATH");
27679 self.write_space();
27680 self.generate_expression(path_expr)?;
27681 }
27682 }
27683 Ok(())
27684 }
27685
27686 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
27687 match e {
27689 ColumnPosition::First => {
27690 self.write_keyword("FIRST");
27691 }
27692 ColumnPosition::After(ident) => {
27693 self.write_keyword("AFTER");
27694 self.write_space();
27695 self.generate_identifier(ident)?;
27696 }
27697 }
27698 Ok(())
27699 }
27700
27701 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
27702 self.generate_expression(&e.this)?;
27704 self.write("(");
27705 self.generate_expression(&e.expression)?;
27706 self.write(")");
27707 Ok(())
27708 }
27709
27710 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
27711 if let Some(ref unpack) = e.unpack {
27714 if let Expression::Boolean(b) = unpack.as_ref() {
27715 if b.value {
27716 self.write("*");
27717 }
27718 }
27719 }
27720 self.write_keyword("COLUMNS");
27721 self.write("(");
27722 self.generate_expression(&e.this)?;
27723 self.write(")");
27724 Ok(())
27725 }
27726
27727 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
27728 self.generate_expression(&e.this)?;
27730 self.write("(");
27731 for (i, expr) in e.expressions.iter().enumerate() {
27732 if i > 0 {
27733 self.write(", ");
27734 }
27735 self.generate_expression(expr)?;
27736 }
27737 self.write(")");
27738 Ok(())
27739 }
27740
27741 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
27742 self.generate_expression(&e.this)?;
27744 self.write("(");
27745 for (i, param) in e.params.iter().enumerate() {
27746 if i > 0 {
27747 self.write(", ");
27748 }
27749 self.generate_expression(param)?;
27750 }
27751 self.write(")(");
27752 for (i, expr) in e.expressions.iter().enumerate() {
27753 if i > 0 {
27754 self.write(", ");
27755 }
27756 self.generate_expression(expr)?;
27757 }
27758 self.write(")");
27759 Ok(())
27760 }
27761
27762 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
27763 self.write_keyword("COMMIT");
27765
27766 if e.this.is_none()
27768 && matches!(
27769 self.config.dialect,
27770 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27771 )
27772 {
27773 self.write_space();
27774 self.write_keyword("TRANSACTION");
27775 }
27776
27777 if let Some(this) = &e.this {
27779 let is_transaction_marker = matches!(
27781 this.as_ref(),
27782 Expression::Identifier(id) if id.name == "TRANSACTION"
27783 );
27784
27785 self.write_space();
27786 self.write_keyword("TRANSACTION");
27787
27788 if !is_transaction_marker {
27790 self.write_space();
27791 self.generate_expression(this)?;
27792 }
27793 }
27794
27795 if let Some(durability) = &e.durability {
27797 self.write_space();
27798 self.write_keyword("WITH");
27799 self.write(" (");
27800 self.write_keyword("DELAYED_DURABILITY");
27801 self.write(" = ");
27802 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
27803 self.write_keyword("ON");
27804 } else {
27805 self.write_keyword("OFF");
27806 }
27807 self.write(")");
27808 }
27809
27810 if let Some(chain) = &e.chain {
27812 self.write_space();
27813 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
27814 self.write_keyword("AND NO CHAIN");
27815 } else {
27816 self.write_keyword("AND CHAIN");
27817 }
27818 }
27819 Ok(())
27820 }
27821
27822 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
27823 self.write("[");
27825 self.generate_expression(&e.this)?;
27826 self.write_space();
27827 self.write_keyword("FOR");
27828 self.write_space();
27829 self.generate_expression(&e.expression)?;
27830 if let Some(pos) = &e.position {
27832 self.write(", ");
27833 self.generate_expression(pos)?;
27834 }
27835 if let Some(iterator) = &e.iterator {
27836 self.write_space();
27837 self.write_keyword("IN");
27838 self.write_space();
27839 self.generate_expression(iterator)?;
27840 }
27841 if let Some(condition) = &e.condition {
27842 self.write_space();
27843 self.write_keyword("IF");
27844 self.write_space();
27845 self.generate_expression(condition)?;
27846 }
27847 self.write("]");
27848 Ok(())
27849 }
27850
27851 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
27852 self.write_keyword("COMPRESS");
27854 self.write("(");
27855 self.generate_expression(&e.this)?;
27856 if let Some(method) = &e.method {
27857 self.write(", '");
27858 self.write(method);
27859 self.write("'");
27860 }
27861 self.write(")");
27862 Ok(())
27863 }
27864
27865 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
27866 self.write_keyword("COMPRESS");
27868 if let Some(this) = &e.this {
27869 self.write_space();
27870 self.generate_expression(this)?;
27871 }
27872 Ok(())
27873 }
27874
27875 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
27876 self.write_keyword("AS");
27878 self.write_space();
27879 self.generate_expression(&e.this)?;
27880 if e.not_null.is_some() {
27881 self.write_space();
27882 self.write_keyword("PERSISTED NOT NULL");
27883 } else if e.persisted.is_some() {
27884 self.write_space();
27885 self.write_keyword("PERSISTED");
27886 }
27887 Ok(())
27888 }
27889
27890 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
27894 let computed_expr = if matches!(
27895 self.config.dialect,
27896 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27897 ) {
27898 match &*cc.expression {
27899 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
27900 {
27901 let wrapped = Expression::Cast(Box::new(Cast {
27902 this: y.this.clone(),
27903 to: DataType::Date,
27904 trailing_comments: Vec::new(),
27905 double_colon_syntax: false,
27906 format: None,
27907 default: None,
27908 inferred_type: None,
27909 }));
27910 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
27911 }
27912 Expression::Function(f)
27913 if f.name.eq_ignore_ascii_case("YEAR")
27914 && f.args.len() == 1
27915 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
27916 {
27917 let wrapped = Expression::Cast(Box::new(Cast {
27918 this: f.args[0].clone(),
27919 to: DataType::Date,
27920 trailing_comments: Vec::new(),
27921 double_colon_syntax: false,
27922 format: None,
27923 default: None,
27924 inferred_type: None,
27925 }));
27926 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
27927 }
27928 _ => *cc.expression.clone(),
27929 }
27930 } else {
27931 *cc.expression.clone()
27932 };
27933
27934 match cc.persistence_kind.as_deref() {
27935 Some("STORED") | Some("VIRTUAL") => {
27936 self.write_keyword("GENERATED ALWAYS AS");
27938 self.write(" (");
27939 self.generate_expression(&computed_expr)?;
27940 self.write(")");
27941 self.write_space();
27942 if cc.persisted {
27943 self.write_keyword("STORED");
27944 } else {
27945 self.write_keyword("VIRTUAL");
27946 }
27947 }
27948 Some("PERSISTED") => {
27949 self.write_keyword("AS");
27951 self.write(" (");
27952 self.generate_expression(&computed_expr)?;
27953 self.write(")");
27954 self.write_space();
27955 self.write_keyword("PERSISTED");
27956 if let Some(ref dt) = cc.data_type {
27958 self.write_space();
27959 self.generate_data_type(dt)?;
27960 }
27961 if cc.not_null {
27962 self.write_space();
27963 self.write_keyword("NOT NULL");
27964 }
27965 }
27966 _ => {
27967 if matches!(
27970 self.config.dialect,
27971 Some(DialectType::Spark)
27972 | Some(DialectType::Databricks)
27973 | Some(DialectType::Hive)
27974 ) {
27975 self.write_keyword("GENERATED ALWAYS AS");
27976 self.write(" (");
27977 self.generate_expression(&computed_expr)?;
27978 self.write(")");
27979 } else if matches!(
27980 self.config.dialect,
27981 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27982 ) {
27983 self.write_keyword("AS");
27984 let omit_parens = matches!(computed_expr, Expression::Year(_))
27985 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
27986 if omit_parens {
27987 self.write_space();
27988 self.generate_expression(&computed_expr)?;
27989 } else {
27990 self.write(" (");
27991 self.generate_expression(&computed_expr)?;
27992 self.write(")");
27993 }
27994 } else {
27995 self.write_keyword("AS");
27996 self.write(" (");
27997 self.generate_expression(&computed_expr)?;
27998 self.write(")");
27999 }
28000 }
28001 }
28002 Ok(())
28003 }
28004
28005 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
28008 self.write_keyword("GENERATED ALWAYS AS ROW ");
28009 if gar.start {
28010 self.write_keyword("START");
28011 } else {
28012 self.write_keyword("END");
28013 }
28014 if gar.hidden {
28015 self.write_space();
28016 self.write_keyword("HIDDEN");
28017 }
28018 Ok(())
28019 }
28020
28021 fn generate_system_versioning_content(
28023 &mut self,
28024 e: &WithSystemVersioningProperty,
28025 ) -> Result<()> {
28026 let mut parts = Vec::new();
28027
28028 if let Some(this) = &e.this {
28029 let mut s = String::from("HISTORY_TABLE=");
28030 let mut gen = Generator::with_arc_config(self.config.clone());
28031 gen.generate_expression(this)?;
28032 s.push_str(&gen.output);
28033 parts.push(s);
28034 }
28035
28036 if let Some(data_consistency) = &e.data_consistency {
28037 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
28038 let mut gen = Generator::with_arc_config(self.config.clone());
28039 gen.generate_expression(data_consistency)?;
28040 s.push_str(&gen.output);
28041 parts.push(s);
28042 }
28043
28044 if let Some(retention_period) = &e.retention_period {
28045 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
28046 let mut gen = Generator::with_arc_config(self.config.clone());
28047 gen.generate_expression(retention_period)?;
28048 s.push_str(&gen.output);
28049 parts.push(s);
28050 }
28051
28052 self.write_keyword("SYSTEM_VERSIONING");
28053 self.write("=");
28054
28055 if !parts.is_empty() {
28056 self.write_keyword("ON");
28057 self.write("(");
28058 self.write(&parts.join(", "));
28059 self.write(")");
28060 } else if e.on.is_some() {
28061 self.write_keyword("ON");
28062 } else {
28063 self.write_keyword("OFF");
28064 }
28065
28066 Ok(())
28067 }
28068
28069 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
28070 if e.else_.is_some() {
28073 self.write_keyword("ELSE");
28074 self.write_space();
28075 } else if let Some(expression) = &e.expression {
28076 self.write_keyword("WHEN");
28077 self.write_space();
28078 self.generate_expression(expression)?;
28079 self.write_space();
28080 self.write_keyword("THEN");
28081 self.write_space();
28082 }
28083
28084 if let Expression::Insert(insert) = e.this.as_ref() {
28087 self.write_keyword("INTO");
28088 self.write_space();
28089 self.generate_table(&insert.table)?;
28090
28091 if !insert.columns.is_empty() {
28093 self.write(" (");
28094 for (i, col) in insert.columns.iter().enumerate() {
28095 if i > 0 {
28096 self.write(", ");
28097 }
28098 self.generate_identifier(col)?;
28099 }
28100 self.write(")");
28101 }
28102
28103 if !insert.values.is_empty() {
28105 self.write_space();
28106 self.write_keyword("VALUES");
28107 for (row_idx, row) in insert.values.iter().enumerate() {
28108 if row_idx > 0 {
28109 self.write(", ");
28110 }
28111 self.write(" (");
28112 for (i, val) in row.iter().enumerate() {
28113 if i > 0 {
28114 self.write(", ");
28115 }
28116 self.generate_expression(val)?;
28117 }
28118 self.write(")");
28119 }
28120 }
28121 } else {
28122 self.generate_expression(&e.this)?;
28124 }
28125 Ok(())
28126 }
28127
28128 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
28129 self.write_keyword("CONSTRAINT");
28131 self.write_space();
28132 self.generate_expression(&e.this)?;
28133 if !e.expressions.is_empty() {
28134 self.write_space();
28135 for (i, expr) in e.expressions.iter().enumerate() {
28136 if i > 0 {
28137 self.write_space();
28138 }
28139 self.generate_expression(expr)?;
28140 }
28141 }
28142 Ok(())
28143 }
28144
28145 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
28146 self.write_keyword("CONVERT_TIMEZONE");
28148 self.write("(");
28149 let mut first = true;
28150 if let Some(source_tz) = &e.source_tz {
28151 self.generate_expression(source_tz)?;
28152 first = false;
28153 }
28154 if let Some(target_tz) = &e.target_tz {
28155 if !first {
28156 self.write(", ");
28157 }
28158 self.generate_expression(target_tz)?;
28159 first = false;
28160 }
28161 if let Some(timestamp) = &e.timestamp {
28162 if !first {
28163 self.write(", ");
28164 }
28165 self.generate_expression(timestamp)?;
28166 }
28167 self.write(")");
28168 Ok(())
28169 }
28170
28171 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
28172 self.write_keyword("CONVERT");
28174 self.write("(");
28175 self.generate_expression(&e.this)?;
28176 if let Some(dest) = &e.dest {
28177 self.write_space();
28178 self.write_keyword("USING");
28179 self.write_space();
28180 self.generate_expression(dest)?;
28181 }
28182 self.write(")");
28183 Ok(())
28184 }
28185
28186 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
28187 self.write_keyword("COPY");
28188 if e.is_into {
28189 self.write_space();
28190 self.write_keyword("INTO");
28191 }
28192 self.write_space();
28193
28194 if let Expression::Literal(lit) = &e.this {
28196 if let Literal::String(s) = lit.as_ref() {
28197 if s.starts_with('@') {
28198 self.write(s);
28199 } else {
28200 self.generate_expression(&e.this)?;
28201 }
28202 }
28203 } else {
28204 self.generate_expression(&e.this)?;
28205 }
28206
28207 if e.kind {
28209 if self.config.pretty {
28211 self.write_newline();
28212 } else {
28213 self.write_space();
28214 }
28215 self.write_keyword("FROM");
28216 self.write_space();
28217 } else if !e.files.is_empty() {
28218 if self.config.pretty {
28220 self.write_newline();
28221 } else {
28222 self.write_space();
28223 }
28224 self.write_keyword("TO");
28225 self.write_space();
28226 }
28227
28228 for (i, file) in e.files.iter().enumerate() {
28230 if i > 0 {
28231 self.write_space();
28232 }
28233 if let Expression::Literal(lit) = file {
28235 if let Literal::String(s) = lit.as_ref() {
28236 if s.starts_with('@') {
28237 self.write(s);
28238 } else {
28239 self.generate_expression(file)?;
28240 }
28241 }
28242 } else if let Expression::Identifier(id) = file {
28243 if id.quoted {
28245 self.write("`");
28246 self.write(&id.name);
28247 self.write("`");
28248 } else {
28249 self.generate_expression(file)?;
28250 }
28251 } else {
28252 self.generate_expression(file)?;
28253 }
28254 }
28255
28256 if !e.with_wrapped {
28258 if let Some(ref creds) = e.credentials {
28259 if let Some(ref storage) = creds.storage {
28260 if self.config.pretty {
28261 self.write_newline();
28262 } else {
28263 self.write_space();
28264 }
28265 self.write_keyword("STORAGE_INTEGRATION");
28266 self.write(" = ");
28267 self.write(storage);
28268 }
28269 if creds.credentials.is_empty() {
28270 if self.config.pretty {
28272 self.write_newline();
28273 } else {
28274 self.write_space();
28275 }
28276 self.write_keyword("CREDENTIALS");
28277 self.write(" = ()");
28278 } else {
28279 if self.config.pretty {
28280 self.write_newline();
28281 } else {
28282 self.write_space();
28283 }
28284 self.write_keyword("CREDENTIALS");
28285 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
28288 self.write(" '");
28290 self.write(&creds.credentials[0].1);
28291 self.write("'");
28292 } else {
28293 self.write(" = (");
28295 for (i, (k, v)) in creds.credentials.iter().enumerate() {
28296 if i > 0 {
28297 self.write_space();
28298 }
28299 self.write(k);
28300 self.write("='");
28301 self.write(v);
28302 self.write("'");
28303 }
28304 self.write(")");
28305 }
28306 }
28307 if let Some(ref encryption) = creds.encryption {
28308 self.write_space();
28309 self.write_keyword("ENCRYPTION");
28310 self.write(" = ");
28311 self.write(encryption);
28312 }
28313 }
28314 }
28315
28316 if !e.params.is_empty() {
28318 if e.with_wrapped {
28319 self.write_space();
28321 self.write_keyword("WITH");
28322 self.write(" (");
28323 for (i, param) in e.params.iter().enumerate() {
28324 if i > 0 {
28325 self.write(", ");
28326 }
28327 self.generate_copy_param_with_format(param)?;
28328 }
28329 self.write(")");
28330 } else {
28331 for param in &e.params {
28335 if self.config.pretty {
28336 self.write_newline();
28337 } else {
28338 self.write_space();
28339 }
28340 self.write(¶m.name);
28342 if let Some(ref value) = param.value {
28343 if param.eq {
28345 self.write(" = ");
28346 } else {
28347 self.write(" ");
28348 }
28349 if !param.values.is_empty() {
28350 self.write("(");
28351 for (i, v) in param.values.iter().enumerate() {
28352 if i > 0 {
28353 self.write_space();
28354 }
28355 self.generate_copy_nested_param(v)?;
28356 }
28357 self.write(")");
28358 } else {
28359 self.generate_copy_param_value(value)?;
28361 }
28362 } else if !param.values.is_empty() {
28363 if param.eq {
28365 self.write(" = (");
28366 } else {
28367 self.write(" (");
28368 }
28369 let is_key_value_pairs = param
28374 .values
28375 .first()
28376 .map_or(false, |v| matches!(v, Expression::Eq(_)));
28377 let sep = if is_key_value_pairs && param.eq {
28378 " "
28379 } else {
28380 ", "
28381 };
28382 for (i, v) in param.values.iter().enumerate() {
28383 if i > 0 {
28384 self.write(sep);
28385 }
28386 self.generate_copy_nested_param(v)?;
28387 }
28388 self.write(")");
28389 }
28390 }
28391 }
28392 }
28393
28394 Ok(())
28395 }
28396
28397 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
28400 self.write_keyword(¶m.name);
28401 if !param.values.is_empty() {
28402 self.write(" = (");
28404 for (i, v) in param.values.iter().enumerate() {
28405 if i > 0 {
28406 self.write(", ");
28407 }
28408 self.generate_copy_nested_param(v)?;
28409 }
28410 self.write(")");
28411 } else if let Some(ref value) = param.value {
28412 if param.eq {
28413 self.write(" = ");
28414 } else {
28415 self.write(" ");
28416 }
28417 self.generate_expression(value)?;
28418 }
28419 Ok(())
28420 }
28421
28422 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
28424 match expr {
28425 Expression::Eq(eq) => {
28426 match &eq.left {
28428 Expression::Column(c) => self.write(&c.name.name),
28429 _ => self.generate_expression(&eq.left)?,
28430 }
28431 self.write("=");
28432 match &eq.right {
28434 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
28435 let Literal::String(s) = lit.as_ref() else {
28436 unreachable!()
28437 };
28438 self.write("'");
28439 self.write(s);
28440 self.write("'");
28441 }
28442 Expression::Tuple(t) => {
28443 self.write("(");
28445 if self.config.pretty {
28446 self.write_newline();
28447 self.indent_level += 1;
28448 for (i, item) in t.expressions.iter().enumerate() {
28449 if i > 0 {
28450 self.write(", ");
28451 }
28452 self.write_indent();
28453 self.generate_expression(item)?;
28454 }
28455 self.write_newline();
28456 self.indent_level -= 1;
28457 } else {
28458 for (i, item) in t.expressions.iter().enumerate() {
28459 if i > 0 {
28460 self.write(", ");
28461 }
28462 self.generate_expression(item)?;
28463 }
28464 }
28465 self.write(")");
28466 }
28467 _ => self.generate_expression(&eq.right)?,
28468 }
28469 Ok(())
28470 }
28471 Expression::Column(c) => {
28472 self.write(&c.name.name);
28474 Ok(())
28475 }
28476 _ => self.generate_expression(expr),
28477 }
28478 }
28479
28480 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
28483 match expr {
28484 Expression::Column(c) => {
28485 if c.name.quoted {
28487 self.write("\"");
28488 self.write(&c.name.name);
28489 self.write("\"");
28490 } else {
28491 self.write(&c.name.name);
28492 }
28493 Ok(())
28494 }
28495 Expression::Identifier(id) => {
28496 if id.quoted {
28498 self.write("\"");
28499 self.write(&id.name);
28500 self.write("\"");
28501 } else {
28502 self.write(&id.name);
28503 }
28504 Ok(())
28505 }
28506 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
28507 let Literal::String(s) = lit.as_ref() else {
28508 unreachable!()
28509 };
28510 self.write("'");
28512 self.write(s);
28513 self.write("'");
28514 Ok(())
28515 }
28516 _ => self.generate_expression(expr),
28517 }
28518 }
28519
28520 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
28521 self.write_keyword(&e.name);
28522 if let Some(ref value) = e.value {
28523 if e.eq {
28524 self.write(" = ");
28525 } else {
28526 self.write(" ");
28527 }
28528 self.generate_expression(value)?;
28529 }
28530 if !e.values.is_empty() {
28531 if e.eq {
28532 self.write(" = ");
28533 } else {
28534 self.write(" ");
28535 }
28536 self.write("(");
28537 for (i, v) in e.values.iter().enumerate() {
28538 if i > 0 {
28539 self.write(", ");
28540 }
28541 self.generate_expression(v)?;
28542 }
28543 self.write(")");
28544 }
28545 Ok(())
28546 }
28547
28548 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
28549 self.write_keyword("CORR");
28551 self.write("(");
28552 self.generate_expression(&e.this)?;
28553 self.write(", ");
28554 self.generate_expression(&e.expression)?;
28555 self.write(")");
28556 Ok(())
28557 }
28558
28559 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
28560 self.write_keyword("COSINE_DISTANCE");
28562 self.write("(");
28563 self.generate_expression(&e.this)?;
28564 self.write(", ");
28565 self.generate_expression(&e.expression)?;
28566 self.write(")");
28567 Ok(())
28568 }
28569
28570 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
28571 self.write_keyword("COVAR_POP");
28573 self.write("(");
28574 self.generate_expression(&e.this)?;
28575 self.write(", ");
28576 self.generate_expression(&e.expression)?;
28577 self.write(")");
28578 Ok(())
28579 }
28580
28581 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
28582 self.write_keyword("COVAR_SAMP");
28584 self.write("(");
28585 self.generate_expression(&e.this)?;
28586 self.write(", ");
28587 self.generate_expression(&e.expression)?;
28588 self.write(")");
28589 Ok(())
28590 }
28591
28592 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
28593 self.write_keyword("CREDENTIALS");
28595 self.write(" (");
28596 for (i, (key, value)) in e.credentials.iter().enumerate() {
28597 if i > 0 {
28598 self.write(", ");
28599 }
28600 self.write(key);
28601 self.write("='");
28602 self.write(value);
28603 self.write("'");
28604 }
28605 self.write(")");
28606 Ok(())
28607 }
28608
28609 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
28610 self.write_keyword("CREDENTIALS");
28612 self.write("=(");
28613 for (i, expr) in e.expressions.iter().enumerate() {
28614 if i > 0 {
28615 self.write(", ");
28616 }
28617 self.generate_expression(expr)?;
28618 }
28619 self.write(")");
28620 Ok(())
28621 }
28622
28623 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
28624 use crate::dialects::DialectType;
28625
28626 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
28629 self.generate_expression(&e.this)?;
28630 self.write_space();
28631 self.write_keyword("AS");
28632 self.write_space();
28633 self.generate_identifier(&e.alias)?;
28634 return Ok(());
28635 }
28636 self.write(&e.alias.name);
28637
28638 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
28640
28641 if !e.columns.is_empty() && !skip_cte_columns {
28642 self.write("(");
28643 for (i, col) in e.columns.iter().enumerate() {
28644 if i > 0 {
28645 self.write(", ");
28646 }
28647 self.write(&col.name);
28648 }
28649 self.write(")");
28650 }
28651 if !e.key_expressions.is_empty() {
28653 self.write_space();
28654 self.write_keyword("USING KEY");
28655 self.write(" (");
28656 for (i, key) in e.key_expressions.iter().enumerate() {
28657 if i > 0 {
28658 self.write(", ");
28659 }
28660 self.write(&key.name);
28661 }
28662 self.write(")");
28663 }
28664 self.write_space();
28665 self.write_keyword("AS");
28666 self.write_space();
28667 if let Some(materialized) = e.materialized {
28668 if materialized {
28669 self.write_keyword("MATERIALIZED");
28670 } else {
28671 self.write_keyword("NOT MATERIALIZED");
28672 }
28673 self.write_space();
28674 }
28675 self.write("(");
28676 self.generate_expression(&e.this)?;
28677 self.write(")");
28678 Ok(())
28679 }
28680
28681 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
28682 if e.expressions.is_empty() {
28684 self.write_keyword("WITH CUBE");
28685 } else {
28686 self.write_keyword("CUBE");
28687 self.write("(");
28688 for (i, expr) in e.expressions.iter().enumerate() {
28689 if i > 0 {
28690 self.write(", ");
28691 }
28692 self.generate_expression(expr)?;
28693 }
28694 self.write(")");
28695 }
28696 Ok(())
28697 }
28698
28699 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
28700 self.write_keyword("CURRENT_DATETIME");
28702 if let Some(this) = &e.this {
28703 self.write("(");
28704 self.generate_expression(this)?;
28705 self.write(")");
28706 }
28707 Ok(())
28708 }
28709
28710 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
28711 self.write_keyword("CURRENT_SCHEMA");
28713 Ok(())
28714 }
28715
28716 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
28717 self.write_keyword("CURRENT_SCHEMAS");
28719 self.write("(");
28720 if !matches!(
28722 self.config.dialect,
28723 Some(crate::dialects::DialectType::Snowflake)
28724 ) {
28725 if let Some(this) = &e.this {
28726 self.generate_expression(this)?;
28727 }
28728 }
28729 self.write(")");
28730 Ok(())
28731 }
28732
28733 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
28734 self.write_keyword("CURRENT_USER");
28736 let needs_parens = e.this.is_some()
28738 || matches!(
28739 self.config.dialect,
28740 Some(DialectType::Snowflake)
28741 | Some(DialectType::Spark)
28742 | Some(DialectType::Hive)
28743 | Some(DialectType::DuckDB)
28744 | Some(DialectType::BigQuery)
28745 | Some(DialectType::MySQL)
28746 | Some(DialectType::Databricks)
28747 );
28748 if needs_parens {
28749 self.write("()");
28750 }
28751 Ok(())
28752 }
28753
28754 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
28755 if self.config.dialect == Some(DialectType::Solr) {
28757 self.generate_expression(&e.this)?;
28758 self.write(" ");
28759 self.write_keyword("OR");
28760 self.write(" ");
28761 self.generate_expression(&e.expression)?;
28762 } else if self.config.dialect == Some(DialectType::MySQL) {
28763 self.generate_mysql_concat_from_dpipe(e)?;
28764 } else {
28765 self.generate_expression(&e.this)?;
28767 self.write(" || ");
28768 self.generate_expression(&e.expression)?;
28769 }
28770 Ok(())
28771 }
28772
28773 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
28774 self.write_keyword("DATABLOCKSIZE");
28776 self.write("=");
28777 if let Some(size) = e.size {
28778 self.write(&size.to_string());
28779 if let Some(units) = &e.units {
28780 self.write_space();
28781 self.generate_expression(units)?;
28782 }
28783 } else if e.minimum.is_some() {
28784 self.write_keyword("MINIMUM");
28785 } else if e.maximum.is_some() {
28786 self.write_keyword("MAXIMUM");
28787 } else if e.default.is_some() {
28788 self.write_keyword("DEFAULT");
28789 }
28790 Ok(())
28791 }
28792
28793 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
28794 self.write_keyword("DATA_DELETION");
28796 self.write("=");
28797
28798 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
28799 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
28800
28801 if is_on {
28802 self.write_keyword("ON");
28803 if has_options {
28804 self.write("(");
28805 let mut first = true;
28806 if let Some(filter_column) = &e.filter_column {
28807 self.write_keyword("FILTER_COLUMN");
28808 self.write("=");
28809 self.generate_expression(filter_column)?;
28810 first = false;
28811 }
28812 if let Some(retention_period) = &e.retention_period {
28813 if !first {
28814 self.write(", ");
28815 }
28816 self.write_keyword("RETENTION_PERIOD");
28817 self.write("=");
28818 self.generate_expression(retention_period)?;
28819 }
28820 self.write(")");
28821 }
28822 } else {
28823 self.write_keyword("OFF");
28824 }
28825 Ok(())
28826 }
28827
28828 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
28832 use crate::dialects::DialectType;
28833 use crate::expressions::Literal;
28834
28835 match self.config.dialect {
28836 Some(DialectType::Exasol) => {
28838 self.write_keyword("TO_DATE");
28839 self.write("(");
28840 match &e.this {
28842 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
28843 let Literal::String(s) = lit.as_ref() else {
28844 unreachable!()
28845 };
28846 self.write("'");
28847 self.write(s);
28848 self.write("'");
28849 }
28850 _ => {
28851 self.generate_expression(&e.this)?;
28852 }
28853 }
28854 self.write(")");
28855 }
28856 _ => {
28858 self.write_keyword("DATE");
28859 self.write("(");
28860 self.generate_expression(&e.this)?;
28861 self.write(")");
28862 }
28863 }
28864 Ok(())
28865 }
28866
28867 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
28868 self.write_keyword("DATE_BIN");
28870 self.write("(");
28871 self.generate_expression(&e.this)?;
28872 self.write(", ");
28873 self.generate_expression(&e.expression)?;
28874 if let Some(origin) = &e.origin {
28875 self.write(", ");
28876 self.generate_expression(origin)?;
28877 }
28878 self.write(")");
28879 Ok(())
28880 }
28881
28882 fn generate_date_format_column_constraint(
28883 &mut self,
28884 e: &DateFormatColumnConstraint,
28885 ) -> Result<()> {
28886 self.write_keyword("FORMAT");
28888 self.write_space();
28889 self.generate_expression(&e.this)?;
28890 Ok(())
28891 }
28892
28893 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
28894 self.write_keyword("DATE_FROM_PARTS");
28896 self.write("(");
28897 let mut first = true;
28898 if let Some(year) = &e.year {
28899 self.generate_expression(year)?;
28900 first = false;
28901 }
28902 if let Some(month) = &e.month {
28903 if !first {
28904 self.write(", ");
28905 }
28906 self.generate_expression(month)?;
28907 first = false;
28908 }
28909 if let Some(day) = &e.day {
28910 if !first {
28911 self.write(", ");
28912 }
28913 self.generate_expression(day)?;
28914 }
28915 self.write(")");
28916 Ok(())
28917 }
28918
28919 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
28920 self.write_keyword("DATETIME");
28922 self.write("(");
28923 self.generate_expression(&e.this)?;
28924 if let Some(expr) = &e.expression {
28925 self.write(", ");
28926 self.generate_expression(expr)?;
28927 }
28928 self.write(")");
28929 Ok(())
28930 }
28931
28932 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
28933 self.write_keyword("DATETIME_ADD");
28935 self.write("(");
28936 self.generate_expression(&e.this)?;
28937 self.write(", ");
28938 self.generate_expression(&e.expression)?;
28939 if let Some(unit) = &e.unit {
28940 self.write(", ");
28941 self.write_keyword(unit);
28942 }
28943 self.write(")");
28944 Ok(())
28945 }
28946
28947 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
28948 self.write_keyword("DATETIME_DIFF");
28950 self.write("(");
28951 self.generate_expression(&e.this)?;
28952 self.write(", ");
28953 self.generate_expression(&e.expression)?;
28954 if let Some(unit) = &e.unit {
28955 self.write(", ");
28956 self.write_keyword(unit);
28957 }
28958 self.write(")");
28959 Ok(())
28960 }
28961
28962 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
28963 self.write_keyword("DATETIME_SUB");
28965 self.write("(");
28966 self.generate_expression(&e.this)?;
28967 self.write(", ");
28968 self.generate_expression(&e.expression)?;
28969 if let Some(unit) = &e.unit {
28970 self.write(", ");
28971 self.write_keyword(unit);
28972 }
28973 self.write(")");
28974 Ok(())
28975 }
28976
28977 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
28978 self.write_keyword("DATETIME_TRUNC");
28980 self.write("(");
28981 self.generate_expression(&e.this)?;
28982 self.write(", ");
28983 self.write_keyword(&e.unit);
28984 if let Some(zone) = &e.zone {
28985 self.write(", ");
28986 self.generate_expression(zone)?;
28987 }
28988 self.write(")");
28989 Ok(())
28990 }
28991
28992 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
28993 self.write_keyword("DAYNAME");
28995 self.write("(");
28996 self.generate_expression(&e.this)?;
28997 self.write(")");
28998 Ok(())
28999 }
29000
29001 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
29002 self.write_keyword("DECLARE");
29004 self.write_space();
29005 if e.replace {
29006 self.write_keyword("OR");
29007 self.write_space();
29008 self.write_keyword("REPLACE");
29009 self.write_space();
29010 }
29011 for (i, expr) in e.expressions.iter().enumerate() {
29012 if i > 0 {
29013 self.write(", ");
29014 }
29015 self.generate_expression(expr)?;
29016 }
29017 Ok(())
29018 }
29019
29020 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
29021 use crate::dialects::DialectType;
29022
29023 self.generate_expression(&e.this)?;
29025 for name in &e.additional_names {
29027 self.write(", ");
29028 self.generate_expression(name)?;
29029 }
29030 if let Some(kind) = &e.kind {
29031 self.write_space();
29032 match self.config.dialect {
29036 Some(DialectType::BigQuery) => {
29037 self.write(kind);
29038 }
29039 Some(DialectType::TSQL) => {
29040 let is_complex_table = kind.starts_with("TABLE")
29044 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
29045 if is_complex_table {
29046 self.write(kind);
29047 } else if kind == "INT" {
29048 self.write("INTEGER");
29049 } else if kind.starts_with("TABLE") {
29050 let normalized = kind
29052 .replace(" INT ", " INTEGER ")
29053 .replace(" INT,", " INTEGER,")
29054 .replace(" INT)", " INTEGER)")
29055 .replace("(INT ", "(INTEGER ");
29056 self.write(&normalized);
29057 } else {
29058 self.write(kind);
29059 }
29060 }
29061 _ => {
29062 if e.has_as {
29063 self.write_keyword("AS");
29064 self.write_space();
29065 }
29066 self.write(kind);
29067 }
29068 }
29069 }
29070 if let Some(default) = &e.default {
29071 match self.config.dialect {
29073 Some(DialectType::BigQuery) => {
29074 self.write_space();
29075 self.write_keyword("DEFAULT");
29076 self.write_space();
29077 }
29078 _ => {
29079 self.write(" = ");
29080 }
29081 }
29082 self.generate_expression(default)?;
29083 }
29084 Ok(())
29085 }
29086
29087 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
29088 self.write_keyword("DECODE");
29090 self.write("(");
29091 for (i, expr) in e.expressions.iter().enumerate() {
29092 if i > 0 {
29093 self.write(", ");
29094 }
29095 self.generate_expression(expr)?;
29096 }
29097 self.write(")");
29098 Ok(())
29099 }
29100
29101 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
29102 self.write_keyword("DECOMPRESS");
29104 self.write("(");
29105 self.generate_expression(&e.this)?;
29106 self.write(", '");
29107 self.write(&e.method);
29108 self.write("')");
29109 Ok(())
29110 }
29111
29112 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
29113 self.write_keyword("DECOMPRESS");
29115 self.write("(");
29116 self.generate_expression(&e.this)?;
29117 self.write(", '");
29118 self.write(&e.method);
29119 self.write("')");
29120 Ok(())
29121 }
29122
29123 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
29124 self.write_keyword("DECRYPT");
29126 self.write("(");
29127 self.generate_expression(&e.this)?;
29128 if let Some(passphrase) = &e.passphrase {
29129 self.write(", ");
29130 self.generate_expression(passphrase)?;
29131 }
29132 if let Some(aad) = &e.aad {
29133 self.write(", ");
29134 self.generate_expression(aad)?;
29135 }
29136 if let Some(method) = &e.encryption_method {
29137 self.write(", ");
29138 self.generate_expression(method)?;
29139 }
29140 self.write(")");
29141 Ok(())
29142 }
29143
29144 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
29145 self.write_keyword("DECRYPT_RAW");
29147 self.write("(");
29148 self.generate_expression(&e.this)?;
29149 if let Some(key) = &e.key {
29150 self.write(", ");
29151 self.generate_expression(key)?;
29152 }
29153 if let Some(iv) = &e.iv {
29154 self.write(", ");
29155 self.generate_expression(iv)?;
29156 }
29157 if let Some(aad) = &e.aad {
29158 self.write(", ");
29159 self.generate_expression(aad)?;
29160 }
29161 if let Some(method) = &e.encryption_method {
29162 self.write(", ");
29163 self.generate_expression(method)?;
29164 }
29165 self.write(")");
29166 Ok(())
29167 }
29168
29169 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
29170 self.write_keyword("DEFINER");
29172 self.write(" = ");
29173 self.generate_expression(&e.this)?;
29174 Ok(())
29175 }
29176
29177 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
29178 self.write_keyword("DETACH");
29180 if e.exists {
29181 self.write_keyword(" DATABASE IF EXISTS");
29182 }
29183 self.write_space();
29184 self.generate_expression(&e.this)?;
29185 Ok(())
29186 }
29187
29188 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
29189 let property_name = match e.this.as_ref() {
29190 Expression::Identifier(id) => id.name.as_str(),
29191 Expression::Var(v) => v.this.as_str(),
29192 _ => "DICTIONARY",
29193 };
29194 self.write_keyword(property_name);
29195 self.write("(");
29196 self.write(&e.kind);
29197 if let Some(settings) = &e.settings {
29198 self.write("(");
29199 if let Expression::Tuple(t) = settings.as_ref() {
29200 if self.config.pretty && !t.expressions.is_empty() {
29201 self.write_newline();
29202 self.indent_level += 1;
29203 for (i, pair) in t.expressions.iter().enumerate() {
29204 if i > 0 {
29205 self.write(",");
29206 self.write_newline();
29207 }
29208 self.write_indent();
29209 if let Expression::Tuple(pair_tuple) = pair {
29210 if let Some(k) = pair_tuple.expressions.first() {
29211 self.generate_expression(k)?;
29212 }
29213 if let Some(v) = pair_tuple.expressions.get(1) {
29214 self.write(" ");
29215 self.generate_expression(v)?;
29216 }
29217 } else {
29218 self.generate_expression(pair)?;
29219 }
29220 }
29221 self.indent_level -= 1;
29222 self.write_newline();
29223 self.write_indent();
29224 } else {
29225 for (i, pair) in t.expressions.iter().enumerate() {
29226 if i > 0 {
29227 self.write(" ");
29229 }
29230 if let Expression::Tuple(pair_tuple) = pair {
29231 if let Some(k) = pair_tuple.expressions.first() {
29232 self.generate_expression(k)?;
29233 }
29234 if let Some(v) = pair_tuple.expressions.get(1) {
29235 self.write(" ");
29236 self.generate_expression(v)?;
29237 }
29238 } else {
29239 self.generate_expression(pair)?;
29240 }
29241 }
29242 }
29243 } else {
29244 self.generate_expression(settings)?;
29245 }
29246 self.write(")");
29247 } else {
29248 self.write("()");
29250 }
29251 self.write(")");
29252 Ok(())
29253 }
29254
29255 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
29256 let property_name = match e.this.as_ref() {
29257 Expression::Identifier(id) => id.name.as_str(),
29258 Expression::Var(v) => v.this.as_str(),
29259 _ => "RANGE",
29260 };
29261 self.write_keyword(property_name);
29262 self.write("(");
29263 if let Some(min) = &e.min {
29264 self.write_keyword("MIN");
29265 self.write_space();
29266 self.generate_expression(min)?;
29267 }
29268 if let Some(max) = &e.max {
29269 self.write_space();
29270 self.write_keyword("MAX");
29271 self.write_space();
29272 self.generate_expression(max)?;
29273 }
29274 self.write(")");
29275 Ok(())
29276 }
29277
29278 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
29279 if e.local.is_some() {
29281 self.write_keyword("LOCAL ");
29282 }
29283 self.write_keyword("DIRECTORY");
29284 self.write_space();
29285 self.generate_expression(&e.this)?;
29286 if let Some(row_format) = &e.row_format {
29287 self.write_space();
29288 self.generate_expression(row_format)?;
29289 }
29290 Ok(())
29291 }
29292
29293 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
29294 self.write_keyword("DISTKEY");
29296 self.write("(");
29297 self.generate_expression(&e.this)?;
29298 self.write(")");
29299 Ok(())
29300 }
29301
29302 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
29303 self.write_keyword("DISTSTYLE");
29305 self.write_space();
29306 self.generate_expression(&e.this)?;
29307 Ok(())
29308 }
29309
29310 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
29311 self.write_keyword("DISTRIBUTE BY");
29313 self.write_space();
29314 for (i, expr) in e.expressions.iter().enumerate() {
29315 if i > 0 {
29316 self.write(", ");
29317 }
29318 self.generate_expression(expr)?;
29319 }
29320 Ok(())
29321 }
29322
29323 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
29324 self.write_keyword("DISTRIBUTED BY");
29326 self.write_space();
29327 self.write(&e.kind);
29328 if !e.expressions.is_empty() {
29329 self.write(" (");
29330 for (i, expr) in e.expressions.iter().enumerate() {
29331 if i > 0 {
29332 self.write(", ");
29333 }
29334 self.generate_expression(expr)?;
29335 }
29336 self.write(")");
29337 }
29338 if let Some(buckets) = &e.buckets {
29339 self.write_space();
29340 self.write_keyword("BUCKETS");
29341 self.write_space();
29342 self.generate_expression(buckets)?;
29343 }
29344 if let Some(order) = &e.order {
29345 self.write_space();
29346 self.generate_expression(order)?;
29347 }
29348 Ok(())
29349 }
29350
29351 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
29352 self.write_keyword("DOT_PRODUCT");
29354 self.write("(");
29355 self.generate_expression(&e.this)?;
29356 self.write(", ");
29357 self.generate_expression(&e.expression)?;
29358 self.write(")");
29359 Ok(())
29360 }
29361
29362 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
29363 self.write_keyword("DROP");
29365 if e.exists {
29366 self.write_keyword(" IF EXISTS ");
29367 } else {
29368 self.write_space();
29369 }
29370 for (i, expr) in e.expressions.iter().enumerate() {
29371 if i > 0 {
29372 self.write(", ");
29373 }
29374 self.generate_expression(expr)?;
29375 }
29376 Ok(())
29377 }
29378
29379 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
29380 self.write_keyword("DUPLICATE KEY");
29382 self.write(" (");
29383 for (i, expr) in e.expressions.iter().enumerate() {
29384 if i > 0 {
29385 self.write(", ");
29386 }
29387 self.generate_expression(expr)?;
29388 }
29389 self.write(")");
29390 Ok(())
29391 }
29392
29393 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
29394 self.write_keyword("ELT");
29396 self.write("(");
29397 self.generate_expression(&e.this)?;
29398 for expr in &e.expressions {
29399 self.write(", ");
29400 self.generate_expression(expr)?;
29401 }
29402 self.write(")");
29403 Ok(())
29404 }
29405
29406 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
29407 self.write_keyword("ENCODE");
29409 self.write("(");
29410 self.generate_expression(&e.this)?;
29411 if let Some(charset) = &e.charset {
29412 self.write(", ");
29413 self.generate_expression(charset)?;
29414 }
29415 self.write(")");
29416 Ok(())
29417 }
29418
29419 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
29420 if e.key.is_some() {
29422 self.write_keyword("KEY ");
29423 }
29424 self.write_keyword("ENCODE");
29425 self.write_space();
29426 self.generate_expression(&e.this)?;
29427 if !e.properties.is_empty() {
29428 self.write(" (");
29429 for (i, prop) in e.properties.iter().enumerate() {
29430 if i > 0 {
29431 self.write(", ");
29432 }
29433 self.generate_expression(prop)?;
29434 }
29435 self.write(")");
29436 }
29437 Ok(())
29438 }
29439
29440 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
29441 self.write_keyword("ENCRYPT");
29443 self.write("(");
29444 self.generate_expression(&e.this)?;
29445 if let Some(passphrase) = &e.passphrase {
29446 self.write(", ");
29447 self.generate_expression(passphrase)?;
29448 }
29449 if let Some(aad) = &e.aad {
29450 self.write(", ");
29451 self.generate_expression(aad)?;
29452 }
29453 if let Some(method) = &e.encryption_method {
29454 self.write(", ");
29455 self.generate_expression(method)?;
29456 }
29457 self.write(")");
29458 Ok(())
29459 }
29460
29461 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
29462 self.write_keyword("ENCRYPT_RAW");
29464 self.write("(");
29465 self.generate_expression(&e.this)?;
29466 if let Some(key) = &e.key {
29467 self.write(", ");
29468 self.generate_expression(key)?;
29469 }
29470 if let Some(iv) = &e.iv {
29471 self.write(", ");
29472 self.generate_expression(iv)?;
29473 }
29474 if let Some(aad) = &e.aad {
29475 self.write(", ");
29476 self.generate_expression(aad)?;
29477 }
29478 if let Some(method) = &e.encryption_method {
29479 self.write(", ");
29480 self.generate_expression(method)?;
29481 }
29482 self.write(")");
29483 Ok(())
29484 }
29485
29486 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
29487 self.write_keyword("ENGINE");
29489 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
29490 self.write("=");
29491 } else {
29492 self.write(" = ");
29493 }
29494 self.generate_expression(&e.this)?;
29495 Ok(())
29496 }
29497
29498 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
29499 self.write_keyword("ENVIRONMENT");
29501 self.write(" (");
29502 for (i, expr) in e.expressions.iter().enumerate() {
29503 if i > 0 {
29504 self.write(", ");
29505 }
29506 self.generate_expression(expr)?;
29507 }
29508 self.write(")");
29509 Ok(())
29510 }
29511
29512 fn generate_ephemeral_column_constraint(
29513 &mut self,
29514 e: &EphemeralColumnConstraint,
29515 ) -> Result<()> {
29516 self.write_keyword("EPHEMERAL");
29518 if let Some(this) = &e.this {
29519 self.write_space();
29520 self.generate_expression(this)?;
29521 }
29522 Ok(())
29523 }
29524
29525 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
29526 self.write_keyword("EQUAL_NULL");
29528 self.write("(");
29529 self.generate_expression(&e.this)?;
29530 self.write(", ");
29531 self.generate_expression(&e.expression)?;
29532 self.write(")");
29533 Ok(())
29534 }
29535
29536 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
29537 use crate::dialects::DialectType;
29538
29539 match self.config.dialect {
29541 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
29542 self.generate_expression(&e.this)?;
29543 self.write(" <-> ");
29544 self.generate_expression(&e.expression)?;
29545 }
29546 _ => {
29547 self.write_keyword("EUCLIDEAN_DISTANCE");
29549 self.write("(");
29550 self.generate_expression(&e.this)?;
29551 self.write(", ");
29552 self.generate_expression(&e.expression)?;
29553 self.write(")");
29554 }
29555 }
29556 Ok(())
29557 }
29558
29559 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
29560 self.write_keyword("EXECUTE AS");
29562 self.write_space();
29563 self.generate_expression(&e.this)?;
29564 Ok(())
29565 }
29566
29567 fn generate_export(&mut self, e: &Export) -> Result<()> {
29568 self.write_keyword("EXPORT DATA");
29570 if let Some(connection) = &e.connection {
29571 self.write_space();
29572 self.write_keyword("WITH CONNECTION");
29573 self.write_space();
29574 self.generate_expression(connection)?;
29575 }
29576 if !e.options.is_empty() {
29577 self.write_space();
29578 self.generate_options_clause(&e.options)?;
29579 }
29580 self.write_space();
29581 self.write_keyword("AS");
29582 self.write_space();
29583 self.generate_expression(&e.this)?;
29584 Ok(())
29585 }
29586
29587 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
29588 self.write_keyword("EXTERNAL");
29590 if let Some(this) = &e.this {
29591 self.write_space();
29592 self.generate_expression(this)?;
29593 }
29594 Ok(())
29595 }
29596
29597 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
29598 if e.no.is_some() {
29600 self.write_keyword("NO ");
29601 }
29602 self.write_keyword("FALLBACK");
29603 if e.protection.is_some() {
29604 self.write_keyword(" PROTECTION");
29605 }
29606 Ok(())
29607 }
29608
29609 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
29610 self.write_keyword("FARM_FINGERPRINT");
29612 self.write("(");
29613 for (i, expr) in e.expressions.iter().enumerate() {
29614 if i > 0 {
29615 self.write(", ");
29616 }
29617 self.generate_expression(expr)?;
29618 }
29619 self.write(")");
29620 Ok(())
29621 }
29622
29623 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
29624 self.write_keyword("FEATURES_AT_TIME");
29626 self.write("(");
29627 self.generate_expression(&e.this)?;
29628 if let Some(time) = &e.time {
29629 self.write(", ");
29630 self.generate_expression(time)?;
29631 }
29632 if let Some(num_rows) = &e.num_rows {
29633 self.write(", ");
29634 self.generate_expression(num_rows)?;
29635 }
29636 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
29637 self.write(", ");
29638 self.generate_expression(ignore_nulls)?;
29639 }
29640 self.write(")");
29641 Ok(())
29642 }
29643
29644 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
29645 let use_limit = !e.percent
29647 && !e.with_ties
29648 && e.count.is_some()
29649 && matches!(
29650 self.config.dialect,
29651 Some(DialectType::Spark)
29652 | Some(DialectType::Hive)
29653 | Some(DialectType::DuckDB)
29654 | Some(DialectType::SQLite)
29655 | Some(DialectType::MySQL)
29656 | Some(DialectType::BigQuery)
29657 | Some(DialectType::Databricks)
29658 | Some(DialectType::StarRocks)
29659 | Some(DialectType::Doris)
29660 | Some(DialectType::Athena)
29661 | Some(DialectType::ClickHouse)
29662 );
29663
29664 if use_limit {
29665 self.write_keyword("LIMIT");
29666 self.write_space();
29667 self.generate_expression(e.count.as_ref().unwrap())?;
29668 return Ok(());
29669 }
29670
29671 self.write_keyword("FETCH");
29673 if !e.direction.is_empty() {
29674 self.write_space();
29675 self.write_keyword(&e.direction);
29676 }
29677 if let Some(count) = &e.count {
29678 self.write_space();
29679 self.generate_expression(count)?;
29680 }
29681 if e.percent {
29683 self.write_keyword(" PERCENT");
29684 }
29685 if e.rows {
29686 self.write_keyword(" ROWS");
29687 }
29688 if e.with_ties {
29689 self.write_keyword(" WITH TIES");
29690 } else if e.rows {
29691 self.write_keyword(" ONLY");
29692 } else {
29693 self.write_keyword(" ROWS ONLY");
29694 }
29695 Ok(())
29696 }
29697
29698 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
29699 if e.hive_format.is_some() {
29703 self.write_keyword("STORED AS");
29705 self.write_space();
29706 if let Some(this) = &e.this {
29707 if let Expression::Identifier(id) = this.as_ref() {
29709 self.write_keyword(&id.name.to_ascii_uppercase());
29710 } else {
29711 self.generate_expression(this)?;
29712 }
29713 }
29714 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
29715 self.write_keyword("STORED AS");
29717 self.write_space();
29718 if let Some(this) = &e.this {
29719 if let Expression::Identifier(id) = this.as_ref() {
29720 self.write_keyword(&id.name.to_ascii_uppercase());
29721 } else {
29722 self.generate_expression(this)?;
29723 }
29724 }
29725 } else if matches!(
29726 self.config.dialect,
29727 Some(DialectType::Spark) | Some(DialectType::Databricks)
29728 ) {
29729 self.write_keyword("USING");
29731 self.write_space();
29732 if let Some(this) = &e.this {
29733 self.generate_expression(this)?;
29734 }
29735 } else {
29736 self.write_keyword("FILE_FORMAT");
29738 self.write(" = ");
29739 if let Some(this) = &e.this {
29740 self.generate_expression(this)?;
29741 } else if !e.expressions.is_empty() {
29742 self.write("(");
29743 for (i, expr) in e.expressions.iter().enumerate() {
29744 if i > 0 {
29745 self.write(", ");
29746 }
29747 self.generate_expression(expr)?;
29748 }
29749 self.write(")");
29750 }
29751 }
29752 Ok(())
29753 }
29754
29755 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
29756 self.generate_expression(&e.this)?;
29758 self.write_space();
29759 self.write_keyword("FILTER");
29760 self.write("(");
29761 self.write_keyword("WHERE");
29762 self.write_space();
29763 self.generate_expression(&e.expression)?;
29764 self.write(")");
29765 Ok(())
29766 }
29767
29768 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
29769 self.write_keyword("FLOAT64");
29771 self.write("(");
29772 self.generate_expression(&e.this)?;
29773 if let Some(expr) = &e.expression {
29774 self.write(", ");
29775 self.generate_expression(expr)?;
29776 }
29777 self.write(")");
29778 Ok(())
29779 }
29780
29781 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
29782 self.write_keyword("FOR");
29784 self.write_space();
29785 self.generate_expression(&e.this)?;
29786 self.write_space();
29787 self.write_keyword("DO");
29788 self.write_space();
29789 self.generate_expression(&e.expression)?;
29790 Ok(())
29791 }
29792
29793 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
29794 self.write_keyword("FOREIGN KEY");
29796 if !e.expressions.is_empty() {
29797 self.write(" (");
29798 for (i, expr) in e.expressions.iter().enumerate() {
29799 if i > 0 {
29800 self.write(", ");
29801 }
29802 self.generate_expression(expr)?;
29803 }
29804 self.write(")");
29805 }
29806 if let Some(reference) = &e.reference {
29807 self.write_space();
29808 self.generate_expression(reference)?;
29809 }
29810 if let Some(delete) = &e.delete {
29811 self.write_space();
29812 self.write_keyword("ON DELETE");
29813 self.write_space();
29814 self.generate_expression(delete)?;
29815 }
29816 if let Some(update) = &e.update {
29817 self.write_space();
29818 self.write_keyword("ON UPDATE");
29819 self.write_space();
29820 self.generate_expression(update)?;
29821 }
29822 if !e.options.is_empty() {
29823 self.write_space();
29824 for (i, opt) in e.options.iter().enumerate() {
29825 if i > 0 {
29826 self.write_space();
29827 }
29828 self.generate_expression(opt)?;
29829 }
29830 }
29831 Ok(())
29832 }
29833
29834 fn generate_format(&mut self, e: &Format) -> Result<()> {
29835 self.write_keyword("FORMAT");
29837 self.write("(");
29838 self.generate_expression(&e.this)?;
29839 for expr in &e.expressions {
29840 self.write(", ");
29841 self.generate_expression(expr)?;
29842 }
29843 self.write(")");
29844 Ok(())
29845 }
29846
29847 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
29848 self.generate_expression(&e.this)?;
29850 self.write(" (");
29851 self.write_keyword("FORMAT");
29852 self.write(" '");
29853 self.write(&e.format);
29854 self.write("')");
29855 Ok(())
29856 }
29857
29858 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
29859 self.write_keyword("FREESPACE");
29861 self.write("=");
29862 self.generate_expression(&e.this)?;
29863 if e.percent.is_some() {
29864 self.write_keyword(" PERCENT");
29865 }
29866 Ok(())
29867 }
29868
29869 fn generate_from(&mut self, e: &From) -> Result<()> {
29870 self.write_keyword("FROM");
29872 self.write_space();
29873
29874 use crate::dialects::DialectType;
29878 let has_tablesample = e
29879 .expressions
29880 .iter()
29881 .any(|expr| matches!(expr, Expression::TableSample(_)));
29882 let is_cross_join_dialect = matches!(
29883 self.config.dialect,
29884 Some(DialectType::BigQuery)
29885 | Some(DialectType::Hive)
29886 | Some(DialectType::Spark)
29887 | Some(DialectType::Databricks)
29888 | Some(DialectType::SQLite)
29889 | Some(DialectType::ClickHouse)
29890 );
29891 let source_is_same_as_target2 = self.config.source_dialect.is_some()
29892 && self.config.source_dialect == self.config.dialect;
29893 let source_is_cross_join_dialect2 = matches!(
29894 self.config.source_dialect,
29895 Some(DialectType::BigQuery)
29896 | Some(DialectType::Hive)
29897 | Some(DialectType::Spark)
29898 | Some(DialectType::Databricks)
29899 | Some(DialectType::SQLite)
29900 | Some(DialectType::ClickHouse)
29901 );
29902 let use_cross_join = !has_tablesample
29903 && is_cross_join_dialect
29904 && (source_is_same_as_target2
29905 || source_is_cross_join_dialect2
29906 || self.config.source_dialect.is_none());
29907
29908 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
29910
29911 for (i, expr) in e.expressions.iter().enumerate() {
29912 if i > 0 {
29913 if use_cross_join {
29914 self.write(" CROSS JOIN ");
29915 } else {
29916 self.write(", ");
29917 }
29918 }
29919 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
29920 self.write("(");
29921 self.generate_expression(expr)?;
29922 self.write(")");
29923 } else {
29924 self.generate_expression(expr)?;
29925 }
29926 let leading = Self::extract_table_leading_comments(expr);
29929 for comment in &leading {
29930 self.write_space();
29931 self.write_formatted_comment(comment);
29932 }
29933 }
29934 Ok(())
29935 }
29936
29937 fn extract_table_leading_comments(expr: &Expression) -> Vec<String> {
29939 match expr {
29940 Expression::Table(t) => t.leading_comments.clone(),
29941 Expression::Pivot(p) => {
29942 if let Expression::Table(t) = &p.this {
29943 t.leading_comments.clone()
29944 } else {
29945 Vec::new()
29946 }
29947 }
29948 _ => Vec::new(),
29949 }
29950 }
29951
29952 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
29953 self.write_keyword("FROM_BASE");
29955 self.write("(");
29956 self.generate_expression(&e.this)?;
29957 self.write(", ");
29958 self.generate_expression(&e.expression)?;
29959 self.write(")");
29960 Ok(())
29961 }
29962
29963 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
29964 self.generate_expression(&e.this)?;
29966 if let Some(zone) = &e.zone {
29967 self.write_space();
29968 self.write_keyword("AT TIME ZONE");
29969 self.write_space();
29970 self.generate_expression(zone)?;
29971 self.write_space();
29972 self.write_keyword("AT TIME ZONE");
29973 self.write(" 'UTC'");
29974 }
29975 Ok(())
29976 }
29977
29978 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
29979 self.write_keyword("GAP_FILL");
29981 self.write("(");
29982 self.generate_expression(&e.this)?;
29983 if let Some(ts_column) = &e.ts_column {
29984 self.write(", ");
29985 self.generate_expression(ts_column)?;
29986 }
29987 if let Some(bucket_width) = &e.bucket_width {
29988 self.write(", ");
29989 self.generate_expression(bucket_width)?;
29990 }
29991 if let Some(partitioning_columns) = &e.partitioning_columns {
29992 self.write(", ");
29993 self.generate_expression(partitioning_columns)?;
29994 }
29995 if let Some(value_columns) = &e.value_columns {
29996 self.write(", ");
29997 self.generate_expression(value_columns)?;
29998 }
29999 self.write(")");
30000 Ok(())
30001 }
30002
30003 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
30004 self.write_keyword("GENERATE_DATE_ARRAY");
30006 self.write("(");
30007 let mut first = true;
30008 if let Some(start) = &e.start {
30009 self.generate_expression(start)?;
30010 first = false;
30011 }
30012 if let Some(end) = &e.end {
30013 if !first {
30014 self.write(", ");
30015 }
30016 self.generate_expression(end)?;
30017 first = false;
30018 }
30019 if let Some(step) = &e.step {
30020 if !first {
30021 self.write(", ");
30022 }
30023 self.generate_expression(step)?;
30024 }
30025 self.write(")");
30026 Ok(())
30027 }
30028
30029 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
30030 self.write_keyword("ML.GENERATE_EMBEDDING");
30032 self.write("(");
30033 self.generate_expression(&e.this)?;
30034 self.write(", ");
30035 self.generate_expression(&e.expression)?;
30036 if let Some(params) = &e.params_struct {
30037 self.write(", ");
30038 self.generate_expression(params)?;
30039 }
30040 self.write(")");
30041 Ok(())
30042 }
30043
30044 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
30045 let fn_name = match self.config.dialect {
30047 Some(DialectType::Presto)
30048 | Some(DialectType::Trino)
30049 | Some(DialectType::Athena)
30050 | Some(DialectType::Spark)
30051 | Some(DialectType::Databricks)
30052 | Some(DialectType::Hive) => "SEQUENCE",
30053 _ => "GENERATE_SERIES",
30054 };
30055 self.write_keyword(fn_name);
30056 self.write("(");
30057 let mut first = true;
30058 if let Some(start) = &e.start {
30059 self.generate_expression(start)?;
30060 first = false;
30061 }
30062 if let Some(end) = &e.end {
30063 if !first {
30064 self.write(", ");
30065 }
30066 self.generate_expression(end)?;
30067 first = false;
30068 }
30069 if let Some(step) = &e.step {
30070 if !first {
30071 self.write(", ");
30072 }
30073 if matches!(
30076 self.config.dialect,
30077 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
30078 ) {
30079 if let Some(converted) = self.convert_week_interval_to_day(step) {
30080 self.generate_expression(&converted)?;
30081 } else {
30082 self.generate_expression(step)?;
30083 }
30084 } else {
30085 self.generate_expression(step)?;
30086 }
30087 }
30088 self.write(")");
30089 Ok(())
30090 }
30091
30092 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
30095 use crate::expressions::*;
30096 if let Expression::Interval(ref iv) = expr {
30097 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
30099 unit: IntervalUnit::Week,
30100 ..
30101 }) = &iv.unit
30102 {
30103 let count = match &iv.this {
30105 Some(Expression::Literal(lit)) => match lit.as_ref() {
30106 Literal::String(s) | Literal::Number(s) => s.clone(),
30107 _ => return None,
30108 },
30109 _ => return None,
30110 };
30111 (true, count)
30112 } else if iv.unit.is_none() {
30113 if let Some(Expression::Literal(lit)) = &iv.this {
30115 if let Literal::String(s) = lit.as_ref() {
30116 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
30117 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
30118 (true, parts[0].to_string())
30119 } else {
30120 (false, String::new())
30121 }
30122 } else {
30123 (false, String::new())
30124 }
30125 } else {
30126 (false, String::new())
30127 }
30128 } else {
30129 (false, String::new())
30130 };
30131
30132 if is_week {
30133 let count_expr = Expression::Literal(Box::new(Literal::Number(count_str)));
30135 let day_interval = Expression::Interval(Box::new(Interval {
30136 this: Some(Expression::Literal(Box::new(Literal::String(
30137 "7".to_string(),
30138 )))),
30139 unit: Some(IntervalUnitSpec::Simple {
30140 unit: IntervalUnit::Day,
30141 use_plural: false,
30142 }),
30143 }));
30144 let mul = Expression::Mul(Box::new(BinaryOp {
30145 left: count_expr,
30146 right: day_interval,
30147 left_comments: vec![],
30148 operator_comments: vec![],
30149 trailing_comments: vec![],
30150 inferred_type: None,
30151 }));
30152 return Some(Expression::Paren(Box::new(Paren {
30153 this: mul,
30154 trailing_comments: vec![],
30155 })));
30156 }
30157 }
30158 None
30159 }
30160
30161 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
30162 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
30164 self.write("(");
30165 let mut first = true;
30166 if let Some(start) = &e.start {
30167 self.generate_expression(start)?;
30168 first = false;
30169 }
30170 if let Some(end) = &e.end {
30171 if !first {
30172 self.write(", ");
30173 }
30174 self.generate_expression(end)?;
30175 first = false;
30176 }
30177 if let Some(step) = &e.step {
30178 if !first {
30179 self.write(", ");
30180 }
30181 self.generate_expression(step)?;
30182 }
30183 self.write(")");
30184 Ok(())
30185 }
30186
30187 fn generate_generated_as_identity_column_constraint(
30188 &mut self,
30189 e: &GeneratedAsIdentityColumnConstraint,
30190 ) -> Result<()> {
30191 use crate::dialects::DialectType;
30192
30193 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
30195 self.write_keyword("AUTOINCREMENT");
30196 if let Some(start) = &e.start {
30197 self.write_keyword(" START ");
30198 self.generate_expression(start)?;
30199 }
30200 if let Some(increment) = &e.increment {
30201 self.write_keyword(" INCREMENT ");
30202 self.generate_expression(increment)?;
30203 }
30204 return Ok(());
30205 }
30206
30207 self.write_keyword("GENERATED");
30209 if let Some(this) = &e.this {
30210 if let Expression::Boolean(b) = this.as_ref() {
30212 if b.value {
30213 self.write_keyword(" ALWAYS");
30214 } else {
30215 self.write_keyword(" BY DEFAULT");
30216 if e.on_null.is_some() {
30217 self.write_keyword(" ON NULL");
30218 }
30219 }
30220 } else {
30221 self.write_keyword(" ALWAYS");
30222 }
30223 }
30224 self.write_keyword(" AS IDENTITY");
30225 let has_options = e.start.is_some()
30227 || e.increment.is_some()
30228 || e.minvalue.is_some()
30229 || e.maxvalue.is_some();
30230 if has_options {
30231 self.write(" (");
30232 let mut first = true;
30233 if let Some(start) = &e.start {
30234 self.write_keyword("START WITH ");
30235 self.generate_expression(start)?;
30236 first = false;
30237 }
30238 if let Some(increment) = &e.increment {
30239 if !first {
30240 self.write(" ");
30241 }
30242 self.write_keyword("INCREMENT BY ");
30243 self.generate_expression(increment)?;
30244 first = false;
30245 }
30246 if let Some(minvalue) = &e.minvalue {
30247 if !first {
30248 self.write(" ");
30249 }
30250 self.write_keyword("MINVALUE ");
30251 self.generate_expression(minvalue)?;
30252 first = false;
30253 }
30254 if let Some(maxvalue) = &e.maxvalue {
30255 if !first {
30256 self.write(" ");
30257 }
30258 self.write_keyword("MAXVALUE ");
30259 self.generate_expression(maxvalue)?;
30260 }
30261 self.write(")");
30262 }
30263 Ok(())
30264 }
30265
30266 fn generate_generated_as_row_column_constraint(
30267 &mut self,
30268 e: &GeneratedAsRowColumnConstraint,
30269 ) -> Result<()> {
30270 self.write_keyword("GENERATED ALWAYS AS ROW ");
30272 if e.start.is_some() {
30273 self.write_keyword("START");
30274 } else {
30275 self.write_keyword("END");
30276 }
30277 if e.hidden.is_some() {
30278 self.write_keyword(" HIDDEN");
30279 }
30280 Ok(())
30281 }
30282
30283 fn generate_get(&mut self, e: &Get) -> Result<()> {
30284 self.write_keyword("GET");
30286 self.write_space();
30287 self.generate_expression(&e.this)?;
30288 if let Some(target) = &e.target {
30289 self.write_space();
30290 self.generate_expression(target)?;
30291 }
30292 for prop in &e.properties {
30293 self.write_space();
30294 self.generate_expression(prop)?;
30295 }
30296 Ok(())
30297 }
30298
30299 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
30300 self.generate_expression(&e.this)?;
30302 self.write("[");
30303 self.generate_expression(&e.expression)?;
30304 self.write("]");
30305 Ok(())
30306 }
30307
30308 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
30309 self.write_keyword("GETBIT");
30311 self.write("(");
30312 self.generate_expression(&e.this)?;
30313 self.write(", ");
30314 self.generate_expression(&e.expression)?;
30315 self.write(")");
30316 Ok(())
30317 }
30318
30319 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
30320 if e.is_role {
30322 self.write_keyword("ROLE");
30323 self.write_space();
30324 } else if e.is_group {
30325 self.write_keyword("GROUP");
30326 self.write_space();
30327 } else if e.is_share {
30328 self.write_keyword("SHARE");
30329 self.write_space();
30330 }
30331 self.write(&e.name.name);
30332 Ok(())
30333 }
30334
30335 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
30336 self.generate_expression(&e.this)?;
30338 if !e.expressions.is_empty() {
30339 self.write("(");
30340 for (i, expr) in e.expressions.iter().enumerate() {
30341 if i > 0 {
30342 self.write(", ");
30343 }
30344 self.generate_expression(expr)?;
30345 }
30346 self.write(")");
30347 }
30348 Ok(())
30349 }
30350
30351 fn generate_group(&mut self, e: &Group) -> Result<()> {
30352 self.write_keyword("GROUP BY");
30354 match e.all {
30356 Some(true) => {
30357 self.write_space();
30358 self.write_keyword("ALL");
30359 }
30360 Some(false) => {
30361 self.write_space();
30362 self.write_keyword("DISTINCT");
30363 }
30364 None => {}
30365 }
30366 if !e.expressions.is_empty() {
30367 self.write_space();
30368 for (i, expr) in e.expressions.iter().enumerate() {
30369 if i > 0 {
30370 self.write(", ");
30371 }
30372 self.generate_expression(expr)?;
30373 }
30374 }
30375 if let Some(cube) = &e.cube {
30377 if !e.expressions.is_empty() {
30378 self.write(", ");
30379 } else {
30380 self.write_space();
30381 }
30382 self.generate_expression(cube)?;
30383 }
30384 if let Some(rollup) = &e.rollup {
30385 if !e.expressions.is_empty() || e.cube.is_some() {
30386 self.write(", ");
30387 } else {
30388 self.write_space();
30389 }
30390 self.generate_expression(rollup)?;
30391 }
30392 if let Some(grouping_sets) = &e.grouping_sets {
30393 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
30394 self.write(", ");
30395 } else {
30396 self.write_space();
30397 }
30398 self.generate_expression(grouping_sets)?;
30399 }
30400 if let Some(totals) = &e.totals {
30401 self.write_space();
30402 self.write_keyword("WITH TOTALS");
30403 self.generate_expression(totals)?;
30404 }
30405 Ok(())
30406 }
30407
30408 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
30409 self.write_keyword("GROUP BY");
30411 match e.all {
30413 Some(true) => {
30414 self.write_space();
30415 self.write_keyword("ALL");
30416 }
30417 Some(false) => {
30418 self.write_space();
30419 self.write_keyword("DISTINCT");
30420 }
30421 None => {}
30422 }
30423
30424 let mut trailing_cube = false;
30427 let mut trailing_rollup = false;
30428 let mut regular_expressions: Vec<&Expression> = Vec::new();
30429
30430 for expr in &e.expressions {
30431 match expr {
30432 Expression::Cube(c) if c.expressions.is_empty() => {
30433 trailing_cube = true;
30434 }
30435 Expression::Rollup(r) if r.expressions.is_empty() => {
30436 trailing_rollup = true;
30437 }
30438 _ => {
30439 regular_expressions.push(expr);
30440 }
30441 }
30442 }
30443
30444 if self.config.pretty {
30446 self.write_newline();
30447 self.indent_level += 1;
30448 for (i, expr) in regular_expressions.iter().enumerate() {
30449 if i > 0 {
30450 self.write(",");
30451 self.write_newline();
30452 }
30453 self.write_indent();
30454 self.generate_expression(expr)?;
30455 }
30456 self.indent_level -= 1;
30457 } else {
30458 self.write_space();
30459 for (i, expr) in regular_expressions.iter().enumerate() {
30460 if i > 0 {
30461 self.write(", ");
30462 }
30463 self.generate_expression(expr)?;
30464 }
30465 }
30466
30467 if trailing_cube {
30469 self.write_space();
30470 self.write_keyword("WITH CUBE");
30471 } else if trailing_rollup {
30472 self.write_space();
30473 self.write_keyword("WITH ROLLUP");
30474 }
30475
30476 if e.totals {
30478 self.write_space();
30479 self.write_keyword("WITH TOTALS");
30480 }
30481
30482 Ok(())
30483 }
30484
30485 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
30486 self.write_keyword("GROUPING");
30488 self.write("(");
30489 for (i, expr) in e.expressions.iter().enumerate() {
30490 if i > 0 {
30491 self.write(", ");
30492 }
30493 self.generate_expression(expr)?;
30494 }
30495 self.write(")");
30496 Ok(())
30497 }
30498
30499 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
30500 self.write_keyword("GROUPING_ID");
30502 self.write("(");
30503 for (i, expr) in e.expressions.iter().enumerate() {
30504 if i > 0 {
30505 self.write(", ");
30506 }
30507 self.generate_expression(expr)?;
30508 }
30509 self.write(")");
30510 Ok(())
30511 }
30512
30513 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
30514 self.write_keyword("GROUPING SETS");
30516 self.write(" (");
30517 for (i, expr) in e.expressions.iter().enumerate() {
30518 if i > 0 {
30519 self.write(", ");
30520 }
30521 self.generate_expression(expr)?;
30522 }
30523 self.write(")");
30524 Ok(())
30525 }
30526
30527 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
30528 self.write_keyword("HASH_AGG");
30530 self.write("(");
30531 self.generate_expression(&e.this)?;
30532 for expr in &e.expressions {
30533 self.write(", ");
30534 self.generate_expression(expr)?;
30535 }
30536 self.write(")");
30537 Ok(())
30538 }
30539
30540 fn generate_having(&mut self, e: &Having) -> Result<()> {
30541 self.write_keyword("HAVING");
30543 self.write_space();
30544 self.generate_expression(&e.this)?;
30545 Ok(())
30546 }
30547
30548 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
30549 self.generate_expression(&e.this)?;
30551 self.write_space();
30552 self.write_keyword("HAVING");
30553 self.write_space();
30554 if e.max.is_some() {
30555 self.write_keyword("MAX");
30556 } else {
30557 self.write_keyword("MIN");
30558 }
30559 self.write_space();
30560 self.generate_expression(&e.expression)?;
30561 Ok(())
30562 }
30563
30564 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
30565 use crate::dialects::DialectType;
30566 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
30568 if let Expression::Literal(ref lit) = *e.this {
30570 if let Literal::String(ref s) = lit.as_ref() {
30571 return self.generate_string_literal(s);
30572 }
30573 }
30574 }
30575 if matches!(
30577 self.config.dialect,
30578 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
30579 ) {
30580 self.write("$");
30581 if let Some(tag) = &e.tag {
30582 self.generate_expression(tag)?;
30583 }
30584 self.write("$");
30585 self.generate_expression(&e.this)?;
30586 self.write("$");
30587 if let Some(tag) = &e.tag {
30588 self.generate_expression(tag)?;
30589 }
30590 self.write("$");
30591 return Ok(());
30592 }
30593 self.write("$");
30595 if let Some(tag) = &e.tag {
30596 self.generate_expression(tag)?;
30597 }
30598 self.write("$");
30599 self.generate_expression(&e.this)?;
30600 self.write("$");
30601 if let Some(tag) = &e.tag {
30602 self.generate_expression(tag)?;
30603 }
30604 self.write("$");
30605 Ok(())
30606 }
30607
30608 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
30609 self.write_keyword("HEX_ENCODE");
30611 self.write("(");
30612 self.generate_expression(&e.this)?;
30613 self.write(")");
30614 Ok(())
30615 }
30616
30617 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
30618 match e.this.as_ref() {
30621 Expression::Identifier(id) => self.write(&id.name),
30622 other => self.generate_expression(other)?,
30623 }
30624 self.write(" (");
30625 self.write(&e.kind);
30626 self.write(" => ");
30627 self.generate_expression(&e.expression)?;
30628 self.write(")");
30629 Ok(())
30630 }
30631
30632 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
30633 self.write_keyword("HLL");
30635 self.write("(");
30636 self.generate_expression(&e.this)?;
30637 for expr in &e.expressions {
30638 self.write(", ");
30639 self.generate_expression(expr)?;
30640 }
30641 self.write(")");
30642 Ok(())
30643 }
30644
30645 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
30646 if e.input_.is_some() && e.output.is_some() {
30648 self.write_keyword("IN OUT");
30649 } else if e.input_.is_some() {
30650 self.write_keyword("IN");
30651 } else if e.output.is_some() {
30652 self.write_keyword("OUT");
30653 }
30654 Ok(())
30655 }
30656
30657 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
30658 self.write_keyword("INCLUDE");
30660 self.write_space();
30661 self.generate_expression(&e.this)?;
30662 if let Some(column_def) = &e.column_def {
30663 self.write_space();
30664 self.generate_expression(column_def)?;
30665 }
30666 if let Some(alias) = &e.alias {
30667 self.write_space();
30668 self.write_keyword("AS");
30669 self.write_space();
30670 self.write(alias);
30671 }
30672 Ok(())
30673 }
30674
30675 fn generate_index(&mut self, e: &Index) -> Result<()> {
30676 if e.unique {
30678 self.write_keyword("UNIQUE");
30679 self.write_space();
30680 }
30681 if e.primary.is_some() {
30682 self.write_keyword("PRIMARY");
30683 self.write_space();
30684 }
30685 if e.amp.is_some() {
30686 self.write_keyword("AMP");
30687 self.write_space();
30688 }
30689 if e.table.is_none() {
30690 self.write_keyword("INDEX");
30691 self.write_space();
30692 }
30693 if let Some(name) = &e.this {
30694 self.generate_expression(name)?;
30695 self.write_space();
30696 }
30697 if let Some(table) = &e.table {
30698 self.write_keyword("ON");
30699 self.write_space();
30700 self.generate_expression(table)?;
30701 }
30702 if !e.params.is_empty() {
30703 self.write("(");
30704 for (i, param) in e.params.iter().enumerate() {
30705 if i > 0 {
30706 self.write(", ");
30707 }
30708 self.generate_expression(param)?;
30709 }
30710 self.write(")");
30711 }
30712 Ok(())
30713 }
30714
30715 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
30716 if let Some(kind) = &e.kind {
30718 self.write(kind);
30719 self.write_space();
30720 }
30721 self.write_keyword("INDEX");
30722 if let Some(this) = &e.this {
30723 self.write_space();
30724 self.generate_expression(this)?;
30725 }
30726 if let Some(index_type) = &e.index_type {
30727 self.write_space();
30728 self.write_keyword("USING");
30729 self.write_space();
30730 self.generate_expression(index_type)?;
30731 }
30732 if !e.expressions.is_empty() {
30733 self.write(" (");
30734 for (i, expr) in e.expressions.iter().enumerate() {
30735 if i > 0 {
30736 self.write(", ");
30737 }
30738 self.generate_expression(expr)?;
30739 }
30740 self.write(")");
30741 }
30742 for opt in &e.options {
30743 self.write_space();
30744 self.generate_expression(opt)?;
30745 }
30746 Ok(())
30747 }
30748
30749 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
30750 if let Some(key_block_size) = &e.key_block_size {
30752 self.write_keyword("KEY_BLOCK_SIZE");
30753 self.write(" = ");
30754 self.generate_expression(key_block_size)?;
30755 } else if let Some(using) = &e.using {
30756 self.write_keyword("USING");
30757 self.write_space();
30758 self.generate_expression(using)?;
30759 } else if let Some(parser) = &e.parser {
30760 self.write_keyword("WITH PARSER");
30761 self.write_space();
30762 self.generate_expression(parser)?;
30763 } else if let Some(comment) = &e.comment {
30764 self.write_keyword("COMMENT");
30765 self.write_space();
30766 self.generate_expression(comment)?;
30767 } else if let Some(visible) = &e.visible {
30768 self.generate_expression(visible)?;
30769 } else if let Some(engine_attr) = &e.engine_attr {
30770 self.write_keyword("ENGINE_ATTRIBUTE");
30771 self.write(" = ");
30772 self.generate_expression(engine_attr)?;
30773 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
30774 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
30775 self.write(" = ");
30776 self.generate_expression(secondary_engine_attr)?;
30777 }
30778 Ok(())
30779 }
30780
30781 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
30782 if let Some(using) = &e.using {
30784 self.write_keyword("USING");
30785 self.write_space();
30786 self.generate_expression(using)?;
30787 }
30788 if !e.columns.is_empty() {
30789 self.write("(");
30790 for (i, col) in e.columns.iter().enumerate() {
30791 if i > 0 {
30792 self.write(", ");
30793 }
30794 self.generate_expression(col)?;
30795 }
30796 self.write(")");
30797 }
30798 if let Some(partition_by) = &e.partition_by {
30799 self.write_space();
30800 self.write_keyword("PARTITION BY");
30801 self.write_space();
30802 self.generate_expression(partition_by)?;
30803 }
30804 if let Some(where_) = &e.where_ {
30805 self.write_space();
30806 self.generate_expression(where_)?;
30807 }
30808 if let Some(include) = &e.include {
30809 self.write_space();
30810 self.write_keyword("INCLUDE");
30811 self.write(" (");
30812 self.generate_expression(include)?;
30813 self.write(")");
30814 }
30815 if let Some(with_storage) = &e.with_storage {
30816 self.write_space();
30817 self.write_keyword("WITH");
30818 self.write(" (");
30819 self.generate_expression(with_storage)?;
30820 self.write(")");
30821 }
30822 if let Some(tablespace) = &e.tablespace {
30823 self.write_space();
30824 self.write_keyword("USING INDEX TABLESPACE");
30825 self.write_space();
30826 self.generate_expression(tablespace)?;
30827 }
30828 Ok(())
30829 }
30830
30831 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
30832 if let Expression::Identifier(id) = &*e.this {
30836 self.write_keyword(&id.name);
30837 } else {
30838 self.generate_expression(&e.this)?;
30839 }
30840 self.write_space();
30841 self.write_keyword("INDEX");
30842 if let Some(target) = &e.target {
30843 self.write_space();
30844 self.write_keyword("FOR");
30845 self.write_space();
30846 if let Expression::Identifier(id) = &**target {
30847 self.write_keyword(&id.name);
30848 } else {
30849 self.generate_expression(target)?;
30850 }
30851 }
30852 self.write(" (");
30854 for (i, expr) in e.expressions.iter().enumerate() {
30855 if i > 0 {
30856 self.write(", ");
30857 }
30858 self.generate_expression(expr)?;
30859 }
30860 self.write(")");
30861 Ok(())
30862 }
30863
30864 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
30865 self.write_keyword("INHERITS");
30867 self.write(" (");
30868 for (i, expr) in e.expressions.iter().enumerate() {
30869 if i > 0 {
30870 self.write(", ");
30871 }
30872 self.generate_expression(expr)?;
30873 }
30874 self.write(")");
30875 Ok(())
30876 }
30877
30878 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
30879 self.write_keyword("INPUT");
30881 self.write("(");
30882 self.generate_expression(&e.this)?;
30883 self.write(")");
30884 Ok(())
30885 }
30886
30887 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
30888 if let Some(input_format) = &e.input_format {
30890 self.write_keyword("INPUTFORMAT");
30891 self.write_space();
30892 self.generate_expression(input_format)?;
30893 }
30894 if let Some(output_format) = &e.output_format {
30895 if e.input_format.is_some() {
30896 self.write(" ");
30897 }
30898 self.write_keyword("OUTPUTFORMAT");
30899 self.write_space();
30900 self.generate_expression(output_format)?;
30901 }
30902 Ok(())
30903 }
30904
30905 fn generate_install(&mut self, e: &Install) -> Result<()> {
30906 if e.force.is_some() {
30908 self.write_keyword("FORCE");
30909 self.write_space();
30910 }
30911 self.write_keyword("INSTALL");
30912 self.write_space();
30913 self.generate_expression(&e.this)?;
30914 if let Some(from) = &e.from_ {
30915 self.write_space();
30916 self.write_keyword("FROM");
30917 self.write_space();
30918 self.generate_expression(from)?;
30919 }
30920 Ok(())
30921 }
30922
30923 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
30924 self.write_keyword("INTERVAL");
30926 self.write_space();
30927 self.generate_expression(&e.expression)?;
30929 if let Some(unit) = &e.unit {
30930 self.write_space();
30931 self.write(unit);
30932 }
30933 Ok(())
30934 }
30935
30936 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
30937 self.write(&format!("{:?}", e.this).to_ascii_uppercase());
30939 self.write_space();
30940 self.write_keyword("TO");
30941 self.write_space();
30942 self.write(&format!("{:?}", e.expression).to_ascii_uppercase());
30943 Ok(())
30944 }
30945
30946 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
30947 self.write_keyword("INTO");
30949 if e.temporary {
30950 self.write_keyword(" TEMPORARY");
30951 }
30952 if e.unlogged.is_some() {
30953 self.write_keyword(" UNLOGGED");
30954 }
30955 if let Some(this) = &e.this {
30956 self.write_space();
30957 self.generate_expression(this)?;
30958 }
30959 if !e.expressions.is_empty() {
30960 self.write(" (");
30961 for (i, expr) in e.expressions.iter().enumerate() {
30962 if i > 0 {
30963 self.write(", ");
30964 }
30965 self.generate_expression(expr)?;
30966 }
30967 self.write(")");
30968 }
30969 Ok(())
30970 }
30971
30972 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
30973 self.generate_expression(&e.this)?;
30975 self.write_space();
30976 self.generate_expression(&e.expression)?;
30977 Ok(())
30978 }
30979
30980 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
30981 self.write_keyword("WITH");
30983 if e.no.is_some() {
30984 self.write_keyword(" NO");
30985 }
30986 if e.concurrent.is_some() {
30987 self.write_keyword(" CONCURRENT");
30988 }
30989 self.write_keyword(" ISOLATED LOADING");
30990 if let Some(target) = &e.target {
30991 self.write_space();
30992 self.generate_expression(target)?;
30993 }
30994 Ok(())
30995 }
30996
30997 fn generate_json(&mut self, e: &JSON) -> Result<()> {
30998 self.write_keyword("JSON");
31000 if let Some(this) = &e.this {
31001 self.write_space();
31002 self.generate_expression(this)?;
31003 }
31004 if let Some(with_) = &e.with_ {
31005 if let Expression::Boolean(b) = with_.as_ref() {
31007 if b.value {
31008 self.write_keyword(" WITH");
31009 } else {
31010 self.write_keyword(" WITHOUT");
31011 }
31012 }
31013 }
31014 if e.unique {
31015 self.write_keyword(" UNIQUE KEYS");
31016 }
31017 Ok(())
31018 }
31019
31020 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
31021 self.write_keyword("JSON_ARRAY");
31023 self.write("(");
31024 for (i, expr) in e.expressions.iter().enumerate() {
31025 if i > 0 {
31026 self.write(", ");
31027 }
31028 self.generate_expression(expr)?;
31029 }
31030 if let Some(null_handling) = &e.null_handling {
31031 self.write_space();
31032 self.generate_expression(null_handling)?;
31033 }
31034 if let Some(return_type) = &e.return_type {
31035 self.write_space();
31036 self.write_keyword("RETURNING");
31037 self.write_space();
31038 self.generate_expression(return_type)?;
31039 }
31040 if e.strict.is_some() {
31041 self.write_space();
31042 self.write_keyword("STRICT");
31043 }
31044 self.write(")");
31045 Ok(())
31046 }
31047
31048 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
31049 self.write_keyword("JSON_ARRAYAGG");
31051 self.write("(");
31052 self.generate_expression(&e.this)?;
31053 if let Some(order) = &e.order {
31054 self.write_space();
31055 if let Expression::OrderBy(ob) = order.as_ref() {
31057 self.write_keyword("ORDER BY");
31058 self.write_space();
31059 for (i, ord) in ob.expressions.iter().enumerate() {
31060 if i > 0 {
31061 self.write(", ");
31062 }
31063 self.generate_ordered(ord)?;
31064 }
31065 } else {
31066 self.generate_expression(order)?;
31068 }
31069 }
31070 if let Some(null_handling) = &e.null_handling {
31071 self.write_space();
31072 self.generate_expression(null_handling)?;
31073 }
31074 if let Some(return_type) = &e.return_type {
31075 self.write_space();
31076 self.write_keyword("RETURNING");
31077 self.write_space();
31078 self.generate_expression(return_type)?;
31079 }
31080 if e.strict.is_some() {
31081 self.write_space();
31082 self.write_keyword("STRICT");
31083 }
31084 self.write(")");
31085 Ok(())
31086 }
31087
31088 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
31089 self.write_keyword("JSON_OBJECTAGG");
31091 self.write("(");
31092 for (i, expr) in e.expressions.iter().enumerate() {
31093 if i > 0 {
31094 self.write(", ");
31095 }
31096 self.generate_expression(expr)?;
31097 }
31098 if let Some(null_handling) = &e.null_handling {
31099 self.write_space();
31100 self.generate_expression(null_handling)?;
31101 }
31102 if let Some(unique_keys) = &e.unique_keys {
31103 self.write_space();
31104 if let Expression::Boolean(b) = unique_keys.as_ref() {
31105 if b.value {
31106 self.write_keyword("WITH UNIQUE KEYS");
31107 } else {
31108 self.write_keyword("WITHOUT UNIQUE KEYS");
31109 }
31110 }
31111 }
31112 if let Some(return_type) = &e.return_type {
31113 self.write_space();
31114 self.write_keyword("RETURNING");
31115 self.write_space();
31116 self.generate_expression(return_type)?;
31117 }
31118 self.write(")");
31119 Ok(())
31120 }
31121
31122 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
31123 self.write_keyword("JSON_ARRAY_APPEND");
31125 self.write("(");
31126 self.generate_expression(&e.this)?;
31127 for expr in &e.expressions {
31128 self.write(", ");
31129 self.generate_expression(expr)?;
31130 }
31131 self.write(")");
31132 Ok(())
31133 }
31134
31135 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
31136 self.write_keyword("JSON_ARRAY_CONTAINS");
31138 self.write("(");
31139 self.generate_expression(&e.this)?;
31140 self.write(", ");
31141 self.generate_expression(&e.expression)?;
31142 self.write(")");
31143 Ok(())
31144 }
31145
31146 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
31147 self.write_keyword("JSON_ARRAY_INSERT");
31149 self.write("(");
31150 self.generate_expression(&e.this)?;
31151 for expr in &e.expressions {
31152 self.write(", ");
31153 self.generate_expression(expr)?;
31154 }
31155 self.write(")");
31156 Ok(())
31157 }
31158
31159 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
31160 self.write_keyword("JSONB_EXISTS");
31162 self.write("(");
31163 self.generate_expression(&e.this)?;
31164 if let Some(path) = &e.path {
31165 self.write(", ");
31166 self.generate_expression(path)?;
31167 }
31168 self.write(")");
31169 Ok(())
31170 }
31171
31172 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
31173 self.write_keyword("JSONB_EXTRACT_SCALAR");
31175 self.write("(");
31176 self.generate_expression(&e.this)?;
31177 self.write(", ");
31178 self.generate_expression(&e.expression)?;
31179 self.write(")");
31180 Ok(())
31181 }
31182
31183 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
31184 self.write_keyword("JSONB_OBJECT_AGG");
31186 self.write("(");
31187 self.generate_expression(&e.this)?;
31188 self.write(", ");
31189 self.generate_expression(&e.expression)?;
31190 self.write(")");
31191 Ok(())
31192 }
31193
31194 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
31195 if let Some(nested_schema) = &e.nested_schema {
31197 self.write_keyword("NESTED");
31198 if let Some(path) = &e.path {
31199 self.write_space();
31200 self.write_keyword("PATH");
31201 self.write_space();
31202 self.generate_expression(path)?;
31203 }
31204 self.write_space();
31205 self.generate_expression(nested_schema)?;
31206 } else {
31207 if let Some(this) = &e.this {
31208 self.generate_expression(this)?;
31209 }
31210 if let Some(kind) = &e.kind {
31211 self.write_space();
31212 self.write(kind);
31213 }
31214 if e.format_json {
31215 self.write_space();
31216 self.write_keyword("FORMAT JSON");
31217 }
31218 if let Some(path) = &e.path {
31219 self.write_space();
31220 self.write_keyword("PATH");
31221 self.write_space();
31222 self.generate_expression(path)?;
31223 }
31224 if e.ordinality.is_some() {
31225 self.write_keyword(" FOR ORDINALITY");
31226 }
31227 }
31228 Ok(())
31229 }
31230
31231 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
31232 self.write_keyword("JSON_EXISTS");
31234 self.write("(");
31235 self.generate_expression(&e.this)?;
31236 if let Some(path) = &e.path {
31237 self.write(", ");
31238 self.generate_expression(path)?;
31239 }
31240 if let Some(passing) = &e.passing {
31241 self.write_space();
31242 self.write_keyword("PASSING");
31243 self.write_space();
31244 self.generate_expression(passing)?;
31245 }
31246 if let Some(on_condition) = &e.on_condition {
31247 self.write_space();
31248 self.generate_expression(on_condition)?;
31249 }
31250 self.write(")");
31251 Ok(())
31252 }
31253
31254 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
31255 self.generate_expression(&e.this)?;
31256 self.write(".:");
31257 if Self::data_type_has_nested_expressions(&e.to) {
31261 let saved = std::mem::take(&mut self.output);
31263 self.generate_data_type(&e.to)?;
31264 let type_sql = std::mem::replace(&mut self.output, saved);
31265 self.write("\"");
31266 self.write(&type_sql);
31267 self.write("\"");
31268 } else {
31269 self.generate_data_type(&e.to)?;
31270 }
31271 Ok(())
31272 }
31273
31274 fn data_type_has_nested_expressions(dt: &DataType) -> bool {
31277 matches!(
31278 dt,
31279 DataType::Array { .. } | DataType::Map { .. } | DataType::Struct { .. }
31280 )
31281 }
31282
31283 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
31284 self.write_keyword("JSON_EXTRACT_ARRAY");
31286 self.write("(");
31287 self.generate_expression(&e.this)?;
31288 if let Some(expr) = &e.expression {
31289 self.write(", ");
31290 self.generate_expression(expr)?;
31291 }
31292 self.write(")");
31293 Ok(())
31294 }
31295
31296 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
31297 if let Some(option) = &e.option {
31299 self.generate_expression(option)?;
31300 self.write_space();
31301 }
31302 self.write_keyword("QUOTES");
31303 if e.scalar.is_some() {
31304 self.write_keyword(" SCALAR_ONLY");
31305 }
31306 Ok(())
31307 }
31308
31309 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
31310 self.write_keyword("JSON_EXTRACT_SCALAR");
31312 self.write("(");
31313 self.generate_expression(&e.this)?;
31314 self.write(", ");
31315 self.generate_expression(&e.expression)?;
31316 self.write(")");
31317 Ok(())
31318 }
31319
31320 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
31321 if e.variant_extract.is_some() {
31325 use crate::dialects::DialectType;
31326 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
31327 self.generate_expression(&e.this)?;
31331 self.write(":");
31332 match e.expression.as_ref() {
31333 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
31334 let Literal::String(s) = lit.as_ref() else {
31335 unreachable!()
31336 };
31337 self.write_databricks_json_path(s);
31338 }
31339 _ => {
31340 self.generate_expression(&e.expression)?;
31342 }
31343 }
31344 } else {
31345 self.write_keyword("GET_PATH");
31347 self.write("(");
31348 self.generate_expression(&e.this)?;
31349 self.write(", ");
31350 self.generate_expression(&e.expression)?;
31351 self.write(")");
31352 }
31353 } else {
31354 self.write_keyword("JSON_EXTRACT");
31355 self.write("(");
31356 self.generate_expression(&e.this)?;
31357 self.write(", ");
31358 self.generate_expression(&e.expression)?;
31359 for expr in &e.expressions {
31360 self.write(", ");
31361 self.generate_expression(expr)?;
31362 }
31363 self.write(")");
31364 }
31365 Ok(())
31366 }
31367
31368 fn write_databricks_json_path(&mut self, path: &str) {
31372 if path.starts_with("[\"") || path.starts_with("['") {
31375 self.write(path);
31376 return;
31377 }
31378 let mut first = true;
31382 for segment in path.split('.') {
31383 if !first {
31384 self.write(".");
31385 }
31386 first = false;
31387 if let Some(bracket_pos) = segment.find('[') {
31389 let key = &segment[..bracket_pos];
31390 let subscript = &segment[bracket_pos..];
31391 if key.is_empty() {
31392 self.write(segment);
31394 } else if Self::is_safe_json_path_key(key) {
31395 self.write(key);
31396 self.write(subscript);
31397 } else {
31398 self.write("[\"");
31399 self.write(key);
31400 self.write("\"]");
31401 self.write(subscript);
31402 }
31403 } else if Self::is_safe_json_path_key(segment) {
31404 self.write(segment);
31405 } else {
31406 self.write("[\"");
31407 self.write(segment);
31408 self.write("\"]");
31409 }
31410 }
31411 }
31412
31413 fn is_safe_json_path_key(key: &str) -> bool {
31416 if key.is_empty() {
31417 return false;
31418 }
31419 let mut chars = key.chars();
31420 let first = chars.next().unwrap();
31421 if first != '_' && !first.is_ascii_alphabetic() {
31422 return false;
31423 }
31424 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
31425 }
31426
31427 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
31428 if let Some(this) = &e.this {
31431 self.generate_expression(this)?;
31432 self.write_space();
31433 }
31434 self.write_keyword("FORMAT JSON");
31435 Ok(())
31436 }
31437
31438 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
31439 self.generate_expression(&e.this)?;
31441 self.write(": ");
31442 self.generate_expression(&e.expression)?;
31443 Ok(())
31444 }
31445
31446 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
31447 self.write_keyword("JSON_KEYS");
31449 self.write("(");
31450 self.generate_expression(&e.this)?;
31451 if let Some(expr) = &e.expression {
31452 self.write(", ");
31453 self.generate_expression(expr)?;
31454 }
31455 for expr in &e.expressions {
31456 self.write(", ");
31457 self.generate_expression(expr)?;
31458 }
31459 self.write(")");
31460 Ok(())
31461 }
31462
31463 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
31464 self.write_keyword("JSON_KEYS");
31466 self.write("(");
31467 self.generate_expression(&e.this)?;
31468 if let Some(expr) = &e.expression {
31469 self.write(", ");
31470 self.generate_expression(expr)?;
31471 }
31472 self.write(")");
31473 Ok(())
31474 }
31475
31476 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
31477 let mut path_str = String::new();
31480 for expr in &e.expressions {
31481 match expr {
31482 Expression::JSONPathRoot(_) => {
31483 path_str.push('$');
31484 }
31485 Expression::JSONPathKey(k) => {
31486 if let Expression::Literal(lit) = k.this.as_ref() {
31488 if let crate::expressions::Literal::String(s) = lit.as_ref() {
31489 path_str.push('.');
31490 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
31492 if needs_quoting {
31493 path_str.push('"');
31494 path_str.push_str(s);
31495 path_str.push('"');
31496 } else {
31497 path_str.push_str(s);
31498 }
31499 }
31500 }
31501 }
31502 Expression::JSONPathSubscript(s) => {
31503 if let Expression::Literal(lit) = s.this.as_ref() {
31505 if let crate::expressions::Literal::Number(n) = lit.as_ref() {
31506 path_str.push('[');
31507 path_str.push_str(n);
31508 path_str.push(']');
31509 }
31510 }
31511 }
31512 _ => {
31513 let mut temp_gen = Self::with_arc_config(self.config.clone());
31515 temp_gen.generate_expression(expr)?;
31516 path_str.push_str(&temp_gen.output);
31517 }
31518 }
31519 }
31520 self.write("'");
31522 self.write(&path_str);
31523 self.write("'");
31524 Ok(())
31525 }
31526
31527 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
31528 self.write("?(");
31530 self.generate_expression(&e.this)?;
31531 self.write(")");
31532 Ok(())
31533 }
31534
31535 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
31536 self.write(".");
31538 self.generate_expression(&e.this)?;
31539 Ok(())
31540 }
31541
31542 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
31543 self.write("..");
31545 if let Some(this) = &e.this {
31546 self.generate_expression(this)?;
31547 }
31548 Ok(())
31549 }
31550
31551 fn generate_json_path_root(&mut self) -> Result<()> {
31552 self.write("$");
31554 Ok(())
31555 }
31556
31557 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
31558 self.write("(");
31560 self.generate_expression(&e.this)?;
31561 self.write(")");
31562 Ok(())
31563 }
31564
31565 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
31566 self.generate_expression(&e.this)?;
31568 Ok(())
31569 }
31570
31571 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
31572 self.write("[");
31574 if let Some(start) = &e.start {
31575 self.generate_expression(start)?;
31576 }
31577 self.write(":");
31578 if let Some(end) = &e.end {
31579 self.generate_expression(end)?;
31580 }
31581 if let Some(step) = &e.step {
31582 self.write(":");
31583 self.generate_expression(step)?;
31584 }
31585 self.write("]");
31586 Ok(())
31587 }
31588
31589 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
31590 self.write("[");
31592 self.generate_expression(&e.this)?;
31593 self.write("]");
31594 Ok(())
31595 }
31596
31597 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
31598 self.write("[");
31600 for (i, expr) in e.expressions.iter().enumerate() {
31601 if i > 0 {
31602 self.write(", ");
31603 }
31604 self.generate_expression(expr)?;
31605 }
31606 self.write("]");
31607 Ok(())
31608 }
31609
31610 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
31611 self.write_keyword("JSON_REMOVE");
31613 self.write("(");
31614 self.generate_expression(&e.this)?;
31615 for expr in &e.expressions {
31616 self.write(", ");
31617 self.generate_expression(expr)?;
31618 }
31619 self.write(")");
31620 Ok(())
31621 }
31622
31623 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
31624 self.write_keyword("COLUMNS");
31627 self.write("(");
31628
31629 if self.config.pretty && !e.expressions.is_empty() {
31630 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
31632 for expr in &e.expressions {
31633 let mut temp_gen = Generator::with_arc_config(self.config.clone());
31634 temp_gen.generate_expression(expr)?;
31635 expr_strings.push(temp_gen.output);
31636 }
31637
31638 if self.too_wide(&expr_strings) {
31640 self.write_newline();
31642 self.indent_level += 1;
31643 for (i, expr_str) in expr_strings.iter().enumerate() {
31644 if i > 0 {
31645 self.write(",");
31646 self.write_newline();
31647 }
31648 self.write_indent();
31649 self.write(expr_str);
31650 }
31651 self.write_newline();
31652 self.indent_level -= 1;
31653 self.write_indent();
31654 } else {
31655 for (i, expr_str) in expr_strings.iter().enumerate() {
31657 if i > 0 {
31658 self.write(", ");
31659 }
31660 self.write(expr_str);
31661 }
31662 }
31663 } else {
31664 for (i, expr) in e.expressions.iter().enumerate() {
31666 if i > 0 {
31667 self.write(", ");
31668 }
31669 self.generate_expression(expr)?;
31670 }
31671 }
31672 self.write(")");
31673 Ok(())
31674 }
31675
31676 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
31677 self.write_keyword("JSON_SET");
31679 self.write("(");
31680 self.generate_expression(&e.this)?;
31681 for expr in &e.expressions {
31682 self.write(", ");
31683 self.generate_expression(expr)?;
31684 }
31685 self.write(")");
31686 Ok(())
31687 }
31688
31689 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
31690 self.write_keyword("JSON_STRIP_NULLS");
31692 self.write("(");
31693 self.generate_expression(&e.this)?;
31694 if let Some(expr) = &e.expression {
31695 self.write(", ");
31696 self.generate_expression(expr)?;
31697 }
31698 self.write(")");
31699 Ok(())
31700 }
31701
31702 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
31703 self.write_keyword("JSON_TABLE");
31705 self.write("(");
31706 self.generate_expression(&e.this)?;
31707 if let Some(path) = &e.path {
31708 self.write(", ");
31709 self.generate_expression(path)?;
31710 }
31711 if let Some(error_handling) = &e.error_handling {
31712 self.write_space();
31713 self.generate_expression(error_handling)?;
31714 }
31715 if let Some(empty_handling) = &e.empty_handling {
31716 self.write_space();
31717 self.generate_expression(empty_handling)?;
31718 }
31719 if let Some(schema) = &e.schema {
31720 self.write_space();
31721 self.generate_expression(schema)?;
31722 }
31723 self.write(")");
31724 Ok(())
31725 }
31726
31727 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
31728 self.write_keyword("JSON_TYPE");
31730 self.write("(");
31731 self.generate_expression(&e.this)?;
31732 self.write(")");
31733 Ok(())
31734 }
31735
31736 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
31737 self.write_keyword("JSON_VALUE");
31739 self.write("(");
31740 self.generate_expression(&e.this)?;
31741 if let Some(path) = &e.path {
31742 self.write(", ");
31743 self.generate_expression(path)?;
31744 }
31745 if let Some(returning) = &e.returning {
31746 self.write_space();
31747 self.write_keyword("RETURNING");
31748 self.write_space();
31749 self.generate_expression(returning)?;
31750 }
31751 if let Some(on_condition) = &e.on_condition {
31752 self.write_space();
31753 self.generate_expression(on_condition)?;
31754 }
31755 self.write(")");
31756 Ok(())
31757 }
31758
31759 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
31760 self.write_keyword("JSON_VALUE_ARRAY");
31762 self.write("(");
31763 self.generate_expression(&e.this)?;
31764 self.write(")");
31765 Ok(())
31766 }
31767
31768 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
31769 self.write_keyword("JAROWINKLER_SIMILARITY");
31771 self.write("(");
31772 self.generate_expression(&e.this)?;
31773 self.write(", ");
31774 self.generate_expression(&e.expression)?;
31775 self.write(")");
31776 Ok(())
31777 }
31778
31779 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
31780 self.generate_expression(&e.this)?;
31782 self.write("(");
31783 for (i, expr) in e.expressions.iter().enumerate() {
31784 if i > 0 {
31785 self.write(", ");
31786 }
31787 self.generate_expression(expr)?;
31788 }
31789 self.write(")");
31790 Ok(())
31791 }
31792
31793 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
31794 if e.no.is_some() {
31796 self.write_keyword("NO ");
31797 }
31798 if let Some(local) = &e.local {
31799 self.generate_expression(local)?;
31800 self.write_space();
31801 }
31802 if e.dual.is_some() {
31803 self.write_keyword("DUAL ");
31804 }
31805 if e.before.is_some() {
31806 self.write_keyword("BEFORE ");
31807 }
31808 if e.after.is_some() {
31809 self.write_keyword("AFTER ");
31810 }
31811 self.write_keyword("JOURNAL");
31812 Ok(())
31813 }
31814
31815 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
31816 self.write_keyword("LANGUAGE");
31818 self.write_space();
31819 self.generate_expression(&e.this)?;
31820 Ok(())
31821 }
31822
31823 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
31824 if e.view.is_some() {
31826 self.write_keyword("LATERAL VIEW");
31828 if e.outer.is_some() {
31829 self.write_space();
31830 self.write_keyword("OUTER");
31831 }
31832 self.write_space();
31833 self.generate_expression(&e.this)?;
31834 if let Some(alias) = &e.alias {
31835 self.write_space();
31836 self.write(alias);
31837 }
31838 } else {
31839 self.write_keyword("LATERAL");
31841 self.write_space();
31842 self.generate_expression(&e.this)?;
31843 if e.ordinality.is_some() {
31844 self.write_space();
31845 self.write_keyword("WITH ORDINALITY");
31846 }
31847 if let Some(alias) = &e.alias {
31848 self.write_space();
31849 self.write_keyword("AS");
31850 self.write_space();
31851 self.write(alias);
31852 if !e.column_aliases.is_empty() {
31853 self.write("(");
31854 for (i, col) in e.column_aliases.iter().enumerate() {
31855 if i > 0 {
31856 self.write(", ");
31857 }
31858 self.write(col);
31859 }
31860 self.write(")");
31861 }
31862 }
31863 }
31864 Ok(())
31865 }
31866
31867 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
31868 self.write_keyword("LIKE");
31870 self.write_space();
31871 self.generate_expression(&e.this)?;
31872 for expr in &e.expressions {
31873 self.write_space();
31874 self.generate_expression(expr)?;
31875 }
31876 Ok(())
31877 }
31878
31879 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
31880 self.write_keyword("LIMIT");
31881 self.write_space();
31882 self.write_limit_expr(&e.this)?;
31883 if e.percent {
31884 self.write_space();
31885 self.write_keyword("PERCENT");
31886 }
31887 for comment in &e.comments {
31889 self.write(" ");
31890 self.write_formatted_comment(comment);
31891 }
31892 Ok(())
31893 }
31894
31895 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
31896 if e.percent.is_some() {
31898 self.write_keyword(" PERCENT");
31899 }
31900 if e.rows.is_some() {
31901 self.write_keyword(" ROWS");
31902 }
31903 if e.with_ties.is_some() {
31904 self.write_keyword(" WITH TIES");
31905 } else if e.rows.is_some() {
31906 self.write_keyword(" ONLY");
31907 }
31908 Ok(())
31909 }
31910
31911 fn generate_list(&mut self, e: &List) -> Result<()> {
31912 use crate::dialects::DialectType;
31913 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
31914
31915 if e.expressions.len() == 1 {
31917 if let Expression::Select(_) = &e.expressions[0] {
31918 self.write_keyword("LIST");
31919 self.write("(");
31920 self.generate_expression(&e.expressions[0])?;
31921 self.write(")");
31922 return Ok(());
31923 }
31924 }
31925
31926 if is_materialize {
31928 self.write_keyword("LIST");
31929 self.write("[");
31930 for (i, expr) in e.expressions.iter().enumerate() {
31931 if i > 0 {
31932 self.write(", ");
31933 }
31934 self.generate_expression(expr)?;
31935 }
31936 self.write("]");
31937 } else {
31938 self.write_keyword("LIST");
31940 self.write("(");
31941 for (i, expr) in e.expressions.iter().enumerate() {
31942 if i > 0 {
31943 self.write(", ");
31944 }
31945 self.generate_expression(expr)?;
31946 }
31947 self.write(")");
31948 }
31949 Ok(())
31950 }
31951
31952 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
31953 if let Expression::Select(_) = &*e.this {
31955 self.write_keyword("MAP");
31956 self.write("(");
31957 self.generate_expression(&e.this)?;
31958 self.write(")");
31959 return Ok(());
31960 }
31961
31962 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
31963
31964 self.write_keyword("MAP");
31966 if is_duckdb {
31967 self.write(" {");
31968 } else {
31969 self.write("[");
31970 }
31971 if let Expression::Struct(s) = &*e.this {
31972 for (i, (_, expr)) in s.fields.iter().enumerate() {
31973 if i > 0 {
31974 self.write(", ");
31975 }
31976 if let Expression::PropertyEQ(op) = expr {
31977 self.generate_expression(&op.left)?;
31978 if is_duckdb {
31979 self.write(": ");
31980 } else {
31981 self.write(" => ");
31982 }
31983 self.generate_expression(&op.right)?;
31984 } else {
31985 self.generate_expression(expr)?;
31986 }
31987 }
31988 }
31989 if is_duckdb {
31990 self.write("}");
31991 } else {
31992 self.write("]");
31993 }
31994 Ok(())
31995 }
31996
31997 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
31998 self.write_keyword("LOCALTIME");
32000 if let Some(precision) = &e.this {
32001 self.write("(");
32002 self.generate_expression(precision)?;
32003 self.write(")");
32004 }
32005 Ok(())
32006 }
32007
32008 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
32009 self.write_keyword("LOCALTIMESTAMP");
32011 if let Some(precision) = &e.this {
32012 self.write("(");
32013 self.generate_expression(precision)?;
32014 self.write(")");
32015 }
32016 Ok(())
32017 }
32018
32019 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
32020 self.write_keyword("LOCATION");
32022 self.write_space();
32023 self.generate_expression(&e.this)?;
32024 Ok(())
32025 }
32026
32027 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
32028 if e.update.is_some() {
32030 if e.key.is_some() {
32031 self.write_keyword("FOR NO KEY UPDATE");
32032 } else {
32033 self.write_keyword("FOR UPDATE");
32034 }
32035 } else {
32036 if e.key.is_some() {
32037 self.write_keyword("FOR KEY SHARE");
32038 } else {
32039 self.write_keyword("FOR SHARE");
32040 }
32041 }
32042 if !e.expressions.is_empty() {
32043 self.write_keyword(" OF ");
32044 for (i, expr) in e.expressions.iter().enumerate() {
32045 if i > 0 {
32046 self.write(", ");
32047 }
32048 self.generate_expression(expr)?;
32049 }
32050 }
32051 if let Some(wait) = &e.wait {
32056 match wait.as_ref() {
32057 Expression::Boolean(b) => {
32058 if b.value {
32059 self.write_keyword(" NOWAIT");
32060 } else {
32061 self.write_keyword(" SKIP LOCKED");
32062 }
32063 }
32064 _ => {
32065 self.write_keyword(" WAIT ");
32067 self.generate_expression(wait)?;
32068 }
32069 }
32070 }
32071 Ok(())
32072 }
32073
32074 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
32075 self.write_keyword("LOCK");
32077 self.write_space();
32078 self.generate_expression(&e.this)?;
32079 Ok(())
32080 }
32081
32082 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
32083 self.write_keyword("LOCKING");
32085 self.write_space();
32086 self.write(&e.kind);
32087 if let Some(this) = &e.this {
32088 self.write_space();
32089 self.generate_expression(this)?;
32090 }
32091 if let Some(for_or_in) = &e.for_or_in {
32092 self.write_space();
32093 self.generate_expression(for_or_in)?;
32094 }
32095 if let Some(lock_type) = &e.lock_type {
32096 self.write_space();
32097 self.generate_expression(lock_type)?;
32098 }
32099 if e.override_.is_some() {
32100 self.write_keyword(" OVERRIDE");
32101 }
32102 Ok(())
32103 }
32104
32105 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
32106 self.generate_expression(&e.this)?;
32108 self.write_space();
32109 self.generate_expression(&e.expression)?;
32110 Ok(())
32111 }
32112
32113 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
32114 if e.no.is_some() {
32116 self.write_keyword("NO ");
32117 }
32118 self.write_keyword("LOG");
32119 Ok(())
32120 }
32121
32122 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
32123 self.write_keyword("MD5");
32125 self.write("(");
32126 self.generate_expression(&e.this)?;
32127 for expr in &e.expressions {
32128 self.write(", ");
32129 self.generate_expression(expr)?;
32130 }
32131 self.write(")");
32132 Ok(())
32133 }
32134
32135 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
32136 self.write_keyword("ML.FORECAST");
32138 self.write("(");
32139 self.generate_expression(&e.this)?;
32140 if let Some(expression) = &e.expression {
32141 self.write(", ");
32142 self.generate_expression(expression)?;
32143 }
32144 if let Some(params) = &e.params_struct {
32145 self.write(", ");
32146 self.generate_expression(params)?;
32147 }
32148 self.write(")");
32149 Ok(())
32150 }
32151
32152 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
32153 self.write_keyword("ML.TRANSLATE");
32155 self.write("(");
32156 self.generate_expression(&e.this)?;
32157 self.write(", ");
32158 self.generate_expression(&e.expression)?;
32159 if let Some(params) = &e.params_struct {
32160 self.write(", ");
32161 self.generate_expression(params)?;
32162 }
32163 self.write(")");
32164 Ok(())
32165 }
32166
32167 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
32168 self.write_keyword("MAKE_INTERVAL");
32170 self.write("(");
32171 let mut first = true;
32172 if let Some(year) = &e.year {
32173 self.write("years => ");
32174 self.generate_expression(year)?;
32175 first = false;
32176 }
32177 if let Some(month) = &e.month {
32178 if !first {
32179 self.write(", ");
32180 }
32181 self.write("months => ");
32182 self.generate_expression(month)?;
32183 first = false;
32184 }
32185 if let Some(week) = &e.week {
32186 if !first {
32187 self.write(", ");
32188 }
32189 self.write("weeks => ");
32190 self.generate_expression(week)?;
32191 first = false;
32192 }
32193 if let Some(day) = &e.day {
32194 if !first {
32195 self.write(", ");
32196 }
32197 self.write("days => ");
32198 self.generate_expression(day)?;
32199 first = false;
32200 }
32201 if let Some(hour) = &e.hour {
32202 if !first {
32203 self.write(", ");
32204 }
32205 self.write("hours => ");
32206 self.generate_expression(hour)?;
32207 first = false;
32208 }
32209 if let Some(minute) = &e.minute {
32210 if !first {
32211 self.write(", ");
32212 }
32213 self.write("mins => ");
32214 self.generate_expression(minute)?;
32215 first = false;
32216 }
32217 if let Some(second) = &e.second {
32218 if !first {
32219 self.write(", ");
32220 }
32221 self.write("secs => ");
32222 self.generate_expression(second)?;
32223 }
32224 self.write(")");
32225 Ok(())
32226 }
32227
32228 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
32229 self.write_keyword("MANHATTAN_DISTANCE");
32231 self.write("(");
32232 self.generate_expression(&e.this)?;
32233 self.write(", ");
32234 self.generate_expression(&e.expression)?;
32235 self.write(")");
32236 Ok(())
32237 }
32238
32239 fn generate_map(&mut self, e: &Map) -> Result<()> {
32240 self.write_keyword("MAP");
32242 self.write("(");
32243 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
32244 if i > 0 {
32245 self.write(", ");
32246 }
32247 self.generate_expression(key)?;
32248 self.write(", ");
32249 self.generate_expression(value)?;
32250 }
32251 self.write(")");
32252 Ok(())
32253 }
32254
32255 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
32256 self.write_keyword("MAP_CAT");
32258 self.write("(");
32259 self.generate_expression(&e.this)?;
32260 self.write(", ");
32261 self.generate_expression(&e.expression)?;
32262 self.write(")");
32263 Ok(())
32264 }
32265
32266 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
32267 self.write_keyword("MAP_DELETE");
32269 self.write("(");
32270 self.generate_expression(&e.this)?;
32271 for expr in &e.expressions {
32272 self.write(", ");
32273 self.generate_expression(expr)?;
32274 }
32275 self.write(")");
32276 Ok(())
32277 }
32278
32279 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
32280 self.write_keyword("MAP_INSERT");
32282 self.write("(");
32283 self.generate_expression(&e.this)?;
32284 if let Some(key) = &e.key {
32285 self.write(", ");
32286 self.generate_expression(key)?;
32287 }
32288 if let Some(value) = &e.value {
32289 self.write(", ");
32290 self.generate_expression(value)?;
32291 }
32292 if let Some(update_flag) = &e.update_flag {
32293 self.write(", ");
32294 self.generate_expression(update_flag)?;
32295 }
32296 self.write(")");
32297 Ok(())
32298 }
32299
32300 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
32301 self.write_keyword("MAP_PICK");
32303 self.write("(");
32304 self.generate_expression(&e.this)?;
32305 for expr in &e.expressions {
32306 self.write(", ");
32307 self.generate_expression(expr)?;
32308 }
32309 self.write(")");
32310 Ok(())
32311 }
32312
32313 fn generate_masking_policy_column_constraint(
32314 &mut self,
32315 e: &MaskingPolicyColumnConstraint,
32316 ) -> Result<()> {
32317 self.write_keyword("MASKING POLICY");
32319 self.write_space();
32320 self.generate_expression(&e.this)?;
32321 if !e.expressions.is_empty() {
32322 self.write_keyword(" USING");
32323 self.write(" (");
32324 for (i, expr) in e.expressions.iter().enumerate() {
32325 if i > 0 {
32326 self.write(", ");
32327 }
32328 self.generate_expression(expr)?;
32329 }
32330 self.write(")");
32331 }
32332 Ok(())
32333 }
32334
32335 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
32336 if matches!(
32337 self.config.dialect,
32338 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
32339 ) {
32340 if e.expressions.len() > 1 {
32341 self.write("(");
32342 }
32343 for (i, expr) in e.expressions.iter().enumerate() {
32344 if i > 0 {
32345 self.write_keyword(" OR ");
32346 }
32347 self.generate_expression(expr)?;
32348 self.write_space();
32349 self.write("@@");
32350 self.write_space();
32351 self.generate_expression(&e.this)?;
32352 }
32353 if e.expressions.len() > 1 {
32354 self.write(")");
32355 }
32356 return Ok(());
32357 }
32358
32359 self.write_keyword("MATCH");
32361 self.write("(");
32362 for (i, expr) in e.expressions.iter().enumerate() {
32363 if i > 0 {
32364 self.write(", ");
32365 }
32366 self.generate_expression(expr)?;
32367 }
32368 self.write(")");
32369 self.write_keyword(" AGAINST");
32370 self.write("(");
32371 self.generate_expression(&e.this)?;
32372 if let Some(modifier) = &e.modifier {
32373 self.write_space();
32374 self.generate_expression(modifier)?;
32375 }
32376 self.write(")");
32377 Ok(())
32378 }
32379
32380 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
32381 if let Some(window_frame) = &e.window_frame {
32383 self.write(&format!("{:?}", window_frame).to_ascii_uppercase());
32384 self.write_space();
32385 }
32386 self.generate_expression(&e.this)?;
32387 Ok(())
32388 }
32389
32390 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
32391 self.write_keyword("MATERIALIZED");
32393 if let Some(this) = &e.this {
32394 self.write_space();
32395 self.generate_expression(this)?;
32396 }
32397 Ok(())
32398 }
32399
32400 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
32401 if let Some(with_) = &e.with_ {
32404 if let Expression::With(with_clause) = with_.as_ref() {
32405 self.generate_with(with_clause)?;
32406 self.write_space();
32407 } else {
32408 self.generate_expression(with_)?;
32409 self.write_space();
32410 }
32411 }
32412 self.write_keyword("MERGE INTO");
32413 self.write_space();
32414 if matches!(self.config.dialect, Some(crate::DialectType::Oracle)) {
32415 if let Expression::Alias(alias) = e.this.as_ref() {
32416 self.generate_expression(&alias.this)?;
32417 self.write_space();
32418 self.generate_identifier(&alias.alias)?;
32419 } else {
32420 self.generate_expression(&e.this)?;
32421 }
32422 } else {
32423 self.generate_expression(&e.this)?;
32424 }
32425
32426 if self.config.pretty {
32428 self.write_newline();
32429 self.write_indent();
32430 } else {
32431 self.write_space();
32432 }
32433 self.write_keyword("USING");
32434 self.write_space();
32435 self.generate_expression(&e.using)?;
32436
32437 if let Some(on) = &e.on {
32439 if self.config.pretty {
32440 self.write_newline();
32441 self.write_indent();
32442 } else {
32443 self.write_space();
32444 }
32445 self.write_keyword("ON");
32446 self.write_space();
32447 self.generate_expression(on)?;
32448 }
32449 if let Some(using_cond) = &e.using_cond {
32451 self.write_space();
32452 self.write_keyword("USING");
32453 self.write_space();
32454 self.write("(");
32455 if let Expression::Tuple(tuple) = using_cond.as_ref() {
32457 for (i, col) in tuple.expressions.iter().enumerate() {
32458 if i > 0 {
32459 self.write(", ");
32460 }
32461 self.generate_expression(col)?;
32462 }
32463 } else {
32464 self.generate_expression(using_cond)?;
32465 }
32466 self.write(")");
32467 }
32468 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
32470 if matches!(
32471 self.config.dialect,
32472 Some(crate::DialectType::PostgreSQL)
32473 | Some(crate::DialectType::Redshift)
32474 | Some(crate::DialectType::Trino)
32475 | Some(crate::DialectType::Presto)
32476 | Some(crate::DialectType::Athena)
32477 ) {
32478 let mut names = Vec::new();
32479 match e.this.as_ref() {
32480 Expression::Alias(a) => {
32481 if let Expression::Table(t) = &a.this {
32483 names.push(t.name.name.clone());
32484 } else if let Expression::Identifier(id) = &a.this {
32485 names.push(id.name.clone());
32486 }
32487 names.push(a.alias.name.clone());
32488 }
32489 Expression::Table(t) => {
32490 names.push(t.name.name.clone());
32491 }
32492 Expression::Identifier(id) => {
32493 names.push(id.name.clone());
32494 }
32495 _ => {}
32496 }
32497 self.merge_strip_qualifiers = names;
32498 }
32499
32500 if let Some(whens) = &e.whens {
32502 if self.config.pretty {
32503 self.write_newline();
32504 self.write_indent();
32505 } else {
32506 self.write_space();
32507 }
32508 self.generate_expression(whens)?;
32509 }
32510
32511 self.merge_strip_qualifiers = saved_merge_strip;
32513
32514 if let Some(returning) = &e.returning {
32516 if self.config.pretty {
32517 self.write_newline();
32518 self.write_indent();
32519 } else {
32520 self.write_space();
32521 }
32522 self.generate_expression(returning)?;
32523 }
32524 Ok(())
32525 }
32526
32527 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
32528 if e.no.is_some() {
32530 self.write_keyword("NO MERGEBLOCKRATIO");
32531 } else if e.default.is_some() {
32532 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
32533 } else {
32534 self.write_keyword("MERGEBLOCKRATIO");
32535 self.write("=");
32536 if let Some(this) = &e.this {
32537 self.generate_expression(this)?;
32538 }
32539 if e.percent.is_some() {
32540 self.write_keyword(" PERCENT");
32541 }
32542 }
32543 Ok(())
32544 }
32545
32546 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
32547 self.write_keyword("TTL");
32549 let pretty_clickhouse = self.config.pretty
32550 && matches!(
32551 self.config.dialect,
32552 Some(crate::dialects::DialectType::ClickHouse)
32553 );
32554
32555 if pretty_clickhouse {
32556 self.write_newline();
32557 self.indent_level += 1;
32558 for (i, expr) in e.expressions.iter().enumerate() {
32559 if i > 0 {
32560 self.write(",");
32561 self.write_newline();
32562 }
32563 self.write_indent();
32564 self.generate_expression(expr)?;
32565 }
32566 self.indent_level -= 1;
32567 } else {
32568 self.write_space();
32569 for (i, expr) in e.expressions.iter().enumerate() {
32570 if i > 0 {
32571 self.write(", ");
32572 }
32573 self.generate_expression(expr)?;
32574 }
32575 }
32576
32577 if let Some(where_) = &e.where_ {
32578 if pretty_clickhouse {
32579 self.write_newline();
32580 if let Expression::Where(w) = where_.as_ref() {
32581 self.write_indent();
32582 self.write_keyword("WHERE");
32583 self.write_newline();
32584 self.indent_level += 1;
32585 self.write_indent();
32586 self.generate_expression(&w.this)?;
32587 self.indent_level -= 1;
32588 } else {
32589 self.write_indent();
32590 self.generate_expression(where_)?;
32591 }
32592 } else {
32593 self.write_space();
32594 self.generate_expression(where_)?;
32595 }
32596 }
32597 if let Some(group) = &e.group {
32598 if pretty_clickhouse {
32599 self.write_newline();
32600 if let Expression::Group(g) = group.as_ref() {
32601 self.write_indent();
32602 self.write_keyword("GROUP BY");
32603 self.write_newline();
32604 self.indent_level += 1;
32605 for (i, expr) in g.expressions.iter().enumerate() {
32606 if i > 0 {
32607 self.write(",");
32608 self.write_newline();
32609 }
32610 self.write_indent();
32611 self.generate_expression(expr)?;
32612 }
32613 self.indent_level -= 1;
32614 } else {
32615 self.write_indent();
32616 self.generate_expression(group)?;
32617 }
32618 } else {
32619 self.write_space();
32620 self.generate_expression(group)?;
32621 }
32622 }
32623 if let Some(aggregates) = &e.aggregates {
32624 if pretty_clickhouse {
32625 self.write_newline();
32626 self.write_indent();
32627 self.write_keyword("SET");
32628 self.write_newline();
32629 self.indent_level += 1;
32630 if let Expression::Tuple(t) = aggregates.as_ref() {
32631 for (i, agg) in t.expressions.iter().enumerate() {
32632 if i > 0 {
32633 self.write(",");
32634 self.write_newline();
32635 }
32636 self.write_indent();
32637 self.generate_expression(agg)?;
32638 }
32639 } else {
32640 self.write_indent();
32641 self.generate_expression(aggregates)?;
32642 }
32643 self.indent_level -= 1;
32644 } else {
32645 self.write_space();
32646 self.write_keyword("SET");
32647 self.write_space();
32648 if let Expression::Tuple(t) = aggregates.as_ref() {
32649 for (i, agg) in t.expressions.iter().enumerate() {
32650 if i > 0 {
32651 self.write(", ");
32652 }
32653 self.generate_expression(agg)?;
32654 }
32655 } else {
32656 self.generate_expression(aggregates)?;
32657 }
32658 }
32659 }
32660 Ok(())
32661 }
32662
32663 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
32664 self.generate_expression(&e.this)?;
32666 if e.delete.is_some() {
32667 self.write_keyword(" DELETE");
32668 }
32669 if let Some(recompress) = &e.recompress {
32670 self.write_keyword(" RECOMPRESS ");
32671 self.generate_expression(recompress)?;
32672 }
32673 if let Some(to_disk) = &e.to_disk {
32674 self.write_keyword(" TO DISK ");
32675 self.generate_expression(to_disk)?;
32676 }
32677 if let Some(to_volume) = &e.to_volume {
32678 self.write_keyword(" TO VOLUME ");
32679 self.generate_expression(to_volume)?;
32680 }
32681 Ok(())
32682 }
32683
32684 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
32685 self.write_keyword("MINHASH");
32687 self.write("(");
32688 self.generate_expression(&e.this)?;
32689 for expr in &e.expressions {
32690 self.write(", ");
32691 self.generate_expression(expr)?;
32692 }
32693 self.write(")");
32694 Ok(())
32695 }
32696
32697 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
32698 self.generate_expression(&e.this)?;
32700 self.write("!");
32701 self.generate_expression(&e.expression)?;
32702 Ok(())
32703 }
32704
32705 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
32706 self.write_keyword("MONTHNAME");
32708 self.write("(");
32709 self.generate_expression(&e.this)?;
32710 self.write(")");
32711 Ok(())
32712 }
32713
32714 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
32715 for comment in &e.leading_comments {
32717 self.write_formatted_comment(comment);
32718 if self.config.pretty {
32719 self.write_newline();
32720 self.write_indent();
32721 } else {
32722 self.write_space();
32723 }
32724 }
32725 self.write_keyword("INSERT");
32727 if e.overwrite {
32728 self.write_space();
32729 self.write_keyword("OVERWRITE");
32730 }
32731 self.write_space();
32732 self.write(&e.kind);
32733 if self.config.pretty {
32734 self.indent_level += 1;
32735 for expr in &e.expressions {
32736 self.write_newline();
32737 self.write_indent();
32738 self.generate_expression(expr)?;
32739 }
32740 self.indent_level -= 1;
32741 } else {
32742 for expr in &e.expressions {
32743 self.write_space();
32744 self.generate_expression(expr)?;
32745 }
32746 }
32747 if let Some(source) = &e.source {
32748 if self.config.pretty {
32749 self.write_newline();
32750 self.write_indent();
32751 } else {
32752 self.write_space();
32753 }
32754 self.generate_expression(source)?;
32755 }
32756 Ok(())
32757 }
32758
32759 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
32760 self.write_keyword("NEXT VALUE FOR");
32762 self.write_space();
32763 self.generate_expression(&e.this)?;
32764 if let Some(order) = &e.order {
32765 self.write_space();
32766 self.write_keyword("OVER");
32767 self.write(" (");
32768 self.generate_expression(order)?;
32769 self.write(")");
32770 }
32771 Ok(())
32772 }
32773
32774 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
32775 self.write_keyword("NORMAL");
32777 self.write("(");
32778 self.generate_expression(&e.this)?;
32779 if let Some(stddev) = &e.stddev {
32780 self.write(", ");
32781 self.generate_expression(stddev)?;
32782 }
32783 if let Some(gen) = &e.gen {
32784 self.write(", ");
32785 self.generate_expression(gen)?;
32786 }
32787 self.write(")");
32788 Ok(())
32789 }
32790
32791 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
32792 if e.is_casefold.is_some() {
32794 self.write_keyword("NORMALIZE_AND_CASEFOLD");
32795 } else {
32796 self.write_keyword("NORMALIZE");
32797 }
32798 self.write("(");
32799 self.generate_expression(&e.this)?;
32800 if let Some(form) = &e.form {
32801 self.write(", ");
32802 self.generate_expression(form)?;
32803 }
32804 self.write(")");
32805 Ok(())
32806 }
32807
32808 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
32809 if e.allow_null.is_none() {
32811 self.write_keyword("NOT ");
32812 }
32813 self.write_keyword("NULL");
32814 Ok(())
32815 }
32816
32817 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
32818 self.write_keyword("NULLIF");
32820 self.write("(");
32821 self.generate_expression(&e.this)?;
32822 self.write(", ");
32823 self.generate_expression(&e.expression)?;
32824 self.write(")");
32825 Ok(())
32826 }
32827
32828 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
32829 self.write_keyword("FORMAT");
32831 self.write("(");
32832 self.generate_expression(&e.this)?;
32833 self.write(", '");
32834 self.write(&e.format);
32835 self.write("'");
32836 if let Some(culture) = &e.culture {
32837 self.write(", ");
32838 self.generate_expression(culture)?;
32839 }
32840 self.write(")");
32841 Ok(())
32842 }
32843
32844 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
32845 self.write_keyword("OBJECT_AGG");
32847 self.write("(");
32848 self.generate_expression(&e.this)?;
32849 self.write(", ");
32850 self.generate_expression(&e.expression)?;
32851 self.write(")");
32852 Ok(())
32853 }
32854
32855 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
32856 self.generate_expression(&e.this)?;
32858 Ok(())
32859 }
32860
32861 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
32862 self.write_keyword("OBJECT_INSERT");
32864 self.write("(");
32865 self.generate_expression(&e.this)?;
32866 if let Some(key) = &e.key {
32867 self.write(", ");
32868 self.generate_expression(key)?;
32869 }
32870 if let Some(value) = &e.value {
32871 self.write(", ");
32872 self.generate_expression(value)?;
32873 }
32874 if let Some(update_flag) = &e.update_flag {
32875 self.write(", ");
32876 self.generate_expression(update_flag)?;
32877 }
32878 self.write(")");
32879 Ok(())
32880 }
32881
32882 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
32883 self.write_keyword("OFFSET");
32885 self.write_space();
32886 self.generate_expression(&e.this)?;
32887 if e.rows == Some(true)
32889 && matches!(
32890 self.config.dialect,
32891 Some(crate::dialects::DialectType::TSQL)
32892 | Some(crate::dialects::DialectType::Oracle)
32893 )
32894 {
32895 self.write_space();
32896 self.write_keyword("ROWS");
32897 }
32898 Ok(())
32899 }
32900
32901 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
32902 self.write_keyword("QUALIFY");
32904 self.write_space();
32905 self.generate_expression(&e.this)?;
32906 Ok(())
32907 }
32908
32909 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
32910 self.write_keyword("ON CLUSTER");
32912 self.write_space();
32913 self.generate_expression(&e.this)?;
32914 Ok(())
32915 }
32916
32917 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
32918 self.write_keyword("ON COMMIT");
32920 if e.delete.is_some() {
32921 self.write_keyword(" DELETE ROWS");
32922 } else {
32923 self.write_keyword(" PRESERVE ROWS");
32924 }
32925 Ok(())
32926 }
32927
32928 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
32929 if let Some(empty) = &e.empty {
32931 self.generate_expression(empty)?;
32932 self.write_keyword(" ON EMPTY");
32933 }
32934 if let Some(error) = &e.error {
32935 if e.empty.is_some() {
32936 self.write_space();
32937 }
32938 self.generate_expression(error)?;
32939 self.write_keyword(" ON ERROR");
32940 }
32941 if let Some(null) = &e.null {
32942 if e.empty.is_some() || e.error.is_some() {
32943 self.write_space();
32944 }
32945 self.generate_expression(null)?;
32946 self.write_keyword(" ON NULL");
32947 }
32948 Ok(())
32949 }
32950
32951 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
32952 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
32954 return Ok(());
32955 }
32956 if e.duplicate.is_some() {
32958 self.write_keyword("ON DUPLICATE KEY UPDATE");
32960 for (i, expr) in e.expressions.iter().enumerate() {
32961 if i > 0 {
32962 self.write(",");
32963 }
32964 self.write_space();
32965 self.generate_expression(expr)?;
32966 }
32967 return Ok(());
32968 } else {
32969 self.write_keyword("ON CONFLICT");
32970 }
32971 if let Some(constraint) = &e.constraint {
32972 self.write_keyword(" ON CONSTRAINT ");
32973 self.generate_expression(constraint)?;
32974 }
32975 if let Some(conflict_keys) = &e.conflict_keys {
32976 if let Expression::Tuple(t) = conflict_keys.as_ref() {
32978 self.write("(");
32979 for (i, expr) in t.expressions.iter().enumerate() {
32980 if i > 0 {
32981 self.write(", ");
32982 }
32983 self.generate_expression(expr)?;
32984 }
32985 self.write(")");
32986 } else {
32987 self.write("(");
32988 self.generate_expression(conflict_keys)?;
32989 self.write(")");
32990 }
32991 }
32992 if let Some(index_predicate) = &e.index_predicate {
32993 self.write_keyword(" WHERE ");
32994 self.generate_expression(index_predicate)?;
32995 }
32996 if let Some(action) = &e.action {
32997 if let Expression::Identifier(id) = action.as_ref() {
32999 if id.name.eq_ignore_ascii_case("NOTHING") {
33000 self.write_keyword(" DO NOTHING");
33001 } else {
33002 self.write_keyword(" DO ");
33003 self.generate_expression(action)?;
33004 }
33005 } else if let Expression::Tuple(t) = action.as_ref() {
33006 self.write_keyword(" DO UPDATE SET ");
33008 for (i, expr) in t.expressions.iter().enumerate() {
33009 if i > 0 {
33010 self.write(", ");
33011 }
33012 self.generate_expression(expr)?;
33013 }
33014 } else {
33015 self.write_keyword(" DO ");
33016 self.generate_expression(action)?;
33017 }
33018 }
33019 if let Some(where_) = &e.where_ {
33021 self.write_keyword(" WHERE ");
33022 self.generate_expression(where_)?;
33023 }
33024 Ok(())
33025 }
33026
33027 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
33028 self.write_keyword("ON");
33030 self.write_space();
33031 self.generate_expression(&e.this)?;
33032 Ok(())
33033 }
33034
33035 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
33036 self.generate_expression(&e.this)?;
33038 self.write_space();
33039 self.generate_expression(&e.expression)?;
33040 Ok(())
33041 }
33042
33043 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
33044 self.write_keyword("OPENJSON");
33046 self.write("(");
33047 self.generate_expression(&e.this)?;
33048 if let Some(path) = &e.path {
33049 self.write(", ");
33050 self.generate_expression(path)?;
33051 }
33052 self.write(")");
33053 if !e.expressions.is_empty() {
33054 self.write_keyword(" WITH");
33055 if self.config.pretty {
33056 self.write(" (\n");
33057 self.indent_level += 2;
33058 for (i, expr) in e.expressions.iter().enumerate() {
33059 if i > 0 {
33060 self.write(",\n");
33061 }
33062 self.write_indent();
33063 self.generate_expression(expr)?;
33064 }
33065 self.write("\n");
33066 self.indent_level -= 2;
33067 self.write(")");
33068 } else {
33069 self.write(" (");
33070 for (i, expr) in e.expressions.iter().enumerate() {
33071 if i > 0 {
33072 self.write(", ");
33073 }
33074 self.generate_expression(expr)?;
33075 }
33076 self.write(")");
33077 }
33078 }
33079 Ok(())
33080 }
33081
33082 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
33083 self.generate_expression(&e.this)?;
33085 self.write_space();
33086 if let Some(ref dt) = e.data_type {
33088 self.generate_data_type(dt)?;
33089 } else if !e.kind.is_empty() {
33090 self.write(&e.kind);
33091 }
33092 if let Some(path) = &e.path {
33093 self.write_space();
33094 self.generate_expression(path)?;
33095 }
33096 if e.as_json.is_some() {
33097 self.write_keyword(" AS JSON");
33098 }
33099 Ok(())
33100 }
33101
33102 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
33103 self.generate_expression(&e.this)?;
33105 self.write_space();
33106 if let Some(op) = &e.operator {
33107 self.write_keyword("OPERATOR");
33108 self.write("(");
33109 self.generate_expression(op)?;
33110 self.write(")");
33111 }
33112 for comment in &e.comments {
33114 self.write_space();
33115 self.write_formatted_comment(comment);
33116 }
33117 self.write_space();
33118 self.generate_expression(&e.expression)?;
33119 Ok(())
33120 }
33121
33122 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
33123 self.write_keyword("ORDER BY");
33125 let pretty_clickhouse_single_paren = self.config.pretty
33126 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
33127 && e.expressions.len() == 1
33128 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
33129 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
33130 && e.expressions.len() == 1
33131 && matches!(e.expressions[0].this, Expression::Tuple(_))
33132 && !e.expressions[0].desc
33133 && e.expressions[0].nulls_first.is_none();
33134
33135 if pretty_clickhouse_single_paren {
33136 self.write_space();
33137 if let Expression::Paren(p) = &e.expressions[0].this {
33138 self.write("(");
33139 self.write_newline();
33140 self.indent_level += 1;
33141 self.write_indent();
33142 self.generate_expression(&p.this)?;
33143 self.indent_level -= 1;
33144 self.write_newline();
33145 self.write(")");
33146 }
33147 return Ok(());
33148 }
33149
33150 if clickhouse_single_tuple {
33151 self.write_space();
33152 if let Expression::Tuple(t) = &e.expressions[0].this {
33153 self.write("(");
33154 for (i, expr) in t.expressions.iter().enumerate() {
33155 if i > 0 {
33156 self.write(", ");
33157 }
33158 self.generate_expression(expr)?;
33159 }
33160 self.write(")");
33161 }
33162 return Ok(());
33163 }
33164
33165 self.write_space();
33166 for (i, ordered) in e.expressions.iter().enumerate() {
33167 if i > 0 {
33168 self.write(", ");
33169 }
33170 self.generate_expression(&ordered.this)?;
33171 if ordered.desc {
33172 self.write_space();
33173 self.write_keyword("DESC");
33174 } else if ordered.explicit_asc {
33175 self.write_space();
33176 self.write_keyword("ASC");
33177 }
33178 if let Some(nulls_first) = ordered.nulls_first {
33179 let skip_nulls_last =
33181 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
33182 if !skip_nulls_last {
33183 self.write_space();
33184 self.write_keyword("NULLS");
33185 self.write_space();
33186 if nulls_first {
33187 self.write_keyword("FIRST");
33188 } else {
33189 self.write_keyword("LAST");
33190 }
33191 }
33192 }
33193 }
33194 Ok(())
33195 }
33196
33197 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
33198 self.write_keyword("OUTPUT");
33200 self.write("(");
33201 if self.config.pretty {
33202 self.indent_level += 1;
33203 self.write_newline();
33204 self.write_indent();
33205 self.generate_expression(&e.this)?;
33206 self.indent_level -= 1;
33207 self.write_newline();
33208 } else {
33209 self.generate_expression(&e.this)?;
33210 }
33211 self.write(")");
33212 Ok(())
33213 }
33214
33215 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
33216 self.write_keyword("TRUNCATE");
33218 if let Some(this) = &e.this {
33219 self.write_space();
33220 self.generate_expression(this)?;
33221 }
33222 if e.with_count.is_some() {
33223 self.write_keyword(" WITH COUNT");
33224 } else {
33225 self.write_keyword(" WITHOUT COUNT");
33226 }
33227 Ok(())
33228 }
33229
33230 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
33231 self.generate_expression(&e.this)?;
33233 self.write("(");
33234 for (i, expr) in e.expressions.iter().enumerate() {
33235 if i > 0 {
33236 self.write(", ");
33237 }
33238 self.generate_expression(expr)?;
33239 }
33240 self.write(")(");
33241 for (i, param) in e.params.iter().enumerate() {
33242 if i > 0 {
33243 self.write(", ");
33244 }
33245 self.generate_expression(param)?;
33246 }
33247 self.write(")");
33248 Ok(())
33249 }
33250
33251 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
33252 self.write_keyword("PARSE_DATETIME");
33254 self.write("(");
33255 if let Some(format) = &e.format {
33256 self.write("'");
33257 self.write(format);
33258 self.write("', ");
33259 }
33260 self.generate_expression(&e.this)?;
33261 if let Some(zone) = &e.zone {
33262 self.write(", ");
33263 self.generate_expression(zone)?;
33264 }
33265 self.write(")");
33266 Ok(())
33267 }
33268
33269 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
33270 self.write_keyword("PARSE_IP");
33272 self.write("(");
33273 self.generate_expression(&e.this)?;
33274 if let Some(type_) = &e.type_ {
33275 self.write(", ");
33276 self.generate_expression(type_)?;
33277 }
33278 if let Some(permissive) = &e.permissive {
33279 self.write(", ");
33280 self.generate_expression(permissive)?;
33281 }
33282 self.write(")");
33283 Ok(())
33284 }
33285
33286 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
33287 self.write_keyword("PARSE_JSON");
33289 self.write("(");
33290 self.generate_expression(&e.this)?;
33291 if let Some(expression) = &e.expression {
33292 self.write(", ");
33293 self.generate_expression(expression)?;
33294 }
33295 self.write(")");
33296 Ok(())
33297 }
33298
33299 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
33300 self.write_keyword("PARSE_TIME");
33302 self.write("(");
33303 self.write(&format!("'{}'", e.format));
33304 self.write(", ");
33305 self.generate_expression(&e.this)?;
33306 self.write(")");
33307 Ok(())
33308 }
33309
33310 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
33311 self.write_keyword("PARSE_URL");
33313 self.write("(");
33314 self.generate_expression(&e.this)?;
33315 if let Some(part) = &e.part_to_extract {
33316 self.write(", ");
33317 self.generate_expression(part)?;
33318 }
33319 if let Some(key) = &e.key {
33320 self.write(", ");
33321 self.generate_expression(key)?;
33322 }
33323 if let Some(permissive) = &e.permissive {
33324 self.write(", ");
33325 self.generate_expression(permissive)?;
33326 }
33327 self.write(")");
33328 Ok(())
33329 }
33330
33331 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
33332 if e.subpartition {
33334 self.write_keyword("SUBPARTITION");
33335 } else {
33336 self.write_keyword("PARTITION");
33337 }
33338 self.write("(");
33339 for (i, expr) in e.expressions.iter().enumerate() {
33340 if i > 0 {
33341 self.write(", ");
33342 }
33343 self.generate_expression(expr)?;
33344 }
33345 self.write(")");
33346 Ok(())
33347 }
33348
33349 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
33350 if let Some(this) = &e.this {
33352 if let Some(expression) = &e.expression {
33353 self.write_keyword("WITH");
33355 self.write(" (");
33356 self.write_keyword("MODULUS");
33357 self.write_space();
33358 self.generate_expression(this)?;
33359 self.write(", ");
33360 self.write_keyword("REMAINDER");
33361 self.write_space();
33362 self.generate_expression(expression)?;
33363 self.write(")");
33364 } else {
33365 self.write_keyword("IN");
33367 self.write(" (");
33368 self.generate_partition_bound_values(this)?;
33369 self.write(")");
33370 }
33371 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
33372 self.write_keyword("FROM");
33374 self.write(" (");
33375 self.generate_partition_bound_values(from)?;
33376 self.write(") ");
33377 self.write_keyword("TO");
33378 self.write(" (");
33379 self.generate_partition_bound_values(to)?;
33380 self.write(")");
33381 }
33382 Ok(())
33383 }
33384
33385 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
33388 if let Expression::Tuple(t) = expr {
33389 for (i, e) in t.expressions.iter().enumerate() {
33390 if i > 0 {
33391 self.write(", ");
33392 }
33393 self.generate_expression(e)?;
33394 }
33395 Ok(())
33396 } else {
33397 self.generate_expression(expr)
33398 }
33399 }
33400
33401 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
33402 self.write_keyword("PARTITION BY LIST");
33404 if let Some(partition_exprs) = &e.partition_expressions {
33405 self.write(" (");
33406 self.generate_doris_partition_expressions(partition_exprs)?;
33408 self.write(")");
33409 }
33410 if let Some(create_exprs) = &e.create_expressions {
33411 self.write(" (");
33412 self.generate_doris_partition_definitions(create_exprs)?;
33414 self.write(")");
33415 }
33416 Ok(())
33417 }
33418
33419 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
33420 self.write_keyword("PARTITION BY RANGE");
33422 if let Some(partition_exprs) = &e.partition_expressions {
33423 self.write(" (");
33424 self.generate_doris_partition_expressions(partition_exprs)?;
33426 self.write(")");
33427 }
33428 if let Some(create_exprs) = &e.create_expressions {
33429 self.write(" (");
33430 self.generate_doris_partition_definitions(create_exprs)?;
33432 self.write(")");
33433 }
33434 Ok(())
33435 }
33436
33437 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
33439 if let Expression::Tuple(t) = expr {
33440 for (i, e) in t.expressions.iter().enumerate() {
33441 if i > 0 {
33442 self.write(", ");
33443 }
33444 self.generate_expression(e)?;
33445 }
33446 } else {
33447 self.generate_expression(expr)?;
33448 }
33449 Ok(())
33450 }
33451
33452 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
33454 match expr {
33455 Expression::Tuple(t) => {
33456 for (i, part) in t.expressions.iter().enumerate() {
33458 if i > 0 {
33459 self.write(", ");
33460 }
33461 if let Expression::Partition(p) = part {
33463 for (j, inner) in p.expressions.iter().enumerate() {
33464 if j > 0 {
33465 self.write(", ");
33466 }
33467 self.generate_expression(inner)?;
33468 }
33469 } else {
33470 self.generate_expression(part)?;
33471 }
33472 }
33473 }
33474 Expression::PartitionByRangePropertyDynamic(_) => {
33475 self.generate_expression(expr)?;
33477 }
33478 _ => {
33479 self.generate_expression(expr)?;
33480 }
33481 }
33482 Ok(())
33483 }
33484
33485 fn generate_partition_by_range_property_dynamic(
33486 &mut self,
33487 e: &PartitionByRangePropertyDynamic,
33488 ) -> Result<()> {
33489 if e.use_start_end {
33490 if let Some(start) = &e.start {
33492 self.write_keyword("START");
33493 self.write(" (");
33494 self.generate_expression(start)?;
33495 self.write(")");
33496 }
33497 if let Some(end) = &e.end {
33498 self.write_space();
33499 self.write_keyword("END");
33500 self.write(" (");
33501 self.generate_expression(end)?;
33502 self.write(")");
33503 }
33504 if let Some(every) = &e.every {
33505 self.write_space();
33506 self.write_keyword("EVERY");
33507 self.write(" (");
33508 self.generate_doris_interval(every)?;
33510 self.write(")");
33511 }
33512 } else {
33513 if let Some(start) = &e.start {
33515 self.write_keyword("FROM");
33516 self.write(" (");
33517 self.generate_expression(start)?;
33518 self.write(")");
33519 }
33520 if let Some(end) = &e.end {
33521 self.write_space();
33522 self.write_keyword("TO");
33523 self.write(" (");
33524 self.generate_expression(end)?;
33525 self.write(")");
33526 }
33527 if let Some(every) = &e.every {
33528 self.write_space();
33529 self.generate_doris_interval(every)?;
33531 }
33532 }
33533 Ok(())
33534 }
33535
33536 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
33538 if let Expression::Interval(interval) = expr {
33539 self.write_keyword("INTERVAL");
33540 if let Some(ref value) = interval.this {
33541 self.write_space();
33542 match value {
33546 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()) => {
33547 if let Literal::String(s) = lit.as_ref() {
33548 self.write(s);
33549 }
33550 }
33551 _ => {
33552 self.generate_expression(value)?;
33553 }
33554 }
33555 }
33556 if let Some(ref unit_spec) = interval.unit {
33557 self.write_space();
33558 self.write_interval_unit_spec(unit_spec)?;
33559 }
33560 Ok(())
33561 } else {
33562 self.generate_expression(expr)
33563 }
33564 }
33565
33566 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
33567 self.write_keyword("TRUNCATE");
33569 self.write("(");
33570 self.generate_expression(&e.expression)?;
33571 self.write(", ");
33572 self.generate_expression(&e.this)?;
33573 self.write(")");
33574 Ok(())
33575 }
33576
33577 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
33578 self.write_keyword("PARTITION");
33580 self.write_space();
33581 self.generate_expression(&e.this)?;
33582 self.write_space();
33583 self.write_keyword("VALUES IN");
33584 self.write(" (");
33585 for (i, expr) in e.expressions.iter().enumerate() {
33586 if i > 0 {
33587 self.write(", ");
33588 }
33589 self.generate_expression(expr)?;
33590 }
33591 self.write(")");
33592 Ok(())
33593 }
33594
33595 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
33596 if e.expressions.is_empty() && e.expression.is_some() {
33599 self.generate_expression(&e.this)?;
33601 self.write_space();
33602 self.write_keyword("TO");
33603 self.write_space();
33604 self.generate_expression(e.expression.as_ref().unwrap())?;
33605 return Ok(());
33606 }
33607
33608 self.write_keyword("PARTITION");
33610 self.write_space();
33611 self.generate_expression(&e.this)?;
33612 self.write_space();
33613
33614 if e.expressions.len() == 1 {
33616 self.write_keyword("VALUES LESS THAN");
33618 self.write(" (");
33619 self.generate_expression(&e.expressions[0])?;
33620 self.write(")");
33621 } else if !e.expressions.is_empty() {
33622 self.write_keyword("VALUES");
33624 self.write(" [");
33625 for (i, expr) in e.expressions.iter().enumerate() {
33626 if i > 0 {
33627 self.write(", ");
33628 }
33629 if let Expression::Tuple(t) = expr {
33631 self.write("(");
33632 for (j, inner) in t.expressions.iter().enumerate() {
33633 if j > 0 {
33634 self.write(", ");
33635 }
33636 self.generate_expression(inner)?;
33637 }
33638 self.write(")");
33639 } else {
33640 self.write("(");
33641 self.generate_expression(expr)?;
33642 self.write(")");
33643 }
33644 }
33645 self.write(")");
33646 }
33647 Ok(())
33648 }
33649
33650 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
33651 self.write_keyword("BUCKET");
33653 self.write("(");
33654 self.generate_expression(&e.this)?;
33655 self.write(", ");
33656 self.generate_expression(&e.expression)?;
33657 self.write(")");
33658 Ok(())
33659 }
33660
33661 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
33662 self.write_keyword("PARTITION BY");
33664 self.write_space();
33665 for (i, expr) in e.expressions.iter().enumerate() {
33666 if i > 0 {
33667 self.write(", ");
33668 }
33669 self.generate_expression(expr)?;
33670 }
33671 Ok(())
33672 }
33673
33674 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
33675 if matches!(
33677 self.config.dialect,
33678 Some(crate::dialects::DialectType::Teradata)
33679 | Some(crate::dialects::DialectType::ClickHouse)
33680 ) {
33681 self.write_keyword("PARTITION BY");
33682 } else {
33683 self.write_keyword("PARTITIONED BY");
33684 }
33685 self.write_space();
33686 if self.config.pretty {
33688 if let Expression::Tuple(ref tuple) = *e.this {
33689 self.write("(");
33690 self.write_newline();
33691 self.indent_level += 1;
33692 for (i, expr) in tuple.expressions.iter().enumerate() {
33693 if i > 0 {
33694 self.write(",");
33695 self.write_newline();
33696 }
33697 self.write_indent();
33698 self.generate_expression(expr)?;
33699 }
33700 self.indent_level -= 1;
33701 self.write_newline();
33702 self.write(")");
33703 } else {
33704 self.generate_expression(&e.this)?;
33705 }
33706 } else {
33707 self.generate_expression(&e.this)?;
33708 }
33709 Ok(())
33710 }
33711
33712 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
33713 self.write_keyword("PARTITION OF");
33715 self.write_space();
33716 self.generate_expression(&e.this)?;
33717 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
33719 self.write_space();
33720 self.write_keyword("FOR VALUES");
33721 self.write_space();
33722 self.generate_expression(&e.expression)?;
33723 } else {
33724 self.write_space();
33725 self.write_keyword("DEFAULT");
33726 }
33727 Ok(())
33728 }
33729
33730 fn generate_period_for_system_time_constraint(
33731 &mut self,
33732 e: &PeriodForSystemTimeConstraint,
33733 ) -> Result<()> {
33734 self.write_keyword("PERIOD FOR SYSTEM_TIME");
33736 self.write(" (");
33737 self.generate_expression(&e.this)?;
33738 self.write(", ");
33739 self.generate_expression(&e.expression)?;
33740 self.write(")");
33741 Ok(())
33742 }
33743
33744 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
33745 self.generate_expression(&e.this)?;
33748 self.write_space();
33749 self.write_keyword("AS");
33750 self.write_space();
33751 if self.config.unpivot_aliases_are_identifiers {
33753 match &e.alias {
33754 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
33755 let Literal::String(s) = lit.as_ref() else {
33756 unreachable!()
33757 };
33758 self.generate_identifier(&Identifier::new(s.clone()))?;
33760 }
33761 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
33762 let Literal::Number(n) = lit.as_ref() else {
33763 unreachable!()
33764 };
33765 let mut id = Identifier::new(n.clone());
33767 id.quoted = true;
33768 self.generate_identifier(&id)?;
33769 }
33770 other => {
33771 self.generate_expression(other)?;
33772 }
33773 }
33774 } else {
33775 self.generate_expression(&e.alias)?;
33776 }
33777 Ok(())
33778 }
33779
33780 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
33781 self.write_keyword("ANY");
33783 if let Some(this) = &e.this {
33784 self.write_space();
33785 self.generate_expression(this)?;
33786 }
33787 Ok(())
33788 }
33789
33790 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
33791 self.write_keyword("ML.PREDICT");
33793 self.write("(");
33794 self.write_keyword("MODEL");
33795 self.write_space();
33796 self.generate_expression(&e.this)?;
33797 self.write(", ");
33798 self.generate_expression(&e.expression)?;
33799 if let Some(params) = &e.params_struct {
33800 self.write(", ");
33801 self.generate_expression(params)?;
33802 }
33803 self.write(")");
33804 Ok(())
33805 }
33806
33807 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
33808 self.write_keyword("PREVIOUS_DAY");
33810 self.write("(");
33811 self.generate_expression(&e.this)?;
33812 self.write(", ");
33813 self.generate_expression(&e.expression)?;
33814 self.write(")");
33815 Ok(())
33816 }
33817
33818 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
33819 self.write_keyword("PRIMARY KEY");
33821 if let Some(name) = &e.this {
33822 self.write_space();
33823 self.generate_expression(name)?;
33824 }
33825 if !e.expressions.is_empty() {
33826 self.write(" (");
33827 for (i, expr) in e.expressions.iter().enumerate() {
33828 if i > 0 {
33829 self.write(", ");
33830 }
33831 self.generate_expression(expr)?;
33832 }
33833 self.write(")");
33834 }
33835 if let Some(include) = &e.include {
33836 self.write_space();
33837 self.generate_expression(include)?;
33838 }
33839 if !e.options.is_empty() {
33840 self.write_space();
33841 for (i, opt) in e.options.iter().enumerate() {
33842 if i > 0 {
33843 self.write_space();
33844 }
33845 self.generate_expression(opt)?;
33846 }
33847 }
33848 Ok(())
33849 }
33850
33851 fn generate_primary_key_column_constraint(
33852 &mut self,
33853 _e: &PrimaryKeyColumnConstraint,
33854 ) -> Result<()> {
33855 self.write_keyword("PRIMARY KEY");
33857 Ok(())
33858 }
33859
33860 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
33861 self.write_keyword("PATH");
33863 self.write_space();
33864 self.generate_expression(&e.this)?;
33865 Ok(())
33866 }
33867
33868 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
33869 self.write_keyword("PROJECTION");
33871 self.write_space();
33872 self.generate_expression(&e.this)?;
33873 self.write(" (");
33874 self.generate_expression(&e.expression)?;
33875 self.write(")");
33876 Ok(())
33877 }
33878
33879 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
33880 for (i, prop) in e.expressions.iter().enumerate() {
33882 if i > 0 {
33883 self.write(", ");
33884 }
33885 self.generate_expression(prop)?;
33886 }
33887 Ok(())
33888 }
33889
33890 fn generate_property(&mut self, e: &Property) -> Result<()> {
33891 self.generate_expression(&e.this)?;
33893 if let Some(value) = &e.value {
33894 self.write("=");
33895 self.generate_expression(value)?;
33896 }
33897 Ok(())
33898 }
33899
33900 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
33901 self.write_keyword("OPTIONS");
33902 if e.entries.is_empty() {
33903 self.write(" ()");
33904 return Ok(());
33905 }
33906
33907 if self.config.pretty {
33908 self.write(" (");
33909 self.write_newline();
33910 self.indent_level += 1;
33911 for (i, entry) in e.entries.iter().enumerate() {
33912 if i > 0 {
33913 self.write(",");
33914 self.write_newline();
33915 }
33916 self.write_indent();
33917 self.generate_identifier(&entry.key)?;
33918 self.write("=");
33919 self.generate_expression(&entry.value)?;
33920 }
33921 self.indent_level -= 1;
33922 self.write_newline();
33923 self.write(")");
33924 } else {
33925 self.write(" (");
33926 for (i, entry) in e.entries.iter().enumerate() {
33927 if i > 0 {
33928 self.write(", ");
33929 }
33930 self.generate_identifier(&entry.key)?;
33931 self.write("=");
33932 self.generate_expression(&entry.value)?;
33933 }
33934 self.write(")");
33935 }
33936 Ok(())
33937 }
33938
33939 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
33941 self.write_keyword("OPTIONS");
33942 self.write(" (");
33943 for (i, opt) in options.iter().enumerate() {
33944 if i > 0 {
33945 self.write(", ");
33946 }
33947 self.generate_option_expression(opt)?;
33948 }
33949 self.write(")");
33950 Ok(())
33951 }
33952
33953 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
33955 self.write_keyword("PROPERTIES");
33956 self.write(" (");
33957 for (i, prop) in properties.iter().enumerate() {
33958 if i > 0 {
33959 self.write(", ");
33960 }
33961 self.generate_option_expression(prop)?;
33962 }
33963 self.write(")");
33964 Ok(())
33965 }
33966
33967 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
33969 self.write_keyword("ENVIRONMENT");
33970 self.write(" (");
33971 for (i, env_item) in environment.iter().enumerate() {
33972 if i > 0 {
33973 self.write(", ");
33974 }
33975 self.generate_environment_expression(env_item)?;
33976 }
33977 self.write(")");
33978 Ok(())
33979 }
33980
33981 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
33983 match expr {
33984 Expression::Eq(eq) => {
33985 self.generate_expression(&eq.left)?;
33987 self.write(" = ");
33988 self.generate_expression(&eq.right)?;
33989 Ok(())
33990 }
33991 _ => self.generate_expression(expr),
33992 }
33993 }
33994
33995 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
33997 self.write_keyword("TBLPROPERTIES");
33998 if self.config.pretty {
33999 self.write(" (");
34000 self.write_newline();
34001 self.indent_level += 1;
34002 for (i, opt) in options.iter().enumerate() {
34003 if i > 0 {
34004 self.write(",");
34005 self.write_newline();
34006 }
34007 self.write_indent();
34008 self.generate_option_expression(opt)?;
34009 }
34010 self.indent_level -= 1;
34011 self.write_newline();
34012 self.write(")");
34013 } else {
34014 self.write(" (");
34015 for (i, opt) in options.iter().enumerate() {
34016 if i > 0 {
34017 self.write(", ");
34018 }
34019 self.generate_option_expression(opt)?;
34020 }
34021 self.write(")");
34022 }
34023 Ok(())
34024 }
34025
34026 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
34028 match expr {
34029 Expression::Eq(eq) => {
34030 self.generate_expression(&eq.left)?;
34032 self.write("=");
34033 self.generate_expression(&eq.right)?;
34034 Ok(())
34035 }
34036 _ => self.generate_expression(expr),
34037 }
34038 }
34039
34040 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
34041 self.generate_expression(&e.this)?;
34043 Ok(())
34044 }
34045
34046 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
34047 self.write_keyword("PUT");
34049 self.write_space();
34050
34051 if e.source_quoted {
34053 self.write("'");
34054 self.write(&e.source);
34055 self.write("'");
34056 } else {
34057 self.write(&e.source);
34058 }
34059
34060 self.write_space();
34061
34062 if let Expression::Literal(lit) = &e.target {
34064 if let Literal::String(s) = lit.as_ref() {
34065 self.write(s);
34066 }
34067 } else {
34068 self.generate_expression(&e.target)?;
34069 }
34070
34071 for param in &e.params {
34073 self.write_space();
34074 self.write(¶m.name);
34075 if let Some(ref value) = param.value {
34076 self.write("=");
34077 self.generate_expression(value)?;
34078 }
34079 }
34080
34081 Ok(())
34082 }
34083
34084 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
34085 self.write_keyword("QUANTILE");
34087 self.write("(");
34088 self.generate_expression(&e.this)?;
34089 if let Some(quantile) = &e.quantile {
34090 self.write(", ");
34091 self.generate_expression(quantile)?;
34092 }
34093 self.write(")");
34094 Ok(())
34095 }
34096
34097 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
34098 if matches!(
34100 self.config.dialect,
34101 Some(crate::dialects::DialectType::Teradata)
34102 ) {
34103 self.write_keyword("SET");
34104 self.write_space();
34105 }
34106 self.write_keyword("QUERY_BAND");
34107 self.write(" = ");
34108 self.generate_expression(&e.this)?;
34109 if e.update.is_some() {
34110 self.write_space();
34111 self.write_keyword("UPDATE");
34112 }
34113 if let Some(scope) = &e.scope {
34114 self.write_space();
34115 self.write_keyword("FOR");
34116 self.write_space();
34117 self.generate_expression(scope)?;
34118 }
34119 Ok(())
34120 }
34121
34122 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
34123 self.generate_expression(&e.this)?;
34125 if let Some(expression) = &e.expression {
34126 self.write(" = ");
34127 self.generate_expression(expression)?;
34128 }
34129 Ok(())
34130 }
34131
34132 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
34133 self.write_keyword("TRANSFORM");
34135 self.write("(");
34136 for (i, expr) in e.expressions.iter().enumerate() {
34137 if i > 0 {
34138 self.write(", ");
34139 }
34140 self.generate_expression(expr)?;
34141 }
34142 self.write(")");
34143 if let Some(row_format_before) = &e.row_format_before {
34144 self.write_space();
34145 self.generate_expression(row_format_before)?;
34146 }
34147 if let Some(record_writer) = &e.record_writer {
34148 self.write_space();
34149 self.write_keyword("RECORDWRITER");
34150 self.write_space();
34151 self.generate_expression(record_writer)?;
34152 }
34153 if let Some(command_script) = &e.command_script {
34154 self.write_space();
34155 self.write_keyword("USING");
34156 self.write_space();
34157 self.generate_expression(command_script)?;
34158 }
34159 if let Some(schema) = &e.schema {
34160 self.write_space();
34161 self.write_keyword("AS");
34162 self.write_space();
34163 self.generate_expression(schema)?;
34164 }
34165 if let Some(row_format_after) = &e.row_format_after {
34166 self.write_space();
34167 self.generate_expression(row_format_after)?;
34168 }
34169 if let Some(record_reader) = &e.record_reader {
34170 self.write_space();
34171 self.write_keyword("RECORDREADER");
34172 self.write_space();
34173 self.generate_expression(record_reader)?;
34174 }
34175 Ok(())
34176 }
34177
34178 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
34179 self.write_keyword("RANDN");
34181 self.write("(");
34182 if let Some(this) = &e.this {
34183 self.generate_expression(this)?;
34184 }
34185 self.write(")");
34186 Ok(())
34187 }
34188
34189 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
34190 self.write_keyword("RANDSTR");
34192 self.write("(");
34193 self.generate_expression(&e.this)?;
34194 if let Some(generator) = &e.generator {
34195 self.write(", ");
34196 self.generate_expression(generator)?;
34197 }
34198 self.write(")");
34199 Ok(())
34200 }
34201
34202 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
34203 self.write_keyword("RANGE_BUCKET");
34205 self.write("(");
34206 self.generate_expression(&e.this)?;
34207 self.write(", ");
34208 self.generate_expression(&e.expression)?;
34209 self.write(")");
34210 Ok(())
34211 }
34212
34213 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
34214 self.write_keyword("RANGE_N");
34216 self.write("(");
34217 self.generate_expression(&e.this)?;
34218 self.write_space();
34219 self.write_keyword("BETWEEN");
34220 self.write_space();
34221 for (i, expr) in e.expressions.iter().enumerate() {
34222 if i > 0 {
34223 self.write(", ");
34224 }
34225 self.generate_expression(expr)?;
34226 }
34227 if let Some(each) = &e.each {
34228 self.write_space();
34229 self.write_keyword("EACH");
34230 self.write_space();
34231 self.generate_expression(each)?;
34232 }
34233 self.write(")");
34234 Ok(())
34235 }
34236
34237 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
34238 self.write_keyword("READ_CSV");
34240 self.write("(");
34241 self.generate_expression(&e.this)?;
34242 for expr in &e.expressions {
34243 self.write(", ");
34244 self.generate_expression(expr)?;
34245 }
34246 self.write(")");
34247 Ok(())
34248 }
34249
34250 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
34251 self.write_keyword("READ_PARQUET");
34253 self.write("(");
34254 for (i, expr) in e.expressions.iter().enumerate() {
34255 if i > 0 {
34256 self.write(", ");
34257 }
34258 self.generate_expression(expr)?;
34259 }
34260 self.write(")");
34261 Ok(())
34262 }
34263
34264 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
34265 if e.kind == "CYCLE" {
34268 self.write_keyword("CYCLE");
34269 } else {
34270 self.write_keyword("SEARCH");
34271 self.write_space();
34272 self.write(&e.kind);
34273 self.write_space();
34274 self.write_keyword("FIRST BY");
34275 }
34276 self.write_space();
34277 self.generate_expression(&e.this)?;
34278 self.write_space();
34279 self.write_keyword("SET");
34280 self.write_space();
34281 self.generate_expression(&e.expression)?;
34282 if let Some(using) = &e.using {
34283 self.write_space();
34284 self.write_keyword("USING");
34285 self.write_space();
34286 self.generate_expression(using)?;
34287 }
34288 Ok(())
34289 }
34290
34291 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
34292 self.write_keyword("REDUCE");
34294 self.write("(");
34295 self.generate_expression(&e.this)?;
34296 if let Some(initial) = &e.initial {
34297 self.write(", ");
34298 self.generate_expression(initial)?;
34299 }
34300 if let Some(merge) = &e.merge {
34301 self.write(", ");
34302 self.generate_expression(merge)?;
34303 }
34304 if let Some(finish) = &e.finish {
34305 self.write(", ");
34306 self.generate_expression(finish)?;
34307 }
34308 self.write(")");
34309 Ok(())
34310 }
34311
34312 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
34313 self.write_keyword("REFERENCES");
34315 self.write_space();
34316 self.generate_expression(&e.this)?;
34317 if !e.expressions.is_empty() {
34318 self.write(" (");
34319 for (i, expr) in e.expressions.iter().enumerate() {
34320 if i > 0 {
34321 self.write(", ");
34322 }
34323 self.generate_expression(expr)?;
34324 }
34325 self.write(")");
34326 }
34327 for opt in &e.options {
34328 self.write_space();
34329 self.generate_expression(opt)?;
34330 }
34331 Ok(())
34332 }
34333
34334 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
34335 self.write_keyword("REFRESH");
34337 if !e.kind.is_empty() {
34338 self.write_space();
34339 self.write_keyword(&e.kind);
34340 }
34341 self.write_space();
34342 self.generate_expression(&e.this)?;
34343 Ok(())
34344 }
34345
34346 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
34347 self.write_keyword("REFRESH");
34349 self.write_space();
34350 self.write_keyword(&e.method);
34351
34352 if let Some(ref kind) = e.kind {
34353 self.write_space();
34354 self.write_keyword("ON");
34355 self.write_space();
34356 self.write_keyword(kind);
34357
34358 if let Some(ref every) = e.every {
34360 self.write_space();
34361 self.write_keyword("EVERY");
34362 self.write_space();
34363 self.generate_expression(every)?;
34364 if let Some(ref unit) = e.unit {
34365 self.write_space();
34366 self.write_keyword(unit);
34367 }
34368 }
34369
34370 if let Some(ref starts) = e.starts {
34372 self.write_space();
34373 self.write_keyword("STARTS");
34374 self.write_space();
34375 self.generate_expression(starts)?;
34376 }
34377 }
34378 Ok(())
34379 }
34380
34381 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
34382 self.write_keyword("REGEXP_COUNT");
34384 self.write("(");
34385 self.generate_expression(&e.this)?;
34386 self.write(", ");
34387 self.generate_expression(&e.expression)?;
34388 if let Some(position) = &e.position {
34389 self.write(", ");
34390 self.generate_expression(position)?;
34391 }
34392 if let Some(parameters) = &e.parameters {
34393 self.write(", ");
34394 self.generate_expression(parameters)?;
34395 }
34396 self.write(")");
34397 Ok(())
34398 }
34399
34400 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
34401 self.write_keyword("REGEXP_EXTRACT_ALL");
34403 self.write("(");
34404 self.generate_expression(&e.this)?;
34405 self.write(", ");
34406 self.generate_expression(&e.expression)?;
34407 if let Some(group) = &e.group {
34408 self.write(", ");
34409 self.generate_expression(group)?;
34410 }
34411 self.write(")");
34412 Ok(())
34413 }
34414
34415 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
34416 self.write_keyword("REGEXP_FULL_MATCH");
34418 self.write("(");
34419 self.generate_expression(&e.this)?;
34420 self.write(", ");
34421 self.generate_expression(&e.expression)?;
34422 self.write(")");
34423 Ok(())
34424 }
34425
34426 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
34427 use crate::dialects::DialectType;
34428 if matches!(
34430 self.config.dialect,
34431 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
34432 ) && e.flag.is_none()
34433 {
34434 self.generate_expression(&e.this)?;
34435 self.write(" ~* ");
34436 self.generate_expression(&e.expression)?;
34437 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
34438 self.write_keyword("REGEXP_LIKE");
34440 self.write("(");
34441 self.generate_expression(&e.this)?;
34442 self.write(", ");
34443 self.generate_expression(&e.expression)?;
34444 self.write(", ");
34445 if let Some(flag) = &e.flag {
34446 self.generate_expression(flag)?;
34447 } else {
34448 self.write("'i'");
34449 }
34450 self.write(")");
34451 } else {
34452 self.generate_expression(&e.this)?;
34454 self.write_space();
34455 self.write_keyword("REGEXP_ILIKE");
34456 self.write_space();
34457 self.generate_expression(&e.expression)?;
34458 if let Some(flag) = &e.flag {
34459 self.write(", ");
34460 self.generate_expression(flag)?;
34461 }
34462 }
34463 Ok(())
34464 }
34465
34466 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
34467 self.write_keyword("REGEXP_INSTR");
34469 self.write("(");
34470 self.generate_expression(&e.this)?;
34471 self.write(", ");
34472 self.generate_expression(&e.expression)?;
34473 if let Some(position) = &e.position {
34474 self.write(", ");
34475 self.generate_expression(position)?;
34476 }
34477 if let Some(occurrence) = &e.occurrence {
34478 self.write(", ");
34479 self.generate_expression(occurrence)?;
34480 }
34481 if let Some(option) = &e.option {
34482 self.write(", ");
34483 self.generate_expression(option)?;
34484 }
34485 if let Some(parameters) = &e.parameters {
34486 self.write(", ");
34487 self.generate_expression(parameters)?;
34488 }
34489 if let Some(group) = &e.group {
34490 self.write(", ");
34491 self.generate_expression(group)?;
34492 }
34493 self.write(")");
34494 Ok(())
34495 }
34496
34497 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
34498 self.write_keyword("REGEXP_SPLIT");
34500 self.write("(");
34501 self.generate_expression(&e.this)?;
34502 self.write(", ");
34503 self.generate_expression(&e.expression)?;
34504 if let Some(limit) = &e.limit {
34505 self.write(", ");
34506 self.generate_expression(limit)?;
34507 }
34508 self.write(")");
34509 Ok(())
34510 }
34511
34512 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
34513 self.write_keyword("REGR_AVGX");
34515 self.write("(");
34516 self.generate_expression(&e.this)?;
34517 self.write(", ");
34518 self.generate_expression(&e.expression)?;
34519 self.write(")");
34520 Ok(())
34521 }
34522
34523 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
34524 self.write_keyword("REGR_AVGY");
34526 self.write("(");
34527 self.generate_expression(&e.this)?;
34528 self.write(", ");
34529 self.generate_expression(&e.expression)?;
34530 self.write(")");
34531 Ok(())
34532 }
34533
34534 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
34535 self.write_keyword("REGR_COUNT");
34537 self.write("(");
34538 self.generate_expression(&e.this)?;
34539 self.write(", ");
34540 self.generate_expression(&e.expression)?;
34541 self.write(")");
34542 Ok(())
34543 }
34544
34545 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
34546 self.write_keyword("REGR_INTERCEPT");
34548 self.write("(");
34549 self.generate_expression(&e.this)?;
34550 self.write(", ");
34551 self.generate_expression(&e.expression)?;
34552 self.write(")");
34553 Ok(())
34554 }
34555
34556 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
34557 self.write_keyword("REGR_R2");
34559 self.write("(");
34560 self.generate_expression(&e.this)?;
34561 self.write(", ");
34562 self.generate_expression(&e.expression)?;
34563 self.write(")");
34564 Ok(())
34565 }
34566
34567 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
34568 self.write_keyword("REGR_SLOPE");
34570 self.write("(");
34571 self.generate_expression(&e.this)?;
34572 self.write(", ");
34573 self.generate_expression(&e.expression)?;
34574 self.write(")");
34575 Ok(())
34576 }
34577
34578 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
34579 self.write_keyword("REGR_SXX");
34581 self.write("(");
34582 self.generate_expression(&e.this)?;
34583 self.write(", ");
34584 self.generate_expression(&e.expression)?;
34585 self.write(")");
34586 Ok(())
34587 }
34588
34589 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
34590 self.write_keyword("REGR_SXY");
34592 self.write("(");
34593 self.generate_expression(&e.this)?;
34594 self.write(", ");
34595 self.generate_expression(&e.expression)?;
34596 self.write(")");
34597 Ok(())
34598 }
34599
34600 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
34601 self.write_keyword("REGR_SYY");
34603 self.write("(");
34604 self.generate_expression(&e.this)?;
34605 self.write(", ");
34606 self.generate_expression(&e.expression)?;
34607 self.write(")");
34608 Ok(())
34609 }
34610
34611 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
34612 self.write_keyword("REGR_VALX");
34614 self.write("(");
34615 self.generate_expression(&e.this)?;
34616 self.write(", ");
34617 self.generate_expression(&e.expression)?;
34618 self.write(")");
34619 Ok(())
34620 }
34621
34622 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
34623 self.write_keyword("REGR_VALY");
34625 self.write("(");
34626 self.generate_expression(&e.this)?;
34627 self.write(", ");
34628 self.generate_expression(&e.expression)?;
34629 self.write(")");
34630 Ok(())
34631 }
34632
34633 fn generate_remote_with_connection_model_property(
34634 &mut self,
34635 e: &RemoteWithConnectionModelProperty,
34636 ) -> Result<()> {
34637 self.write_keyword("REMOTE WITH CONNECTION");
34639 self.write_space();
34640 self.generate_expression(&e.this)?;
34641 Ok(())
34642 }
34643
34644 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
34645 self.write_keyword("RENAME COLUMN");
34647 if e.exists {
34648 self.write_space();
34649 self.write_keyword("IF EXISTS");
34650 }
34651 self.write_space();
34652 self.generate_expression(&e.this)?;
34653 if let Some(to) = &e.to {
34654 self.write_space();
34655 self.write_keyword("TO");
34656 self.write_space();
34657 self.generate_expression(to)?;
34658 }
34659 Ok(())
34660 }
34661
34662 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
34663 self.write_keyword("REPLACE PARTITION");
34665 self.write_space();
34666 self.generate_expression(&e.expression)?;
34667 if let Some(source) = &e.source {
34668 self.write_space();
34669 self.write_keyword("FROM");
34670 self.write_space();
34671 self.generate_expression(source)?;
34672 }
34673 Ok(())
34674 }
34675
34676 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
34677 let keyword = match self.config.dialect {
34680 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
34681 _ => "RETURNING",
34682 };
34683 self.write_keyword(keyword);
34684 self.write_space();
34685 for (i, expr) in e.expressions.iter().enumerate() {
34686 if i > 0 {
34687 self.write(", ");
34688 }
34689 self.generate_expression(expr)?;
34690 }
34691 if let Some(into) = &e.into {
34692 self.write_space();
34693 self.write_keyword("INTO");
34694 self.write_space();
34695 self.generate_expression(into)?;
34696 }
34697 Ok(())
34698 }
34699
34700 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
34701 self.write_space();
34703 self.write_keyword("OUTPUT");
34704 self.write_space();
34705 for (i, expr) in output.columns.iter().enumerate() {
34706 if i > 0 {
34707 self.write(", ");
34708 }
34709 self.generate_expression(expr)?;
34710 }
34711 if let Some(into_table) = &output.into_table {
34712 self.write_space();
34713 self.write_keyword("INTO");
34714 self.write_space();
34715 self.generate_expression(into_table)?;
34716 }
34717 Ok(())
34718 }
34719
34720 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
34721 self.write_keyword("RETURNS");
34723 if e.is_table.is_some() {
34724 self.write_space();
34725 self.write_keyword("TABLE");
34726 }
34727 if let Some(table) = &e.table {
34728 self.write_space();
34729 self.generate_expression(table)?;
34730 } else if let Some(this) = &e.this {
34731 self.write_space();
34732 self.generate_expression(this)?;
34733 }
34734 if e.null.is_some() {
34735 self.write_space();
34736 self.write_keyword("NULL ON NULL INPUT");
34737 }
34738 Ok(())
34739 }
34740
34741 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
34742 self.write_keyword("ROLLBACK");
34744
34745 if e.this.is_none()
34747 && matches!(
34748 self.config.dialect,
34749 Some(DialectType::TSQL) | Some(DialectType::Fabric)
34750 )
34751 {
34752 self.write_space();
34753 self.write_keyword("TRANSACTION");
34754 }
34755
34756 if let Some(this) = &e.this {
34758 let is_transaction_marker = matches!(
34760 this.as_ref(),
34761 Expression::Identifier(id) if id.name == "TRANSACTION"
34762 );
34763
34764 self.write_space();
34765 self.write_keyword("TRANSACTION");
34766
34767 if !is_transaction_marker {
34769 self.write_space();
34770 self.generate_expression(this)?;
34771 }
34772 }
34773
34774 if let Some(savepoint) = &e.savepoint {
34776 self.write_space();
34777 self.write_keyword("TO");
34778 self.write_space();
34779 self.generate_expression(savepoint)?;
34780 }
34781 Ok(())
34782 }
34783
34784 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
34785 if e.expressions.is_empty() {
34787 self.write_keyword("WITH ROLLUP");
34788 } else {
34789 self.write_keyword("ROLLUP");
34790 self.write("(");
34791 for (i, expr) in e.expressions.iter().enumerate() {
34792 if i > 0 {
34793 self.write(", ");
34794 }
34795 self.generate_expression(expr)?;
34796 }
34797 self.write(")");
34798 }
34799 Ok(())
34800 }
34801
34802 fn generate_row_format_delimited_property(
34803 &mut self,
34804 e: &RowFormatDelimitedProperty,
34805 ) -> Result<()> {
34806 self.write_keyword("ROW FORMAT DELIMITED");
34808 if let Some(fields) = &e.fields {
34809 self.write_space();
34810 self.write_keyword("FIELDS TERMINATED BY");
34811 self.write_space();
34812 self.generate_expression(fields)?;
34813 }
34814 if let Some(escaped) = &e.escaped {
34815 self.write_space();
34816 self.write_keyword("ESCAPED BY");
34817 self.write_space();
34818 self.generate_expression(escaped)?;
34819 }
34820 if let Some(items) = &e.collection_items {
34821 self.write_space();
34822 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
34823 self.write_space();
34824 self.generate_expression(items)?;
34825 }
34826 if let Some(keys) = &e.map_keys {
34827 self.write_space();
34828 self.write_keyword("MAP KEYS TERMINATED BY");
34829 self.write_space();
34830 self.generate_expression(keys)?;
34831 }
34832 if let Some(lines) = &e.lines {
34833 self.write_space();
34834 self.write_keyword("LINES TERMINATED BY");
34835 self.write_space();
34836 self.generate_expression(lines)?;
34837 }
34838 if let Some(null) = &e.null {
34839 self.write_space();
34840 self.write_keyword("NULL DEFINED AS");
34841 self.write_space();
34842 self.generate_expression(null)?;
34843 }
34844 if let Some(serde) = &e.serde {
34845 self.write_space();
34846 self.generate_expression(serde)?;
34847 }
34848 Ok(())
34849 }
34850
34851 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
34852 self.write_keyword("ROW FORMAT");
34854 self.write_space();
34855 self.generate_expression(&e.this)?;
34856 Ok(())
34857 }
34858
34859 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
34860 self.write_keyword("ROW FORMAT SERDE");
34862 self.write_space();
34863 self.generate_expression(&e.this)?;
34864 if let Some(props) = &e.serde_properties {
34865 self.write_space();
34866 self.generate_expression(props)?;
34868 }
34869 Ok(())
34870 }
34871
34872 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
34873 self.write_keyword("SHA2");
34875 self.write("(");
34876 self.generate_expression(&e.this)?;
34877 if let Some(length) = e.length {
34878 self.write(", ");
34879 self.write(&length.to_string());
34880 }
34881 self.write(")");
34882 Ok(())
34883 }
34884
34885 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
34886 self.write_keyword("SHA2_DIGEST");
34888 self.write("(");
34889 self.generate_expression(&e.this)?;
34890 if let Some(length) = e.length {
34891 self.write(", ");
34892 self.write(&length.to_string());
34893 }
34894 self.write(")");
34895 Ok(())
34896 }
34897
34898 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
34899 let name = if matches!(
34900 self.config.dialect,
34901 Some(crate::dialects::DialectType::Spark)
34902 | Some(crate::dialects::DialectType::Databricks)
34903 ) {
34904 "TRY_ADD"
34905 } else {
34906 "SAFE_ADD"
34907 };
34908 self.write_keyword(name);
34909 self.write("(");
34910 self.generate_expression(&e.this)?;
34911 self.write(", ");
34912 self.generate_expression(&e.expression)?;
34913 self.write(")");
34914 Ok(())
34915 }
34916
34917 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
34918 self.write_keyword("SAFE_DIVIDE");
34920 self.write("(");
34921 self.generate_expression(&e.this)?;
34922 self.write(", ");
34923 self.generate_expression(&e.expression)?;
34924 self.write(")");
34925 Ok(())
34926 }
34927
34928 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
34929 let name = if matches!(
34930 self.config.dialect,
34931 Some(crate::dialects::DialectType::Spark)
34932 | Some(crate::dialects::DialectType::Databricks)
34933 ) {
34934 "TRY_MULTIPLY"
34935 } else {
34936 "SAFE_MULTIPLY"
34937 };
34938 self.write_keyword(name);
34939 self.write("(");
34940 self.generate_expression(&e.this)?;
34941 self.write(", ");
34942 self.generate_expression(&e.expression)?;
34943 self.write(")");
34944 Ok(())
34945 }
34946
34947 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
34948 let name = if matches!(
34949 self.config.dialect,
34950 Some(crate::dialects::DialectType::Spark)
34951 | Some(crate::dialects::DialectType::Databricks)
34952 ) {
34953 "TRY_SUBTRACT"
34954 } else {
34955 "SAFE_SUBTRACT"
34956 };
34957 self.write_keyword(name);
34958 self.write("(");
34959 self.generate_expression(&e.this)?;
34960 self.write(", ");
34961 self.generate_expression(&e.expression)?;
34962 self.write(")");
34963 Ok(())
34964 }
34965
34966 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
34969 if matches!(sample.method, SampleMethod::Bucket) {
34971 self.write(" (");
34972 self.write_keyword("BUCKET");
34973 self.write_space();
34974 if let Some(ref num) = sample.bucket_numerator {
34975 self.generate_expression(num)?;
34976 }
34977 self.write_space();
34978 self.write_keyword("OUT OF");
34979 self.write_space();
34980 if let Some(ref denom) = sample.bucket_denominator {
34981 self.generate_expression(denom)?;
34982 }
34983 if let Some(ref field) = sample.bucket_field {
34984 self.write_space();
34985 self.write_keyword("ON");
34986 self.write_space();
34987 self.generate_expression(field)?;
34988 }
34989 self.write(")");
34990 return Ok(());
34991 }
34992
34993 let is_snowflake = matches!(
34995 self.config.dialect,
34996 Some(crate::dialects::DialectType::Snowflake)
34997 );
34998 let is_postgres = matches!(
34999 self.config.dialect,
35000 Some(crate::dialects::DialectType::PostgreSQL)
35001 | Some(crate::dialects::DialectType::Redshift)
35002 );
35003 let is_databricks = matches!(
35005 self.config.dialect,
35006 Some(crate::dialects::DialectType::Databricks)
35007 );
35008 let is_spark = matches!(
35009 self.config.dialect,
35010 Some(crate::dialects::DialectType::Spark)
35011 );
35012 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
35013 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
35015 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
35016 self.write_space();
35017 if !sample.explicit_method && (is_snowflake || force_method) {
35018 self.write_keyword("BERNOULLI");
35020 } else {
35021 match sample.method {
35022 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
35023 SampleMethod::System => self.write_keyword("SYSTEM"),
35024 SampleMethod::Block => self.write_keyword("BLOCK"),
35025 SampleMethod::Row => self.write_keyword("ROW"),
35026 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
35027 SampleMethod::Percent => self.write_keyword("SYSTEM"),
35028 SampleMethod::Bucket => {} }
35030 }
35031 }
35032
35033 let emit_size_no_parens = !self.config.tablesample_requires_parens;
35035 if emit_size_no_parens {
35036 self.write_space();
35037 match &sample.size {
35038 Expression::Tuple(tuple) => {
35039 for (i, expr) in tuple.expressions.iter().enumerate() {
35040 if i > 0 {
35041 self.write(", ");
35042 }
35043 self.generate_expression(expr)?;
35044 }
35045 }
35046 expr => self.generate_expression(expr)?,
35047 }
35048 } else {
35049 self.write(" (");
35050 self.generate_expression(&sample.size)?;
35051 }
35052
35053 let is_rows_method = matches!(
35055 sample.method,
35056 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
35057 );
35058 let is_percent = matches!(
35059 sample.method,
35060 SampleMethod::Percent
35061 | SampleMethod::System
35062 | SampleMethod::Bernoulli
35063 | SampleMethod::Block
35064 );
35065
35066 let is_presto = matches!(
35070 self.config.dialect,
35071 Some(crate::dialects::DialectType::Presto)
35072 | Some(crate::dialects::DialectType::Trino)
35073 | Some(crate::dialects::DialectType::Athena)
35074 );
35075 let should_output_unit = if is_databricks || is_spark {
35076 is_percent || is_rows_method || sample.unit_after_size
35078 } else if is_snowflake || is_postgres || is_presto {
35079 sample.unit_after_size
35080 } else {
35081 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
35082 };
35083
35084 if should_output_unit {
35085 self.write_space();
35086 if sample.is_percent {
35087 self.write_keyword("PERCENT");
35088 } else if is_rows_method && !sample.unit_after_size {
35089 self.write_keyword("ROWS");
35090 } else if sample.unit_after_size {
35091 match sample.method {
35092 SampleMethod::Percent
35093 | SampleMethod::System
35094 | SampleMethod::Bernoulli
35095 | SampleMethod::Block => {
35096 self.write_keyword("PERCENT");
35097 }
35098 SampleMethod::Row | SampleMethod::Reservoir => {
35099 self.write_keyword("ROWS");
35100 }
35101 _ => self.write_keyword("ROWS"),
35102 }
35103 } else {
35104 self.write_keyword("PERCENT");
35105 }
35106 }
35107
35108 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
35109 if let Some(ref offset) = sample.offset {
35110 self.write_space();
35111 self.write_keyword("OFFSET");
35112 self.write_space();
35113 self.generate_expression(offset)?;
35114 }
35115 }
35116 if !emit_size_no_parens {
35117 self.write(")");
35118 }
35119
35120 Ok(())
35121 }
35122
35123 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
35124 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
35126 self.write_keyword("SAMPLE BY");
35127 } else {
35128 self.write_keyword("SAMPLE");
35129 }
35130 self.write_space();
35131 self.generate_expression(&e.this)?;
35132 Ok(())
35133 }
35134
35135 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
35136 if let Some(this) = &e.this {
35138 self.generate_expression(this)?;
35139 }
35140 if !e.expressions.is_empty() {
35141 if e.this.is_some() {
35143 self.write_space();
35144 }
35145 self.write("(");
35146 for (i, expr) in e.expressions.iter().enumerate() {
35147 if i > 0 {
35148 self.write(", ");
35149 }
35150 self.generate_expression(expr)?;
35151 }
35152 self.write(")");
35153 }
35154 Ok(())
35155 }
35156
35157 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
35158 self.write_keyword("COMMENT");
35160 self.write_space();
35161 self.generate_expression(&e.this)?;
35162 Ok(())
35163 }
35164
35165 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
35166 if let Some(this) = &e.this {
35168 self.generate_expression(this)?;
35169 self.write("::");
35170 }
35171 self.generate_expression(&e.expression)?;
35172 Ok(())
35173 }
35174
35175 fn generate_search(&mut self, e: &Search) -> Result<()> {
35176 self.write_keyword("SEARCH");
35178 self.write("(");
35179 self.generate_expression(&e.this)?;
35180 self.write(", ");
35181 self.generate_expression(&e.expression)?;
35182 if let Some(json_scope) = &e.json_scope {
35183 self.write(", ");
35184 self.generate_expression(json_scope)?;
35185 }
35186 if let Some(analyzer) = &e.analyzer {
35187 self.write(", ");
35188 self.generate_expression(analyzer)?;
35189 }
35190 if let Some(analyzer_options) = &e.analyzer_options {
35191 self.write(", ");
35192 self.generate_expression(analyzer_options)?;
35193 }
35194 if let Some(search_mode) = &e.search_mode {
35195 self.write(", ");
35196 self.generate_expression(search_mode)?;
35197 }
35198 self.write(")");
35199 Ok(())
35200 }
35201
35202 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
35203 self.write_keyword("SEARCH_IP");
35205 self.write("(");
35206 self.generate_expression(&e.this)?;
35207 self.write(", ");
35208 self.generate_expression(&e.expression)?;
35209 self.write(")");
35210 Ok(())
35211 }
35212
35213 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
35214 self.write_keyword("SECURITY");
35216 self.write_space();
35217 self.generate_expression(&e.this)?;
35218 Ok(())
35219 }
35220
35221 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
35222 self.write("SEMANTIC_VIEW(");
35224
35225 if self.config.pretty {
35226 self.write_newline();
35228 self.indent_level += 1;
35229 self.write_indent();
35230 self.generate_expression(&e.this)?;
35231
35232 if let Some(metrics) = &e.metrics {
35233 self.write_newline();
35234 self.write_indent();
35235 self.write_keyword("METRICS");
35236 self.write_space();
35237 self.generate_semantic_view_tuple(metrics)?;
35238 }
35239 if let Some(dimensions) = &e.dimensions {
35240 self.write_newline();
35241 self.write_indent();
35242 self.write_keyword("DIMENSIONS");
35243 self.write_space();
35244 self.generate_semantic_view_tuple(dimensions)?;
35245 }
35246 if let Some(facts) = &e.facts {
35247 self.write_newline();
35248 self.write_indent();
35249 self.write_keyword("FACTS");
35250 self.write_space();
35251 self.generate_semantic_view_tuple(facts)?;
35252 }
35253 if let Some(where_) = &e.where_ {
35254 self.write_newline();
35255 self.write_indent();
35256 self.write_keyword("WHERE");
35257 self.write_space();
35258 self.generate_expression(where_)?;
35259 }
35260 self.write_newline();
35261 self.indent_level -= 1;
35262 self.write_indent();
35263 } else {
35264 self.generate_expression(&e.this)?;
35266 if let Some(metrics) = &e.metrics {
35267 self.write_space();
35268 self.write_keyword("METRICS");
35269 self.write_space();
35270 self.generate_semantic_view_tuple(metrics)?;
35271 }
35272 if let Some(dimensions) = &e.dimensions {
35273 self.write_space();
35274 self.write_keyword("DIMENSIONS");
35275 self.write_space();
35276 self.generate_semantic_view_tuple(dimensions)?;
35277 }
35278 if let Some(facts) = &e.facts {
35279 self.write_space();
35280 self.write_keyword("FACTS");
35281 self.write_space();
35282 self.generate_semantic_view_tuple(facts)?;
35283 }
35284 if let Some(where_) = &e.where_ {
35285 self.write_space();
35286 self.write_keyword("WHERE");
35287 self.write_space();
35288 self.generate_expression(where_)?;
35289 }
35290 }
35291 self.write(")");
35292 Ok(())
35293 }
35294
35295 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
35297 if let Expression::Tuple(t) = expr {
35298 for (i, e) in t.expressions.iter().enumerate() {
35299 if i > 0 {
35300 self.write(", ");
35301 }
35302 self.generate_expression(e)?;
35303 }
35304 } else {
35305 self.generate_expression(expr)?;
35306 }
35307 Ok(())
35308 }
35309
35310 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
35311 if let Some(start) = &e.start {
35313 self.write_keyword("START WITH");
35314 self.write_space();
35315 self.generate_expression(start)?;
35316 }
35317 if let Some(increment) = &e.increment {
35318 self.write_space();
35319 self.write_keyword("INCREMENT BY");
35320 self.write_space();
35321 self.generate_expression(increment)?;
35322 }
35323 if let Some(minvalue) = &e.minvalue {
35324 self.write_space();
35325 self.write_keyword("MINVALUE");
35326 self.write_space();
35327 self.generate_expression(minvalue)?;
35328 }
35329 if let Some(maxvalue) = &e.maxvalue {
35330 self.write_space();
35331 self.write_keyword("MAXVALUE");
35332 self.write_space();
35333 self.generate_expression(maxvalue)?;
35334 }
35335 if let Some(cache) = &e.cache {
35336 self.write_space();
35337 self.write_keyword("CACHE");
35338 self.write_space();
35339 self.generate_expression(cache)?;
35340 }
35341 if let Some(owned) = &e.owned {
35342 self.write_space();
35343 self.write_keyword("OWNED BY");
35344 self.write_space();
35345 self.generate_expression(owned)?;
35346 }
35347 for opt in &e.options {
35348 self.write_space();
35349 self.generate_expression(opt)?;
35350 }
35351 Ok(())
35352 }
35353
35354 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
35355 if e.with_.is_some() {
35357 self.write_keyword("WITH");
35358 self.write_space();
35359 }
35360 self.write_keyword("SERDEPROPERTIES");
35361 self.write(" (");
35362 for (i, expr) in e.expressions.iter().enumerate() {
35363 if i > 0 {
35364 self.write(", ");
35365 }
35366 match expr {
35368 Expression::Eq(eq) => {
35369 self.generate_expression(&eq.left)?;
35370 self.write("=");
35371 self.generate_expression(&eq.right)?;
35372 }
35373 _ => self.generate_expression(expr)?,
35374 }
35375 }
35376 self.write(")");
35377 Ok(())
35378 }
35379
35380 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
35381 self.write("@@");
35383 if let Some(kind) = &e.kind {
35384 self.write(kind);
35385 self.write(".");
35386 }
35387 self.generate_expression(&e.this)?;
35388 Ok(())
35389 }
35390
35391 fn generate_set(&mut self, e: &Set) -> Result<()> {
35392 if e.unset.is_some() {
35394 self.write_keyword("UNSET");
35395 } else {
35396 self.write_keyword("SET");
35397 }
35398 if e.tag.is_some() {
35399 self.write_space();
35400 self.write_keyword("TAG");
35401 }
35402 if !e.expressions.is_empty() {
35403 self.write_space();
35404 for (i, expr) in e.expressions.iter().enumerate() {
35405 if i > 0 {
35406 self.write(", ");
35407 }
35408 self.generate_expression(expr)?;
35409 }
35410 }
35411 Ok(())
35412 }
35413
35414 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
35415 self.write_keyword("SET");
35417 self.write_space();
35418 self.generate_expression(&e.this)?;
35419 Ok(())
35420 }
35421
35422 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
35423 if let Some(kind) = &e.kind {
35425 self.write_keyword(kind);
35426 self.write_space();
35427 }
35428 self.generate_expression(&e.name)?;
35429 self.write(" = ");
35430 self.generate_expression(&e.value)?;
35431 Ok(())
35432 }
35433
35434 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
35435 if let Some(with_) = &e.with_ {
35437 self.generate_expression(with_)?;
35438 self.write_space();
35439 }
35440 self.generate_expression(&e.this)?;
35441 self.write_space();
35442 if let Some(kind) = &e.kind {
35444 self.write_keyword(kind);
35445 }
35446 if e.distinct {
35447 self.write_space();
35448 self.write_keyword("DISTINCT");
35449 } else {
35450 self.write_space();
35451 self.write_keyword("ALL");
35452 }
35453 if e.by_name.is_some() {
35454 self.write_space();
35455 self.write_keyword("BY NAME");
35456 }
35457 self.write_space();
35458 self.generate_expression(&e.expression)?;
35459 Ok(())
35460 }
35461
35462 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
35463 if e.multi.is_some() {
35465 self.write_keyword("MULTISET");
35466 } else {
35467 self.write_keyword("SET");
35468 }
35469 Ok(())
35470 }
35471
35472 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
35473 self.write_keyword("SETTINGS");
35475 if self.config.pretty && e.expressions.len() > 1 {
35476 self.indent_level += 1;
35478 for (i, expr) in e.expressions.iter().enumerate() {
35479 if i > 0 {
35480 self.write(",");
35481 }
35482 self.write_newline();
35483 self.write_indent();
35484 self.generate_expression(expr)?;
35485 }
35486 self.indent_level -= 1;
35487 } else {
35488 self.write_space();
35489 for (i, expr) in e.expressions.iter().enumerate() {
35490 if i > 0 {
35491 self.write(", ");
35492 }
35493 self.generate_expression(expr)?;
35494 }
35495 }
35496 Ok(())
35497 }
35498
35499 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
35500 self.write_keyword("SHARING");
35502 if let Some(this) = &e.this {
35503 self.write(" = ");
35504 self.generate_expression(this)?;
35505 }
35506 Ok(())
35507 }
35508
35509 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
35510 if let Some(begin) = &e.this {
35512 self.generate_expression(begin)?;
35513 }
35514 self.write(":");
35515 if let Some(end) = &e.expression {
35516 self.generate_expression(end)?;
35517 }
35518 if let Some(step) = &e.step {
35519 self.write(":");
35520 self.generate_expression(step)?;
35521 }
35522 Ok(())
35523 }
35524
35525 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
35526 self.write_keyword("SORT_ARRAY");
35528 self.write("(");
35529 self.generate_expression(&e.this)?;
35530 if let Some(asc) = &e.asc {
35531 self.write(", ");
35532 self.generate_expression(asc)?;
35533 }
35534 self.write(")");
35535 Ok(())
35536 }
35537
35538 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
35539 self.write_keyword("SORT BY");
35541 self.write_space();
35542 for (i, expr) in e.expressions.iter().enumerate() {
35543 if i > 0 {
35544 self.write(", ");
35545 }
35546 self.generate_ordered(expr)?;
35547 }
35548 Ok(())
35549 }
35550
35551 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
35552 if e.compound.is_some() {
35554 self.write_keyword("COMPOUND");
35555 self.write_space();
35556 }
35557 self.write_keyword("SORTKEY");
35558 self.write("(");
35559 if let Expression::Tuple(t) = e.this.as_ref() {
35561 for (i, expr) in t.expressions.iter().enumerate() {
35562 if i > 0 {
35563 self.write(", ");
35564 }
35565 self.generate_expression(expr)?;
35566 }
35567 } else {
35568 self.generate_expression(&e.this)?;
35569 }
35570 self.write(")");
35571 Ok(())
35572 }
35573
35574 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
35575 self.write_keyword("SPLIT_PART");
35577 self.write("(");
35578 self.generate_expression(&e.this)?;
35579 if let Some(delimiter) = &e.delimiter {
35580 self.write(", ");
35581 self.generate_expression(delimiter)?;
35582 }
35583 if let Some(part_index) = &e.part_index {
35584 self.write(", ");
35585 self.generate_expression(part_index)?;
35586 }
35587 self.write(")");
35588 Ok(())
35589 }
35590
35591 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
35592 self.generate_expression(&e.this)?;
35594 Ok(())
35595 }
35596
35597 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
35598 self.write_keyword("SQL SECURITY");
35600 self.write_space();
35601 self.generate_expression(&e.this)?;
35602 Ok(())
35603 }
35604
35605 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
35606 self.write_keyword("ST_DISTANCE");
35608 self.write("(");
35609 self.generate_expression(&e.this)?;
35610 self.write(", ");
35611 self.generate_expression(&e.expression)?;
35612 if let Some(use_spheroid) = &e.use_spheroid {
35613 self.write(", ");
35614 self.generate_expression(use_spheroid)?;
35615 }
35616 self.write(")");
35617 Ok(())
35618 }
35619
35620 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
35621 self.write_keyword("ST_POINT");
35623 self.write("(");
35624 self.generate_expression(&e.this)?;
35625 self.write(", ");
35626 self.generate_expression(&e.expression)?;
35627 self.write(")");
35628 Ok(())
35629 }
35630
35631 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
35632 self.generate_expression(&e.this)?;
35634 Ok(())
35635 }
35636
35637 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
35638 self.write_keyword("STANDARD_HASH");
35640 self.write("(");
35641 self.generate_expression(&e.this)?;
35642 if let Some(expression) = &e.expression {
35643 self.write(", ");
35644 self.generate_expression(expression)?;
35645 }
35646 self.write(")");
35647 Ok(())
35648 }
35649
35650 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
35651 self.write_keyword("STORED BY");
35653 self.write_space();
35654 self.generate_expression(&e.this)?;
35655 Ok(())
35656 }
35657
35658 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
35659 use crate::dialects::DialectType;
35662 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35663 self.write_keyword("CHARINDEX");
35665 self.write("(");
35666 if let Some(substr) = &e.substr {
35667 self.generate_expression(substr)?;
35668 self.write(", ");
35669 }
35670 self.generate_expression(&e.this)?;
35671 if let Some(position) = &e.position {
35672 self.write(", ");
35673 self.generate_expression(position)?;
35674 }
35675 self.write(")");
35676 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
35677 self.write_keyword("POSITION");
35678 self.write("(");
35679 self.generate_expression(&e.this)?;
35680 if let Some(substr) = &e.substr {
35681 self.write(", ");
35682 self.generate_expression(substr)?;
35683 }
35684 if let Some(position) = &e.position {
35685 self.write(", ");
35686 self.generate_expression(position)?;
35687 }
35688 if let Some(occurrence) = &e.occurrence {
35689 self.write(", ");
35690 self.generate_expression(occurrence)?;
35691 }
35692 self.write(")");
35693 } else if matches!(
35694 self.config.dialect,
35695 Some(DialectType::SQLite)
35696 | Some(DialectType::Oracle)
35697 | Some(DialectType::BigQuery)
35698 | Some(DialectType::Teradata)
35699 ) {
35700 self.write_keyword("INSTR");
35701 self.write("(");
35702 self.generate_expression(&e.this)?;
35703 if let Some(substr) = &e.substr {
35704 self.write(", ");
35705 self.generate_expression(substr)?;
35706 }
35707 if let Some(position) = &e.position {
35708 self.write(", ");
35709 self.generate_expression(position)?;
35710 } else if e.occurrence.is_some() {
35711 self.write(", 1");
35714 }
35715 if let Some(occurrence) = &e.occurrence {
35716 self.write(", ");
35717 self.generate_expression(occurrence)?;
35718 }
35719 self.write(")");
35720 } else if matches!(
35721 self.config.dialect,
35722 Some(DialectType::MySQL)
35723 | Some(DialectType::SingleStore)
35724 | Some(DialectType::Doris)
35725 | Some(DialectType::StarRocks)
35726 | Some(DialectType::Hive)
35727 | Some(DialectType::Spark)
35728 | Some(DialectType::Databricks)
35729 ) {
35730 self.write_keyword("LOCATE");
35732 self.write("(");
35733 if let Some(substr) = &e.substr {
35734 self.generate_expression(substr)?;
35735 self.write(", ");
35736 }
35737 self.generate_expression(&e.this)?;
35738 if let Some(position) = &e.position {
35739 self.write(", ");
35740 self.generate_expression(position)?;
35741 }
35742 self.write(")");
35743 } else if matches!(
35744 self.config.dialect,
35745 Some(DialectType::TSQL) | Some(DialectType::Fabric)
35746 ) {
35747 self.write_keyword("CHARINDEX");
35749 self.write("(");
35750 if let Some(substr) = &e.substr {
35751 self.generate_expression(substr)?;
35752 self.write(", ");
35753 }
35754 self.generate_expression(&e.this)?;
35755 if let Some(position) = &e.position {
35756 self.write(", ");
35757 self.generate_expression(position)?;
35758 }
35759 self.write(")");
35760 } else if matches!(
35761 self.config.dialect,
35762 Some(DialectType::PostgreSQL)
35763 | Some(DialectType::Materialize)
35764 | Some(DialectType::RisingWave)
35765 | Some(DialectType::Redshift)
35766 ) {
35767 self.write_keyword("POSITION");
35769 self.write("(");
35770 if let Some(substr) = &e.substr {
35771 self.generate_expression(substr)?;
35772 self.write(" IN ");
35773 }
35774 self.generate_expression(&e.this)?;
35775 self.write(")");
35776 } else {
35777 self.write_keyword("STRPOS");
35778 self.write("(");
35779 self.generate_expression(&e.this)?;
35780 if let Some(substr) = &e.substr {
35781 self.write(", ");
35782 self.generate_expression(substr)?;
35783 }
35784 if let Some(position) = &e.position {
35785 self.write(", ");
35786 self.generate_expression(position)?;
35787 }
35788 if let Some(occurrence) = &e.occurrence {
35789 self.write(", ");
35790 self.generate_expression(occurrence)?;
35791 }
35792 self.write(")");
35793 }
35794 Ok(())
35795 }
35796
35797 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
35798 match self.config.dialect {
35799 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
35800 self.write_keyword("TO_DATE");
35802 self.write("(");
35803 self.generate_expression(&e.this)?;
35804 if let Some(format) = &e.format {
35805 self.write(", '");
35806 self.write(&Self::strftime_to_java_format(format));
35807 self.write("'");
35808 }
35809 self.write(")");
35810 }
35811 Some(DialectType::DuckDB) => {
35812 self.write_keyword("CAST");
35814 self.write("(");
35815 self.write_keyword("STRPTIME");
35816 self.write("(");
35817 self.generate_expression(&e.this)?;
35818 if let Some(format) = &e.format {
35819 self.write(", '");
35820 self.write(format);
35821 self.write("'");
35822 }
35823 self.write(")");
35824 self.write_keyword(" AS ");
35825 self.write_keyword("DATE");
35826 self.write(")");
35827 }
35828 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
35829 self.write_keyword("TO_DATE");
35831 self.write("(");
35832 self.generate_expression(&e.this)?;
35833 if let Some(format) = &e.format {
35834 self.write(", '");
35835 self.write(&Self::strftime_to_postgres_format(format));
35836 self.write("'");
35837 }
35838 self.write(")");
35839 }
35840 Some(DialectType::BigQuery) => {
35841 self.write_keyword("PARSE_DATE");
35843 self.write("(");
35844 if let Some(format) = &e.format {
35845 self.write("'");
35846 self.write(format);
35847 self.write("'");
35848 self.write(", ");
35849 }
35850 self.generate_expression(&e.this)?;
35851 self.write(")");
35852 }
35853 Some(DialectType::Teradata) => {
35854 self.write_keyword("CAST");
35856 self.write("(");
35857 self.generate_expression(&e.this)?;
35858 self.write_keyword(" AS ");
35859 self.write_keyword("DATE");
35860 if let Some(format) = &e.format {
35861 self.write_keyword(" FORMAT ");
35862 self.write("'");
35863 self.write(&Self::strftime_to_teradata_format(format));
35864 self.write("'");
35865 }
35866 self.write(")");
35867 }
35868 _ => {
35869 self.write_keyword("STR_TO_DATE");
35871 self.write("(");
35872 self.generate_expression(&e.this)?;
35873 if let Some(format) = &e.format {
35874 self.write(", '");
35875 self.write(format);
35876 self.write("'");
35877 }
35878 self.write(")");
35879 }
35880 }
35881 Ok(())
35882 }
35883
35884 fn strftime_to_teradata_format(fmt: &str) -> String {
35886 let mut result = String::with_capacity(fmt.len() * 2);
35887 let bytes = fmt.as_bytes();
35888 let len = bytes.len();
35889 let mut i = 0;
35890 while i < len {
35891 if bytes[i] == b'%' && i + 1 < len {
35892 let replacement = match bytes[i + 1] {
35893 b'Y' => "YYYY",
35894 b'y' => "YY",
35895 b'm' => "MM",
35896 b'B' => "MMMM",
35897 b'b' => "MMM",
35898 b'd' => "DD",
35899 b'j' => "DDD",
35900 b'H' => "HH",
35901 b'M' => "MI",
35902 b'S' => "SS",
35903 b'f' => "SSSSSS",
35904 b'A' => "EEEE",
35905 b'a' => "EEE",
35906 _ => {
35907 result.push('%');
35908 i += 1;
35909 continue;
35910 }
35911 };
35912 result.push_str(replacement);
35913 i += 2;
35914 } else {
35915 result.push(bytes[i] as char);
35916 i += 1;
35917 }
35918 }
35919 result
35920 }
35921
35922 pub fn strftime_to_java_format_static(fmt: &str) -> String {
35925 Self::strftime_to_java_format(fmt)
35926 }
35927
35928 fn strftime_to_java_format(fmt: &str) -> String {
35930 let mut result = String::with_capacity(fmt.len() * 2);
35931 let bytes = fmt.as_bytes();
35932 let len = bytes.len();
35933 let mut i = 0;
35934 while i < len {
35935 if bytes[i] == b'%' && i + 1 < len {
35936 if bytes[i + 1] == b'-' && i + 2 < len {
35938 let replacement = match bytes[i + 2] {
35939 b'd' => "d",
35940 b'm' => "M",
35941 b'H' => "H",
35942 b'M' => "m",
35943 b'S' => "s",
35944 _ => {
35945 result.push('%');
35946 i += 1;
35947 continue;
35948 }
35949 };
35950 result.push_str(replacement);
35951 i += 3;
35952 } else {
35953 let replacement = match bytes[i + 1] {
35954 b'Y' => "yyyy",
35955 b'y' => "yy",
35956 b'm' => "MM",
35957 b'B' => "MMMM",
35958 b'b' => "MMM",
35959 b'd' => "dd",
35960 b'j' => "DDD",
35961 b'H' => "HH",
35962 b'M' => "mm",
35963 b'S' => "ss",
35964 b'f' => "SSSSSS",
35965 b'A' => "EEEE",
35966 b'a' => "EEE",
35967 _ => {
35968 result.push('%');
35969 i += 1;
35970 continue;
35971 }
35972 };
35973 result.push_str(replacement);
35974 i += 2;
35975 }
35976 } else {
35977 result.push(bytes[i] as char);
35978 i += 1;
35979 }
35980 }
35981 result
35982 }
35983
35984 fn strftime_to_tsql_format(fmt: &str) -> String {
35987 let mut result = String::with_capacity(fmt.len() * 2);
35988 let bytes = fmt.as_bytes();
35989 let len = bytes.len();
35990 let mut i = 0;
35991 while i < len {
35992 if bytes[i] == b'%' && i + 1 < len {
35993 if bytes[i + 1] == b'-' && i + 2 < len {
35995 let replacement = match bytes[i + 2] {
35996 b'd' => "d",
35997 b'm' => "M",
35998 b'H' => "H",
35999 b'M' => "m",
36000 b'S' => "s",
36001 _ => {
36002 result.push('%');
36003 i += 1;
36004 continue;
36005 }
36006 };
36007 result.push_str(replacement);
36008 i += 3;
36009 } else {
36010 let replacement = match bytes[i + 1] {
36011 b'Y' => "yyyy",
36012 b'y' => "yy",
36013 b'm' => "MM",
36014 b'B' => "MMMM",
36015 b'b' => "MMM",
36016 b'd' => "dd",
36017 b'j' => "DDD",
36018 b'H' => "HH",
36019 b'M' => "mm",
36020 b'S' => "ss",
36021 b'f' => "ffffff",
36022 b'A' => "dddd",
36023 b'a' => "ddd",
36024 _ => {
36025 result.push('%');
36026 i += 1;
36027 continue;
36028 }
36029 };
36030 result.push_str(replacement);
36031 i += 2;
36032 }
36033 } else {
36034 result.push(bytes[i] as char);
36035 i += 1;
36036 }
36037 }
36038 result
36039 }
36040
36041 fn decompose_json_path(path: &str) -> Vec<String> {
36044 let mut parts = Vec::new();
36045 let path = if path.starts_with("$.") {
36047 &path[2..]
36048 } else if path.starts_with('$') {
36049 &path[1..]
36050 } else {
36051 path
36052 };
36053 if path.is_empty() {
36054 return parts;
36055 }
36056 let mut current = String::new();
36057 let chars: Vec<char> = path.chars().collect();
36058 let mut i = 0;
36059 while i < chars.len() {
36060 match chars[i] {
36061 '.' => {
36062 if !current.is_empty() {
36063 parts.push(current.clone());
36064 current.clear();
36065 }
36066 i += 1;
36067 }
36068 '[' => {
36069 if !current.is_empty() {
36070 parts.push(current.clone());
36071 current.clear();
36072 }
36073 i += 1;
36074 let mut bracket_content = String::new();
36076 while i < chars.len() && chars[i] != ']' {
36077 if chars[i] == '"' || chars[i] == '\'' {
36079 let quote = chars[i];
36080 i += 1;
36081 while i < chars.len() && chars[i] != quote {
36082 bracket_content.push(chars[i]);
36083 i += 1;
36084 }
36085 if i < chars.len() {
36086 i += 1;
36087 } } else {
36089 bracket_content.push(chars[i]);
36090 i += 1;
36091 }
36092 }
36093 if i < chars.len() {
36094 i += 1;
36095 } if bracket_content != "*" {
36098 parts.push(bracket_content);
36099 }
36100 }
36101 _ => {
36102 current.push(chars[i]);
36103 i += 1;
36104 }
36105 }
36106 }
36107 if !current.is_empty() {
36108 parts.push(current);
36109 }
36110 parts
36111 }
36112
36113 fn strftime_to_postgres_format(fmt: &str) -> String {
36115 let mut result = String::with_capacity(fmt.len() * 2);
36116 let bytes = fmt.as_bytes();
36117 let len = bytes.len();
36118 let mut i = 0;
36119 while i < len {
36120 if bytes[i] == b'%' && i + 1 < len {
36121 if bytes[i + 1] == b'-' && i + 2 < len {
36123 let replacement = match bytes[i + 2] {
36124 b'd' => "FMDD",
36125 b'm' => "FMMM",
36126 b'H' => "FMHH24",
36127 b'M' => "FMMI",
36128 b'S' => "FMSS",
36129 _ => {
36130 result.push('%');
36131 i += 1;
36132 continue;
36133 }
36134 };
36135 result.push_str(replacement);
36136 i += 3;
36137 } else {
36138 let replacement = match bytes[i + 1] {
36139 b'Y' => "YYYY",
36140 b'y' => "YY",
36141 b'm' => "MM",
36142 b'B' => "Month",
36143 b'b' => "Mon",
36144 b'd' => "DD",
36145 b'j' => "DDD",
36146 b'H' => "HH24",
36147 b'M' => "MI",
36148 b'S' => "SS",
36149 b'f' => "US",
36150 b'A' => "Day",
36151 b'a' => "Dy",
36152 _ => {
36153 result.push('%');
36154 i += 1;
36155 continue;
36156 }
36157 };
36158 result.push_str(replacement);
36159 i += 2;
36160 }
36161 } else {
36162 result.push(bytes[i] as char);
36163 i += 1;
36164 }
36165 }
36166 result
36167 }
36168
36169 fn strftime_to_snowflake_format(fmt: &str) -> String {
36171 let mut result = String::with_capacity(fmt.len() * 2);
36172 let bytes = fmt.as_bytes();
36173 let len = bytes.len();
36174 let mut i = 0;
36175 while i < len {
36176 if bytes[i] == b'%' && i + 1 < len {
36177 if bytes[i + 1] == b'-' && i + 2 < len {
36179 let replacement = match bytes[i + 2] {
36180 b'd' => "dd",
36181 b'm' => "mm",
36182 _ => {
36183 result.push('%');
36184 i += 1;
36185 continue;
36186 }
36187 };
36188 result.push_str(replacement);
36189 i += 3;
36190 } else {
36191 let replacement = match bytes[i + 1] {
36192 b'Y' => "yyyy",
36193 b'y' => "yy",
36194 b'm' => "mm",
36195 b'd' => "DD",
36196 b'H' => "hh24",
36197 b'M' => "mi",
36198 b'S' => "ss",
36199 b'f' => "ff",
36200 _ => {
36201 result.push('%');
36202 i += 1;
36203 continue;
36204 }
36205 };
36206 result.push_str(replacement);
36207 i += 2;
36208 }
36209 } else {
36210 result.push(bytes[i] as char);
36211 i += 1;
36212 }
36213 }
36214 result
36215 }
36216
36217 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
36218 self.write_keyword("STR_TO_MAP");
36220 self.write("(");
36221 self.generate_expression(&e.this)?;
36222 let needs_defaults = matches!(
36224 self.config.dialect,
36225 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
36226 );
36227 if let Some(pair_delim) = &e.pair_delim {
36228 self.write(", ");
36229 self.generate_expression(pair_delim)?;
36230 } else if needs_defaults {
36231 self.write(", ','");
36232 }
36233 if let Some(key_value_delim) = &e.key_value_delim {
36234 self.write(", ");
36235 self.generate_expression(key_value_delim)?;
36236 } else if needs_defaults {
36237 self.write(", ':'");
36238 }
36239 self.write(")");
36240 Ok(())
36241 }
36242
36243 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
36244 let is_strftime = e.format.contains('%');
36246 let to_strftime = |f: &str| -> String {
36248 if is_strftime {
36249 f.to_string()
36250 } else {
36251 Self::snowflake_format_to_strftime(f)
36252 }
36253 };
36254 let to_java = |f: &str| -> String {
36256 if is_strftime {
36257 Self::strftime_to_java_format(f)
36258 } else {
36259 Self::snowflake_format_to_spark(f)
36260 }
36261 };
36262 let to_pg = |f: &str| -> String {
36264 if is_strftime {
36265 Self::strftime_to_postgres_format(f)
36266 } else {
36267 Self::convert_strptime_to_postgres_format(f)
36268 }
36269 };
36270
36271 match self.config.dialect {
36272 Some(DialectType::Exasol) => {
36273 self.write_keyword("TO_DATE");
36274 self.write("(");
36275 self.generate_expression(&e.this)?;
36276 self.write(", '");
36277 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
36278 self.write("'");
36279 self.write(")");
36280 }
36281 Some(DialectType::BigQuery) => {
36282 let fmt = to_strftime(&e.format);
36284 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
36286 self.write_keyword("PARSE_TIMESTAMP");
36287 self.write("('");
36288 self.write(&fmt);
36289 self.write("', ");
36290 self.generate_expression(&e.this)?;
36291 self.write(")");
36292 }
36293 Some(DialectType::Hive) => {
36294 let java_fmt = to_java(&e.format);
36297 if java_fmt == "yyyy-MM-dd HH:mm:ss"
36298 || java_fmt == "yyyy-MM-dd"
36299 || e.format == "yyyy-MM-dd HH:mm:ss"
36300 || e.format == "yyyy-MM-dd"
36301 {
36302 self.write_keyword("CAST");
36303 self.write("(");
36304 self.generate_expression(&e.this)?;
36305 self.write(" ");
36306 self.write_keyword("AS TIMESTAMP");
36307 self.write(")");
36308 } else {
36309 self.write_keyword("CAST");
36311 self.write("(");
36312 self.write_keyword("FROM_UNIXTIME");
36313 self.write("(");
36314 self.write_keyword("UNIX_TIMESTAMP");
36315 self.write("(");
36316 self.generate_expression(&e.this)?;
36317 self.write(", '");
36318 self.write(&java_fmt);
36319 self.write("')");
36320 self.write(") ");
36321 self.write_keyword("AS TIMESTAMP");
36322 self.write(")");
36323 }
36324 }
36325 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36326 let java_fmt = to_java(&e.format);
36328 self.write_keyword("TO_TIMESTAMP");
36329 self.write("(");
36330 self.generate_expression(&e.this)?;
36331 self.write(", '");
36332 self.write(&java_fmt);
36333 self.write("')");
36334 }
36335 Some(DialectType::MySQL) => {
36336 let mut fmt = to_strftime(&e.format);
36338 fmt = fmt.replace("%-d", "%e");
36340 fmt = fmt.replace("%-m", "%c");
36341 fmt = fmt.replace("%H:%M:%S", "%T");
36342 self.write_keyword("STR_TO_DATE");
36343 self.write("(");
36344 self.generate_expression(&e.this)?;
36345 self.write(", '");
36346 self.write(&fmt);
36347 self.write("')");
36348 }
36349 Some(DialectType::Drill) => {
36350 let java_fmt = to_java(&e.format);
36352 let java_fmt = java_fmt.replace('T', "''T''");
36354 self.write_keyword("TO_TIMESTAMP");
36355 self.write("(");
36356 self.generate_expression(&e.this)?;
36357 self.write(", '");
36358 self.write(&java_fmt);
36359 self.write("')");
36360 }
36361 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
36362 let mut fmt = to_strftime(&e.format);
36364 fmt = fmt.replace("%-d", "%e");
36366 fmt = fmt.replace("%-m", "%c");
36367 fmt = fmt.replace("%H:%M:%S", "%T");
36368 self.write_keyword("DATE_PARSE");
36369 self.write("(");
36370 self.generate_expression(&e.this)?;
36371 self.write(", '");
36372 self.write(&fmt);
36373 self.write("')");
36374 }
36375 Some(DialectType::DuckDB) => {
36376 let fmt = to_strftime(&e.format);
36378 self.write_keyword("STRPTIME");
36379 self.write("(");
36380 self.generate_expression(&e.this)?;
36381 self.write(", '");
36382 self.write(&fmt);
36383 self.write("')");
36384 }
36385 Some(DialectType::PostgreSQL)
36386 | Some(DialectType::Redshift)
36387 | Some(DialectType::Materialize) => {
36388 let pg_fmt = to_pg(&e.format);
36390 self.write_keyword("TO_TIMESTAMP");
36391 self.write("(");
36392 self.generate_expression(&e.this)?;
36393 self.write(", '");
36394 self.write(&pg_fmt);
36395 self.write("')");
36396 }
36397 Some(DialectType::Oracle) => {
36398 let pg_fmt = to_pg(&e.format);
36400 self.write_keyword("TO_TIMESTAMP");
36401 self.write("(");
36402 self.generate_expression(&e.this)?;
36403 self.write(", '");
36404 self.write(&pg_fmt);
36405 self.write("')");
36406 }
36407 Some(DialectType::Snowflake) => {
36408 self.write_keyword("TO_TIMESTAMP");
36410 self.write("(");
36411 self.generate_expression(&e.this)?;
36412 self.write(", '");
36413 self.write(&e.format);
36414 self.write("')");
36415 }
36416 _ => {
36417 self.write_keyword("STR_TO_TIME");
36419 self.write("(");
36420 self.generate_expression(&e.this)?;
36421 self.write(", '");
36422 self.write(&e.format);
36423 self.write("'");
36424 self.write(")");
36425 }
36426 }
36427 Ok(())
36428 }
36429
36430 fn snowflake_format_to_strftime(format: &str) -> String {
36432 let mut result = String::new();
36433 let chars: Vec<char> = format.chars().collect();
36434 let mut i = 0;
36435 while i < chars.len() {
36436 let remaining = &format[i..];
36437 if remaining.starts_with("yyyy") {
36438 result.push_str("%Y");
36439 i += 4;
36440 } else if remaining.starts_with("yy") {
36441 result.push_str("%y");
36442 i += 2;
36443 } else if remaining.starts_with("mmmm") {
36444 result.push_str("%B"); i += 4;
36446 } else if remaining.starts_with("mon") {
36447 result.push_str("%b"); i += 3;
36449 } else if remaining.starts_with("mm") {
36450 result.push_str("%m");
36451 i += 2;
36452 } else if remaining.starts_with("DD") {
36453 result.push_str("%d");
36454 i += 2;
36455 } else if remaining.starts_with("dy") {
36456 result.push_str("%a"); i += 2;
36458 } else if remaining.starts_with("hh24") {
36459 result.push_str("%H");
36460 i += 4;
36461 } else if remaining.starts_with("hh12") {
36462 result.push_str("%I");
36463 i += 4;
36464 } else if remaining.starts_with("hh") {
36465 result.push_str("%H");
36466 i += 2;
36467 } else if remaining.starts_with("mi") {
36468 result.push_str("%M");
36469 i += 2;
36470 } else if remaining.starts_with("ss") {
36471 result.push_str("%S");
36472 i += 2;
36473 } else if remaining.starts_with("ff") {
36474 result.push_str("%f");
36476 i += 2;
36477 while i < chars.len() && chars[i].is_ascii_digit() {
36479 i += 1;
36480 }
36481 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
36482 result.push_str("%p");
36483 i += 2;
36484 } else if remaining.starts_with("tz") {
36485 result.push_str("%Z");
36486 i += 2;
36487 } else {
36488 result.push(chars[i]);
36489 i += 1;
36490 }
36491 }
36492 result
36493 }
36494
36495 fn snowflake_format_to_spark(format: &str) -> String {
36497 let mut result = String::new();
36498 let chars: Vec<char> = format.chars().collect();
36499 let mut i = 0;
36500 while i < chars.len() {
36501 let remaining = &format[i..];
36502 if remaining.starts_with("yyyy") {
36503 result.push_str("yyyy");
36504 i += 4;
36505 } else if remaining.starts_with("yy") {
36506 result.push_str("yy");
36507 i += 2;
36508 } else if remaining.starts_with("mmmm") {
36509 result.push_str("MMMM"); i += 4;
36511 } else if remaining.starts_with("mon") {
36512 result.push_str("MMM"); i += 3;
36514 } else if remaining.starts_with("mm") {
36515 result.push_str("MM");
36516 i += 2;
36517 } else if remaining.starts_with("DD") {
36518 result.push_str("dd");
36519 i += 2;
36520 } else if remaining.starts_with("dy") {
36521 result.push_str("EEE"); i += 2;
36523 } else if remaining.starts_with("hh24") {
36524 result.push_str("HH");
36525 i += 4;
36526 } else if remaining.starts_with("hh12") {
36527 result.push_str("hh");
36528 i += 4;
36529 } else if remaining.starts_with("hh") {
36530 result.push_str("HH");
36531 i += 2;
36532 } else if remaining.starts_with("mi") {
36533 result.push_str("mm");
36534 i += 2;
36535 } else if remaining.starts_with("ss") {
36536 result.push_str("ss");
36537 i += 2;
36538 } else if remaining.starts_with("ff") {
36539 result.push_str("SSS"); i += 2;
36541 while i < chars.len() && chars[i].is_ascii_digit() {
36543 i += 1;
36544 }
36545 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
36546 result.push_str("a");
36547 i += 2;
36548 } else if remaining.starts_with("tz") {
36549 result.push_str("z");
36550 i += 2;
36551 } else {
36552 result.push(chars[i]);
36553 i += 1;
36554 }
36555 }
36556 result
36557 }
36558
36559 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
36560 match self.config.dialect {
36561 Some(DialectType::DuckDB) => {
36562 self.write_keyword("EPOCH");
36564 self.write("(");
36565 self.write_keyword("STRPTIME");
36566 self.write("(");
36567 if let Some(this) = &e.this {
36568 self.generate_expression(this)?;
36569 }
36570 if let Some(format) = &e.format {
36571 self.write(", '");
36572 self.write(format);
36573 self.write("'");
36574 }
36575 self.write("))");
36576 }
36577 Some(DialectType::Hive) => {
36578 self.write_keyword("UNIX_TIMESTAMP");
36580 self.write("(");
36581 if let Some(this) = &e.this {
36582 self.generate_expression(this)?;
36583 }
36584 if let Some(format) = &e.format {
36585 let java_fmt = Self::strftime_to_java_format(format);
36586 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
36587 self.write(", '");
36588 self.write(&java_fmt);
36589 self.write("'");
36590 }
36591 }
36592 self.write(")");
36593 }
36594 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
36595 self.write_keyword("UNIX_TIMESTAMP");
36597 self.write("(");
36598 if let Some(this) = &e.this {
36599 self.generate_expression(this)?;
36600 }
36601 if let Some(format) = &e.format {
36602 self.write(", '");
36603 self.write(format);
36604 self.write("'");
36605 }
36606 self.write(")");
36607 }
36608 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36609 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
36612 let java_fmt = Self::strftime_to_java_format(c_fmt);
36613 self.write_keyword("TO_UNIXTIME");
36614 self.write("(");
36615 self.write_keyword("COALESCE");
36616 self.write("(");
36617 self.write_keyword("TRY");
36618 self.write("(");
36619 self.write_keyword("DATE_PARSE");
36620 self.write("(");
36621 self.write_keyword("CAST");
36622 self.write("(");
36623 if let Some(this) = &e.this {
36624 self.generate_expression(this)?;
36625 }
36626 self.write(" ");
36627 self.write_keyword("AS VARCHAR");
36628 self.write("), '");
36629 self.write(c_fmt);
36630 self.write("')), ");
36631 self.write_keyword("PARSE_DATETIME");
36632 self.write("(");
36633 self.write_keyword("DATE_FORMAT");
36634 self.write("(");
36635 self.write_keyword("CAST");
36636 self.write("(");
36637 if let Some(this) = &e.this {
36638 self.generate_expression(this)?;
36639 }
36640 self.write(" ");
36641 self.write_keyword("AS TIMESTAMP");
36642 self.write("), '");
36643 self.write(c_fmt);
36644 self.write("'), '");
36645 self.write(&java_fmt);
36646 self.write("')))");
36647 }
36648 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36649 self.write_keyword("UNIX_TIMESTAMP");
36651 self.write("(");
36652 if let Some(this) = &e.this {
36653 self.generate_expression(this)?;
36654 }
36655 if let Some(format) = &e.format {
36656 let java_fmt = Self::strftime_to_java_format(format);
36657 self.write(", '");
36658 self.write(&java_fmt);
36659 self.write("'");
36660 }
36661 self.write(")");
36662 }
36663 _ => {
36664 self.write_keyword("STR_TO_UNIX");
36666 self.write("(");
36667 if let Some(this) = &e.this {
36668 self.generate_expression(this)?;
36669 }
36670 if let Some(format) = &e.format {
36671 self.write(", '");
36672 self.write(format);
36673 self.write("'");
36674 }
36675 self.write(")");
36676 }
36677 }
36678 Ok(())
36679 }
36680
36681 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
36682 self.write_keyword("STRING_TO_ARRAY");
36684 self.write("(");
36685 self.generate_expression(&e.this)?;
36686 if let Some(expression) = &e.expression {
36687 self.write(", ");
36688 self.generate_expression(expression)?;
36689 }
36690 if let Some(null_val) = &e.null {
36691 self.write(", ");
36692 self.generate_expression(null_val)?;
36693 }
36694 self.write(")");
36695 Ok(())
36696 }
36697
36698 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
36699 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
36700 self.write_keyword("OBJECT_CONSTRUCT");
36702 self.write("(");
36703 for (i, (name, expr)) in e.fields.iter().enumerate() {
36704 if i > 0 {
36705 self.write(", ");
36706 }
36707 if let Some(name) = name {
36708 self.write("'");
36709 self.write(name);
36710 self.write("'");
36711 self.write(", ");
36712 } else {
36713 self.write("'_");
36714 self.write(&i.to_string());
36715 self.write("'");
36716 self.write(", ");
36717 }
36718 self.generate_expression(expr)?;
36719 }
36720 self.write(")");
36721 } else if self.config.struct_curly_brace_notation {
36722 self.write("{");
36724 for (i, (name, expr)) in e.fields.iter().enumerate() {
36725 if i > 0 {
36726 self.write(", ");
36727 }
36728 if let Some(name) = name {
36729 self.write("'");
36731 self.write(name);
36732 self.write("'");
36733 self.write(": ");
36734 } else {
36735 self.write("'_");
36737 self.write(&i.to_string());
36738 self.write("'");
36739 self.write(": ");
36740 }
36741 self.generate_expression(expr)?;
36742 }
36743 self.write("}");
36744 } else {
36745 let value_as_name = matches!(
36749 self.config.dialect,
36750 Some(DialectType::BigQuery)
36751 | Some(DialectType::Spark)
36752 | Some(DialectType::Databricks)
36753 | Some(DialectType::Hive)
36754 );
36755 self.write_keyword("STRUCT");
36756 self.write("(");
36757 for (i, (name, expr)) in e.fields.iter().enumerate() {
36758 if i > 0 {
36759 self.write(", ");
36760 }
36761 if let Some(name) = name {
36762 if value_as_name {
36763 self.generate_expression(expr)?;
36765 self.write_space();
36766 self.write_keyword("AS");
36767 self.write_space();
36768 let needs_quoting = name.contains(' ') || name.contains('-');
36770 if needs_quoting {
36771 if matches!(
36772 self.config.dialect,
36773 Some(DialectType::Spark)
36774 | Some(DialectType::Databricks)
36775 | Some(DialectType::Hive)
36776 ) {
36777 self.write("`");
36778 self.write(name);
36779 self.write("`");
36780 } else {
36781 self.write(name);
36782 }
36783 } else {
36784 self.write(name);
36785 }
36786 } else {
36787 self.write(name);
36789 self.write_space();
36790 self.write_keyword("AS");
36791 self.write_space();
36792 self.generate_expression(expr)?;
36793 }
36794 } else {
36795 self.generate_expression(expr)?;
36796 }
36797 }
36798 self.write(")");
36799 }
36800 Ok(())
36801 }
36802
36803 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
36804 self.write_keyword("STUFF");
36806 self.write("(");
36807 self.generate_expression(&e.this)?;
36808 if let Some(start) = &e.start {
36809 self.write(", ");
36810 self.generate_expression(start)?;
36811 }
36812 if let Some(length) = e.length {
36813 self.write(", ");
36814 self.write(&length.to_string());
36815 }
36816 self.write(", ");
36817 self.generate_expression(&e.expression)?;
36818 self.write(")");
36819 Ok(())
36820 }
36821
36822 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
36823 self.write_keyword("SUBSTRING_INDEX");
36825 self.write("(");
36826 self.generate_expression(&e.this)?;
36827 if let Some(delimiter) = &e.delimiter {
36828 self.write(", ");
36829 self.generate_expression(delimiter)?;
36830 }
36831 if let Some(count) = &e.count {
36832 self.write(", ");
36833 self.generate_expression(count)?;
36834 }
36835 self.write(")");
36836 Ok(())
36837 }
36838
36839 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
36840 self.write_keyword("SUMMARIZE");
36842 if e.table.is_some() {
36843 self.write_space();
36844 self.write_keyword("TABLE");
36845 }
36846 self.write_space();
36847 self.generate_expression(&e.this)?;
36848 Ok(())
36849 }
36850
36851 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
36852 self.write_keyword("SYSTIMESTAMP");
36854 Ok(())
36855 }
36856
36857 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
36858 if let Some(this) = &e.this {
36860 self.generate_expression(this)?;
36861 }
36862 if !e.columns.is_empty() {
36863 self.write("(");
36864 for (i, col) in e.columns.iter().enumerate() {
36865 if i > 0 {
36866 self.write(", ");
36867 }
36868 self.generate_expression(col)?;
36869 }
36870 self.write(")");
36871 }
36872 Ok(())
36873 }
36874
36875 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
36876 self.write_keyword("TABLE");
36878 self.write("(");
36879 self.generate_expression(&e.this)?;
36880 self.write(")");
36881 if let Some(alias) = &e.alias {
36882 self.write_space();
36883 self.write_keyword("AS");
36884 self.write_space();
36885 self.write(alias);
36886 }
36887 Ok(())
36888 }
36889
36890 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
36891 self.write_keyword("ROWS FROM");
36893 self.write(" (");
36894 for (i, expr) in e.expressions.iter().enumerate() {
36895 if i > 0 {
36896 self.write(", ");
36897 }
36898 match expr {
36902 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
36903 self.generate_expression(&tuple.expressions[0])?;
36905 self.write_space();
36906 self.write_keyword("AS");
36907 self.write_space();
36908 self.generate_expression(&tuple.expressions[1])?;
36909 }
36910 _ => {
36911 self.generate_expression(expr)?;
36912 }
36913 }
36914 }
36915 self.write(")");
36916 if e.ordinality {
36917 self.write_space();
36918 self.write_keyword("WITH ORDINALITY");
36919 }
36920 if let Some(alias) = &e.alias {
36921 self.write_space();
36922 self.write_keyword("AS");
36923 self.write_space();
36924 self.generate_expression(alias)?;
36925 }
36926 Ok(())
36927 }
36928
36929 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
36930 use crate::dialects::DialectType;
36931
36932 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
36934 if self.config.alias_post_tablesample {
36936 if let Expression::Subquery(ref s) = **this {
36938 if let Some(ref alias) = s.alias {
36939 let mut subquery_no_alias = (**s).clone();
36941 subquery_no_alias.alias = None;
36942 subquery_no_alias.column_aliases = Vec::new();
36943 self.generate_expression(&Expression::Subquery(Box::new(
36944 subquery_no_alias,
36945 )))?;
36946 self.write_space();
36947 self.write_keyword(self.config.tablesample_keywords);
36948 self.generate_sample_body(sample)?;
36949 if let Some(ref seed) = sample.seed {
36950 self.write_space();
36951 let use_seed = sample.use_seed_keyword
36952 && !matches!(
36953 self.config.dialect,
36954 Some(crate::dialects::DialectType::Databricks)
36955 | Some(crate::dialects::DialectType::Spark)
36956 );
36957 if use_seed {
36958 self.write_keyword("SEED");
36959 } else {
36960 self.write_keyword("REPEATABLE");
36961 }
36962 self.write(" (");
36963 self.generate_expression(seed)?;
36964 self.write(")");
36965 }
36966 self.write_space();
36967 self.write_keyword("AS");
36968 self.write_space();
36969 self.generate_identifier(alias)?;
36970 return Ok(());
36971 }
36972 } else if let Expression::Alias(ref a) = **this {
36973 self.generate_expression(&a.this)?;
36975 self.write_space();
36976 self.write_keyword(self.config.tablesample_keywords);
36977 self.generate_sample_body(sample)?;
36978 if let Some(ref seed) = sample.seed {
36979 self.write_space();
36980 let use_seed = sample.use_seed_keyword
36981 && !matches!(
36982 self.config.dialect,
36983 Some(crate::dialects::DialectType::Databricks)
36984 | Some(crate::dialects::DialectType::Spark)
36985 );
36986 if use_seed {
36987 self.write_keyword("SEED");
36988 } else {
36989 self.write_keyword("REPEATABLE");
36990 }
36991 self.write(" (");
36992 self.generate_expression(seed)?;
36993 self.write(")");
36994 }
36995 self.write_space();
36997 self.write_keyword("AS");
36998 self.write_space();
36999 self.generate_identifier(&a.alias)?;
37000 return Ok(());
37001 }
37002 }
37003 self.generate_expression(this)?;
37005 self.write_space();
37006 self.write_keyword(self.config.tablesample_keywords);
37007 self.generate_sample_body(sample)?;
37008 if let Some(ref seed) = sample.seed {
37010 self.write_space();
37011 let use_seed = sample.use_seed_keyword
37013 && !matches!(
37014 self.config.dialect,
37015 Some(crate::dialects::DialectType::Databricks)
37016 | Some(crate::dialects::DialectType::Spark)
37017 );
37018 if use_seed {
37019 self.write_keyword("SEED");
37020 } else {
37021 self.write_keyword("REPEATABLE");
37022 }
37023 self.write(" (");
37024 self.generate_expression(seed)?;
37025 self.write(")");
37026 }
37027 return Ok(());
37028 }
37029
37030 self.write_keyword(self.config.tablesample_keywords);
37032 if let Some(method) = &e.method {
37033 self.write_space();
37034 self.write_keyword(method);
37035 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
37036 self.write_space();
37038 self.write_keyword("BERNOULLI");
37039 }
37040 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
37041 self.write_space();
37042 self.write_keyword("BUCKET");
37043 self.write_space();
37044 self.generate_expression(numerator)?;
37045 self.write_space();
37046 self.write_keyword("OUT OF");
37047 self.write_space();
37048 self.generate_expression(denominator)?;
37049 if let Some(field) = &e.bucket_field {
37050 self.write_space();
37051 self.write_keyword("ON");
37052 self.write_space();
37053 self.generate_expression(field)?;
37054 }
37055 } else if !e.expressions.is_empty() {
37056 self.write(" (");
37057 for (i, expr) in e.expressions.iter().enumerate() {
37058 if i > 0 {
37059 self.write(", ");
37060 }
37061 self.generate_expression(expr)?;
37062 }
37063 self.write(")");
37064 } else if let Some(percent) = &e.percent {
37065 self.write(" (");
37066 self.generate_expression(percent)?;
37067 self.write_space();
37068 self.write_keyword("PERCENT");
37069 self.write(")");
37070 }
37071 Ok(())
37072 }
37073
37074 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
37075 if let Some(prefix) = &e.prefix {
37077 self.generate_expression(prefix)?;
37078 }
37079 if let Some(this) = &e.this {
37080 self.generate_expression(this)?;
37081 }
37082 if let Some(postfix) = &e.postfix {
37083 self.generate_expression(postfix)?;
37084 }
37085 Ok(())
37086 }
37087
37088 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
37089 self.write_keyword("TAG");
37091 self.write(" (");
37092 for (i, expr) in e.expressions.iter().enumerate() {
37093 if i > 0 {
37094 self.write(", ");
37095 }
37096 self.generate_expression(expr)?;
37097 }
37098 self.write(")");
37099 Ok(())
37100 }
37101
37102 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
37103 if let Some(this) = &e.this {
37105 self.generate_expression(this)?;
37106 self.write_space();
37107 }
37108 self.write_keyword("TEMPORARY");
37109 Ok(())
37110 }
37111
37112 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
37115 self.write_keyword("TIME");
37117 self.write("(");
37118 self.generate_expression(&e.this)?;
37119 self.write(")");
37120 Ok(())
37121 }
37122
37123 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
37124 self.write_keyword("TIME_ADD");
37126 self.write("(");
37127 self.generate_expression(&e.this)?;
37128 self.write(", ");
37129 self.generate_expression(&e.expression)?;
37130 if let Some(unit) = &e.unit {
37131 self.write(", ");
37132 self.write_keyword(unit);
37133 }
37134 self.write(")");
37135 Ok(())
37136 }
37137
37138 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
37139 self.write_keyword("TIME_DIFF");
37141 self.write("(");
37142 self.generate_expression(&e.this)?;
37143 self.write(", ");
37144 self.generate_expression(&e.expression)?;
37145 if let Some(unit) = &e.unit {
37146 self.write(", ");
37147 self.write_keyword(unit);
37148 }
37149 self.write(")");
37150 Ok(())
37151 }
37152
37153 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
37154 self.write_keyword("TIME_FROM_PARTS");
37156 self.write("(");
37157 let mut first = true;
37158 if let Some(hour) = &e.hour {
37159 self.generate_expression(hour)?;
37160 first = false;
37161 }
37162 if let Some(minute) = &e.min {
37163 if !first {
37164 self.write(", ");
37165 }
37166 self.generate_expression(minute)?;
37167 first = false;
37168 }
37169 if let Some(second) = &e.sec {
37170 if !first {
37171 self.write(", ");
37172 }
37173 self.generate_expression(second)?;
37174 first = false;
37175 }
37176 if let Some(ns) = &e.nano {
37177 if !first {
37178 self.write(", ");
37179 }
37180 self.generate_expression(ns)?;
37181 }
37182 self.write(")");
37183 Ok(())
37184 }
37185
37186 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
37187 self.write_keyword("TIME_SLICE");
37189 self.write("(");
37190 self.generate_expression(&e.this)?;
37191 self.write(", ");
37192 self.generate_expression(&e.expression)?;
37193 self.write(", ");
37194 self.write_keyword(&e.unit);
37195 self.write(")");
37196 Ok(())
37197 }
37198
37199 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
37200 self.write_keyword("TIME_STR_TO_TIME");
37202 self.write("(");
37203 self.generate_expression(&e.this)?;
37204 self.write(")");
37205 Ok(())
37206 }
37207
37208 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
37209 self.write_keyword("TIME_SUB");
37211 self.write("(");
37212 self.generate_expression(&e.this)?;
37213 self.write(", ");
37214 self.generate_expression(&e.expression)?;
37215 if let Some(unit) = &e.unit {
37216 self.write(", ");
37217 self.write_keyword(unit);
37218 }
37219 self.write(")");
37220 Ok(())
37221 }
37222
37223 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
37224 match self.config.dialect {
37225 Some(DialectType::Exasol) => {
37226 self.write_keyword("TO_CHAR");
37228 self.write("(");
37229 self.generate_expression(&e.this)?;
37230 self.write(", '");
37231 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
37232 self.write("'");
37233 self.write(")");
37234 }
37235 Some(DialectType::PostgreSQL)
37236 | Some(DialectType::Redshift)
37237 | Some(DialectType::Materialize) => {
37238 self.write_keyword("TO_CHAR");
37240 self.write("(");
37241 self.generate_expression(&e.this)?;
37242 self.write(", '");
37243 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
37244 self.write("'");
37245 self.write(")");
37246 }
37247 Some(DialectType::Oracle) => {
37248 self.write_keyword("TO_CHAR");
37250 self.write("(");
37251 self.generate_expression(&e.this)?;
37252 self.write(", '");
37253 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
37254 self.write("'");
37255 self.write(")");
37256 }
37257 Some(DialectType::Drill) => {
37258 self.write_keyword("TO_CHAR");
37260 self.write("(");
37261 self.generate_expression(&e.this)?;
37262 self.write(", '");
37263 self.write(&Self::strftime_to_java_format(&e.format));
37264 self.write("'");
37265 self.write(")");
37266 }
37267 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
37268 self.write_keyword("FORMAT");
37270 self.write("(");
37271 self.generate_expression(&e.this)?;
37272 self.write(", '");
37273 self.write(&Self::strftime_to_tsql_format(&e.format));
37274 self.write("'");
37275 self.write(")");
37276 }
37277 Some(DialectType::DuckDB) => {
37278 self.write_keyword("STRFTIME");
37280 self.write("(");
37281 self.generate_expression(&e.this)?;
37282 self.write(", '");
37283 self.write(&e.format);
37284 self.write("'");
37285 self.write(")");
37286 }
37287 Some(DialectType::BigQuery) => {
37288 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
37291 self.write_keyword("FORMAT_DATE");
37292 self.write("('");
37293 self.write(&fmt);
37294 self.write("', ");
37295 self.generate_expression(&e.this)?;
37296 self.write(")");
37297 }
37298 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
37299 self.write_keyword("DATE_FORMAT");
37301 self.write("(");
37302 self.generate_expression(&e.this)?;
37303 self.write(", '");
37304 self.write(&Self::strftime_to_java_format(&e.format));
37305 self.write("'");
37306 self.write(")");
37307 }
37308 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
37309 self.write_keyword("DATE_FORMAT");
37311 self.write("(");
37312 self.generate_expression(&e.this)?;
37313 self.write(", '");
37314 self.write(&e.format);
37315 self.write("'");
37316 self.write(")");
37317 }
37318 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
37319 self.write_keyword("DATE_FORMAT");
37321 self.write("(");
37322 self.generate_expression(&e.this)?;
37323 self.write(", '");
37324 self.write(&e.format);
37325 self.write("'");
37326 self.write(")");
37327 }
37328 _ => {
37329 self.write_keyword("TIME_TO_STR");
37331 self.write("(");
37332 self.generate_expression(&e.this)?;
37333 self.write(", '");
37334 self.write(&e.format);
37335 self.write("'");
37336 self.write(")");
37337 }
37338 }
37339 Ok(())
37340 }
37341
37342 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
37343 match self.config.dialect {
37344 Some(DialectType::DuckDB) => {
37345 self.write_keyword("EPOCH");
37347 self.write("(");
37348 self.generate_expression(&e.this)?;
37349 self.write(")");
37350 }
37351 Some(DialectType::Hive)
37352 | Some(DialectType::Spark)
37353 | Some(DialectType::Databricks)
37354 | Some(DialectType::Doris)
37355 | Some(DialectType::StarRocks)
37356 | Some(DialectType::Drill) => {
37357 self.write_keyword("UNIX_TIMESTAMP");
37359 self.write("(");
37360 self.generate_expression(&e.this)?;
37361 self.write(")");
37362 }
37363 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37364 self.write_keyword("TO_UNIXTIME");
37366 self.write("(");
37367 self.generate_expression(&e.this)?;
37368 self.write(")");
37369 }
37370 _ => {
37371 self.write_keyword("TIME_TO_UNIX");
37373 self.write("(");
37374 self.generate_expression(&e.this)?;
37375 self.write(")");
37376 }
37377 }
37378 Ok(())
37379 }
37380
37381 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
37382 match self.config.dialect {
37383 Some(DialectType::Hive) => {
37384 self.write_keyword("TO_DATE");
37386 self.write("(");
37387 self.generate_expression(&e.this)?;
37388 self.write(")");
37389 }
37390 _ => {
37391 self.write_keyword("TIME_STR_TO_DATE");
37393 self.write("(");
37394 self.generate_expression(&e.this)?;
37395 self.write(")");
37396 }
37397 }
37398 Ok(())
37399 }
37400
37401 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
37402 self.write_keyword("TIME_TRUNC");
37404 self.write("(");
37405 self.generate_expression(&e.this)?;
37406 self.write(", ");
37407 self.write_keyword(&e.unit);
37408 self.write(")");
37409 Ok(())
37410 }
37411
37412 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
37413 if let Some(unit) = &e.unit {
37415 self.write_keyword(unit);
37416 }
37417 Ok(())
37418 }
37419
37420 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
37424 use crate::dialects::DialectType;
37425 use crate::expressions::Literal;
37426
37427 match self.config.dialect {
37428 Some(DialectType::Exasol) => {
37430 self.write_keyword("TO_TIMESTAMP");
37431 self.write("(");
37432 if let Some(this) = &e.this {
37434 match this.as_ref() {
37435 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
37436 let Literal::String(s) = lit.as_ref() else {
37437 unreachable!()
37438 };
37439 self.write("'");
37440 self.write(s);
37441 self.write("'");
37442 }
37443 _ => {
37444 self.generate_expression(this)?;
37445 }
37446 }
37447 }
37448 self.write(")");
37449 }
37450 _ => {
37452 self.write_keyword("TIMESTAMP");
37453 self.write("(");
37454 if let Some(this) = &e.this {
37455 self.generate_expression(this)?;
37456 }
37457 if let Some(zone) = &e.zone {
37458 self.write(", ");
37459 self.generate_expression(zone)?;
37460 }
37461 self.write(")");
37462 }
37463 }
37464 Ok(())
37465 }
37466
37467 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
37468 self.write_keyword("TIMESTAMP_ADD");
37470 self.write("(");
37471 self.generate_expression(&e.this)?;
37472 self.write(", ");
37473 self.generate_expression(&e.expression)?;
37474 if let Some(unit) = &e.unit {
37475 self.write(", ");
37476 self.write_keyword(unit);
37477 }
37478 self.write(")");
37479 Ok(())
37480 }
37481
37482 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
37483 self.write_keyword("TIMESTAMP_DIFF");
37485 self.write("(");
37486 self.generate_expression(&e.this)?;
37487 self.write(", ");
37488 self.generate_expression(&e.expression)?;
37489 if let Some(unit) = &e.unit {
37490 self.write(", ");
37491 self.write_keyword(unit);
37492 }
37493 self.write(")");
37494 Ok(())
37495 }
37496
37497 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
37498 self.write_keyword("TIMESTAMP_FROM_PARTS");
37500 self.write("(");
37501 if let Some(this) = &e.this {
37502 self.generate_expression(this)?;
37503 }
37504 if let Some(expression) = &e.expression {
37505 self.write(", ");
37506 self.generate_expression(expression)?;
37507 }
37508 if let Some(zone) = &e.zone {
37509 self.write(", ");
37510 self.generate_expression(zone)?;
37511 }
37512 if let Some(milli) = &e.milli {
37513 self.write(", ");
37514 self.generate_expression(milli)?;
37515 }
37516 self.write(")");
37517 Ok(())
37518 }
37519
37520 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
37521 self.write_keyword("TIMESTAMP_SUB");
37523 self.write("(");
37524 self.generate_expression(&e.this)?;
37525 self.write(", ");
37526 self.write_keyword("INTERVAL");
37527 self.write_space();
37528 self.generate_expression(&e.expression)?;
37529 if let Some(unit) = &e.unit {
37530 self.write_space();
37531 self.write_keyword(unit);
37532 }
37533 self.write(")");
37534 Ok(())
37535 }
37536
37537 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
37538 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
37540 self.write("(");
37541 if let Some(zone) = &e.zone {
37542 self.generate_expression(zone)?;
37543 }
37544 self.write(")");
37545 Ok(())
37546 }
37547
37548 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
37549 self.write_keyword("TO_BINARY");
37551 self.write("(");
37552 self.generate_expression(&e.this)?;
37553 if let Some(format) = &e.format {
37554 self.write(", '");
37555 self.write(format);
37556 self.write("'");
37557 }
37558 self.write(")");
37559 Ok(())
37560 }
37561
37562 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
37563 self.write_keyword("TO_BOOLEAN");
37565 self.write("(");
37566 self.generate_expression(&e.this)?;
37567 self.write(")");
37568 Ok(())
37569 }
37570
37571 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
37572 self.write_keyword("TO_CHAR");
37574 self.write("(");
37575 self.generate_expression(&e.this)?;
37576 if let Some(format) = &e.format {
37577 self.write(", '");
37578 self.write(format);
37579 self.write("'");
37580 }
37581 if let Some(nlsparam) = &e.nlsparam {
37582 self.write(", ");
37583 self.generate_expression(nlsparam)?;
37584 }
37585 self.write(")");
37586 Ok(())
37587 }
37588
37589 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
37590 self.write_keyword("TO_DECFLOAT");
37592 self.write("(");
37593 self.generate_expression(&e.this)?;
37594 if let Some(format) = &e.format {
37595 self.write(", '");
37596 self.write(format);
37597 self.write("'");
37598 }
37599 self.write(")");
37600 Ok(())
37601 }
37602
37603 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
37604 self.write_keyword("TO_DOUBLE");
37606 self.write("(");
37607 self.generate_expression(&e.this)?;
37608 if let Some(format) = &e.format {
37609 self.write(", '");
37610 self.write(format);
37611 self.write("'");
37612 }
37613 self.write(")");
37614 Ok(())
37615 }
37616
37617 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
37618 self.write_keyword("TO_FILE");
37620 self.write("(");
37621 self.generate_expression(&e.this)?;
37622 if let Some(path) = &e.path {
37623 self.write(", ");
37624 self.generate_expression(path)?;
37625 }
37626 self.write(")");
37627 Ok(())
37628 }
37629
37630 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
37631 let is_safe = e.safe.is_some();
37634 if is_safe {
37635 self.write_keyword("TRY_TO_NUMBER");
37636 } else {
37637 self.write_keyword("TO_NUMBER");
37638 }
37639 self.write("(");
37640 self.generate_expression(&e.this)?;
37641 let precision_is_snowflake_default = e.precision.is_none()
37642 || matches!(
37643 e.precision.as_deref(),
37644 Some(Expression::Literal(lit))
37645 if matches!(lit.as_ref(), Literal::Number(n) if n == "0")
37646 );
37647 let is_snowflake_default_precision =
37648 matches!(self.config.dialect, Some(DialectType::Snowflake))
37649 && e.nlsparam.is_none()
37650 && e.scale.is_none()
37651 && matches!(
37652 e.format.as_deref(),
37653 Some(Expression::Literal(lit))
37654 if matches!(lit.as_ref(), Literal::Number(n) if n == "38")
37655 )
37656 && precision_is_snowflake_default;
37657
37658 if !is_snowflake_default_precision {
37659 if let Some(format) = &e.format {
37660 self.write(", ");
37661 self.generate_expression(format)?;
37662 }
37663 if let Some(nlsparam) = &e.nlsparam {
37664 self.write(", ");
37665 self.generate_expression(nlsparam)?;
37666 }
37667 if let Some(precision) = &e.precision {
37668 self.write(", ");
37669 self.generate_expression(precision)?;
37670 }
37671 if let Some(scale) = &e.scale {
37672 self.write(", ");
37673 self.generate_expression(scale)?;
37674 }
37675 }
37676 self.write(")");
37677 Ok(())
37678 }
37679
37680 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
37681 self.write_keyword("TO_TABLE");
37683 self.write_space();
37684 self.generate_expression(&e.this)?;
37685 Ok(())
37686 }
37687
37688 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
37689 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
37691 Expression::Identifier(id) => id.name.clone(),
37692 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
37693 let Literal::String(s) = lit.as_ref() else {
37694 unreachable!()
37695 };
37696 s.clone()
37697 }
37698 _ => String::new(),
37699 });
37700
37701 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
37702 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
37703 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
37704 matches!(m.as_ref(), Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)))
37705 });
37706
37707 let use_start_transaction = matches!(
37709 self.config.dialect,
37710 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
37711 );
37712 let strip_transaction = matches!(
37714 self.config.dialect,
37715 Some(DialectType::Snowflake)
37716 | Some(DialectType::PostgreSQL)
37717 | Some(DialectType::Redshift)
37718 | Some(DialectType::MySQL)
37719 | Some(DialectType::Hive)
37720 | Some(DialectType::Spark)
37721 | Some(DialectType::Databricks)
37722 | Some(DialectType::DuckDB)
37723 | Some(DialectType::Oracle)
37724 | Some(DialectType::Doris)
37725 | Some(DialectType::StarRocks)
37726 | Some(DialectType::Materialize)
37727 | Some(DialectType::ClickHouse)
37728 );
37729
37730 if is_start || use_start_transaction {
37731 self.write_keyword("START TRANSACTION");
37733 if let Some(modes) = &e.modes {
37734 self.write_space();
37735 self.generate_expression(modes)?;
37736 }
37737 } else {
37738 self.write_keyword("BEGIN");
37740
37741 let is_kind = e.this.as_ref().map_or(false, |t| {
37743 if let Expression::Identifier(id) = t.as_ref() {
37744 id.name.eq_ignore_ascii_case("DEFERRED")
37745 || id.name.eq_ignore_ascii_case("IMMEDIATE")
37746 || id.name.eq_ignore_ascii_case("EXCLUSIVE")
37747 } else {
37748 false
37749 }
37750 });
37751
37752 if is_kind {
37754 if let Some(this) = &e.this {
37755 self.write_space();
37756 if let Expression::Identifier(id) = this.as_ref() {
37757 self.write_keyword(&id.name);
37758 }
37759 }
37760 }
37761
37762 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
37764 self.write_space();
37765 self.write_keyword("TRANSACTION");
37766 }
37767
37768 if !is_kind {
37770 if let Some(this) = &e.this {
37771 self.write_space();
37772 self.generate_expression(this)?;
37773 }
37774 }
37775
37776 if has_with_mark {
37778 self.write_space();
37779 self.write_keyword("WITH MARK");
37780 if let Some(Expression::Literal(lit)) = e.mark.as_deref() {
37781 if let Literal::String(desc) = lit.as_ref() {
37782 if !desc.is_empty() {
37783 self.write_space();
37784 self.write(&format!("'{}'", desc));
37785 }
37786 }
37787 }
37788 }
37789
37790 if let Some(modes) = &e.modes {
37792 self.write_space();
37793 self.generate_expression(modes)?;
37794 }
37795 }
37796 Ok(())
37797 }
37798
37799 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
37800 self.write_keyword("TRANSFORM");
37802 self.write("(");
37803 self.generate_expression(&e.this)?;
37804 self.write(", ");
37805 self.generate_expression(&e.expression)?;
37806 self.write(")");
37807 Ok(())
37808 }
37809
37810 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
37811 self.write_keyword("TRANSFORM");
37813 self.write("(");
37814 if self.config.pretty && !e.expressions.is_empty() {
37815 self.indent_level += 1;
37816 for (i, expr) in e.expressions.iter().enumerate() {
37817 if i > 0 {
37818 self.write(",");
37819 }
37820 self.write_newline();
37821 self.write_indent();
37822 self.generate_expression(expr)?;
37823 }
37824 self.indent_level -= 1;
37825 self.write_newline();
37826 self.write(")");
37827 } else {
37828 for (i, expr) in e.expressions.iter().enumerate() {
37829 if i > 0 {
37830 self.write(", ");
37831 }
37832 self.generate_expression(expr)?;
37833 }
37834 self.write(")");
37835 }
37836 Ok(())
37837 }
37838
37839 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
37840 use crate::dialects::DialectType;
37841 if let Some(this) = &e.this {
37843 self.generate_expression(this)?;
37844 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
37845 self.write_space();
37846 }
37847 }
37848 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
37849 self.write_keyword("TRANSIENT");
37850 }
37851 Ok(())
37852 }
37853
37854 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
37855 self.write_keyword("TRANSLATE");
37857 self.write("(");
37858 self.generate_expression(&e.this)?;
37859 if let Some(from) = &e.from_ {
37860 self.write(", ");
37861 self.generate_expression(from)?;
37862 }
37863 if let Some(to) = &e.to {
37864 self.write(", ");
37865 self.generate_expression(to)?;
37866 }
37867 self.write(")");
37868 Ok(())
37869 }
37870
37871 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
37872 self.write_keyword("TRANSLATE");
37874 self.write("(");
37875 self.generate_expression(&e.this)?;
37876 self.write_space();
37877 self.write_keyword("USING");
37878 self.write_space();
37879 self.generate_expression(&e.expression)?;
37880 if e.with_error.is_some() {
37881 self.write_space();
37882 self.write_keyword("WITH ERROR");
37883 }
37884 self.write(")");
37885 Ok(())
37886 }
37887
37888 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
37889 self.write_keyword("TRUNCATE TABLE");
37891 self.write_space();
37892 for (i, expr) in e.expressions.iter().enumerate() {
37893 if i > 0 {
37894 self.write(", ");
37895 }
37896 self.generate_expression(expr)?;
37897 }
37898 Ok(())
37899 }
37900
37901 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
37902 self.write_keyword("TRY_BASE64_DECODE_BINARY");
37904 self.write("(");
37905 self.generate_expression(&e.this)?;
37906 if let Some(alphabet) = &e.alphabet {
37907 self.write(", ");
37908 self.generate_expression(alphabet)?;
37909 }
37910 self.write(")");
37911 Ok(())
37912 }
37913
37914 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
37915 self.write_keyword("TRY_BASE64_DECODE_STRING");
37917 self.write("(");
37918 self.generate_expression(&e.this)?;
37919 if let Some(alphabet) = &e.alphabet {
37920 self.write(", ");
37921 self.generate_expression(alphabet)?;
37922 }
37923 self.write(")");
37924 Ok(())
37925 }
37926
37927 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
37928 self.write_keyword("TRY_TO_DECFLOAT");
37930 self.write("(");
37931 self.generate_expression(&e.this)?;
37932 if let Some(format) = &e.format {
37933 self.write(", '");
37934 self.write(format);
37935 self.write("'");
37936 }
37937 self.write(")");
37938 Ok(())
37939 }
37940
37941 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
37942 self.write_keyword("TS_OR_DS_ADD");
37944 self.write("(");
37945 self.generate_expression(&e.this)?;
37946 self.write(", ");
37947 self.generate_expression(&e.expression)?;
37948 if let Some(unit) = &e.unit {
37949 self.write(", ");
37950 self.write_keyword(unit);
37951 }
37952 if let Some(return_type) = &e.return_type {
37953 self.write(", ");
37954 self.generate_expression(return_type)?;
37955 }
37956 self.write(")");
37957 Ok(())
37958 }
37959
37960 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
37961 self.write_keyword("TS_OR_DS_DIFF");
37963 self.write("(");
37964 self.generate_expression(&e.this)?;
37965 self.write(", ");
37966 self.generate_expression(&e.expression)?;
37967 if let Some(unit) = &e.unit {
37968 self.write(", ");
37969 self.write_keyword(unit);
37970 }
37971 self.write(")");
37972 Ok(())
37973 }
37974
37975 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
37976 let default_time_format = "%Y-%m-%d %H:%M:%S";
37977 let default_date_format = "%Y-%m-%d";
37978 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
37979 f != default_time_format && f != default_date_format
37980 });
37981
37982 if has_non_default_format {
37983 let fmt = e.format.as_ref().unwrap();
37985 match self.config.dialect {
37986 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
37987 let str_to_time = crate::expressions::StrToTime {
37990 this: Box::new((*e.this).clone()),
37991 format: fmt.clone(),
37992 zone: None,
37993 safe: None,
37994 target_type: None,
37995 };
37996 self.generate_str_to_time(&str_to_time)?;
37997 }
37998 Some(DialectType::Hive)
37999 | Some(DialectType::Spark)
38000 | Some(DialectType::Databricks) => {
38001 self.write_keyword("TO_DATE");
38003 self.write("(");
38004 self.generate_expression(&e.this)?;
38005 self.write(", '");
38006 self.write(&Self::strftime_to_java_format(fmt));
38007 self.write("')");
38008 }
38009 Some(DialectType::Snowflake) => {
38010 self.write_keyword("TO_DATE");
38012 self.write("(");
38013 self.generate_expression(&e.this)?;
38014 self.write(", '");
38015 self.write(&Self::strftime_to_snowflake_format(fmt));
38016 self.write("')");
38017 }
38018 Some(DialectType::Doris) => {
38019 self.write_keyword("TO_DATE");
38021 self.write("(");
38022 self.generate_expression(&e.this)?;
38023 self.write(")");
38024 }
38025 _ => {
38026 self.write_keyword("CAST");
38028 self.write("(");
38029 let str_to_time = crate::expressions::StrToTime {
38030 this: Box::new((*e.this).clone()),
38031 format: fmt.clone(),
38032 zone: None,
38033 safe: None,
38034 target_type: None,
38035 };
38036 self.generate_str_to_time(&str_to_time)?;
38037 self.write_keyword(" AS ");
38038 self.write_keyword("DATE");
38039 self.write(")");
38040 }
38041 }
38042 } else {
38043 match self.config.dialect {
38045 Some(DialectType::MySQL)
38046 | Some(DialectType::SQLite)
38047 | Some(DialectType::StarRocks) => {
38048 self.write_keyword("DATE");
38050 self.write("(");
38051 self.generate_expression(&e.this)?;
38052 self.write(")");
38053 }
38054 Some(DialectType::Hive)
38055 | Some(DialectType::Spark)
38056 | Some(DialectType::Databricks)
38057 | Some(DialectType::Snowflake)
38058 | Some(DialectType::Doris) => {
38059 self.write_keyword("TO_DATE");
38061 self.write("(");
38062 self.generate_expression(&e.this)?;
38063 self.write(")");
38064 }
38065 Some(DialectType::Presto)
38066 | Some(DialectType::Trino)
38067 | Some(DialectType::Athena) => {
38068 self.write_keyword("CAST");
38070 self.write("(");
38071 self.write_keyword("CAST");
38072 self.write("(");
38073 self.generate_expression(&e.this)?;
38074 self.write_keyword(" AS ");
38075 self.write_keyword("TIMESTAMP");
38076 self.write(")");
38077 self.write_keyword(" AS ");
38078 self.write_keyword("DATE");
38079 self.write(")");
38080 }
38081 Some(DialectType::ClickHouse) => {
38082 self.write_keyword("CAST");
38084 self.write("(");
38085 self.generate_expression(&e.this)?;
38086 self.write_keyword(" AS ");
38087 self.write("Nullable(DATE)");
38088 self.write(")");
38089 }
38090 _ => {
38091 self.write_keyword("CAST");
38093 self.write("(");
38094 self.generate_expression(&e.this)?;
38095 self.write_keyword(" AS ");
38096 self.write_keyword("DATE");
38097 self.write(")");
38098 }
38099 }
38100 }
38101 Ok(())
38102 }
38103
38104 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
38105 self.write_keyword("TS_OR_DS_TO_TIME");
38107 self.write("(");
38108 self.generate_expression(&e.this)?;
38109 if let Some(format) = &e.format {
38110 self.write(", '");
38111 self.write(format);
38112 self.write("'");
38113 }
38114 self.write(")");
38115 Ok(())
38116 }
38117
38118 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
38119 self.write_keyword("UNHEX");
38121 self.write("(");
38122 self.generate_expression(&e.this)?;
38123 if let Some(expression) = &e.expression {
38124 self.write(", ");
38125 self.generate_expression(expression)?;
38126 }
38127 self.write(")");
38128 Ok(())
38129 }
38130
38131 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
38132 self.write("U&");
38134 self.generate_expression(&e.this)?;
38135 if let Some(escape) = &e.escape {
38136 self.write_space();
38137 self.write_keyword("UESCAPE");
38138 self.write_space();
38139 self.generate_expression(escape)?;
38140 }
38141 Ok(())
38142 }
38143
38144 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
38145 self.write_keyword("UNIFORM");
38147 self.write("(");
38148 self.generate_expression(&e.this)?;
38149 self.write(", ");
38150 self.generate_expression(&e.expression)?;
38151 if let Some(gen) = &e.gen {
38152 self.write(", ");
38153 self.generate_expression(gen)?;
38154 }
38155 if let Some(seed) = &e.seed {
38156 self.write(", ");
38157 self.generate_expression(seed)?;
38158 }
38159 self.write(")");
38160 Ok(())
38161 }
38162
38163 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
38164 self.write_keyword("UNIQUE");
38166 if e.nulls.is_some() {
38168 self.write(" NULLS NOT DISTINCT");
38169 }
38170 if let Some(this) = &e.this {
38171 self.write_space();
38172 self.generate_expression(this)?;
38173 }
38174 if let Some(index_type) = &e.index_type {
38175 self.write(" USING ");
38176 self.generate_expression(index_type)?;
38177 }
38178 if let Some(on_conflict) = &e.on_conflict {
38179 self.write_space();
38180 self.generate_expression(on_conflict)?;
38181 }
38182 for opt in &e.options {
38183 self.write_space();
38184 self.generate_expression(opt)?;
38185 }
38186 Ok(())
38187 }
38188
38189 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
38190 self.write_keyword("UNIQUE KEY");
38192 self.write(" (");
38193 for (i, expr) in e.expressions.iter().enumerate() {
38194 if i > 0 {
38195 self.write(", ");
38196 }
38197 self.generate_expression(expr)?;
38198 }
38199 self.write(")");
38200 Ok(())
38201 }
38202
38203 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
38204 self.write_keyword("ROLLUP");
38206 self.write(" (");
38207 for (i, index) in e.expressions.iter().enumerate() {
38208 if i > 0 {
38209 self.write(", ");
38210 }
38211 self.generate_identifier(&index.name)?;
38212 self.write("(");
38213 for (j, col) in index.expressions.iter().enumerate() {
38214 if j > 0 {
38215 self.write(", ");
38216 }
38217 self.generate_identifier(col)?;
38218 }
38219 self.write(")");
38220 }
38221 self.write(")");
38222 Ok(())
38223 }
38224
38225 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
38226 match self.config.dialect {
38227 Some(DialectType::DuckDB) => {
38228 self.write_keyword("STRFTIME");
38230 self.write("(");
38231 self.write_keyword("TO_TIMESTAMP");
38232 self.write("(");
38233 self.generate_expression(&e.this)?;
38234 self.write("), '");
38235 if let Some(format) = &e.format {
38236 self.write(format);
38237 }
38238 self.write("')");
38239 }
38240 Some(DialectType::Hive) => {
38241 self.write_keyword("FROM_UNIXTIME");
38243 self.write("(");
38244 self.generate_expression(&e.this)?;
38245 if let Some(format) = &e.format {
38246 if format != "yyyy-MM-dd HH:mm:ss" {
38247 self.write(", '");
38248 self.write(format);
38249 self.write("'");
38250 }
38251 }
38252 self.write(")");
38253 }
38254 Some(DialectType::Presto) | Some(DialectType::Trino) => {
38255 self.write_keyword("DATE_FORMAT");
38257 self.write("(");
38258 self.write_keyword("FROM_UNIXTIME");
38259 self.write("(");
38260 self.generate_expression(&e.this)?;
38261 self.write("), '");
38262 if let Some(format) = &e.format {
38263 self.write(format);
38264 }
38265 self.write("')");
38266 }
38267 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
38268 self.write_keyword("FROM_UNIXTIME");
38270 self.write("(");
38271 self.generate_expression(&e.this)?;
38272 if let Some(format) = &e.format {
38273 self.write(", '");
38274 self.write(format);
38275 self.write("'");
38276 }
38277 self.write(")");
38278 }
38279 _ => {
38280 self.write_keyword("UNIX_TO_STR");
38282 self.write("(");
38283 self.generate_expression(&e.this)?;
38284 if let Some(format) = &e.format {
38285 self.write(", '");
38286 self.write(format);
38287 self.write("'");
38288 }
38289 self.write(")");
38290 }
38291 }
38292 Ok(())
38293 }
38294
38295 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
38296 use crate::dialects::DialectType;
38297 let scale = e.scale.unwrap_or(0); match self.config.dialect {
38300 Some(DialectType::Snowflake) => {
38301 self.write_keyword("TO_TIMESTAMP");
38303 self.write("(");
38304 self.generate_expression(&e.this)?;
38305 if let Some(s) = e.scale {
38306 if s > 0 {
38307 self.write(", ");
38308 self.write(&s.to_string());
38309 }
38310 }
38311 self.write(")");
38312 }
38313 Some(DialectType::BigQuery) => {
38314 match scale {
38317 0 => {
38318 self.write_keyword("TIMESTAMP_SECONDS");
38319 self.write("(");
38320 self.generate_expression(&e.this)?;
38321 self.write(")");
38322 }
38323 3 => {
38324 self.write_keyword("TIMESTAMP_MILLIS");
38325 self.write("(");
38326 self.generate_expression(&e.this)?;
38327 self.write(")");
38328 }
38329 6 => {
38330 self.write_keyword("TIMESTAMP_MICROS");
38331 self.write("(");
38332 self.generate_expression(&e.this)?;
38333 self.write(")");
38334 }
38335 _ => {
38336 self.write_keyword("TIMESTAMP_SECONDS");
38338 self.write("(CAST(");
38339 self.generate_expression(&e.this)?;
38340 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
38341 }
38342 }
38343 }
38344 Some(DialectType::Spark) => {
38345 match scale {
38350 0 => {
38351 self.write_keyword("CAST");
38352 self.write("(");
38353 self.write_keyword("FROM_UNIXTIME");
38354 self.write("(");
38355 self.generate_expression(&e.this)?;
38356 self.write(") ");
38357 self.write_keyword("AS TIMESTAMP");
38358 self.write(")");
38359 }
38360 3 => {
38361 self.write_keyword("TIMESTAMP_MILLIS");
38362 self.write("(");
38363 self.generate_expression(&e.this)?;
38364 self.write(")");
38365 }
38366 6 => {
38367 self.write_keyword("TIMESTAMP_MICROS");
38368 self.write("(");
38369 self.generate_expression(&e.this)?;
38370 self.write(")");
38371 }
38372 _ => {
38373 self.write_keyword("TIMESTAMP_SECONDS");
38374 self.write("(");
38375 self.generate_expression(&e.this)?;
38376 self.write(&format!(" / POWER(10, {}))", scale));
38377 }
38378 }
38379 }
38380 Some(DialectType::Databricks) => {
38381 match scale {
38385 0 => {
38386 self.write_keyword("CAST");
38387 self.write("(");
38388 self.write_keyword("FROM_UNIXTIME");
38389 self.write("(");
38390 self.generate_expression(&e.this)?;
38391 self.write(") ");
38392 self.write_keyword("AS TIMESTAMP");
38393 self.write(")");
38394 }
38395 3 => {
38396 self.write_keyword("TIMESTAMP_MILLIS");
38397 self.write("(");
38398 self.generate_expression(&e.this)?;
38399 self.write(")");
38400 }
38401 6 => {
38402 self.write_keyword("TIMESTAMP_MICROS");
38403 self.write("(");
38404 self.generate_expression(&e.this)?;
38405 self.write(")");
38406 }
38407 _ => {
38408 self.write_keyword("TIMESTAMP_SECONDS");
38409 self.write("(");
38410 self.generate_expression(&e.this)?;
38411 self.write(&format!(" / POWER(10, {}))", scale));
38412 }
38413 }
38414 }
38415 Some(DialectType::Hive) => {
38416 if scale == 0 {
38418 self.write_keyword("FROM_UNIXTIME");
38419 self.write("(");
38420 self.generate_expression(&e.this)?;
38421 self.write(")");
38422 } else {
38423 self.write_keyword("FROM_UNIXTIME");
38424 self.write("(");
38425 self.generate_expression(&e.this)?;
38426 self.write(&format!(" / POWER(10, {})", scale));
38427 self.write(")");
38428 }
38429 }
38430 Some(DialectType::Presto) | Some(DialectType::Trino) => {
38431 if scale == 0 {
38434 self.write_keyword("FROM_UNIXTIME");
38435 self.write("(");
38436 self.generate_expression(&e.this)?;
38437 self.write(")");
38438 } else {
38439 self.write_keyword("FROM_UNIXTIME");
38440 self.write("(CAST(");
38441 self.generate_expression(&e.this)?;
38442 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
38443 }
38444 }
38445 Some(DialectType::DuckDB) => {
38446 match scale {
38450 0 => {
38451 self.write_keyword("TO_TIMESTAMP");
38452 self.write("(");
38453 self.generate_expression(&e.this)?;
38454 self.write(")");
38455 }
38456 3 => {
38457 self.write_keyword("EPOCH_MS");
38458 self.write("(");
38459 self.generate_expression(&e.this)?;
38460 self.write(")");
38461 }
38462 6 => {
38463 self.write_keyword("MAKE_TIMESTAMP");
38464 self.write("(");
38465 self.generate_expression(&e.this)?;
38466 self.write(")");
38467 }
38468 _ => {
38469 self.write_keyword("TO_TIMESTAMP");
38470 self.write("(");
38471 self.generate_expression(&e.this)?;
38472 self.write(&format!(" / POWER(10, {}))", scale));
38473 self.write_keyword(" AT TIME ZONE");
38474 self.write(" 'UTC'");
38475 }
38476 }
38477 }
38478 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
38479 self.write_keyword("FROM_UNIXTIME");
38481 self.write("(");
38482 self.generate_expression(&e.this)?;
38483 self.write(")");
38484 }
38485 Some(DialectType::Oracle) => {
38486 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
38488 self.generate_expression(&e.this)?;
38489 self.write(" / 86400)");
38490 }
38491 Some(DialectType::Redshift) => {
38492 self.write("(TIMESTAMP 'epoch' + ");
38495 if scale == 0 {
38496 self.generate_expression(&e.this)?;
38497 } else {
38498 self.write("(");
38499 self.generate_expression(&e.this)?;
38500 self.write(&format!(" / POWER(10, {}))", scale));
38501 }
38502 self.write(" * INTERVAL '1 SECOND')");
38503 }
38504 Some(DialectType::Exasol) => {
38505 self.write_keyword("FROM_POSIX_TIME");
38507 self.write("(");
38508 self.generate_expression(&e.this)?;
38509 self.write(")");
38510 }
38511 _ => {
38512 self.write_keyword("TO_TIMESTAMP");
38514 self.write("(");
38515 self.generate_expression(&e.this)?;
38516 if let Some(s) = e.scale {
38517 self.write(", ");
38518 self.write(&s.to_string());
38519 }
38520 self.write(")");
38521 }
38522 }
38523 Ok(())
38524 }
38525
38526 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
38527 if !matches!(&*e.this, Expression::Null(_)) {
38529 self.write_keyword("NAME");
38530 self.write_space();
38531 self.generate_expression(&e.this)?;
38532 }
38533 if !e.expressions.is_empty() {
38534 self.write_space();
38535 self.write_keyword("VALUE");
38536 self.write_space();
38537 for (i, expr) in e.expressions.iter().enumerate() {
38538 if i > 0 {
38539 self.write(", ");
38540 }
38541 self.generate_expression(expr)?;
38542 }
38543 }
38544 Ok(())
38545 }
38546
38547 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
38548 if e.wrapped.is_some() {
38550 self.write("(");
38551 }
38552 self.generate_expression(&e.this)?;
38553 if e.wrapped.is_some() {
38554 self.write(")");
38555 }
38556 self.write("(");
38557 for (i, expr) in e.expressions.iter().enumerate() {
38558 if i > 0 {
38559 self.write(", ");
38560 }
38561 self.generate_expression(expr)?;
38562 }
38563 self.write(")");
38564 Ok(())
38565 }
38566
38567 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
38568 self.write_keyword("USING TEMPLATE");
38570 self.write_space();
38571 self.generate_expression(&e.this)?;
38572 Ok(())
38573 }
38574
38575 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
38576 self.write_keyword("UTC_TIME");
38578 Ok(())
38579 }
38580
38581 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
38582 if matches!(
38583 self.config.dialect,
38584 Some(crate::dialects::DialectType::ClickHouse)
38585 ) {
38586 self.write_keyword("CURRENT_TIMESTAMP");
38587 self.write("('UTC')");
38588 } else {
38589 self.write_keyword("UTC_TIMESTAMP");
38590 }
38591 Ok(())
38592 }
38593
38594 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
38595 use crate::dialects::DialectType;
38596 let func_name = match self.config.dialect {
38598 Some(DialectType::Snowflake) => "UUID_STRING",
38599 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
38600 Some(DialectType::BigQuery) => "GENERATE_UUID",
38601 _ => {
38602 if let Some(name) = &e.name {
38603 name.as_str()
38604 } else {
38605 "UUID"
38606 }
38607 }
38608 };
38609 self.write_keyword(func_name);
38610 self.write("(");
38611 if let Some(this) = &e.this {
38612 self.generate_expression(this)?;
38613 }
38614 self.write(")");
38615 Ok(())
38616 }
38617
38618 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
38619 self.write_keyword("MAP");
38621 self.write("(");
38622 let mut first = true;
38623 for (k, v) in e.keys.iter().zip(e.values.iter()) {
38624 if !first {
38625 self.write(", ");
38626 }
38627 self.generate_expression(k)?;
38628 self.write(", ");
38629 self.generate_expression(v)?;
38630 first = false;
38631 }
38632 self.write(")");
38633 Ok(())
38634 }
38635
38636 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
38637 self.write_keyword("VECTOR_SEARCH");
38639 self.write("(");
38640 self.generate_expression(&e.this)?;
38641 if let Some(col) = &e.column_to_search {
38642 self.write(", ");
38643 self.generate_expression(col)?;
38644 }
38645 if let Some(query_table) = &e.query_table {
38646 self.write(", ");
38647 self.generate_expression(query_table)?;
38648 }
38649 if let Some(query_col) = &e.query_column_to_search {
38650 self.write(", ");
38651 self.generate_expression(query_col)?;
38652 }
38653 if let Some(top_k) = &e.top_k {
38654 self.write(", ");
38655 self.generate_expression(top_k)?;
38656 }
38657 if let Some(dist_type) = &e.distance_type {
38658 self.write(", ");
38659 self.generate_expression(dist_type)?;
38660 }
38661 self.write(")");
38662 Ok(())
38663 }
38664
38665 fn generate_version(&mut self, e: &Version) -> Result<()> {
38666 use crate::dialects::DialectType;
38672 let skip_for = matches!(
38673 self.config.dialect,
38674 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
38675 );
38676 if !skip_for {
38677 self.write_keyword("FOR");
38678 self.write_space();
38679 }
38680 match e.this.as_ref() {
38682 Expression::Identifier(ident) => {
38683 self.write_keyword(&ident.name);
38684 }
38685 _ => {
38686 self.generate_expression(&e.this)?;
38687 }
38688 }
38689 self.write_space();
38690 self.write_keyword(&e.kind);
38691 if let Some(expression) = &e.expression {
38692 self.write_space();
38693 self.generate_expression(expression)?;
38694 }
38695 Ok(())
38696 }
38697
38698 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
38699 self.generate_expression(&e.this)?;
38701 Ok(())
38702 }
38703
38704 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
38705 if e.this.is_some() {
38707 self.write_keyword("NOT VOLATILE");
38708 } else {
38709 self.write_keyword("VOLATILE");
38710 }
38711 Ok(())
38712 }
38713
38714 fn generate_watermark_column_constraint(
38715 &mut self,
38716 e: &WatermarkColumnConstraint,
38717 ) -> Result<()> {
38718 self.write_keyword("WATERMARK FOR");
38720 self.write_space();
38721 self.generate_expression(&e.this)?;
38722 self.write_space();
38723 self.write_keyword("AS");
38724 self.write_space();
38725 self.generate_expression(&e.expression)?;
38726 Ok(())
38727 }
38728
38729 fn generate_week(&mut self, e: &Week) -> Result<()> {
38730 self.write_keyword("WEEK");
38732 self.write("(");
38733 self.generate_expression(&e.this)?;
38734 if let Some(mode) = &e.mode {
38735 self.write(", ");
38736 self.generate_expression(mode)?;
38737 }
38738 self.write(")");
38739 Ok(())
38740 }
38741
38742 fn generate_when(&mut self, e: &When) -> Result<()> {
38743 self.write_keyword("WHEN");
38747 self.write_space();
38748
38749 if let Some(matched) = &e.matched {
38751 match matched.as_ref() {
38753 Expression::Boolean(b) if b.value => {
38754 self.write_keyword("MATCHED");
38755 }
38756 _ => {
38757 self.write_keyword("NOT MATCHED");
38758 }
38759 }
38760 } else {
38761 self.write_keyword("NOT MATCHED");
38762 }
38763
38764 if self.config.matched_by_source {
38769 if let Some(source) = &e.source {
38770 if let Expression::Boolean(b) = source.as_ref() {
38771 if b.value {
38772 self.write_space();
38774 self.write_keyword("BY SOURCE");
38775 }
38776 } else {
38778 self.write_space();
38780 self.write_keyword("BY SOURCE");
38781 }
38782 }
38783 }
38784
38785 if let Some(condition) = &e.condition {
38787 self.write_space();
38788 self.write_keyword("AND");
38789 self.write_space();
38790 self.generate_expression(condition)?;
38791 }
38792
38793 self.write_space();
38794 self.write_keyword("THEN");
38795 self.write_space();
38796
38797 self.generate_merge_action(&e.then)?;
38800
38801 Ok(())
38802 }
38803
38804 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
38805 match action {
38806 Expression::Tuple(tuple) => {
38807 let elements = &tuple.expressions;
38808 if elements.is_empty() {
38809 return self.generate_expression(action);
38810 }
38811 match &elements[0] {
38813 Expression::Var(v) if v.this == "INSERT" => {
38814 self.write_keyword("INSERT");
38815 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
38817 self.write(" *");
38818 if let Some(Expression::Where(w)) = elements.get(2) {
38819 self.write_space();
38820 self.generate_where(w)?;
38821 }
38822 } else {
38823 let mut values_idx = 1;
38824 if elements.len() > 1 {
38826 if let Expression::Tuple(cols) = &elements[1] {
38827 if elements.len() > 2 {
38829 self.write(" (");
38831 for (i, col) in cols.expressions.iter().enumerate() {
38832 if i > 0 {
38833 self.write(", ");
38834 }
38835 if !self.merge_strip_qualifiers.is_empty() {
38837 let stripped = self.strip_merge_qualifier(col);
38838 self.generate_expression(&stripped)?;
38839 } else {
38840 self.generate_expression(col)?;
38841 }
38842 }
38843 self.write(")");
38844 values_idx = 2;
38845 } else {
38846 values_idx = 1;
38848 }
38849 }
38850 }
38851 let mut next_idx = values_idx;
38852 if values_idx < elements.len()
38854 && !matches!(&elements[values_idx], Expression::Where(_))
38855 {
38856 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
38858 if !is_row {
38859 self.write_space();
38860 self.write_keyword("VALUES");
38861 }
38862 self.write(" ");
38863 if let Expression::Tuple(vals) = &elements[values_idx] {
38864 self.write("(");
38865 for (i, val) in vals.expressions.iter().enumerate() {
38866 if i > 0 {
38867 self.write(", ");
38868 }
38869 self.generate_expression(val)?;
38870 }
38871 self.write(")");
38872 } else {
38873 self.generate_expression(&elements[values_idx])?;
38874 }
38875 next_idx += 1;
38876 }
38877 if let Some(Expression::Where(w)) = elements.get(next_idx) {
38878 self.write_space();
38879 self.generate_where(w)?;
38880 }
38881 } }
38883 Expression::Var(v) if v.this == "UPDATE" => {
38884 self.write_keyword("UPDATE");
38885 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
38887 self.write(" *");
38888 if let Some(Expression::Where(w)) = elements.get(2) {
38889 self.write_space();
38890 self.generate_where(w)?;
38891 }
38892 } else if elements.len() > 1 {
38893 self.write_space();
38894 self.write_keyword("SET");
38895 if self.config.pretty {
38897 self.write_newline();
38898 self.indent_level += 1;
38899 self.write_indent();
38900 } else {
38901 self.write_space();
38902 }
38903 if let Expression::Tuple(assignments) = &elements[1] {
38904 for (i, assignment) in assignments.expressions.iter().enumerate() {
38905 if i > 0 {
38906 if self.config.pretty {
38907 self.write(",");
38908 self.write_newline();
38909 self.write_indent();
38910 } else {
38911 self.write(", ");
38912 }
38913 }
38914 if !self.merge_strip_qualifiers.is_empty() {
38916 self.generate_merge_set_assignment(assignment)?;
38917 } else {
38918 self.generate_expression(assignment)?;
38919 }
38920 }
38921 } else {
38922 self.generate_expression(&elements[1])?;
38923 }
38924 if self.config.pretty {
38925 self.indent_level -= 1;
38926 }
38927 if let Some(Expression::Where(w)) = elements.get(2) {
38928 self.write_space();
38929 self.generate_where(w)?;
38930 }
38931 }
38932 }
38933 Expression::Var(v) if v.this == "DELETE" => {
38934 self.write_keyword("DELETE");
38935 if let Some(Expression::Where(w)) = elements.get(1) {
38936 self.write_space();
38937 self.generate_where(w)?;
38938 }
38939 }
38940 _ => {
38941 self.generate_expression(action)?;
38943 }
38944 }
38945 }
38946 Expression::Var(v)
38947 if v.this == "INSERT"
38948 || v.this == "UPDATE"
38949 || v.this == "DELETE"
38950 || v.this == "DO NOTHING" =>
38951 {
38952 self.write_keyword(&v.this);
38953 }
38954 _ => {
38955 self.generate_expression(action)?;
38956 }
38957 }
38958 Ok(())
38959 }
38960
38961 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
38963 match assignment {
38964 Expression::Eq(eq) => {
38965 let stripped_left = self.strip_merge_qualifier(&eq.left);
38967 self.generate_expression(&stripped_left)?;
38968 self.write(" = ");
38969 self.generate_expression(&eq.right)?;
38970 Ok(())
38971 }
38972 other => self.generate_expression(other),
38973 }
38974 }
38975
38976 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
38978 match expr {
38979 Expression::Column(col) => {
38980 if let Some(ref table_ident) = col.table {
38981 if self
38982 .merge_strip_qualifiers
38983 .iter()
38984 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
38985 {
38986 let mut col = col.clone();
38988 col.table = None;
38989 return Expression::Column(col);
38990 }
38991 }
38992 expr.clone()
38993 }
38994 Expression::Dot(dot) => {
38995 if let Expression::Identifier(id) = &dot.this {
38997 if self
38998 .merge_strip_qualifiers
38999 .iter()
39000 .any(|n| n.eq_ignore_ascii_case(&id.name))
39001 {
39002 return Expression::Identifier(dot.field.clone());
39003 }
39004 }
39005 expr.clone()
39006 }
39007 _ => expr.clone(),
39008 }
39009 }
39010
39011 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
39012 for (i, expr) in e.expressions.iter().enumerate() {
39014 if i > 0 {
39015 if self.config.pretty {
39017 self.write_newline();
39018 self.write_indent();
39019 } else {
39020 self.write_space();
39021 }
39022 }
39023 self.generate_expression(expr)?;
39024 }
39025 Ok(())
39026 }
39027
39028 fn generate_where(&mut self, e: &Where) -> Result<()> {
39029 self.write_keyword("WHERE");
39031 self.write_space();
39032 self.generate_expression(&e.this)?;
39033 Ok(())
39034 }
39035
39036 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
39037 self.write_keyword("WIDTH_BUCKET");
39039 self.write("(");
39040 self.generate_expression(&e.this)?;
39041 if let Some(min_value) = &e.min_value {
39042 self.write(", ");
39043 self.generate_expression(min_value)?;
39044 }
39045 if let Some(max_value) = &e.max_value {
39046 self.write(", ");
39047 self.generate_expression(max_value)?;
39048 }
39049 if let Some(num_buckets) = &e.num_buckets {
39050 self.write(", ");
39051 self.generate_expression(num_buckets)?;
39052 }
39053 self.write(")");
39054 Ok(())
39055 }
39056
39057 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
39058 self.generate_window_spec(e)
39060 }
39061
39062 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
39063 let mut has_content = false;
39065
39066 if !e.partition_by.is_empty() {
39068 self.write_keyword("PARTITION BY");
39069 self.write_space();
39070 for (i, expr) in e.partition_by.iter().enumerate() {
39071 if i > 0 {
39072 self.write(", ");
39073 }
39074 self.generate_expression(expr)?;
39075 }
39076 has_content = true;
39077 }
39078
39079 if !e.order_by.is_empty() {
39081 if has_content {
39082 self.write_space();
39083 }
39084 self.write_keyword("ORDER BY");
39085 self.write_space();
39086 for (i, ordered) in e.order_by.iter().enumerate() {
39087 if i > 0 {
39088 self.write(", ");
39089 }
39090 self.generate_expression(&ordered.this)?;
39091 if ordered.desc {
39092 self.write_space();
39093 self.write_keyword("DESC");
39094 } else if ordered.explicit_asc {
39095 self.write_space();
39096 self.write_keyword("ASC");
39097 }
39098 if let Some(nulls_first) = ordered.nulls_first {
39099 self.write_space();
39100 self.write_keyword("NULLS");
39101 self.write_space();
39102 if nulls_first {
39103 self.write_keyword("FIRST");
39104 } else {
39105 self.write_keyword("LAST");
39106 }
39107 }
39108 }
39109 has_content = true;
39110 }
39111
39112 if let Some(frame) = &e.frame {
39114 if has_content {
39115 self.write_space();
39116 }
39117 self.generate_window_frame(frame)?;
39118 }
39119
39120 Ok(())
39121 }
39122
39123 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
39124 self.write_keyword("WITH");
39126 self.write_space();
39127 if e.no.is_some() {
39128 self.write_keyword("NO");
39129 self.write_space();
39130 }
39131 self.write_keyword("DATA");
39132
39133 if let Some(statistics) = &e.statistics {
39135 self.write_space();
39136 self.write_keyword("AND");
39137 self.write_space();
39138 match statistics.as_ref() {
39140 Expression::Boolean(b) if !b.value => {
39141 self.write_keyword("NO");
39142 self.write_space();
39143 }
39144 _ => {}
39145 }
39146 self.write_keyword("STATISTICS");
39147 }
39148 Ok(())
39149 }
39150
39151 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
39152 self.write_keyword("WITH FILL");
39154
39155 if let Some(from_) = &e.from_ {
39156 self.write_space();
39157 self.write_keyword("FROM");
39158 self.write_space();
39159 self.generate_expression(from_)?;
39160 }
39161
39162 if let Some(to) = &e.to {
39163 self.write_space();
39164 self.write_keyword("TO");
39165 self.write_space();
39166 self.generate_expression(to)?;
39167 }
39168
39169 if let Some(step) = &e.step {
39170 self.write_space();
39171 self.write_keyword("STEP");
39172 self.write_space();
39173 self.generate_expression(step)?;
39174 }
39175
39176 if let Some(staleness) = &e.staleness {
39177 self.write_space();
39178 self.write_keyword("STALENESS");
39179 self.write_space();
39180 self.generate_expression(staleness)?;
39181 }
39182
39183 if let Some(interpolate) = &e.interpolate {
39184 self.write_space();
39185 self.write_keyword("INTERPOLATE");
39186 self.write(" (");
39187 self.generate_interpolate_item(interpolate)?;
39189 self.write(")");
39190 }
39191
39192 Ok(())
39193 }
39194
39195 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
39197 match expr {
39198 Expression::Alias(alias) => {
39199 self.generate_identifier(&alias.alias)?;
39201 self.write_space();
39202 self.write_keyword("AS");
39203 self.write_space();
39204 self.generate_expression(&alias.this)?;
39205 }
39206 Expression::Tuple(tuple) => {
39207 for (i, item) in tuple.expressions.iter().enumerate() {
39208 if i > 0 {
39209 self.write(", ");
39210 }
39211 self.generate_interpolate_item(item)?;
39212 }
39213 }
39214 other => {
39215 self.generate_expression(other)?;
39216 }
39217 }
39218 Ok(())
39219 }
39220
39221 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
39222 self.write_keyword("WITH JOURNAL TABLE");
39224 self.write("=");
39225 self.generate_expression(&e.this)?;
39226 Ok(())
39227 }
39228
39229 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
39230 self.generate_expression(&e.this)?;
39232 self.write_space();
39233 self.write_keyword("WITH");
39234 self.write_space();
39235 self.write_keyword(&e.op);
39236 Ok(())
39237 }
39238
39239 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
39240 self.write_keyword("WITH");
39242 self.write_space();
39243 for (i, expr) in e.expressions.iter().enumerate() {
39244 if i > 0 {
39245 self.write(", ");
39246 }
39247 self.generate_expression(expr)?;
39248 }
39249 Ok(())
39250 }
39251
39252 fn generate_with_schema_binding_property(
39253 &mut self,
39254 e: &WithSchemaBindingProperty,
39255 ) -> Result<()> {
39256 self.write_keyword("WITH");
39258 self.write_space();
39259 self.generate_expression(&e.this)?;
39260 Ok(())
39261 }
39262
39263 fn generate_with_system_versioning_property(
39264 &mut self,
39265 e: &WithSystemVersioningProperty,
39266 ) -> Result<()> {
39267 let mut parts = Vec::new();
39273
39274 if let Some(this) = &e.this {
39275 let mut s = String::from("HISTORY_TABLE=");
39277 let mut gen = Generator::new();
39278 gen.generate_expression(this)?;
39279 s.push_str(&gen.output);
39280 parts.push(s);
39281 }
39282
39283 if let Some(data_consistency) = &e.data_consistency {
39284 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
39285 let mut gen = Generator::new();
39286 gen.generate_expression(data_consistency)?;
39287 s.push_str(&gen.output);
39288 parts.push(s);
39289 }
39290
39291 if let Some(retention_period) = &e.retention_period {
39292 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
39293 let mut gen = Generator::new();
39294 gen.generate_expression(retention_period)?;
39295 s.push_str(&gen.output);
39296 parts.push(s);
39297 }
39298
39299 self.write_keyword("SYSTEM_VERSIONING");
39300 self.write("=");
39301
39302 if !parts.is_empty() {
39303 self.write_keyword("ON");
39304 self.write("(");
39305 self.write(&parts.join(", "));
39306 self.write(")");
39307 } else if e.on.is_some() {
39308 self.write_keyword("ON");
39309 } else {
39310 self.write_keyword("OFF");
39311 }
39312
39313 if e.with_.is_some() {
39315 let inner = self.output.clone();
39316 self.output.clear();
39317 self.write("WITH(");
39318 self.write(&inner);
39319 self.write(")");
39320 }
39321
39322 Ok(())
39323 }
39324
39325 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
39326 self.write_keyword("WITH");
39328 self.write(" (");
39329 for (i, expr) in e.expressions.iter().enumerate() {
39330 if i > 0 {
39331 self.write(", ");
39332 }
39333 self.generate_expression(expr)?;
39334 }
39335 self.write(")");
39336 Ok(())
39337 }
39338
39339 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
39340 self.write_keyword("XMLELEMENT");
39343 self.write("(");
39344
39345 if e.evalname.is_some() {
39346 self.write_keyword("EVALNAME");
39347 } else {
39348 self.write_keyword("NAME");
39349 }
39350 self.write_space();
39351 self.generate_expression(&e.this)?;
39352
39353 for expr in &e.expressions {
39354 self.write(", ");
39355 self.generate_expression(expr)?;
39356 }
39357 self.write(")");
39358 Ok(())
39359 }
39360
39361 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
39362 self.write_keyword("XMLGET");
39364 self.write("(");
39365 self.generate_expression(&e.this)?;
39366 self.write(", ");
39367 self.generate_expression(&e.expression)?;
39368 if let Some(instance) = &e.instance {
39369 self.write(", ");
39370 self.generate_expression(instance)?;
39371 }
39372 self.write(")");
39373 Ok(())
39374 }
39375
39376 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
39377 self.generate_expression(&e.this)?;
39379 if let Some(expression) = &e.expression {
39380 self.write("(");
39381 self.generate_expression(expression)?;
39382 self.write(")");
39383 }
39384 Ok(())
39385 }
39386
39387 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
39388 self.write_keyword("XMLTABLE");
39390 self.write("(");
39391
39392 if self.config.pretty {
39393 self.indent_level += 1;
39394 self.write_newline();
39395 self.write_indent();
39396 self.generate_expression(&e.this)?;
39397
39398 if let Some(passing) = &e.passing {
39399 self.write_newline();
39400 self.write_indent();
39401 self.write_keyword("PASSING");
39402 if let Expression::Tuple(tuple) = passing.as_ref() {
39403 for expr in &tuple.expressions {
39404 self.write_newline();
39405 self.indent_level += 1;
39406 self.write_indent();
39407 self.generate_expression(expr)?;
39408 self.indent_level -= 1;
39409 }
39410 } else {
39411 self.write_newline();
39412 self.indent_level += 1;
39413 self.write_indent();
39414 self.generate_expression(passing)?;
39415 self.indent_level -= 1;
39416 }
39417 }
39418
39419 if e.by_ref.is_some() {
39420 self.write_newline();
39421 self.write_indent();
39422 self.write_keyword("RETURNING SEQUENCE BY REF");
39423 }
39424
39425 if !e.columns.is_empty() {
39426 self.write_newline();
39427 self.write_indent();
39428 self.write_keyword("COLUMNS");
39429 for (i, col) in e.columns.iter().enumerate() {
39430 self.write_newline();
39431 self.indent_level += 1;
39432 self.write_indent();
39433 self.generate_expression(col)?;
39434 self.indent_level -= 1;
39435 if i < e.columns.len() - 1 {
39436 self.write(",");
39437 }
39438 }
39439 }
39440
39441 self.indent_level -= 1;
39442 self.write_newline();
39443 self.write_indent();
39444 self.write(")");
39445 return Ok(());
39446 }
39447
39448 if let Some(namespaces) = &e.namespaces {
39450 self.write_keyword("XMLNAMESPACES");
39451 self.write("(");
39452 if let Expression::Tuple(tuple) = namespaces.as_ref() {
39454 for (i, expr) in tuple.expressions.iter().enumerate() {
39455 if i > 0 {
39456 self.write(", ");
39457 }
39458 if !matches!(expr, Expression::Alias(_)) {
39461 self.write_keyword("DEFAULT");
39462 self.write_space();
39463 }
39464 self.generate_expression(expr)?;
39465 }
39466 } else {
39467 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
39469 self.write_keyword("DEFAULT");
39470 self.write_space();
39471 }
39472 self.generate_expression(namespaces)?;
39473 }
39474 self.write("), ");
39475 }
39476
39477 self.generate_expression(&e.this)?;
39479
39480 if let Some(passing) = &e.passing {
39482 self.write_space();
39483 self.write_keyword("PASSING");
39484 self.write_space();
39485 if let Expression::Tuple(tuple) = passing.as_ref() {
39487 for (i, expr) in tuple.expressions.iter().enumerate() {
39488 if i > 0 {
39489 self.write(", ");
39490 }
39491 self.generate_expression(expr)?;
39492 }
39493 } else {
39494 self.generate_expression(passing)?;
39495 }
39496 }
39497
39498 if e.by_ref.is_some() {
39500 self.write_space();
39501 self.write_keyword("RETURNING SEQUENCE BY REF");
39502 }
39503
39504 if !e.columns.is_empty() {
39506 self.write_space();
39507 self.write_keyword("COLUMNS");
39508 self.write_space();
39509 for (i, col) in e.columns.iter().enumerate() {
39510 if i > 0 {
39511 self.write(", ");
39512 }
39513 self.generate_expression(col)?;
39514 }
39515 }
39516
39517 self.write(")");
39518 Ok(())
39519 }
39520
39521 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
39522 if let Some(this) = &e.this {
39525 self.generate_expression(this)?;
39526 if let Some(expression) = &e.expression {
39527 self.write_space();
39528 self.write_keyword("XOR");
39529 self.write_space();
39530 self.generate_expression(expression)?;
39531 }
39532 }
39533
39534 for (i, expr) in e.expressions.iter().enumerate() {
39536 if i > 0 || e.this.is_some() {
39537 self.write_space();
39538 self.write_keyword("XOR");
39539 self.write_space();
39540 }
39541 self.generate_expression(expr)?;
39542 }
39543 Ok(())
39544 }
39545
39546 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
39547 self.write_keyword("ZIPF");
39549 self.write("(");
39550 self.generate_expression(&e.this)?;
39551 if let Some(elementcount) = &e.elementcount {
39552 self.write(", ");
39553 self.generate_expression(elementcount)?;
39554 }
39555 if let Some(gen) = &e.gen {
39556 self.write(", ");
39557 self.generate_expression(gen)?;
39558 }
39559 self.write(")");
39560 Ok(())
39561 }
39562}
39563
39564impl Default for Generator {
39565 fn default() -> Self {
39566 Self::new()
39567 }
39568}
39569
39570#[cfg(test)]
39571mod tests {
39572 use super::*;
39573 use crate::parser::Parser;
39574
39575 fn roundtrip(sql: &str) -> String {
39576 let ast = Parser::parse_sql(sql).unwrap();
39577 Generator::sql(&ast[0]).unwrap()
39578 }
39579
39580 #[test]
39581 fn test_simple_select() {
39582 let result = roundtrip("SELECT 1");
39583 assert_eq!(result, "SELECT 1");
39584 }
39585
39586 #[test]
39587 fn test_select_from() {
39588 let result = roundtrip("SELECT a, b FROM t");
39589 assert_eq!(result, "SELECT a, b FROM t");
39590 }
39591
39592 #[test]
39593 fn test_select_where() {
39594 let result = roundtrip("SELECT * FROM t WHERE x = 1");
39595 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
39596 }
39597
39598 #[test]
39599 fn test_select_join() {
39600 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
39601 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
39602 }
39603
39604 #[test]
39605 fn test_insert() {
39606 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
39607 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
39608 }
39609
39610 #[test]
39611 fn test_pretty_print() {
39612 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
39613 let result = Generator::pretty_sql(&ast[0]).unwrap();
39614 assert!(result.contains('\n'));
39615 }
39616
39617 #[test]
39618 fn test_window_function() {
39619 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
39620 assert_eq!(
39621 result,
39622 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
39623 );
39624 }
39625
39626 #[test]
39627 fn test_window_function_with_frame() {
39628 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
39629 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
39630 }
39631
39632 #[test]
39633 fn test_aggregate_with_filter() {
39634 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
39635 assert_eq!(
39636 result,
39637 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
39638 );
39639 }
39640
39641 #[test]
39642 fn test_subscript() {
39643 let result = roundtrip("SELECT arr[0]");
39644 assert_eq!(result, "SELECT arr[0]");
39645 }
39646
39647 #[test]
39649 fn test_create_table() {
39650 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
39651 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
39652 }
39653
39654 #[test]
39655 fn test_create_table_with_constraints() {
39656 let result = roundtrip(
39657 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
39658 );
39659 assert_eq!(
39660 result,
39661 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
39662 );
39663 }
39664
39665 #[test]
39666 fn test_create_table_if_not_exists() {
39667 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
39668 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
39669 }
39670
39671 #[test]
39672 fn test_drop_table() {
39673 let result = roundtrip("DROP TABLE users");
39674 assert_eq!(result, "DROP TABLE users");
39675 }
39676
39677 #[test]
39678 fn test_drop_table_if_exists_cascade() {
39679 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
39680 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
39681 }
39682
39683 #[test]
39684 fn test_alter_table_add_column() {
39685 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
39686 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
39687 }
39688
39689 #[test]
39690 fn test_alter_table_drop_column() {
39691 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
39692 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
39693 }
39694
39695 #[test]
39696 fn test_create_index() {
39697 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
39698 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
39699 }
39700
39701 #[test]
39702 fn test_create_unique_index() {
39703 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
39704 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
39705 }
39706
39707 #[test]
39708 fn test_drop_index() {
39709 let result = roundtrip("DROP INDEX idx_name");
39710 assert_eq!(result, "DROP INDEX idx_name");
39711
39712 let result = roundtrip(r#"DROP INDEX IF EXISTS "idx_tokenKey__pb_users_auth_""#);
39713 assert_eq!(
39714 result,
39715 r#"DROP INDEX IF EXISTS "idx_tokenKey__pb_users_auth_""#
39716 );
39717
39718 let result = roundtrip(r#"DROP INDEX "public"."IdxMixed""#);
39719 assert_eq!(result, r#"DROP INDEX "public"."IdxMixed""#);
39720 }
39721
39722 #[test]
39723 fn test_create_view() {
39724 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
39725 assert_eq!(
39726 result,
39727 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
39728 );
39729 }
39730
39731 #[test]
39732 fn test_drop_view() {
39733 let result = roundtrip("DROP VIEW active_users");
39734 assert_eq!(result, "DROP VIEW active_users");
39735 }
39736
39737 #[test]
39738 fn test_truncate() {
39739 let result = roundtrip("TRUNCATE TABLE users");
39740 assert_eq!(result, "TRUNCATE TABLE users");
39741 }
39742
39743 #[test]
39744 fn test_string_literal_escaping_default() {
39745 let result = roundtrip("SELECT 'hello'");
39747 assert_eq!(result, "SELECT 'hello'");
39748
39749 let result = roundtrip("SELECT 'it''s a test'");
39751 assert_eq!(result, "SELECT 'it''s a test'");
39752 }
39753
39754 #[test]
39755 fn test_not_in_style_prefix_default_generic() {
39756 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
39757 assert_eq!(
39758 result,
39759 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
39760 );
39761 }
39762
39763 #[test]
39764 fn test_not_in_style_infix_generic_override() {
39765 let ast =
39766 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
39767 .unwrap();
39768 let config = GeneratorConfig {
39769 not_in_style: NotInStyle::Infix,
39770 ..Default::default()
39771 };
39772 let mut gen = Generator::with_config(config);
39773 let result = gen.generate(&ast[0]).unwrap();
39774 assert_eq!(
39775 result,
39776 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
39777 );
39778 }
39779
39780 #[test]
39781 fn test_string_literal_escaping_mysql() {
39782 use crate::dialects::DialectType;
39783
39784 let config = GeneratorConfig {
39785 dialect: Some(DialectType::MySQL),
39786 ..Default::default()
39787 };
39788
39789 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
39790 let mut gen = Generator::with_config(config.clone());
39791 let result = gen.generate(&ast[0]).unwrap();
39792 assert_eq!(result, "SELECT 'hello'");
39793
39794 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
39796 let mut gen = Generator::with_config(config.clone());
39797 let result = gen.generate(&ast[0]).unwrap();
39798 assert_eq!(result, "SELECT 'it''s'");
39799 }
39800
39801 #[test]
39802 fn test_string_literal_escaping_postgres() {
39803 use crate::dialects::DialectType;
39804
39805 let config = GeneratorConfig {
39806 dialect: Some(DialectType::PostgreSQL),
39807 ..Default::default()
39808 };
39809
39810 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
39811 let mut gen = Generator::with_config(config.clone());
39812 let result = gen.generate(&ast[0]).unwrap();
39813 assert_eq!(result, "SELECT 'hello'");
39814
39815 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
39817 let mut gen = Generator::with_config(config.clone());
39818 let result = gen.generate(&ast[0]).unwrap();
39819 assert_eq!(result, "SELECT 'it''s'");
39820 }
39821
39822 #[test]
39823 fn test_string_literal_escaping_bigquery() {
39824 use crate::dialects::DialectType;
39825
39826 let config = GeneratorConfig {
39827 dialect: Some(DialectType::BigQuery),
39828 ..Default::default()
39829 };
39830
39831 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
39832 let mut gen = Generator::with_config(config.clone());
39833 let result = gen.generate(&ast[0]).unwrap();
39834 assert_eq!(result, "SELECT 'hello'");
39835
39836 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
39838 let mut gen = Generator::with_config(config.clone());
39839 let result = gen.generate(&ast[0]).unwrap();
39840 assert_eq!(result, "SELECT 'it\\'s'");
39841 }
39842
39843 #[test]
39844 fn test_generate_deep_and_chain_without_stack_growth() {
39845 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
39846 Expression::column("c0"),
39847 Expression::number(0),
39848 )));
39849
39850 for i in 1..2500 {
39851 let predicate = Expression::Eq(Box::new(BinaryOp::new(
39852 Expression::column(format!("c{i}")),
39853 Expression::number(i as i64),
39854 )));
39855 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
39856 }
39857
39858 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
39859 assert!(sql.contains("c2499 = 2499"), "{}", sql);
39860 }
39861
39862 #[test]
39863 fn test_generate_deep_or_chain_without_stack_growth() {
39864 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
39865 Expression::column("c0"),
39866 Expression::number(0),
39867 )));
39868
39869 for i in 1..2500 {
39870 let predicate = Expression::Eq(Box::new(BinaryOp::new(
39871 Expression::column(format!("c{i}")),
39872 Expression::number(i as i64),
39873 )));
39874 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
39875 }
39876
39877 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
39878 assert!(sql.contains("c2499 = 2499"), "{}", sql);
39879 }
39880}