1use std::borrow::Cow;
14use std::sync::Arc;
15
16use crate::error::Result;
17use crate::expressions::*;
18use crate::DialectType;
19
20pub struct Generator {
45 config: Arc<GeneratorConfig>,
46 output: String,
47 unsupported_messages: Vec<String>,
48 indent_level: usize,
49 athena_hive_context: bool,
52 sqlite_inline_pk_columns: std::collections::HashSet<String>,
54 merge_strip_qualifiers: Vec<String>,
56 clickhouse_nullable_depth: i32,
61}
62
63#[derive(Debug, Clone, Copy, PartialEq, Default)]
69pub enum NormalizeFunctions {
70 #[default]
72 Upper,
73 Lower,
75 None,
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Default)]
81pub enum LimitFetchStyle {
82 #[default]
84 Limit,
85 Top,
87 FetchFirst,
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
93pub enum NotInStyle {
94 #[default]
96 Prefix,
97 Infix,
99}
100
101#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
103pub enum UnsupportedLevel {
104 Ignore,
106 #[default]
108 Warn,
109 Raise,
111 Immediate,
113}
114
115#[derive(Debug, Clone, Copy, PartialEq, Eq)]
116enum ConnectorOperator {
117 And,
118 Or,
119}
120
121impl ConnectorOperator {
122 fn keyword(self) -> &'static str {
123 match self {
124 Self::And => "AND",
125 Self::Or => "OR",
126 }
127 }
128}
129
130#[derive(Debug, Clone, Copy, PartialEq)]
132pub struct IdentifierQuoteStyle {
133 pub start: char,
135 pub end: char,
137}
138
139impl Default for IdentifierQuoteStyle {
140 fn default() -> Self {
141 Self {
142 start: '"',
143 end: '"',
144 }
145 }
146}
147
148impl IdentifierQuoteStyle {
149 pub const DOUBLE_QUOTE: Self = Self {
151 start: '"',
152 end: '"',
153 };
154 pub const BACKTICK: Self = Self {
156 start: '`',
157 end: '`',
158 };
159 pub const BRACKET: Self = Self {
161 start: '[',
162 end: ']',
163 };
164}
165
166#[derive(Debug, Clone)]
188pub struct GeneratorConfig {
189 pub pretty: bool,
192 pub indent: &'static str,
194 pub max_text_width: usize,
196 pub identifier_quote: char,
198 pub identifier_quote_style: IdentifierQuoteStyle,
200 pub uppercase_keywords: bool,
202 pub normalize_identifiers: bool,
204 pub dialect: Option<crate::dialects::DialectType>,
206 pub source_dialect: Option<crate::dialects::DialectType>,
208 pub unsupported_level: UnsupportedLevel,
210 pub max_unsupported: usize,
212 pub normalize_functions: NormalizeFunctions,
214 pub string_escape: char,
216 pub case_sensitive_identifiers: bool,
218 pub identifiers_can_start_with_digit: bool,
220 pub always_quote_identifiers: bool,
223 pub not_in_style: NotInStyle,
225
226 pub null_ordering_supported: bool,
230 pub ignore_nulls_in_func: bool,
233 pub nvl2_supported: bool,
235
236 pub limit_fetch_style: LimitFetchStyle,
239 pub limit_is_top: bool,
241 pub limit_only_literals: bool,
243
244 pub single_string_interval: bool,
247 pub interval_allows_plural_form: bool,
249
250 pub cte_recursive_keyword_required: bool,
253
254 pub values_as_table: bool,
257 pub wrap_derived_values: bool,
259
260 pub tablesample_seed_keyword: &'static str,
263 pub tablesample_requires_parens: bool,
265 pub tablesample_size_is_rows: bool,
267 pub tablesample_keywords: &'static str,
269 pub tablesample_with_method: bool,
271 pub alias_post_tablesample: bool,
273
274 pub aggregate_filter_supported: bool,
277 pub multi_arg_distinct: bool,
279 pub quantified_no_paren_space: bool,
281 pub supports_median: bool,
283
284 pub supports_select_into: bool,
287 pub locking_reads_supported: bool,
289
290 pub rename_table_with_db: bool,
293 pub semi_anti_join_with_side: bool,
295 pub supports_table_alias_columns: bool,
297 pub join_hints: bool,
299 pub table_hints: bool,
301 pub query_hints: bool,
303 pub query_hint_sep: &'static str,
305 pub supports_column_join_marks: bool,
307
308 pub index_using_no_space: bool,
312 pub supports_unlogged_tables: bool,
314 pub supports_create_table_like: bool,
316 pub like_property_inside_schema: bool,
318 pub alter_table_include_column_keyword: bool,
320 pub supports_table_copy: bool,
322 pub alter_set_type: &'static str,
324 pub alter_set_wrapped: bool,
326
327 pub tz_to_with_time_zone: bool,
330 pub supports_convert_timezone: bool,
332
333 pub json_type_required_for_extraction: bool,
336 pub json_path_bracketed_key_supported: bool,
338 pub json_path_single_quote_escape: bool,
340 pub quote_json_path: bool,
342 pub json_key_value_pair_sep: &'static str,
344
345 pub copy_params_are_wrapped: bool,
348 pub copy_params_eq_required: bool,
350 pub copy_has_into_keyword: bool,
352
353 pub supports_window_exclude: bool,
356 pub unnest_with_ordinality: bool,
358 pub lowercase_window_frame_keywords: bool,
361 pub normalize_window_frame_between: bool,
364
365 pub array_concat_is_var_len: bool,
368 pub array_size_dim_required: Option<bool>,
371 pub can_implement_array_any: bool,
373 pub array_size_name: &'static str,
375
376 pub supports_between_flags: bool,
379
380 pub is_bool_allowed: bool,
383 pub ensure_bools: bool,
385
386 pub extract_allows_quotes: bool,
389 pub normalize_extract_date_parts: bool,
391
392 pub try_supported: bool,
395 pub supports_uescape: bool,
397 pub supports_to_number: bool,
399 pub supports_single_arg_concat: bool,
401 pub last_day_supports_date_part: bool,
403 pub supports_exploding_projections: bool,
405 pub supports_unix_seconds: bool,
407 pub supports_like_quantifiers: bool,
409 pub supports_decode_case: bool,
411 pub set_op_modifiers: bool,
413 pub update_statement_supports_from: bool,
415
416 pub collate_is_func: bool,
419
420 pub duplicate_key_update_with_set: bool,
423 pub insert_overwrite: &'static str,
425
426 pub returning_end: bool,
429
430 pub matched_by_source: bool,
433
434 pub create_function_return_as: bool,
437 pub parameter_default_equals: bool,
439
440 pub computed_column_with_type: bool,
443
444 pub unpivot_aliases_are_identifiers: bool,
447
448 pub star_except: &'static str,
451
452 pub hex_func: &'static str,
455
456 pub with_properties_prefix: &'static str,
459
460 pub pad_fill_pattern_is_required: bool,
463
464 pub index_on: &'static str,
467
468 pub groupings_sep: &'static str,
471
472 pub struct_delimiter: (&'static str, &'static str),
475 pub struct_curly_brace_notation: bool,
477 pub array_bracket_only: bool,
479 pub struct_field_sep: &'static str,
481
482 pub except_intersect_support_all_clause: bool,
485
486 pub parameter_token: &'static str,
489 pub named_placeholder_token: &'static str,
491
492 pub data_type_specifiers_allowed: bool,
495
496 pub schema_comment_with_eq: bool,
500}
501
502impl Default for GeneratorConfig {
503 fn default() -> Self {
504 Self {
505 pretty: false,
507 indent: " ",
508 max_text_width: 80,
509 identifier_quote: '"',
510 identifier_quote_style: IdentifierQuoteStyle::DOUBLE_QUOTE,
511 uppercase_keywords: true,
512 normalize_identifiers: false,
513 dialect: None,
514 source_dialect: None,
515 unsupported_level: UnsupportedLevel::Warn,
516 max_unsupported: 3,
517 normalize_functions: NormalizeFunctions::Upper,
518 string_escape: '\'',
519 case_sensitive_identifiers: false,
520 identifiers_can_start_with_digit: false,
521 always_quote_identifiers: false,
522 not_in_style: NotInStyle::Prefix,
523
524 null_ordering_supported: true,
526 ignore_nulls_in_func: false,
527 nvl2_supported: true,
528
529 limit_fetch_style: LimitFetchStyle::Limit,
531 limit_is_top: false,
532 limit_only_literals: false,
533
534 single_string_interval: false,
536 interval_allows_plural_form: true,
537
538 cte_recursive_keyword_required: true,
540
541 values_as_table: true,
543 wrap_derived_values: true,
544
545 tablesample_seed_keyword: "SEED",
547 tablesample_requires_parens: true,
548 tablesample_size_is_rows: true,
549 tablesample_keywords: "TABLESAMPLE",
550 tablesample_with_method: true,
551 alias_post_tablesample: false,
552
553 aggregate_filter_supported: true,
555 multi_arg_distinct: true,
556 quantified_no_paren_space: false,
557 supports_median: true,
558
559 supports_select_into: false,
561 locking_reads_supported: true,
562
563 rename_table_with_db: true,
565 semi_anti_join_with_side: true,
566 supports_table_alias_columns: true,
567 join_hints: true,
568 table_hints: true,
569 query_hints: true,
570 query_hint_sep: ", ",
571 supports_column_join_marks: false,
572
573 index_using_no_space: false,
575 supports_unlogged_tables: false,
576 supports_create_table_like: true,
577 like_property_inside_schema: false,
578 alter_table_include_column_keyword: true,
579 supports_table_copy: true,
580 alter_set_type: "SET DATA TYPE",
581 alter_set_wrapped: false,
582
583 tz_to_with_time_zone: false,
585 supports_convert_timezone: false,
586
587 json_type_required_for_extraction: false,
589 json_path_bracketed_key_supported: true,
590 json_path_single_quote_escape: false,
591 quote_json_path: true,
592 json_key_value_pair_sep: ":",
593
594 copy_params_are_wrapped: true,
596 copy_params_eq_required: false,
597 copy_has_into_keyword: true,
598
599 supports_window_exclude: false,
601 unnest_with_ordinality: true,
602 lowercase_window_frame_keywords: false,
603 normalize_window_frame_between: false,
604
605 array_concat_is_var_len: true,
607 array_size_dim_required: None,
608 can_implement_array_any: false,
609 array_size_name: "ARRAY_LENGTH",
610
611 supports_between_flags: false,
613
614 is_bool_allowed: true,
616 ensure_bools: false,
617
618 extract_allows_quotes: true,
620 normalize_extract_date_parts: false,
621
622 try_supported: true,
624 supports_uescape: true,
625 supports_to_number: true,
626 supports_single_arg_concat: true,
627 last_day_supports_date_part: true,
628 supports_exploding_projections: true,
629 supports_unix_seconds: false,
630 supports_like_quantifiers: true,
631 supports_decode_case: true,
632 set_op_modifiers: true,
633 update_statement_supports_from: true,
634
635 collate_is_func: false,
637
638 duplicate_key_update_with_set: true,
640 insert_overwrite: " OVERWRITE TABLE",
641
642 returning_end: true,
644
645 matched_by_source: true,
647
648 create_function_return_as: true,
650 parameter_default_equals: false,
651
652 computed_column_with_type: true,
654
655 unpivot_aliases_are_identifiers: true,
657
658 star_except: "EXCEPT",
660
661 hex_func: "HEX",
663
664 with_properties_prefix: "WITH",
666
667 pad_fill_pattern_is_required: false,
669
670 index_on: "ON",
672
673 groupings_sep: ",",
675
676 struct_delimiter: ("<", ">"),
678 struct_curly_brace_notation: false,
679 array_bracket_only: false,
680 struct_field_sep: " ",
681
682 except_intersect_support_all_clause: true,
684
685 parameter_token: "@",
687 named_placeholder_token: ":",
688
689 data_type_specifiers_allowed: false,
691
692 schema_comment_with_eq: true,
694 }
695 }
696}
697
698mod reserved_keywords {
701 use std::collections::HashSet;
702 use std::sync::LazyLock;
703
704 pub static SQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
706 [
707 "all",
708 "alter",
709 "and",
710 "any",
711 "array",
712 "as",
713 "asc",
714 "at",
715 "authorization",
716 "begin",
717 "between",
718 "both",
719 "by",
720 "case",
721 "cast",
722 "check",
723 "collate",
724 "column",
725 "commit",
726 "constraint",
727 "create",
728 "cross",
729 "cube",
730 "current",
731 "current_date",
732 "current_time",
733 "current_timestamp",
734 "current_user",
735 "default",
736 "delete",
737 "desc",
738 "distinct",
739 "drop",
740 "else",
741 "end",
742 "escape",
743 "except",
744 "execute",
745 "exists",
746 "external",
747 "false",
748 "fetch",
749 "filter",
750 "for",
751 "foreign",
752 "from",
753 "full",
754 "function",
755 "grant",
756 "group",
757 "grouping",
758 "having",
759 "if",
760 "in",
761 "index",
762 "inner",
763 "insert",
764 "intersect",
765 "interval",
766 "into",
767 "is",
768 "join",
769 "key",
770 "leading",
771 "left",
772 "like",
773 "limit",
774 "local",
775 "localtime",
776 "localtimestamp",
777 "match",
778 "merge",
779 "natural",
780 "no",
781 "not",
782 "null",
783 "of",
784 "offset",
785 "on",
786 "only",
787 "or",
788 "order",
789 "outer",
790 "over",
791 "partition",
792 "primary",
793 "procedure",
794 "range",
795 "references",
796 "right",
797 "rollback",
798 "rollup",
799 "row",
800 "rows",
801 "select",
802 "session_user",
803 "set",
804 "some",
805 "table",
806 "tablesample",
807 "then",
808 "to",
809 "trailing",
810 "true",
811 "truncate",
812 "union",
813 "unique",
814 "unknown",
815 "update",
816 "user",
817 "using",
818 "values",
819 "view",
820 "when",
821 "where",
822 "window",
823 "with",
824 ]
825 .into_iter()
826 .collect()
827 });
828
829 pub static BIGQUERY_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
832 let mut set = SQL_RESERVED.clone();
833 set.extend([
834 "assert_rows_modified",
835 "at",
836 "contains",
837 "cube",
838 "current",
839 "define",
840 "enum",
841 "escape",
842 "exclude",
843 "following",
844 "for",
845 "groups",
846 "hash",
847 "ignore",
848 "lateral",
849 "lookup",
850 "new",
851 "no",
852 "nulls",
853 "of",
854 "over",
855 "preceding",
856 "proto",
857 "qualify",
858 "recursive",
859 "respect",
860 "struct",
861 "tablesample",
862 "treat",
863 "unbounded",
864 "unnest",
865 "window",
866 "within",
867 ]);
868 set.remove("grant");
870 set.remove("key");
871 set.remove("index");
872 set.remove("values");
873 set.remove("table");
874 set
875 });
876
877 pub static MYSQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
879 let mut set = SQL_RESERVED.clone();
880 set.extend([
881 "accessible",
882 "add",
883 "analyze",
884 "asensitive",
885 "before",
886 "bigint",
887 "binary",
888 "blob",
889 "call",
890 "cascade",
891 "change",
892 "char",
893 "character",
894 "condition",
895 "continue",
896 "convert",
897 "current_date",
898 "current_time",
899 "current_timestamp",
900 "current_user",
901 "cursor",
902 "database",
903 "databases",
904 "day_hour",
905 "day_microsecond",
906 "day_minute",
907 "day_second",
908 "dec",
909 "decimal",
910 "declare",
911 "delayed",
912 "describe",
913 "deterministic",
914 "distinctrow",
915 "div",
916 "double",
917 "dual",
918 "each",
919 "elseif",
920 "enclosed",
921 "escaped",
922 "exit",
923 "explain",
924 "float",
925 "float4",
926 "float8",
927 "force",
928 "get",
929 "high_priority",
930 "hour_microsecond",
931 "hour_minute",
932 "hour_second",
933 "ignore",
934 "infile",
935 "inout",
936 "insensitive",
937 "int",
938 "int1",
939 "int2",
940 "int3",
941 "int4",
942 "int8",
943 "integer",
944 "iterate",
945 "keys",
946 "kill",
947 "leave",
948 "linear",
949 "lines",
950 "load",
951 "lock",
952 "long",
953 "longblob",
954 "longtext",
955 "loop",
956 "low_priority",
957 "master_ssl_verify_server_cert",
958 "maxvalue",
959 "mediumblob",
960 "mediumint",
961 "mediumtext",
962 "middleint",
963 "minute_microsecond",
964 "minute_second",
965 "mod",
966 "modifies",
967 "no_write_to_binlog",
968 "numeric",
969 "optimize",
970 "option",
971 "optionally",
972 "out",
973 "outfile",
974 "precision",
975 "purge",
976 "read",
977 "reads",
978 "real",
979 "regexp",
980 "release",
981 "rename",
982 "repeat",
983 "replace",
984 "require",
985 "resignal",
986 "restrict",
987 "return",
988 "revoke",
989 "rlike",
990 "schema",
991 "schemas",
992 "second_microsecond",
993 "sensitive",
994 "separator",
995 "show",
996 "signal",
997 "smallint",
998 "spatial",
999 "specific",
1000 "sql",
1001 "sql_big_result",
1002 "sql_calc_found_rows",
1003 "sql_small_result",
1004 "sqlexception",
1005 "sqlstate",
1006 "sqlwarning",
1007 "ssl",
1008 "starting",
1009 "straight_join",
1010 "terminated",
1011 "text",
1012 "tinyblob",
1013 "tinyint",
1014 "tinytext",
1015 "trigger",
1016 "undo",
1017 "unlock",
1018 "unsigned",
1019 "usage",
1020 "utc_date",
1021 "utc_time",
1022 "utc_timestamp",
1023 "varbinary",
1024 "varchar",
1025 "varcharacter",
1026 "varying",
1027 "while",
1028 "write",
1029 "xor",
1030 "year_month",
1031 "zerofill",
1032 ]);
1033 set.remove("table");
1034 set
1035 });
1036
1037 pub static DORIS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1040 let mut set = MYSQL_RESERVED.clone();
1041 set.extend([
1042 "aggregate",
1043 "anti",
1044 "array",
1045 "backend",
1046 "backup",
1047 "begin",
1048 "bitmap",
1049 "boolean",
1050 "broker",
1051 "buckets",
1052 "cached",
1053 "cancel",
1054 "cast",
1055 "catalog",
1056 "charset",
1057 "cluster",
1058 "collation",
1059 "columns",
1060 "comment",
1061 "commit",
1062 "config",
1063 "connection",
1064 "count",
1065 "current",
1066 "data",
1067 "date",
1068 "datetime",
1069 "day",
1070 "deferred",
1071 "distributed",
1072 "dynamic",
1073 "enable",
1074 "end",
1075 "events",
1076 "export",
1077 "external",
1078 "fields",
1079 "first",
1080 "follower",
1081 "format",
1082 "free",
1083 "frontend",
1084 "full",
1085 "functions",
1086 "global",
1087 "grants",
1088 "hash",
1089 "help",
1090 "hour",
1091 "install",
1092 "intermediate",
1093 "json",
1094 "label",
1095 "last",
1096 "less",
1097 "level",
1098 "link",
1099 "local",
1100 "location",
1101 "max",
1102 "merge",
1103 "min",
1104 "minute",
1105 "modify",
1106 "month",
1107 "name",
1108 "names",
1109 "negative",
1110 "nulls",
1111 "observer",
1112 "offset",
1113 "only",
1114 "open",
1115 "overwrite",
1116 "password",
1117 "path",
1118 "plan",
1119 "plugin",
1120 "plugins",
1121 "policy",
1122 "process",
1123 "properties",
1124 "property",
1125 "query",
1126 "quota",
1127 "recover",
1128 "refresh",
1129 "repair",
1130 "replica",
1131 "repository",
1132 "resource",
1133 "restore",
1134 "resume",
1135 "role",
1136 "roles",
1137 "rollback",
1138 "rollup",
1139 "routine",
1140 "sample",
1141 "second",
1142 "semi",
1143 "session",
1144 "signed",
1145 "snapshot",
1146 "start",
1147 "stats",
1148 "status",
1149 "stop",
1150 "stream",
1151 "string",
1152 "sum",
1153 "tables",
1154 "tablet",
1155 "temporary",
1156 "text",
1157 "timestamp",
1158 "transaction",
1159 "trash",
1160 "trim",
1161 "truncate",
1162 "type",
1163 "user",
1164 "value",
1165 "variables",
1166 "verbose",
1167 "version",
1168 "view",
1169 "warnings",
1170 "week",
1171 "work",
1172 "year",
1173 ]);
1174 set
1175 });
1176
1177 pub static POSTGRES_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1179 let mut set = SQL_RESERVED.clone();
1180 set.extend([
1181 "analyse",
1182 "analyze",
1183 "asymmetric",
1184 "binary",
1185 "collation",
1186 "concurrently",
1187 "current_catalog",
1188 "current_role",
1189 "current_schema",
1190 "deferrable",
1191 "do",
1192 "freeze",
1193 "ilike",
1194 "initially",
1195 "isnull",
1196 "lateral",
1197 "notnull",
1198 "placing",
1199 "returning",
1200 "similar",
1201 "symmetric",
1202 "variadic",
1203 "verbose",
1204 ]);
1205 set.remove("default");
1207 set.remove("interval");
1208 set.remove("match");
1209 set.remove("offset");
1210 set.remove("table");
1211 set
1212 });
1213
1214 pub static REDSHIFT_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1218 [
1219 "aes128",
1220 "aes256",
1221 "all",
1222 "allowoverwrite",
1223 "analyse",
1224 "analyze",
1225 "and",
1226 "any",
1227 "array",
1228 "as",
1229 "asc",
1230 "authorization",
1231 "az64",
1232 "backup",
1233 "between",
1234 "binary",
1235 "blanksasnull",
1236 "both",
1237 "bytedict",
1238 "bzip2",
1239 "case",
1240 "cast",
1241 "check",
1242 "collate",
1243 "column",
1244 "constraint",
1245 "create",
1246 "credentials",
1247 "cross",
1248 "current_date",
1249 "current_time",
1250 "current_timestamp",
1251 "current_user",
1252 "current_user_id",
1253 "default",
1254 "deferrable",
1255 "deflate",
1256 "defrag",
1257 "delta",
1258 "delta32k",
1259 "desc",
1260 "disable",
1261 "distinct",
1262 "do",
1263 "else",
1264 "emptyasnull",
1265 "enable",
1266 "encode",
1267 "encrypt",
1268 "encryption",
1269 "end",
1270 "except",
1271 "explicit",
1272 "false",
1273 "for",
1274 "foreign",
1275 "freeze",
1276 "from",
1277 "full",
1278 "globaldict256",
1279 "globaldict64k",
1280 "grant",
1281 "group",
1282 "gzip",
1283 "having",
1284 "identity",
1285 "ignore",
1286 "ilike",
1287 "in",
1288 "initially",
1289 "inner",
1290 "intersect",
1291 "interval",
1292 "into",
1293 "is",
1294 "isnull",
1295 "join",
1296 "leading",
1297 "left",
1298 "like",
1299 "limit",
1300 "localtime",
1301 "localtimestamp",
1302 "lun",
1303 "luns",
1304 "lzo",
1305 "lzop",
1306 "minus",
1307 "mostly16",
1308 "mostly32",
1309 "mostly8",
1310 "natural",
1311 "new",
1312 "not",
1313 "notnull",
1314 "null",
1315 "nulls",
1316 "off",
1317 "offline",
1318 "offset",
1319 "oid",
1320 "old",
1321 "on",
1322 "only",
1323 "open",
1324 "or",
1325 "order",
1326 "outer",
1327 "overlaps",
1328 "parallel",
1329 "partition",
1330 "percent",
1331 "permissions",
1332 "pivot",
1333 "placing",
1334 "primary",
1335 "raw",
1336 "readratio",
1337 "recover",
1338 "references",
1339 "rejectlog",
1340 "resort",
1341 "respect",
1342 "restore",
1343 "right",
1344 "select",
1345 "session_user",
1346 "similar",
1347 "snapshot",
1348 "some",
1349 "sysdate",
1350 "system",
1351 "table",
1352 "tag",
1353 "tdes",
1354 "text255",
1355 "text32k",
1356 "then",
1357 "timestamp",
1358 "to",
1359 "top",
1360 "trailing",
1361 "true",
1362 "truncatecolumns",
1363 "type",
1364 "union",
1365 "unique",
1366 "unnest",
1367 "unpivot",
1368 "user",
1369 "using",
1370 "verbose",
1371 "wallet",
1372 "when",
1373 "where",
1374 "with",
1375 "without",
1376 ]
1377 .into_iter()
1378 .collect()
1379 });
1380
1381 pub static DUCKDB_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1383 let mut set = POSTGRES_RESERVED.clone();
1384 set.extend([
1385 "anti",
1386 "asof",
1387 "columns",
1388 "describe",
1389 "groups",
1390 "macro",
1391 "pivot",
1392 "pivot_longer",
1393 "pivot_wider",
1394 "qualify",
1395 "replace",
1396 "respect",
1397 "semi",
1398 "show",
1399 "table",
1400 "unpivot",
1401 ]);
1402 set.remove("at");
1403 set.remove("key");
1404 set.remove("range");
1405 set.remove("row");
1406 set.remove("values");
1407 set
1408 });
1409
1410 pub static PRESTO_TRINO_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1412 let mut set = SQL_RESERVED.clone();
1413 set.extend([
1414 "alter",
1415 "and",
1416 "as",
1417 "between",
1418 "by",
1419 "case",
1420 "cast",
1421 "constraint",
1422 "create",
1423 "cross",
1424 "cube",
1425 "current_catalog",
1426 "current_date",
1427 "current_path",
1428 "current_role",
1429 "current_schema",
1430 "current_time",
1431 "current_timestamp",
1432 "current_user",
1433 "deallocate",
1434 "delete",
1435 "describe",
1436 "distinct",
1437 "drop",
1438 "else",
1439 "end",
1440 "escape",
1441 "except",
1442 "execute",
1443 "exists",
1444 "extract",
1445 "false",
1446 "for",
1447 "from",
1448 "full",
1449 "group",
1450 "grouping",
1451 "having",
1452 "in",
1453 "inner",
1454 "insert",
1455 "intersect",
1456 "into",
1457 "is",
1458 "join",
1459 "json_array",
1460 "json_exists",
1461 "json_object",
1462 "json_query",
1463 "json_table",
1464 "json_value",
1465 "left",
1466 "like",
1467 "listagg",
1468 "localtime",
1469 "localtimestamp",
1470 "natural",
1471 "normalize",
1472 "not",
1473 "null",
1474 "on",
1475 "or",
1476 "order",
1477 "outer",
1478 "prepare",
1479 "recursive",
1480 "right",
1481 "rollup",
1482 "select",
1483 "skip",
1484 "table",
1485 "then",
1486 "trim",
1487 "true",
1488 "uescape",
1489 "union",
1490 "unnest",
1491 "using",
1492 "values",
1493 "when",
1494 "where",
1495 "with",
1496 ]);
1497 set.remove("key");
1499 set
1500 });
1501
1502 pub static STARROCKS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1505 [
1506 "add",
1507 "all",
1508 "alter",
1509 "analyze",
1510 "and",
1511 "array",
1512 "as",
1513 "asc",
1514 "between",
1515 "bigint",
1516 "bitmap",
1517 "both",
1518 "by",
1519 "case",
1520 "char",
1521 "character",
1522 "check",
1523 "collate",
1524 "column",
1525 "compaction",
1526 "convert",
1527 "create",
1528 "cross",
1529 "cube",
1530 "current_date",
1531 "current_role",
1532 "current_time",
1533 "current_timestamp",
1534 "current_user",
1535 "database",
1536 "databases",
1537 "decimal",
1538 "decimalv2",
1539 "decimal32",
1540 "decimal64",
1541 "decimal128",
1542 "default",
1543 "deferred",
1544 "delete",
1545 "dense_rank",
1546 "desc",
1547 "describe",
1548 "distinct",
1549 "double",
1550 "drop",
1551 "dual",
1552 "else",
1553 "except",
1554 "exists",
1555 "explain",
1556 "false",
1557 "first_value",
1558 "float",
1559 "for",
1560 "force",
1561 "from",
1562 "full",
1563 "function",
1564 "grant",
1565 "group",
1566 "grouping",
1567 "grouping_id",
1568 "groups",
1569 "having",
1570 "hll",
1571 "host",
1572 "if",
1573 "ignore",
1574 "immediate",
1575 "in",
1576 "index",
1577 "infile",
1578 "inner",
1579 "insert",
1580 "int",
1581 "integer",
1582 "intersect",
1583 "into",
1584 "is",
1585 "join",
1586 "json",
1587 "key",
1588 "keys",
1589 "kill",
1590 "lag",
1591 "largeint",
1592 "last_value",
1593 "lateral",
1594 "lead",
1595 "left",
1596 "like",
1597 "limit",
1598 "load",
1599 "localtime",
1600 "localtimestamp",
1601 "maxvalue",
1602 "minus",
1603 "mod",
1604 "not",
1605 "ntile",
1606 "null",
1607 "on",
1608 "or",
1609 "order",
1610 "outer",
1611 "outfile",
1612 "over",
1613 "partition",
1614 "percentile",
1615 "primary",
1616 "procedure",
1617 "qualify",
1618 "range",
1619 "rank",
1620 "read",
1621 "regexp",
1622 "release",
1623 "rename",
1624 "replace",
1625 "revoke",
1626 "right",
1627 "rlike",
1628 "row",
1629 "row_number",
1630 "rows",
1631 "schema",
1632 "schemas",
1633 "select",
1634 "set",
1635 "set_var",
1636 "show",
1637 "smallint",
1638 "system",
1639 "table",
1640 "terminated",
1641 "text",
1642 "then",
1643 "tinyint",
1644 "to",
1645 "true",
1646 "union",
1647 "unique",
1648 "unsigned",
1649 "update",
1650 "use",
1651 "using",
1652 "values",
1653 "varchar",
1654 "when",
1655 "where",
1656 "with",
1657 ]
1658 .into_iter()
1659 .collect()
1660 });
1661
1662 pub static SINGLESTORE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1665 let mut set = MYSQL_RESERVED.clone();
1666 set.extend([
1667 "abs",
1670 "account",
1671 "acos",
1672 "adddate",
1673 "addtime",
1674 "admin",
1675 "aes_decrypt",
1676 "aes_encrypt",
1677 "aggregate",
1678 "aggregates",
1679 "aggregator",
1680 "anti_join",
1681 "any_value",
1682 "approx_count_distinct",
1683 "approx_percentile",
1684 "arrange",
1685 "arrangement",
1686 "asin",
1687 "atan",
1688 "atan2",
1689 "attach",
1690 "autostats",
1691 "avro",
1692 "background",
1693 "backup",
1694 "batch",
1695 "batches",
1696 "boot_strapping",
1697 "ceil",
1698 "ceiling",
1699 "coercibility",
1700 "columnar",
1701 "columnstore",
1702 "compile",
1703 "concurrent",
1704 "connection_id",
1705 "cos",
1706 "cot",
1707 "current_security_groups",
1708 "current_security_roles",
1709 "dayname",
1710 "dayofmonth",
1711 "dayofweek",
1712 "dayofyear",
1713 "degrees",
1714 "dot_product",
1715 "dump",
1716 "durability",
1717 "earliest",
1718 "echo",
1719 "election",
1720 "euclidean_distance",
1721 "exp",
1722 "extractor",
1723 "extractors",
1724 "floor",
1725 "foreground",
1726 "found_rows",
1727 "from_base64",
1728 "from_days",
1729 "from_unixtime",
1730 "fs",
1731 "fulltext",
1732 "gc",
1733 "gcs",
1734 "geography",
1735 "geography_area",
1736 "geography_contains",
1737 "geography_distance",
1738 "geography_intersects",
1739 "geography_latitude",
1740 "geography_length",
1741 "geography_longitude",
1742 "geographypoint",
1743 "geography_point",
1744 "geography_within_distance",
1745 "geometry",
1746 "geometry_area",
1747 "geometry_contains",
1748 "geometry_distance",
1749 "geometry_filter",
1750 "geometry_intersects",
1751 "geometry_length",
1752 "geometrypoint",
1753 "geometry_point",
1754 "geometry_within_distance",
1755 "geometry_x",
1756 "geometry_y",
1757 "greatest",
1758 "groups",
1759 "group_concat",
1760 "gzip",
1761 "hdfs",
1762 "hex",
1763 "highlight",
1764 "ifnull",
1765 "ilike",
1766 "inet_aton",
1767 "inet_ntoa",
1768 "inet6_aton",
1769 "inet6_ntoa",
1770 "initcap",
1771 "instr",
1772 "interpreter_mode",
1773 "isnull",
1774 "json",
1775 "json_agg",
1776 "json_array_contains_double",
1777 "json_array_contains_json",
1778 "json_array_contains_string",
1779 "json_delete_key",
1780 "json_extract_double",
1781 "json_extract_json",
1782 "json_extract_string",
1783 "json_extract_bigint",
1784 "json_get_type",
1785 "json_length",
1786 "json_set_double",
1787 "json_set_json",
1788 "json_set_string",
1789 "kafka",
1790 "lag",
1791 "last_day",
1792 "last_insert_id",
1793 "latest",
1794 "lcase",
1795 "lead",
1796 "leaf",
1797 "least",
1798 "leaves",
1799 "length",
1800 "license",
1801 "links",
1802 "llvm",
1803 "ln",
1804 "load",
1805 "locate",
1806 "log",
1807 "log10",
1808 "log2",
1809 "lpad",
1810 "lz4",
1811 "management",
1812 "match",
1813 "mbc",
1814 "md5",
1815 "median",
1816 "memsql",
1817 "memsql_deserialize",
1818 "memsql_serialize",
1819 "metadata",
1820 "microsecond",
1821 "minute",
1822 "model",
1823 "monthname",
1824 "months_between",
1825 "mpl",
1826 "namespace",
1827 "node",
1828 "noparam",
1829 "now",
1830 "nth_value",
1831 "ntile",
1832 "nullcols",
1833 "nullif",
1834 "object",
1835 "octet_length",
1836 "offsets",
1837 "online",
1838 "optimizer",
1839 "orphan",
1840 "parquet",
1841 "partitions",
1842 "pause",
1843 "percentile_cont",
1844 "percentile_disc",
1845 "periodic",
1846 "persisted",
1847 "pi",
1848 "pipeline",
1849 "pipelines",
1850 "plancache",
1851 "plugins",
1852 "pool",
1853 "pools",
1854 "pow",
1855 "power",
1856 "process",
1857 "processlist",
1858 "profile",
1859 "profiles",
1860 "quarter",
1861 "queries",
1862 "query",
1863 "radians",
1864 "rand",
1865 "record",
1866 "reduce",
1867 "redundancy",
1868 "regexp_match",
1869 "regexp_substr",
1870 "remote",
1871 "replication",
1872 "resource",
1873 "resource_pool",
1874 "restore",
1875 "retry",
1876 "role",
1877 "roles",
1878 "round",
1879 "rpad",
1880 "rtrim",
1881 "running",
1882 "s3",
1883 "scalar",
1884 "sec_to_time",
1885 "second",
1886 "security_lists_intersect",
1887 "semi_join",
1888 "sha",
1889 "sha1",
1890 "sha2",
1891 "shard",
1892 "sharded",
1893 "sharded_id",
1894 "sigmoid",
1895 "sign",
1896 "sin",
1897 "skip",
1898 "sleep",
1899 "snapshot",
1900 "soname",
1901 "sparse",
1902 "spatial_check_index",
1903 "split",
1904 "sqrt",
1905 "standalone",
1906 "std",
1907 "stddev",
1908 "stddev_pop",
1909 "stddev_samp",
1910 "stop",
1911 "str_to_date",
1912 "subdate",
1913 "substr",
1914 "substring_index",
1915 "success",
1916 "synchronize",
1917 "table_checksum",
1918 "tan",
1919 "task",
1920 "timediff",
1921 "time_bucket",
1922 "time_format",
1923 "time_to_sec",
1924 "timestampadd",
1925 "timestampdiff",
1926 "to_base64",
1927 "to_char",
1928 "to_date",
1929 "to_days",
1930 "to_json",
1931 "to_number",
1932 "to_seconds",
1933 "to_timestamp",
1934 "tracelogs",
1935 "transform",
1936 "trim",
1937 "trunc",
1938 "truncate",
1939 "ucase",
1940 "unhex",
1941 "unix_timestamp",
1942 "utc_date",
1943 "utc_time",
1944 "utc_timestamp",
1945 "vacuum",
1946 "variance",
1947 "var_pop",
1948 "var_samp",
1949 "vector_sub",
1950 "voting",
1951 "week",
1952 "weekday",
1953 "weekofyear",
1954 "workload",
1955 "year",
1956 ]);
1957 set.remove("all");
1959 set
1960 });
1961
1962 pub static SQLITE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1966 [
1968 "abort",
1969 "action",
1970 "add",
1971 "after",
1972 "all",
1973 "alter",
1974 "always",
1975 "analyze",
1976 "and",
1977 "as",
1978 "asc",
1979 "attach",
1980 "autoincrement",
1981 "before",
1982 "begin",
1983 "between",
1984 "by",
1985 "cascade",
1986 "case",
1987 "cast",
1988 "check",
1989 "collate",
1990 "column",
1991 "commit",
1992 "conflict",
1993 "constraint",
1994 "create",
1995 "cross",
1996 "current",
1997 "current_date",
1998 "current_time",
1999 "current_timestamp",
2000 "database",
2001 "default",
2002 "deferrable",
2003 "deferred",
2004 "delete",
2005 "desc",
2006 "detach",
2007 "distinct",
2008 "do",
2009 "drop",
2010 "each",
2011 "else",
2012 "end",
2013 "escape",
2014 "except",
2015 "exclude",
2016 "exclusive",
2017 "exists",
2018 "explain",
2019 "fail",
2020 "filter",
2021 "first",
2022 "following",
2023 "for",
2024 "foreign",
2025 "from",
2026 "full",
2027 "generated",
2028 "glob",
2029 "group",
2030 "groups",
2031 "having",
2032 "if",
2033 "ignore",
2034 "immediate",
2035 "in",
2036 "index",
2037 "indexed",
2038 "initially",
2039 "inner",
2040 "insert",
2041 "instead",
2042 "intersect",
2043 "into",
2044 "is",
2045 "isnull",
2046 "join",
2047 "key",
2048 "last",
2049 "left",
2050 "like",
2051 "limit",
2052 "natural",
2053 "no",
2054 "not",
2055 "nothing",
2056 "notnull",
2057 "null",
2058 "nulls",
2059 "of",
2060 "offset",
2061 "on",
2062 "or",
2063 "order",
2064 "others",
2065 "outer",
2066 "partition",
2067 "plan",
2068 "pragma",
2069 "preceding",
2070 "primary",
2071 "query",
2072 "raise",
2073 "range",
2074 "recursive",
2075 "references",
2076 "regexp",
2077 "reindex",
2078 "release",
2079 "rename",
2080 "replace",
2081 "restrict",
2082 "returning",
2083 "right",
2084 "rollback",
2085 "row",
2086 "rows",
2087 "savepoint",
2088 "select",
2089 "set",
2090 "table",
2091 "temp",
2092 "temporary",
2093 "then",
2094 "ties",
2095 "to",
2096 "transaction",
2097 "trigger",
2098 "unbounded",
2099 "union",
2100 "unique",
2101 "update",
2102 "using",
2103 "vacuum",
2104 "values",
2105 "view",
2106 "virtual",
2107 "when",
2108 "where",
2109 "window",
2110 "with",
2111 "without",
2112 ]
2113 .into_iter()
2114 .collect()
2115 });
2116}
2117
2118impl Generator {
2119 pub fn new() -> Self {
2125 Self::with_config(GeneratorConfig::default())
2126 }
2127
2128 pub fn with_config(config: GeneratorConfig) -> Self {
2133 Self::with_arc_config(Arc::new(config))
2134 }
2135
2136 pub(crate) fn with_arc_config(config: Arc<GeneratorConfig>) -> Self {
2141 Self {
2142 config,
2143 output: String::new(),
2144 unsupported_messages: Vec::new(),
2145 indent_level: 0,
2146 athena_hive_context: false,
2147 sqlite_inline_pk_columns: std::collections::HashSet::new(),
2148 merge_strip_qualifiers: Vec::new(),
2149 clickhouse_nullable_depth: 0,
2150 }
2151 }
2152
2153 fn add_column_aliases_to_query(expr: Expression) -> Expression {
2157 match expr {
2158 Expression::Select(mut select) => {
2159 select.expressions = select
2161 .expressions
2162 .into_iter()
2163 .map(|e| Self::add_alias_to_expression(e))
2164 .collect();
2165
2166 if let Some(ref mut from) = select.from {
2168 from.expressions = from
2169 .expressions
2170 .iter()
2171 .cloned()
2172 .map(|e| Self::add_column_aliases_to_query(e))
2173 .collect();
2174 }
2175
2176 Expression::Select(select)
2177 }
2178 Expression::Subquery(mut sq) => {
2179 sq.this = Self::add_column_aliases_to_query(sq.this);
2180 Expression::Subquery(sq)
2181 }
2182 Expression::Paren(mut p) => {
2183 p.this = Self::add_column_aliases_to_query(p.this);
2184 Expression::Paren(p)
2185 }
2186 other => other,
2188 }
2189 }
2190
2191 fn add_alias_to_expression(expr: Expression) -> Expression {
2194 use crate::expressions::Alias;
2195
2196 match &expr {
2197 Expression::Alias(_) => expr,
2199
2200 Expression::Column(col) => Expression::Alias(Box::new(Alias {
2202 this: expr.clone(),
2203 alias: col.name.clone(),
2204 column_aliases: Vec::new(),
2205 pre_alias_comments: Vec::new(),
2206 trailing_comments: Vec::new(),
2207 inferred_type: None,
2208 })),
2209
2210 Expression::Identifier(ident) => Expression::Alias(Box::new(Alias {
2212 this: expr.clone(),
2213 alias: ident.clone(),
2214 column_aliases: Vec::new(),
2215 pre_alias_comments: Vec::new(),
2216 trailing_comments: Vec::new(),
2217 inferred_type: None,
2218 })),
2219
2220 Expression::Subquery(sq) => {
2222 let processed = Self::add_column_aliases_to_query(Expression::Subquery(sq.clone()));
2223 if sq.alias.is_some() {
2225 processed
2226 } else {
2227 processed
2229 }
2230 }
2231
2232 Expression::Star(_) => expr,
2234
2235 _ => expr,
2238 }
2239 }
2240
2241 fn try_evaluate_constant(expr: &Expression) -> Option<i64> {
2245 match expr {
2246 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => { let Literal::Number(n) = lit.as_ref() else { unreachable!() }; n.parse::<i64>().ok() },
2247 Expression::Add(op) => {
2248 let left = Self::try_evaluate_constant(&op.left)?;
2249 let right = Self::try_evaluate_constant(&op.right)?;
2250 Some(left + right)
2251 }
2252 Expression::Sub(op) => {
2253 let left = Self::try_evaluate_constant(&op.left)?;
2254 let right = Self::try_evaluate_constant(&op.right)?;
2255 Some(left - right)
2256 }
2257 Expression::Mul(op) => {
2258 let left = Self::try_evaluate_constant(&op.left)?;
2259 let right = Self::try_evaluate_constant(&op.right)?;
2260 Some(left * right)
2261 }
2262 Expression::Div(op) => {
2263 let left = Self::try_evaluate_constant(&op.left)?;
2264 let right = Self::try_evaluate_constant(&op.right)?;
2265 if right != 0 {
2266 Some(left / right)
2267 } else {
2268 None
2269 }
2270 }
2271 Expression::Paren(p) => Self::try_evaluate_constant(&p.this),
2272 _ => None,
2273 }
2274 }
2275
2276 fn is_reserved_keyword(&self, name: &str) -> bool {
2278 use crate::dialects::DialectType;
2279 let mut buf = [0u8; 128];
2280 let lower_ref: &str = if name.len() <= 128 {
2281 for (i, b) in name.bytes().enumerate() {
2282 buf[i] = b.to_ascii_lowercase();
2283 }
2284 std::str::from_utf8(&buf[..name.len()]).unwrap_or(name)
2286 } else {
2287 return false;
2288 };
2289
2290 match self.config.dialect {
2291 Some(DialectType::BigQuery) => reserved_keywords::BIGQUERY_RESERVED.contains(lower_ref),
2292 Some(DialectType::MySQL) | Some(DialectType::TiDB) => {
2293 reserved_keywords::MYSQL_RESERVED.contains(lower_ref)
2294 }
2295 Some(DialectType::Doris) => reserved_keywords::DORIS_RESERVED.contains(lower_ref),
2296 Some(DialectType::SingleStore) => {
2297 reserved_keywords::SINGLESTORE_RESERVED.contains(lower_ref)
2298 }
2299 Some(DialectType::StarRocks) => {
2300 reserved_keywords::STARROCKS_RESERVED.contains(lower_ref)
2301 }
2302 Some(DialectType::PostgreSQL)
2303 | Some(DialectType::CockroachDB)
2304 | Some(DialectType::Materialize)
2305 | Some(DialectType::RisingWave) => {
2306 reserved_keywords::POSTGRES_RESERVED.contains(lower_ref)
2307 }
2308 Some(DialectType::Redshift) => reserved_keywords::REDSHIFT_RESERVED.contains(lower_ref),
2309 Some(DialectType::Snowflake) => false,
2312 Some(DialectType::ClickHouse) => false,
2314 Some(DialectType::DuckDB) => reserved_keywords::DUCKDB_RESERVED.contains(lower_ref),
2315 Some(DialectType::Teradata) => false,
2317 Some(DialectType::TSQL)
2319 | Some(DialectType::Fabric)
2320 | Some(DialectType::Oracle)
2321 | Some(DialectType::Spark)
2322 | Some(DialectType::Databricks)
2323 | Some(DialectType::Hive)
2324 | Some(DialectType::Solr) => false,
2325 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
2326 reserved_keywords::PRESTO_TRINO_RESERVED.contains(lower_ref)
2327 }
2328 Some(DialectType::SQLite) => reserved_keywords::SQLITE_RESERVED.contains(lower_ref),
2329 Some(DialectType::Generic) | None => false,
2331 _ => reserved_keywords::SQL_RESERVED.contains(lower_ref),
2333 }
2334 }
2335
2336 fn normalize_func_name<'a>(&self, name: &'a str) -> Cow<'a, str> {
2338 match self.config.normalize_functions {
2339 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
2340 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
2341 NormalizeFunctions::None => Cow::Borrowed(name),
2342 }
2343 }
2344
2345 pub fn generate(&mut self, expr: &Expression) -> Result<String> {
2354 self.output.clear();
2355 self.unsupported_messages.clear();
2356 self.generate_expression(expr)?;
2357 if self.config.unsupported_level == UnsupportedLevel::Raise
2358 && !self.unsupported_messages.is_empty()
2359 {
2360 return Err(crate::error::Error::generate(
2361 self.format_unsupported_messages(),
2362 ));
2363 }
2364 Ok(std::mem::take(&mut self.output))
2365 }
2366
2367 pub fn unsupported_messages(&self) -> &[String] {
2369 &self.unsupported_messages
2370 }
2371
2372 fn unsupported(&mut self, message: impl Into<String>) -> Result<()> {
2373 let message = message.into();
2374 if self.config.unsupported_level == UnsupportedLevel::Immediate {
2375 return Err(crate::error::Error::generate(message));
2376 }
2377 self.unsupported_messages.push(message);
2378 Ok(())
2379 }
2380
2381 fn write_unsupported_comment(&mut self, message: &str) -> Result<()> {
2382 self.unsupported(message.to_string())?;
2383 self.write("/* ");
2384 self.write(message);
2385 self.write(" */");
2386 Ok(())
2387 }
2388
2389 fn format_unsupported_messages(&self) -> String {
2390 let limit = self.config.max_unsupported.max(1);
2391 if self.unsupported_messages.len() <= limit {
2392 return self.unsupported_messages.join("; ");
2393 }
2394
2395 let mut messages = self
2396 .unsupported_messages
2397 .iter()
2398 .take(limit)
2399 .cloned()
2400 .collect::<Vec<_>>();
2401 messages.push(format!(
2402 "... and {} more",
2403 self.unsupported_messages.len() - limit
2404 ));
2405 messages.join("; ")
2406 }
2407
2408 pub fn sql(expr: &Expression) -> Result<String> {
2414 let mut gen = Generator::new();
2415 gen.generate(expr)
2416 }
2417
2418 pub fn pretty_sql(expr: &Expression) -> Result<String> {
2423 let config = GeneratorConfig {
2424 pretty: true,
2425 ..Default::default()
2426 };
2427 let mut gen = Generator::with_config(config);
2428 let mut sql = gen.generate(expr)?;
2429 if !sql.ends_with(';') {
2431 sql.push(';');
2432 }
2433 Ok(sql)
2434 }
2435
2436 fn generate_expression(&mut self, expr: &Expression) -> Result<()> {
2437 match expr {
2438 Expression::Select(select) => self.generate_select(select),
2439 Expression::Union(union) => self.generate_union(union),
2440 Expression::Intersect(intersect) => self.generate_intersect(intersect),
2441 Expression::Except(except) => self.generate_except(except),
2442 Expression::Insert(insert) => self.generate_insert(insert),
2443 Expression::Update(update) => self.generate_update(update),
2444 Expression::Delete(delete) => self.generate_delete(delete),
2445 Expression::Literal(lit) => self.generate_literal(lit),
2446 Expression::Boolean(b) => self.generate_boolean(b),
2447 Expression::Null(_) => {
2448 self.write_keyword("NULL");
2449 Ok(())
2450 }
2451 Expression::Identifier(id) => self.generate_identifier(id),
2452 Expression::Column(col) => self.generate_column(col),
2453 Expression::Pseudocolumn(pc) => self.generate_pseudocolumn(pc),
2454 Expression::Connect(c) => self.generate_connect_expr(c),
2455 Expression::Prior(p) => self.generate_prior(p),
2456 Expression::ConnectByRoot(cbr) => self.generate_connect_by_root(cbr),
2457 Expression::MatchRecognize(mr) => self.generate_match_recognize(mr),
2458 Expression::Table(table) => self.generate_table(table),
2459 Expression::StageReference(sr) => self.generate_stage_reference(sr),
2460 Expression::HistoricalData(hd) => self.generate_historical_data(hd),
2461 Expression::JoinedTable(jt) => self.generate_joined_table(jt),
2462 Expression::Star(star) => self.generate_star(star),
2463 Expression::BracedWildcard(expr) => self.generate_braced_wildcard(expr),
2464 Expression::Alias(alias) => self.generate_alias(alias),
2465 Expression::Cast(cast) => self.generate_cast(cast),
2466 Expression::Collation(coll) => self.generate_collation(coll),
2467 Expression::Case(case) => self.generate_case(case),
2468 Expression::Function(func) => self.generate_function(func),
2469 Expression::FunctionEmits(fe) => self.generate_function_emits(fe),
2470 Expression::AggregateFunction(func) => self.generate_aggregate_function(func),
2471 Expression::WindowFunction(wf) => self.generate_window_function(wf),
2472 Expression::WithinGroup(wg) => self.generate_within_group(wg),
2473 Expression::Interval(interval) => self.generate_interval(interval),
2474
2475 Expression::ConcatWs(f) => self.generate_concat_ws(f),
2477 Expression::Substring(f) => self.generate_substring(f),
2478 Expression::Upper(f) => self.generate_unary_func("UPPER", f),
2479 Expression::Lower(f) => self.generate_unary_func("LOWER", f),
2480 Expression::Length(f) => self.generate_unary_func("LENGTH", f),
2481 Expression::Trim(f) => self.generate_trim(f),
2482 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
2483 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
2484 Expression::Replace(f) => self.generate_replace(f),
2485 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
2486 Expression::Left(f) => self.generate_left_right("LEFT", f),
2487 Expression::Right(f) => self.generate_left_right("RIGHT", f),
2488 Expression::Repeat(f) => self.generate_repeat(f),
2489 Expression::Lpad(f) => self.generate_pad("LPAD", f),
2490 Expression::Rpad(f) => self.generate_pad("RPAD", f),
2491 Expression::Split(f) => self.generate_split(f),
2492 Expression::RegexpLike(f) => self.generate_regexp_like(f),
2493 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
2494 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
2495 Expression::Overlay(f) => self.generate_overlay(f),
2496
2497 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
2499 Expression::Round(f) => self.generate_round(f),
2500 Expression::Floor(f) => self.generate_floor(f),
2501 Expression::Ceil(f) => self.generate_ceil(f),
2502 Expression::Power(f) => self.generate_power(f),
2503 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
2504 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
2505 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
2506 Expression::Log(f) => self.generate_log(f),
2507 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
2508 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
2509 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
2510 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
2511
2512 Expression::CurrentDate(_) => {
2514 self.write_keyword("CURRENT_DATE");
2515 Ok(())
2516 }
2517 Expression::CurrentTime(f) => self.generate_current_time(f),
2518 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
2519 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
2520 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
2521 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
2522 Expression::DateDiff(f) => self.generate_datediff(f),
2523 Expression::DateTrunc(f) => self.generate_date_trunc(f),
2524 Expression::Extract(f) => self.generate_extract(f),
2525 Expression::ToDate(f) => self.generate_to_date(f),
2526 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
2527
2528 Expression::Coalesce(f) => {
2530 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
2532 self.generate_vararg_func(func_name, &f.expressions)
2533 }
2534 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
2535 Expression::IfFunc(f) => self.generate_if_func(f),
2536 Expression::IfNull(f) => self.generate_ifnull(f),
2537 Expression::Nvl(f) => self.generate_nvl(f),
2538 Expression::Nvl2(f) => self.generate_nvl2(f),
2539
2540 Expression::TryCast(cast) => self.generate_try_cast(cast),
2542 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
2543
2544 Expression::Count(f) => self.generate_count(f),
2546 Expression::Sum(f) => self.generate_agg_func("SUM", f),
2547 Expression::Avg(f) => self.generate_agg_func("AVG", f),
2548 Expression::Min(f) => self.generate_agg_func("MIN", f),
2549 Expression::Max(f) => self.generate_agg_func("MAX", f),
2550 Expression::GroupConcat(f) => self.generate_group_concat(f),
2551 Expression::StringAgg(f) => self.generate_string_agg(f),
2552 Expression::ListAgg(f) => self.generate_listagg(f),
2553 Expression::ArrayAgg(f) => {
2554 let override_name = f
2557 .name
2558 .as_ref()
2559 .filter(|n| !n.eq_ignore_ascii_case("ARRAY_AGG"))
2560 .map(|n| n.to_ascii_uppercase());
2561 match override_name {
2562 Some(name) => self.generate_agg_func(&name, f),
2563 None => self.generate_agg_func("ARRAY_AGG", f),
2564 }
2565 }
2566 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
2567 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
2568 Expression::SumIf(f) => self.generate_sum_if(f),
2569 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
2570 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
2571 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
2572 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
2573 Expression::VarPop(f) => {
2574 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
2575 "VARIANCE_POP"
2576 } else {
2577 "VAR_POP"
2578 };
2579 self.generate_agg_func(name, f)
2580 }
2581 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
2582 Expression::Skewness(f) => {
2583 let name = match self.config.dialect {
2584 Some(DialectType::Snowflake) => "SKEW",
2585 _ => "SKEWNESS",
2586 };
2587 self.generate_agg_func(name, f)
2588 }
2589 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
2590 Expression::Mode(f) => self.generate_agg_func("MODE", f),
2591 Expression::First(f) => self.generate_agg_func_with_ignore_nulls_bool("FIRST", f),
2592 Expression::Last(f) => self.generate_agg_func_with_ignore_nulls_bool("LAST", f),
2593 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
2594 Expression::ApproxDistinct(f) => {
2595 match self.config.dialect {
2596 Some(DialectType::Hive)
2597 | Some(DialectType::Spark)
2598 | Some(DialectType::Databricks)
2599 | Some(DialectType::BigQuery) => {
2600 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2602 }
2603 Some(DialectType::Redshift) => {
2604 self.write_keyword("APPROXIMATE COUNT");
2606 self.write("(");
2607 self.write_keyword("DISTINCT");
2608 self.write(" ");
2609 self.generate_expression(&f.this)?;
2610 self.write(")");
2611 Ok(())
2612 }
2613 _ => self.generate_agg_func("APPROX_DISTINCT", f),
2614 }
2615 }
2616 Expression::ApproxCountDistinct(f) => {
2617 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2618 }
2619 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
2620 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
2621 Expression::LogicalAnd(f) => {
2622 let name = match self.config.dialect {
2623 Some(DialectType::Snowflake) => "BOOLAND_AGG",
2624 Some(DialectType::Spark)
2625 | Some(DialectType::Databricks)
2626 | Some(DialectType::PostgreSQL)
2627 | Some(DialectType::DuckDB)
2628 | Some(DialectType::Redshift) => "BOOL_AND",
2629 Some(DialectType::Oracle)
2630 | Some(DialectType::SQLite)
2631 | Some(DialectType::MySQL) => "MIN",
2632 _ => "BOOL_AND",
2633 };
2634 self.generate_agg_func(name, f)
2635 }
2636 Expression::LogicalOr(f) => {
2637 let name = match self.config.dialect {
2638 Some(DialectType::Snowflake) => "BOOLOR_AGG",
2639 Some(DialectType::Spark)
2640 | Some(DialectType::Databricks)
2641 | Some(DialectType::PostgreSQL)
2642 | Some(DialectType::DuckDB)
2643 | Some(DialectType::Redshift) => "BOOL_OR",
2644 Some(DialectType::Oracle)
2645 | Some(DialectType::SQLite)
2646 | Some(DialectType::MySQL) => "MAX",
2647 _ => "BOOL_OR",
2648 };
2649 self.generate_agg_func(name, f)
2650 }
2651
2652 Expression::RowNumber(_) => {
2654 if self.config.dialect == Some(DialectType::ClickHouse) {
2655 self.write("row_number");
2656 } else {
2657 self.write_keyword("ROW_NUMBER");
2658 }
2659 self.write("()");
2660 Ok(())
2661 }
2662 Expression::Rank(r) => {
2663 self.write_keyword("RANK");
2664 self.write("(");
2665 if !r.args.is_empty() {
2667 for (i, arg) in r.args.iter().enumerate() {
2668 if i > 0 {
2669 self.write(", ");
2670 }
2671 self.generate_expression(arg)?;
2672 }
2673 } else if let Some(order_by) = &r.order_by {
2674 self.write_keyword(" ORDER BY ");
2676 for (i, ob) in order_by.iter().enumerate() {
2677 if i > 0 {
2678 self.write(", ");
2679 }
2680 self.generate_ordered(ob)?;
2681 }
2682 }
2683 self.write(")");
2684 Ok(())
2685 }
2686 Expression::DenseRank(dr) => {
2687 self.write_keyword("DENSE_RANK");
2688 self.write("(");
2689 for (i, arg) in dr.args.iter().enumerate() {
2691 if i > 0 {
2692 self.write(", ");
2693 }
2694 self.generate_expression(arg)?;
2695 }
2696 self.write(")");
2697 Ok(())
2698 }
2699 Expression::NTile(f) => self.generate_ntile(f),
2700 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
2701 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
2702 Expression::FirstValue(f) => self.generate_value_func_with_ignore_nulls_bool("FIRST_VALUE", f),
2703 Expression::LastValue(f) => self.generate_value_func_with_ignore_nulls_bool("LAST_VALUE", f),
2704 Expression::NthValue(f) => self.generate_nth_value(f),
2705 Expression::PercentRank(pr) => {
2706 self.write_keyword("PERCENT_RANK");
2707 self.write("(");
2708 if !pr.args.is_empty() {
2710 for (i, arg) in pr.args.iter().enumerate() {
2711 if i > 0 {
2712 self.write(", ");
2713 }
2714 self.generate_expression(arg)?;
2715 }
2716 } else if let Some(order_by) = &pr.order_by {
2717 self.write_keyword(" ORDER BY ");
2719 for (i, ob) in order_by.iter().enumerate() {
2720 if i > 0 {
2721 self.write(", ");
2722 }
2723 self.generate_ordered(ob)?;
2724 }
2725 }
2726 self.write(")");
2727 Ok(())
2728 }
2729 Expression::CumeDist(cd) => {
2730 self.write_keyword("CUME_DIST");
2731 self.write("(");
2732 if !cd.args.is_empty() {
2734 for (i, arg) in cd.args.iter().enumerate() {
2735 if i > 0 {
2736 self.write(", ");
2737 }
2738 self.generate_expression(arg)?;
2739 }
2740 } else if let Some(order_by) = &cd.order_by {
2741 self.write_keyword(" ORDER BY ");
2743 for (i, ob) in order_by.iter().enumerate() {
2744 if i > 0 {
2745 self.write(", ");
2746 }
2747 self.generate_ordered(ob)?;
2748 }
2749 }
2750 self.write(")");
2751 Ok(())
2752 }
2753 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
2754 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
2755
2756 Expression::Contains(f) => {
2758 self.generate_binary_func("CONTAINS", &f.this, &f.expression)
2759 }
2760 Expression::StartsWith(f) => {
2761 let name = match self.config.dialect {
2762 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
2763 _ => "STARTS_WITH",
2764 };
2765 self.generate_binary_func(name, &f.this, &f.expression)
2766 }
2767 Expression::EndsWith(f) => {
2768 let name = match self.config.dialect {
2769 Some(DialectType::Snowflake) => "ENDSWITH",
2770 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
2771 Some(DialectType::ClickHouse) => "endsWith",
2772 _ => "ENDS_WITH",
2773 };
2774 self.generate_binary_func(name, &f.this, &f.expression)
2775 }
2776 Expression::Position(f) => self.generate_position(f),
2777 Expression::Initcap(f) => match self.config.dialect {
2778 Some(DialectType::Presto)
2779 | Some(DialectType::Trino)
2780 | Some(DialectType::Athena) => {
2781 self.write_keyword("REGEXP_REPLACE");
2782 self.write("(");
2783 self.generate_expression(&f.this)?;
2784 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
2785 Ok(())
2786 }
2787 _ => self.generate_simple_func("INITCAP", &f.this),
2788 },
2789 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
2790 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
2791 Expression::CharFunc(f) => self.generate_char_func(f),
2792 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
2793 Expression::Levenshtein(f) => {
2794 self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression)
2795 }
2796
2797 Expression::ModFunc(f) => self.generate_mod_func(f),
2799 Expression::Random(_) => {
2800 self.write_keyword("RANDOM");
2801 self.write("()");
2802 Ok(())
2803 }
2804 Expression::Rand(f) => self.generate_rand(f),
2805 Expression::TruncFunc(f) => self.generate_truncate_func(f),
2806 Expression::Pi(_) => {
2807 self.write_keyword("PI");
2808 self.write("()");
2809 Ok(())
2810 }
2811 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
2812 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
2813 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
2814 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
2815 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
2816 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
2817 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
2818 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
2819 Expression::Atan2(f) => {
2820 let name = f.original_name.as_deref().unwrap_or("ATAN2");
2821 self.generate_binary_func(name, &f.this, &f.expression)
2822 }
2823
2824 Expression::Decode(f) => self.generate_decode(f),
2826
2827 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
2829 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
2830 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
2831 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
2832 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
2833 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
2834 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
2835 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
2836 Expression::DayOfWeek(f) => {
2837 let name = match self.config.dialect {
2838 Some(DialectType::Presto)
2839 | Some(DialectType::Trino)
2840 | Some(DialectType::Athena) => "DAY_OF_WEEK",
2841 Some(DialectType::DuckDB) => "ISODOW",
2842 _ => "DAYOFWEEK",
2843 };
2844 self.generate_simple_func(name, &f.this)
2845 }
2846 Expression::DayOfMonth(f) => {
2847 let name = match self.config.dialect {
2848 Some(DialectType::Presto)
2849 | Some(DialectType::Trino)
2850 | Some(DialectType::Athena) => "DAY_OF_MONTH",
2851 _ => "DAYOFMONTH",
2852 };
2853 self.generate_simple_func(name, &f.this)
2854 }
2855 Expression::DayOfYear(f) => {
2856 let name = match self.config.dialect {
2857 Some(DialectType::Presto)
2858 | Some(DialectType::Trino)
2859 | Some(DialectType::Athena) => "DAY_OF_YEAR",
2860 _ => "DAYOFYEAR",
2861 };
2862 self.generate_simple_func(name, &f.this)
2863 }
2864 Expression::WeekOfYear(f) => {
2865 let name = match self.config.dialect {
2867 Some(DialectType::Hive)
2868 | Some(DialectType::DuckDB)
2869 | Some(DialectType::Spark)
2870 | Some(DialectType::Databricks)
2871 | Some(DialectType::MySQL) => "WEEKOFYEAR",
2872 _ => "WEEK_OF_YEAR",
2873 };
2874 self.generate_simple_func(name, &f.this)
2875 }
2876 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
2877 Expression::AddMonths(f) => {
2878 self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression)
2879 }
2880 Expression::MonthsBetween(f) => {
2881 self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression)
2882 }
2883 Expression::LastDay(f) => self.generate_last_day(f),
2884 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
2885 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
2886 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
2887 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
2888 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
2889 Expression::MakeDate(f) => self.generate_make_date(f),
2890 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
2891 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
2892
2893 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
2895 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
2896 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
2897 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
2898 Expression::ArrayContains(f) => {
2899 self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression)
2900 }
2901 Expression::ArrayPosition(f) => {
2902 self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression)
2903 }
2904 Expression::ArrayAppend(f) => {
2905 self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression)
2906 }
2907 Expression::ArrayPrepend(f) => {
2908 self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression)
2909 }
2910 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
2911 Expression::ArraySort(f) => self.generate_array_sort(f),
2912 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
2913 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
2914 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
2915 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
2916 Expression::Unnest(f) => self.generate_unnest(f),
2917 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
2918 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
2919 Expression::ArrayFilter(f) => self.generate_array_filter(f),
2920 Expression::ArrayTransform(f) => self.generate_array_transform(f),
2921 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
2922 Expression::ArrayCompact(f) => {
2923 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
2924 self.write("LIST_FILTER(");
2926 self.generate_expression(&f.this)?;
2927 self.write(", _u -> NOT _u IS NULL)");
2928 Ok(())
2929 } else {
2930 self.generate_simple_func("ARRAY_COMPACT", &f.this)
2931 }
2932 }
2933 Expression::ArrayIntersect(f) => {
2934 let func_name = f.original_name.as_deref().unwrap_or("ARRAY_INTERSECT");
2935 self.generate_vararg_func(func_name, &f.expressions)
2936 }
2937 Expression::ArrayUnion(f) => {
2938 self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression)
2939 }
2940 Expression::ArrayExcept(f) => {
2941 self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression)
2942 }
2943 Expression::ArrayRemove(f) => {
2944 self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression)
2945 }
2946 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
2947 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
2948 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
2949
2950 Expression::StructFunc(f) => self.generate_struct_constructor(f),
2952 Expression::StructExtract(f) => self.generate_struct_extract(f),
2953 Expression::NamedStruct(f) => self.generate_named_struct(f),
2954
2955 Expression::MapFunc(f) => self.generate_map_constructor(f),
2957 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
2958 Expression::MapFromArrays(f) => {
2959 self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression)
2960 }
2961 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
2962 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
2963 Expression::MapContainsKey(f) => {
2964 self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression)
2965 }
2966 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
2967 Expression::ElementAt(f) => {
2968 self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression)
2969 }
2970 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
2971 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
2972
2973 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
2975 Expression::JsonExtractScalar(f) => {
2976 self.generate_json_extract("JSON_EXTRACT_SCALAR", f)
2977 }
2978 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
2979 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
2980 Expression::JsonObject(f) => self.generate_json_object(f),
2981 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
2982 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
2983 Expression::JsonArrayLength(f) => {
2984 self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this)
2985 }
2986 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
2987 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
2988 Expression::ParseJson(f) => {
2989 let name = match self.config.dialect {
2990 Some(DialectType::Presto)
2991 | Some(DialectType::Trino)
2992 | Some(DialectType::Athena) => "JSON_PARSE",
2993 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
2994 self.write_keyword("CAST");
2996 self.write("(");
2997 self.generate_expression(&f.this)?;
2998 self.write_keyword(" AS ");
2999 self.write_keyword("JSON");
3000 self.write(")");
3001 return Ok(());
3002 }
3003 Some(DialectType::Hive)
3004 | Some(DialectType::Spark)
3005 | Some(DialectType::MySQL)
3006 | Some(DialectType::SingleStore)
3007 | Some(DialectType::TiDB)
3008 | Some(DialectType::TSQL) => {
3009 self.generate_expression(&f.this)?;
3011 return Ok(());
3012 }
3013 Some(DialectType::DuckDB) => "JSON",
3014 _ => "PARSE_JSON",
3015 };
3016 self.generate_simple_func(name, &f.this)
3017 }
3018 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
3019 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
3020 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
3021 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
3022 Expression::JsonMergePatch(f) => {
3023 self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression)
3024 }
3025 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
3026 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
3027
3028 Expression::Convert(f) => self.generate_convert(f),
3030 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
3031
3032 Expression::Lambda(f) => self.generate_lambda(f),
3034 Expression::Parameter(f) => self.generate_parameter(f),
3035 Expression::Placeholder(f) => self.generate_placeholder(f),
3036 Expression::NamedArgument(f) => self.generate_named_argument(f),
3037 Expression::TableArgument(f) => self.generate_table_argument(f),
3038 Expression::SqlComment(f) => self.generate_sql_comment(f),
3039
3040 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
3042 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
3043 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
3044 Expression::SimilarTo(f) => self.generate_similar_to(f),
3045 Expression::Any(f) => self.generate_quantified("ANY", f),
3046 Expression::All(f) => self.generate_quantified("ALL", f),
3047 Expression::Overlaps(f) => self.generate_overlaps(f),
3048
3049 Expression::BitwiseLeftShift(op) => {
3051 if matches!(
3052 self.config.dialect,
3053 Some(DialectType::Presto) | Some(DialectType::Trino)
3054 ) {
3055 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_LEFT");
3056 self.write("(");
3057 self.generate_expression(&op.left)?;
3058 self.write(", ");
3059 self.generate_expression(&op.right)?;
3060 self.write(")");
3061 Ok(())
3062 } else if matches!(
3063 self.config.dialect,
3064 Some(DialectType::Spark) | Some(DialectType::Databricks)
3065 ) {
3066 self.write_keyword("SHIFTLEFT");
3067 self.write("(");
3068 self.generate_expression(&op.left)?;
3069 self.write(", ");
3070 self.generate_expression(&op.right)?;
3071 self.write(")");
3072 Ok(())
3073 } else {
3074 self.generate_binary_op(op, "<<")
3075 }
3076 }
3077 Expression::BitwiseRightShift(op) => {
3078 if matches!(
3079 self.config.dialect,
3080 Some(DialectType::Presto) | Some(DialectType::Trino)
3081 ) {
3082 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_RIGHT");
3083 self.write("(");
3084 self.generate_expression(&op.left)?;
3085 self.write(", ");
3086 self.generate_expression(&op.right)?;
3087 self.write(")");
3088 Ok(())
3089 } else if matches!(
3090 self.config.dialect,
3091 Some(DialectType::Spark) | Some(DialectType::Databricks)
3092 ) {
3093 self.write_keyword("SHIFTRIGHT");
3094 self.write("(");
3095 self.generate_expression(&op.left)?;
3096 self.write(", ");
3097 self.generate_expression(&op.right)?;
3098 self.write(")");
3099 Ok(())
3100 } else {
3101 self.generate_binary_op(op, ">>")
3102 }
3103 }
3104 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
3105 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
3106 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
3107
3108 Expression::Subscript(s) => self.generate_subscript(s),
3110 Expression::Dot(d) => self.generate_dot_access(d),
3111 Expression::MethodCall(m) => self.generate_method_call(m),
3112 Expression::ArraySlice(s) => self.generate_array_slice(s),
3113
3114 Expression::And(op) => self.generate_connector_op(op, ConnectorOperator::And),
3115 Expression::Or(op) => self.generate_connector_op(op, ConnectorOperator::Or),
3116 Expression::Add(op) => self.generate_binary_op(op, "+"),
3117 Expression::Sub(op) => self.generate_binary_op(op, "-"),
3118 Expression::Mul(op) => self.generate_binary_op(op, "*"),
3119 Expression::Div(op) => self.generate_binary_op(op, "/"),
3120 Expression::IntDiv(f) => {
3121 use crate::dialects::DialectType;
3122 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
3123 self.generate_expression(&f.this)?;
3125 self.write(" // ");
3126 self.generate_expression(&f.expression)?;
3127 Ok(())
3128 } else if matches!(
3129 self.config.dialect,
3130 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
3131 ) {
3132 self.generate_expression(&f.this)?;
3134 self.write(" ");
3135 self.write_keyword("DIV");
3136 self.write(" ");
3137 self.generate_expression(&f.expression)?;
3138 Ok(())
3139 } else {
3140 self.write_keyword("DIV");
3142 self.write("(");
3143 self.generate_expression(&f.this)?;
3144 self.write(", ");
3145 self.generate_expression(&f.expression)?;
3146 self.write(")");
3147 Ok(())
3148 }
3149 }
3150 Expression::Mod(op) => {
3151 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
3152 self.generate_binary_op(op, "MOD")
3153 } else {
3154 self.generate_binary_op(op, "%")
3155 }
3156 }
3157 Expression::Eq(op) => self.generate_binary_op(op, "="),
3158 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
3159 Expression::Lt(op) => self.generate_binary_op(op, "<"),
3160 Expression::Lte(op) => self.generate_binary_op(op, "<="),
3161 Expression::Gt(op) => self.generate_binary_op(op, ">"),
3162 Expression::Gte(op) => self.generate_binary_op(op, ">="),
3163 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
3164 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
3165 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
3166 Expression::Concat(op) => {
3167 if self.config.dialect == Some(DialectType::Solr) {
3169 self.generate_binary_op(op, "OR")
3170 } else if self.config.dialect == Some(DialectType::MySQL) {
3171 self.generate_mysql_concat_from_concat(op)
3172 } else {
3173 self.generate_binary_op(op, "||")
3174 }
3175 }
3176 Expression::BitwiseAnd(op) => {
3177 if matches!(
3179 self.config.dialect,
3180 Some(DialectType::Presto) | Some(DialectType::Trino)
3181 ) {
3182 self.write_keyword("BITWISE_AND");
3183 self.write("(");
3184 self.generate_expression(&op.left)?;
3185 self.write(", ");
3186 self.generate_expression(&op.right)?;
3187 self.write(")");
3188 Ok(())
3189 } else {
3190 self.generate_binary_op(op, "&")
3191 }
3192 }
3193 Expression::BitwiseOr(op) => {
3194 if matches!(
3196 self.config.dialect,
3197 Some(DialectType::Presto) | Some(DialectType::Trino)
3198 ) {
3199 self.write_keyword("BITWISE_OR");
3200 self.write("(");
3201 self.generate_expression(&op.left)?;
3202 self.write(", ");
3203 self.generate_expression(&op.right)?;
3204 self.write(")");
3205 Ok(())
3206 } else {
3207 self.generate_binary_op(op, "|")
3208 }
3209 }
3210 Expression::BitwiseXor(op) => {
3211 if matches!(
3213 self.config.dialect,
3214 Some(DialectType::Presto) | Some(DialectType::Trino)
3215 ) {
3216 self.write_keyword("BITWISE_XOR");
3217 self.write("(");
3218 self.generate_expression(&op.left)?;
3219 self.write(", ");
3220 self.generate_expression(&op.right)?;
3221 self.write(")");
3222 Ok(())
3223 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
3224 self.generate_binary_op(op, "#")
3225 } else {
3226 self.generate_binary_op(op, "^")
3227 }
3228 }
3229 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
3230 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
3231 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
3232 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
3233 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
3234 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
3235 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
3236 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
3237 Expression::JSONBContains(f) => {
3238 self.generate_expression(&f.this)?;
3240 self.write_space();
3241 self.write("?");
3242 self.write_space();
3243 self.generate_expression(&f.expression)
3244 }
3245 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
3246 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
3247 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
3248 Expression::Not(op) => self.generate_unary_op(op, "NOT"),
3249 Expression::Neg(op) => self.generate_unary_op(op, "-"),
3250 Expression::BitwiseNot(op) => {
3251 if matches!(
3253 self.config.dialect,
3254 Some(DialectType::Presto) | Some(DialectType::Trino)
3255 ) {
3256 self.write_keyword("BITWISE_NOT");
3257 self.write("(");
3258 self.generate_expression(&op.this)?;
3259 self.write(")");
3260 Ok(())
3261 } else {
3262 self.generate_unary_op(op, "~")
3263 }
3264 }
3265 Expression::In(in_expr) => self.generate_in(in_expr),
3266 Expression::Between(between) => self.generate_between(between),
3267 Expression::IsNull(is_null) => self.generate_is_null(is_null),
3268 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
3269 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
3270 Expression::IsJson(is_json) => self.generate_is_json(is_json),
3271 Expression::Is(is_expr) => self.generate_is(is_expr),
3272 Expression::Exists(exists) => self.generate_exists(exists),
3273 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
3274 Expression::Subquery(subquery) => self.generate_subquery(subquery),
3275 Expression::Paren(paren) => {
3276 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
3278
3279 if !skip_parens {
3280 self.write("(");
3281 if self.config.pretty {
3282 self.write_newline();
3283 self.indent_level += 1;
3284 self.write_indent();
3285 }
3286 }
3287 self.generate_expression(&paren.this)?;
3288 if !skip_parens {
3289 if self.config.pretty {
3290 self.write_newline();
3291 self.indent_level -= 1;
3292 self.write_indent();
3293 }
3294 self.write(")");
3295 }
3296 for comment in &paren.trailing_comments {
3298 self.write(" ");
3299 self.write_formatted_comment(comment);
3300 }
3301 Ok(())
3302 }
3303 Expression::Array(arr) => self.generate_array(arr),
3304 Expression::Tuple(tuple) => self.generate_tuple(tuple),
3305 Expression::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
3306 Expression::Ordered(ordered) => self.generate_ordered(ordered),
3307 Expression::DataType(dt) => self.generate_data_type(dt),
3308 Expression::Raw(raw) => {
3309 self.write(&raw.sql);
3310 Ok(())
3311 }
3312 Expression::Command(cmd) => {
3313 self.write(&cmd.this);
3314 Ok(())
3315 }
3316 Expression::Kill(kill) => {
3317 self.write_keyword("KILL");
3318 if let Some(kind) = &kill.kind {
3319 self.write_space();
3320 self.write_keyword(kind);
3321 }
3322 self.write_space();
3323 self.generate_expression(&kill.this)?;
3324 Ok(())
3325 }
3326 Expression::Execute(exec) => {
3327 self.write_keyword("EXECUTE");
3328 self.write_space();
3329 self.generate_expression(&exec.this)?;
3330 for (i, param) in exec.parameters.iter().enumerate() {
3331 if i == 0 {
3332 self.write_space();
3333 } else {
3334 self.write(", ");
3335 }
3336 self.write(¶m.name);
3337 if !param.positional {
3339 self.write(" = ");
3340 self.generate_expression(¶m.value)?;
3341 }
3342 }
3343 Ok(())
3344 }
3345 Expression::Annotated(annotated) => {
3346 self.generate_expression(&annotated.this)?;
3347 for comment in &annotated.trailing_comments {
3348 self.write(" ");
3349 self.write_formatted_comment(comment);
3350 }
3351 Ok(())
3352 }
3353
3354 Expression::CreateTable(ct) => self.generate_create_table(ct),
3356 Expression::DropTable(dt) => self.generate_drop_table(dt),
3357 Expression::AlterTable(at) => self.generate_alter_table(at),
3358 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3359 Expression::DropIndex(di) => self.generate_drop_index(di),
3360 Expression::CreateView(cv) => self.generate_create_view(cv),
3361 Expression::DropView(dv) => self.generate_drop_view(dv),
3362 Expression::AlterView(av) => self.generate_alter_view(av),
3363 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3364 Expression::Truncate(tr) => self.generate_truncate(tr),
3365 Expression::Use(u) => self.generate_use(u),
3366 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3368 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3369 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3370 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3371 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3372 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3373 Expression::DropFunction(df) => self.generate_drop_function(df),
3374 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3375 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3376 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3377 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3378 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3379 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3380 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3381 Expression::CreateType(ct) => self.generate_create_type(ct),
3382 Expression::DropType(dt) => self.generate_drop_type(dt),
3383 Expression::Describe(d) => self.generate_describe(d),
3384 Expression::Show(s) => self.generate_show(s),
3385
3386 Expression::Cache(c) => self.generate_cache(c),
3388 Expression::Uncache(u) => self.generate_uncache(u),
3389 Expression::LoadData(l) => self.generate_load_data(l),
3390 Expression::Pragma(p) => self.generate_pragma(p),
3391 Expression::Grant(g) => self.generate_grant(g),
3392 Expression::Revoke(r) => self.generate_revoke(r),
3393 Expression::Comment(c) => self.generate_comment(c),
3394 Expression::SetStatement(s) => self.generate_set_statement(s),
3395
3396 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3398 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3399
3400 Expression::Values(values) => self.generate_values(values),
3402
3403 Expression::AIAgg(e) => self.generate_ai_agg(e),
3405 Expression::AIClassify(e) => self.generate_ai_classify(e),
3406 Expression::AddPartition(e) => self.generate_add_partition(e),
3407 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3408 Expression::Aliases(e) => self.generate_aliases(e),
3409 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3410 Expression::AlterColumn(e) => self.generate_alter_column(e),
3411 Expression::AlterSession(e) => self.generate_alter_session(e),
3412 Expression::AlterSet(e) => self.generate_alter_set(e),
3413 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3414 Expression::Analyze(e) => self.generate_analyze(e),
3415 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3416 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3417 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3418 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3419 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3420 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3421 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3422 Expression::Anonymous(e) => self.generate_anonymous(e),
3423 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3424 Expression::Apply(e) => self.generate_apply(e),
3425 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3426 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3427 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3428 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3429 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3430 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3431 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3432 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3433 Expression::ArgMax(e) => self.generate_arg_max(e),
3434 Expression::ArgMin(e) => self.generate_arg_min(e),
3435 Expression::ArrayAll(e) => self.generate_array_all(e),
3436 Expression::ArrayAny(e) => self.generate_array_any(e),
3437 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3438 Expression::ArraySum(e) => self.generate_array_sum(e),
3439 Expression::AtIndex(e) => self.generate_at_index(e),
3440 Expression::Attach(e) => self.generate_attach(e),
3441 Expression::AttachOption(e) => self.generate_attach_option(e),
3442 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3443 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3444 Expression::BackupProperty(e) => self.generate_backup_property(e),
3445 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3446 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3447 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3448 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3449 Expression::Booland(e) => self.generate_booland(e),
3450 Expression::Boolor(e) => self.generate_boolor(e),
3451 Expression::BuildProperty(e) => self.generate_build_property(e),
3452 Expression::ByteString(e) => self.generate_byte_string(e),
3453 Expression::CaseSpecificColumnConstraint(e) => {
3454 self.generate_case_specific_column_constraint(e)
3455 }
3456 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3457 Expression::Changes(e) => self.generate_changes(e),
3458 Expression::CharacterSetColumnConstraint(e) => {
3459 self.generate_character_set_column_constraint(e)
3460 }
3461 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3462 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3463 Expression::AssumeColumnConstraint(e) => self.generate_assume_column_constraint(e),
3464 Expression::CheckJson(e) => self.generate_check_json(e),
3465 Expression::CheckXml(e) => self.generate_check_xml(e),
3466 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3467 Expression::Clone(e) => self.generate_clone(e),
3468 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3469 Expression::ClusterByColumnsProperty(e) => self.generate_cluster_by_columns_property(e),
3470 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3471 Expression::CollateProperty(e) => self.generate_collate_property(e),
3472 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3473 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3474 Expression::ColumnPosition(e) => self.generate_column_position(e),
3475 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3476 Expression::Columns(e) => self.generate_columns(e),
3477 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3478 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3479 Expression::Commit(e) => self.generate_commit(e),
3480 Expression::Comprehension(e) => self.generate_comprehension(e),
3481 Expression::Compress(e) => self.generate_compress(e),
3482 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3483 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3484 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3485 Expression::Constraint(e) => self.generate_constraint(e),
3486 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3487 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3488 Expression::Copy(e) => self.generate_copy(e),
3489 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3490 Expression::Corr(e) => self.generate_corr(e),
3491 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3492 Expression::CovarPop(e) => self.generate_covar_pop(e),
3493 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3494 Expression::Credentials(e) => self.generate_credentials(e),
3495 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3496 Expression::Cte(e) => self.generate_cte(e),
3497 Expression::Cube(e) => self.generate_cube(e),
3498 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3499 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3500 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3501 Expression::CurrentUser(e) => self.generate_current_user(e),
3502 Expression::DPipe(e) => self.generate_d_pipe(e),
3503 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3504 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3505 Expression::Date(e) => self.generate_date_func(e),
3506 Expression::DateBin(e) => self.generate_date_bin(e),
3507 Expression::DateFormatColumnConstraint(e) => {
3508 self.generate_date_format_column_constraint(e)
3509 }
3510 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3511 Expression::Datetime(e) => self.generate_datetime(e),
3512 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3513 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3514 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3515 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3516 Expression::Dayname(e) => self.generate_dayname(e),
3517 Expression::Declare(e) => self.generate_declare(e),
3518 Expression::DeclareItem(e) => self.generate_declare_item(e),
3519 Expression::DecodeCase(e) => self.generate_decode_case(e),
3520 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3521 Expression::DecompressString(e) => self.generate_decompress_string(e),
3522 Expression::Decrypt(e) => self.generate_decrypt(e),
3523 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3524 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3525 Expression::Detach(e) => self.generate_detach(e),
3526 Expression::DictProperty(e) => self.generate_dict_property(e),
3527 Expression::DictRange(e) => self.generate_dict_range(e),
3528 Expression::Directory(e) => self.generate_directory(e),
3529 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3530 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3531 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3532 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3533 Expression::DotProduct(e) => self.generate_dot_product(e),
3534 Expression::DropPartition(e) => self.generate_drop_partition(e),
3535 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3536 Expression::Elt(e) => self.generate_elt(e),
3537 Expression::Encode(e) => self.generate_encode(e),
3538 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3539 Expression::Encrypt(e) => self.generate_encrypt(e),
3540 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3541 Expression::EngineProperty(e) => self.generate_engine_property(e),
3542 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3543 Expression::EphemeralColumnConstraint(e) => {
3544 self.generate_ephemeral_column_constraint(e)
3545 }
3546 Expression::EqualNull(e) => self.generate_equal_null(e),
3547 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3548 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3549 Expression::Export(e) => self.generate_export(e),
3550 Expression::ExternalProperty(e) => self.generate_external_property(e),
3551 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3552 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3553 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3554 Expression::Fetch(e) => self.generate_fetch(e),
3555 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3556 Expression::Filter(e) => self.generate_filter(e),
3557 Expression::Float64(e) => self.generate_float64(e),
3558 Expression::ForIn(e) => self.generate_for_in(e),
3559 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3560 Expression::Format(e) => self.generate_format(e),
3561 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3562 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3563 Expression::From(e) => self.generate_from(e),
3564 Expression::FromBase(e) => self.generate_from_base(e),
3565 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3566 Expression::GapFill(e) => self.generate_gap_fill(e),
3567 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3568 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3569 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3570 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3571 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3572 self.generate_generated_as_identity_column_constraint(e)
3573 }
3574 Expression::GeneratedAsRowColumnConstraint(e) => {
3575 self.generate_generated_as_row_column_constraint(e)
3576 }
3577 Expression::Get(e) => self.generate_get(e),
3578 Expression::GetExtract(e) => self.generate_get_extract(e),
3579 Expression::Getbit(e) => self.generate_getbit(e),
3580 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3581 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3582 Expression::Group(e) => self.generate_group(e),
3583 Expression::GroupBy(e) => self.generate_group_by(e),
3584 Expression::Grouping(e) => self.generate_grouping(e),
3585 Expression::GroupingId(e) => self.generate_grouping_id(e),
3586 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3587 Expression::HashAgg(e) => self.generate_hash_agg(e),
3588 Expression::Having(e) => self.generate_having(e),
3589 Expression::HavingMax(e) => self.generate_having_max(e),
3590 Expression::Heredoc(e) => self.generate_heredoc(e),
3591 Expression::HexEncode(e) => self.generate_hex_encode(e),
3592 Expression::Hll(e) => self.generate_hll(e),
3593 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3594 Expression::IncludeProperty(e) => self.generate_include_property(e),
3595 Expression::Index(e) => self.generate_index(e),
3596 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3597 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3598 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3599 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3600 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3601 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3602 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3603 Expression::Install(e) => self.generate_install(e),
3604 Expression::IntervalOp(e) => self.generate_interval_op(e),
3605 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3606 Expression::IntoClause(e) => self.generate_into_clause(e),
3607 Expression::Introducer(e) => self.generate_introducer(e),
3608 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3609 Expression::JSON(e) => self.generate_json(e),
3610 Expression::JSONArray(e) => self.generate_json_array(e),
3611 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3612 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3613 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3614 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3615 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3616 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3617 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3618 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3619 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3620 Expression::JSONExists(e) => self.generate_json_exists(e),
3621 Expression::JSONCast(e) => self.generate_json_cast(e),
3622 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3623 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3624 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3625 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3626 Expression::JSONFormat(e) => self.generate_json_format(e),
3627 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3628 Expression::JSONKeys(e) => self.generate_json_keys(e),
3629 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3630 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3631 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3632 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3633 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3634 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3635 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3636 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3637 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3638 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3639 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3640 Expression::JSONRemove(e) => self.generate_json_remove(e),
3641 Expression::JSONSchema(e) => self.generate_json_schema(e),
3642 Expression::JSONSet(e) => self.generate_json_set(e),
3643 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3644 Expression::JSONTable(e) => self.generate_json_table(e),
3645 Expression::JSONType(e) => self.generate_json_type(e),
3646 Expression::JSONValue(e) => self.generate_json_value(e),
3647 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3648 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3649 Expression::JoinHint(e) => self.generate_join_hint(e),
3650 Expression::JournalProperty(e) => self.generate_journal_property(e),
3651 Expression::LanguageProperty(e) => self.generate_language_property(e),
3652 Expression::Lateral(e) => self.generate_lateral(e),
3653 Expression::LikeProperty(e) => self.generate_like_property(e),
3654 Expression::Limit(e) => self.generate_limit(e),
3655 Expression::LimitOptions(e) => self.generate_limit_options(e),
3656 Expression::List(e) => self.generate_list(e),
3657 Expression::ToMap(e) => self.generate_tomap(e),
3658 Expression::Localtime(e) => self.generate_localtime(e),
3659 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3660 Expression::LocationProperty(e) => self.generate_location_property(e),
3661 Expression::Lock(e) => self.generate_lock(e),
3662 Expression::LockProperty(e) => self.generate_lock_property(e),
3663 Expression::LockingProperty(e) => self.generate_locking_property(e),
3664 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3665 Expression::LogProperty(e) => self.generate_log_property(e),
3666 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3667 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3668 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3669 Expression::MakeInterval(e) => self.generate_make_interval(e),
3670 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3671 Expression::Map(e) => self.generate_map(e),
3672 Expression::MapCat(e) => self.generate_map_cat(e),
3673 Expression::MapDelete(e) => self.generate_map_delete(e),
3674 Expression::MapInsert(e) => self.generate_map_insert(e),
3675 Expression::MapPick(e) => self.generate_map_pick(e),
3676 Expression::MaskingPolicyColumnConstraint(e) => {
3677 self.generate_masking_policy_column_constraint(e)
3678 }
3679 Expression::MatchAgainst(e) => self.generate_match_against(e),
3680 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3681 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3682 Expression::Merge(e) => self.generate_merge(e),
3683 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3684 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3685 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3686 Expression::Minhash(e) => self.generate_minhash(e),
3687 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3688 Expression::Monthname(e) => self.generate_monthname(e),
3689 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3690 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3691 Expression::Normal(e) => self.generate_normal(e),
3692 Expression::Normalize(e) => self.generate_normalize(e),
3693 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3694 Expression::Nullif(e) => self.generate_nullif(e),
3695 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3696 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3697 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3698 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3699 Expression::Offset(e) => self.generate_offset(e),
3700 Expression::Qualify(e) => self.generate_qualify(e),
3701 Expression::OnCluster(e) => self.generate_on_cluster(e),
3702 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3703 Expression::OnCondition(e) => self.generate_on_condition(e),
3704 Expression::OnConflict(e) => self.generate_on_conflict(e),
3705 Expression::OnProperty(e) => self.generate_on_property(e),
3706 Expression::Opclass(e) => self.generate_opclass(e),
3707 Expression::OpenJSON(e) => self.generate_open_json(e),
3708 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3709 Expression::Operator(e) => self.generate_operator(e),
3710 Expression::OrderBy(e) => self.generate_order_by(e),
3711 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3712 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3713 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3714 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3715 Expression::ParseIp(e) => self.generate_parse_ip(e),
3716 Expression::ParseJSON(e) => self.generate_parse_json(e),
3717 Expression::ParseTime(e) => self.generate_parse_time(e),
3718 Expression::ParseUrl(e) => self.generate_parse_url(e),
3719 Expression::Partition(e) => self.generate_partition_expr(e),
3720 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3721 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3722 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3723 Expression::PartitionByRangePropertyDynamic(e) => {
3724 self.generate_partition_by_range_property_dynamic(e)
3725 }
3726 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3727 Expression::PartitionList(e) => self.generate_partition_list(e),
3728 Expression::PartitionRange(e) => self.generate_partition_range(e),
3729 Expression::PartitionByProperty(e) => self.generate_partition_by_property(e),
3730 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3731 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3732 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3733 Expression::PeriodForSystemTimeConstraint(e) => {
3734 self.generate_period_for_system_time_constraint(e)
3735 }
3736 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3737 Expression::PivotAny(e) => self.generate_pivot_any(e),
3738 Expression::Predict(e) => self.generate_predict(e),
3739 Expression::PreviousDay(e) => self.generate_previous_day(e),
3740 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3741 Expression::PrimaryKeyColumnConstraint(e) => {
3742 self.generate_primary_key_column_constraint(e)
3743 }
3744 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3745 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3746 Expression::OptionsProperty(e) => self.generate_options_property(e),
3747 Expression::Properties(e) => self.generate_properties(e),
3748 Expression::Property(e) => self.generate_property(e),
3749 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3750 Expression::Put(e) => self.generate_put(e),
3751 Expression::Quantile(e) => self.generate_quantile(e),
3752 Expression::QueryBand(e) => self.generate_query_band(e),
3753 Expression::QueryOption(e) => self.generate_query_option(e),
3754 Expression::QueryTransform(e) => self.generate_query_transform(e),
3755 Expression::Randn(e) => self.generate_randn(e),
3756 Expression::Randstr(e) => self.generate_randstr(e),
3757 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3758 Expression::RangeN(e) => self.generate_range_n(e),
3759 Expression::ReadCSV(e) => self.generate_read_csv(e),
3760 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3761 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3762 Expression::Reduce(e) => self.generate_reduce(e),
3763 Expression::Reference(e) => self.generate_reference(e),
3764 Expression::Refresh(e) => self.generate_refresh(e),
3765 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3766 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3767 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3768 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3769 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3770 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3771 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3772 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3773 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3774 Expression::RegrCount(e) => self.generate_regr_count(e),
3775 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3776 Expression::RegrR2(e) => self.generate_regr_r2(e),
3777 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3778 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3779 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3780 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3781 Expression::RegrValx(e) => self.generate_regr_valx(e),
3782 Expression::RegrValy(e) => self.generate_regr_valy(e),
3783 Expression::RemoteWithConnectionModelProperty(e) => {
3784 self.generate_remote_with_connection_model_property(e)
3785 }
3786 Expression::RenameColumn(e) => self.generate_rename_column(e),
3787 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3788 Expression::Returning(e) => self.generate_returning(e),
3789 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3790 Expression::Rollback(e) => self.generate_rollback(e),
3791 Expression::Rollup(e) => self.generate_rollup(e),
3792 Expression::RowFormatDelimitedProperty(e) => {
3793 self.generate_row_format_delimited_property(e)
3794 }
3795 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3796 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3797 Expression::SHA2(e) => self.generate_sha2(e),
3798 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3799 Expression::SafeAdd(e) => self.generate_safe_add(e),
3800 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3801 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3802 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3803 Expression::SampleProperty(e) => self.generate_sample_property(e),
3804 Expression::Schema(e) => self.generate_schema(e),
3805 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3806 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3807 Expression::Search(e) => self.generate_search(e),
3808 Expression::SearchIp(e) => self.generate_search_ip(e),
3809 Expression::SecurityProperty(e) => self.generate_security_property(e),
3810 Expression::SemanticView(e) => self.generate_semantic_view(e),
3811 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3812 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3813 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3814 Expression::Set(e) => self.generate_set(e),
3815 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3816 Expression::SetItem(e) => self.generate_set_item(e),
3817 Expression::SetOperation(e) => self.generate_set_operation(e),
3818 Expression::SetProperty(e) => self.generate_set_property(e),
3819 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3820 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3821 Expression::Slice(e) => self.generate_slice(e),
3822 Expression::SortArray(e) => self.generate_sort_array(e),
3823 Expression::SortBy(e) => self.generate_sort_by(e),
3824 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3825 Expression::SplitPart(e) => self.generate_split_part(e),
3826 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3827 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3828 Expression::StDistance(e) => self.generate_st_distance(e),
3829 Expression::StPoint(e) => self.generate_st_point(e),
3830 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3831 Expression::StandardHash(e) => self.generate_standard_hash(e),
3832 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3833 Expression::StrPosition(e) => self.generate_str_position(e),
3834 Expression::StrToDate(e) => self.generate_str_to_date(e),
3835 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3836 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3837 Expression::StrToMap(e) => self.generate_str_to_map(e),
3838 Expression::StrToTime(e) => self.generate_str_to_time(e),
3839 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3840 Expression::StringToArray(e) => self.generate_string_to_array(e),
3841 Expression::Struct(e) => self.generate_struct(e),
3842 Expression::Stuff(e) => self.generate_stuff(e),
3843 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3844 Expression::Summarize(e) => self.generate_summarize(e),
3845 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3846 Expression::TableAlias(e) => self.generate_table_alias(e),
3847 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3848 Expression::RowsFrom(e) => self.generate_rows_from(e),
3849 Expression::TableSample(e) => self.generate_table_sample(e),
3850 Expression::Tag(e) => self.generate_tag(e),
3851 Expression::Tags(e) => self.generate_tags(e),
3852 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3853 Expression::Time(e) => self.generate_time_func(e),
3854 Expression::TimeAdd(e) => self.generate_time_add(e),
3855 Expression::TimeDiff(e) => self.generate_time_diff(e),
3856 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3857 Expression::TimeSlice(e) => self.generate_time_slice(e),
3858 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3859 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3860 Expression::TimeSub(e) => self.generate_time_sub(e),
3861 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3862 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3863 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3864 Expression::TimeUnit(e) => self.generate_time_unit(e),
3865 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3866 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3867 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3868 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3869 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3870 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3871 Expression::ToBinary(e) => self.generate_to_binary(e),
3872 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3873 Expression::ToChar(e) => self.generate_to_char(e),
3874 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3875 Expression::ToDouble(e) => self.generate_to_double(e),
3876 Expression::ToFile(e) => self.generate_to_file(e),
3877 Expression::ToNumber(e) => self.generate_to_number(e),
3878 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3879 Expression::Transaction(e) => self.generate_transaction(e),
3880 Expression::Transform(e) => self.generate_transform(e),
3881 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3882 Expression::TransientProperty(e) => self.generate_transient_property(e),
3883 Expression::Translate(e) => self.generate_translate(e),
3884 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
3885 Expression::TruncateTable(e) => self.generate_truncate_table(e),
3886 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
3887 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
3888 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
3889 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
3890 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
3891 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
3892 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
3893 Expression::Unhex(e) => self.generate_unhex(e),
3894 Expression::UnicodeString(e) => self.generate_unicode_string(e),
3895 Expression::Uniform(e) => self.generate_uniform(e),
3896 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
3897 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
3898 Expression::RollupProperty(e) => self.generate_rollup_property(e),
3899 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
3900 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
3901 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
3902 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
3903 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
3904 Expression::UtcTime(e) => self.generate_utc_time(e),
3905 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
3906 Expression::Uuid(e) => self.generate_uuid(e),
3907 Expression::Var(v) => {
3908 if matches!(self.config.dialect, Some(DialectType::MySQL))
3909 && v.this.len() > 2
3910 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
3911 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
3912 {
3913 return self.generate_identifier(&Identifier {
3914 name: v.this.clone(),
3915 quoted: true,
3916 trailing_comments: Vec::new(),
3917 span: None,
3918 });
3919 }
3920 self.write(&v.this);
3921 Ok(())
3922 }
3923 Expression::Variadic(e) => {
3924 self.write_keyword("VARIADIC");
3925 self.write_space();
3926 self.generate_expression(&e.this)?;
3927 Ok(())
3928 }
3929 Expression::VarMap(e) => self.generate_var_map(e),
3930 Expression::VectorSearch(e) => self.generate_vector_search(e),
3931 Expression::Version(e) => self.generate_version(e),
3932 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
3933 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
3934 Expression::WatermarkColumnConstraint(e) => {
3935 self.generate_watermark_column_constraint(e)
3936 }
3937 Expression::Week(e) => self.generate_week(e),
3938 Expression::When(e) => self.generate_when(e),
3939 Expression::Whens(e) => self.generate_whens(e),
3940 Expression::Where(e) => self.generate_where(e),
3941 Expression::WidthBucket(e) => self.generate_width_bucket(e),
3942 Expression::Window(e) => self.generate_window(e),
3943 Expression::WindowSpec(e) => self.generate_window_spec(e),
3944 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
3945 Expression::WithFill(e) => self.generate_with_fill(e),
3946 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
3947 Expression::WithOperator(e) => self.generate_with_operator(e),
3948 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
3949 Expression::WithSchemaBindingProperty(e) => {
3950 self.generate_with_schema_binding_property(e)
3951 }
3952 Expression::WithSystemVersioningProperty(e) => {
3953 self.generate_with_system_versioning_property(e)
3954 }
3955 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
3956 Expression::XMLElement(e) => self.generate_xml_element(e),
3957 Expression::XMLGet(e) => self.generate_xml_get(e),
3958 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
3959 Expression::XMLTable(e) => self.generate_xml_table(e),
3960 Expression::Xor(e) => self.generate_xor(e),
3961 Expression::Zipf(e) => self.generate_zipf(e),
3962 _ => self.write_unsupported_comment("unsupported expression"),
3963 }
3964 }
3965
3966 fn generate_select(&mut self, select: &Select) -> Result<()> {
3967 use crate::dialects::DialectType;
3968
3969 if let Some(exclude) = &select.exclude {
3973 if !exclude.is_empty()
3974 && !matches!(self.config.dialect, Some(DialectType::Redshift))
3975 {
3976 let mut inner_select = select.clone();
3978 inner_select.exclude = None;
3979 let inner_expr = Expression::Select(Box::new(inner_select));
3980
3981 let subquery = crate::expressions::Subquery {
3983 this: inner_expr,
3984 alias: None,
3985 column_aliases: Vec::new(),
3986 order_by: None,
3987 limit: None,
3988 offset: None,
3989 distribute_by: None,
3990 sort_by: None,
3991 cluster_by: None,
3992 lateral: false,
3993 modifiers_inside: false,
3994 trailing_comments: Vec::new(),
3995 inferred_type: None,
3996 };
3997
3998 let star = Expression::Star(crate::expressions::Star {
4000 table: None,
4001 except: Some(
4002 exclude.iter().map(|e| {
4003 match e {
4004 Expression::Column(col) => col.name.clone(),
4005 Expression::Identifier(id) => id.clone(),
4006 _ => crate::expressions::Identifier::new("unknown".to_string()),
4007 }
4008 }).collect()
4009 ),
4010 replace: None,
4011 rename: None,
4012 trailing_comments: Vec::new(),
4013 span: None,
4014 });
4015
4016 let outer_select = Select {
4017 expressions: vec![star],
4018 from: Some(crate::expressions::From {
4019 expressions: vec![Expression::Subquery(Box::new(subquery))],
4020 }),
4021 ..Select::new()
4022 };
4023
4024 return self.generate_select(&outer_select);
4025 }
4026 }
4027
4028 for comment in &select.leading_comments {
4030 self.write_formatted_comment(comment);
4031 self.write(" ");
4032 }
4033
4034 if let Some(with) = &select.with {
4036 self.generate_with(with)?;
4037 if self.config.pretty {
4038 self.write_newline();
4039 self.write_indent();
4040 } else {
4041 self.write_space();
4042 }
4043 }
4044
4045 for comment in &select.post_select_comments {
4048 self.write_formatted_comment(comment);
4049 self.write(" ");
4050 }
4051
4052 self.write_keyword("SELECT");
4053
4054 if let Some(hint) = &select.hint {
4056 self.generate_hint(hint)?;
4057 }
4058
4059 let use_top_from_limit = matches!(self.config.dialect, Some(DialectType::TSQL))
4063 && select.top.is_none()
4064 && select.limit.is_some()
4065 && select.offset.is_none(); let is_top_dialect = matches!(
4070 self.config.dialect,
4071 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
4072 );
4073 let keep_top_verbatim = !is_top_dialect
4074 && select.limit.is_none()
4075 && select
4076 .top
4077 .as_ref()
4078 .map_or(false, |top| top.percent || top.with_ties);
4079
4080 if select.distinct && (is_top_dialect || select.top.is_some()) {
4081 self.write_space();
4082 self.write_keyword("DISTINCT");
4083 }
4084
4085 if is_top_dialect || keep_top_verbatim {
4086 if let Some(top) = &select.top {
4087 self.write_space();
4088 self.write_keyword("TOP");
4089 if top.parenthesized {
4090 self.write(" (");
4091 self.generate_expression(&top.this)?;
4092 self.write(")");
4093 } else {
4094 self.write_space();
4095 self.generate_expression(&top.this)?;
4096 }
4097 if top.percent {
4098 self.write_space();
4099 self.write_keyword("PERCENT");
4100 }
4101 if top.with_ties {
4102 self.write_space();
4103 self.write_keyword("WITH TIES");
4104 }
4105 } else if use_top_from_limit {
4106 if let Some(limit) = &select.limit {
4108 self.write_space();
4109 self.write_keyword("TOP");
4110 let is_simple_literal =
4112 matches!(&limit.this, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)));
4113 if is_simple_literal {
4114 self.write_space();
4115 self.generate_expression(&limit.this)?;
4116 } else {
4117 self.write(" (");
4118 self.generate_expression(&limit.this)?;
4119 self.write(")");
4120 }
4121 }
4122 }
4123 }
4124
4125 if select.distinct && !is_top_dialect && select.top.is_none() {
4126 self.write_space();
4127 self.write_keyword("DISTINCT");
4128 }
4129
4130 if let Some(distinct_on) = &select.distinct_on {
4132 self.write_space();
4133 self.write_keyword("ON");
4134 self.write(" (");
4135 for (i, expr) in distinct_on.iter().enumerate() {
4136 if i > 0 {
4137 self.write(", ");
4138 }
4139 self.generate_expression(expr)?;
4140 }
4141 self.write(")");
4142 }
4143
4144 for modifier in &select.operation_modifiers {
4146 self.write_space();
4147 self.write_keyword(modifier);
4148 }
4149
4150 if let Some(kind) = &select.kind {
4152 self.write_space();
4153 self.write_keyword("AS");
4154 self.write_space();
4155 self.write_keyword(kind);
4156 }
4157
4158 if !select.expressions.is_empty() {
4160 if self.config.pretty {
4161 self.write_newline();
4162 self.indent_level += 1;
4163 } else {
4164 self.write_space();
4165 }
4166 }
4167
4168 for (i, expr) in select.expressions.iter().enumerate() {
4169 if i > 0 {
4170 self.write(",");
4171 if self.config.pretty {
4172 self.write_newline();
4173 } else {
4174 self.write_space();
4175 }
4176 }
4177 if self.config.pretty {
4178 self.write_indent();
4179 }
4180 self.generate_expression(expr)?;
4181 }
4182
4183 if self.config.pretty && !select.expressions.is_empty() {
4184 self.indent_level -= 1;
4185 }
4186
4187 if let Some(exclude) = &select.exclude {
4192 if !exclude.is_empty()
4193 && matches!(
4194 self.config.dialect,
4195 Some(DialectType::Redshift)
4196 )
4197 {
4198 self.write_space();
4199 self.write_keyword("EXCLUDE");
4200 self.write(" (");
4201 for (i, col) in exclude.iter().enumerate() {
4202 if i > 0 {
4203 self.write(", ");
4204 }
4205 self.generate_expression(col)?;
4206 }
4207 self.write(")");
4208 }
4209 }
4210
4211 if let Some(into) = &select.into {
4214 if self.config.pretty {
4215 self.write_newline();
4216 self.write_indent();
4217 } else {
4218 self.write_space();
4219 }
4220 if into.bulk_collect {
4221 self.write_keyword("BULK COLLECT INTO");
4222 } else {
4223 self.write_keyword("INTO");
4224 }
4225 if into.temporary {
4226 self.write_space();
4227 self.write_keyword("TEMPORARY");
4228 }
4229 if into.unlogged {
4230 self.write_space();
4231 self.write_keyword("UNLOGGED");
4232 }
4233 self.write_space();
4234 if !into.expressions.is_empty() {
4236 for (i, expr) in into.expressions.iter().enumerate() {
4237 if i > 0 {
4238 self.write(", ");
4239 }
4240 self.generate_expression(expr)?;
4241 }
4242 } else {
4243 self.generate_expression(&into.this)?;
4244 }
4245 }
4246
4247 if let Some(from) = &select.from {
4249 if self.config.pretty {
4250 self.write_newline();
4251 self.write_indent();
4252 } else {
4253 self.write_space();
4254 }
4255 self.write_keyword("FROM");
4256 self.write_space();
4257
4258 let has_tablesample = from
4263 .expressions
4264 .iter()
4265 .any(|e| matches!(e, Expression::TableSample(_)));
4266 let is_cross_join_dialect = matches!(
4267 self.config.dialect,
4268 Some(DialectType::BigQuery)
4269 | Some(DialectType::Hive)
4270 | Some(DialectType::Spark)
4271 | Some(DialectType::Databricks)
4272 | Some(DialectType::SQLite)
4273 | Some(DialectType::ClickHouse)
4274 );
4275 let source_is_same_as_target = self.config.source_dialect.is_some()
4278 && self.config.source_dialect == self.config.dialect;
4279 let source_is_cross_join_dialect = matches!(
4280 self.config.source_dialect,
4281 Some(DialectType::BigQuery)
4282 | Some(DialectType::Hive)
4283 | Some(DialectType::Spark)
4284 | Some(DialectType::Databricks)
4285 | Some(DialectType::SQLite)
4286 | Some(DialectType::ClickHouse)
4287 );
4288 let use_cross_join = !has_tablesample
4289 && is_cross_join_dialect
4290 && (source_is_same_as_target
4291 || source_is_cross_join_dialect
4292 || self.config.source_dialect.is_none());
4293
4294 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4296
4297 for (i, expr) in from.expressions.iter().enumerate() {
4298 if i > 0 {
4299 if use_cross_join {
4300 self.write(" CROSS JOIN ");
4301 } else {
4302 self.write(", ");
4303 }
4304 }
4305 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4306 self.write("(");
4307 self.generate_expression(expr)?;
4308 self.write(")");
4309 } else {
4310 self.generate_expression(expr)?;
4311 }
4312 }
4313 }
4314
4315 if self.config.pretty {
4319 self.generate_joins_with_nesting(&select.joins)?;
4320 } else {
4321 for join in &select.joins {
4322 self.generate_join(join)?;
4323 }
4324 for join in select.joins.iter().rev() {
4326 if join.deferred_condition {
4327 self.generate_join_condition(join)?;
4328 }
4329 }
4330 }
4331
4332 for (lv_idx, lateral_view) in select.lateral_views.iter().enumerate() {
4334 self.generate_lateral_view(lateral_view, lv_idx)?;
4335 }
4336
4337 if let Some(prewhere) = &select.prewhere {
4339 self.write_clause_condition("PREWHERE", prewhere)?;
4340 }
4341
4342 if let Some(where_clause) = &select.where_clause {
4344 self.write_clause_condition("WHERE", &where_clause.this)?;
4345 }
4346
4347 if let Some(connect) = &select.connect {
4349 self.generate_connect(connect)?;
4350 }
4351
4352 if let Some(group_by) = &select.group_by {
4354 if self.config.pretty {
4355 for comment in &group_by.comments {
4357 self.write_newline();
4358 self.write_indent();
4359 self.write_formatted_comment(comment);
4360 }
4361 self.write_newline();
4362 self.write_indent();
4363 } else {
4364 self.write_space();
4365 for comment in &group_by.comments {
4367 self.write_formatted_comment(comment);
4368 self.write_space();
4369 }
4370 }
4371 self.write_keyword("GROUP BY");
4372 match group_by.all {
4374 Some(true) => {
4375 self.write_space();
4376 self.write_keyword("ALL");
4377 }
4378 Some(false) => {
4379 self.write_space();
4380 self.write_keyword("DISTINCT");
4381 }
4382 None => {}
4383 }
4384 if !group_by.expressions.is_empty() {
4385 let mut trailing_cube = false;
4388 let mut trailing_rollup = false;
4389 let mut plain_expressions: Vec<&Expression> = Vec::new();
4390 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4391 let mut cube_expressions: Vec<&Expression> = Vec::new();
4392 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4393
4394 for expr in &group_by.expressions {
4395 match expr {
4396 Expression::Cube(c) if c.expressions.is_empty() => {
4397 trailing_cube = true;
4398 }
4399 Expression::Rollup(r) if r.expressions.is_empty() => {
4400 trailing_rollup = true;
4401 }
4402 Expression::Function(f) if f.name == "CUBE" => {
4403 cube_expressions.push(expr);
4404 }
4405 Expression::Function(f) if f.name == "ROLLUP" => {
4406 rollup_expressions.push(expr);
4407 }
4408 Expression::Function(f) if f.name == "GROUPING SETS" => {
4409 grouping_sets_expressions.push(expr);
4410 }
4411 _ => {
4412 plain_expressions.push(expr);
4413 }
4414 }
4415 }
4416
4417 let mut regular_expressions: Vec<&Expression> = Vec::new();
4419 regular_expressions.extend(plain_expressions);
4420 regular_expressions.extend(grouping_sets_expressions);
4421 regular_expressions.extend(cube_expressions);
4422 regular_expressions.extend(rollup_expressions);
4423
4424 if self.config.pretty {
4425 self.write_newline();
4426 self.indent_level += 1;
4427 self.write_indent();
4428 } else {
4429 self.write_space();
4430 }
4431
4432 for (i, expr) in regular_expressions.iter().enumerate() {
4433 if i > 0 {
4434 if self.config.pretty {
4435 self.write(",");
4436 self.write_newline();
4437 self.write_indent();
4438 } else {
4439 self.write(", ");
4440 }
4441 }
4442 self.generate_expression(expr)?;
4443 }
4444
4445 if self.config.pretty {
4446 self.indent_level -= 1;
4447 }
4448
4449 if trailing_cube {
4451 self.write_space();
4452 self.write_keyword("WITH CUBE");
4453 } else if trailing_rollup {
4454 self.write_space();
4455 self.write_keyword("WITH ROLLUP");
4456 }
4457 }
4458
4459 if group_by.totals {
4461 self.write_space();
4462 self.write_keyword("WITH TOTALS");
4463 }
4464 }
4465
4466 if let Some(having) = &select.having {
4468 if self.config.pretty {
4469 for comment in &having.comments {
4471 self.write_newline();
4472 self.write_indent();
4473 self.write_formatted_comment(comment);
4474 }
4475 } else {
4476 for comment in &having.comments {
4477 self.write_space();
4478 self.write_formatted_comment(comment);
4479 }
4480 }
4481 self.write_clause_condition("HAVING", &having.this)?;
4482 }
4483
4484 if select.qualify_after_window {
4486 if let Some(windows) = &select.windows {
4488 self.write_window_clause(windows)?;
4489 }
4490 if let Some(qualify) = &select.qualify {
4491 self.write_clause_condition("QUALIFY", &qualify.this)?;
4492 }
4493 } else {
4494 if let Some(qualify) = &select.qualify {
4496 self.write_clause_condition("QUALIFY", &qualify.this)?;
4497 }
4498 if let Some(windows) = &select.windows {
4499 self.write_window_clause(windows)?;
4500 }
4501 }
4502
4503 if let Some(distribute_by) = &select.distribute_by {
4505 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4506 }
4507
4508 if let Some(cluster_by) = &select.cluster_by {
4510 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4511 }
4512
4513 if let Some(sort_by) = &select.sort_by {
4515 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4516 }
4517
4518 if let Some(order_by) = &select.order_by {
4520 if self.config.pretty {
4521 for comment in &order_by.comments {
4523 self.write_newline();
4524 self.write_indent();
4525 self.write_formatted_comment(comment);
4526 }
4527 } else {
4528 for comment in &order_by.comments {
4529 self.write_space();
4530 self.write_formatted_comment(comment);
4531 }
4532 }
4533 let keyword = if order_by.siblings {
4534 "ORDER SIBLINGS BY"
4535 } else {
4536 "ORDER BY"
4537 };
4538 self.write_order_clause(keyword, &order_by.expressions)?;
4539 }
4540
4541 if select.order_by.is_none()
4543 && select.fetch.is_some()
4544 && matches!(
4545 self.config.dialect,
4546 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4547 )
4548 {
4549 if self.config.pretty {
4550 self.write_newline();
4551 self.write_indent();
4552 } else {
4553 self.write_space();
4554 }
4555 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4556 }
4557
4558 let is_presto_like = matches!(
4563 self.config.dialect,
4564 Some(DialectType::Presto) | Some(DialectType::Trino)
4565 );
4566
4567 if is_presto_like && select.offset.is_some() {
4568 if let Some(offset) = &select.offset {
4570 if self.config.pretty {
4571 self.write_newline();
4572 self.write_indent();
4573 } else {
4574 self.write_space();
4575 }
4576 self.write_keyword("OFFSET");
4577 self.write_space();
4578 self.write_limit_expr(&offset.this)?;
4579 if offset.rows == Some(true) {
4580 self.write_space();
4581 self.write_keyword("ROWS");
4582 }
4583 }
4584 if let Some(limit) = &select.limit {
4585 if self.config.pretty {
4586 self.write_newline();
4587 self.write_indent();
4588 } else {
4589 self.write_space();
4590 }
4591 self.write_keyword("LIMIT");
4592 self.write_space();
4593 self.write_limit_expr(&limit.this)?;
4594 if limit.percent {
4595 self.write_space();
4596 self.write_keyword("PERCENT");
4597 }
4598 for comment in &limit.comments {
4600 self.write(" ");
4601 self.write_formatted_comment(comment);
4602 }
4603 }
4604 } else {
4605 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
4607 !fetch.percent
4608 && !fetch.with_ties
4609 && fetch.count.is_some()
4610 && matches!(
4611 self.config.dialect,
4612 Some(DialectType::Spark)
4613 | Some(DialectType::Hive)
4614 | Some(DialectType::DuckDB)
4615 | Some(DialectType::SQLite)
4616 | Some(DialectType::MySQL)
4617 | Some(DialectType::BigQuery)
4618 | Some(DialectType::Databricks)
4619 | Some(DialectType::StarRocks)
4620 | Some(DialectType::Doris)
4621 | Some(DialectType::Athena)
4622 | Some(DialectType::ClickHouse)
4623 | Some(DialectType::Redshift)
4624 )
4625 });
4626
4627 if let Some(limit) = &select.limit {
4629 if !matches!(self.config.dialect, Some(DialectType::TSQL)) {
4631 if self.config.pretty {
4632 self.write_newline();
4633 self.write_indent();
4634 } else {
4635 self.write_space();
4636 }
4637 self.write_keyword("LIMIT");
4638 self.write_space();
4639 self.write_limit_expr(&limit.this)?;
4640 if limit.percent {
4641 self.write_space();
4642 self.write_keyword("PERCENT");
4643 }
4644 for comment in &limit.comments {
4646 self.write(" ");
4647 self.write_formatted_comment(comment);
4648 }
4649 }
4650 }
4651
4652 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
4654 if let Some(top) = &select.top {
4655 if !top.percent && !top.with_ties {
4656 if self.config.pretty {
4657 self.write_newline();
4658 self.write_indent();
4659 } else {
4660 self.write_space();
4661 }
4662 self.write_keyword("LIMIT");
4663 self.write_space();
4664 self.generate_expression(&top.this)?;
4665 }
4666 }
4667 }
4668
4669 if fetch_as_limit && select.offset.is_some() {
4672 if let Some(fetch) = &select.fetch {
4673 if self.config.pretty {
4674 self.write_newline();
4675 self.write_indent();
4676 } else {
4677 self.write_space();
4678 }
4679 self.write_keyword("LIMIT");
4680 self.write_space();
4681 self.generate_expression(fetch.count.as_ref().unwrap())?;
4682 }
4683 }
4684
4685 if let Some(offset) = &select.offset {
4689 if self.config.pretty {
4690 self.write_newline();
4691 self.write_indent();
4692 } else {
4693 self.write_space();
4694 }
4695 if matches!(self.config.dialect, Some(DialectType::TSQL)) {
4696 self.write_keyword("OFFSET");
4698 self.write_space();
4699 self.write_limit_expr(&offset.this)?;
4700 self.write_space();
4701 self.write_keyword("ROWS");
4702 if let Some(limit) = &select.limit {
4704 self.write_space();
4705 self.write_keyword("FETCH NEXT");
4706 self.write_space();
4707 self.write_limit_expr(&limit.this)?;
4708 self.write_space();
4709 self.write_keyword("ROWS ONLY");
4710 }
4711 } else {
4712 self.write_keyword("OFFSET");
4713 self.write_space();
4714 self.write_limit_expr(&offset.this)?;
4715 if offset.rows == Some(true) {
4717 self.write_space();
4718 self.write_keyword("ROWS");
4719 }
4720 }
4721 }
4722 }
4723
4724 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4726 if let Some(limit_by) = &select.limit_by {
4727 if !limit_by.is_empty() {
4728 self.write_space();
4729 self.write_keyword("BY");
4730 self.write_space();
4731 for (i, expr) in limit_by.iter().enumerate() {
4732 if i > 0 {
4733 self.write(", ");
4734 }
4735 self.generate_expression(expr)?;
4736 }
4737 }
4738 }
4739 }
4740
4741 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4743 if let Some(settings) = &select.settings {
4744 if self.config.pretty {
4745 self.write_newline();
4746 self.write_indent();
4747 } else {
4748 self.write_space();
4749 }
4750 self.write_keyword("SETTINGS");
4751 self.write_space();
4752 for (i, expr) in settings.iter().enumerate() {
4753 if i > 0 {
4754 self.write(", ");
4755 }
4756 self.generate_expression(expr)?;
4757 }
4758 }
4759
4760 if let Some(format_expr) = &select.format {
4761 if self.config.pretty {
4762 self.write_newline();
4763 self.write_indent();
4764 } else {
4765 self.write_space();
4766 }
4767 self.write_keyword("FORMAT");
4768 self.write_space();
4769 self.generate_expression(format_expr)?;
4770 }
4771 }
4772
4773 if let Some(fetch) = &select.fetch {
4775 let fetch_already_as_limit = select.offset.is_some()
4777 && !fetch.percent
4778 && !fetch.with_ties
4779 && fetch.count.is_some()
4780 && matches!(
4781 self.config.dialect,
4782 Some(DialectType::Spark)
4783 | Some(DialectType::Hive)
4784 | Some(DialectType::DuckDB)
4785 | Some(DialectType::SQLite)
4786 | Some(DialectType::MySQL)
4787 | Some(DialectType::BigQuery)
4788 | Some(DialectType::Databricks)
4789 | Some(DialectType::StarRocks)
4790 | Some(DialectType::Doris)
4791 | Some(DialectType::Athena)
4792 | Some(DialectType::ClickHouse)
4793 | Some(DialectType::Redshift)
4794 );
4795
4796 if fetch_already_as_limit {
4797 } else {
4799 if self.config.pretty {
4800 self.write_newline();
4801 self.write_indent();
4802 } else {
4803 self.write_space();
4804 }
4805
4806 let use_limit = !fetch.percent
4808 && !fetch.with_ties
4809 && fetch.count.is_some()
4810 && matches!(
4811 self.config.dialect,
4812 Some(DialectType::Spark)
4813 | Some(DialectType::Hive)
4814 | Some(DialectType::DuckDB)
4815 | Some(DialectType::SQLite)
4816 | Some(DialectType::MySQL)
4817 | Some(DialectType::BigQuery)
4818 | Some(DialectType::Databricks)
4819 | Some(DialectType::StarRocks)
4820 | Some(DialectType::Doris)
4821 | Some(DialectType::Athena)
4822 | Some(DialectType::ClickHouse)
4823 | Some(DialectType::Redshift)
4824 );
4825
4826 if use_limit {
4827 self.write_keyword("LIMIT");
4828 self.write_space();
4829 self.generate_expression(fetch.count.as_ref().unwrap())?;
4830 } else {
4831 self.write_keyword("FETCH");
4832 self.write_space();
4833 self.write_keyword(&fetch.direction);
4834 if let Some(ref count) = fetch.count {
4835 self.write_space();
4836 self.generate_expression(count)?;
4837 }
4838 if fetch.percent {
4839 self.write_space();
4840 self.write_keyword("PERCENT");
4841 }
4842 if fetch.rows {
4843 self.write_space();
4844 self.write_keyword("ROWS");
4845 }
4846 if fetch.with_ties {
4847 self.write_space();
4848 self.write_keyword("WITH TIES");
4849 } else {
4850 self.write_space();
4851 self.write_keyword("ONLY");
4852 }
4853 }
4854 } }
4856
4857 if let Some(sample) = &select.sample {
4859 use crate::dialects::DialectType;
4860 if self.config.pretty {
4861 self.write_newline();
4862 } else {
4863 self.write_space();
4864 }
4865
4866 if sample.is_using_sample {
4867 self.write_keyword("USING SAMPLE");
4869 self.generate_sample_body(sample)?;
4870 } else {
4871 self.write_keyword("TABLESAMPLE");
4872
4873 let snowflake_bernoulli =
4875 matches!(self.config.dialect, Some(DialectType::Snowflake))
4876 && !sample.explicit_method;
4877 if snowflake_bernoulli {
4878 self.write_space();
4879 self.write_keyword("BERNOULLI");
4880 }
4881
4882 if matches!(sample.method, SampleMethod::Bucket) {
4884 self.write_space();
4885 self.write("(");
4886 self.write_keyword("BUCKET");
4887 self.write_space();
4888 if let Some(ref num) = sample.bucket_numerator {
4889 self.generate_expression(num)?;
4890 }
4891 self.write_space();
4892 self.write_keyword("OUT OF");
4893 self.write_space();
4894 if let Some(ref denom) = sample.bucket_denominator {
4895 self.generate_expression(denom)?;
4896 }
4897 if let Some(ref field) = sample.bucket_field {
4898 self.write_space();
4899 self.write_keyword("ON");
4900 self.write_space();
4901 self.generate_expression(field)?;
4902 }
4903 self.write(")");
4904 } else if sample.unit_after_size {
4905 if sample.explicit_method && sample.method_before_size {
4907 self.write_space();
4908 match sample.method {
4909 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4910 SampleMethod::System => self.write_keyword("SYSTEM"),
4911 SampleMethod::Block => self.write_keyword("BLOCK"),
4912 SampleMethod::Row => self.write_keyword("ROW"),
4913 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4914 _ => {}
4915 }
4916 }
4917 self.write(" (");
4918 self.generate_expression(&sample.size)?;
4919 self.write_space();
4920 match sample.method {
4921 SampleMethod::Percent => self.write_keyword("PERCENT"),
4922 SampleMethod::Row => self.write_keyword("ROWS"),
4923 SampleMethod::Reservoir => self.write_keyword("ROWS"),
4924 _ => {
4925 self.write_keyword("PERCENT");
4926 }
4927 }
4928 self.write(")");
4929 } else {
4930 self.write_space();
4932 match sample.method {
4933 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4934 SampleMethod::System => self.write_keyword("SYSTEM"),
4935 SampleMethod::Block => self.write_keyword("BLOCK"),
4936 SampleMethod::Row => self.write_keyword("ROW"),
4937 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
4938 SampleMethod::Bucket => {}
4939 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4940 }
4941 self.write(" (");
4942 self.generate_expression(&sample.size)?;
4943 if matches!(sample.method, SampleMethod::Percent) {
4944 self.write_space();
4945 self.write_keyword("PERCENT");
4946 }
4947 self.write(")");
4948 }
4949 }
4950
4951 if let Some(seed) = &sample.seed {
4952 self.write_space();
4953 let use_seed = sample.use_seed_keyword
4955 && !matches!(
4956 self.config.dialect,
4957 Some(crate::dialects::DialectType::Databricks)
4958 | Some(crate::dialects::DialectType::Spark)
4959 );
4960 if use_seed {
4961 self.write_keyword("SEED");
4962 } else {
4963 self.write_keyword("REPEATABLE");
4964 }
4965 self.write(" (");
4966 self.generate_expression(seed)?;
4967 self.write(")");
4968 }
4969 }
4970
4971 if self.config.locking_reads_supported {
4974 for lock in &select.locks {
4975 if self.config.pretty {
4976 self.write_newline();
4977 self.write_indent();
4978 } else {
4979 self.write_space();
4980 }
4981 self.generate_lock(lock)?;
4982 }
4983 }
4984
4985 if !select.for_xml.is_empty() {
4987 if self.config.pretty {
4988 self.write_newline();
4989 self.write_indent();
4990 } else {
4991 self.write_space();
4992 }
4993 self.write_keyword("FOR XML");
4994 for (i, opt) in select.for_xml.iter().enumerate() {
4995 if self.config.pretty {
4996 if i > 0 {
4997 self.write(",");
4998 }
4999 self.write_newline();
5000 self.write_indent();
5001 self.write(" "); } else {
5003 if i > 0 {
5004 self.write(",");
5005 }
5006 self.write_space();
5007 }
5008 self.generate_for_xml_option(opt)?;
5009 }
5010 }
5011
5012 if let Some(ref option) = select.option {
5014 if matches!(
5015 self.config.dialect,
5016 Some(crate::dialects::DialectType::TSQL)
5017 | Some(crate::dialects::DialectType::Fabric)
5018 ) {
5019 self.write_space();
5020 self.write(option);
5021 }
5022 }
5023
5024 Ok(())
5025 }
5026
5027 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
5029 match opt {
5030 Expression::QueryOption(qo) => {
5031 if let Expression::Var(var) = &*qo.this {
5033 self.write(&var.this);
5034 } else {
5035 self.generate_expression(&qo.this)?;
5036 }
5037 if let Some(expr) = &qo.expression {
5039 self.write("(");
5040 self.generate_expression(expr)?;
5041 self.write(")");
5042 }
5043 }
5044 _ => {
5045 self.generate_expression(opt)?;
5046 }
5047 }
5048 Ok(())
5049 }
5050
5051 fn generate_with(&mut self, with: &With) -> Result<()> {
5052 use crate::dialects::DialectType;
5053
5054 for comment in &with.leading_comments {
5056 self.write_formatted_comment(comment);
5057 self.write(" ");
5058 }
5059 self.write_keyword("WITH");
5060 if with.recursive && self.config.cte_recursive_keyword_required {
5061 self.write_space();
5062 self.write_keyword("RECURSIVE");
5063 }
5064 self.write_space();
5065
5066 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
5068
5069 for (i, cte) in with.ctes.iter().enumerate() {
5070 if i > 0 {
5071 self.write(",");
5072 if self.config.pretty {
5073 self.write_space();
5074 } else {
5075 self.write(" ");
5076 }
5077 }
5078 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
5079 self.generate_expression(&cte.this)?;
5080 self.write_space();
5081 self.write_keyword("AS");
5082 self.write_space();
5083 self.generate_identifier(&cte.alias)?;
5084 continue;
5085 }
5086 self.generate_identifier(&cte.alias)?;
5087 for comment in &cte.comments {
5089 self.write_space();
5090 self.write_formatted_comment(comment);
5091 }
5092 if !cte.columns.is_empty() && !skip_cte_columns {
5093 self.write("(");
5094 for (j, col) in cte.columns.iter().enumerate() {
5095 if j > 0 {
5096 self.write(", ");
5097 }
5098 self.generate_identifier(col)?;
5099 }
5100 self.write(")");
5101 }
5102 if !cte.key_expressions.is_empty() {
5104 self.write_space();
5105 self.write_keyword("USING KEY");
5106 self.write(" (");
5107 for (i, key) in cte.key_expressions.iter().enumerate() {
5108 if i > 0 {
5109 self.write(", ");
5110 }
5111 self.generate_identifier(key)?;
5112 }
5113 self.write(")");
5114 }
5115 self.write_space();
5116 self.write_keyword("AS");
5117 if let Some(materialized) = cte.materialized {
5119 self.write_space();
5120 if materialized {
5121 self.write_keyword("MATERIALIZED");
5122 } else {
5123 self.write_keyword("NOT MATERIALIZED");
5124 }
5125 }
5126 self.write(" (");
5127 if self.config.pretty {
5128 self.write_newline();
5129 self.indent_level += 1;
5130 self.write_indent();
5131 }
5132 let wrap_values_in_select = matches!(
5135 self.config.dialect,
5136 Some(DialectType::Spark) | Some(DialectType::Databricks)
5137 ) && matches!(&cte.this, Expression::Values(_));
5138
5139 if wrap_values_in_select {
5140 self.write_keyword("SELECT");
5141 self.write(" * ");
5142 self.write_keyword("FROM");
5143 self.write_space();
5144 }
5145 self.generate_expression(&cte.this)?;
5146 if self.config.pretty {
5147 self.write_newline();
5148 self.indent_level -= 1;
5149 self.write_indent();
5150 }
5151 self.write(")");
5152 }
5153
5154 if let Some(search) = &with.search {
5156 self.write_space();
5157 self.generate_expression(search)?;
5158 }
5159
5160 Ok(())
5161 }
5162
5163 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
5167 let mut i = 0;
5168 while i < joins.len() {
5169 if joins[i].deferred_condition {
5170 let parent_group = joins[i].nesting_group;
5171
5172 self.generate_join_without_condition(&joins[i])?;
5175
5176 let child_start = i + 1;
5178 let mut child_end = child_start;
5179 while child_end < joins.len()
5180 && !joins[child_end].deferred_condition
5181 && joins[child_end].nesting_group == parent_group
5182 {
5183 child_end += 1;
5184 }
5185
5186 if child_start < child_end {
5188 self.indent_level += 1;
5189 for j in child_start..child_end {
5190 self.generate_join(&joins[j])?;
5191 }
5192 self.indent_level -= 1;
5193 }
5194
5195 self.generate_join_condition(&joins[i])?;
5197
5198 i = child_end;
5199 } else {
5200 self.generate_join(&joins[i])?;
5202 i += 1;
5203 }
5204 }
5205 Ok(())
5206 }
5207
5208 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5211 let mut join_copy = join.clone();
5214 join_copy.on = None;
5215 join_copy.using = Vec::new();
5216 join_copy.deferred_condition = false;
5217 self.generate_join(&join_copy)
5218 }
5219
5220 fn generate_join(&mut self, join: &Join) -> Result<()> {
5221 if join.kind == JoinKind::Implicit {
5223 self.write(",");
5224 if self.config.pretty {
5225 self.write_newline();
5226 self.write_indent();
5227 } else {
5228 self.write_space();
5229 }
5230 self.generate_expression(&join.this)?;
5231 return Ok(());
5232 }
5233
5234 if self.config.pretty {
5235 self.write_newline();
5236 self.write_indent();
5237 } else {
5238 self.write_space();
5239 }
5240
5241 let hint_str = if self.config.join_hints {
5244 join.join_hint
5245 .as_ref()
5246 .map(|h| format!(" {}", h))
5247 .unwrap_or_default()
5248 } else {
5249 String::new()
5250 };
5251
5252 let clickhouse_join_keyword =
5253 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5254 if let Some(hint) = &join.join_hint {
5255 let mut global = false;
5256 let mut strictness: Option<&'static str> = None;
5257 for part in hint.split_whitespace() {
5258 if part.eq_ignore_ascii_case("GLOBAL") {
5259 global = true;
5260 } else if part.eq_ignore_ascii_case("ANY") {
5261 strictness = Some("ANY");
5262 } else if part.eq_ignore_ascii_case("ASOF") {
5263 strictness = Some("ASOF");
5264 } else if part.eq_ignore_ascii_case("SEMI") {
5265 strictness = Some("SEMI");
5266 } else if part.eq_ignore_ascii_case("ANTI") {
5267 strictness = Some("ANTI");
5268 }
5269 }
5270
5271 if global || strictness.is_some() {
5272 let join_type = match join.kind {
5273 JoinKind::Left => {
5274 if join.use_outer_keyword {
5275 "LEFT OUTER"
5276 } else if join.use_inner_keyword {
5277 "LEFT INNER"
5278 } else {
5279 "LEFT"
5280 }
5281 }
5282 JoinKind::Right => {
5283 if join.use_outer_keyword {
5284 "RIGHT OUTER"
5285 } else if join.use_inner_keyword {
5286 "RIGHT INNER"
5287 } else {
5288 "RIGHT"
5289 }
5290 }
5291 JoinKind::Full => {
5292 if join.use_outer_keyword {
5293 "FULL OUTER"
5294 } else {
5295 "FULL"
5296 }
5297 }
5298 JoinKind::Inner => {
5299 if join.use_inner_keyword {
5300 "INNER"
5301 } else {
5302 ""
5303 }
5304 }
5305 _ => "",
5306 };
5307
5308 let mut parts = Vec::new();
5309 if global {
5310 parts.push("GLOBAL");
5311 }
5312 if !join_type.is_empty() {
5313 parts.push(join_type);
5314 }
5315 if let Some(strict) = strictness {
5316 parts.push(strict);
5317 }
5318 parts.push("JOIN");
5319 Some(parts.join(" "))
5320 } else {
5321 None
5322 }
5323 } else {
5324 None
5325 }
5326 } else {
5327 None
5328 };
5329
5330 if !join.comments.is_empty() {
5334 if self.config.pretty {
5335 let trimmed = self.output.trim_end().len();
5340 self.output.truncate(trimmed);
5341 for comment in &join.comments {
5342 self.write_newline();
5343 self.write_indent();
5344 self.write_formatted_comment(comment);
5345 }
5346 self.write_newline();
5347 self.write_indent();
5348 } else {
5349 for comment in &join.comments {
5350 self.write_formatted_comment(comment);
5351 self.write_space();
5352 }
5353 }
5354 }
5355
5356 let directed_str = if join.directed { " DIRECTED" } else { "" };
5357
5358 if let Some(keyword) = clickhouse_join_keyword {
5359 self.write_keyword(&keyword);
5360 } else {
5361 match join.kind {
5362 JoinKind::Inner => {
5363 if join.use_inner_keyword {
5364 if hint_str.is_empty() && directed_str.is_empty() {
5365 self.write_keyword("INNER JOIN");
5366 } else {
5367 self.write_keyword("INNER");
5368 if !hint_str.is_empty() { self.write_keyword(&hint_str); }
5369 if !directed_str.is_empty() { self.write_keyword(directed_str); }
5370 self.write_keyword(" JOIN");
5371 }
5372 } else {
5373 if !hint_str.is_empty() {
5374 self.write_keyword(hint_str.trim());
5375 self.write_keyword(" ");
5376 }
5377 if !directed_str.is_empty() {
5378 self.write_keyword("DIRECTED ");
5379 }
5380 self.write_keyword("JOIN");
5381 }
5382 }
5383 JoinKind::Left => {
5384 if join.use_outer_keyword {
5385 if hint_str.is_empty() && directed_str.is_empty() {
5386 self.write_keyword("LEFT OUTER JOIN");
5387 } else {
5388 self.write_keyword("LEFT OUTER");
5389 if !hint_str.is_empty() { self.write_keyword(&hint_str); }
5390 if !directed_str.is_empty() { self.write_keyword(directed_str); }
5391 self.write_keyword(" JOIN");
5392 }
5393 } else if join.use_inner_keyword {
5394 if hint_str.is_empty() && directed_str.is_empty() {
5395 self.write_keyword("LEFT INNER JOIN");
5396 } else {
5397 self.write_keyword("LEFT INNER");
5398 if !hint_str.is_empty() { self.write_keyword(&hint_str); }
5399 if !directed_str.is_empty() { self.write_keyword(directed_str); }
5400 self.write_keyword(" JOIN");
5401 }
5402 } else {
5403 if hint_str.is_empty() && directed_str.is_empty() {
5404 self.write_keyword("LEFT JOIN");
5405 } else {
5406 self.write_keyword("LEFT");
5407 if !hint_str.is_empty() { self.write_keyword(&hint_str); }
5408 if !directed_str.is_empty() { self.write_keyword(directed_str); }
5409 self.write_keyword(" JOIN");
5410 }
5411 }
5412 }
5413 JoinKind::Right => {
5414 if join.use_outer_keyword {
5415 if hint_str.is_empty() && directed_str.is_empty() {
5416 self.write_keyword("RIGHT OUTER JOIN");
5417 } else {
5418 self.write_keyword("RIGHT OUTER");
5419 if !hint_str.is_empty() { self.write_keyword(&hint_str); }
5420 if !directed_str.is_empty() { self.write_keyword(directed_str); }
5421 self.write_keyword(" JOIN");
5422 }
5423 } else if join.use_inner_keyword {
5424 if hint_str.is_empty() && directed_str.is_empty() {
5425 self.write_keyword("RIGHT INNER JOIN");
5426 } else {
5427 self.write_keyword("RIGHT INNER");
5428 if !hint_str.is_empty() { self.write_keyword(&hint_str); }
5429 if !directed_str.is_empty() { self.write_keyword(directed_str); }
5430 self.write_keyword(" JOIN");
5431 }
5432 } else {
5433 if hint_str.is_empty() && directed_str.is_empty() {
5434 self.write_keyword("RIGHT JOIN");
5435 } else {
5436 self.write_keyword("RIGHT");
5437 if !hint_str.is_empty() { self.write_keyword(&hint_str); }
5438 if !directed_str.is_empty() { self.write_keyword(directed_str); }
5439 self.write_keyword(" JOIN");
5440 }
5441 }
5442 }
5443 JoinKind::Full => {
5444 if join.use_outer_keyword {
5445 if hint_str.is_empty() && directed_str.is_empty() {
5446 self.write_keyword("FULL OUTER JOIN");
5447 } else {
5448 self.write_keyword("FULL OUTER");
5449 if !hint_str.is_empty() { self.write_keyword(&hint_str); }
5450 if !directed_str.is_empty() { self.write_keyword(directed_str); }
5451 self.write_keyword(" JOIN");
5452 }
5453 } else {
5454 if hint_str.is_empty() && directed_str.is_empty() {
5455 self.write_keyword("FULL JOIN");
5456 } else {
5457 self.write_keyword("FULL");
5458 if !hint_str.is_empty() { self.write_keyword(&hint_str); }
5459 if !directed_str.is_empty() { self.write_keyword(directed_str); }
5460 self.write_keyword(" JOIN");
5461 }
5462 }
5463 }
5464 JoinKind::Outer => {
5465 if directed_str.is_empty() {
5466 self.write_keyword("OUTER JOIN");
5467 } else {
5468 self.write_keyword("OUTER");
5469 self.write_keyword(directed_str);
5470 self.write_keyword(" JOIN");
5471 }
5472 }
5473 JoinKind::Cross => {
5474 if directed_str.is_empty() {
5475 self.write_keyword("CROSS JOIN");
5476 } else {
5477 self.write_keyword("CROSS");
5478 self.write_keyword(directed_str);
5479 self.write_keyword(" JOIN");
5480 }
5481 }
5482 JoinKind::Natural => {
5483 if join.use_inner_keyword {
5484 if directed_str.is_empty() {
5485 self.write_keyword("NATURAL INNER JOIN");
5486 } else {
5487 self.write_keyword("NATURAL INNER");
5488 self.write_keyword(directed_str);
5489 self.write_keyword(" JOIN");
5490 }
5491 } else {
5492 if directed_str.is_empty() {
5493 self.write_keyword("NATURAL JOIN");
5494 } else {
5495 self.write_keyword("NATURAL");
5496 self.write_keyword(directed_str);
5497 self.write_keyword(" JOIN");
5498 }
5499 }
5500 }
5501 JoinKind::NaturalLeft => {
5502 if join.use_outer_keyword {
5503 if directed_str.is_empty() {
5504 self.write_keyword("NATURAL LEFT OUTER JOIN");
5505 } else {
5506 self.write_keyword("NATURAL LEFT OUTER");
5507 self.write_keyword(directed_str);
5508 self.write_keyword(" JOIN");
5509 }
5510 } else {
5511 if directed_str.is_empty() {
5512 self.write_keyword("NATURAL LEFT JOIN");
5513 } else {
5514 self.write_keyword("NATURAL LEFT");
5515 self.write_keyword(directed_str);
5516 self.write_keyword(" JOIN");
5517 }
5518 }
5519 }
5520 JoinKind::NaturalRight => {
5521 if join.use_outer_keyword {
5522 if directed_str.is_empty() {
5523 self.write_keyword("NATURAL RIGHT OUTER JOIN");
5524 } else {
5525 self.write_keyword("NATURAL RIGHT OUTER");
5526 self.write_keyword(directed_str);
5527 self.write_keyword(" JOIN");
5528 }
5529 } else {
5530 if directed_str.is_empty() {
5531 self.write_keyword("NATURAL RIGHT JOIN");
5532 } else {
5533 self.write_keyword("NATURAL RIGHT");
5534 self.write_keyword(directed_str);
5535 self.write_keyword(" JOIN");
5536 }
5537 }
5538 }
5539 JoinKind::NaturalFull => {
5540 if join.use_outer_keyword {
5541 if directed_str.is_empty() {
5542 self.write_keyword("NATURAL FULL OUTER JOIN");
5543 } else {
5544 self.write_keyword("NATURAL FULL OUTER");
5545 self.write_keyword(directed_str);
5546 self.write_keyword(" JOIN");
5547 }
5548 } else {
5549 if directed_str.is_empty() {
5550 self.write_keyword("NATURAL FULL JOIN");
5551 } else {
5552 self.write_keyword("NATURAL FULL");
5553 self.write_keyword(directed_str);
5554 self.write_keyword(" JOIN");
5555 }
5556 }
5557 }
5558 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
5559 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
5560 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
5561 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
5562 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
5563 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
5564 JoinKind::CrossApply => {
5565 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5567 self.write_keyword("CROSS APPLY");
5568 } else {
5569 self.write_keyword("INNER JOIN LATERAL");
5570 }
5571 }
5572 JoinKind::OuterApply => {
5573 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5575 self.write_keyword("OUTER APPLY");
5576 } else {
5577 self.write_keyword("LEFT JOIN LATERAL");
5578 }
5579 }
5580 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
5581 JoinKind::AsOfLeft => {
5582 if join.use_outer_keyword {
5583 self.write_keyword("ASOF LEFT OUTER JOIN");
5584 } else {
5585 self.write_keyword("ASOF LEFT JOIN");
5586 }
5587 }
5588 JoinKind::AsOfRight => {
5589 if join.use_outer_keyword {
5590 self.write_keyword("ASOF RIGHT OUTER JOIN");
5591 } else {
5592 self.write_keyword("ASOF RIGHT JOIN");
5593 }
5594 }
5595 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
5596 JoinKind::LeftLateral => {
5597 if join.use_outer_keyword {
5598 self.write_keyword("LEFT OUTER LATERAL JOIN");
5599 } else {
5600 self.write_keyword("LEFT LATERAL JOIN");
5601 }
5602 }
5603 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
5604 JoinKind::Implicit => {
5605 use crate::dialects::DialectType;
5609 let is_cj_dialect = matches!(
5610 self.config.dialect,
5611 Some(DialectType::BigQuery)
5612 | Some(DialectType::Hive)
5613 | Some(DialectType::Spark)
5614 | Some(DialectType::Databricks)
5615 );
5616 let source_is_same = self.config.source_dialect.is_some()
5617 && self.config.source_dialect == self.config.dialect;
5618 let source_is_cj = matches!(
5619 self.config.source_dialect,
5620 Some(DialectType::BigQuery)
5621 | Some(DialectType::Hive)
5622 | Some(DialectType::Spark)
5623 | Some(DialectType::Databricks)
5624 );
5625 if is_cj_dialect
5626 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
5627 {
5628 self.write_keyword("CROSS JOIN");
5629 } else {
5630 self.output.truncate(self.output.trim_end().len());
5634 self.write(",");
5635 }
5636 }
5637 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
5638 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
5639 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
5640 JoinKind::Positional => self.write_keyword("POSITIONAL JOIN"),
5641 }
5642 }
5643
5644 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
5646 self.write_space();
5647 match &join.this {
5648 Expression::Tuple(t) => {
5649 for (i, item) in t.expressions.iter().enumerate() {
5650 if i > 0 {
5651 self.write(", ");
5652 }
5653 self.generate_expression(item)?;
5654 }
5655 }
5656 other => {
5657 self.generate_expression(other)?;
5658 }
5659 }
5660 } else {
5661 self.write_space();
5662 self.generate_expression(&join.this)?;
5663 }
5664
5665 if !join.deferred_condition {
5667 if let Some(match_cond) = &join.match_condition {
5669 self.write_space();
5670 self.write_keyword("MATCH_CONDITION");
5671 self.write(" (");
5672 self.generate_expression(match_cond)?;
5673 self.write(")");
5674 }
5675
5676 if let Some(on) = &join.on {
5677 if self.config.pretty {
5678 self.write_newline();
5679 self.indent_level += 1;
5680 self.write_indent();
5681 self.write_keyword("ON");
5682 self.write_space();
5683 self.generate_join_on_condition(on)?;
5684 self.indent_level -= 1;
5685 } else {
5686 self.write_space();
5687 self.write_keyword("ON");
5688 self.write_space();
5689 self.generate_expression(on)?;
5690 }
5691 }
5692
5693 if !join.using.is_empty() {
5694 if self.config.pretty {
5695 self.write_newline();
5696 self.indent_level += 1;
5697 self.write_indent();
5698 self.write_keyword("USING");
5699 self.write(" (");
5700 for (i, col) in join.using.iter().enumerate() {
5701 if i > 0 {
5702 self.write(", ");
5703 }
5704 self.generate_identifier(col)?;
5705 }
5706 self.write(")");
5707 self.indent_level -= 1;
5708 } else {
5709 self.write_space();
5710 self.write_keyword("USING");
5711 self.write(" (");
5712 for (i, col) in join.using.iter().enumerate() {
5713 if i > 0 {
5714 self.write(", ");
5715 }
5716 self.generate_identifier(col)?;
5717 }
5718 self.write(")");
5719 }
5720 }
5721 }
5722
5723 for pivot in &join.pivots {
5725 self.write_space();
5726 self.generate_expression(pivot)?;
5727 }
5728
5729 Ok(())
5730 }
5731
5732 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
5734 if let Some(match_cond) = &join.match_condition {
5736 self.write_space();
5737 self.write_keyword("MATCH_CONDITION");
5738 self.write(" (");
5739 self.generate_expression(match_cond)?;
5740 self.write(")");
5741 }
5742
5743 if let Some(on) = &join.on {
5744 if self.config.pretty {
5745 self.write_newline();
5746 self.indent_level += 1;
5747 self.write_indent();
5748 self.write_keyword("ON");
5749 self.write_space();
5750 self.generate_join_on_condition(on)?;
5752 self.indent_level -= 1;
5753 } else {
5754 self.write_space();
5755 self.write_keyword("ON");
5756 self.write_space();
5757 self.generate_expression(on)?;
5758 }
5759 }
5760
5761 if !join.using.is_empty() {
5762 if self.config.pretty {
5763 self.write_newline();
5764 self.indent_level += 1;
5765 self.write_indent();
5766 self.write_keyword("USING");
5767 self.write(" (");
5768 for (i, col) in join.using.iter().enumerate() {
5769 if i > 0 {
5770 self.write(", ");
5771 }
5772 self.generate_identifier(col)?;
5773 }
5774 self.write(")");
5775 self.indent_level -= 1;
5776 } else {
5777 self.write_space();
5778 self.write_keyword("USING");
5779 self.write(" (");
5780 for (i, col) in join.using.iter().enumerate() {
5781 if i > 0 {
5782 self.write(", ");
5783 }
5784 self.generate_identifier(col)?;
5785 }
5786 self.write(")");
5787 }
5788 }
5789
5790 for pivot in &join.pivots {
5792 self.write_space();
5793 self.generate_expression(pivot)?;
5794 }
5795
5796 Ok(())
5797 }
5798
5799 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
5801 if let Expression::And(and_op) = expr {
5802 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
5803 self.generate_expression(conditions[0])?;
5804 for condition in conditions.iter().skip(1) {
5805 self.write_newline();
5806 self.write_indent();
5807 self.write_keyword("AND");
5808 self.write_space();
5809 self.generate_expression(condition)?;
5810 }
5811 return Ok(());
5812 }
5813 }
5814
5815 self.generate_expression(expr)
5816 }
5817
5818 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
5819 self.write("(");
5821 self.generate_expression(&jt.left)?;
5822
5823 for join in &jt.joins {
5825 self.generate_join(join)?;
5826 }
5827
5828 for (lv_idx, lv) in jt.lateral_views.iter().enumerate() {
5830 self.generate_lateral_view(lv, lv_idx)?;
5831 }
5832
5833 self.write(")");
5834
5835 if let Some(alias) = &jt.alias {
5837 self.write_space();
5838 self.write_keyword("AS");
5839 self.write_space();
5840 self.generate_identifier(alias)?;
5841 }
5842
5843 Ok(())
5844 }
5845
5846 fn generate_lateral_view(&mut self, lv: &LateralView, lv_index: usize) -> Result<()> {
5847 use crate::dialects::DialectType;
5848
5849 if self.config.pretty {
5850 self.write_newline();
5851 self.write_indent();
5852 } else {
5853 self.write_space();
5854 }
5855
5856 let use_lateral_join = matches!(
5859 self.config.dialect,
5860 Some(DialectType::PostgreSQL)
5861 | Some(DialectType::DuckDB)
5862 | Some(DialectType::Snowflake)
5863 | Some(DialectType::TSQL)
5864 | Some(DialectType::Presto)
5865 | Some(DialectType::Trino)
5866 | Some(DialectType::Athena)
5867 );
5868
5869 let use_unnest = matches!(
5871 self.config.dialect,
5872 Some(DialectType::DuckDB)
5873 | Some(DialectType::Presto)
5874 | Some(DialectType::Trino)
5875 | Some(DialectType::Athena)
5876 );
5877
5878 let (is_posexplode, is_inline, func_args) = match &lv.this {
5880 Expression::Explode(uf) => {
5881 (false, false, vec![uf.this.clone()])
5883 }
5884 Expression::Unnest(uf) => {
5885 let mut args = vec![uf.this.clone()];
5886 args.extend(uf.expressions.clone());
5887 (false, false, args)
5888 }
5889 Expression::Function(func) => {
5890 if func.name.eq_ignore_ascii_case("POSEXPLODE") || func.name.eq_ignore_ascii_case("POSEXPLODE_OUTER") {
5891 (true, false, func.args.clone())
5892 } else if func.name.eq_ignore_ascii_case("INLINE") {
5893 (false, true, func.args.clone())
5894 } else if func.name.eq_ignore_ascii_case("EXPLODE") || func.name.eq_ignore_ascii_case("EXPLODE_OUTER") {
5895 (false, false, func.args.clone())
5896 } else {
5897 (false, false, vec![])
5898 }
5899 }
5900 _ => (false, false, vec![]),
5901 };
5902
5903 if use_lateral_join {
5904 if lv.outer {
5906 self.write_keyword("LEFT JOIN LATERAL");
5907 } else {
5908 self.write_keyword("CROSS JOIN");
5909 }
5910 self.write_space();
5911
5912 if use_unnest && !func_args.is_empty() {
5913 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
5916 func_args
5918 .iter()
5919 .map(|a| {
5920 if let Expression::Function(ref f) = a {
5921 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() == 1 {
5922 return Expression::ArrayFunc(Box::new(
5923 crate::expressions::ArrayConstructor {
5924 expressions: f.args.clone(),
5925 bracket_notation: true,
5926 use_list_keyword: false,
5927 },
5928 ));
5929 }
5930 }
5931 a.clone()
5932 })
5933 .collect::<Vec<_>>()
5934 } else if matches!(
5935 self.config.dialect,
5936 Some(DialectType::Presto)
5937 | Some(DialectType::Trino)
5938 | Some(DialectType::Athena)
5939 ) {
5940 func_args
5942 .iter()
5943 .map(|a| {
5944 if let Expression::Function(ref f) = a {
5945 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() >= 1 {
5946 return Expression::ArrayFunc(Box::new(
5947 crate::expressions::ArrayConstructor {
5948 expressions: f.args.clone(),
5949 bracket_notation: true,
5950 use_list_keyword: false,
5951 },
5952 ));
5953 }
5954 }
5955 a.clone()
5956 })
5957 .collect::<Vec<_>>()
5958 } else {
5959 func_args
5960 };
5961
5962 if is_posexplode {
5964 self.write_keyword("LATERAL");
5965 self.write(" (");
5966 self.write_keyword("SELECT");
5967 self.write_space();
5968
5969 let pos_alias = if !lv.column_aliases.is_empty() {
5972 lv.column_aliases[0].clone()
5973 } else {
5974 Identifier::new("pos")
5975 };
5976 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
5977 lv.column_aliases[1..].to_vec()
5978 } else {
5979 vec![Identifier::new("col")]
5980 };
5981
5982 self.generate_identifier(&pos_alias)?;
5984 self.write(" - 1");
5985 self.write_space();
5986 self.write_keyword("AS");
5987 self.write_space();
5988 self.generate_identifier(&pos_alias)?;
5989
5990 for data_col in &data_aliases {
5992 self.write(", ");
5993 self.generate_identifier(data_col)?;
5994 }
5995
5996 self.write_space();
5997 self.write_keyword("FROM");
5998 self.write_space();
5999 self.write_keyword("UNNEST");
6000 self.write("(");
6001 for (i, arg) in unnest_args.iter().enumerate() {
6002 if i > 0 {
6003 self.write(", ");
6004 }
6005 self.generate_expression(arg)?;
6006 }
6007 self.write(")");
6008 self.write_space();
6009 self.write_keyword("WITH ORDINALITY");
6010 self.write_space();
6011 self.write_keyword("AS");
6012 self.write_space();
6013
6014 let table_alias_ident = lv
6016 .table_alias
6017 .clone()
6018 .unwrap_or_else(|| Identifier::new("t"));
6019 self.generate_identifier(&table_alias_ident)?;
6020 self.write("(");
6021 for (i, data_col) in data_aliases.iter().enumerate() {
6022 if i > 0 {
6023 self.write(", ");
6024 }
6025 self.generate_identifier(data_col)?;
6026 }
6027 self.write(", ");
6028 self.generate_identifier(&pos_alias)?;
6029 self.write("))");
6030 } else if is_inline && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6031 self.write_keyword("LATERAL");
6033 self.write(" (");
6034 self.write_keyword("SELECT");
6035 self.write_space();
6036 self.write_keyword("UNNEST");
6037 self.write("(");
6038 for (i, arg) in unnest_args.iter().enumerate() {
6039 if i > 0 {
6040 self.write(", ");
6041 }
6042 self.generate_expression(arg)?;
6043 }
6044 self.write(", ");
6045 self.write_keyword("max_depth");
6046 self.write(" => 2))");
6047
6048 if let Some(alias) = &lv.table_alias {
6050 self.write_space();
6051 self.write_keyword("AS");
6052 self.write_space();
6053 self.generate_identifier(alias)?;
6054 if !lv.column_aliases.is_empty() {
6055 self.write("(");
6056 for (i, col) in lv.column_aliases.iter().enumerate() {
6057 if i > 0 {
6058 self.write(", ");
6059 }
6060 self.generate_identifier(col)?;
6061 }
6062 self.write(")");
6063 }
6064 } else if !lv.column_aliases.is_empty() {
6065 self.write_space();
6067 self.write_keyword("AS");
6068 self.write_space();
6069 self.write(&format!("_u_{}", lv_index));
6070 self.write("(");
6071 for (i, col) in lv.column_aliases.iter().enumerate() {
6072 if i > 0 {
6073 self.write(", ");
6074 }
6075 self.generate_identifier(col)?;
6076 }
6077 self.write(")");
6078 }
6079 } else {
6080 self.write_keyword("UNNEST");
6081 self.write("(");
6082 for (i, arg) in unnest_args.iter().enumerate() {
6083 if i > 0 {
6084 self.write(", ");
6085 }
6086 self.generate_expression(arg)?;
6087 }
6088 self.write(")");
6089
6090 if let Some(alias) = &lv.table_alias {
6092 self.write_space();
6093 self.write_keyword("AS");
6094 self.write_space();
6095 self.generate_identifier(alias)?;
6096 if !lv.column_aliases.is_empty() {
6097 self.write("(");
6098 for (i, col) in lv.column_aliases.iter().enumerate() {
6099 if i > 0 {
6100 self.write(", ");
6101 }
6102 self.generate_identifier(col)?;
6103 }
6104 self.write(")");
6105 }
6106 } else if !lv.column_aliases.is_empty() {
6107 self.write_space();
6108 self.write_keyword("AS");
6109 self.write(" t(");
6110 for (i, col) in lv.column_aliases.iter().enumerate() {
6111 if i > 0 {
6112 self.write(", ");
6113 }
6114 self.generate_identifier(col)?;
6115 }
6116 self.write(")");
6117 }
6118 }
6119 } else {
6120 if !lv.outer {
6122 self.write_keyword("LATERAL");
6123 self.write_space();
6124 }
6125 self.generate_expression(&lv.this)?;
6126
6127 if let Some(alias) = &lv.table_alias {
6129 self.write_space();
6130 self.write_keyword("AS");
6131 self.write_space();
6132 self.generate_identifier(alias)?;
6133 if !lv.column_aliases.is_empty() {
6134 self.write("(");
6135 for (i, col) in lv.column_aliases.iter().enumerate() {
6136 if i > 0 {
6137 self.write(", ");
6138 }
6139 self.generate_identifier(col)?;
6140 }
6141 self.write(")");
6142 }
6143 } else if !lv.column_aliases.is_empty() {
6144 self.write_space();
6145 self.write_keyword("AS");
6146 self.write(" t(");
6147 for (i, col) in lv.column_aliases.iter().enumerate() {
6148 if i > 0 {
6149 self.write(", ");
6150 }
6151 self.generate_identifier(col)?;
6152 }
6153 self.write(")");
6154 }
6155 }
6156
6157 if lv.outer {
6159 self.write_space();
6160 self.write_keyword("ON TRUE");
6161 }
6162 } else {
6163 self.write_keyword("LATERAL VIEW");
6165 if lv.outer {
6166 self.write_space();
6167 self.write_keyword("OUTER");
6168 }
6169 if self.config.pretty {
6170 self.write_newline();
6171 self.write_indent();
6172 } else {
6173 self.write_space();
6174 }
6175 self.generate_expression(&lv.this)?;
6176
6177 if let Some(alias) = &lv.table_alias {
6179 self.write_space();
6180 self.generate_identifier(alias)?;
6181 }
6182
6183 if !lv.column_aliases.is_empty() {
6185 self.write_space();
6186 self.write_keyword("AS");
6187 self.write_space();
6188 for (i, col) in lv.column_aliases.iter().enumerate() {
6189 if i > 0 {
6190 self.write(", ");
6191 }
6192 self.generate_identifier(col)?;
6193 }
6194 }
6195 }
6196
6197 Ok(())
6198 }
6199
6200 fn generate_union(&mut self, union: &Union) -> Result<()> {
6201 if let Some(with) = &union.with {
6203 self.generate_with(with)?;
6204 self.write_space();
6205 }
6206 self.generate_expression(&union.left)?;
6207 if self.config.pretty {
6208 self.write_newline();
6209 self.write_indent();
6210 } else {
6211 self.write_space();
6212 }
6213
6214 if let Some(side) = &union.side {
6216 self.write_keyword(side);
6217 self.write_space();
6218 }
6219 if let Some(kind) = &union.kind {
6220 self.write_keyword(kind);
6221 self.write_space();
6222 }
6223
6224 self.write_keyword("UNION");
6225 if union.all {
6226 self.write_space();
6227 self.write_keyword("ALL");
6228 } else if union.distinct {
6229 self.write_space();
6230 self.write_keyword("DISTINCT");
6231 }
6232
6233 if union.corresponding || union.by_name {
6236 self.write_space();
6237 self.write_keyword("BY NAME");
6238 }
6239 if !union.on_columns.is_empty() {
6240 self.write_space();
6241 self.write_keyword("ON");
6242 self.write(" (");
6243 for (i, col) in union.on_columns.iter().enumerate() {
6244 if i > 0 {
6245 self.write(", ");
6246 }
6247 self.generate_expression(col)?;
6248 }
6249 self.write(")");
6250 }
6251
6252 if self.config.pretty {
6253 self.write_newline();
6254 self.write_indent();
6255 } else {
6256 self.write_space();
6257 }
6258 self.generate_expression(&union.right)?;
6259 if let Some(order_by) = &union.order_by {
6261 if self.config.pretty {
6262 self.write_newline();
6263 } else {
6264 self.write_space();
6265 }
6266 self.write_keyword("ORDER BY");
6267 self.write_space();
6268 for (i, ordered) in order_by.expressions.iter().enumerate() {
6269 if i > 0 {
6270 self.write(", ");
6271 }
6272 self.generate_ordered(ordered)?;
6273 }
6274 }
6275 if let Some(limit) = &union.limit {
6276 if self.config.pretty {
6277 self.write_newline();
6278 } else {
6279 self.write_space();
6280 }
6281 self.write_keyword("LIMIT");
6282 self.write_space();
6283 self.generate_expression(limit)?;
6284 }
6285 if let Some(offset) = &union.offset {
6286 if self.config.pretty {
6287 self.write_newline();
6288 } else {
6289 self.write_space();
6290 }
6291 self.write_keyword("OFFSET");
6292 self.write_space();
6293 self.generate_expression(offset)?;
6294 }
6295 if let Some(distribute_by) = &union.distribute_by {
6297 self.write_space();
6298 self.write_keyword("DISTRIBUTE BY");
6299 self.write_space();
6300 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6301 if i > 0 {
6302 self.write(", ");
6303 }
6304 self.generate_expression(expr)?;
6305 }
6306 }
6307 if let Some(sort_by) = &union.sort_by {
6309 self.write_space();
6310 self.write_keyword("SORT BY");
6311 self.write_space();
6312 for (i, ord) in sort_by.expressions.iter().enumerate() {
6313 if i > 0 {
6314 self.write(", ");
6315 }
6316 self.generate_ordered(ord)?;
6317 }
6318 }
6319 if let Some(cluster_by) = &union.cluster_by {
6321 self.write_space();
6322 self.write_keyword("CLUSTER BY");
6323 self.write_space();
6324 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6325 if i > 0 {
6326 self.write(", ");
6327 }
6328 self.generate_ordered(ord)?;
6329 }
6330 }
6331 Ok(())
6332 }
6333
6334 fn generate_intersect(&mut self, intersect: &Intersect) -> Result<()> {
6335 if let Some(with) = &intersect.with {
6337 self.generate_with(with)?;
6338 self.write_space();
6339 }
6340 self.generate_expression(&intersect.left)?;
6341 if self.config.pretty {
6342 self.write_newline();
6343 self.write_indent();
6344 } else {
6345 self.write_space();
6346 }
6347
6348 if let Some(side) = &intersect.side {
6350 self.write_keyword(side);
6351 self.write_space();
6352 }
6353 if let Some(kind) = &intersect.kind {
6354 self.write_keyword(kind);
6355 self.write_space();
6356 }
6357
6358 self.write_keyword("INTERSECT");
6359 if intersect.all {
6360 self.write_space();
6361 self.write_keyword("ALL");
6362 } else if intersect.distinct {
6363 self.write_space();
6364 self.write_keyword("DISTINCT");
6365 }
6366
6367 if intersect.corresponding || intersect.by_name {
6370 self.write_space();
6371 self.write_keyword("BY NAME");
6372 }
6373 if !intersect.on_columns.is_empty() {
6374 self.write_space();
6375 self.write_keyword("ON");
6376 self.write(" (");
6377 for (i, col) in intersect.on_columns.iter().enumerate() {
6378 if i > 0 {
6379 self.write(", ");
6380 }
6381 self.generate_expression(col)?;
6382 }
6383 self.write(")");
6384 }
6385
6386 if self.config.pretty {
6387 self.write_newline();
6388 self.write_indent();
6389 } else {
6390 self.write_space();
6391 }
6392 self.generate_expression(&intersect.right)?;
6393 if let Some(order_by) = &intersect.order_by {
6395 if self.config.pretty {
6396 self.write_newline();
6397 } else {
6398 self.write_space();
6399 }
6400 self.write_keyword("ORDER BY");
6401 self.write_space();
6402 for (i, ordered) in order_by.expressions.iter().enumerate() {
6403 if i > 0 {
6404 self.write(", ");
6405 }
6406 self.generate_ordered(ordered)?;
6407 }
6408 }
6409 if let Some(limit) = &intersect.limit {
6410 if self.config.pretty {
6411 self.write_newline();
6412 } else {
6413 self.write_space();
6414 }
6415 self.write_keyword("LIMIT");
6416 self.write_space();
6417 self.generate_expression(limit)?;
6418 }
6419 if let Some(offset) = &intersect.offset {
6420 if self.config.pretty {
6421 self.write_newline();
6422 } else {
6423 self.write_space();
6424 }
6425 self.write_keyword("OFFSET");
6426 self.write_space();
6427 self.generate_expression(offset)?;
6428 }
6429 if let Some(distribute_by) = &intersect.distribute_by {
6431 self.write_space();
6432 self.write_keyword("DISTRIBUTE BY");
6433 self.write_space();
6434 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6435 if i > 0 {
6436 self.write(", ");
6437 }
6438 self.generate_expression(expr)?;
6439 }
6440 }
6441 if let Some(sort_by) = &intersect.sort_by {
6443 self.write_space();
6444 self.write_keyword("SORT BY");
6445 self.write_space();
6446 for (i, ord) in sort_by.expressions.iter().enumerate() {
6447 if i > 0 {
6448 self.write(", ");
6449 }
6450 self.generate_ordered(ord)?;
6451 }
6452 }
6453 if let Some(cluster_by) = &intersect.cluster_by {
6455 self.write_space();
6456 self.write_keyword("CLUSTER BY");
6457 self.write_space();
6458 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6459 if i > 0 {
6460 self.write(", ");
6461 }
6462 self.generate_ordered(ord)?;
6463 }
6464 }
6465 Ok(())
6466 }
6467
6468 fn generate_except(&mut self, except: &Except) -> Result<()> {
6469 use crate::dialects::DialectType;
6470
6471 if let Some(with) = &except.with {
6473 self.generate_with(with)?;
6474 self.write_space();
6475 }
6476
6477 self.generate_expression(&except.left)?;
6478 if self.config.pretty {
6479 self.write_newline();
6480 self.write_indent();
6481 } else {
6482 self.write_space();
6483 }
6484
6485 if let Some(side) = &except.side {
6487 self.write_keyword(side);
6488 self.write_space();
6489 }
6490 if let Some(kind) = &except.kind {
6491 self.write_keyword(kind);
6492 self.write_space();
6493 }
6494
6495 match self.config.dialect {
6497 Some(DialectType::Oracle) if !except.all => {
6498 self.write_keyword("MINUS");
6499 }
6500 Some(DialectType::ClickHouse) => {
6501 self.write_keyword("EXCEPT");
6503 if except.distinct {
6504 self.write_space();
6505 self.write_keyword("DISTINCT");
6506 }
6507 }
6508 Some(DialectType::BigQuery) => {
6509 self.write_keyword("EXCEPT");
6511 if except.all {
6512 self.write_space();
6513 self.write_keyword("ALL");
6514 } else {
6515 self.write_space();
6516 self.write_keyword("DISTINCT");
6517 }
6518 }
6519 _ => {
6520 self.write_keyword("EXCEPT");
6521 if except.all {
6522 self.write_space();
6523 self.write_keyword("ALL");
6524 } else if except.distinct {
6525 self.write_space();
6526 self.write_keyword("DISTINCT");
6527 }
6528 }
6529 }
6530
6531 if except.corresponding || except.by_name {
6534 self.write_space();
6535 self.write_keyword("BY NAME");
6536 }
6537 if !except.on_columns.is_empty() {
6538 self.write_space();
6539 self.write_keyword("ON");
6540 self.write(" (");
6541 for (i, col) in except.on_columns.iter().enumerate() {
6542 if i > 0 {
6543 self.write(", ");
6544 }
6545 self.generate_expression(col)?;
6546 }
6547 self.write(")");
6548 }
6549
6550 if self.config.pretty {
6551 self.write_newline();
6552 self.write_indent();
6553 } else {
6554 self.write_space();
6555 }
6556 self.generate_expression(&except.right)?;
6557 if let Some(order_by) = &except.order_by {
6559 if self.config.pretty {
6560 self.write_newline();
6561 } else {
6562 self.write_space();
6563 }
6564 self.write_keyword("ORDER BY");
6565 self.write_space();
6566 for (i, ordered) in order_by.expressions.iter().enumerate() {
6567 if i > 0 {
6568 self.write(", ");
6569 }
6570 self.generate_ordered(ordered)?;
6571 }
6572 }
6573 if let Some(limit) = &except.limit {
6574 if self.config.pretty {
6575 self.write_newline();
6576 } else {
6577 self.write_space();
6578 }
6579 self.write_keyword("LIMIT");
6580 self.write_space();
6581 self.generate_expression(limit)?;
6582 }
6583 if let Some(offset) = &except.offset {
6584 if self.config.pretty {
6585 self.write_newline();
6586 } else {
6587 self.write_space();
6588 }
6589 self.write_keyword("OFFSET");
6590 self.write_space();
6591 self.generate_expression(offset)?;
6592 }
6593 if let Some(distribute_by) = &except.distribute_by {
6595 self.write_space();
6596 self.write_keyword("DISTRIBUTE BY");
6597 self.write_space();
6598 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6599 if i > 0 {
6600 self.write(", ");
6601 }
6602 self.generate_expression(expr)?;
6603 }
6604 }
6605 if let Some(sort_by) = &except.sort_by {
6607 self.write_space();
6608 self.write_keyword("SORT BY");
6609 self.write_space();
6610 for (i, ord) in sort_by.expressions.iter().enumerate() {
6611 if i > 0 {
6612 self.write(", ");
6613 }
6614 self.generate_ordered(ord)?;
6615 }
6616 }
6617 if let Some(cluster_by) = &except.cluster_by {
6619 self.write_space();
6620 self.write_keyword("CLUSTER BY");
6621 self.write_space();
6622 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6623 if i > 0 {
6624 self.write(", ");
6625 }
6626 self.generate_ordered(ord)?;
6627 }
6628 }
6629 Ok(())
6630 }
6631
6632 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
6633 let prepend_query_cte = if insert.with.is_none() {
6635 use crate::dialects::DialectType;
6636 let should_prepend = matches!(
6637 self.config.dialect,
6638 Some(DialectType::TSQL)
6639 | Some(DialectType::Fabric)
6640 | Some(DialectType::Spark)
6641 | Some(DialectType::Databricks)
6642 | Some(DialectType::Hive)
6643 );
6644 if should_prepend {
6645 if let Some(Expression::Select(select)) = &insert.query {
6646 select.with.clone()
6647 } else {
6648 None
6649 }
6650 } else {
6651 None
6652 }
6653 } else {
6654 None
6655 };
6656
6657 if let Some(with) = &insert.with {
6659 self.generate_with(with)?;
6660 self.write_space();
6661 } else if let Some(with) = &prepend_query_cte {
6662 self.generate_with(with)?;
6663 self.write_space();
6664 }
6665
6666 for comment in &insert.leading_comments {
6668 self.write_formatted_comment(comment);
6669 self.write(" ");
6670 }
6671
6672 if let Some(dir) = &insert.directory {
6674 self.write_keyword("INSERT OVERWRITE");
6675 if dir.local {
6676 self.write_space();
6677 self.write_keyword("LOCAL");
6678 }
6679 self.write_space();
6680 self.write_keyword("DIRECTORY");
6681 self.write_space();
6682 self.write("'");
6683 self.write(&dir.path);
6684 self.write("'");
6685
6686 if let Some(row_format) = &dir.row_format {
6688 self.write_space();
6689 self.write_keyword("ROW FORMAT");
6690 if row_format.delimited {
6691 self.write_space();
6692 self.write_keyword("DELIMITED");
6693 }
6694 if let Some(val) = &row_format.fields_terminated_by {
6695 self.write_space();
6696 self.write_keyword("FIELDS TERMINATED BY");
6697 self.write_space();
6698 self.write("'");
6699 self.write(val);
6700 self.write("'");
6701 }
6702 if let Some(val) = &row_format.collection_items_terminated_by {
6703 self.write_space();
6704 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
6705 self.write_space();
6706 self.write("'");
6707 self.write(val);
6708 self.write("'");
6709 }
6710 if let Some(val) = &row_format.map_keys_terminated_by {
6711 self.write_space();
6712 self.write_keyword("MAP KEYS TERMINATED BY");
6713 self.write_space();
6714 self.write("'");
6715 self.write(val);
6716 self.write("'");
6717 }
6718 if let Some(val) = &row_format.lines_terminated_by {
6719 self.write_space();
6720 self.write_keyword("LINES TERMINATED BY");
6721 self.write_space();
6722 self.write("'");
6723 self.write(val);
6724 self.write("'");
6725 }
6726 if let Some(val) = &row_format.null_defined_as {
6727 self.write_space();
6728 self.write_keyword("NULL DEFINED AS");
6729 self.write_space();
6730 self.write("'");
6731 self.write(val);
6732 self.write("'");
6733 }
6734 }
6735
6736 if let Some(format) = &dir.stored_as {
6738 self.write_space();
6739 self.write_keyword("STORED AS");
6740 self.write_space();
6741 self.write_keyword(format);
6742 }
6743
6744 if let Some(query) = &insert.query {
6746 self.write_space();
6747 self.generate_expression(query)?;
6748 }
6749
6750 return Ok(());
6751 }
6752
6753 if insert.is_replace {
6754 self.write_keyword("REPLACE INTO");
6756 } else if insert.overwrite {
6757 self.write_keyword("INSERT");
6759 if let Some(ref hint) = insert.hint {
6761 self.generate_hint(hint)?;
6762 }
6763 self.write(&self.config.insert_overwrite.to_ascii_uppercase());
6764 } else if let Some(ref action) = insert.conflict_action {
6765 self.write_keyword("INSERT OR");
6767 self.write_space();
6768 self.write_keyword(action);
6769 self.write_space();
6770 self.write_keyword("INTO");
6771 } else if insert.ignore {
6772 self.write_keyword("INSERT IGNORE INTO");
6774 } else {
6775 self.write_keyword("INSERT");
6776 if let Some(ref hint) = insert.hint {
6778 self.generate_hint(hint)?;
6779 }
6780 self.write_space();
6781 self.write_keyword("INTO");
6782 }
6783 if let Some(ref func) = insert.function_target {
6785 self.write_space();
6786 self.write_keyword("FUNCTION");
6787 self.write_space();
6788 self.generate_expression(func)?;
6789 } else {
6790 self.write_space();
6791 self.generate_table(&insert.table)?;
6792 }
6793
6794 if let Some(ref alias) = insert.alias {
6796 self.write_space();
6797 if insert.alias_explicit_as {
6798 self.write_keyword("AS");
6799 self.write_space();
6800 }
6801 self.generate_identifier(alias)?;
6802 }
6803
6804 if insert.if_exists {
6806 self.write_space();
6807 self.write_keyword("IF EXISTS");
6808 }
6809
6810 if let Some(ref replace_where) = insert.replace_where {
6812 if self.config.pretty {
6813 self.write_newline();
6814 self.write_indent();
6815 } else {
6816 self.write_space();
6817 }
6818 self.write_keyword("REPLACE WHERE");
6819 self.write_space();
6820 self.generate_expression(replace_where)?;
6821 }
6822
6823 if !insert.partition.is_empty() {
6825 self.write_space();
6826 self.write_keyword("PARTITION");
6827 self.write("(");
6828 for (i, (col, val)) in insert.partition.iter().enumerate() {
6829 if i > 0 {
6830 self.write(", ");
6831 }
6832 self.generate_identifier(col)?;
6833 if let Some(v) = val {
6834 self.write(" = ");
6835 self.generate_expression(v)?;
6836 }
6837 }
6838 self.write(")");
6839 }
6840
6841 if let Some(ref partition_by) = insert.partition_by {
6843 self.write_space();
6844 self.write_keyword("PARTITION BY");
6845 self.write_space();
6846 self.generate_expression(partition_by)?;
6847 }
6848
6849 if !insert.settings.is_empty() {
6851 self.write_space();
6852 self.write_keyword("SETTINGS");
6853 self.write_space();
6854 for (i, setting) in insert.settings.iter().enumerate() {
6855 if i > 0 {
6856 self.write(", ");
6857 }
6858 self.generate_expression(setting)?;
6859 }
6860 }
6861
6862 if !insert.columns.is_empty() {
6863 if insert.alias.is_some() && insert.alias_explicit_as {
6864 self.write("(");
6866 } else {
6867 self.write(" (");
6869 }
6870 for (i, col) in insert.columns.iter().enumerate() {
6871 if i > 0 {
6872 self.write(", ");
6873 }
6874 self.generate_identifier(col)?;
6875 }
6876 self.write(")");
6877 }
6878
6879 if let Some(ref output) = insert.output {
6881 self.generate_output_clause(output)?;
6882 }
6883
6884 if insert.by_name {
6886 self.write_space();
6887 self.write_keyword("BY NAME");
6888 }
6889
6890 if insert.default_values {
6891 self.write_space();
6892 self.write_keyword("DEFAULT VALUES");
6893 } else if let Some(query) = &insert.query {
6894 if self.config.pretty {
6895 self.write_newline();
6896 } else {
6897 self.write_space();
6898 }
6899 if prepend_query_cte.is_some() {
6901 if let Expression::Select(select) = query {
6902 let mut select_no_with = select.clone();
6903 select_no_with.with = None;
6904 self.generate_select(&select_no_with)?;
6905 } else {
6906 self.generate_expression(query)?;
6907 }
6908 } else {
6909 self.generate_expression(query)?;
6910 }
6911 } else if !insert.values.is_empty() {
6912 if self.config.pretty {
6913 self.write_newline();
6915 self.write_keyword("VALUES");
6916 self.write_newline();
6917 self.indent_level += 1;
6918 for (i, row) in insert.values.iter().enumerate() {
6919 if i > 0 {
6920 self.write(",");
6921 self.write_newline();
6922 }
6923 self.write_indent();
6924 self.write("(");
6925 for (j, val) in row.iter().enumerate() {
6926 if j > 0 {
6927 self.write(", ");
6928 }
6929 self.generate_expression(val)?;
6930 }
6931 self.write(")");
6932 }
6933 self.indent_level -= 1;
6934 } else {
6935 self.write_space();
6937 self.write_keyword("VALUES");
6938 for (i, row) in insert.values.iter().enumerate() {
6939 if i > 0 {
6940 self.write(",");
6941 }
6942 self.write(" (");
6943 for (j, val) in row.iter().enumerate() {
6944 if j > 0 {
6945 self.write(", ");
6946 }
6947 self.generate_expression(val)?;
6948 }
6949 self.write(")");
6950 }
6951 }
6952 }
6953
6954 if let Some(ref source) = insert.source {
6956 self.write_space();
6957 self.write_keyword("TABLE");
6958 self.write_space();
6959 self.generate_expression(source)?;
6960 }
6961
6962 if let Some(alias) = &insert.source_alias {
6964 self.write_space();
6965 self.write_keyword("AS");
6966 self.write_space();
6967 self.generate_identifier(alias)?;
6968 }
6969
6970 if let Some(on_conflict) = &insert.on_conflict {
6972 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
6973 self.write_space();
6974 self.generate_expression(on_conflict)?;
6975 }
6976 }
6977
6978 if !insert.returning.is_empty() {
6980 self.write_space();
6981 self.write_keyword("RETURNING");
6982 self.write_space();
6983 for (i, expr) in insert.returning.iter().enumerate() {
6984 if i > 0 {
6985 self.write(", ");
6986 }
6987 self.generate_expression(expr)?;
6988 }
6989 }
6990
6991 Ok(())
6992 }
6993
6994 fn generate_update(&mut self, update: &Update) -> Result<()> {
6995 for comment in &update.leading_comments {
6997 self.write_formatted_comment(comment);
6998 self.write(" ");
6999 }
7000
7001 if let Some(ref with) = update.with {
7003 self.generate_with(with)?;
7004 self.write_space();
7005 }
7006
7007 self.write_keyword("UPDATE");
7008 self.write_space();
7009 self.generate_table(&update.table)?;
7010
7011 let mysql_like_update_from = matches!(
7012 self.config.dialect,
7013 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
7014 ) && update.from_clause.is_some();
7015
7016 let mut set_pairs = update.set.clone();
7017
7018 let mut pre_set_joins = update.table_joins.clone();
7020 if mysql_like_update_from {
7021 let target_name = update
7022 .table
7023 .alias
7024 .as_ref()
7025 .map(|a| a.name.clone())
7026 .unwrap_or_else(|| update.table.name.name.clone());
7027
7028 for (col, _) in &mut set_pairs {
7029 if !col.name.contains('.') {
7030 col.name = format!("{}.{}", target_name, col.name);
7031 }
7032 }
7033
7034 if let Some(from_clause) = &update.from_clause {
7035 for table_expr in &from_clause.expressions {
7036 pre_set_joins.push(crate::expressions::Join {
7037 this: table_expr.clone(),
7038 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7039 value: true,
7040 })),
7041 using: Vec::new(),
7042 kind: crate::expressions::JoinKind::Inner,
7043 use_inner_keyword: false,
7044 use_outer_keyword: false,
7045 deferred_condition: false,
7046 join_hint: None,
7047 match_condition: None,
7048 pivots: Vec::new(),
7049 comments: Vec::new(),
7050 nesting_group: 0,
7051 directed: false,
7052 });
7053 }
7054 }
7055 for join in &update.from_joins {
7056 let mut join = join.clone();
7057 if join.on.is_none() && join.using.is_empty() {
7058 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7059 value: true,
7060 }));
7061 }
7062 pre_set_joins.push(join);
7063 }
7064 }
7065
7066 for extra_table in &update.extra_tables {
7068 self.write(", ");
7069 self.generate_table(extra_table)?;
7070 }
7071
7072 for join in &pre_set_joins {
7074 self.generate_join(join)?;
7076 }
7077
7078 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
7080 if teradata_from_before_set && !mysql_like_update_from {
7081 if let Some(ref from_clause) = update.from_clause {
7082 self.write_space();
7083 self.write_keyword("FROM");
7084 self.write_space();
7085 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7086 if i > 0 {
7087 self.write(", ");
7088 }
7089 self.generate_expression(table_expr)?;
7090 }
7091 }
7092 for join in &update.from_joins {
7093 self.generate_join(join)?;
7094 }
7095 }
7096
7097 self.write_space();
7098 self.write_keyword("SET");
7099 self.write_space();
7100
7101 for (i, (col, val)) in set_pairs.iter().enumerate() {
7102 if i > 0 {
7103 self.write(", ");
7104 }
7105 self.generate_identifier(col)?;
7106 self.write(" = ");
7107 self.generate_expression(val)?;
7108 }
7109
7110 if let Some(ref output) = update.output {
7112 self.generate_output_clause(output)?;
7113 }
7114
7115 if !mysql_like_update_from && !teradata_from_before_set {
7117 if let Some(ref from_clause) = update.from_clause {
7118 self.write_space();
7119 self.write_keyword("FROM");
7120 self.write_space();
7121 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7123 if i > 0 {
7124 self.write(", ");
7125 }
7126 self.generate_expression(table_expr)?;
7127 }
7128 }
7129 }
7130
7131 if !mysql_like_update_from && !teradata_from_before_set {
7132 for join in &update.from_joins {
7134 self.generate_join(join)?;
7135 }
7136 }
7137
7138 if let Some(where_clause) = &update.where_clause {
7139 self.write_space();
7140 self.write_keyword("WHERE");
7141 self.write_space();
7142 self.generate_expression(&where_clause.this)?;
7143 }
7144
7145 if !update.returning.is_empty() {
7147 self.write_space();
7148 self.write_keyword("RETURNING");
7149 self.write_space();
7150 for (i, expr) in update.returning.iter().enumerate() {
7151 if i > 0 {
7152 self.write(", ");
7153 }
7154 self.generate_expression(expr)?;
7155 }
7156 }
7157
7158 if let Some(ref order_by) = update.order_by {
7160 self.write_space();
7161 self.generate_order_by(order_by)?;
7162 }
7163
7164 if let Some(ref limit) = update.limit {
7166 self.write_space();
7167 self.write_keyword("LIMIT");
7168 self.write_space();
7169 self.generate_expression(limit)?;
7170 }
7171
7172 Ok(())
7173 }
7174
7175 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
7176 if let Some(with) = &delete.with {
7178 self.generate_with(with)?;
7179 self.write_space();
7180 }
7181
7182 for comment in &delete.leading_comments {
7184 self.write_formatted_comment(comment);
7185 self.write(" ");
7186 }
7187
7188 if !delete.tables.is_empty() && !delete.tables_from_using {
7190 self.write_keyword("DELETE");
7192 self.write_space();
7193 for (i, tbl) in delete.tables.iter().enumerate() {
7194 if i > 0 {
7195 self.write(", ");
7196 }
7197 self.generate_table(tbl)?;
7198 }
7199 if let Some(ref output) = delete.output {
7201 self.generate_output_clause(output)?;
7202 }
7203 self.write_space();
7204 self.write_keyword("FROM");
7205 self.write_space();
7206 self.generate_table(&delete.table)?;
7207 } else if !delete.tables.is_empty() && delete.tables_from_using {
7208 self.write_keyword("DELETE FROM");
7210 self.write_space();
7211 for (i, tbl) in delete.tables.iter().enumerate() {
7212 if i > 0 {
7213 self.write(", ");
7214 }
7215 self.generate_table(tbl)?;
7216 }
7217 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
7218 self.write_keyword("DELETE");
7220 self.write_space();
7221 self.generate_table(&delete.table)?;
7222 } else {
7223 self.write_keyword("DELETE FROM");
7224 self.write_space();
7225 self.generate_table(&delete.table)?;
7226 }
7227
7228 if let Some(ref on_cluster) = delete.on_cluster {
7230 self.write_space();
7231 self.generate_on_cluster(on_cluster)?;
7232 }
7233
7234 if let Some(ref idx) = delete.force_index {
7236 self.write_space();
7237 self.write_keyword("FORCE INDEX");
7238 self.write(" (");
7239 self.write(idx);
7240 self.write(")");
7241 }
7242
7243 if let Some(ref alias) = delete.alias {
7245 self.write_space();
7246 if delete.alias_explicit_as
7247 || matches!(self.config.dialect, Some(DialectType::BigQuery))
7248 {
7249 self.write_keyword("AS");
7250 self.write_space();
7251 }
7252 self.generate_identifier(alias)?;
7253 }
7254
7255 if !delete.tables_from_using {
7257 for join in &delete.joins {
7258 self.generate_join(join)?;
7259 }
7260 }
7261
7262 if !delete.using.is_empty() {
7264 self.write_space();
7265 self.write_keyword("USING");
7266 for (i, table) in delete.using.iter().enumerate() {
7267 if i > 0 {
7268 self.write(",");
7269 }
7270 self.write_space();
7271 if !table.hints.is_empty() && table.name.is_empty() {
7273 self.generate_expression(&table.hints[0])?;
7275 if let Some(ref alias) = table.alias {
7276 self.write_space();
7277 if table.alias_explicit_as {
7278 self.write_keyword("AS");
7279 self.write_space();
7280 }
7281 self.generate_identifier(alias)?;
7282 if !table.column_aliases.is_empty() {
7283 self.write("(");
7284 for (j, col_alias) in table.column_aliases.iter().enumerate() {
7285 if j > 0 {
7286 self.write(", ");
7287 }
7288 self.generate_identifier(col_alias)?;
7289 }
7290 self.write(")");
7291 }
7292 }
7293 } else {
7294 self.generate_table(table)?;
7295 }
7296 }
7297 }
7298
7299 if delete.tables_from_using {
7301 for join in &delete.joins {
7302 self.generate_join(join)?;
7303 }
7304 }
7305
7306 let output_already_emitted =
7308 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
7309 if !output_already_emitted {
7310 if let Some(ref output) = delete.output {
7311 self.generate_output_clause(output)?;
7312 }
7313 }
7314
7315 if let Some(where_clause) = &delete.where_clause {
7316 self.write_space();
7317 self.write_keyword("WHERE");
7318 self.write_space();
7319 self.generate_expression(&where_clause.this)?;
7320 }
7321
7322 if let Some(ref order_by) = delete.order_by {
7324 self.write_space();
7325 self.generate_order_by(order_by)?;
7326 }
7327
7328 if let Some(ref limit) = delete.limit {
7330 self.write_space();
7331 self.write_keyword("LIMIT");
7332 self.write_space();
7333 self.generate_expression(limit)?;
7334 }
7335
7336 if !delete.returning.is_empty() {
7338 self.write_space();
7339 self.write_keyword("RETURNING");
7340 self.write_space();
7341 for (i, expr) in delete.returning.iter().enumerate() {
7342 if i > 0 {
7343 self.write(", ");
7344 }
7345 self.generate_expression(expr)?;
7346 }
7347 }
7348
7349 Ok(())
7350 }
7351
7352 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
7355 let saved_athena_hive_context = self.athena_hive_context;
7359 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
7360 if matches!(
7361 self.config.dialect,
7362 Some(crate::dialects::DialectType::Athena)
7363 ) {
7364 let is_external = ct
7368 .table_modifier
7369 .as_ref()
7370 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
7371 .unwrap_or(false);
7372 let has_as_select = ct.as_select.is_some();
7373 self.athena_hive_context = is_external || !has_as_select;
7374 }
7375
7376 if matches!(
7378 self.config.dialect,
7379 Some(crate::dialects::DialectType::TSQL)
7380 ) {
7381 if let Some(ref query) = ct.as_select {
7382 if let Some(with_cte) = &ct.with_cte {
7384 self.generate_with(with_cte)?;
7385 self.write_space();
7386 }
7387
7388 self.write_keyword("SELECT");
7390 self.write(" * ");
7391 self.write_keyword("INTO");
7392 self.write_space();
7393
7394 if ct.temporary {
7396 self.write("#");
7397 }
7398 self.generate_table(&ct.name)?;
7399
7400 self.write_space();
7401 self.write_keyword("FROM");
7402 self.write(" (");
7403 let aliased_query = Self::add_column_aliases_to_query(query.clone());
7405 self.generate_expression(&aliased_query)?;
7406 self.write(") ");
7407 self.write_keyword("AS");
7408 self.write(" temp");
7409 return Ok(());
7410 }
7411 }
7412
7413 if let Some(with_cte) = &ct.with_cte {
7415 self.generate_with(with_cte)?;
7416 self.write_space();
7417 }
7418
7419 for comment in &ct.leading_comments {
7421 self.write_formatted_comment(comment);
7422 self.write(" ");
7423 }
7424 self.write_keyword("CREATE");
7425
7426 if ct.or_replace {
7427 self.write_space();
7428 self.write_keyword("OR REPLACE");
7429 }
7430
7431 if ct.temporary {
7432 self.write_space();
7433 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
7435 self.write_keyword("GLOBAL TEMPORARY");
7436 } else {
7437 self.write_keyword("TEMPORARY");
7438 }
7439 }
7440
7441 let is_dictionary = ct
7443 .table_modifier
7444 .as_ref()
7445 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
7446 .unwrap_or(false);
7447 if let Some(ref modifier) = ct.table_modifier {
7448 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
7450 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
7451 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
7453 || modifier.eq_ignore_ascii_case("SET")
7454 || modifier.eq_ignore_ascii_case("MULTISET")
7455 || modifier.to_ascii_uppercase().contains("VOLATILE")
7456 || modifier.to_ascii_uppercase().starts_with("SET ")
7457 || modifier.to_ascii_uppercase().starts_with("MULTISET ");
7458 let skip_teradata =
7459 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
7460 if !skip_transient && !skip_teradata {
7461 self.write_space();
7462 self.write_keyword(modifier);
7463 }
7464 }
7465
7466 if !is_dictionary {
7467 self.write_space();
7468 self.write_keyword("TABLE");
7469 }
7470
7471 if ct.if_not_exists {
7472 self.write_space();
7473 self.write_keyword("IF NOT EXISTS");
7474 }
7475
7476 self.write_space();
7477 self.generate_table(&ct.name)?;
7478
7479 if let Some(ref on_cluster) = ct.on_cluster {
7481 self.write_space();
7482 self.generate_on_cluster(on_cluster)?;
7483 }
7484
7485 if matches!(
7487 self.config.dialect,
7488 Some(crate::dialects::DialectType::Teradata)
7489 ) && !ct.teradata_post_name_options.is_empty()
7490 {
7491 for opt in &ct.teradata_post_name_options {
7492 self.write(", ");
7493 self.write(opt);
7494 }
7495 }
7496
7497 if ct.copy_grants {
7499 self.write_space();
7500 self.write_keyword("COPY GRANTS");
7501 }
7502
7503 if let Some(ref using_template) = ct.using_template {
7505 self.write_space();
7506 self.write_keyword("USING TEMPLATE");
7507 self.write_space();
7508 self.generate_expression(using_template)?;
7509 return Ok(());
7510 }
7511
7512 if let Some(ref clone_source) = ct.clone_source {
7514 self.write_space();
7515 if ct.is_copy && self.config.supports_table_copy {
7516 self.write_keyword("COPY");
7518 } else if ct.shallow_clone {
7519 self.write_keyword("SHALLOW CLONE");
7520 } else {
7521 self.write_keyword("CLONE");
7522 }
7523 self.write_space();
7524 self.generate_table(clone_source)?;
7525 if let Some(ref at_clause) = ct.clone_at_clause {
7527 self.write_space();
7528 self.generate_expression(at_clause)?;
7529 }
7530 return Ok(());
7531 }
7532
7533 if let Some(ref partition_of) = ct.partition_of {
7537 self.write_space();
7538
7539 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
7541 self.write_keyword("PARTITION OF");
7543 self.write_space();
7544 self.generate_expression(&pop.this)?;
7545
7546 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7548 self.write(" (");
7549 let mut first = true;
7550 for col in &ct.columns {
7551 if !first {
7552 self.write(", ");
7553 }
7554 first = false;
7555 self.generate_column_def(col)?;
7556 }
7557 for constraint in &ct.constraints {
7558 if !first {
7559 self.write(", ");
7560 }
7561 first = false;
7562 self.generate_table_constraint(constraint)?;
7563 }
7564 self.write(")");
7565 }
7566
7567 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
7569 self.write_space();
7570 self.write_keyword("FOR VALUES");
7571 self.write_space();
7572 self.generate_expression(&pop.expression)?;
7573 } else {
7574 self.write_space();
7575 self.write_keyword("DEFAULT");
7576 }
7577 } else {
7578 self.generate_expression(partition_of)?;
7580
7581 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7583 self.write(" (");
7584 let mut first = true;
7585 for col in &ct.columns {
7586 if !first {
7587 self.write(", ");
7588 }
7589 first = false;
7590 self.generate_column_def(col)?;
7591 }
7592 for constraint in &ct.constraints {
7593 if !first {
7594 self.write(", ");
7595 }
7596 first = false;
7597 self.generate_table_constraint(constraint)?;
7598 }
7599 self.write(")");
7600 }
7601 }
7602
7603 for prop in &ct.properties {
7605 self.write_space();
7606 self.generate_expression(prop)?;
7607 }
7608
7609 return Ok(());
7610 }
7611
7612 self.sqlite_inline_pk_columns.clear();
7615 if matches!(
7616 self.config.dialect,
7617 Some(crate::dialects::DialectType::SQLite)
7618 ) {
7619 for constraint in &ct.constraints {
7620 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7621 if columns.len() == 1 && name.is_none() {
7623 let pk_col_name = columns[0].name.to_ascii_lowercase();
7624 if ct
7626 .columns
7627 .iter()
7628 .any(|c| c.name.name.to_ascii_lowercase() == pk_col_name)
7629 {
7630 self.sqlite_inline_pk_columns.insert(pk_col_name);
7631 }
7632 }
7633 }
7634 }
7635 }
7636
7637 if !ct.columns.is_empty() {
7639 if self.config.pretty {
7640 self.write(" (");
7642 self.write_newline();
7643 self.indent_level += 1;
7644 for (i, col) in ct.columns.iter().enumerate() {
7645 if i > 0 {
7646 self.write(",");
7647 self.write_newline();
7648 }
7649 self.write_indent();
7650 self.generate_column_def(col)?;
7651 }
7652 for constraint in &ct.constraints {
7654 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7656 if columns.len() == 1
7657 && name.is_none()
7658 && self
7659 .sqlite_inline_pk_columns
7660 .contains(&columns[0].name.to_ascii_lowercase())
7661 {
7662 continue;
7663 }
7664 }
7665 self.write(",");
7666 self.write_newline();
7667 self.write_indent();
7668 self.generate_table_constraint(constraint)?;
7669 }
7670 self.indent_level -= 1;
7671 self.write_newline();
7672 self.write(")");
7673 } else {
7674 self.write(" (");
7675 for (i, col) in ct.columns.iter().enumerate() {
7676 if i > 0 {
7677 self.write(", ");
7678 }
7679 self.generate_column_def(col)?;
7680 }
7681 let mut first_constraint = true;
7683 for constraint in &ct.constraints {
7684 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7686 if columns.len() == 1
7687 && name.is_none()
7688 && self
7689 .sqlite_inline_pk_columns
7690 .contains(&columns[0].name.to_ascii_lowercase())
7691 {
7692 continue;
7693 }
7694 }
7695 if first_constraint {
7696 self.write(", ");
7697 first_constraint = false;
7698 } else {
7699 self.write(", ");
7700 }
7701 self.generate_table_constraint(constraint)?;
7702 }
7703 self.write(")");
7704 }
7705 } else if !ct.constraints.is_empty() {
7706 let has_like_only = ct
7708 .constraints
7709 .iter()
7710 .all(|c| matches!(c, TableConstraint::Like { .. }));
7711 let has_tags_only = ct
7712 .constraints
7713 .iter()
7714 .all(|c| matches!(c, TableConstraint::Tags(_)));
7715 let is_pg_like = matches!(
7719 self.config.dialect,
7720 Some(crate::dialects::DialectType::PostgreSQL)
7721 | Some(crate::dialects::DialectType::CockroachDB)
7722 | Some(crate::dialects::DialectType::Materialize)
7723 | Some(crate::dialects::DialectType::RisingWave)
7724 | Some(crate::dialects::DialectType::Redshift)
7725 | Some(crate::dialects::DialectType::Presto)
7726 | Some(crate::dialects::DialectType::Trino)
7727 | Some(crate::dialects::DialectType::Athena)
7728 );
7729 let use_parens = if has_like_only {
7730 is_pg_like
7731 } else {
7732 !has_tags_only
7733 };
7734 if self.config.pretty && use_parens {
7735 self.write(" (");
7736 self.write_newline();
7737 self.indent_level += 1;
7738 for (i, constraint) in ct.constraints.iter().enumerate() {
7739 if i > 0 {
7740 self.write(",");
7741 self.write_newline();
7742 }
7743 self.write_indent();
7744 self.generate_table_constraint(constraint)?;
7745 }
7746 self.indent_level -= 1;
7747 self.write_newline();
7748 self.write(")");
7749 } else {
7750 if use_parens {
7751 self.write(" (");
7752 } else {
7753 self.write_space();
7754 }
7755 for (i, constraint) in ct.constraints.iter().enumerate() {
7756 if i > 0 {
7757 self.write(", ");
7758 }
7759 self.generate_table_constraint(constraint)?;
7760 }
7761 if use_parens {
7762 self.write(")");
7763 }
7764 }
7765 }
7766
7767 if let Some(ref on_prop) = ct.on_property {
7769 self.write(" ");
7770 self.write_keyword("ON");
7771 self.write(" ");
7772 self.generate_expression(&on_prop.this)?;
7773 }
7774
7775 if !is_clickhouse {
7778 for prop in &ct.properties {
7779 if let Expression::SchemaCommentProperty(_) = prop {
7780 if self.config.pretty {
7781 self.write_newline();
7782 } else {
7783 self.write_space();
7784 }
7785 self.generate_expression(prop)?;
7786 }
7787 }
7788 }
7789
7790 if !ct.with_properties.is_empty() {
7792 let is_snowflake_special_table = matches!(
7794 self.config.dialect,
7795 Some(crate::dialects::DialectType::Snowflake)
7796 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
7797 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
7798 if is_snowflake_special_table {
7799 for (key, value) in &ct.with_properties {
7800 self.write_space();
7801 self.write(key);
7802 self.write("=");
7803 self.write(value);
7804 }
7805 } else if self.config.pretty {
7806 self.write_newline();
7807 self.write_keyword("WITH");
7808 self.write(" (");
7809 self.write_newline();
7810 self.indent_level += 1;
7811 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7812 if i > 0 {
7813 self.write(",");
7814 self.write_newline();
7815 }
7816 self.write_indent();
7817 self.write(key);
7818 self.write("=");
7819 self.write(value);
7820 }
7821 self.indent_level -= 1;
7822 self.write_newline();
7823 self.write(")");
7824 } else {
7825 self.write_space();
7826 self.write_keyword("WITH");
7827 self.write(" (");
7828 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7829 if i > 0 {
7830 self.write(", ");
7831 }
7832 self.write(key);
7833 self.write("=");
7834 self.write(value);
7835 }
7836 self.write(")");
7837 }
7838 }
7839
7840 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
7841 if is_clickhouse && ct.as_select.is_some() {
7842 let mut pre = Vec::new();
7843 let mut post = Vec::new();
7844 for prop in &ct.properties {
7845 if matches!(prop, Expression::SchemaCommentProperty(_)) {
7846 post.push(prop);
7847 } else {
7848 pre.push(prop);
7849 }
7850 }
7851 (pre, post)
7852 } else {
7853 (ct.properties.iter().collect(), Vec::new())
7854 };
7855
7856 for prop in pre_as_properties {
7858 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
7860 continue;
7861 }
7862 if self.config.pretty {
7863 self.write_newline();
7864 } else {
7865 self.write_space();
7866 }
7867 if let Expression::Properties(props) = prop {
7871 let is_hive_dialect = matches!(
7872 self.config.dialect,
7873 Some(crate::dialects::DialectType::Hive)
7874 | Some(crate::dialects::DialectType::Spark)
7875 | Some(crate::dialects::DialectType::Databricks)
7876 | Some(crate::dialects::DialectType::Athena)
7877 );
7878 let is_doris_starrocks = matches!(
7879 self.config.dialect,
7880 Some(crate::dialects::DialectType::Doris)
7881 | Some(crate::dialects::DialectType::StarRocks)
7882 );
7883 if is_hive_dialect {
7884 self.generate_tblproperties_clause(&props.expressions)?;
7885 } else if is_doris_starrocks {
7886 self.generate_properties_clause(&props.expressions)?;
7887 } else {
7888 self.generate_options_clause(&props.expressions)?;
7889 }
7890 } else {
7891 self.generate_expression(prop)?;
7892 }
7893 }
7894
7895 for prop in &ct.post_table_properties {
7897 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
7898 self.write(" WITH(");
7899 self.generate_system_versioning_content(svp)?;
7900 self.write(")");
7901 } else if let Expression::Properties(props) = prop {
7902 let is_doris_starrocks = matches!(
7904 self.config.dialect,
7905 Some(crate::dialects::DialectType::Doris)
7906 | Some(crate::dialects::DialectType::StarRocks)
7907 );
7908 self.write_space();
7909 if is_doris_starrocks {
7910 self.generate_properties_clause(&props.expressions)?;
7911 } else {
7912 self.generate_options_clause(&props.expressions)?;
7913 }
7914 } else {
7915 self.write_space();
7916 self.generate_expression(prop)?;
7917 }
7918 }
7919
7920 if let Some(ref rollup) = ct.rollup {
7923 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
7924 self.write_space();
7925 self.generate_rollup_property(rollup)?;
7926 }
7927 }
7928
7929 let is_mysql_compatible = matches!(
7933 self.config.dialect,
7934 Some(DialectType::MySQL)
7935 | Some(DialectType::SingleStore)
7936 | Some(DialectType::Doris)
7937 | Some(DialectType::StarRocks)
7938 | None
7939 );
7940 let is_hive_compatible = matches!(
7941 self.config.dialect,
7942 Some(DialectType::Hive)
7943 | Some(DialectType::Spark)
7944 | Some(DialectType::Databricks)
7945 | Some(DialectType::Athena)
7946 );
7947 let mysql_pretty_options =
7948 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
7949 for (key, value) in &ct.mysql_table_options {
7950 let should_output = if is_mysql_compatible {
7952 true
7953 } else if is_hive_compatible && key == "COMMENT" {
7954 true } else {
7956 false
7957 };
7958 if should_output {
7959 if mysql_pretty_options {
7960 self.write_newline();
7961 self.write_indent();
7962 } else {
7963 self.write_space();
7964 }
7965 self.write_keyword(key);
7966 if key == "COMMENT" && !self.config.schema_comment_with_eq {
7968 self.write_space();
7969 } else {
7970 self.write("=");
7971 }
7972 self.write(value);
7973 }
7974 }
7975
7976 if ct.temporary
7978 && matches!(
7979 self.config.dialect,
7980 Some(DialectType::Spark) | Some(DialectType::Databricks)
7981 )
7982 && ct.as_select.is_none()
7983 {
7984 self.write_space();
7985 self.write_keyword("USING PARQUET");
7986 }
7987
7988 if !ct.inherits.is_empty() {
7990 self.write_space();
7991 self.write_keyword("INHERITS");
7992 self.write(" (");
7993 for (i, parent) in ct.inherits.iter().enumerate() {
7994 if i > 0 {
7995 self.write(", ");
7996 }
7997 self.generate_table(parent)?;
7998 }
7999 self.write(")");
8000 }
8001
8002 if let Some(ref query) = ct.as_select {
8004 self.write_space();
8005 self.write_keyword("AS");
8006 self.write_space();
8007 if ct.as_select_parenthesized {
8008 self.write("(");
8009 }
8010 self.generate_expression(query)?;
8011 if ct.as_select_parenthesized {
8012 self.write(")");
8013 }
8014
8015 if let Some(with_data) = ct.with_data {
8017 self.write_space();
8018 self.write_keyword("WITH");
8019 if !with_data {
8020 self.write_space();
8021 self.write_keyword("NO");
8022 }
8023 self.write_space();
8024 self.write_keyword("DATA");
8025 }
8026
8027 if let Some(with_statistics) = ct.with_statistics {
8029 self.write_space();
8030 self.write_keyword("AND");
8031 if !with_statistics {
8032 self.write_space();
8033 self.write_keyword("NO");
8034 }
8035 self.write_space();
8036 self.write_keyword("STATISTICS");
8037 }
8038
8039 for index in &ct.teradata_indexes {
8041 self.write_space();
8042 match index.kind {
8043 TeradataIndexKind::NoPrimary => {
8044 self.write_keyword("NO PRIMARY INDEX");
8045 }
8046 TeradataIndexKind::Primary => {
8047 self.write_keyword("PRIMARY INDEX");
8048 }
8049 TeradataIndexKind::PrimaryAmp => {
8050 self.write_keyword("PRIMARY AMP INDEX");
8051 }
8052 TeradataIndexKind::Unique => {
8053 self.write_keyword("UNIQUE INDEX");
8054 }
8055 TeradataIndexKind::UniquePrimary => {
8056 self.write_keyword("UNIQUE PRIMARY INDEX");
8057 }
8058 TeradataIndexKind::Secondary => {
8059 self.write_keyword("INDEX");
8060 }
8061 }
8062 if let Some(ref name) = index.name {
8064 self.write_space();
8065 self.write(name);
8066 }
8067 if !index.columns.is_empty() {
8069 self.write(" (");
8070 for (i, col) in index.columns.iter().enumerate() {
8071 if i > 0 {
8072 self.write(", ");
8073 }
8074 self.write(col);
8075 }
8076 self.write(")");
8077 }
8078 }
8079
8080 if let Some(ref on_commit) = ct.on_commit {
8082 self.write_space();
8083 self.write_keyword("ON COMMIT");
8084 self.write_space();
8085 match on_commit {
8086 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8087 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8088 }
8089 }
8090
8091 if !post_as_properties.is_empty() {
8092 for prop in post_as_properties {
8093 self.write_space();
8094 self.generate_expression(prop)?;
8095 }
8096 }
8097
8098 self.athena_hive_context = saved_athena_hive_context;
8100 return Ok(());
8101 }
8102
8103 if let Some(ref on_commit) = ct.on_commit {
8105 self.write_space();
8106 self.write_keyword("ON COMMIT");
8107 self.write_space();
8108 match on_commit {
8109 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8110 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8111 }
8112 }
8113
8114 self.athena_hive_context = saved_athena_hive_context;
8116
8117 Ok(())
8118 }
8119
8120 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
8123 self.generate_identifier(&col.name)?;
8125 if !matches!(col.data_type, DataType::Unknown) {
8127 self.write_space();
8128 self.generate_data_type(&col.data_type)?;
8129 }
8130 for constraint in &col.constraints {
8132 if let ColumnConstraint::Path(path_expr) = constraint {
8133 self.write_space();
8134 self.write_keyword("PATH");
8135 self.write_space();
8136 self.generate_expression(path_expr)?;
8137 }
8138 }
8139 Ok(())
8140 }
8141
8142 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
8143 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8145 && col
8146 .constraints
8147 .iter()
8148 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8149 let omit_computed_type = !self.config.computed_column_with_type
8151 && col
8152 .constraints
8153 .iter()
8154 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8155
8156 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
8159
8160 let has_no_type = col.no_type
8163 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8164 && col.constraints.is_empty());
8165
8166 self.generate_identifier(&col.name)?;
8167
8168 let serial_expansion = if matches!(
8170 self.config.dialect,
8171 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
8172 ) {
8173 if let DataType::Custom { ref name } = col.data_type {
8174 if name.eq_ignore_ascii_case("SERIAL") {
8175 Some("INT")
8176 } else if name.eq_ignore_ascii_case("BIGSERIAL") {
8177 Some("BIGINT")
8178 } else if name.eq_ignore_ascii_case("SMALLSERIAL") {
8179 Some("SMALLINT")
8180 } else {
8181 None
8182 }
8183 } else {
8184 None
8185 }
8186 } else {
8187 None
8188 };
8189
8190 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
8191 {
8192 self.write_space();
8193 let saved_nullable_depth = self.clickhouse_nullable_depth;
8196 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
8197 self.clickhouse_nullable_depth = -1;
8198 }
8199 if let Some(int_type) = serial_expansion {
8200 self.write_keyword(int_type);
8202 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8203 let unsigned_type = match &col.data_type {
8205 DataType::Int { .. } => Some("UINTEGER"),
8206 DataType::BigInt { .. } => Some("UBIGINT"),
8207 DataType::SmallInt { .. } => Some("USMALLINT"),
8208 DataType::TinyInt { .. } => Some("UTINYINT"),
8209 _ => None,
8210 };
8211 if let Some(utype) = unsigned_type {
8212 self.write_keyword(utype);
8213 } else {
8214 self.generate_data_type(&col.data_type)?;
8215 }
8216 } else {
8217 self.generate_data_type(&col.data_type)?;
8218 }
8219 self.clickhouse_nullable_depth = saved_nullable_depth;
8220 }
8221
8222 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8225 self.write_space();
8226 self.write_keyword("UNSIGNED");
8227 }
8228 if col.zerofill {
8229 self.write_space();
8230 self.write_keyword("ZEROFILL");
8231 }
8232
8233 if let Some(ref charset) = col.character_set {
8237 self.write_space();
8238 self.write_keyword("CHARACTER SET");
8239 self.write_space();
8240 self.write(charset);
8241 }
8242
8243 if col.uppercase {
8244 self.write_space();
8245 self.write_keyword("UPPERCASE");
8246 }
8247
8248 if let Some(casespecific) = col.casespecific {
8249 self.write_space();
8250 if casespecific {
8251 self.write_keyword("CASESPECIFIC");
8252 } else {
8253 self.write_keyword("NOT CASESPECIFIC");
8254 }
8255 }
8256
8257 if let Some(ref format) = col.format {
8258 self.write_space();
8259 self.write_keyword("FORMAT");
8260 self.write(" '");
8261 self.write(format);
8262 self.write("'");
8263 }
8264
8265 if let Some(ref title) = col.title {
8266 self.write_space();
8267 self.write_keyword("TITLE");
8268 self.write(" '");
8269 self.write(title);
8270 self.write("'");
8271 }
8272
8273 if let Some(length) = col.inline_length {
8274 self.write_space();
8275 self.write_keyword("INLINE LENGTH");
8276 self.write(" ");
8277 self.write(&length.to_string());
8278 }
8279
8280 if let Some(ref compress) = col.compress {
8281 self.write_space();
8282 self.write_keyword("COMPRESS");
8283 if !compress.is_empty() {
8284 if compress.len() == 1 {
8286 if let Expression::Literal(lit) = &compress[0] {
8287 if let Literal::String(_) = lit.as_ref() {
8288 self.write_space();
8289 self.generate_expression(&compress[0])?;
8290 }
8291 } else {
8292 self.write(" (");
8293 self.generate_expression(&compress[0])?;
8294 self.write(")");
8295 }
8296 } else {
8297 self.write(" (");
8298 for (i, val) in compress.iter().enumerate() {
8299 if i > 0 {
8300 self.write(", ");
8301 }
8302 self.generate_expression(val)?;
8303 }
8304 self.write(")");
8305 }
8306 }
8307 }
8308
8309 if !col.constraint_order.is_empty() {
8312 let mut references_idx = 0;
8315 let mut check_idx = 0;
8316 let mut generated_idx = 0;
8317 let mut collate_idx = 0;
8318 let mut comment_idx = 0;
8319 let defer_not_null_after_identity = false;
8322 let mut pending_not_null_after_identity = false;
8323
8324 for constraint_type in &col.constraint_order {
8325 match constraint_type {
8326 ConstraintType::PrimaryKey => {
8327 if col.primary_key
8329 && !matches!(self.config.dialect, Some(DialectType::Materialize))
8330 {
8331 if let Some(ref cname) = col.primary_key_constraint_name {
8332 self.write_space();
8333 self.write_keyword("CONSTRAINT");
8334 self.write_space();
8335 self.write(cname);
8336 }
8337 self.write_space();
8338 self.write_keyword("PRIMARY KEY");
8339 if let Some(ref order) = col.primary_key_order {
8340 self.write_space();
8341 match order {
8342 SortOrder::Asc => self.write_keyword("ASC"),
8343 SortOrder::Desc => self.write_keyword("DESC"),
8344 }
8345 }
8346 }
8347 }
8348 ConstraintType::Unique => {
8349 if col.unique {
8350 if let Some(ref cname) = col.unique_constraint_name {
8351 self.write_space();
8352 self.write_keyword("CONSTRAINT");
8353 self.write_space();
8354 self.write(cname);
8355 }
8356 self.write_space();
8357 self.write_keyword("UNIQUE");
8358 if col.unique_nulls_not_distinct {
8360 self.write(" NULLS NOT DISTINCT");
8361 }
8362 }
8363 }
8364 ConstraintType::NotNull => {
8365 if col.nullable == Some(false) {
8366 if defer_not_null_after_identity {
8367 pending_not_null_after_identity = true;
8368 continue;
8369 }
8370 if let Some(ref cname) = col.not_null_constraint_name {
8371 self.write_space();
8372 self.write_keyword("CONSTRAINT");
8373 self.write_space();
8374 self.write(cname);
8375 }
8376 self.write_space();
8377 self.write_keyword("NOT NULL");
8378 }
8379 }
8380 ConstraintType::Null => {
8381 if col.nullable == Some(true) {
8382 self.write_space();
8383 self.write_keyword("NULL");
8384 }
8385 }
8386 ConstraintType::Default => {
8387 if let Some(ref default) = col.default {
8388 self.write_space();
8389 self.write_keyword("DEFAULT");
8390 self.write_space();
8391 self.generate_expression(default)?;
8392 }
8393 }
8394 ConstraintType::AutoIncrement => {
8395 if col.auto_increment {
8396 if matches!(
8398 self.config.dialect,
8399 Some(crate::dialects::DialectType::DuckDB)
8400 ) {
8401 } else if matches!(
8403 self.config.dialect,
8404 Some(crate::dialects::DialectType::Materialize)
8405 ) {
8406 if !matches!(col.nullable, Some(false)) {
8408 self.write_space();
8409 self.write_keyword("NOT NULL");
8410 }
8411 } else if matches!(
8412 self.config.dialect,
8413 Some(crate::dialects::DialectType::PostgreSQL)
8414 ) {
8415 self.write_space();
8417 self.generate_auto_increment_keyword(col)?;
8418 } else {
8419 self.write_space();
8420 self.generate_auto_increment_keyword(col)?;
8421 if pending_not_null_after_identity {
8422 self.write_space();
8423 self.write_keyword("NOT NULL");
8424 pending_not_null_after_identity = false;
8425 }
8426 }
8427 } }
8429 ConstraintType::References => {
8430 while references_idx < col.constraints.len() {
8432 if let ColumnConstraint::References(fk_ref) =
8433 &col.constraints[references_idx]
8434 {
8435 if let Some(ref name) = fk_ref.constraint_name {
8437 self.write_space();
8438 self.write_keyword("CONSTRAINT");
8439 self.write_space();
8440 self.write(name);
8441 }
8442 self.write_space();
8443 if fk_ref.has_foreign_key_keywords {
8444 self.write_keyword("FOREIGN KEY");
8445 self.write_space();
8446 }
8447 self.write_keyword("REFERENCES");
8448 self.write_space();
8449 self.generate_table(&fk_ref.table)?;
8450 if !fk_ref.columns.is_empty() {
8451 self.write(" (");
8452 for (i, c) in fk_ref.columns.iter().enumerate() {
8453 if i > 0 {
8454 self.write(", ");
8455 }
8456 self.generate_identifier(c)?;
8457 }
8458 self.write(")");
8459 }
8460 self.generate_referential_actions(fk_ref)?;
8461 references_idx += 1;
8462 break;
8463 }
8464 references_idx += 1;
8465 }
8466 }
8467 ConstraintType::Check => {
8468 while check_idx < col.constraints.len() {
8470 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
8471 if check_idx == 0 {
8473 if let Some(ref cname) = col.check_constraint_name {
8474 self.write_space();
8475 self.write_keyword("CONSTRAINT");
8476 self.write_space();
8477 self.write(cname);
8478 }
8479 }
8480 self.write_space();
8481 self.write_keyword("CHECK");
8482 self.write(" (");
8483 self.generate_expression(expr)?;
8484 self.write(")");
8485 check_idx += 1;
8486 break;
8487 }
8488 check_idx += 1;
8489 }
8490 }
8491 ConstraintType::GeneratedAsIdentity => {
8492 while generated_idx < col.constraints.len() {
8494 if let ColumnConstraint::GeneratedAsIdentity(gen) =
8495 &col.constraints[generated_idx]
8496 {
8497 self.write_space();
8498 if matches!(
8500 self.config.dialect,
8501 Some(crate::dialects::DialectType::Redshift)
8502 ) {
8503 self.write_keyword("IDENTITY");
8504 self.write("(");
8505 if let Some(ref start) = gen.start {
8506 self.generate_expression(start)?;
8507 } else {
8508 self.write("0");
8509 }
8510 self.write(", ");
8511 if let Some(ref incr) = gen.increment {
8512 self.generate_expression(incr)?;
8513 } else {
8514 self.write("1");
8515 }
8516 self.write(")");
8517 } else {
8518 self.write_keyword("GENERATED");
8519 if gen.always {
8520 self.write_space();
8521 self.write_keyword("ALWAYS");
8522 } else {
8523 self.write_space();
8524 self.write_keyword("BY DEFAULT");
8525 if gen.on_null {
8526 self.write_space();
8527 self.write_keyword("ON NULL");
8528 }
8529 }
8530 self.write_space();
8531 self.write_keyword("AS IDENTITY");
8532
8533 let has_options = gen.start.is_some()
8534 || gen.increment.is_some()
8535 || gen.minvalue.is_some()
8536 || gen.maxvalue.is_some()
8537 || gen.cycle.is_some();
8538 if has_options {
8539 self.write(" (");
8540 let mut first = true;
8541 if let Some(ref start) = gen.start {
8542 if !first {
8543 self.write(" ");
8544 }
8545 first = false;
8546 self.write_keyword("START WITH");
8547 self.write_space();
8548 self.generate_expression(start)?;
8549 }
8550 if let Some(ref incr) = gen.increment {
8551 if !first {
8552 self.write(" ");
8553 }
8554 first = false;
8555 self.write_keyword("INCREMENT BY");
8556 self.write_space();
8557 self.generate_expression(incr)?;
8558 }
8559 if let Some(ref minv) = gen.minvalue {
8560 if !first {
8561 self.write(" ");
8562 }
8563 first = false;
8564 self.write_keyword("MINVALUE");
8565 self.write_space();
8566 self.generate_expression(minv)?;
8567 }
8568 if let Some(ref maxv) = gen.maxvalue {
8569 if !first {
8570 self.write(" ");
8571 }
8572 first = false;
8573 self.write_keyword("MAXVALUE");
8574 self.write_space();
8575 self.generate_expression(maxv)?;
8576 }
8577 if let Some(cycle) = gen.cycle {
8578 if !first {
8579 self.write(" ");
8580 }
8581 if cycle {
8582 self.write_keyword("CYCLE");
8583 } else {
8584 self.write_keyword("NO CYCLE");
8585 }
8586 }
8587 self.write(")");
8588 }
8589 }
8590 generated_idx += 1;
8591 break;
8592 }
8593 generated_idx += 1;
8594 }
8595 }
8596 ConstraintType::Collate => {
8597 while collate_idx < col.constraints.len() {
8599 if let ColumnConstraint::Collate(collation) =
8600 &col.constraints[collate_idx]
8601 {
8602 self.write_space();
8603 self.write_keyword("COLLATE");
8604 self.write_space();
8605 self.generate_identifier(collation)?;
8606 collate_idx += 1;
8607 break;
8608 }
8609 collate_idx += 1;
8610 }
8611 }
8612 ConstraintType::Comment => {
8613 while comment_idx < col.constraints.len() {
8615 if let ColumnConstraint::Comment(comment) =
8616 &col.constraints[comment_idx]
8617 {
8618 self.write_space();
8619 self.write_keyword("COMMENT");
8620 self.write_space();
8621 self.generate_string_literal(comment)?;
8622 comment_idx += 1;
8623 break;
8624 }
8625 comment_idx += 1;
8626 }
8627 }
8628 ConstraintType::Tags => {
8629 for constraint in &col.constraints {
8631 if let ColumnConstraint::Tags(tags) = constraint {
8632 self.write_space();
8633 self.write_keyword("TAG");
8634 self.write(" (");
8635 for (i, expr) in tags.expressions.iter().enumerate() {
8636 if i > 0 {
8637 self.write(", ");
8638 }
8639 self.generate_expression(expr)?;
8640 }
8641 self.write(")");
8642 break;
8643 }
8644 }
8645 }
8646 ConstraintType::ComputedColumn => {
8647 for constraint in &col.constraints {
8649 if let ColumnConstraint::ComputedColumn(cc) = constraint {
8650 self.write_space();
8651 self.generate_computed_column_inline(cc)?;
8652 break;
8653 }
8654 }
8655 }
8656 ConstraintType::GeneratedAsRow => {
8657 for constraint in &col.constraints {
8659 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
8660 self.write_space();
8661 self.generate_generated_as_row_inline(gar)?;
8662 break;
8663 }
8664 }
8665 }
8666 ConstraintType::OnUpdate => {
8667 if let Some(ref expr) = col.on_update {
8668 self.write_space();
8669 self.write_keyword("ON UPDATE");
8670 self.write_space();
8671 self.generate_expression(expr)?;
8672 }
8673 }
8674 ConstraintType::Encode => {
8675 if let Some(ref encoding) = col.encoding {
8676 self.write_space();
8677 self.write_keyword("ENCODE");
8678 self.write_space();
8679 self.write(encoding);
8680 }
8681 }
8682 ConstraintType::Path => {
8683 for constraint in &col.constraints {
8685 if let ColumnConstraint::Path(path_expr) = constraint {
8686 self.write_space();
8687 self.write_keyword("PATH");
8688 self.write_space();
8689 self.generate_expression(path_expr)?;
8690 break;
8691 }
8692 }
8693 }
8694 }
8695 }
8696 if pending_not_null_after_identity {
8697 self.write_space();
8698 self.write_keyword("NOT NULL");
8699 }
8700 } else {
8701 if col.primary_key {
8703 self.write_space();
8704 self.write_keyword("PRIMARY KEY");
8705 if let Some(ref order) = col.primary_key_order {
8706 self.write_space();
8707 match order {
8708 SortOrder::Asc => self.write_keyword("ASC"),
8709 SortOrder::Desc => self.write_keyword("DESC"),
8710 }
8711 }
8712 }
8713
8714 if col.unique {
8715 self.write_space();
8716 self.write_keyword("UNIQUE");
8717 if col.unique_nulls_not_distinct {
8719 self.write(" NULLS NOT DISTINCT");
8720 }
8721 }
8722
8723 match col.nullable {
8724 Some(false) => {
8725 self.write_space();
8726 self.write_keyword("NOT NULL");
8727 }
8728 Some(true) => {
8729 self.write_space();
8730 self.write_keyword("NULL");
8731 }
8732 None => {}
8733 }
8734
8735 if let Some(ref default) = col.default {
8736 self.write_space();
8737 self.write_keyword("DEFAULT");
8738 self.write_space();
8739 self.generate_expression(default)?;
8740 }
8741
8742 if col.auto_increment {
8743 self.write_space();
8744 self.generate_auto_increment_keyword(col)?;
8745 }
8746
8747 for constraint in &col.constraints {
8749 match constraint {
8750 ColumnConstraint::References(fk_ref) => {
8751 self.write_space();
8752 if fk_ref.has_foreign_key_keywords {
8753 self.write_keyword("FOREIGN KEY");
8754 self.write_space();
8755 }
8756 self.write_keyword("REFERENCES");
8757 self.write_space();
8758 self.generate_table(&fk_ref.table)?;
8759 if !fk_ref.columns.is_empty() {
8760 self.write(" (");
8761 for (i, c) in fk_ref.columns.iter().enumerate() {
8762 if i > 0 {
8763 self.write(", ");
8764 }
8765 self.generate_identifier(c)?;
8766 }
8767 self.write(")");
8768 }
8769 self.generate_referential_actions(fk_ref)?;
8770 }
8771 ColumnConstraint::Check(expr) => {
8772 self.write_space();
8773 self.write_keyword("CHECK");
8774 self.write(" (");
8775 self.generate_expression(expr)?;
8776 self.write(")");
8777 }
8778 ColumnConstraint::GeneratedAsIdentity(gen) => {
8779 self.write_space();
8780 if matches!(
8782 self.config.dialect,
8783 Some(crate::dialects::DialectType::Redshift)
8784 ) {
8785 self.write_keyword("IDENTITY");
8786 self.write("(");
8787 if let Some(ref start) = gen.start {
8788 self.generate_expression(start)?;
8789 } else {
8790 self.write("0");
8791 }
8792 self.write(", ");
8793 if let Some(ref incr) = gen.increment {
8794 self.generate_expression(incr)?;
8795 } else {
8796 self.write("1");
8797 }
8798 self.write(")");
8799 } else {
8800 self.write_keyword("GENERATED");
8801 if gen.always {
8802 self.write_space();
8803 self.write_keyword("ALWAYS");
8804 } else {
8805 self.write_space();
8806 self.write_keyword("BY DEFAULT");
8807 if gen.on_null {
8808 self.write_space();
8809 self.write_keyword("ON NULL");
8810 }
8811 }
8812 self.write_space();
8813 self.write_keyword("AS IDENTITY");
8814
8815 let has_options = gen.start.is_some()
8816 || gen.increment.is_some()
8817 || gen.minvalue.is_some()
8818 || gen.maxvalue.is_some()
8819 || gen.cycle.is_some();
8820 if has_options {
8821 self.write(" (");
8822 let mut first = true;
8823 if let Some(ref start) = gen.start {
8824 if !first {
8825 self.write(" ");
8826 }
8827 first = false;
8828 self.write_keyword("START WITH");
8829 self.write_space();
8830 self.generate_expression(start)?;
8831 }
8832 if let Some(ref incr) = gen.increment {
8833 if !first {
8834 self.write(" ");
8835 }
8836 first = false;
8837 self.write_keyword("INCREMENT BY");
8838 self.write_space();
8839 self.generate_expression(incr)?;
8840 }
8841 if let Some(ref minv) = gen.minvalue {
8842 if !first {
8843 self.write(" ");
8844 }
8845 first = false;
8846 self.write_keyword("MINVALUE");
8847 self.write_space();
8848 self.generate_expression(minv)?;
8849 }
8850 if let Some(ref maxv) = gen.maxvalue {
8851 if !first {
8852 self.write(" ");
8853 }
8854 first = false;
8855 self.write_keyword("MAXVALUE");
8856 self.write_space();
8857 self.generate_expression(maxv)?;
8858 }
8859 if let Some(cycle) = gen.cycle {
8860 if !first {
8861 self.write(" ");
8862 }
8863 if cycle {
8864 self.write_keyword("CYCLE");
8865 } else {
8866 self.write_keyword("NO CYCLE");
8867 }
8868 }
8869 self.write(")");
8870 }
8871 }
8872 }
8873 ColumnConstraint::Collate(collation) => {
8874 self.write_space();
8875 self.write_keyword("COLLATE");
8876 self.write_space();
8877 self.generate_identifier(collation)?;
8878 }
8879 ColumnConstraint::Comment(comment) => {
8880 self.write_space();
8881 self.write_keyword("COMMENT");
8882 self.write_space();
8883 self.generate_string_literal(comment)?;
8884 }
8885 ColumnConstraint::Path(path_expr) => {
8886 self.write_space();
8887 self.write_keyword("PATH");
8888 self.write_space();
8889 self.generate_expression(path_expr)?;
8890 }
8891 _ => {} }
8893 }
8894
8895 if let Some(ref encoding) = col.encoding {
8897 self.write_space();
8898 self.write_keyword("ENCODE");
8899 self.write_space();
8900 self.write(encoding);
8901 }
8902 }
8903
8904 if let Some(ref codec) = col.codec {
8906 self.write_space();
8907 self.write_keyword("CODEC");
8908 self.write("(");
8909 self.write(codec);
8910 self.write(")");
8911 }
8912
8913 if let Some(ref ephemeral) = col.ephemeral {
8915 self.write_space();
8916 self.write_keyword("EPHEMERAL");
8917 if let Some(ref expr) = ephemeral {
8918 self.write_space();
8919 self.generate_expression(expr)?;
8920 }
8921 }
8922
8923 if let Some(ref mat_expr) = col.materialized_expr {
8925 self.write_space();
8926 self.write_keyword("MATERIALIZED");
8927 self.write_space();
8928 self.generate_expression(mat_expr)?;
8929 }
8930
8931 if let Some(ref alias_expr) = col.alias_expr {
8933 self.write_space();
8934 self.write_keyword("ALIAS");
8935 self.write_space();
8936 self.generate_expression(alias_expr)?;
8937 }
8938
8939 if let Some(ref ttl_expr) = col.ttl_expr {
8941 self.write_space();
8942 self.write_keyword("TTL");
8943 self.write_space();
8944 self.generate_expression(ttl_expr)?;
8945 }
8946
8947 if col.not_for_replication
8949 && matches!(
8950 self.config.dialect,
8951 Some(crate::dialects::DialectType::TSQL)
8952 | Some(crate::dialects::DialectType::Fabric)
8953 )
8954 {
8955 self.write_space();
8956 self.write_keyword("NOT FOR REPLICATION");
8957 }
8958
8959 if !col.options.is_empty() {
8961 self.write_space();
8962 self.generate_options_clause(&col.options)?;
8963 }
8964
8965 if !col.primary_key
8968 && self
8969 .sqlite_inline_pk_columns
8970 .contains(&col.name.name.to_ascii_lowercase())
8971 {
8972 self.write_space();
8973 self.write_keyword("PRIMARY KEY");
8974 }
8975
8976 if serial_expansion.is_some() {
8979 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
8980 self.write_space();
8981 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
8982 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
8983 self.write_space();
8984 self.write_keyword("NOT NULL");
8985 }
8986 }
8987
8988 Ok(())
8989 }
8990
8991 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
8992 match constraint {
8993 TableConstraint::PrimaryKey {
8994 name,
8995 columns,
8996 include_columns,
8997 modifiers,
8998 has_constraint_keyword,
8999 } => {
9000 if let Some(ref n) = name {
9001 if *has_constraint_keyword {
9002 self.write_keyword("CONSTRAINT");
9003 self.write_space();
9004 self.generate_identifier(n)?;
9005 self.write_space();
9006 }
9007 }
9008 self.write_keyword("PRIMARY KEY");
9009 if let Some(ref clustered) = modifiers.clustered {
9011 self.write_space();
9012 self.write_keyword(clustered);
9013 }
9014 if let Some(ref n) = name {
9016 if !*has_constraint_keyword {
9017 self.write_space();
9018 self.generate_identifier(n)?;
9019 }
9020 }
9021 self.write(" (");
9022 for (i, col) in columns.iter().enumerate() {
9023 if i > 0 {
9024 self.write(", ");
9025 }
9026 self.generate_identifier(col)?;
9027 }
9028 self.write(")");
9029 if !include_columns.is_empty() {
9030 self.write_space();
9031 self.write_keyword("INCLUDE");
9032 self.write(" (");
9033 for (i, col) in include_columns.iter().enumerate() {
9034 if i > 0 {
9035 self.write(", ");
9036 }
9037 self.generate_identifier(col)?;
9038 }
9039 self.write(")");
9040 }
9041 self.generate_constraint_modifiers(modifiers);
9042 }
9043 TableConstraint::Unique {
9044 name,
9045 columns,
9046 columns_parenthesized,
9047 modifiers,
9048 has_constraint_keyword,
9049 nulls_not_distinct,
9050 } => {
9051 if let Some(ref n) = name {
9052 if *has_constraint_keyword {
9053 self.write_keyword("CONSTRAINT");
9054 self.write_space();
9055 self.generate_identifier(n)?;
9056 self.write_space();
9057 }
9058 }
9059 self.write_keyword("UNIQUE");
9060 if let Some(ref clustered) = modifiers.clustered {
9062 self.write_space();
9063 self.write_keyword(clustered);
9064 }
9065 if *nulls_not_distinct {
9067 self.write(" NULLS NOT DISTINCT");
9068 }
9069 if let Some(ref n) = name {
9071 if !*has_constraint_keyword {
9072 self.write_space();
9073 self.generate_identifier(n)?;
9074 }
9075 }
9076 if *columns_parenthesized {
9077 self.write(" (");
9078 for (i, col) in columns.iter().enumerate() {
9079 if i > 0 {
9080 self.write(", ");
9081 }
9082 self.generate_identifier(col)?;
9083 }
9084 self.write(")");
9085 } else {
9086 for col in columns.iter() {
9088 self.write_space();
9089 self.generate_identifier(col)?;
9090 }
9091 }
9092 self.generate_constraint_modifiers(modifiers);
9093 }
9094 TableConstraint::ForeignKey {
9095 name,
9096 columns,
9097 references,
9098 on_delete,
9099 on_update,
9100 modifiers,
9101 } => {
9102 if let Some(ref n) = name {
9103 self.write_keyword("CONSTRAINT");
9104 self.write_space();
9105 self.generate_identifier(n)?;
9106 self.write_space();
9107 }
9108 self.write_keyword("FOREIGN KEY");
9109 self.write(" (");
9110 for (i, col) in columns.iter().enumerate() {
9111 if i > 0 {
9112 self.write(", ");
9113 }
9114 self.generate_identifier(col)?;
9115 }
9116 self.write(")");
9117 if let Some(ref refs) = references {
9118 self.write(" ");
9119 self.write_keyword("REFERENCES");
9120 self.write_space();
9121 self.generate_table(&refs.table)?;
9122 if !refs.columns.is_empty() {
9123 if self.config.pretty {
9124 self.write(" (");
9125 self.write_newline();
9126 self.indent_level += 1;
9127 for (i, col) in refs.columns.iter().enumerate() {
9128 if i > 0 {
9129 self.write(",");
9130 self.write_newline();
9131 }
9132 self.write_indent();
9133 self.generate_identifier(col)?;
9134 }
9135 self.indent_level -= 1;
9136 self.write_newline();
9137 self.write_indent();
9138 self.write(")");
9139 } else {
9140 self.write(" (");
9141 for (i, col) in refs.columns.iter().enumerate() {
9142 if i > 0 {
9143 self.write(", ");
9144 }
9145 self.generate_identifier(col)?;
9146 }
9147 self.write(")");
9148 }
9149 }
9150 self.generate_referential_actions(refs)?;
9151 } else {
9152 if let Some(ref action) = on_delete {
9154 self.write_space();
9155 self.write_keyword("ON DELETE");
9156 self.write_space();
9157 self.generate_referential_action(action);
9158 }
9159 if let Some(ref action) = on_update {
9160 self.write_space();
9161 self.write_keyword("ON UPDATE");
9162 self.write_space();
9163 self.generate_referential_action(action);
9164 }
9165 }
9166 self.generate_constraint_modifiers(modifiers);
9167 }
9168 TableConstraint::Check {
9169 name,
9170 expression,
9171 modifiers,
9172 } => {
9173 if let Some(ref n) = name {
9174 self.write_keyword("CONSTRAINT");
9175 self.write_space();
9176 self.generate_identifier(n)?;
9177 self.write_space();
9178 }
9179 self.write_keyword("CHECK");
9180 self.write(" (");
9181 self.generate_expression(expression)?;
9182 self.write(")");
9183 self.generate_constraint_modifiers(modifiers);
9184 }
9185 TableConstraint::Assume {
9186 name,
9187 expression,
9188 } => {
9189 if let Some(ref n) = name {
9190 self.write_keyword("CONSTRAINT");
9191 self.write_space();
9192 self.generate_identifier(n)?;
9193 self.write_space();
9194 }
9195 self.write_keyword("ASSUME");
9196 self.write(" (");
9197 self.generate_expression(expression)?;
9198 self.write(")");
9199 }
9200 TableConstraint::Index {
9201 name,
9202 columns,
9203 kind,
9204 modifiers,
9205 use_key_keyword,
9206 expression,
9207 index_type,
9208 granularity,
9209 } => {
9210 if expression.is_some() {
9212 self.write_keyword("INDEX");
9213 if let Some(ref n) = name {
9214 self.write_space();
9215 self.generate_identifier(n)?;
9216 }
9217 if let Some(ref expr) = expression {
9218 self.write_space();
9219 self.generate_expression(expr)?;
9220 }
9221 if let Some(ref idx_type) = index_type {
9222 self.write_space();
9223 self.write_keyword("TYPE");
9224 self.write_space();
9225 self.generate_expression(idx_type)?;
9226 }
9227 if let Some(ref gran) = granularity {
9228 self.write_space();
9229 self.write_keyword("GRANULARITY");
9230 self.write_space();
9231 self.generate_expression(gran)?;
9232 }
9233 } else {
9234 use crate::dialects::DialectType;
9238 let index_keyword = if *use_key_keyword
9239 && !matches!(self.config.dialect, Some(DialectType::MySQL))
9240 {
9241 "KEY"
9242 } else {
9243 "INDEX"
9244 };
9245
9246 if let Some(ref k) = kind {
9248 self.write_keyword(k);
9249 if k != "UNIQUE" {
9251 self.write_space();
9252 self.write_keyword(index_keyword);
9253 }
9254 } else {
9255 self.write_keyword(index_keyword);
9256 }
9257
9258 if modifiers.using_before_columns && name.is_none() {
9260 if let Some(ref using) = modifiers.using {
9261 self.write_space();
9262 self.write_keyword("USING");
9263 self.write_space();
9264 self.write_keyword(using);
9265 }
9266 }
9267
9268 if let Some(ref n) = name {
9270 self.write_space();
9271 self.generate_identifier(n)?;
9272 }
9273
9274 if modifiers.using_before_columns && name.is_some() {
9276 if let Some(ref using) = modifiers.using {
9277 self.write_space();
9278 self.write_keyword("USING");
9279 self.write_space();
9280 self.write_keyword(using);
9281 }
9282 }
9283
9284 self.write(" (");
9286 for (i, col) in columns.iter().enumerate() {
9287 if i > 0 {
9288 self.write(", ");
9289 }
9290 self.generate_identifier(col)?;
9291 }
9292 self.write(")");
9293
9294 if !modifiers.using_before_columns {
9296 if let Some(ref using) = modifiers.using {
9297 self.write_space();
9298 self.write_keyword("USING");
9299 self.write_space();
9300 self.write_keyword(using);
9301 }
9302 }
9303
9304 self.generate_constraint_modifiers_without_using(modifiers);
9306 }
9307 }
9308 TableConstraint::Projection { name, expression } => {
9309 self.write_keyword("PROJECTION");
9311 self.write_space();
9312 self.generate_identifier(name)?;
9313 self.write(" (");
9314 self.generate_expression(expression)?;
9315 self.write(")");
9316 }
9317 TableConstraint::Like { source, options } => {
9318 self.write_keyword("LIKE");
9319 self.write_space();
9320 self.generate_table(source)?;
9321 for (action, prop) in options {
9322 self.write_space();
9323 match action {
9324 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
9325 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
9326 }
9327 self.write_space();
9328 self.write_keyword(prop);
9329 }
9330 }
9331 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
9332 self.write_keyword("PERIOD FOR SYSTEM_TIME");
9333 self.write(" (");
9334 self.generate_identifier(start_col)?;
9335 self.write(", ");
9336 self.generate_identifier(end_col)?;
9337 self.write(")");
9338 }
9339 TableConstraint::Exclude {
9340 name,
9341 using,
9342 elements,
9343 include_columns,
9344 where_clause,
9345 with_params,
9346 using_index_tablespace,
9347 modifiers: _,
9348 } => {
9349 if let Some(ref n) = name {
9350 self.write_keyword("CONSTRAINT");
9351 self.write_space();
9352 self.generate_identifier(n)?;
9353 self.write_space();
9354 }
9355 self.write_keyword("EXCLUDE");
9356 if let Some(ref method) = using {
9357 self.write_space();
9358 self.write_keyword("USING");
9359 self.write_space();
9360 self.write(method);
9361 self.write("(");
9362 } else {
9363 self.write(" (");
9364 }
9365 for (i, elem) in elements.iter().enumerate() {
9366 if i > 0 {
9367 self.write(", ");
9368 }
9369 self.write(&elem.expression);
9370 self.write_space();
9371 self.write_keyword("WITH");
9372 self.write_space();
9373 self.write(&elem.operator);
9374 }
9375 self.write(")");
9376 if !include_columns.is_empty() {
9377 self.write_space();
9378 self.write_keyword("INCLUDE");
9379 self.write(" (");
9380 for (i, col) in include_columns.iter().enumerate() {
9381 if i > 0 {
9382 self.write(", ");
9383 }
9384 self.generate_identifier(col)?;
9385 }
9386 self.write(")");
9387 }
9388 if !with_params.is_empty() {
9389 self.write_space();
9390 self.write_keyword("WITH");
9391 self.write(" (");
9392 for (i, (key, val)) in with_params.iter().enumerate() {
9393 if i > 0 {
9394 self.write(", ");
9395 }
9396 self.write(key);
9397 self.write("=");
9398 self.write(val);
9399 }
9400 self.write(")");
9401 }
9402 if let Some(ref tablespace) = using_index_tablespace {
9403 self.write_space();
9404 self.write_keyword("USING INDEX TABLESPACE");
9405 self.write_space();
9406 self.write(tablespace);
9407 }
9408 if let Some(ref where_expr) = where_clause {
9409 self.write_space();
9410 self.write_keyword("WHERE");
9411 self.write(" (");
9412 self.generate_expression(where_expr)?;
9413 self.write(")");
9414 }
9415 }
9416 TableConstraint::Tags(tags) => {
9417 self.write_keyword("TAG");
9418 self.write(" (");
9419 for (i, expr) in tags.expressions.iter().enumerate() {
9420 if i > 0 {
9421 self.write(", ");
9422 }
9423 self.generate_expression(expr)?;
9424 }
9425 self.write(")");
9426 }
9427 TableConstraint::InitiallyDeferred { deferred } => {
9428 self.write_keyword("INITIALLY");
9429 self.write_space();
9430 if *deferred {
9431 self.write_keyword("DEFERRED");
9432 } else {
9433 self.write_keyword("IMMEDIATE");
9434 }
9435 }
9436 }
9437 Ok(())
9438 }
9439
9440 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9441 if let Some(using) = &modifiers.using {
9443 self.write_space();
9444 self.write_keyword("USING");
9445 self.write_space();
9446 self.write_keyword(using);
9447 }
9448 if let Some(enforced) = modifiers.enforced {
9450 self.write_space();
9451 if enforced {
9452 self.write_keyword("ENFORCED");
9453 } else {
9454 self.write_keyword("NOT ENFORCED");
9455 }
9456 }
9457 if let Some(deferrable) = modifiers.deferrable {
9459 self.write_space();
9460 if deferrable {
9461 self.write_keyword("DEFERRABLE");
9462 } else {
9463 self.write_keyword("NOT DEFERRABLE");
9464 }
9465 }
9466 if let Some(initially_deferred) = modifiers.initially_deferred {
9468 self.write_space();
9469 if initially_deferred {
9470 self.write_keyword("INITIALLY DEFERRED");
9471 } else {
9472 self.write_keyword("INITIALLY IMMEDIATE");
9473 }
9474 }
9475 if modifiers.norely {
9477 self.write_space();
9478 self.write_keyword("NORELY");
9479 }
9480 if modifiers.rely {
9482 self.write_space();
9483 self.write_keyword("RELY");
9484 }
9485 if modifiers.not_valid {
9487 self.write_space();
9488 self.write_keyword("NOT VALID");
9489 }
9490 if let Some(on_conflict) = &modifiers.on_conflict {
9492 self.write_space();
9493 self.write_keyword("ON CONFLICT");
9494 self.write_space();
9495 self.write_keyword(on_conflict);
9496 }
9497 if !modifiers.with_options.is_empty() {
9499 self.write_space();
9500 self.write_keyword("WITH");
9501 self.write(" (");
9502 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
9503 if i > 0 {
9504 self.write(", ");
9505 }
9506 self.write(key);
9507 self.write("=");
9508 self.write(value);
9509 }
9510 self.write(")");
9511 }
9512 if let Some(ref fg) = modifiers.on_filegroup {
9514 self.write_space();
9515 self.write_keyword("ON");
9516 self.write_space();
9517 let _ = self.generate_identifier(fg);
9518 }
9519 }
9520
9521 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
9523 if let Some(enforced) = modifiers.enforced {
9525 self.write_space();
9526 if enforced {
9527 self.write_keyword("ENFORCED");
9528 } else {
9529 self.write_keyword("NOT ENFORCED");
9530 }
9531 }
9532 if let Some(deferrable) = modifiers.deferrable {
9534 self.write_space();
9535 if deferrable {
9536 self.write_keyword("DEFERRABLE");
9537 } else {
9538 self.write_keyword("NOT DEFERRABLE");
9539 }
9540 }
9541 if let Some(initially_deferred) = modifiers.initially_deferred {
9543 self.write_space();
9544 if initially_deferred {
9545 self.write_keyword("INITIALLY DEFERRED");
9546 } else {
9547 self.write_keyword("INITIALLY IMMEDIATE");
9548 }
9549 }
9550 if modifiers.norely {
9552 self.write_space();
9553 self.write_keyword("NORELY");
9554 }
9555 if modifiers.rely {
9557 self.write_space();
9558 self.write_keyword("RELY");
9559 }
9560 if modifiers.not_valid {
9562 self.write_space();
9563 self.write_keyword("NOT VALID");
9564 }
9565 if let Some(on_conflict) = &modifiers.on_conflict {
9567 self.write_space();
9568 self.write_keyword("ON CONFLICT");
9569 self.write_space();
9570 self.write_keyword(on_conflict);
9571 }
9572 self.generate_index_specific_modifiers(modifiers);
9574 }
9575
9576 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9578 if let Some(ref comment) = modifiers.comment {
9579 self.write_space();
9580 self.write_keyword("COMMENT");
9581 self.write(" '");
9582 self.write(comment);
9583 self.write("'");
9584 }
9585 if let Some(visible) = modifiers.visible {
9586 self.write_space();
9587 if visible {
9588 self.write_keyword("VISIBLE");
9589 } else {
9590 self.write_keyword("INVISIBLE");
9591 }
9592 }
9593 if let Some(ref attr) = modifiers.engine_attribute {
9594 self.write_space();
9595 self.write_keyword("ENGINE_ATTRIBUTE");
9596 self.write(" = '");
9597 self.write(attr);
9598 self.write("'");
9599 }
9600 if let Some(ref parser) = modifiers.with_parser {
9601 self.write_space();
9602 self.write_keyword("WITH PARSER");
9603 self.write_space();
9604 self.write(parser);
9605 }
9606 }
9607
9608 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
9609 if !fk_ref.match_after_actions {
9611 if let Some(ref match_type) = fk_ref.match_type {
9612 self.write_space();
9613 self.write_keyword("MATCH");
9614 self.write_space();
9615 match match_type {
9616 MatchType::Full => self.write_keyword("FULL"),
9617 MatchType::Partial => self.write_keyword("PARTIAL"),
9618 MatchType::Simple => self.write_keyword("SIMPLE"),
9619 }
9620 }
9621 }
9622
9623 if fk_ref.on_update_first {
9625 if let Some(ref action) = fk_ref.on_update {
9626 self.write_space();
9627 self.write_keyword("ON UPDATE");
9628 self.write_space();
9629 self.generate_referential_action(action);
9630 }
9631 if let Some(ref action) = fk_ref.on_delete {
9632 self.write_space();
9633 self.write_keyword("ON DELETE");
9634 self.write_space();
9635 self.generate_referential_action(action);
9636 }
9637 } else {
9638 if let Some(ref action) = fk_ref.on_delete {
9639 self.write_space();
9640 self.write_keyword("ON DELETE");
9641 self.write_space();
9642 self.generate_referential_action(action);
9643 }
9644 if let Some(ref action) = fk_ref.on_update {
9645 self.write_space();
9646 self.write_keyword("ON UPDATE");
9647 self.write_space();
9648 self.generate_referential_action(action);
9649 }
9650 }
9651
9652 if fk_ref.match_after_actions {
9654 if let Some(ref match_type) = fk_ref.match_type {
9655 self.write_space();
9656 self.write_keyword("MATCH");
9657 self.write_space();
9658 match match_type {
9659 MatchType::Full => self.write_keyword("FULL"),
9660 MatchType::Partial => self.write_keyword("PARTIAL"),
9661 MatchType::Simple => self.write_keyword("SIMPLE"),
9662 }
9663 }
9664 }
9665
9666 if let Some(deferrable) = fk_ref.deferrable {
9668 self.write_space();
9669 if deferrable {
9670 self.write_keyword("DEFERRABLE");
9671 } else {
9672 self.write_keyword("NOT DEFERRABLE");
9673 }
9674 }
9675
9676 Ok(())
9677 }
9678
9679 fn generate_referential_action(&mut self, action: &ReferentialAction) {
9680 match action {
9681 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
9682 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
9683 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
9684 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
9685 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
9686 }
9687 }
9688
9689 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
9690 if let Some(ref object_id_args) = dt.object_id_args {
9692 if matches!(
9693 self.config.dialect,
9694 Some(crate::dialects::DialectType::TSQL) | Some(crate::dialects::DialectType::Fabric)
9695 ) {
9696 self.write_keyword("IF NOT OBJECT_ID");
9697 self.write("(");
9698 self.write(object_id_args);
9699 self.write(")");
9700 self.write_space();
9701 self.write_keyword("IS NULL BEGIN DROP TABLE");
9702 self.write_space();
9703 for (i, table) in dt.names.iter().enumerate() {
9704 if i > 0 {
9705 self.write(", ");
9706 }
9707 self.generate_table(table)?;
9708 }
9709 self.write("; ");
9710 self.write_keyword("END");
9711 return Ok(());
9712 }
9713 }
9714
9715 let saved_athena_hive_context = self.athena_hive_context;
9717 if matches!(
9718 self.config.dialect,
9719 Some(crate::dialects::DialectType::Athena)
9720 ) {
9721 self.athena_hive_context = true;
9722 }
9723
9724 for comment in &dt.leading_comments {
9726 self.write_formatted_comment(comment);
9727 self.write_space();
9728 }
9729 self.write_keyword("DROP TABLE");
9730
9731 if dt.if_exists {
9732 self.write_space();
9733 self.write_keyword("IF EXISTS");
9734 }
9735
9736 self.write_space();
9737 for (i, table) in dt.names.iter().enumerate() {
9738 if i > 0 {
9739 self.write(", ");
9740 }
9741 self.generate_table(table)?;
9742 }
9743
9744 if dt.cascade_constraints {
9745 self.write_space();
9746 self.write_keyword("CASCADE CONSTRAINTS");
9747 } else if dt.cascade {
9748 self.write_space();
9749 self.write_keyword("CASCADE");
9750 }
9751
9752 if dt.purge {
9753 self.write_space();
9754 self.write_keyword("PURGE");
9755 }
9756
9757 if dt.sync {
9758 self.write_space();
9759 self.write_keyword("SYNC");
9760 }
9761
9762 self.athena_hive_context = saved_athena_hive_context;
9764
9765 Ok(())
9766 }
9767
9768 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
9769 let saved_athena_hive_context = self.athena_hive_context;
9771 if matches!(
9772 self.config.dialect,
9773 Some(crate::dialects::DialectType::Athena)
9774 ) {
9775 self.athena_hive_context = true;
9776 }
9777
9778 self.write_keyword("ALTER TABLE");
9779 if at.if_exists {
9780 self.write_space();
9781 self.write_keyword("IF EXISTS");
9782 }
9783 self.write_space();
9784 self.generate_table(&at.name)?;
9785
9786 if let Some(ref on_cluster) = at.on_cluster {
9788 self.write_space();
9789 self.generate_on_cluster(on_cluster)?;
9790 }
9791
9792 if let Some(ref partition) = at.partition {
9794 self.write_space();
9795 self.write_keyword("PARTITION");
9796 self.write("(");
9797 for (i, (key, value)) in partition.iter().enumerate() {
9798 if i > 0 {
9799 self.write(", ");
9800 }
9801 self.generate_identifier(key)?;
9802 self.write(" = ");
9803 self.generate_expression(value)?;
9804 }
9805 self.write(")");
9806 }
9807
9808 if let Some(ref with_check) = at.with_check {
9810 self.write_space();
9811 self.write_keyword(with_check);
9812 }
9813
9814 if self.config.pretty {
9815 self.write_newline();
9817 self.indent_level += 1;
9818 for (i, action) in at.actions.iter().enumerate() {
9819 let is_continuation = i > 0
9821 && matches!(
9822 (&at.actions[i - 1], action),
9823 (
9824 AlterTableAction::AddColumn { .. },
9825 AlterTableAction::AddColumn { .. }
9826 ) | (
9827 AlterTableAction::AddConstraint(_),
9828 AlterTableAction::AddConstraint(_)
9829 )
9830 );
9831 if i > 0 {
9832 self.write(",");
9833 self.write_newline();
9834 }
9835 self.write_indent();
9836 self.generate_alter_action_with_continuation(action, is_continuation)?;
9837 }
9838 self.indent_level -= 1;
9839 } else {
9840 for (i, action) in at.actions.iter().enumerate() {
9841 let is_continuation = i > 0
9843 && matches!(
9844 (&at.actions[i - 1], action),
9845 (
9846 AlterTableAction::AddColumn { .. },
9847 AlterTableAction::AddColumn { .. }
9848 ) | (
9849 AlterTableAction::AddConstraint(_),
9850 AlterTableAction::AddConstraint(_)
9851 )
9852 );
9853 if i > 0 {
9854 self.write(",");
9855 }
9856 self.write_space();
9857 self.generate_alter_action_with_continuation(action, is_continuation)?;
9858 }
9859 }
9860
9861 if let Some(ref algorithm) = at.algorithm {
9863 self.write(", ");
9864 self.write_keyword("ALGORITHM");
9865 self.write("=");
9866 self.write_keyword(algorithm);
9867 }
9868 if let Some(ref lock) = at.lock {
9869 self.write(", ");
9870 self.write_keyword("LOCK");
9871 self.write("=");
9872 self.write_keyword(lock);
9873 }
9874
9875 self.athena_hive_context = saved_athena_hive_context;
9877
9878 Ok(())
9879 }
9880
9881 fn generate_alter_action_with_continuation(
9882 &mut self,
9883 action: &AlterTableAction,
9884 is_continuation: bool,
9885 ) -> Result<()> {
9886 match action {
9887 AlterTableAction::AddColumn {
9888 column,
9889 if_not_exists,
9890 position,
9891 } => {
9892 use crate::dialects::DialectType;
9893 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
9897 let is_tsql_like = matches!(
9898 self.config.dialect,
9899 Some(DialectType::TSQL) | Some(DialectType::Fabric)
9900 );
9901 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
9903
9904 if is_continuation && (is_snowflake || is_tsql_like) {
9905 } else if is_snowflake {
9907 self.write_keyword("ADD");
9908 self.write_space();
9909 } else if is_athena {
9910 self.write_keyword("ADD COLUMNS");
9912 self.write(" (");
9913 } else if self.config.alter_table_include_column_keyword {
9914 self.write_keyword("ADD COLUMN");
9915 self.write_space();
9916 } else {
9917 self.write_keyword("ADD");
9919 self.write_space();
9920 }
9921
9922 if *if_not_exists {
9923 self.write_keyword("IF NOT EXISTS");
9924 self.write_space();
9925 }
9926 self.generate_column_def(column)?;
9927
9928 if is_athena {
9930 self.write(")");
9931 }
9932
9933 if let Some(pos) = position {
9935 self.write_space();
9936 match pos {
9937 ColumnPosition::First => self.write_keyword("FIRST"),
9938 ColumnPosition::After(col_name) => {
9939 self.write_keyword("AFTER");
9940 self.write_space();
9941 self.generate_identifier(col_name)?;
9942 }
9943 }
9944 }
9945 }
9946 AlterTableAction::DropColumn {
9947 name,
9948 if_exists,
9949 cascade,
9950 } => {
9951 self.write_keyword("DROP COLUMN");
9952 if *if_exists {
9953 self.write_space();
9954 self.write_keyword("IF EXISTS");
9955 }
9956 self.write_space();
9957 self.generate_identifier(name)?;
9958 if *cascade {
9959 self.write_space();
9960 self.write_keyword("CASCADE");
9961 }
9962 }
9963 AlterTableAction::DropColumns { names } => {
9964 self.write_keyword("DROP COLUMNS");
9965 self.write(" (");
9966 for (i, name) in names.iter().enumerate() {
9967 if i > 0 {
9968 self.write(", ");
9969 }
9970 self.generate_identifier(name)?;
9971 }
9972 self.write(")");
9973 }
9974 AlterTableAction::RenameColumn {
9975 old_name,
9976 new_name,
9977 if_exists,
9978 } => {
9979 self.write_keyword("RENAME COLUMN");
9980 if *if_exists {
9981 self.write_space();
9982 self.write_keyword("IF EXISTS");
9983 }
9984 self.write_space();
9985 self.generate_identifier(old_name)?;
9986 self.write_space();
9987 self.write_keyword("TO");
9988 self.write_space();
9989 self.generate_identifier(new_name)?;
9990 }
9991 AlterTableAction::AlterColumn {
9992 name,
9993 action,
9994 use_modify_keyword,
9995 } => {
9996 use crate::dialects::DialectType;
9997 let use_modify = *use_modify_keyword
10000 || (matches!(self.config.dialect, Some(DialectType::MySQL))
10001 && matches!(action, AlterColumnAction::SetDataType { .. }));
10002 if use_modify {
10003 self.write_keyword("MODIFY COLUMN");
10004 self.write_space();
10005 self.generate_identifier(name)?;
10006 if let AlterColumnAction::SetDataType {
10008 data_type,
10009 using: _,
10010 collate,
10011 } = action
10012 {
10013 self.write_space();
10014 self.generate_data_type(data_type)?;
10015 if let Some(collate_name) = collate {
10017 self.write_space();
10018 self.write_keyword("COLLATE");
10019 self.write_space();
10020 self.write(&format!("'{}'", collate_name));
10022 }
10023 } else {
10024 self.write_space();
10025 self.generate_alter_column_action(action)?;
10026 }
10027 } else if matches!(self.config.dialect, Some(DialectType::Hive))
10028 && matches!(action, AlterColumnAction::SetDataType { .. })
10029 {
10030 self.write_keyword("CHANGE COLUMN");
10032 self.write_space();
10033 self.generate_identifier(name)?;
10034 self.write_space();
10035 self.generate_identifier(name)?;
10036 if let AlterColumnAction::SetDataType { data_type, .. } = action {
10037 self.write_space();
10038 self.generate_data_type(data_type)?;
10039 }
10040 } else {
10041 self.write_keyword("ALTER COLUMN");
10042 self.write_space();
10043 self.generate_identifier(name)?;
10044 self.write_space();
10045 self.generate_alter_column_action(action)?;
10046 }
10047 }
10048 AlterTableAction::RenameTable(new_name) => {
10049 let mysql_like = matches!(
10051 self.config.dialect,
10052 Some(DialectType::MySQL)
10053 | Some(DialectType::Doris)
10054 | Some(DialectType::StarRocks)
10055 | Some(DialectType::SingleStore)
10056 );
10057 if mysql_like {
10058 self.write_keyword("RENAME");
10059 } else {
10060 self.write_keyword("RENAME TO");
10061 }
10062 self.write_space();
10063 let rename_table_with_db = !matches!(
10065 self.config.dialect,
10066 Some(DialectType::Doris)
10067 | Some(DialectType::DuckDB)
10068 | Some(DialectType::BigQuery)
10069 | Some(DialectType::PostgreSQL)
10070 );
10071 if !rename_table_with_db {
10072 let mut stripped = new_name.clone();
10073 stripped.schema = None;
10074 stripped.catalog = None;
10075 self.generate_table(&stripped)?;
10076 } else {
10077 self.generate_table(new_name)?;
10078 }
10079 }
10080 AlterTableAction::AddConstraint(constraint) => {
10081 if !is_continuation {
10084 self.write_keyword("ADD");
10085 self.write_space();
10086 }
10087 self.generate_table_constraint(constraint)?;
10088 }
10089 AlterTableAction::DropConstraint { name, if_exists } => {
10090 self.write_keyword("DROP CONSTRAINT");
10091 if *if_exists {
10092 self.write_space();
10093 self.write_keyword("IF EXISTS");
10094 }
10095 self.write_space();
10096 self.generate_identifier(name)?;
10097 }
10098 AlterTableAction::DropForeignKey { name } => {
10099 self.write_keyword("DROP FOREIGN KEY");
10100 self.write_space();
10101 self.generate_identifier(name)?;
10102 }
10103 AlterTableAction::DropPartition {
10104 partitions,
10105 if_exists,
10106 } => {
10107 self.write_keyword("DROP");
10108 if *if_exists {
10109 self.write_space();
10110 self.write_keyword("IF EXISTS");
10111 }
10112 for (i, partition) in partitions.iter().enumerate() {
10113 if i > 0 {
10114 self.write(",");
10115 }
10116 self.write_space();
10117 self.write_keyword("PARTITION");
10118 if partition.len() == 1 && partition[0].0.name == "__expr__" {
10120 self.write_space();
10122 self.generate_expression(&partition[0].1)?;
10123 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
10124 self.write_space();
10126 self.write_keyword("ALL");
10127 } else if partition.len() == 1 && partition[0].0.name == "ID" {
10128 self.write_space();
10130 self.write_keyword("ID");
10131 self.write_space();
10132 self.generate_expression(&partition[0].1)?;
10133 } else {
10134 self.write("(");
10136 for (j, (key, value)) in partition.iter().enumerate() {
10137 if j > 0 {
10138 self.write(", ");
10139 }
10140 self.generate_identifier(key)?;
10141 self.write(" = ");
10142 self.generate_expression(value)?;
10143 }
10144 self.write(")");
10145 }
10146 }
10147 }
10148 AlterTableAction::Delete { where_clause } => {
10149 self.write_keyword("DELETE");
10150 self.write_space();
10151 self.write_keyword("WHERE");
10152 self.write_space();
10153 self.generate_expression(where_clause)?;
10154 }
10155 AlterTableAction::SwapWith(target) => {
10156 self.write_keyword("SWAP WITH");
10157 self.write_space();
10158 self.generate_table(target)?;
10159 }
10160 AlterTableAction::SetProperty { properties } => {
10161 use crate::dialects::DialectType;
10162 self.write_keyword("SET");
10163 let is_trino_presto = matches!(
10165 self.config.dialect,
10166 Some(DialectType::Trino) | Some(DialectType::Presto)
10167 );
10168 if is_trino_presto {
10169 self.write_space();
10170 self.write_keyword("PROPERTIES");
10171 }
10172 let eq = if is_trino_presto { " = " } else { "=" };
10173 for (i, (key, value)) in properties.iter().enumerate() {
10174 if i > 0 {
10175 self.write(",");
10176 }
10177 self.write_space();
10178 if key.contains(' ') {
10180 self.generate_string_literal(key)?;
10181 } else {
10182 self.write(key);
10183 }
10184 self.write(eq);
10185 self.generate_expression(value)?;
10186 }
10187 }
10188 AlterTableAction::UnsetProperty { properties } => {
10189 self.write_keyword("UNSET");
10190 for (i, name) in properties.iter().enumerate() {
10191 if i > 0 {
10192 self.write(",");
10193 }
10194 self.write_space();
10195 self.write(name);
10196 }
10197 }
10198 AlterTableAction::ClusterBy { expressions } => {
10199 self.write_keyword("CLUSTER BY");
10200 self.write(" (");
10201 for (i, expr) in expressions.iter().enumerate() {
10202 if i > 0 {
10203 self.write(", ");
10204 }
10205 self.generate_expression(expr)?;
10206 }
10207 self.write(")");
10208 }
10209 AlterTableAction::SetTag { expressions } => {
10210 self.write_keyword("SET TAG");
10211 for (i, (key, value)) in expressions.iter().enumerate() {
10212 if i > 0 {
10213 self.write(",");
10214 }
10215 self.write_space();
10216 self.write(key);
10217 self.write(" = ");
10218 self.generate_expression(value)?;
10219 }
10220 }
10221 AlterTableAction::UnsetTag { names } => {
10222 self.write_keyword("UNSET TAG");
10223 for (i, name) in names.iter().enumerate() {
10224 if i > 0 {
10225 self.write(",");
10226 }
10227 self.write_space();
10228 self.write(name);
10229 }
10230 }
10231 AlterTableAction::SetOptions { expressions } => {
10232 self.write_keyword("SET");
10233 self.write(" (");
10234 for (i, expr) in expressions.iter().enumerate() {
10235 if i > 0 {
10236 self.write(", ");
10237 }
10238 self.generate_expression(expr)?;
10239 }
10240 self.write(")");
10241 }
10242 AlterTableAction::AlterIndex { name, visible } => {
10243 self.write_keyword("ALTER INDEX");
10244 self.write_space();
10245 self.generate_identifier(name)?;
10246 self.write_space();
10247 if *visible {
10248 self.write_keyword("VISIBLE");
10249 } else {
10250 self.write_keyword("INVISIBLE");
10251 }
10252 }
10253 AlterTableAction::SetAttribute { attribute } => {
10254 self.write_keyword("SET");
10255 self.write_space();
10256 self.write_keyword(attribute);
10257 }
10258 AlterTableAction::SetStageFileFormat { options } => {
10259 self.write_keyword("SET");
10260 self.write_space();
10261 self.write_keyword("STAGE_FILE_FORMAT");
10262 self.write(" = (");
10263 if let Some(opts) = options {
10264 self.generate_space_separated_properties(opts)?;
10265 }
10266 self.write(")");
10267 }
10268 AlterTableAction::SetStageCopyOptions { options } => {
10269 self.write_keyword("SET");
10270 self.write_space();
10271 self.write_keyword("STAGE_COPY_OPTIONS");
10272 self.write(" = (");
10273 if let Some(opts) = options {
10274 self.generate_space_separated_properties(opts)?;
10275 }
10276 self.write(")");
10277 }
10278 AlterTableAction::AddColumns { columns, cascade } => {
10279 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
10282 if is_oracle {
10283 self.write_keyword("ADD");
10284 } else {
10285 self.write_keyword("ADD COLUMNS");
10286 }
10287 self.write(" (");
10288 for (i, col) in columns.iter().enumerate() {
10289 if i > 0 {
10290 self.write(", ");
10291 }
10292 self.generate_column_def(col)?;
10293 }
10294 self.write(")");
10295 if *cascade {
10296 self.write_space();
10297 self.write_keyword("CASCADE");
10298 }
10299 }
10300 AlterTableAction::ChangeColumn {
10301 old_name,
10302 new_name,
10303 data_type,
10304 comment,
10305 cascade,
10306 } => {
10307 use crate::dialects::DialectType;
10308 let is_spark = matches!(
10309 self.config.dialect,
10310 Some(DialectType::Spark) | Some(DialectType::Databricks)
10311 );
10312 let is_rename = old_name.name != new_name.name;
10313
10314 if is_spark {
10315 if is_rename {
10316 self.write_keyword("RENAME COLUMN");
10318 self.write_space();
10319 self.generate_identifier(old_name)?;
10320 self.write_space();
10321 self.write_keyword("TO");
10322 self.write_space();
10323 self.generate_identifier(new_name)?;
10324 } else if comment.is_some() {
10325 self.write_keyword("ALTER COLUMN");
10327 self.write_space();
10328 self.generate_identifier(old_name)?;
10329 self.write_space();
10330 self.write_keyword("COMMENT");
10331 self.write_space();
10332 self.write("'");
10333 self.write(comment.as_ref().unwrap());
10334 self.write("'");
10335 } else if data_type.is_some() {
10336 self.write_keyword("ALTER COLUMN");
10338 self.write_space();
10339 self.generate_identifier(old_name)?;
10340 self.write_space();
10341 self.write_keyword("TYPE");
10342 self.write_space();
10343 self.generate_data_type(data_type.as_ref().unwrap())?;
10344 } else {
10345 self.write_keyword("CHANGE COLUMN");
10347 self.write_space();
10348 self.generate_identifier(old_name)?;
10349 self.write_space();
10350 self.generate_identifier(new_name)?;
10351 }
10352 } else {
10353 if data_type.is_some() {
10355 self.write_keyword("CHANGE COLUMN");
10356 } else {
10357 self.write_keyword("CHANGE");
10358 }
10359 self.write_space();
10360 self.generate_identifier(old_name)?;
10361 self.write_space();
10362 self.generate_identifier(new_name)?;
10363 if let Some(ref dt) = data_type {
10364 self.write_space();
10365 self.generate_data_type(dt)?;
10366 }
10367 if let Some(ref c) = comment {
10368 self.write_space();
10369 self.write_keyword("COMMENT");
10370 self.write_space();
10371 self.write("'");
10372 self.write(c);
10373 self.write("'");
10374 }
10375 if *cascade {
10376 self.write_space();
10377 self.write_keyword("CASCADE");
10378 }
10379 }
10380 }
10381 AlterTableAction::AddPartition {
10382 partition,
10383 if_not_exists,
10384 location,
10385 } => {
10386 self.write_keyword("ADD");
10387 self.write_space();
10388 if *if_not_exists {
10389 self.write_keyword("IF NOT EXISTS");
10390 self.write_space();
10391 }
10392 self.generate_expression(partition)?;
10393 if let Some(ref loc) = location {
10394 self.write_space();
10395 self.write_keyword("LOCATION");
10396 self.write_space();
10397 self.generate_expression(loc)?;
10398 }
10399 }
10400 AlterTableAction::AlterSortKey {
10401 this,
10402 expressions,
10403 compound,
10404 } => {
10405 self.write_keyword("ALTER");
10407 if *compound {
10408 self.write_space();
10409 self.write_keyword("COMPOUND");
10410 }
10411 self.write_space();
10412 self.write_keyword("SORTKEY");
10413 self.write_space();
10414 if let Some(style) = this {
10415 self.write_keyword(style);
10416 } else if !expressions.is_empty() {
10417 self.write("(");
10418 for (i, expr) in expressions.iter().enumerate() {
10419 if i > 0 {
10420 self.write(", ");
10421 }
10422 self.generate_expression(expr)?;
10423 }
10424 self.write(")");
10425 }
10426 }
10427 AlterTableAction::AlterDistStyle { style, distkey } => {
10428 self.write_keyword("ALTER");
10430 self.write_space();
10431 self.write_keyword("DISTSTYLE");
10432 self.write_space();
10433 self.write_keyword(style);
10434 if let Some(col) = distkey {
10435 self.write_space();
10436 self.write_keyword("DISTKEY");
10437 self.write_space();
10438 self.generate_identifier(col)?;
10439 }
10440 }
10441 AlterTableAction::SetTableProperties { properties } => {
10442 self.write_keyword("SET TABLE PROPERTIES");
10444 self.write(" (");
10445 for (i, (key, value)) in properties.iter().enumerate() {
10446 if i > 0 {
10447 self.write(", ");
10448 }
10449 self.generate_expression(key)?;
10450 self.write(" = ");
10451 self.generate_expression(value)?;
10452 }
10453 self.write(")");
10454 }
10455 AlterTableAction::SetLocation { location } => {
10456 self.write_keyword("SET LOCATION");
10458 self.write_space();
10459 self.write("'");
10460 self.write(location);
10461 self.write("'");
10462 }
10463 AlterTableAction::SetFileFormat { format } => {
10464 self.write_keyword("SET FILE FORMAT");
10466 self.write_space();
10467 self.write_keyword(format);
10468 }
10469 AlterTableAction::ReplacePartition { partition, source } => {
10470 self.write_keyword("REPLACE PARTITION");
10472 self.write_space();
10473 self.generate_expression(partition)?;
10474 if let Some(src) = source {
10475 self.write_space();
10476 self.write_keyword("FROM");
10477 self.write_space();
10478 self.generate_expression(src)?;
10479 }
10480 }
10481 AlterTableAction::Raw { sql } => {
10482 self.write(sql);
10483 }
10484 }
10485 Ok(())
10486 }
10487
10488 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
10489 match action {
10490 AlterColumnAction::SetDataType {
10491 data_type,
10492 using,
10493 collate,
10494 } => {
10495 use crate::dialects::DialectType;
10496 let is_no_prefix = matches!(
10501 self.config.dialect,
10502 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
10503 );
10504 let is_type_only = matches!(
10505 self.config.dialect,
10506 Some(DialectType::Redshift)
10507 | Some(DialectType::Spark)
10508 | Some(DialectType::Databricks)
10509 );
10510 if is_type_only {
10511 self.write_keyword("TYPE");
10512 self.write_space();
10513 } else if !is_no_prefix {
10514 self.write_keyword("SET DATA TYPE");
10515 self.write_space();
10516 }
10517 self.generate_data_type(data_type)?;
10518 if let Some(ref collation) = collate {
10519 self.write_space();
10520 self.write_keyword("COLLATE");
10521 self.write_space();
10522 self.write(collation);
10523 }
10524 if let Some(ref using_expr) = using {
10525 self.write_space();
10526 self.write_keyword("USING");
10527 self.write_space();
10528 self.generate_expression(using_expr)?;
10529 }
10530 }
10531 AlterColumnAction::SetDefault(expr) => {
10532 self.write_keyword("SET DEFAULT");
10533 self.write_space();
10534 self.generate_expression(expr)?;
10535 }
10536 AlterColumnAction::DropDefault => {
10537 self.write_keyword("DROP DEFAULT");
10538 }
10539 AlterColumnAction::SetNotNull => {
10540 self.write_keyword("SET NOT NULL");
10541 }
10542 AlterColumnAction::DropNotNull => {
10543 self.write_keyword("DROP NOT NULL");
10544 }
10545 AlterColumnAction::Comment(comment) => {
10546 self.write_keyword("COMMENT");
10547 self.write_space();
10548 self.generate_string_literal(comment)?;
10549 }
10550 AlterColumnAction::SetVisible => {
10551 self.write_keyword("SET VISIBLE");
10552 }
10553 AlterColumnAction::SetInvisible => {
10554 self.write_keyword("SET INVISIBLE");
10555 }
10556 }
10557 Ok(())
10558 }
10559
10560 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
10561 self.write_keyword("CREATE");
10562
10563 if ci.unique {
10564 self.write_space();
10565 self.write_keyword("UNIQUE");
10566 }
10567
10568 if let Some(ref clustered) = ci.clustered {
10570 self.write_space();
10571 self.write_keyword(clustered);
10572 }
10573
10574 self.write_space();
10575 self.write_keyword("INDEX");
10576
10577 if ci.concurrently {
10579 self.write_space();
10580 self.write_keyword("CONCURRENTLY");
10581 }
10582
10583 if ci.if_not_exists {
10584 self.write_space();
10585 self.write_keyword("IF NOT EXISTS");
10586 }
10587
10588 if !ci.name.name.is_empty() {
10590 self.write_space();
10591 self.generate_identifier(&ci.name)?;
10592 }
10593 self.write_space();
10594 self.write_keyword("ON");
10595 if matches!(self.config.dialect, Some(DialectType::Hive)) {
10597 self.write_space();
10598 self.write_keyword("TABLE");
10599 }
10600 self.write_space();
10601 self.generate_table(&ci.table)?;
10602
10603 if !ci.columns.is_empty() || ci.using.is_some() {
10606 let space_before_paren = false;
10607
10608 if let Some(ref using) = ci.using {
10609 self.write_space();
10610 self.write_keyword("USING");
10611 self.write_space();
10612 self.write(using);
10613 if space_before_paren {
10614 self.write(" (");
10615 } else {
10616 self.write("(");
10617 }
10618 } else {
10619 if space_before_paren {
10620 self.write(" (");
10621 } else {
10622 self.write("(");
10623 }
10624 }
10625 for (i, col) in ci.columns.iter().enumerate() {
10626 if i > 0 {
10627 self.write(", ");
10628 }
10629 self.generate_identifier(&col.column)?;
10630 if let Some(ref opclass) = col.opclass {
10631 self.write_space();
10632 self.write(opclass);
10633 }
10634 if col.desc {
10635 self.write_space();
10636 self.write_keyword("DESC");
10637 } else if col.asc {
10638 self.write_space();
10639 self.write_keyword("ASC");
10640 }
10641 if let Some(nulls_first) = col.nulls_first {
10642 self.write_space();
10643 self.write_keyword("NULLS");
10644 self.write_space();
10645 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
10646 }
10647 }
10648 self.write(")");
10649 }
10650
10651 if !ci.include_columns.is_empty() {
10653 self.write_space();
10654 self.write_keyword("INCLUDE");
10655 self.write(" (");
10656 for (i, col) in ci.include_columns.iter().enumerate() {
10657 if i > 0 {
10658 self.write(", ");
10659 }
10660 self.generate_identifier(col)?;
10661 }
10662 self.write(")");
10663 }
10664
10665 if !ci.with_options.is_empty() {
10667 self.write_space();
10668 self.write_keyword("WITH");
10669 self.write(" (");
10670 for (i, (key, value)) in ci.with_options.iter().enumerate() {
10671 if i > 0 {
10672 self.write(", ");
10673 }
10674 self.write(key);
10675 self.write("=");
10676 self.write(value);
10677 }
10678 self.write(")");
10679 }
10680
10681 if let Some(ref where_clause) = ci.where_clause {
10683 self.write_space();
10684 self.write_keyword("WHERE");
10685 self.write_space();
10686 self.generate_expression(where_clause)?;
10687 }
10688
10689 if let Some(ref on_fg) = ci.on_filegroup {
10691 self.write_space();
10692 self.write_keyword("ON");
10693 self.write_space();
10694 self.write(on_fg);
10695 }
10696
10697 Ok(())
10698 }
10699
10700 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
10701 self.write_keyword("DROP INDEX");
10702
10703 if di.concurrently {
10704 self.write_space();
10705 self.write_keyword("CONCURRENTLY");
10706 }
10707
10708 if di.if_exists {
10709 self.write_space();
10710 self.write_keyword("IF EXISTS");
10711 }
10712
10713 self.write_space();
10714 self.generate_identifier(&di.name)?;
10715
10716 if let Some(ref table) = di.table {
10717 self.write_space();
10718 self.write_keyword("ON");
10719 self.write_space();
10720 self.generate_table(table)?;
10721 }
10722
10723 Ok(())
10724 }
10725
10726 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
10727 self.write_keyword("CREATE");
10728
10729 if let Some(ref algorithm) = cv.algorithm {
10731 self.write_space();
10732 self.write_keyword("ALGORITHM");
10733 self.write("=");
10734 self.write_keyword(algorithm);
10735 }
10736
10737 if let Some(ref definer) = cv.definer {
10739 self.write_space();
10740 self.write_keyword("DEFINER");
10741 self.write("=");
10742 self.write(definer);
10743 }
10744
10745 if cv.security_sql_style && !cv.security_after_name {
10747 if let Some(ref security) = cv.security {
10748 self.write_space();
10749 self.write_keyword("SQL SECURITY");
10750 self.write_space();
10751 match security {
10752 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10753 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10754 FunctionSecurity::None => self.write_keyword("NONE"),
10755 }
10756 }
10757 }
10758
10759 if cv.or_replace {
10760 self.write_space();
10761 self.write_keyword("OR REPLACE");
10762 }
10763
10764 if cv.temporary {
10765 self.write_space();
10766 self.write_keyword("TEMPORARY");
10767 }
10768
10769 if cv.materialized {
10770 self.write_space();
10771 self.write_keyword("MATERIALIZED");
10772 }
10773
10774 if cv.secure {
10776 self.write_space();
10777 self.write_keyword("SECURE");
10778 }
10779
10780 self.write_space();
10781 self.write_keyword("VIEW");
10782
10783 if cv.if_not_exists {
10784 self.write_space();
10785 self.write_keyword("IF NOT EXISTS");
10786 }
10787
10788 self.write_space();
10789 self.generate_table(&cv.name)?;
10790
10791 if let Some(ref on_cluster) = cv.on_cluster {
10793 self.write_space();
10794 self.generate_on_cluster(on_cluster)?;
10795 }
10796
10797 if let Some(ref to_table) = cv.to_table {
10799 self.write_space();
10800 self.write_keyword("TO");
10801 self.write_space();
10802 self.generate_table(to_table)?;
10803 }
10804
10805 if !cv.materialized {
10808 if !cv.columns.is_empty() {
10810 self.write(" (");
10811 for (i, col) in cv.columns.iter().enumerate() {
10812 if i > 0 {
10813 self.write(", ");
10814 }
10815 self.generate_identifier(&col.name)?;
10816 if !col.options.is_empty() {
10818 self.write_space();
10819 self.generate_options_clause(&col.options)?;
10820 }
10821 if let Some(ref comment) = col.comment {
10822 self.write_space();
10823 self.write_keyword("COMMENT");
10824 self.write_space();
10825 self.generate_string_literal(comment)?;
10826 }
10827 }
10828 self.write(")");
10829 }
10830
10831 if !cv.security_sql_style || cv.security_after_name {
10834 if let Some(ref security) = cv.security {
10835 self.write_space();
10836 if cv.security_sql_style {
10837 self.write_keyword("SQL SECURITY");
10838 } else {
10839 self.write_keyword("SECURITY");
10840 }
10841 self.write_space();
10842 match security {
10843 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10844 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10845 FunctionSecurity::None => self.write_keyword("NONE"),
10846 }
10847 }
10848 }
10849
10850 if cv.copy_grants {
10852 self.write_space();
10853 self.write_keyword("COPY GRANTS");
10854 }
10855 } else {
10856 if cv.copy_grants {
10858 self.write_space();
10859 self.write_keyword("COPY GRANTS");
10860 }
10861
10862 if let Some(ref schema) = cv.schema {
10864 self.write(" (");
10865 for (i, expr) in schema.expressions.iter().enumerate() {
10866 if i > 0 {
10867 self.write(", ");
10868 }
10869 self.generate_expression(expr)?;
10870 }
10871 self.write(")");
10872 } else if !cv.columns.is_empty() {
10873 self.write(" (");
10875 for (i, col) in cv.columns.iter().enumerate() {
10876 if i > 0 {
10877 self.write(", ");
10878 }
10879 self.generate_identifier(&col.name)?;
10880 if !col.options.is_empty() {
10882 self.write_space();
10883 self.generate_options_clause(&col.options)?;
10884 }
10885 if let Some(ref comment) = col.comment {
10886 self.write_space();
10887 self.write_keyword("COMMENT");
10888 self.write_space();
10889 self.generate_string_literal(comment)?;
10890 }
10891 }
10892 self.write(")");
10893 }
10894
10895 if let Some(ref unique_key) = cv.unique_key {
10897 self.write_space();
10898 self.write_keyword("KEY");
10899 self.write(" (");
10900 for (i, expr) in unique_key.expressions.iter().enumerate() {
10901 if i > 0 {
10902 self.write(", ");
10903 }
10904 self.generate_expression(expr)?;
10905 }
10906 self.write(")");
10907 }
10908 }
10909
10910 if let Some(ref comment) = cv.comment {
10912 self.write_space();
10913 self.write_keyword("COMMENT");
10914 self.write("=");
10915 self.generate_string_literal(comment)?;
10916 }
10917
10918 if !cv.tags.is_empty() {
10920 self.write_space();
10921 self.write_keyword("TAG");
10922 self.write(" (");
10923 for (i, (name, value)) in cv.tags.iter().enumerate() {
10924 if i > 0 {
10925 self.write(", ");
10926 }
10927 self.write(name);
10928 self.write("='");
10929 self.write(value);
10930 self.write("'");
10931 }
10932 self.write(")");
10933 }
10934
10935 if !cv.options.is_empty() {
10937 self.write_space();
10938 self.generate_options_clause(&cv.options)?;
10939 }
10940
10941 if let Some(ref build) = cv.build {
10943 self.write_space();
10944 self.write_keyword("BUILD");
10945 self.write_space();
10946 self.write_keyword(build);
10947 }
10948
10949 if let Some(ref refresh) = cv.refresh {
10951 self.write_space();
10952 self.generate_refresh_trigger_property(refresh)?;
10953 }
10954
10955 if let Some(auto_refresh) = cv.auto_refresh {
10957 self.write_space();
10958 self.write_keyword("AUTO REFRESH");
10959 self.write_space();
10960 if auto_refresh {
10961 self.write_keyword("YES");
10962 } else {
10963 self.write_keyword("NO");
10964 }
10965 }
10966
10967 for prop in &cv.table_properties {
10969 self.write_space();
10970 self.generate_expression(prop)?;
10971 }
10972
10973 if !matches!(&cv.query, Expression::Null(_)) {
10975 self.write_space();
10976 self.write_keyword("AS");
10977 self.write_space();
10978
10979 if let Some(ref mode) = cv.locking_mode {
10981 self.write_keyword("LOCKING");
10982 self.write_space();
10983 self.write_keyword(mode);
10984 if let Some(ref access) = cv.locking_access {
10985 self.write_space();
10986 self.write_keyword("FOR");
10987 self.write_space();
10988 self.write_keyword(access);
10989 }
10990 self.write_space();
10991 }
10992
10993 if cv.query_parenthesized {
10994 self.write("(");
10995 }
10996 self.generate_expression(&cv.query)?;
10997 if cv.query_parenthesized {
10998 self.write(")");
10999 }
11000 }
11001
11002 if cv.no_schema_binding {
11004 self.write_space();
11005 self.write_keyword("WITH NO SCHEMA BINDING");
11006 }
11007
11008 Ok(())
11009 }
11010
11011 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
11012 self.write_keyword("DROP");
11013
11014 if dv.materialized {
11015 self.write_space();
11016 self.write_keyword("MATERIALIZED");
11017 }
11018
11019 self.write_space();
11020 self.write_keyword("VIEW");
11021
11022 if dv.if_exists {
11023 self.write_space();
11024 self.write_keyword("IF EXISTS");
11025 }
11026
11027 self.write_space();
11028 self.generate_table(&dv.name)?;
11029
11030 Ok(())
11031 }
11032
11033 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
11034 match tr.target {
11035 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
11036 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
11037 }
11038 if tr.if_exists {
11039 self.write_space();
11040 self.write_keyword("IF EXISTS");
11041 }
11042 self.write_space();
11043 self.generate_table(&tr.table)?;
11044
11045 if let Some(ref on_cluster) = tr.on_cluster {
11047 self.write_space();
11048 self.generate_on_cluster(on_cluster)?;
11049 }
11050
11051 if !tr.extra_tables.is_empty() {
11053 let skip_first = if let Some(first) = tr.extra_tables.first() {
11055 first.table.name == tr.table.name && first.star
11056 } else {
11057 false
11058 };
11059
11060 let strip_star = matches!(
11062 self.config.dialect,
11063 Some(crate::dialects::DialectType::PostgreSQL)
11064 | Some(crate::dialects::DialectType::Redshift)
11065 );
11066 if skip_first && !strip_star {
11067 self.write("*");
11068 }
11069
11070 for (i, entry) in tr.extra_tables.iter().enumerate() {
11072 if i == 0 && skip_first {
11073 continue; }
11075 self.write(", ");
11076 self.generate_table(&entry.table)?;
11077 if entry.star && !strip_star {
11078 self.write("*");
11079 }
11080 }
11081 }
11082
11083 if let Some(identity) = &tr.identity {
11085 self.write_space();
11086 match identity {
11087 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
11088 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
11089 }
11090 }
11091
11092 if tr.cascade {
11093 self.write_space();
11094 self.write_keyword("CASCADE");
11095 }
11096
11097 if tr.restrict {
11098 self.write_space();
11099 self.write_keyword("RESTRICT");
11100 }
11101
11102 if let Some(ref partition) = tr.partition {
11104 self.write_space();
11105 self.generate_expression(partition)?;
11106 }
11107
11108 Ok(())
11109 }
11110
11111 fn generate_use(&mut self, u: &Use) -> Result<()> {
11112 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
11114 self.write_keyword("DATABASE");
11115 self.write_space();
11116 self.generate_identifier(&u.this)?;
11117 return Ok(());
11118 }
11119
11120 self.write_keyword("USE");
11121
11122 if let Some(kind) = &u.kind {
11123 self.write_space();
11124 match kind {
11125 UseKind::Database => self.write_keyword("DATABASE"),
11126 UseKind::Schema => self.write_keyword("SCHEMA"),
11127 UseKind::Role => self.write_keyword("ROLE"),
11128 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
11129 UseKind::Catalog => self.write_keyword("CATALOG"),
11130 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
11131 }
11132 }
11133
11134 self.write_space();
11135 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
11138 self.write(&u.this.name);
11139 } else {
11140 self.generate_identifier(&u.this)?;
11141 }
11142 Ok(())
11143 }
11144
11145 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
11146 self.write_keyword("CACHE");
11147 if c.lazy {
11148 self.write_space();
11149 self.write_keyword("LAZY");
11150 }
11151 self.write_space();
11152 self.write_keyword("TABLE");
11153 self.write_space();
11154 self.generate_identifier(&c.table)?;
11155
11156 if !c.options.is_empty() {
11158 self.write_space();
11159 self.write_keyword("OPTIONS");
11160 self.write("(");
11161 for (i, (key, value)) in c.options.iter().enumerate() {
11162 if i > 0 {
11163 self.write(", ");
11164 }
11165 self.generate_expression(key)?;
11166 self.write(" = ");
11167 self.generate_expression(value)?;
11168 }
11169 self.write(")");
11170 }
11171
11172 if let Some(query) = &c.query {
11174 self.write_space();
11175 self.write_keyword("AS");
11176 self.write_space();
11177 self.generate_expression(query)?;
11178 }
11179
11180 Ok(())
11181 }
11182
11183 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
11184 self.write_keyword("UNCACHE TABLE");
11185 if u.if_exists {
11186 self.write_space();
11187 self.write_keyword("IF EXISTS");
11188 }
11189 self.write_space();
11190 self.generate_identifier(&u.table)?;
11191 Ok(())
11192 }
11193
11194 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
11195 self.write_keyword("LOAD DATA");
11196 if l.local {
11197 self.write_space();
11198 self.write_keyword("LOCAL");
11199 }
11200 self.write_space();
11201 self.write_keyword("INPATH");
11202 self.write_space();
11203 self.write("'");
11204 self.write(&l.inpath);
11205 self.write("'");
11206
11207 if l.overwrite {
11208 self.write_space();
11209 self.write_keyword("OVERWRITE");
11210 }
11211
11212 self.write_space();
11213 self.write_keyword("INTO TABLE");
11214 self.write_space();
11215 self.generate_expression(&l.table)?;
11216
11217 if !l.partition.is_empty() {
11219 self.write_space();
11220 self.write_keyword("PARTITION");
11221 self.write("(");
11222 for (i, (col, val)) in l.partition.iter().enumerate() {
11223 if i > 0 {
11224 self.write(", ");
11225 }
11226 self.generate_identifier(col)?;
11227 self.write(" = ");
11228 self.generate_expression(val)?;
11229 }
11230 self.write(")");
11231 }
11232
11233 if let Some(fmt) = &l.input_format {
11235 self.write_space();
11236 self.write_keyword("INPUTFORMAT");
11237 self.write_space();
11238 self.write("'");
11239 self.write(fmt);
11240 self.write("'");
11241 }
11242
11243 if let Some(serde) = &l.serde {
11245 self.write_space();
11246 self.write_keyword("SERDE");
11247 self.write_space();
11248 self.write("'");
11249 self.write(serde);
11250 self.write("'");
11251 }
11252
11253 Ok(())
11254 }
11255
11256 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
11257 self.write_keyword("PRAGMA");
11258 self.write_space();
11259
11260 if let Some(schema) = &p.schema {
11262 self.generate_identifier(schema)?;
11263 self.write(".");
11264 }
11265
11266 self.generate_identifier(&p.name)?;
11268
11269 if let Some(value) = &p.value {
11271 self.write(" = ");
11272 self.generate_expression(value)?;
11273 } else if !p.args.is_empty() {
11274 self.write("(");
11275 for (i, arg) in p.args.iter().enumerate() {
11276 if i > 0 {
11277 self.write(", ");
11278 }
11279 self.generate_expression(arg)?;
11280 }
11281 self.write(")");
11282 }
11283
11284 Ok(())
11285 }
11286
11287 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
11288 self.write_keyword("GRANT");
11289 self.write_space();
11290
11291 for (i, privilege) in g.privileges.iter().enumerate() {
11293 if i > 0 {
11294 self.write(", ");
11295 }
11296 self.write_keyword(&privilege.name);
11297 if !privilege.columns.is_empty() {
11299 self.write("(");
11300 for (j, col) in privilege.columns.iter().enumerate() {
11301 if j > 0 {
11302 self.write(", ");
11303 }
11304 self.write(col);
11305 }
11306 self.write(")");
11307 }
11308 }
11309
11310 self.write_space();
11311 self.write_keyword("ON");
11312 self.write_space();
11313
11314 if let Some(kind) = &g.kind {
11316 self.write_keyword(kind);
11317 self.write_space();
11318 }
11319
11320 {
11322 use crate::dialects::DialectType;
11323 let should_upper = matches!(
11324 self.config.dialect,
11325 Some(DialectType::PostgreSQL)
11326 | Some(DialectType::CockroachDB)
11327 | Some(DialectType::Materialize)
11328 | Some(DialectType::RisingWave)
11329 ) && (g.kind.as_deref() == Some("FUNCTION")
11330 || g.kind.as_deref() == Some("PROCEDURE"));
11331 if should_upper {
11332 use crate::expressions::Identifier;
11333 let upper_id = Identifier {
11334 name: g.securable.name.to_ascii_uppercase(),
11335 quoted: g.securable.quoted,
11336 ..g.securable.clone()
11337 };
11338 self.generate_identifier(&upper_id)?;
11339 } else {
11340 self.generate_identifier(&g.securable)?;
11341 }
11342 }
11343
11344 if !g.function_params.is_empty() {
11346 self.write("(");
11347 for (i, param) in g.function_params.iter().enumerate() {
11348 if i > 0 {
11349 self.write(", ");
11350 }
11351 self.write(param);
11352 }
11353 self.write(")");
11354 }
11355
11356 self.write_space();
11357 self.write_keyword("TO");
11358 self.write_space();
11359
11360 for (i, principal) in g.principals.iter().enumerate() {
11362 if i > 0 {
11363 self.write(", ");
11364 }
11365 if principal.is_role {
11366 self.write_keyword("ROLE");
11367 self.write_space();
11368 } else if principal.is_group {
11369 self.write_keyword("GROUP");
11370 self.write_space();
11371 }
11372 self.generate_identifier(&principal.name)?;
11373 }
11374
11375 if g.grant_option {
11377 self.write_space();
11378 self.write_keyword("WITH GRANT OPTION");
11379 }
11380
11381 if let Some(ref principal) = g.as_principal {
11383 self.write_space();
11384 self.write_keyword("AS");
11385 self.write_space();
11386 self.generate_identifier(principal)?;
11387 }
11388
11389 Ok(())
11390 }
11391
11392 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
11393 self.write_keyword("REVOKE");
11394 self.write_space();
11395
11396 if r.grant_option {
11398 self.write_keyword("GRANT OPTION FOR");
11399 self.write_space();
11400 }
11401
11402 for (i, privilege) in r.privileges.iter().enumerate() {
11404 if i > 0 {
11405 self.write(", ");
11406 }
11407 self.write_keyword(&privilege.name);
11408 if !privilege.columns.is_empty() {
11410 self.write("(");
11411 for (j, col) in privilege.columns.iter().enumerate() {
11412 if j > 0 {
11413 self.write(", ");
11414 }
11415 self.write(col);
11416 }
11417 self.write(")");
11418 }
11419 }
11420
11421 self.write_space();
11422 self.write_keyword("ON");
11423 self.write_space();
11424
11425 if let Some(kind) = &r.kind {
11427 self.write_keyword(kind);
11428 self.write_space();
11429 }
11430
11431 {
11433 use crate::dialects::DialectType;
11434 let should_upper = matches!(
11435 self.config.dialect,
11436 Some(DialectType::PostgreSQL)
11437 | Some(DialectType::CockroachDB)
11438 | Some(DialectType::Materialize)
11439 | Some(DialectType::RisingWave)
11440 ) && (r.kind.as_deref() == Some("FUNCTION")
11441 || r.kind.as_deref() == Some("PROCEDURE"));
11442 if should_upper {
11443 use crate::expressions::Identifier;
11444 let upper_id = Identifier {
11445 name: r.securable.name.to_ascii_uppercase(),
11446 quoted: r.securable.quoted,
11447 ..r.securable.clone()
11448 };
11449 self.generate_identifier(&upper_id)?;
11450 } else {
11451 self.generate_identifier(&r.securable)?;
11452 }
11453 }
11454
11455 if !r.function_params.is_empty() {
11457 self.write("(");
11458 for (i, param) in r.function_params.iter().enumerate() {
11459 if i > 0 {
11460 self.write(", ");
11461 }
11462 self.write(param);
11463 }
11464 self.write(")");
11465 }
11466
11467 self.write_space();
11468 self.write_keyword("FROM");
11469 self.write_space();
11470
11471 for (i, principal) in r.principals.iter().enumerate() {
11473 if i > 0 {
11474 self.write(", ");
11475 }
11476 if principal.is_role {
11477 self.write_keyword("ROLE");
11478 self.write_space();
11479 } else if principal.is_group {
11480 self.write_keyword("GROUP");
11481 self.write_space();
11482 }
11483 self.generate_identifier(&principal.name)?;
11484 }
11485
11486 if r.cascade {
11488 self.write_space();
11489 self.write_keyword("CASCADE");
11490 } else if r.restrict {
11491 self.write_space();
11492 self.write_keyword("RESTRICT");
11493 }
11494
11495 Ok(())
11496 }
11497
11498 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
11499 self.write_keyword("COMMENT");
11500
11501 if c.exists {
11503 self.write_space();
11504 self.write_keyword("IF EXISTS");
11505 }
11506
11507 self.write_space();
11508 self.write_keyword("ON");
11509
11510 if c.materialized {
11512 self.write_space();
11513 self.write_keyword("MATERIALIZED");
11514 }
11515
11516 self.write_space();
11517 self.write_keyword(&c.kind);
11518 self.write_space();
11519
11520 self.generate_expression(&c.this)?;
11522
11523 self.write_space();
11524 self.write_keyword("IS");
11525 self.write_space();
11526
11527 self.generate_expression(&c.expression)?;
11529
11530 Ok(())
11531 }
11532
11533 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
11534 self.write_keyword("SET");
11535
11536 for (i, item) in s.items.iter().enumerate() {
11537 if i > 0 {
11538 self.write(",");
11539 }
11540 self.write_space();
11541
11542 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
11544 if let Some(ref kind) = item.kind {
11545 if has_variable_kind {
11549 if matches!(
11550 self.config.dialect,
11551 Some(
11552 DialectType::Spark
11553 | DialectType::Databricks
11554 | DialectType::DuckDB
11555 )
11556 ) {
11557 self.write_keyword("VARIABLE");
11558 self.write_space();
11559 }
11560 } else {
11561 self.write_keyword(kind);
11562 self.write_space();
11563 }
11564 }
11565
11566 let name_str = match &item.name {
11568 Expression::Identifier(id) => Some(id.name.as_str()),
11569 _ => None,
11570 };
11571
11572 let is_transaction = name_str == Some("TRANSACTION");
11573 let is_character_set = name_str == Some("CHARACTER SET");
11574 let is_names = name_str == Some("NAMES");
11575 let is_collate = name_str == Some("COLLATE");
11576 let is_value_only =
11577 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
11578
11579 if is_transaction {
11580 self.write_keyword("TRANSACTION");
11582 if let Expression::Identifier(id) = &item.value {
11583 if !id.name.is_empty() {
11584 self.write_space();
11585 self.write(&id.name);
11586 }
11587 }
11588 } else if is_character_set {
11589 self.write_keyword("CHARACTER SET");
11591 self.write_space();
11592 self.generate_set_value(&item.value)?;
11593 } else if is_names {
11594 self.write_keyword("NAMES");
11596 self.write_space();
11597 self.generate_set_value(&item.value)?;
11598 } else if is_collate {
11599 self.write_keyword("COLLATE");
11601 self.write_space();
11602 self.generate_set_value(&item.value)?;
11603 } else if has_variable_kind {
11604 if let Some(ns) = name_str {
11607 self.write(ns);
11608 } else {
11609 self.generate_expression(&item.name)?;
11610 }
11611 self.write(" = ");
11612 self.generate_set_value(&item.value)?;
11613 } else if is_value_only {
11614 self.generate_expression(&item.name)?;
11616 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
11617 self.generate_expression(&item.name)?;
11619 self.write_space();
11620 self.generate_set_value(&item.value)?;
11621 } else {
11622 match &item.name {
11625 Expression::Identifier(id) => {
11626 self.write(&id.name);
11627 }
11628 _ => {
11629 self.generate_expression(&item.name)?;
11630 }
11631 }
11632 self.write(" = ");
11633 self.generate_set_value(&item.value)?;
11634 }
11635 }
11636
11637 Ok(())
11638 }
11639
11640 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
11643 if let Expression::Identifier(id) = value {
11644 match id.name.as_str() {
11645 "DEFAULT" | "ON" | "OFF" => {
11646 self.write_keyword(&id.name);
11647 return Ok(());
11648 }
11649 _ => {}
11650 }
11651 }
11652 self.generate_expression(value)
11653 }
11654
11655 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
11658 self.write_keyword("ALTER");
11659 if let Some(ref algorithm) = av.algorithm {
11661 self.write_space();
11662 self.write_keyword("ALGORITHM");
11663 self.write(" = ");
11664 self.write_keyword(algorithm);
11665 }
11666 if let Some(ref definer) = av.definer {
11667 self.write_space();
11668 self.write_keyword("DEFINER");
11669 self.write(" = ");
11670 self.write(definer);
11671 }
11672 if let Some(ref sql_security) = av.sql_security {
11673 self.write_space();
11674 self.write_keyword("SQL SECURITY");
11675 self.write(" = ");
11676 self.write_keyword(sql_security);
11677 }
11678 self.write_space();
11679 self.write_keyword("VIEW");
11680 self.write_space();
11681 self.generate_table(&av.name)?;
11682
11683 if !av.columns.is_empty() {
11685 self.write(" (");
11686 for (i, col) in av.columns.iter().enumerate() {
11687 if i > 0 {
11688 self.write(", ");
11689 }
11690 self.generate_identifier(&col.name)?;
11691 if let Some(ref comment) = col.comment {
11692 self.write_space();
11693 self.write_keyword("COMMENT");
11694 self.write(" ");
11695 self.generate_string_literal(comment)?;
11696 }
11697 }
11698 self.write(")");
11699 }
11700
11701 if let Some(ref opt) = av.with_option {
11703 self.write_space();
11704 self.write_keyword("WITH");
11705 self.write_space();
11706 self.write_keyword(opt);
11707 }
11708
11709 for action in &av.actions {
11710 self.write_space();
11711 match action {
11712 AlterViewAction::Rename(new_name) => {
11713 self.write_keyword("RENAME TO");
11714 self.write_space();
11715 self.generate_table(new_name)?;
11716 }
11717 AlterViewAction::OwnerTo(owner) => {
11718 self.write_keyword("OWNER TO");
11719 self.write_space();
11720 self.generate_identifier(owner)?;
11721 }
11722 AlterViewAction::SetSchema(schema) => {
11723 self.write_keyword("SET SCHEMA");
11724 self.write_space();
11725 self.generate_identifier(schema)?;
11726 }
11727 AlterViewAction::SetAuthorization(auth) => {
11728 self.write_keyword("SET AUTHORIZATION");
11729 self.write_space();
11730 self.write(auth);
11731 }
11732 AlterViewAction::AlterColumn { name, action } => {
11733 self.write_keyword("ALTER COLUMN");
11734 self.write_space();
11735 self.generate_identifier(name)?;
11736 self.write_space();
11737 self.generate_alter_column_action(action)?;
11738 }
11739 AlterViewAction::AsSelect(query) => {
11740 self.write_keyword("AS");
11741 self.write_space();
11742 self.generate_expression(query)?;
11743 }
11744 AlterViewAction::SetTblproperties(props) => {
11745 self.write_keyword("SET TBLPROPERTIES");
11746 self.write(" (");
11747 for (i, (key, value)) in props.iter().enumerate() {
11748 if i > 0 {
11749 self.write(", ");
11750 }
11751 self.generate_string_literal(key)?;
11752 self.write("=");
11753 self.generate_string_literal(value)?;
11754 }
11755 self.write(")");
11756 }
11757 AlterViewAction::UnsetTblproperties(keys) => {
11758 self.write_keyword("UNSET TBLPROPERTIES");
11759 self.write(" (");
11760 for (i, key) in keys.iter().enumerate() {
11761 if i > 0 {
11762 self.write(", ");
11763 }
11764 self.generate_string_literal(key)?;
11765 }
11766 self.write(")");
11767 }
11768 }
11769 }
11770
11771 Ok(())
11772 }
11773
11774 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
11775 self.write_keyword("ALTER INDEX");
11776 self.write_space();
11777 self.generate_identifier(&ai.name)?;
11778
11779 if let Some(table) = &ai.table {
11780 self.write_space();
11781 self.write_keyword("ON");
11782 self.write_space();
11783 self.generate_table(table)?;
11784 }
11785
11786 for action in &ai.actions {
11787 self.write_space();
11788 match action {
11789 AlterIndexAction::Rename(new_name) => {
11790 self.write_keyword("RENAME TO");
11791 self.write_space();
11792 self.generate_identifier(new_name)?;
11793 }
11794 AlterIndexAction::SetTablespace(tablespace) => {
11795 self.write_keyword("SET TABLESPACE");
11796 self.write_space();
11797 self.generate_identifier(tablespace)?;
11798 }
11799 AlterIndexAction::Visible(visible) => {
11800 if *visible {
11801 self.write_keyword("VISIBLE");
11802 } else {
11803 self.write_keyword("INVISIBLE");
11804 }
11805 }
11806 }
11807 }
11808
11809 Ok(())
11810 }
11811
11812 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
11813 for comment in &cs.leading_comments {
11815 self.write_formatted_comment(comment);
11816 self.write_space();
11817 }
11818
11819 let saved_athena_hive_context = self.athena_hive_context;
11821 if matches!(
11822 self.config.dialect,
11823 Some(crate::dialects::DialectType::Athena)
11824 ) {
11825 self.athena_hive_context = true;
11826 }
11827
11828 self.write_keyword("CREATE SCHEMA");
11829
11830 if cs.if_not_exists {
11831 self.write_space();
11832 self.write_keyword("IF NOT EXISTS");
11833 }
11834
11835 self.write_space();
11836 self.generate_identifier(&cs.name)?;
11837
11838 if let Some(ref clone_src) = cs.clone_from {
11839 self.write_keyword(" CLONE ");
11840 self.generate_identifier(clone_src)?;
11841 }
11842
11843 if let Some(ref at_clause) = cs.at_clause {
11844 self.write_space();
11845 self.generate_expression(at_clause)?;
11846 }
11847
11848 if let Some(auth) = &cs.authorization {
11849 self.write_space();
11850 self.write_keyword("AUTHORIZATION");
11851 self.write_space();
11852 self.generate_identifier(auth)?;
11853 }
11854
11855 let with_properties: Vec<_> = cs
11858 .properties
11859 .iter()
11860 .filter(|p| matches!(p, Expression::Property(_)))
11861 .collect();
11862 let other_properties: Vec<_> = cs
11863 .properties
11864 .iter()
11865 .filter(|p| !matches!(p, Expression::Property(_)))
11866 .collect();
11867
11868 if !with_properties.is_empty() {
11870 self.write_space();
11871 self.write_keyword("WITH");
11872 self.write(" (");
11873 for (i, prop) in with_properties.iter().enumerate() {
11874 if i > 0 {
11875 self.write(", ");
11876 }
11877 self.generate_expression(prop)?;
11878 }
11879 self.write(")");
11880 }
11881
11882 for prop in other_properties {
11884 self.write_space();
11885 self.generate_expression(prop)?;
11886 }
11887
11888 self.athena_hive_context = saved_athena_hive_context;
11890
11891 Ok(())
11892 }
11893
11894 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
11895 self.write_keyword("DROP SCHEMA");
11896
11897 if ds.if_exists {
11898 self.write_space();
11899 self.write_keyword("IF EXISTS");
11900 }
11901
11902 self.write_space();
11903 self.generate_identifier(&ds.name)?;
11904
11905 if ds.cascade {
11906 self.write_space();
11907 self.write_keyword("CASCADE");
11908 }
11909
11910 Ok(())
11911 }
11912
11913 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
11914 self.write_keyword("DROP NAMESPACE");
11915
11916 if dn.if_exists {
11917 self.write_space();
11918 self.write_keyword("IF EXISTS");
11919 }
11920
11921 self.write_space();
11922 self.generate_identifier(&dn.name)?;
11923
11924 if dn.cascade {
11925 self.write_space();
11926 self.write_keyword("CASCADE");
11927 }
11928
11929 Ok(())
11930 }
11931
11932 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
11933 self.write_keyword("CREATE DATABASE");
11934
11935 if cd.if_not_exists {
11936 self.write_space();
11937 self.write_keyword("IF NOT EXISTS");
11938 }
11939
11940 self.write_space();
11941 self.generate_identifier(&cd.name)?;
11942
11943 if let Some(ref clone_src) = cd.clone_from {
11944 self.write_keyword(" CLONE ");
11945 self.generate_identifier(clone_src)?;
11946 }
11947
11948 if let Some(ref at_clause) = cd.at_clause {
11950 self.write_space();
11951 self.generate_expression(at_clause)?;
11952 }
11953
11954 for option in &cd.options {
11955 self.write_space();
11956 match option {
11957 DatabaseOption::CharacterSet(charset) => {
11958 self.write_keyword("CHARACTER SET");
11959 self.write(" = ");
11960 self.write(&format!("'{}'", charset));
11961 }
11962 DatabaseOption::Collate(collate) => {
11963 self.write_keyword("COLLATE");
11964 self.write(" = ");
11965 self.write(&format!("'{}'", collate));
11966 }
11967 DatabaseOption::Owner(owner) => {
11968 self.write_keyword("OWNER");
11969 self.write(" = ");
11970 self.generate_identifier(owner)?;
11971 }
11972 DatabaseOption::Template(template) => {
11973 self.write_keyword("TEMPLATE");
11974 self.write(" = ");
11975 self.generate_identifier(template)?;
11976 }
11977 DatabaseOption::Encoding(encoding) => {
11978 self.write_keyword("ENCODING");
11979 self.write(" = ");
11980 self.write(&format!("'{}'", encoding));
11981 }
11982 DatabaseOption::Location(location) => {
11983 self.write_keyword("LOCATION");
11984 self.write(" = ");
11985 self.write(&format!("'{}'", location));
11986 }
11987 }
11988 }
11989
11990 Ok(())
11991 }
11992
11993 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
11994 self.write_keyword("DROP DATABASE");
11995
11996 if dd.if_exists {
11997 self.write_space();
11998 self.write_keyword("IF EXISTS");
11999 }
12000
12001 self.write_space();
12002 self.generate_identifier(&dd.name)?;
12003
12004 if dd.sync {
12005 self.write_space();
12006 self.write_keyword("SYNC");
12007 }
12008
12009 Ok(())
12010 }
12011
12012 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
12013 self.write_keyword("CREATE");
12014
12015 if cf.or_replace {
12016 self.write_space();
12017 self.write_keyword("OR REPLACE");
12018 }
12019
12020 if cf.temporary {
12021 self.write_space();
12022 self.write_keyword("TEMPORARY");
12023 }
12024
12025 self.write_space();
12026 if cf.is_table_function {
12027 self.write_keyword("TABLE FUNCTION");
12028 } else {
12029 self.write_keyword("FUNCTION");
12030 }
12031
12032 if cf.if_not_exists {
12033 self.write_space();
12034 self.write_keyword("IF NOT EXISTS");
12035 }
12036
12037 self.write_space();
12038 self.generate_table(&cf.name)?;
12039 if cf.has_parens {
12040 let func_multiline = self.config.pretty
12041 && matches!(
12042 self.config.dialect,
12043 Some(crate::dialects::DialectType::TSQL)
12044 | Some(crate::dialects::DialectType::Fabric)
12045 )
12046 && !cf.parameters.is_empty();
12047 if func_multiline {
12048 self.write("(\n");
12049 self.indent_level += 2;
12050 self.write_indent();
12051 self.generate_function_parameters(&cf.parameters)?;
12052 self.write("\n");
12053 self.indent_level -= 2;
12054 self.write(")");
12055 } else {
12056 self.write("(");
12057 self.generate_function_parameters(&cf.parameters)?;
12058 self.write(")");
12059 }
12060 }
12061
12062 let use_multiline = self.config.pretty
12065 && matches!(
12066 self.config.dialect,
12067 Some(crate::dialects::DialectType::BigQuery)
12068 | Some(crate::dialects::DialectType::TSQL)
12069 | Some(crate::dialects::DialectType::Fabric)
12070 );
12071
12072 if cf.language_first {
12073 if let Some(lang) = &cf.language {
12075 if use_multiline {
12076 self.write_newline();
12077 } else {
12078 self.write_space();
12079 }
12080 self.write_keyword("LANGUAGE");
12081 self.write_space();
12082 self.write(lang);
12083 }
12084
12085 if let Some(sql_data) = &cf.sql_data_access {
12087 self.write_space();
12088 match sql_data {
12089 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12090 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12091 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12092 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12093 }
12094 }
12095
12096 if let Some(ref rtb) = cf.returns_table_body {
12097 if use_multiline {
12098 self.write_newline();
12099 } else {
12100 self.write_space();
12101 }
12102 self.write_keyword("RETURNS");
12103 self.write_space();
12104 self.write(rtb);
12105 } else if let Some(return_type) = &cf.return_type {
12106 if use_multiline {
12107 self.write_newline();
12108 } else {
12109 self.write_space();
12110 }
12111 self.write_keyword("RETURNS");
12112 self.write_space();
12113 self.generate_data_type(return_type)?;
12114 }
12115 } else {
12116 let is_duckdb = matches!(
12119 self.config.dialect,
12120 Some(crate::dialects::DialectType::DuckDB)
12121 );
12122 if let Some(ref rtb) = cf.returns_table_body {
12123 if !(is_duckdb && rtb.is_empty()) {
12124 if use_multiline {
12125 self.write_newline();
12126 } else {
12127 self.write_space();
12128 }
12129 self.write_keyword("RETURNS");
12130 self.write_space();
12131 self.write(rtb);
12132 }
12133 } else if let Some(return_type) = &cf.return_type {
12134 if use_multiline {
12135 self.write_newline();
12136 } else {
12137 self.write_space();
12138 }
12139 self.write_keyword("RETURNS");
12140 self.write_space();
12141 self.generate_data_type(return_type)?;
12142 }
12143 }
12144
12145 if !cf.property_order.is_empty() {
12147 let is_bigquery = matches!(
12149 self.config.dialect,
12150 Some(crate::dialects::DialectType::BigQuery)
12151 );
12152 let property_order = if is_bigquery {
12153 let mut reordered = Vec::new();
12155 let mut has_as = false;
12156 let mut has_options = false;
12157 for prop in &cf.property_order {
12158 match prop {
12159 FunctionPropertyKind::As => has_as = true,
12160 FunctionPropertyKind::Options => has_options = true,
12161 _ => {}
12162 }
12163 }
12164 if has_as && has_options {
12165 for prop in &cf.property_order {
12167 if *prop != FunctionPropertyKind::As
12168 && *prop != FunctionPropertyKind::Options
12169 {
12170 reordered.push(*prop);
12171 }
12172 }
12173 reordered.push(FunctionPropertyKind::Options);
12174 reordered.push(FunctionPropertyKind::As);
12175 reordered
12176 } else {
12177 cf.property_order.clone()
12178 }
12179 } else {
12180 cf.property_order.clone()
12181 };
12182
12183 for prop in &property_order {
12184 match prop {
12185 FunctionPropertyKind::Set => {
12186 self.generate_function_set_options(cf)?;
12187 }
12188 FunctionPropertyKind::As => {
12189 self.generate_function_body(cf)?;
12190 }
12191 FunctionPropertyKind::Language => {
12192 if !cf.language_first {
12193 if let Some(lang) = &cf.language {
12195 let use_multiline = self.config.pretty
12197 && matches!(
12198 self.config.dialect,
12199 Some(crate::dialects::DialectType::BigQuery)
12200 );
12201 if use_multiline {
12202 self.write_newline();
12203 } else {
12204 self.write_space();
12205 }
12206 self.write_keyword("LANGUAGE");
12207 self.write_space();
12208 self.write(lang);
12209 }
12210 }
12211 }
12212 FunctionPropertyKind::Determinism => {
12213 self.generate_function_determinism(cf)?;
12214 }
12215 FunctionPropertyKind::NullInput => {
12216 self.generate_function_null_input(cf)?;
12217 }
12218 FunctionPropertyKind::Security => {
12219 self.generate_function_security(cf)?;
12220 }
12221 FunctionPropertyKind::SqlDataAccess => {
12222 if !cf.language_first {
12223 self.generate_function_sql_data_access(cf)?;
12225 }
12226 }
12227 FunctionPropertyKind::Options => {
12228 if !cf.options.is_empty() {
12229 self.write_space();
12230 self.generate_options_clause(&cf.options)?;
12231 }
12232 }
12233 FunctionPropertyKind::Environment => {
12234 if !cf.environment.is_empty() {
12235 self.write_space();
12236 self.generate_environment_clause(&cf.environment)?;
12237 }
12238 }
12239 FunctionPropertyKind::Handler => {
12240 if let Some(ref h) = cf.handler {
12241 self.write_space();
12242 self.write_keyword("HANDLER");
12243 self.write_space();
12244 self.write("'");
12245 self.write(h);
12246 self.write("'");
12247 }
12248 }
12249 FunctionPropertyKind::ParameterStyle => {
12250 if let Some(ref ps) = cf.parameter_style {
12251 self.write_space();
12252 self.write_keyword("PARAMETER STYLE");
12253 self.write_space();
12254 self.write_keyword(ps);
12255 }
12256 }
12257 }
12258 }
12259
12260 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
12262 {
12263 self.write_space();
12264 self.generate_options_clause(&cf.options)?;
12265 }
12266
12267 if !cf.environment.is_empty()
12269 && !cf
12270 .property_order
12271 .contains(&FunctionPropertyKind::Environment)
12272 {
12273 self.write_space();
12274 self.generate_environment_clause(&cf.environment)?;
12275 }
12276 } else {
12277 if matches!(
12280 self.config.dialect,
12281 Some(crate::dialects::DialectType::BigQuery)
12282 ) {
12283 self.generate_function_determinism(cf)?;
12284 }
12285
12286 let use_multiline = self.config.pretty
12288 && matches!(
12289 self.config.dialect,
12290 Some(crate::dialects::DialectType::BigQuery)
12291 );
12292
12293 if !cf.language_first {
12294 if let Some(lang) = &cf.language {
12295 if use_multiline {
12296 self.write_newline();
12297 } else {
12298 self.write_space();
12299 }
12300 self.write_keyword("LANGUAGE");
12301 self.write_space();
12302 self.write(lang);
12303 }
12304
12305 self.generate_function_sql_data_access(cf)?;
12307 }
12308
12309 if !matches!(
12311 self.config.dialect,
12312 Some(crate::dialects::DialectType::BigQuery)
12313 ) {
12314 self.generate_function_determinism(cf)?;
12315 }
12316
12317 self.generate_function_null_input(cf)?;
12318 self.generate_function_security(cf)?;
12319 self.generate_function_set_options(cf)?;
12320
12321 if !cf.options.is_empty() {
12323 self.write_space();
12324 self.generate_options_clause(&cf.options)?;
12325 }
12326
12327 if !cf.environment.is_empty() {
12329 self.write_space();
12330 self.generate_environment_clause(&cf.environment)?;
12331 }
12332
12333 self.generate_function_body(cf)?;
12334 }
12335
12336 Ok(())
12337 }
12338
12339 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
12341 for opt in &cf.set_options {
12342 self.write_space();
12343 self.write_keyword("SET");
12344 self.write_space();
12345 self.write(&opt.name);
12346 match &opt.value {
12347 FunctionSetValue::Value { value, use_to } => {
12348 if *use_to {
12349 self.write(" TO ");
12350 } else {
12351 self.write(" = ");
12352 }
12353 self.write(value);
12354 }
12355 FunctionSetValue::FromCurrent => {
12356 self.write_space();
12357 self.write_keyword("FROM CURRENT");
12358 }
12359 }
12360 }
12361 Ok(())
12362 }
12363
12364 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
12366 if let Some(body) = &cf.body {
12367 self.write_space();
12369 let use_multiline = self.config.pretty
12371 && matches!(
12372 self.config.dialect,
12373 Some(crate::dialects::DialectType::BigQuery)
12374 );
12375 match body {
12376 FunctionBody::Block(block) => {
12377 self.write_keyword("AS");
12378 if matches!(
12379 self.config.dialect,
12380 Some(crate::dialects::DialectType::TSQL)
12381 ) {
12382 self.write(" BEGIN ");
12383 self.write(block);
12384 self.write(" END");
12385 } else if matches!(
12386 self.config.dialect,
12387 Some(crate::dialects::DialectType::PostgreSQL)
12388 ) {
12389 self.write(" $$");
12390 self.write(block);
12391 self.write("$$");
12392 } else {
12393 let escaped = self.escape_block_for_single_quote(block);
12395 if use_multiline {
12397 self.write_newline();
12398 } else {
12399 self.write(" ");
12400 }
12401 self.write("'");
12402 self.write(&escaped);
12403 self.write("'");
12404 }
12405 }
12406 FunctionBody::StringLiteral(s) => {
12407 self.write_keyword("AS");
12408 if use_multiline {
12410 self.write_newline();
12411 } else {
12412 self.write(" ");
12413 }
12414 self.write("'");
12415 self.write(s);
12416 self.write("'");
12417 }
12418 FunctionBody::Expression(expr) => {
12419 self.write_keyword("AS");
12420 self.write_space();
12421 self.generate_expression(expr)?;
12422 }
12423 FunctionBody::External(name) => {
12424 self.write_keyword("EXTERNAL NAME");
12425 self.write(" '");
12426 self.write(name);
12427 self.write("'");
12428 }
12429 FunctionBody::Return(expr) => {
12430 if matches!(
12431 self.config.dialect,
12432 Some(crate::dialects::DialectType::DuckDB)
12433 ) {
12434 self.write_keyword("AS");
12436 self.write_space();
12437 if cf.returns_table_body.is_some() {
12439 self.write_keyword("TABLE");
12440 self.write_space();
12441 }
12442 self.generate_expression(expr)?;
12443 } else {
12444 if self.config.create_function_return_as {
12445 self.write_keyword("AS");
12446 if self.config.pretty
12448 && matches!(
12449 self.config.dialect,
12450 Some(crate::dialects::DialectType::TSQL)
12451 | Some(crate::dialects::DialectType::Fabric)
12452 )
12453 {
12454 self.write_newline();
12455 } else {
12456 self.write_space();
12457 }
12458 }
12459 self.write_keyword("RETURN");
12460 self.write_space();
12461 self.generate_expression(expr)?;
12462 }
12463 }
12464 FunctionBody::Statements(stmts) => {
12465 self.write_keyword("AS");
12466 self.write(" BEGIN ");
12467 for (i, stmt) in stmts.iter().enumerate() {
12468 if i > 0 {
12469 self.write(" ");
12470 }
12471 self.generate_expression(stmt)?;
12472 self.write(";");
12473 }
12474 self.write(" END");
12475 }
12476 FunctionBody::DollarQuoted { content, tag } => {
12477 self.write_keyword("AS");
12478 self.write(" ");
12479 let supports_dollar_quoting = matches!(
12481 self.config.dialect,
12482 Some(crate::dialects::DialectType::PostgreSQL)
12483 | Some(crate::dialects::DialectType::Databricks)
12484 | Some(crate::dialects::DialectType::Redshift)
12485 | Some(crate::dialects::DialectType::DuckDB)
12486 );
12487 if supports_dollar_quoting {
12488 self.write("$");
12490 if let Some(t) = tag {
12491 self.write(t);
12492 }
12493 self.write("$");
12494 self.write(content);
12495 self.write("$");
12496 if let Some(t) = tag {
12497 self.write(t);
12498 }
12499 self.write("$");
12500 } else {
12501 let escaped = self.escape_block_for_single_quote(content);
12503 self.write("'");
12504 self.write(&escaped);
12505 self.write("'");
12506 }
12507 }
12508 }
12509 }
12510 Ok(())
12511 }
12512
12513 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
12515 if let Some(det) = cf.deterministic {
12516 self.write_space();
12517 if matches!(
12518 self.config.dialect,
12519 Some(crate::dialects::DialectType::BigQuery)
12520 ) {
12521 if det {
12523 self.write_keyword("DETERMINISTIC");
12524 } else {
12525 self.write_keyword("NOT DETERMINISTIC");
12526 }
12527 } else {
12528 if det {
12530 self.write_keyword("IMMUTABLE");
12531 } else {
12532 self.write_keyword("VOLATILE");
12533 }
12534 }
12535 }
12536 Ok(())
12537 }
12538
12539 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
12541 if let Some(returns_null) = cf.returns_null_on_null_input {
12542 self.write_space();
12543 if returns_null {
12544 if cf.strict {
12545 self.write_keyword("STRICT");
12546 } else {
12547 self.write_keyword("RETURNS NULL ON NULL INPUT");
12548 }
12549 } else {
12550 self.write_keyword("CALLED ON NULL INPUT");
12551 }
12552 }
12553 Ok(())
12554 }
12555
12556 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
12558 if let Some(security) = &cf.security {
12559 self.write_space();
12560 if matches!(
12562 self.config.dialect,
12563 Some(crate::dialects::DialectType::MySQL)
12564 ) {
12565 self.write_keyword("SQL SECURITY");
12566 } else {
12567 self.write_keyword("SECURITY");
12568 }
12569 self.write_space();
12570 match security {
12571 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12572 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12573 FunctionSecurity::None => self.write_keyword("NONE"),
12574 }
12575 }
12576 Ok(())
12577 }
12578
12579 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
12581 if let Some(sql_data) = &cf.sql_data_access {
12582 self.write_space();
12583 match sql_data {
12584 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12585 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12586 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12587 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12588 }
12589 }
12590 Ok(())
12591 }
12592
12593 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
12594 for (i, param) in params.iter().enumerate() {
12595 if i > 0 {
12596 self.write(", ");
12597 }
12598
12599 if let Some(mode) = ¶m.mode {
12600 if let Some(text) = ¶m.mode_text {
12601 self.write(text);
12602 } else {
12603 match mode {
12604 ParameterMode::In => self.write_keyword("IN"),
12605 ParameterMode::Out => self.write_keyword("OUT"),
12606 ParameterMode::InOut => self.write_keyword("INOUT"),
12607 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
12608 }
12609 }
12610 self.write_space();
12611 }
12612
12613 if let Some(name) = ¶m.name {
12614 self.generate_identifier(name)?;
12615 let skip_type =
12617 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
12618 if !skip_type {
12619 self.write_space();
12620 self.generate_data_type(¶m.data_type)?;
12621 }
12622 } else {
12623 self.generate_data_type(¶m.data_type)?;
12624 }
12625
12626 if let Some(default) = ¶m.default {
12627 if self.config.parameter_default_equals {
12628 self.write(" = ");
12629 } else {
12630 self.write(" DEFAULT ");
12631 }
12632 self.generate_expression(default)?;
12633 }
12634 }
12635
12636 Ok(())
12637 }
12638
12639 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
12640 self.write_keyword("DROP FUNCTION");
12641
12642 if df.if_exists {
12643 self.write_space();
12644 self.write_keyword("IF EXISTS");
12645 }
12646
12647 self.write_space();
12648 self.generate_table(&df.name)?;
12649
12650 if let Some(params) = &df.parameters {
12651 self.write(" (");
12652 for (i, dt) in params.iter().enumerate() {
12653 if i > 0 {
12654 self.write(", ");
12655 }
12656 self.generate_data_type(dt)?;
12657 }
12658 self.write(")");
12659 }
12660
12661 if df.cascade {
12662 self.write_space();
12663 self.write_keyword("CASCADE");
12664 }
12665
12666 Ok(())
12667 }
12668
12669 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
12670 self.write_keyword("CREATE");
12671
12672 if cp.or_replace {
12673 self.write_space();
12674 self.write_keyword("OR REPLACE");
12675 }
12676
12677 self.write_space();
12678 if cp.use_proc_keyword {
12679 self.write_keyword("PROC");
12680 } else {
12681 self.write_keyword("PROCEDURE");
12682 }
12683
12684 if cp.if_not_exists {
12685 self.write_space();
12686 self.write_keyword("IF NOT EXISTS");
12687 }
12688
12689 self.write_space();
12690 self.generate_table(&cp.name)?;
12691 if cp.has_parens {
12692 self.write("(");
12693 self.generate_function_parameters(&cp.parameters)?;
12694 self.write(")");
12695 } else if !cp.parameters.is_empty() {
12696 self.write_space();
12698 self.generate_function_parameters(&cp.parameters)?;
12699 }
12700
12701 if let Some(return_type) = &cp.return_type {
12703 self.write_space();
12704 self.write_keyword("RETURNS");
12705 self.write_space();
12706 self.generate_data_type(return_type)?;
12707 }
12708
12709 if let Some(execute_as) = &cp.execute_as {
12711 self.write_space();
12712 self.write_keyword("EXECUTE AS");
12713 self.write_space();
12714 self.write_keyword(execute_as);
12715 }
12716
12717 if let Some(lang) = &cp.language {
12718 self.write_space();
12719 self.write_keyword("LANGUAGE");
12720 self.write_space();
12721 self.write(lang);
12722 }
12723
12724 if let Some(security) = &cp.security {
12725 self.write_space();
12726 self.write_keyword("SECURITY");
12727 self.write_space();
12728 match security {
12729 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12730 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12731 FunctionSecurity::None => self.write_keyword("NONE"),
12732 }
12733 }
12734
12735 if !cp.with_options.is_empty() {
12737 self.write_space();
12738 self.write_keyword("WITH");
12739 self.write_space();
12740 for (i, opt) in cp.with_options.iter().enumerate() {
12741 if i > 0 {
12742 self.write(", ");
12743 }
12744 self.write(opt);
12745 }
12746 }
12747
12748 if let Some(body) = &cp.body {
12749 self.write_space();
12750 match body {
12751 FunctionBody::Block(block) => {
12752 self.write_keyword("AS");
12753 if matches!(
12754 self.config.dialect,
12755 Some(crate::dialects::DialectType::TSQL)
12756 ) {
12757 self.write(" BEGIN ");
12758 self.write(block);
12759 self.write(" END");
12760 } else if matches!(
12761 self.config.dialect,
12762 Some(crate::dialects::DialectType::PostgreSQL)
12763 ) {
12764 self.write(" $$");
12765 self.write(block);
12766 self.write("$$");
12767 } else {
12768 let escaped = self.escape_block_for_single_quote(block);
12770 self.write(" '");
12771 self.write(&escaped);
12772 self.write("'");
12773 }
12774 }
12775 FunctionBody::StringLiteral(s) => {
12776 self.write_keyword("AS");
12777 self.write(" '");
12778 self.write(s);
12779 self.write("'");
12780 }
12781 FunctionBody::Expression(expr) => {
12782 self.write_keyword("AS");
12783 self.write_space();
12784 self.generate_expression(expr)?;
12785 }
12786 FunctionBody::External(name) => {
12787 self.write_keyword("EXTERNAL NAME");
12788 self.write(" '");
12789 self.write(name);
12790 self.write("'");
12791 }
12792 FunctionBody::Return(expr) => {
12793 self.write_keyword("RETURN");
12794 self.write_space();
12795 self.generate_expression(expr)?;
12796 }
12797 FunctionBody::Statements(stmts) => {
12798 self.write_keyword("AS");
12799 self.write(" BEGIN ");
12800 for (i, stmt) in stmts.iter().enumerate() {
12801 if i > 0 {
12802 self.write(" ");
12803 }
12804 self.generate_expression(stmt)?;
12805 self.write(";");
12806 }
12807 self.write(" END");
12808 }
12809 FunctionBody::DollarQuoted { content, tag } => {
12810 self.write_keyword("AS");
12811 self.write(" ");
12812 let supports_dollar_quoting = matches!(
12814 self.config.dialect,
12815 Some(crate::dialects::DialectType::PostgreSQL)
12816 | Some(crate::dialects::DialectType::Databricks)
12817 | Some(crate::dialects::DialectType::Redshift)
12818 | Some(crate::dialects::DialectType::DuckDB)
12819 );
12820 if supports_dollar_quoting {
12821 self.write("$");
12823 if let Some(t) = tag {
12824 self.write(t);
12825 }
12826 self.write("$");
12827 self.write(content);
12828 self.write("$");
12829 if let Some(t) = tag {
12830 self.write(t);
12831 }
12832 self.write("$");
12833 } else {
12834 let escaped = self.escape_block_for_single_quote(content);
12836 self.write("'");
12837 self.write(&escaped);
12838 self.write("'");
12839 }
12840 }
12841 }
12842 }
12843
12844 Ok(())
12845 }
12846
12847 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
12848 self.write_keyword("DROP PROCEDURE");
12849
12850 if dp.if_exists {
12851 self.write_space();
12852 self.write_keyword("IF EXISTS");
12853 }
12854
12855 self.write_space();
12856 self.generate_table(&dp.name)?;
12857
12858 if let Some(params) = &dp.parameters {
12859 self.write(" (");
12860 for (i, dt) in params.iter().enumerate() {
12861 if i > 0 {
12862 self.write(", ");
12863 }
12864 self.generate_data_type(dt)?;
12865 }
12866 self.write(")");
12867 }
12868
12869 if dp.cascade {
12870 self.write_space();
12871 self.write_keyword("CASCADE");
12872 }
12873
12874 Ok(())
12875 }
12876
12877 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
12878 self.write_keyword("CREATE");
12879
12880 if cs.or_replace {
12881 self.write_space();
12882 self.write_keyword("OR REPLACE");
12883 }
12884
12885 if cs.temporary {
12886 self.write_space();
12887 self.write_keyword("TEMPORARY");
12888 }
12889
12890 self.write_space();
12891 self.write_keyword("SEQUENCE");
12892
12893 if cs.if_not_exists {
12894 self.write_space();
12895 self.write_keyword("IF NOT EXISTS");
12896 }
12897
12898 self.write_space();
12899 self.generate_table(&cs.name)?;
12900
12901 if let Some(as_type) = &cs.as_type {
12903 self.write_space();
12904 self.write_keyword("AS");
12905 self.write_space();
12906 self.generate_data_type(as_type)?;
12907 }
12908
12909 if let Some(comment) = &cs.comment {
12911 self.write_space();
12912 self.write_keyword("COMMENT");
12913 self.write("=");
12914 self.generate_string_literal(comment)?;
12915 }
12916
12917 if !cs.property_order.is_empty() {
12919 for prop in &cs.property_order {
12920 match prop {
12921 SeqPropKind::Start => {
12922 if let Some(start) = cs.start {
12923 self.write_space();
12924 self.write_keyword("START WITH");
12925 self.write(&format!(" {}", start));
12926 }
12927 }
12928 SeqPropKind::Increment => {
12929 if let Some(inc) = cs.increment {
12930 self.write_space();
12931 self.write_keyword("INCREMENT BY");
12932 self.write(&format!(" {}", inc));
12933 }
12934 }
12935 SeqPropKind::Minvalue => {
12936 if let Some(min) = &cs.minvalue {
12937 self.write_space();
12938 match min {
12939 SequenceBound::Value(v) => {
12940 self.write_keyword("MINVALUE");
12941 self.write(&format!(" {}", v));
12942 }
12943 SequenceBound::None => {
12944 self.write_keyword("NO MINVALUE");
12945 }
12946 }
12947 }
12948 }
12949 SeqPropKind::Maxvalue => {
12950 if let Some(max) = &cs.maxvalue {
12951 self.write_space();
12952 match max {
12953 SequenceBound::Value(v) => {
12954 self.write_keyword("MAXVALUE");
12955 self.write(&format!(" {}", v));
12956 }
12957 SequenceBound::None => {
12958 self.write_keyword("NO MAXVALUE");
12959 }
12960 }
12961 }
12962 }
12963 SeqPropKind::Cache => {
12964 if let Some(cache) = cs.cache {
12965 self.write_space();
12966 self.write_keyword("CACHE");
12967 self.write(&format!(" {}", cache));
12968 }
12969 }
12970 SeqPropKind::NoCache => {
12971 self.write_space();
12972 self.write_keyword("NO CACHE");
12973 }
12974 SeqPropKind::NoCacheWord => {
12975 self.write_space();
12976 self.write_keyword("NOCACHE");
12977 }
12978 SeqPropKind::Cycle => {
12979 self.write_space();
12980 self.write_keyword("CYCLE");
12981 }
12982 SeqPropKind::NoCycle => {
12983 self.write_space();
12984 self.write_keyword("NO CYCLE");
12985 }
12986 SeqPropKind::NoCycleWord => {
12987 self.write_space();
12988 self.write_keyword("NOCYCLE");
12989 }
12990 SeqPropKind::OwnedBy => {
12991 if !cs.owned_by_none {
12993 if let Some(owned) = &cs.owned_by {
12994 self.write_space();
12995 self.write_keyword("OWNED BY");
12996 self.write_space();
12997 self.generate_table(owned)?;
12998 }
12999 }
13000 }
13001 SeqPropKind::Order => {
13002 self.write_space();
13003 self.write_keyword("ORDER");
13004 }
13005 SeqPropKind::NoOrder => {
13006 self.write_space();
13007 self.write_keyword("NOORDER");
13008 }
13009 SeqPropKind::Comment => {
13010 }
13012 SeqPropKind::Sharing => {
13013 if let Some(val) = &cs.sharing {
13014 self.write_space();
13015 self.write(&format!("SHARING={}", val));
13016 }
13017 }
13018 SeqPropKind::Keep => {
13019 self.write_space();
13020 self.write_keyword("KEEP");
13021 }
13022 SeqPropKind::NoKeep => {
13023 self.write_space();
13024 self.write_keyword("NOKEEP");
13025 }
13026 SeqPropKind::Scale => {
13027 self.write_space();
13028 self.write_keyword("SCALE");
13029 if let Some(modifier) = &cs.scale_modifier {
13030 if !modifier.is_empty() {
13031 self.write_space();
13032 self.write_keyword(modifier);
13033 }
13034 }
13035 }
13036 SeqPropKind::NoScale => {
13037 self.write_space();
13038 self.write_keyword("NOSCALE");
13039 }
13040 SeqPropKind::Shard => {
13041 self.write_space();
13042 self.write_keyword("SHARD");
13043 if let Some(modifier) = &cs.shard_modifier {
13044 if !modifier.is_empty() {
13045 self.write_space();
13046 self.write_keyword(modifier);
13047 }
13048 }
13049 }
13050 SeqPropKind::NoShard => {
13051 self.write_space();
13052 self.write_keyword("NOSHARD");
13053 }
13054 SeqPropKind::Session => {
13055 self.write_space();
13056 self.write_keyword("SESSION");
13057 }
13058 SeqPropKind::Global => {
13059 self.write_space();
13060 self.write_keyword("GLOBAL");
13061 }
13062 SeqPropKind::NoMinvalueWord => {
13063 self.write_space();
13064 self.write_keyword("NOMINVALUE");
13065 }
13066 SeqPropKind::NoMaxvalueWord => {
13067 self.write_space();
13068 self.write_keyword("NOMAXVALUE");
13069 }
13070 }
13071 }
13072 } else {
13073 if let Some(inc) = cs.increment {
13075 self.write_space();
13076 self.write_keyword("INCREMENT BY");
13077 self.write(&format!(" {}", inc));
13078 }
13079
13080 if let Some(min) = &cs.minvalue {
13081 self.write_space();
13082 match min {
13083 SequenceBound::Value(v) => {
13084 self.write_keyword("MINVALUE");
13085 self.write(&format!(" {}", v));
13086 }
13087 SequenceBound::None => {
13088 self.write_keyword("NO MINVALUE");
13089 }
13090 }
13091 }
13092
13093 if let Some(max) = &cs.maxvalue {
13094 self.write_space();
13095 match max {
13096 SequenceBound::Value(v) => {
13097 self.write_keyword("MAXVALUE");
13098 self.write(&format!(" {}", v));
13099 }
13100 SequenceBound::None => {
13101 self.write_keyword("NO MAXVALUE");
13102 }
13103 }
13104 }
13105
13106 if let Some(start) = cs.start {
13107 self.write_space();
13108 self.write_keyword("START WITH");
13109 self.write(&format!(" {}", start));
13110 }
13111
13112 if let Some(cache) = cs.cache {
13113 self.write_space();
13114 self.write_keyword("CACHE");
13115 self.write(&format!(" {}", cache));
13116 }
13117
13118 if cs.cycle {
13119 self.write_space();
13120 self.write_keyword("CYCLE");
13121 }
13122
13123 if let Some(owned) = &cs.owned_by {
13124 self.write_space();
13125 self.write_keyword("OWNED BY");
13126 self.write_space();
13127 self.generate_table(owned)?;
13128 }
13129 }
13130
13131 Ok(())
13132 }
13133
13134 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
13135 self.write_keyword("DROP SEQUENCE");
13136
13137 if ds.if_exists {
13138 self.write_space();
13139 self.write_keyword("IF EXISTS");
13140 }
13141
13142 self.write_space();
13143 self.generate_table(&ds.name)?;
13144
13145 if ds.cascade {
13146 self.write_space();
13147 self.write_keyword("CASCADE");
13148 }
13149
13150 Ok(())
13151 }
13152
13153 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
13154 self.write_keyword("ALTER SEQUENCE");
13155
13156 if als.if_exists {
13157 self.write_space();
13158 self.write_keyword("IF EXISTS");
13159 }
13160
13161 self.write_space();
13162 self.generate_table(&als.name)?;
13163
13164 if let Some(inc) = als.increment {
13165 self.write_space();
13166 self.write_keyword("INCREMENT BY");
13167 self.write(&format!(" {}", inc));
13168 }
13169
13170 if let Some(min) = &als.minvalue {
13171 self.write_space();
13172 match min {
13173 SequenceBound::Value(v) => {
13174 self.write_keyword("MINVALUE");
13175 self.write(&format!(" {}", v));
13176 }
13177 SequenceBound::None => {
13178 self.write_keyword("NO MINVALUE");
13179 }
13180 }
13181 }
13182
13183 if let Some(max) = &als.maxvalue {
13184 self.write_space();
13185 match max {
13186 SequenceBound::Value(v) => {
13187 self.write_keyword("MAXVALUE");
13188 self.write(&format!(" {}", v));
13189 }
13190 SequenceBound::None => {
13191 self.write_keyword("NO MAXVALUE");
13192 }
13193 }
13194 }
13195
13196 if let Some(start) = als.start {
13197 self.write_space();
13198 self.write_keyword("START WITH");
13199 self.write(&format!(" {}", start));
13200 }
13201
13202 if let Some(restart) = &als.restart {
13203 self.write_space();
13204 self.write_keyword("RESTART");
13205 if let Some(val) = restart {
13206 self.write_keyword(" WITH");
13207 self.write(&format!(" {}", val));
13208 }
13209 }
13210
13211 if let Some(cache) = als.cache {
13212 self.write_space();
13213 self.write_keyword("CACHE");
13214 self.write(&format!(" {}", cache));
13215 }
13216
13217 if let Some(cycle) = als.cycle {
13218 self.write_space();
13219 if cycle {
13220 self.write_keyword("CYCLE");
13221 } else {
13222 self.write_keyword("NO CYCLE");
13223 }
13224 }
13225
13226 if let Some(owned) = &als.owned_by {
13227 self.write_space();
13228 self.write_keyword("OWNED BY");
13229 self.write_space();
13230 if let Some(table) = owned {
13231 self.generate_table(table)?;
13232 } else {
13233 self.write_keyword("NONE");
13234 }
13235 }
13236
13237 Ok(())
13238 }
13239
13240 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
13241 self.write_keyword("CREATE");
13242
13243 if ct.or_replace {
13244 self.write_space();
13245 self.write_keyword("OR REPLACE");
13246 }
13247
13248 if ct.constraint {
13249 self.write_space();
13250 self.write_keyword("CONSTRAINT");
13251 }
13252
13253 self.write_space();
13254 self.write_keyword("TRIGGER");
13255 self.write_space();
13256 self.generate_identifier(&ct.name)?;
13257
13258 self.write_space();
13259 match ct.timing {
13260 TriggerTiming::Before => self.write_keyword("BEFORE"),
13261 TriggerTiming::After => self.write_keyword("AFTER"),
13262 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
13263 }
13264
13265 for (i, event) in ct.events.iter().enumerate() {
13267 if i > 0 {
13268 self.write_keyword(" OR");
13269 }
13270 self.write_space();
13271 match event {
13272 TriggerEvent::Insert => self.write_keyword("INSERT"),
13273 TriggerEvent::Update(cols) => {
13274 self.write_keyword("UPDATE");
13275 if let Some(cols) = cols {
13276 self.write_space();
13277 self.write_keyword("OF");
13278 for (j, col) in cols.iter().enumerate() {
13279 if j > 0 {
13280 self.write(",");
13281 }
13282 self.write_space();
13283 self.generate_identifier(col)?;
13284 }
13285 }
13286 }
13287 TriggerEvent::Delete => self.write_keyword("DELETE"),
13288 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
13289 }
13290 }
13291
13292 self.write_space();
13293 self.write_keyword("ON");
13294 self.write_space();
13295 self.generate_table(&ct.table)?;
13296
13297 if let Some(ref_clause) = &ct.referencing {
13299 self.write_space();
13300 self.write_keyword("REFERENCING");
13301 if let Some(old_table) = &ref_clause.old_table {
13302 self.write_space();
13303 self.write_keyword("OLD TABLE AS");
13304 self.write_space();
13305 self.generate_identifier(old_table)?;
13306 }
13307 if let Some(new_table) = &ref_clause.new_table {
13308 self.write_space();
13309 self.write_keyword("NEW TABLE AS");
13310 self.write_space();
13311 self.generate_identifier(new_table)?;
13312 }
13313 if let Some(old_row) = &ref_clause.old_row {
13314 self.write_space();
13315 self.write_keyword("OLD ROW AS");
13316 self.write_space();
13317 self.generate_identifier(old_row)?;
13318 }
13319 if let Some(new_row) = &ref_clause.new_row {
13320 self.write_space();
13321 self.write_keyword("NEW ROW AS");
13322 self.write_space();
13323 self.generate_identifier(new_row)?;
13324 }
13325 }
13326
13327 if let Some(deferrable) = ct.deferrable {
13329 self.write_space();
13330 if deferrable {
13331 self.write_keyword("DEFERRABLE");
13332 } else {
13333 self.write_keyword("NOT DEFERRABLE");
13334 }
13335 }
13336
13337 if let Some(initially) = ct.initially_deferred {
13338 self.write_space();
13339 self.write_keyword("INITIALLY");
13340 self.write_space();
13341 if initially {
13342 self.write_keyword("DEFERRED");
13343 } else {
13344 self.write_keyword("IMMEDIATE");
13345 }
13346 }
13347
13348 if let Some(for_each) = ct.for_each {
13349 self.write_space();
13350 self.write_keyword("FOR EACH");
13351 self.write_space();
13352 match for_each {
13353 TriggerForEach::Row => self.write_keyword("ROW"),
13354 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
13355 }
13356 }
13357
13358 if let Some(when) = &ct.when {
13360 self.write_space();
13361 self.write_keyword("WHEN");
13362 if ct.when_paren {
13363 self.write(" (");
13364 self.generate_expression(when)?;
13365 self.write(")");
13366 } else {
13367 self.write_space();
13368 self.generate_expression(when)?;
13369 }
13370 }
13371
13372 self.write_space();
13374 match &ct.body {
13375 TriggerBody::Execute { function, args } => {
13376 self.write_keyword("EXECUTE FUNCTION");
13377 self.write_space();
13378 self.generate_table(function)?;
13379 self.write("(");
13380 for (i, arg) in args.iter().enumerate() {
13381 if i > 0 {
13382 self.write(", ");
13383 }
13384 self.generate_expression(arg)?;
13385 }
13386 self.write(")");
13387 }
13388 TriggerBody::Block(block) => {
13389 self.write_keyword("BEGIN");
13390 self.write_space();
13391 self.write(block);
13392 self.write_space();
13393 self.write_keyword("END");
13394 }
13395 }
13396
13397 Ok(())
13398 }
13399
13400 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
13401 self.write_keyword("DROP TRIGGER");
13402
13403 if dt.if_exists {
13404 self.write_space();
13405 self.write_keyword("IF EXISTS");
13406 }
13407
13408 self.write_space();
13409 self.generate_identifier(&dt.name)?;
13410
13411 if let Some(table) = &dt.table {
13412 self.write_space();
13413 self.write_keyword("ON");
13414 self.write_space();
13415 self.generate_table(table)?;
13416 }
13417
13418 if dt.cascade {
13419 self.write_space();
13420 self.write_keyword("CASCADE");
13421 }
13422
13423 Ok(())
13424 }
13425
13426 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
13427 self.write_keyword("CREATE TYPE");
13428
13429 if ct.if_not_exists {
13430 self.write_space();
13431 self.write_keyword("IF NOT EXISTS");
13432 }
13433
13434 self.write_space();
13435 self.generate_table(&ct.name)?;
13436
13437 self.write_space();
13438 self.write_keyword("AS");
13439 self.write_space();
13440
13441 match &ct.definition {
13442 TypeDefinition::Enum(values) => {
13443 self.write_keyword("ENUM");
13444 self.write(" (");
13445 for (i, val) in values.iter().enumerate() {
13446 if i > 0 {
13447 self.write(", ");
13448 }
13449 self.write(&format!("'{}'", val));
13450 }
13451 self.write(")");
13452 }
13453 TypeDefinition::Composite(attrs) => {
13454 self.write("(");
13455 for (i, attr) in attrs.iter().enumerate() {
13456 if i > 0 {
13457 self.write(", ");
13458 }
13459 self.generate_identifier(&attr.name)?;
13460 self.write_space();
13461 self.generate_data_type(&attr.data_type)?;
13462 if let Some(collate) = &attr.collate {
13463 self.write_space();
13464 self.write_keyword("COLLATE");
13465 self.write_space();
13466 self.generate_identifier(collate)?;
13467 }
13468 }
13469 self.write(")");
13470 }
13471 TypeDefinition::Range {
13472 subtype,
13473 subtype_diff,
13474 canonical,
13475 } => {
13476 self.write_keyword("RANGE");
13477 self.write(" (");
13478 self.write_keyword("SUBTYPE");
13479 self.write(" = ");
13480 self.generate_data_type(subtype)?;
13481 if let Some(diff) = subtype_diff {
13482 self.write(", ");
13483 self.write_keyword("SUBTYPE_DIFF");
13484 self.write(" = ");
13485 self.write(diff);
13486 }
13487 if let Some(canon) = canonical {
13488 self.write(", ");
13489 self.write_keyword("CANONICAL");
13490 self.write(" = ");
13491 self.write(canon);
13492 }
13493 self.write(")");
13494 }
13495 TypeDefinition::Base {
13496 input,
13497 output,
13498 internallength,
13499 } => {
13500 self.write("(");
13501 self.write_keyword("INPUT");
13502 self.write(" = ");
13503 self.write(input);
13504 self.write(", ");
13505 self.write_keyword("OUTPUT");
13506 self.write(" = ");
13507 self.write(output);
13508 if let Some(len) = internallength {
13509 self.write(", ");
13510 self.write_keyword("INTERNALLENGTH");
13511 self.write(" = ");
13512 self.write(&len.to_string());
13513 }
13514 self.write(")");
13515 }
13516 TypeDefinition::Domain {
13517 base_type,
13518 default,
13519 constraints,
13520 } => {
13521 self.generate_data_type(base_type)?;
13522 if let Some(def) = default {
13523 self.write_space();
13524 self.write_keyword("DEFAULT");
13525 self.write_space();
13526 self.generate_expression(def)?;
13527 }
13528 for constr in constraints {
13529 self.write_space();
13530 if let Some(name) = &constr.name {
13531 self.write_keyword("CONSTRAINT");
13532 self.write_space();
13533 self.generate_identifier(name)?;
13534 self.write_space();
13535 }
13536 self.write_keyword("CHECK");
13537 self.write(" (");
13538 self.generate_expression(&constr.check)?;
13539 self.write(")");
13540 }
13541 }
13542 }
13543
13544 Ok(())
13545 }
13546
13547 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
13548 self.write_keyword("DROP TYPE");
13549
13550 if dt.if_exists {
13551 self.write_space();
13552 self.write_keyword("IF EXISTS");
13553 }
13554
13555 self.write_space();
13556 self.generate_table(&dt.name)?;
13557
13558 if dt.cascade {
13559 self.write_space();
13560 self.write_keyword("CASCADE");
13561 }
13562
13563 Ok(())
13564 }
13565
13566 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
13567 let saved_athena_hive_context = self.athena_hive_context;
13569 if matches!(
13570 self.config.dialect,
13571 Some(crate::dialects::DialectType::Athena)
13572 ) {
13573 self.athena_hive_context = true;
13574 }
13575
13576 for comment in &d.leading_comments {
13578 self.write_formatted_comment(comment);
13579 self.write(" ");
13580 }
13581
13582 self.write_keyword("DESCRIBE");
13583
13584 if d.extended {
13585 self.write_space();
13586 self.write_keyword("EXTENDED");
13587 } else if d.formatted {
13588 self.write_space();
13589 self.write_keyword("FORMATTED");
13590 }
13591
13592 if let Some(ref style) = d.style {
13594 self.write_space();
13595 self.write_keyword(style);
13596 }
13597
13598 let should_output_kind = match self.config.dialect {
13600 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
13602 false
13603 }
13604 Some(DialectType::Snowflake) => true,
13606 _ => d.kind.is_some(),
13607 };
13608 if should_output_kind {
13609 if let Some(ref kind) = d.kind {
13610 self.write_space();
13611 self.write_keyword(kind);
13612 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
13613 self.write_space();
13614 self.write_keyword("TABLE");
13615 }
13616 }
13617
13618 self.write_space();
13619 self.generate_expression(&d.target)?;
13620
13621 if let Some(ref partition) = d.partition {
13623 self.write_space();
13624 self.generate_expression(partition)?;
13625 }
13626
13627 if d.as_json {
13629 self.write_space();
13630 self.write_keyword("AS JSON");
13631 }
13632
13633 for (name, value) in &d.properties {
13635 self.write_space();
13636 self.write(name);
13637 self.write("=");
13638 self.write(value);
13639 }
13640
13641 self.athena_hive_context = saved_athena_hive_context;
13643
13644 Ok(())
13645 }
13646
13647 fn generate_show(&mut self, s: &Show) -> Result<()> {
13650 self.write_keyword("SHOW");
13651 self.write_space();
13652
13653 let show_terse = s.terse
13656 && !matches!(
13657 s.this.as_str(),
13658 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
13659 );
13660 if show_terse {
13661 self.write_keyword("TERSE");
13662 self.write_space();
13663 }
13664
13665 self.write_keyword(&s.this);
13667
13668 if let Some(ref target_expr) = s.target {
13670 self.write_space();
13671 self.generate_expression(target_expr)?;
13672 }
13673
13674 if s.history {
13676 self.write_space();
13677 self.write_keyword("HISTORY");
13678 }
13679
13680 if let Some(ref for_target) = s.for_target {
13682 self.write_space();
13683 self.write_keyword("FOR");
13684 self.write_space();
13685 self.generate_expression(for_target)?;
13686 }
13687
13688 use crate::dialects::DialectType;
13692 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
13693
13694 if !is_snowflake && s.from.is_some() {
13695 if let Some(ref scope_kind) = s.scope_kind {
13699 self.write_space();
13700 self.write_keyword("IN");
13701 self.write_space();
13702 self.write_keyword(scope_kind);
13703 if let Some(ref scope) = s.scope {
13704 self.write_space();
13705 self.generate_expression(scope)?;
13706 }
13707 } else if let Some(ref scope) = s.scope {
13708 self.write_space();
13709 self.write_keyword("IN");
13710 self.write_space();
13711 self.generate_expression(scope)?;
13712 }
13713
13714 if let Some(ref from) = s.from {
13716 self.write_space();
13717 self.write_keyword("FROM");
13718 self.write_space();
13719 self.generate_expression(from)?;
13720 }
13721
13722 if let Some(ref db) = s.db {
13724 self.write_space();
13725 self.write_keyword("FROM");
13726 self.write_space();
13727 self.generate_expression(db)?;
13728 }
13729
13730 if let Some(ref like) = s.like {
13732 self.write_space();
13733 self.write_keyword("LIKE");
13734 self.write_space();
13735 self.generate_expression(like)?;
13736 }
13737 } else {
13738 if let Some(ref like) = s.like {
13742 self.write_space();
13743 self.write_keyword("LIKE");
13744 self.write_space();
13745 self.generate_expression(like)?;
13746 }
13747
13748 if let Some(ref scope_kind) = s.scope_kind {
13750 self.write_space();
13751 self.write_keyword("IN");
13752 self.write_space();
13753 self.write_keyword(scope_kind);
13754 if let Some(ref scope) = s.scope {
13755 self.write_space();
13756 self.generate_expression(scope)?;
13757 }
13758 } else if let Some(ref scope) = s.scope {
13759 self.write_space();
13760 self.write_keyword("IN");
13761 self.write_space();
13762 self.generate_expression(scope)?;
13763 }
13764 }
13765
13766 if let Some(ref starts_with) = s.starts_with {
13768 self.write_space();
13769 self.write_keyword("STARTS WITH");
13770 self.write_space();
13771 self.generate_expression(starts_with)?;
13772 }
13773
13774 if let Some(ref limit) = s.limit {
13776 self.write_space();
13777 self.generate_limit(limit)?;
13778 }
13779
13780 if is_snowflake {
13782 if let Some(ref from) = s.from {
13783 self.write_space();
13784 self.write_keyword("FROM");
13785 self.write_space();
13786 self.generate_expression(from)?;
13787 }
13788 }
13789
13790 if let Some(ref where_clause) = s.where_clause {
13792 self.write_space();
13793 self.write_keyword("WHERE");
13794 self.write_space();
13795 self.generate_expression(where_clause)?;
13796 }
13797
13798 if let Some(is_mutex) = s.mutex {
13800 self.write_space();
13801 if is_mutex {
13802 self.write_keyword("MUTEX");
13803 } else {
13804 self.write_keyword("STATUS");
13805 }
13806 }
13807
13808 if !s.privileges.is_empty() {
13810 self.write_space();
13811 self.write_keyword("WITH PRIVILEGES");
13812 self.write_space();
13813 for (i, priv_name) in s.privileges.iter().enumerate() {
13814 if i > 0 {
13815 self.write(", ");
13816 }
13817 self.write_keyword(priv_name);
13818 }
13819 }
13820
13821 Ok(())
13822 }
13823
13824 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
13827 use crate::dialects::DialectType;
13828 match lit {
13829 Literal::String(s) => {
13830 self.generate_string_literal(s)?;
13831 }
13832 Literal::Number(n) => {
13833 if matches!(self.config.dialect, Some(DialectType::MySQL))
13834 && n.len() > 2
13835 && (n.starts_with("0x") || n.starts_with("0X"))
13836 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
13837 {
13838 return self.generate_identifier(&Identifier {
13839 name: n.clone(),
13840 quoted: true,
13841 trailing_comments: Vec::new(),
13842 span: None,
13843 });
13844 }
13845 let n = if n.contains('_')
13849 && !matches!(
13850 self.config.dialect,
13851 Some(DialectType::ClickHouse)
13852 | Some(DialectType::DuckDB)
13853 | Some(DialectType::PostgreSQL)
13854 | Some(DialectType::Hive)
13855 | Some(DialectType::Spark)
13856 | Some(DialectType::Databricks)
13857 ) {
13858 std::borrow::Cow::Owned(n.replace('_', ""))
13859 } else {
13860 std::borrow::Cow::Borrowed(n.as_str())
13861 };
13862 if n.starts_with('.') {
13865 self.write("0");
13866 self.write(&n);
13867 } else if n.starts_with("-.") {
13868 self.write("-0");
13870 self.write(&n[1..]);
13871 } else {
13872 self.write(&n);
13873 }
13874 }
13875 Literal::HexString(h) => {
13876 match self.config.dialect {
13878 Some(DialectType::Spark)
13879 | Some(DialectType::Databricks)
13880 | Some(DialectType::Teradata) => self.write("X'"),
13881 _ => self.write("x'"),
13882 }
13883 self.write(h);
13884 self.write("'");
13885 }
13886 Literal::HexNumber(h) => {
13887 match self.config.dialect {
13891 Some(DialectType::BigQuery)
13892 | Some(DialectType::TSQL)
13893 | Some(DialectType::Fabric) => {
13894 self.write("0x");
13895 self.write(h);
13896 }
13897 _ => {
13898 if let Ok(val) = u64::from_str_radix(h, 16) {
13900 self.write(&val.to_string());
13901 } else {
13902 self.write("0x");
13904 self.write(h);
13905 }
13906 }
13907 }
13908 }
13909 Literal::BitString(b) => {
13910 self.write("B'");
13912 self.write(b);
13913 self.write("'");
13914 }
13915 Literal::ByteString(b) => {
13916 self.write("b'");
13918 self.write_escaped_byte_string(b);
13920 self.write("'");
13921 }
13922 Literal::NationalString(s) => {
13923 let keep_n_prefix = matches!(
13926 self.config.dialect,
13927 Some(DialectType::TSQL)
13928 | Some(DialectType::Oracle)
13929 | Some(DialectType::MySQL)
13930 | None
13931 );
13932 if keep_n_prefix {
13933 self.write("N'");
13934 } else {
13935 self.write("'");
13936 }
13937 self.write(s);
13938 self.write("'");
13939 }
13940 Literal::Date(d) => {
13941 self.generate_date_literal(d)?;
13942 }
13943 Literal::Time(t) => {
13944 self.generate_time_literal(t)?;
13945 }
13946 Literal::Timestamp(ts) => {
13947 self.generate_timestamp_literal(ts)?;
13948 }
13949 Literal::Datetime(dt) => {
13950 self.generate_datetime_literal(dt)?;
13951 }
13952 Literal::TripleQuotedString(s, _quote_char) => {
13953 if matches!(
13955 self.config.dialect,
13956 Some(crate::dialects::DialectType::BigQuery)
13957 | Some(crate::dialects::DialectType::DuckDB)
13958 | Some(crate::dialects::DialectType::Snowflake)
13959 | Some(crate::dialects::DialectType::Spark)
13960 | Some(crate::dialects::DialectType::Hive)
13961 | Some(crate::dialects::DialectType::Presto)
13962 | Some(crate::dialects::DialectType::Trino)
13963 | Some(crate::dialects::DialectType::PostgreSQL)
13964 | Some(crate::dialects::DialectType::MySQL)
13965 | Some(crate::dialects::DialectType::Redshift)
13966 | Some(crate::dialects::DialectType::TSQL)
13967 | Some(crate::dialects::DialectType::Oracle)
13968 | Some(crate::dialects::DialectType::ClickHouse)
13969 | Some(crate::dialects::DialectType::Databricks)
13970 | Some(crate::dialects::DialectType::SQLite)
13971 ) {
13972 self.generate_string_literal(s)?;
13973 } else {
13974 let quotes = format!("{0}{0}{0}", _quote_char);
13976 self.write("es);
13977 self.write(s);
13978 self.write("es);
13979 }
13980 }
13981 Literal::EscapeString(s) => {
13982 use crate::dialects::DialectType;
13986 let content = if let Some(c) = s.strip_prefix("e:") {
13987 c
13988 } else if let Some(c) = s.strip_prefix("E:") {
13989 c
13990 } else {
13991 s.as_str()
13992 };
13993
13994 if matches!(
13996 self.config.dialect,
13997 Some(DialectType::MySQL) | Some(DialectType::TiDB)
13998 ) {
13999 self.write(content);
14000 } else {
14001 let prefix = if matches!(
14003 self.config.dialect,
14004 Some(DialectType::SingleStore)
14005 | Some(DialectType::DuckDB)
14006 | Some(DialectType::PostgreSQL)
14007 | Some(DialectType::CockroachDB)
14008 | Some(DialectType::Materialize)
14009 | Some(DialectType::RisingWave)
14010 ) {
14011 "e'"
14012 } else {
14013 "E'"
14014 };
14015
14016 let normalized = content.replace("\\'", "''");
14018 self.write(prefix);
14019 self.write(&normalized);
14020 self.write("'");
14021 }
14022 }
14023 Literal::DollarString(s) => {
14024 use crate::dialects::DialectType;
14027 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
14029 let escape_backslash = matches!(self.config.dialect, Some(DialectType::Snowflake));
14031 let use_backslash_quote =
14035 matches!(self.config.dialect, Some(DialectType::Snowflake));
14036
14037 let mut escaped = String::with_capacity(content.len() + 4);
14038 for ch in content.chars() {
14039 if escape_backslash && ch == '\\' {
14040 escaped.push('\\');
14042 escaped.push('\\');
14043 } else if ch == '\'' {
14044 if use_backslash_quote {
14045 escaped.push('\\');
14046 escaped.push('\'');
14047 } else {
14048 escaped.push('\'');
14049 escaped.push('\'');
14050 }
14051 } else {
14052 escaped.push(ch);
14053 }
14054 }
14055 self.write("'");
14056 self.write(&escaped);
14057 self.write("'");
14058 }
14059 Literal::RawString(s) => {
14060 use crate::dialects::DialectType;
14066
14067 let escape_backslash = matches!(
14069 self.config.dialect,
14070 Some(DialectType::BigQuery)
14071 | Some(DialectType::MySQL)
14072 | Some(DialectType::SingleStore)
14073 | Some(DialectType::TiDB)
14074 | Some(DialectType::Hive)
14075 | Some(DialectType::Spark)
14076 | Some(DialectType::Databricks)
14077 | Some(DialectType::Drill)
14078 | Some(DialectType::Snowflake)
14079 | Some(DialectType::Redshift)
14080 | Some(DialectType::ClickHouse)
14081 );
14082
14083 let backslash_escapes_quote = matches!(
14086 self.config.dialect,
14087 Some(DialectType::BigQuery)
14088 | Some(DialectType::Hive)
14089 | Some(DialectType::Spark)
14090 | Some(DialectType::Databricks)
14091 | Some(DialectType::Drill)
14092 | Some(DialectType::Snowflake)
14093 | Some(DialectType::Redshift)
14094 );
14095
14096 let supports_escape_sequences = escape_backslash;
14099
14100 let mut escaped = String::with_capacity(s.len() + 4);
14101 for ch in s.chars() {
14102 if escape_backslash && ch == '\\' {
14103 escaped.push('\\');
14105 escaped.push('\\');
14106 } else if ch == '\'' {
14107 if backslash_escapes_quote {
14108 escaped.push('\\');
14110 escaped.push('\'');
14111 } else {
14112 escaped.push('\'');
14114 escaped.push('\'');
14115 }
14116 } else if supports_escape_sequences {
14117 match ch {
14120 '\n' => {
14121 escaped.push('\\');
14122 escaped.push('n');
14123 }
14124 '\r' => {
14125 escaped.push('\\');
14126 escaped.push('r');
14127 }
14128 '\t' => {
14129 escaped.push('\\');
14130 escaped.push('t');
14131 }
14132 '\x07' => {
14133 escaped.push('\\');
14134 escaped.push('a');
14135 }
14136 '\x08' => {
14137 escaped.push('\\');
14138 escaped.push('b');
14139 }
14140 '\x0C' => {
14141 escaped.push('\\');
14142 escaped.push('f');
14143 }
14144 '\x0B' => {
14145 escaped.push('\\');
14146 escaped.push('v');
14147 }
14148 _ => escaped.push(ch),
14149 }
14150 } else {
14151 escaped.push(ch);
14152 }
14153 }
14154 self.write("'");
14155 self.write(&escaped);
14156 self.write("'");
14157 }
14158 }
14159 Ok(())
14160 }
14161
14162 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
14164 use crate::dialects::DialectType;
14165
14166 match self.config.dialect {
14167 Some(DialectType::TSQL) => {
14169 self.write("CAST('");
14170 self.write(d);
14171 self.write("' AS DATE)");
14172 }
14173 Some(DialectType::BigQuery) => {
14176 self.write("CAST('");
14177 self.write(d);
14178 self.write("' AS DATE)");
14179 }
14180 Some(DialectType::Exasol) => {
14183 self.write("CAST('");
14184 self.write(d);
14185 self.write("' AS DATE)");
14186 }
14187 Some(DialectType::Snowflake) => {
14190 self.write("CAST('");
14191 self.write(d);
14192 self.write("' AS DATE)");
14193 }
14194 Some(DialectType::PostgreSQL)
14196 | Some(DialectType::MySQL)
14197 | Some(DialectType::SingleStore)
14198 | Some(DialectType::TiDB)
14199 | Some(DialectType::Redshift) => {
14200 self.write("CAST('");
14201 self.write(d);
14202 self.write("' AS DATE)");
14203 }
14204 Some(DialectType::DuckDB)
14206 | Some(DialectType::Presto)
14207 | Some(DialectType::Trino)
14208 | Some(DialectType::Athena)
14209 | Some(DialectType::Spark)
14210 | Some(DialectType::Databricks)
14211 | Some(DialectType::Hive) => {
14212 self.write("CAST('");
14213 self.write(d);
14214 self.write("' AS DATE)");
14215 }
14216 Some(DialectType::Oracle) => {
14218 self.write("TO_DATE('");
14219 self.write(d);
14220 self.write("', 'YYYY-MM-DD')");
14221 }
14222 _ => {
14224 self.write_keyword("DATE");
14225 self.write(" '");
14226 self.write(d);
14227 self.write("'");
14228 }
14229 }
14230 Ok(())
14231 }
14232
14233 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
14235 use crate::dialects::DialectType;
14236
14237 match self.config.dialect {
14238 Some(DialectType::TSQL) => {
14240 self.write("CAST('");
14241 self.write(t);
14242 self.write("' AS TIME)");
14243 }
14244 _ => {
14246 self.write_keyword("TIME");
14247 self.write(" '");
14248 self.write(t);
14249 self.write("'");
14250 }
14251 }
14252 Ok(())
14253 }
14254
14255 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
14257 use crate::expressions::Literal;
14258
14259 match expr {
14260 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
14261 let Literal::Date(d) = lit.as_ref() else { unreachable!() };
14262 self.write("CAST('");
14264 self.write(d);
14265 self.write("' AS DATE)");
14266 }
14267 _ => {
14268 self.generate_expression(expr)?;
14270 }
14271 }
14272 Ok(())
14273 }
14274
14275 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
14277 use crate::dialects::DialectType;
14278
14279 match self.config.dialect {
14280 Some(DialectType::TSQL) => {
14282 self.write("CAST('");
14283 self.write(ts);
14284 self.write("' AS DATETIME2)");
14285 }
14286 Some(DialectType::BigQuery) => {
14289 self.write("CAST('");
14290 self.write(ts);
14291 self.write("' AS TIMESTAMP)");
14292 }
14293 Some(DialectType::Snowflake) => {
14296 self.write("CAST('");
14297 self.write(ts);
14298 self.write("' AS TIMESTAMP)");
14299 }
14300 Some(DialectType::Dremio) => {
14303 self.write("CAST('");
14304 self.write(ts);
14305 self.write("' AS TIMESTAMP)");
14306 }
14307 Some(DialectType::Exasol) => {
14310 self.write("CAST('");
14311 self.write(ts);
14312 self.write("' AS TIMESTAMP)");
14313 }
14314 Some(DialectType::Oracle) => {
14317 self.write("TO_TIMESTAMP('");
14318 self.write(ts);
14319 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
14320 }
14321 Some(DialectType::Presto) | Some(DialectType::Trino) => {
14323 if Self::timestamp_has_timezone(ts) {
14324 self.write("CAST('");
14325 self.write(ts);
14326 self.write("' AS TIMESTAMP WITH TIME ZONE)");
14327 } else {
14328 self.write("CAST('");
14329 self.write(ts);
14330 self.write("' AS TIMESTAMP)");
14331 }
14332 }
14333 Some(DialectType::ClickHouse) => {
14335 self.write("CAST('");
14336 self.write(ts);
14337 self.write("' AS Nullable(DateTime))");
14338 }
14339 Some(DialectType::Spark) => {
14341 self.write("CAST('");
14342 self.write(ts);
14343 self.write("' AS TIMESTAMP)");
14344 }
14345 Some(DialectType::Redshift) => {
14348 if ts == "epoch" {
14349 self.write_keyword("TIMESTAMP");
14350 self.write(" '");
14351 self.write(ts);
14352 self.write("'");
14353 } else {
14354 self.write("CAST('");
14355 self.write(ts);
14356 self.write("' AS TIMESTAMP)");
14357 }
14358 }
14359 Some(DialectType::PostgreSQL)
14361 | Some(DialectType::Hive)
14362 | Some(DialectType::SQLite)
14363 | Some(DialectType::DuckDB)
14364 | Some(DialectType::Athena)
14365 | Some(DialectType::Drill)
14366 | Some(DialectType::Teradata) => {
14367 self.write("CAST('");
14368 self.write(ts);
14369 self.write("' AS TIMESTAMP)");
14370 }
14371 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
14373 self.write("CAST('");
14374 self.write(ts);
14375 self.write("' AS DATETIME)");
14376 }
14377 Some(DialectType::Databricks) => {
14379 self.write("CAST('");
14380 self.write(ts);
14381 self.write("' AS TIMESTAMP_NTZ)");
14382 }
14383 _ => {
14385 self.write_keyword("TIMESTAMP");
14386 self.write(" '");
14387 self.write(ts);
14388 self.write("'");
14389 }
14390 }
14391 Ok(())
14392 }
14393
14394 fn timestamp_has_timezone(ts: &str) -> bool {
14397 let ts_lower = ts.to_ascii_lowercase();
14401
14402 let continent_prefixes = [
14404 "africa/",
14405 "america/",
14406 "antarctica/",
14407 "arctic/",
14408 "asia/",
14409 "atlantic/",
14410 "australia/",
14411 "europe/",
14412 "indian/",
14413 "pacific/",
14414 "etc/",
14415 "brazil/",
14416 "canada/",
14417 "chile/",
14418 "mexico/",
14419 "us/",
14420 ];
14421
14422 for prefix in &continent_prefixes {
14423 if ts_lower.contains(prefix) {
14424 return true;
14425 }
14426 }
14427
14428 let tz_abbrevs = [
14431 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
14432 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
14433 " sgt", " aest", " aedt", " acst", " acdt", " awst",
14434 ];
14435
14436 for abbrev in &tz_abbrevs {
14437 if ts_lower.ends_with(abbrev) {
14438 return true;
14439 }
14440 }
14441
14442 let trimmed = ts.trim();
14446 if let Some(last_space) = trimmed.rfind(' ') {
14447 let suffix = &trimmed[last_space + 1..];
14448 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
14449 let rest = &suffix[1..];
14451 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
14452 return true;
14453 }
14454 }
14455 }
14456
14457 false
14458 }
14459
14460 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
14462 use crate::dialects::DialectType;
14463
14464 match self.config.dialect {
14465 Some(DialectType::BigQuery) => {
14468 self.write("CAST('");
14469 self.write(dt);
14470 self.write("' AS DATETIME)");
14471 }
14472 Some(DialectType::DuckDB) => {
14474 self.write("CAST('");
14475 self.write(dt);
14476 self.write("' AS TIMESTAMP)");
14477 }
14478 _ => {
14481 self.write_keyword("DATETIME");
14482 self.write(" '");
14483 self.write(dt);
14484 self.write("'");
14485 }
14486 }
14487 Ok(())
14488 }
14489
14490 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
14492 use crate::dialects::DialectType;
14493
14494 match self.config.dialect {
14495 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
14499 self.write("'");
14501 for c in s.chars() {
14502 match c {
14503 '\'' => self.write("\\'"),
14504 '\\' => self.write("\\\\"),
14505 '\n' => self.write("\\n"),
14506 '\r' => self.write("\\r"),
14507 '\t' => self.write("\\t"),
14508 '\0' => self.write("\\0"),
14509 _ => self.output.push(c),
14510 }
14511 }
14512 self.write("'");
14513 }
14514 Some(DialectType::Drill) => {
14515 self.write("'");
14518 for c in s.chars() {
14519 match c {
14520 '\'' => self.write("''"),
14521 '\\' => self.write("\\\\"),
14522 '\n' => self.write("\\n"),
14523 '\r' => self.write("\\r"),
14524 '\t' => self.write("\\t"),
14525 '\0' => self.write("\\0"),
14526 _ => self.output.push(c),
14527 }
14528 }
14529 self.write("'");
14530 }
14531 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
14532 self.write("'");
14533 for c in s.chars() {
14534 match c {
14535 '\'' => self.write("''"),
14537 '\\' => self.write("\\\\"),
14538 '\n' => self.write("\\n"),
14539 '\r' => self.write("\\r"),
14540 '\t' => self.write("\\t"),
14541 '\0' => self.output.push('\0'),
14543 _ => self.output.push(c),
14544 }
14545 }
14546 self.write("'");
14547 }
14548 Some(DialectType::BigQuery) => {
14550 self.write("'");
14551 for c in s.chars() {
14552 match c {
14553 '\'' => self.write("\\'"),
14554 '\\' => self.write("\\\\"),
14555 '\n' => self.write("\\n"),
14556 '\r' => self.write("\\r"),
14557 '\t' => self.write("\\t"),
14558 '\0' => self.write("\\0"),
14559 '\x07' => self.write("\\a"),
14560 '\x08' => self.write("\\b"),
14561 '\x0C' => self.write("\\f"),
14562 '\x0B' => self.write("\\v"),
14563 _ => self.output.push(c),
14564 }
14565 }
14566 self.write("'");
14567 }
14568 Some(DialectType::Athena) => {
14572 if self.athena_hive_context {
14573 self.write("'");
14575 for c in s.chars() {
14576 match c {
14577 '\'' => self.write("\\'"),
14578 '\\' => self.write("\\\\"),
14579 '\n' => self.write("\\n"),
14580 '\r' => self.write("\\r"),
14581 '\t' => self.write("\\t"),
14582 '\0' => self.write("\\0"),
14583 _ => self.output.push(c),
14584 }
14585 }
14586 self.write("'");
14587 } else {
14588 self.write("'");
14590 for c in s.chars() {
14591 match c {
14592 '\'' => self.write("''"),
14593 _ => self.output.push(c),
14595 }
14596 }
14597 self.write("'");
14598 }
14599 }
14600 Some(DialectType::Snowflake) => {
14605 self.write("'");
14606 for c in s.chars() {
14607 match c {
14608 '\'' => self.write("\\'"),
14609 '\n' => self.write("\\n"),
14612 '\r' => self.write("\\r"),
14613 '\t' => self.write("\\t"),
14614 _ => self.output.push(c),
14615 }
14616 }
14617 self.write("'");
14618 }
14619 Some(DialectType::PostgreSQL) => {
14621 self.write("'");
14622 for c in s.chars() {
14623 match c {
14624 '\'' => self.write("''"),
14625 _ => self.output.push(c),
14626 }
14627 }
14628 self.write("'");
14629 }
14630 Some(DialectType::Redshift) => {
14632 self.write("'");
14633 for c in s.chars() {
14634 match c {
14635 '\'' => self.write("\\'"),
14636 _ => self.output.push(c),
14637 }
14638 }
14639 self.write("'");
14640 }
14641 Some(DialectType::Oracle) => {
14643 self.write("'");
14644 for ch in s.chars() {
14645 if ch == '\'' { self.output.push_str("''"); } else { self.output.push(ch); }
14646 }
14647 self.write("'");
14648 }
14649 Some(DialectType::ClickHouse) => {
14652 self.write("'");
14653 for c in s.chars() {
14654 match c {
14655 '\'' => self.write("''"),
14656 '\\' => self.write("\\\\"),
14657 '\n' => self.write("\\n"),
14658 '\r' => self.write("\\r"),
14659 '\t' => self.write("\\t"),
14660 '\0' => self.write("\\0"),
14661 '\x07' => self.write("\\a"),
14662 '\x08' => self.write("\\b"),
14663 '\x0C' => self.write("\\f"),
14664 '\x0B' => self.write("\\v"),
14665 c if c.is_control() || (c as u32) < 0x20 => {
14667 let byte = c as u32;
14668 if byte < 256 {
14669 self.write(&format!("\\x{:02X}", byte));
14670 } else {
14671 self.output.push(c);
14672 }
14673 }
14674 _ => self.output.push(c),
14675 }
14676 }
14677 self.write("'");
14678 }
14679 _ => {
14682 self.write("'");
14683 for ch in s.chars() {
14684 if ch == '\'' { self.output.push_str("''"); } else { self.output.push(ch); }
14685 }
14686 self.write("'");
14687 }
14688 }
14689 Ok(())
14690 }
14691
14692 fn write_escaped_byte_string(&mut self, s: &str) {
14695 for c in s.chars() {
14696 match c {
14697 '\'' => self.write("\\'"),
14699 '\\' => self.write("\\\\"),
14701 _ if !c.is_control() => self.output.push(c),
14703 _ => {
14705 let byte = c as u32;
14706 if byte < 256 {
14707 self.write(&format!("\\x{:02x}", byte));
14708 } else {
14709 for b in c.to_string().as_bytes() {
14711 self.write(&format!("\\x{:02x}", b));
14712 }
14713 }
14714 }
14715 }
14716 }
14717 }
14718
14719 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
14720 use crate::dialects::DialectType;
14721
14722 match self.config.dialect {
14724 Some(DialectType::TSQL) => {
14727 self.write(if b.value { "1" } else { "0" });
14728 }
14729 Some(DialectType::Oracle) => {
14731 self.write(if b.value { "1" } else { "0" });
14732 }
14733 Some(DialectType::MySQL) => {
14735 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14736 }
14737 _ => {
14739 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14740 }
14741 }
14742 Ok(())
14743 }
14744
14745 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
14748 let name = &id.name;
14749 let quote_style = &self.config.identifier_quote_style;
14750
14751 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
14755
14756 let output_name = if self.config.normalize_identifiers && !id.quoted {
14758 name.to_ascii_lowercase()
14759 } else {
14760 name.to_string()
14761 };
14762
14763 if needs_quoting {
14764 let escaped_name = if quote_style.start == quote_style.end {
14766 output_name.replace(
14767 quote_style.end,
14768 &format!("{}{}", quote_style.end, quote_style.end),
14769 )
14770 } else {
14771 output_name.replace(
14772 quote_style.end,
14773 &format!("{}{}", quote_style.end, quote_style.end),
14774 )
14775 };
14776 self.write(&format!(
14777 "{}{}{}",
14778 quote_style.start, escaped_name, quote_style.end
14779 ));
14780 } else {
14781 self.write(&output_name);
14782 }
14783
14784 for comment in &id.trailing_comments {
14786 self.write(" ");
14787 self.write_formatted_comment(comment);
14788 }
14789 Ok(())
14790 }
14791
14792 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
14793 use crate::dialects::DialectType;
14794
14795 let name = &id.name;
14796
14797 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
14799 && self.athena_hive_context
14800 {
14801 &IdentifierQuoteStyle::BACKTICK
14802 } else {
14803 &self.config.identifier_quote_style
14804 };
14805
14806 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
14813 let needs_digit_quoting = starts_with_digit
14814 && !self.config.identifiers_can_start_with_digit
14815 && self.config.dialect.is_some();
14816 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
14817 && name.len() > 2
14818 && (name.starts_with("0x") || name.starts_with("0X"))
14819 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
14820 let needs_quoting = id.quoted
14821 || self.is_reserved_keyword(name)
14822 || self.config.always_quote_identifiers
14823 || needs_digit_quoting
14824 || mysql_invalid_hex_identifier;
14825
14826 let (base_name, suffix) = if needs_quoting {
14829 if let Some(paren_pos) = name.find('(') {
14831 let base = &name[..paren_pos];
14832 let rest = &name[paren_pos..];
14833 if rest.starts_with('(')
14835 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
14836 {
14837 let close_paren = rest.find(')').unwrap_or(rest.len());
14839 let inside = &rest[1..close_paren];
14840 if inside.chars().all(|c| c.is_ascii_digit()) {
14841 (base.to_string(), rest.to_string())
14842 } else {
14843 (name.to_string(), String::new())
14844 }
14845 } else {
14846 (name.to_string(), String::new())
14847 }
14848 } else if name.ends_with(" ASC") {
14849 let base = &name[..name.len() - 4];
14850 (base.to_string(), " ASC".to_string())
14851 } else if name.ends_with(" DESC") {
14852 let base = &name[..name.len() - 5];
14853 (base.to_string(), " DESC".to_string())
14854 } else {
14855 (name.to_string(), String::new())
14856 }
14857 } else {
14858 (name.to_string(), String::new())
14859 };
14860
14861 let output_name = if self.config.normalize_identifiers && !id.quoted {
14865 base_name.to_ascii_lowercase()
14866 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
14867 && !id.quoted
14868 && self.is_reserved_keyword(name)
14869 {
14870 base_name.to_ascii_uppercase()
14873 } else {
14874 base_name
14875 };
14876
14877 if needs_quoting {
14878 let escaped_name = if quote_style.start == quote_style.end {
14880 output_name.replace(
14882 quote_style.end,
14883 &format!("{}{}", quote_style.end, quote_style.end),
14884 )
14885 } else {
14886 output_name.replace(
14888 quote_style.end,
14889 &format!("{}{}", quote_style.end, quote_style.end),
14890 )
14891 };
14892 self.write(&format!(
14893 "{}{}{}{}",
14894 quote_style.start, escaped_name, quote_style.end, suffix
14895 ));
14896 } else {
14897 self.write(&output_name);
14898 }
14899
14900 for comment in &id.trailing_comments {
14902 self.write(" ");
14903 self.write_formatted_comment(comment);
14904 }
14905 Ok(())
14906 }
14907
14908 fn generate_column(&mut self, col: &Column) -> Result<()> {
14909 use crate::dialects::DialectType;
14910
14911 if let Some(table) = &col.table {
14912 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
14916 && !table.quoted
14917 && table.name.eq_ignore_ascii_case("LOCAL");
14918
14919 if is_exasol_local_prefix {
14920 self.write("LOCAL");
14922 } else {
14923 self.generate_identifier(table)?;
14924 }
14925 self.write(".");
14926 }
14927 self.generate_identifier(&col.name)?;
14928 if col.join_mark && self.config.supports_column_join_marks {
14931 self.write(" (+)");
14932 }
14933 for comment in &col.trailing_comments {
14935 self.write_space();
14936 self.write_formatted_comment(comment);
14937 }
14938 Ok(())
14939 }
14940
14941 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
14944 use crate::dialects::DialectType;
14945 use crate::expressions::PseudocolumnType;
14946
14947 if pc.kind == PseudocolumnType::Sysdate
14949 && !matches!(
14950 self.config.dialect,
14951 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
14952 )
14953 {
14954 self.write_keyword("CURRENT_TIMESTAMP");
14955 if matches!(
14957 self.config.dialect,
14958 Some(DialectType::MySQL)
14959 | Some(DialectType::ClickHouse)
14960 | Some(DialectType::Spark)
14961 | Some(DialectType::Databricks)
14962 | Some(DialectType::Hive)
14963 ) {
14964 self.write("()");
14965 }
14966 } else {
14967 self.write(pc.kind.as_str());
14968 }
14969 Ok(())
14970 }
14971
14972 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
14974 use crate::dialects::DialectType;
14975
14976 let supports_connect_by = matches!(
14979 self.config.dialect,
14980 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
14981 );
14982
14983 if !supports_connect_by && self.config.dialect.is_some() {
14984 if self.config.pretty {
14986 self.write_newline();
14987 } else {
14988 self.write_space();
14989 }
14990 self.write_unsupported_comment(
14991 "CONNECT BY requires manual conversion to recursive CTE",
14992 )?;
14993 }
14994
14995 if let Some(start) = &connect.start {
14997 if self.config.pretty {
14998 self.write_newline();
14999 } else {
15000 self.write_space();
15001 }
15002 self.write_keyword("START WITH");
15003 self.write_space();
15004 self.generate_expression(start)?;
15005 }
15006
15007 if self.config.pretty {
15009 self.write_newline();
15010 } else {
15011 self.write_space();
15012 }
15013 self.write_keyword("CONNECT BY");
15014 if connect.nocycle {
15015 self.write_space();
15016 self.write_keyword("NOCYCLE");
15017 }
15018 self.write_space();
15019 self.generate_expression(&connect.connect)?;
15020
15021 Ok(())
15022 }
15023
15024 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
15026 self.generate_connect(connect)
15027 }
15028
15029 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
15031 self.write_keyword("PRIOR");
15032 self.write_space();
15033 self.generate_expression(&prior.this)?;
15034 Ok(())
15035 }
15036
15037 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
15040 self.write_keyword("CONNECT_BY_ROOT");
15041 self.write_space();
15042 self.generate_expression(&cbr.this)?;
15043 Ok(())
15044 }
15045
15046 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
15048 use crate::dialects::DialectType;
15049
15050 let supports_match_recognize = matches!(
15052 self.config.dialect,
15053 Some(DialectType::Oracle)
15054 | Some(DialectType::Snowflake)
15055 | Some(DialectType::Presto)
15056 | Some(DialectType::Trino)
15057 );
15058
15059 if let Some(source) = &mr.this {
15061 self.generate_expression(source)?;
15062 }
15063
15064 if !supports_match_recognize {
15065 self.write_unsupported_comment("MATCH_RECOGNIZE not supported in this dialect")?;
15066 return Ok(());
15067 }
15068
15069 if self.config.pretty {
15071 self.write_newline();
15072 } else {
15073 self.write_space();
15074 }
15075
15076 self.write_keyword("MATCH_RECOGNIZE");
15077 self.write(" (");
15078
15079 if self.config.pretty {
15080 self.indent_level += 1;
15081 }
15082
15083 let mut needs_separator = false;
15084
15085 if let Some(partition_by) = &mr.partition_by {
15087 if !partition_by.is_empty() {
15088 if self.config.pretty {
15089 self.write_newline();
15090 self.write_indent();
15091 }
15092 self.write_keyword("PARTITION BY");
15093 self.write_space();
15094 for (i, expr) in partition_by.iter().enumerate() {
15095 if i > 0 {
15096 self.write(", ");
15097 }
15098 self.generate_expression(expr)?;
15099 }
15100 needs_separator = true;
15101 }
15102 }
15103
15104 if let Some(order_by) = &mr.order_by {
15106 if !order_by.is_empty() {
15107 if needs_separator {
15108 if self.config.pretty {
15109 self.write_newline();
15110 self.write_indent();
15111 } else {
15112 self.write_space();
15113 }
15114 } else if self.config.pretty {
15115 self.write_newline();
15116 self.write_indent();
15117 }
15118 self.write_keyword("ORDER BY");
15119 if self.config.pretty {
15121 self.indent_level += 1;
15122 for (i, ordered) in order_by.iter().enumerate() {
15123 if i > 0 {
15124 self.write(",");
15125 }
15126 self.write_newline();
15127 self.write_indent();
15128 self.generate_ordered(ordered)?;
15129 }
15130 self.indent_level -= 1;
15131 } else {
15132 self.write_space();
15133 for (i, ordered) in order_by.iter().enumerate() {
15134 if i > 0 {
15135 self.write(", ");
15136 }
15137 self.generate_ordered(ordered)?;
15138 }
15139 }
15140 needs_separator = true;
15141 }
15142 }
15143
15144 if let Some(measures) = &mr.measures {
15146 if !measures.is_empty() {
15147 if needs_separator {
15148 if self.config.pretty {
15149 self.write_newline();
15150 self.write_indent();
15151 } else {
15152 self.write_space();
15153 }
15154 } else if self.config.pretty {
15155 self.write_newline();
15156 self.write_indent();
15157 }
15158 self.write_keyword("MEASURES");
15159 if self.config.pretty {
15161 self.indent_level += 1;
15162 for (i, measure) in measures.iter().enumerate() {
15163 if i > 0 {
15164 self.write(",");
15165 }
15166 self.write_newline();
15167 self.write_indent();
15168 if let Some(semantics) = &measure.window_frame {
15170 match semantics {
15171 MatchRecognizeSemantics::Running => {
15172 self.write_keyword("RUNNING");
15173 self.write_space();
15174 }
15175 MatchRecognizeSemantics::Final => {
15176 self.write_keyword("FINAL");
15177 self.write_space();
15178 }
15179 }
15180 }
15181 self.generate_expression(&measure.this)?;
15182 }
15183 self.indent_level -= 1;
15184 } else {
15185 self.write_space();
15186 for (i, measure) in measures.iter().enumerate() {
15187 if i > 0 {
15188 self.write(", ");
15189 }
15190 if let Some(semantics) = &measure.window_frame {
15192 match semantics {
15193 MatchRecognizeSemantics::Running => {
15194 self.write_keyword("RUNNING");
15195 self.write_space();
15196 }
15197 MatchRecognizeSemantics::Final => {
15198 self.write_keyword("FINAL");
15199 self.write_space();
15200 }
15201 }
15202 }
15203 self.generate_expression(&measure.this)?;
15204 }
15205 }
15206 needs_separator = true;
15207 }
15208 }
15209
15210 if let Some(rows) = &mr.rows {
15212 if needs_separator {
15213 if self.config.pretty {
15214 self.write_newline();
15215 self.write_indent();
15216 } else {
15217 self.write_space();
15218 }
15219 } else if self.config.pretty {
15220 self.write_newline();
15221 self.write_indent();
15222 }
15223 match rows {
15224 MatchRecognizeRows::OneRowPerMatch => {
15225 self.write_keyword("ONE ROW PER MATCH");
15226 }
15227 MatchRecognizeRows::AllRowsPerMatch => {
15228 self.write_keyword("ALL ROWS PER MATCH");
15229 }
15230 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
15231 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
15232 }
15233 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
15234 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
15235 }
15236 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
15237 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
15238 }
15239 }
15240 needs_separator = true;
15241 }
15242
15243 if let Some(after) = &mr.after {
15245 if needs_separator {
15246 if self.config.pretty {
15247 self.write_newline();
15248 self.write_indent();
15249 } else {
15250 self.write_space();
15251 }
15252 } else if self.config.pretty {
15253 self.write_newline();
15254 self.write_indent();
15255 }
15256 match after {
15257 MatchRecognizeAfter::PastLastRow => {
15258 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
15259 }
15260 MatchRecognizeAfter::ToNextRow => {
15261 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
15262 }
15263 MatchRecognizeAfter::ToFirst(ident) => {
15264 self.write_keyword("AFTER MATCH SKIP TO FIRST");
15265 self.write_space();
15266 self.generate_identifier(ident)?;
15267 }
15268 MatchRecognizeAfter::ToLast(ident) => {
15269 self.write_keyword("AFTER MATCH SKIP TO LAST");
15270 self.write_space();
15271 self.generate_identifier(ident)?;
15272 }
15273 }
15274 needs_separator = true;
15275 }
15276
15277 if let Some(pattern) = &mr.pattern {
15279 if needs_separator {
15280 if self.config.pretty {
15281 self.write_newline();
15282 self.write_indent();
15283 } else {
15284 self.write_space();
15285 }
15286 } else if self.config.pretty {
15287 self.write_newline();
15288 self.write_indent();
15289 }
15290 self.write_keyword("PATTERN");
15291 self.write_space();
15292 self.write("(");
15293 self.write(pattern);
15294 self.write(")");
15295 needs_separator = true;
15296 }
15297
15298 if let Some(define) = &mr.define {
15300 if !define.is_empty() {
15301 if needs_separator {
15302 if self.config.pretty {
15303 self.write_newline();
15304 self.write_indent();
15305 } else {
15306 self.write_space();
15307 }
15308 } else if self.config.pretty {
15309 self.write_newline();
15310 self.write_indent();
15311 }
15312 self.write_keyword("DEFINE");
15313 if self.config.pretty {
15315 self.indent_level += 1;
15316 for (i, (name, expr)) in define.iter().enumerate() {
15317 if i > 0 {
15318 self.write(",");
15319 }
15320 self.write_newline();
15321 self.write_indent();
15322 self.generate_identifier(name)?;
15323 self.write(" AS ");
15324 self.generate_expression(expr)?;
15325 }
15326 self.indent_level -= 1;
15327 } else {
15328 self.write_space();
15329 for (i, (name, expr)) in define.iter().enumerate() {
15330 if i > 0 {
15331 self.write(", ");
15332 }
15333 self.generate_identifier(name)?;
15334 self.write(" AS ");
15335 self.generate_expression(expr)?;
15336 }
15337 }
15338 }
15339 }
15340
15341 if self.config.pretty {
15342 self.indent_level -= 1;
15343 self.write_newline();
15344 }
15345 self.write(")");
15346
15347 if let Some(alias) = &mr.alias {
15349 self.write(" ");
15350 if mr.alias_explicit_as {
15351 self.write_keyword("AS");
15352 self.write(" ");
15353 }
15354 self.generate_identifier(alias)?;
15355 }
15356
15357 Ok(())
15358 }
15359
15360 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
15362 use crate::dialects::DialectType;
15363
15364 let supports_hints = matches!(
15366 self.config.dialect,
15367 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
15369 Some(DialectType::Spark) | Some(DialectType::Hive) |
15370 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
15371 );
15372
15373 if !supports_hints || hint.expressions.is_empty() {
15374 return Ok(());
15375 }
15376
15377 let mut hint_strings: Vec<String> = Vec::new();
15380 for expr in &hint.expressions {
15381 match expr {
15382 HintExpression::Raw(text) => {
15383 let parsed = self.parse_raw_hint_text(text);
15385 hint_strings.extend(parsed);
15386 }
15387 _ => {
15388 hint_strings.push(self.hint_expression_to_string(expr)?);
15389 }
15390 }
15391 }
15392
15393 let use_multiline = self.config.pretty && hint_strings.len() > 1;
15397
15398 if use_multiline {
15399 self.write(" /*+ ");
15401 for (i, hint_str) in hint_strings.iter().enumerate() {
15402 if i > 0 {
15403 self.write_newline();
15404 self.write(" "); }
15406 self.write(hint_str);
15407 }
15408 self.write(" */");
15409 } else {
15410 self.write(" /*+ ");
15412 let sep = match self.config.dialect {
15413 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
15414 _ => " ",
15415 };
15416 for (i, hint_str) in hint_strings.iter().enumerate() {
15417 if i > 0 {
15418 self.write(sep);
15419 }
15420 self.write(hint_str);
15421 }
15422 self.write(" */");
15423 }
15424
15425 Ok(())
15426 }
15427
15428 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
15432 let mut results = Vec::new();
15433 let mut chars = text.chars().peekable();
15434 let mut current = String::new();
15435 let mut paren_depth = 0;
15436 let mut has_unparseable_content = false;
15437 let mut position_after_last_function = 0;
15438 let mut char_position = 0;
15439
15440 while let Some(c) = chars.next() {
15441 char_position += c.len_utf8();
15442 match c {
15443 '(' => {
15444 paren_depth += 1;
15445 current.push(c);
15446 }
15447 ')' => {
15448 paren_depth -= 1;
15449 current.push(c);
15450 if paren_depth == 0 {
15452 let trimmed = current.trim().to_string();
15453 if !trimmed.is_empty() {
15454 let formatted = self.format_hint_function(&trimmed);
15456 results.push(formatted);
15457 }
15458 current.clear();
15459 position_after_last_function = char_position;
15460 }
15461 }
15462 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
15463 }
15465 _ if paren_depth == 0 => {
15466 current.push(c);
15468 }
15469 _ => {
15470 current.push(c);
15471 }
15472 }
15473 }
15474
15475 let remaining_text = text[position_after_last_function..].trim();
15477 if !remaining_text.is_empty() {
15478 let words: Vec<&str> = remaining_text.split_whitespace().collect();
15482 let looks_like_hint_functions = words.iter().all(|word| {
15483 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
15485 });
15486
15487 if !looks_like_hint_functions && words.len() > 1 {
15488 has_unparseable_content = true;
15489 }
15490 }
15491
15492 if has_unparseable_content {
15494 return vec![text.trim().to_string()];
15495 }
15496
15497 if results.is_empty() {
15499 results.push(text.trim().to_string());
15500 }
15501
15502 results
15503 }
15504
15505 fn format_hint_function(&self, hint: &str) -> String {
15508 if !self.config.pretty {
15509 return hint.to_string();
15510 }
15511
15512 if let Some(paren_pos) = hint.find('(') {
15514 if hint.ends_with(')') {
15515 let name = &hint[..paren_pos];
15516 let args_str = &hint[paren_pos + 1..hint.len() - 1];
15517
15518 let args: Vec<&str> = args_str.split_whitespace().collect();
15520
15521 let total_args_width: usize =
15523 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() {
15527 let mut result = format!("{}(\n", name);
15528 for arg in &args {
15529 result.push_str(" "); result.push_str(arg);
15531 result.push('\n');
15532 }
15533 result.push_str(" )"); return result;
15535 }
15536 }
15537 }
15538
15539 hint.to_string()
15540 }
15541
15542 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
15544 match expr {
15545 HintExpression::Function { name, args } => {
15546 let arg_strings: Vec<String> = args
15548 .iter()
15549 .map(|arg| {
15550 let mut gen = Generator::with_arc_config(self.config.clone());
15551 gen.generate_expression(arg)?;
15552 Ok(gen.output)
15553 })
15554 .collect::<Result<Vec<_>>>()?;
15555
15556 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
15558 + arg_strings.len().saturating_sub(1); let args_multiline =
15563 self.config.pretty && total_args_width > self.config.max_text_width;
15564
15565 if args_multiline && !arg_strings.is_empty() {
15566 let mut result = format!("{}(\n", name);
15568 for arg_str in &arg_strings {
15569 result.push_str(" "); result.push_str(arg_str);
15571 result.push('\n');
15572 }
15573 result.push_str(" )"); Ok(result)
15575 } else {
15576 let args_str = arg_strings.join(" ");
15578 Ok(format!("{}({})", name, args_str))
15579 }
15580 }
15581 HintExpression::Identifier(name) => Ok(name.clone()),
15582 HintExpression::Raw(text) => {
15583 if self.config.pretty {
15585 Ok(self.format_hint_function(text))
15586 } else {
15587 Ok(text.clone())
15588 }
15589 }
15590 }
15591 }
15592
15593 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
15594 if table.only {
15596 self.write_keyword("ONLY");
15597 self.write_space();
15598 }
15599
15600 if let Some(ref identifier_func) = table.identifier_func {
15602 self.generate_expression(identifier_func)?;
15603 } else {
15604 if let Some(catalog) = &table.catalog {
15605 self.generate_identifier(catalog)?;
15606 self.write(".");
15607 }
15608 if let Some(schema) = &table.schema {
15609 self.generate_identifier(schema)?;
15610 self.write(".");
15611 }
15612 self.generate_identifier(&table.name)?;
15613 }
15614
15615 if let Some(changes) = &table.changes {
15617 self.write(" ");
15618 self.generate_changes(changes)?;
15619 }
15620
15621 if !table.partitions.is_empty() {
15623 self.write_space();
15624 self.write_keyword("PARTITION");
15625 self.write("(");
15626 for (i, partition) in table.partitions.iter().enumerate() {
15627 if i > 0 {
15628 self.write(", ");
15629 }
15630 self.generate_identifier(partition)?;
15631 }
15632 self.write(")");
15633 }
15634
15635 if table.changes.is_none() {
15638 if let Some(when) = &table.when {
15639 self.write_space();
15640 self.generate_historical_data(when)?;
15641 }
15642 }
15643
15644 let system_time_post_alias = matches!(self.config.dialect, Some(DialectType::BigQuery));
15646 if !system_time_post_alias {
15647 if let Some(ref system_time) = table.system_time {
15648 self.write_space();
15649 self.write(system_time);
15650 }
15651 }
15652
15653 if let Some(ref version) = table.version {
15655 self.write_space();
15656 self.generate_version(version)?;
15657 }
15658
15659 let alias_post_tablesample = self.config.alias_post_tablesample;
15663
15664 if alias_post_tablesample {
15665 self.generate_table_sample_clause(table)?;
15667 }
15668
15669 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
15672 && table.hints.iter().any(|h| {
15673 if let Expression::Identifier(id) = h {
15674 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
15675 } else {
15676 false
15677 }
15678 });
15679 if !table.hints.is_empty() && !is_sqlite_hint {
15680 for hint in &table.hints {
15681 self.write_space();
15682 self.generate_expression(hint)?;
15683 }
15684 }
15685
15686 if let Some(alias) = &table.alias {
15687 self.write_space();
15688 let always_use_as = self.config.dialect.is_none()
15691 || matches!(
15692 self.config.dialect,
15693 Some(DialectType::Generic)
15694 | Some(DialectType::PostgreSQL)
15695 | Some(DialectType::Redshift)
15696 | Some(DialectType::Snowflake)
15697 | Some(DialectType::BigQuery)
15698 | Some(DialectType::DuckDB)
15699 | Some(DialectType::Presto)
15700 | Some(DialectType::Trino)
15701 | Some(DialectType::TSQL)
15702 | Some(DialectType::Fabric)
15703 | Some(DialectType::MySQL)
15704 | Some(DialectType::Spark)
15705 | Some(DialectType::Hive)
15706 | Some(DialectType::SQLite)
15707 | Some(DialectType::Drill)
15708 );
15709 let is_stage_ref = table.name.name.starts_with('@');
15710 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
15712 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
15713 self.write_keyword("AS");
15714 self.write_space();
15715 }
15716 self.generate_identifier(alias)?;
15717
15718 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
15721 self.write("(");
15722 for (i, col_alias) in table.column_aliases.iter().enumerate() {
15723 if i > 0 {
15724 self.write(", ");
15725 }
15726 self.generate_identifier(col_alias)?;
15727 }
15728 self.write(")");
15729 }
15730 }
15731
15732 if system_time_post_alias {
15734 if let Some(ref system_time) = table.system_time {
15735 self.write_space();
15736 self.write(system_time);
15737 }
15738 }
15739
15740 if !alias_post_tablesample {
15742 self.generate_table_sample_clause(table)?;
15743 }
15744
15745 if is_sqlite_hint {
15747 for hint in &table.hints {
15748 self.write_space();
15749 self.generate_expression(hint)?;
15750 }
15751 }
15752
15753 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
15755 self.write_space();
15756 self.write_keyword("FINAL");
15757 }
15758
15759 for comment in &table.trailing_comments {
15761 self.write_space();
15762 self.write_formatted_comment(comment);
15763 }
15764
15765 Ok(())
15766 }
15767
15768 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
15770 if let Some(ref ts) = table.table_sample {
15771 self.write_space();
15772 if ts.is_using_sample {
15773 self.write_keyword("USING SAMPLE");
15774 } else {
15775 self.write_keyword(self.config.tablesample_keywords);
15777 }
15778 self.generate_sample_body(ts)?;
15779 if let Some(ref seed) = ts.seed {
15781 self.write_space();
15782 self.write_keyword(self.config.tablesample_seed_keyword);
15783 self.write(" (");
15784 self.generate_expression(seed)?;
15785 self.write(")");
15786 }
15787 }
15788 Ok(())
15789 }
15790
15791 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
15792 if sr.quoted {
15796 self.write("'");
15797 }
15798
15799 self.write(&sr.name);
15800 if let Some(path) = &sr.path {
15801 self.write(path);
15802 }
15803
15804 if sr.quoted {
15805 self.write("'");
15806 }
15807
15808 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
15810 if has_options {
15811 self.write(" (");
15812 let mut first = true;
15813
15814 if let Some(file_format) = &sr.file_format {
15815 if !first {
15816 self.write(", ");
15817 }
15818 self.write_keyword("FILE_FORMAT");
15819 self.write(" => ");
15820 self.generate_expression(file_format)?;
15821 first = false;
15822 }
15823
15824 if let Some(pattern) = &sr.pattern {
15825 if !first {
15826 self.write(", ");
15827 }
15828 self.write_keyword("PATTERN");
15829 self.write(" => '");
15830 self.write(pattern);
15831 self.write("'");
15832 }
15833
15834 self.write(")");
15835 }
15836 Ok(())
15837 }
15838
15839 fn generate_star(&mut self, star: &Star) -> Result<()> {
15840 use crate::dialects::DialectType;
15841
15842 if let Some(table) = &star.table {
15843 self.generate_identifier(table)?;
15844 self.write(".");
15845 }
15846 self.write("*");
15847
15848 if let Some(except) = &star.except {
15850 if !except.is_empty() {
15851 self.write_space();
15852 match self.config.dialect {
15854 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
15855 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
15856 self.write_keyword("EXCLUDE")
15857 }
15858 _ => self.write_keyword("EXCEPT"), }
15860 self.write(" (");
15861 for (i, col) in except.iter().enumerate() {
15862 if i > 0 {
15863 self.write(", ");
15864 }
15865 self.generate_identifier(col)?;
15866 }
15867 self.write(")");
15868 }
15869 }
15870
15871 if let Some(replace) = &star.replace {
15873 if !replace.is_empty() {
15874 self.write_space();
15875 self.write_keyword("REPLACE");
15876 self.write(" (");
15877 for (i, alias) in replace.iter().enumerate() {
15878 if i > 0 {
15879 self.write(", ");
15880 }
15881 self.generate_expression(&alias.this)?;
15882 self.write_space();
15883 self.write_keyword("AS");
15884 self.write_space();
15885 self.generate_identifier(&alias.alias)?;
15886 }
15887 self.write(")");
15888 }
15889 }
15890
15891 if let Some(rename) = &star.rename {
15893 if !rename.is_empty() {
15894 self.write_space();
15895 self.write_keyword("RENAME");
15896 self.write(" (");
15897 for (i, (old_name, new_name)) in rename.iter().enumerate() {
15898 if i > 0 {
15899 self.write(", ");
15900 }
15901 self.generate_identifier(old_name)?;
15902 self.write_space();
15903 self.write_keyword("AS");
15904 self.write_space();
15905 self.generate_identifier(new_name)?;
15906 }
15907 self.write(")");
15908 }
15909 }
15910
15911 for comment in &star.trailing_comments {
15913 self.write_space();
15914 self.write_formatted_comment(comment);
15915 }
15916
15917 Ok(())
15918 }
15919
15920 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
15922 self.write("{");
15923 match expr {
15924 Expression::Star(star) => {
15925 self.generate_star(star)?;
15927 }
15928 Expression::ILike(ilike) => {
15929 self.generate_expression(&ilike.left)?;
15931 self.write_space();
15932 self.write_keyword("ILIKE");
15933 self.write_space();
15934 self.generate_expression(&ilike.right)?;
15935 }
15936 _ => {
15937 self.generate_expression(expr)?;
15938 }
15939 }
15940 self.write("}");
15941 Ok(())
15942 }
15943
15944 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
15945 match &alias.this {
15949 Expression::Column(col) => {
15950 if let Some(table) = &col.table {
15952 self.generate_identifier(table)?;
15953 self.write(".");
15954 }
15955 self.generate_identifier(&col.name)?;
15956 }
15957 _ => {
15958 self.generate_expression(&alias.this)?;
15959 }
15960 }
15961
15962 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
15966 for comment in &alias.pre_alias_comments {
15967 self.write_space();
15968 self.write_formatted_comment(comment);
15969 }
15970 }
15971
15972 use crate::dialects::DialectType;
15973
15974 let is_table_source = matches!(
15980 &alias.this,
15981 Expression::JSONTable(_)
15982 | Expression::XMLTable(_)
15983 | Expression::TableFromRows(_)
15984 | Expression::Unnest(_)
15985 | Expression::MatchRecognize(_)
15986 | Expression::Select(_)
15987 | Expression::Subquery(_)
15988 | Expression::Paren(_)
15989 );
15990 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
15991 let skip_as = is_table_source && dialect_skips_table_alias_as;
15992
15993 self.write_space();
15994 if !skip_as {
15995 self.write_keyword("AS");
15996 self.write_space();
15997 }
15998
15999 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
16001
16002 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
16004 self.write("(");
16006 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16007 if i > 0 {
16008 self.write(", ");
16009 }
16010 self.generate_alias_identifier(col_alias)?;
16011 }
16012 self.write(")");
16013 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
16014 self.generate_alias_identifier(&alias.alias)?;
16016 self.write("(");
16017 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16018 if i > 0 {
16019 self.write(", ");
16020 }
16021 self.generate_alias_identifier(col_alias)?;
16022 }
16023 self.write(")");
16024 } else {
16025 self.generate_alias_identifier(&alias.alias)?;
16027 }
16028
16029 for comment in &alias.trailing_comments {
16031 self.write_space();
16032 self.write_formatted_comment(comment);
16033 }
16034
16035 if alias.trailing_comments.is_empty() {
16040 for comment in &alias.pre_alias_comments {
16041 self.write_space();
16042 self.write_formatted_comment(comment);
16043 }
16044 }
16045
16046 Ok(())
16047 }
16048
16049 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
16050 use crate::dialects::DialectType;
16051
16052 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
16054 self.generate_expression(&cast.this)?;
16055 self.write(" :> ");
16056 self.generate_data_type(&cast.to)?;
16057 return Ok(());
16058 }
16059
16060 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
16062 let is_unknown_type = matches!(cast.to, DataType::Unknown)
16063 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
16064 if is_unknown_type {
16065 if let Some(format) = &cast.format {
16066 self.write_keyword("CAST");
16067 self.write("(");
16068 self.generate_expression(&cast.this)?;
16069 self.write_space();
16070 self.write_keyword("AS");
16071 self.write_space();
16072 self.write_keyword("FORMAT");
16073 self.write_space();
16074 self.generate_expression(format)?;
16075 self.write(")");
16076 return Ok(());
16077 }
16078 }
16079 }
16080
16081 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
16084 if let Some(format) = &cast.format {
16085 let is_date = matches!(cast.to, DataType::Date);
16087 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
16088
16089 if is_date || is_timestamp {
16090 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
16091 self.write_keyword(func_name);
16092 self.write("(");
16093 self.generate_expression(&cast.this)?;
16094 self.write(", ");
16095
16096 if let Expression::Literal(lit) = format.as_ref() {
16099 if let Literal::String(fmt_str) = lit.as_ref() {
16100 let normalized = self.normalize_oracle_format(fmt_str);
16101 self.write("'");
16102 self.write(&normalized);
16103 self.write("'");
16104 }
16105 } else {
16106 self.generate_expression(format)?;
16107 }
16108
16109 self.write(")");
16110 return Ok(());
16111 }
16112 }
16113 }
16114
16115 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
16118 if let Expression::Array(arr) = &cast.this {
16119 self.generate_data_type(&cast.to)?;
16120 self.write("[");
16122 for (i, expr) in arr.expressions.iter().enumerate() {
16123 if i > 0 {
16124 self.write(", ");
16125 }
16126 self.generate_expression(expr)?;
16127 }
16128 self.write("]");
16129 return Ok(());
16130 }
16131 if matches!(&cast.this, Expression::ArrayFunc(_)) {
16132 self.generate_data_type(&cast.to)?;
16133 self.generate_expression(&cast.this)?;
16134 return Ok(());
16135 }
16136 }
16137
16138 if matches!(
16141 self.config.dialect,
16142 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
16143 ) {
16144 if let Expression::Struct(ref s) = cast.this {
16145 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
16146 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
16147 self.write_keyword("CAST");
16148 self.write("(");
16149 self.generate_struct_as_row(s)?;
16150 self.write_space();
16151 self.write_keyword("AS");
16152 self.write_space();
16153 self.generate_data_type(&cast.to)?;
16154 self.write(")");
16155 return Ok(());
16156 }
16157 }
16158 }
16159
16160 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
16163
16164 if use_double_colon {
16165 self.generate_expression(&cast.this)?;
16167 self.write("::");
16168 self.generate_data_type(&cast.to)?;
16169 } else {
16170 self.write_keyword("CAST");
16172 self.write("(");
16173 self.generate_expression(&cast.this)?;
16174 self.write_space();
16175 self.write_keyword("AS");
16176 self.write_space();
16177 if matches!(
16180 self.config.dialect,
16181 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
16182 ) {
16183 match &cast.to {
16184 DataType::Custom { ref name } => {
16185 if name.eq_ignore_ascii_case("LONGTEXT")
16186 || name.eq_ignore_ascii_case("MEDIUMTEXT")
16187 || name.eq_ignore_ascii_case("TINYTEXT")
16188 || name.eq_ignore_ascii_case("LONGBLOB")
16189 || name.eq_ignore_ascii_case("MEDIUMBLOB")
16190 || name.eq_ignore_ascii_case("TINYBLOB")
16191 {
16192 self.write_keyword("CHAR");
16193 } else {
16194 self.generate_data_type(&cast.to)?;
16195 }
16196 }
16197 DataType::VarChar { length, .. } => {
16198 self.write_keyword("CHAR");
16200 if let Some(n) = length {
16201 self.write(&format!("({})", n));
16202 }
16203 }
16204 DataType::Text => {
16205 self.write_keyword("CHAR");
16207 }
16208 DataType::Timestamp {
16209 precision,
16210 timezone: false,
16211 } => {
16212 self.write_keyword("DATETIME");
16214 if let Some(p) = precision {
16215 self.write(&format!("({})", p));
16216 }
16217 }
16218 _ => {
16219 self.generate_data_type(&cast.to)?;
16220 }
16221 }
16222 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
16223 match &cast.to {
16225 DataType::String { length } => {
16226 self.write_keyword("VARCHAR");
16227 if let Some(n) = length {
16228 self.write(&format!("({})", n));
16229 }
16230 }
16231 _ => {
16232 self.generate_data_type(&cast.to)?;
16233 }
16234 }
16235 } else {
16236 self.generate_data_type(&cast.to)?;
16237 }
16238
16239 if let Some(default) = &cast.default {
16241 self.write_space();
16242 self.write_keyword("DEFAULT");
16243 self.write_space();
16244 self.generate_expression(default)?;
16245 self.write_space();
16246 self.write_keyword("ON");
16247 self.write_space();
16248 self.write_keyword("CONVERSION");
16249 self.write_space();
16250 self.write_keyword("ERROR");
16251 }
16252
16253 if let Some(format) = &cast.format {
16256 if matches!(
16258 self.config.dialect,
16259 Some(crate::dialects::DialectType::Oracle)
16260 ) {
16261 self.write(", ");
16262 } else {
16263 self.write_space();
16264 self.write_keyword("FORMAT");
16265 self.write_space();
16266 }
16267 self.generate_expression(format)?;
16268 }
16269
16270 self.write(")");
16271 for comment in &cast.trailing_comments {
16273 self.write_space();
16274 self.write_formatted_comment(comment);
16275 }
16276 }
16277 Ok(())
16278 }
16279
16280 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
16283 self.write_keyword("ROW");
16284 self.write("(");
16285 for (i, (_, expr)) in s.fields.iter().enumerate() {
16286 if i > 0 {
16287 self.write(", ");
16288 }
16289 if let Expression::Struct(ref inner_s) = expr {
16291 self.generate_struct_as_row(inner_s)?;
16292 } else {
16293 self.generate_expression(expr)?;
16294 }
16295 }
16296 self.write(")");
16297 Ok(())
16298 }
16299
16300 fn normalize_oracle_format(&self, format: &str) -> String {
16303 let mut result = String::new();
16306 let chars: Vec<char> = format.chars().collect();
16307 let mut i = 0;
16308
16309 while i < chars.len() {
16310 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
16311 if i + 2 < chars.len() {
16313 let next = chars[i + 2];
16314 if next == '1' || next == '2' {
16315 result.push('H');
16317 result.push('H');
16318 i += 2;
16319 continue;
16320 }
16321 }
16322 result.push_str("HH12");
16324 i += 2;
16325 } else {
16326 result.push(chars[i]);
16327 i += 1;
16328 }
16329 }
16330
16331 result
16332 }
16333
16334 fn dialect_prefers_double_colon(&self) -> bool {
16338 false
16341 }
16342
16343 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16345 use crate::dialects::DialectType;
16346
16347 let use_percent_operator = matches!(
16349 self.config.dialect,
16350 Some(DialectType::Snowflake)
16351 | Some(DialectType::MySQL)
16352 | Some(DialectType::Presto)
16353 | Some(DialectType::Trino)
16354 | Some(DialectType::PostgreSQL)
16355 | Some(DialectType::DuckDB)
16356 | Some(DialectType::Hive)
16357 | Some(DialectType::Spark)
16358 | Some(DialectType::Databricks)
16359 | Some(DialectType::Athena)
16360 );
16361
16362 if use_percent_operator {
16363 let needs_paren = |e: &Expression| matches!(e, Expression::Add(_) | Expression::Sub(_));
16366 if needs_paren(&f.this) {
16367 self.write("(");
16368 self.generate_expression(&f.this)?;
16369 self.write(")");
16370 } else {
16371 self.generate_expression(&f.this)?;
16372 }
16373 self.write(" % ");
16374 if needs_paren(&f.expression) {
16375 self.write("(");
16376 self.generate_expression(&f.expression)?;
16377 self.write(")");
16378 } else {
16379 self.generate_expression(&f.expression)?;
16380 }
16381 Ok(())
16382 } else {
16383 self.generate_binary_func("MOD", &f.this, &f.expression)
16384 }
16385 }
16386
16387 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16389 use crate::dialects::DialectType;
16390
16391 let func_name = match self.config.dialect {
16393 Some(DialectType::Snowflake) => "COALESCE",
16394 _ => "IFNULL",
16395 };
16396
16397 self.generate_binary_func(func_name, &f.this, &f.expression)
16398 }
16399
16400 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16402 if let Some(ref original_name) = f.original_name {
16404 return self.generate_binary_func(original_name, &f.this, &f.expression);
16405 }
16406
16407 use crate::dialects::DialectType;
16409 let func_name = match self.config.dialect {
16410 Some(DialectType::Snowflake)
16411 | Some(DialectType::ClickHouse)
16412 | Some(DialectType::PostgreSQL)
16413 | Some(DialectType::Presto)
16414 | Some(DialectType::Trino)
16415 | Some(DialectType::Athena)
16416 | Some(DialectType::DuckDB)
16417 | Some(DialectType::BigQuery)
16418 | Some(DialectType::Spark)
16419 | Some(DialectType::Databricks)
16420 | Some(DialectType::Hive) => "COALESCE",
16421 Some(DialectType::MySQL)
16422 | Some(DialectType::Doris)
16423 | Some(DialectType::StarRocks)
16424 | Some(DialectType::SingleStore)
16425 | Some(DialectType::TiDB) => "IFNULL",
16426 _ => "NVL",
16427 };
16428
16429 self.generate_binary_func(func_name, &f.this, &f.expression)
16430 }
16431
16432 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
16434 use crate::dialects::DialectType;
16435
16436 let func_name = match self.config.dialect {
16438 Some(DialectType::Snowflake) => "STDDEV",
16439 _ => "STDDEV_SAMP",
16440 };
16441
16442 self.generate_agg_func(func_name, f)
16443 }
16444
16445 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
16446 self.generate_expression(&coll.this)?;
16447 self.write_space();
16448 self.write_keyword("COLLATE");
16449 self.write_space();
16450 if coll.quoted {
16451 self.write("'");
16453 self.write(&coll.collation);
16454 self.write("'");
16455 } else if coll.double_quoted {
16456 self.write("\"");
16458 self.write(&coll.collation);
16459 self.write("\"");
16460 } else {
16461 self.write(&coll.collation);
16463 }
16464 Ok(())
16465 }
16466
16467 fn generate_case(&mut self, case: &Case) -> Result<()> {
16468 let multiline_case = if self.config.pretty {
16470 let mut statements: Vec<String> = Vec::new();
16472 let operand_str = if let Some(operand) = &case.operand {
16473 let s = self.generate_to_string(operand)?;
16474 statements.push(format!("CASE {}", s));
16475 s
16476 } else {
16477 statements.push("CASE".to_string());
16478 String::new()
16479 };
16480 let _ = operand_str;
16481 for (condition, result) in &case.whens {
16482 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
16483 statements.push(format!("THEN {}", self.generate_to_string(result)?));
16484 }
16485 if let Some(else_) = &case.else_ {
16486 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
16487 }
16488 statements.push("END".to_string());
16489 self.too_wide(&statements)
16490 } else {
16491 false
16492 };
16493
16494 self.write_keyword("CASE");
16495 if let Some(operand) = &case.operand {
16496 self.write_space();
16497 self.generate_expression(operand)?;
16498 }
16499 if multiline_case {
16500 self.indent_level += 1;
16501 }
16502 for (condition, result) in &case.whens {
16503 if multiline_case {
16504 self.write_newline();
16505 self.write_indent();
16506 } else {
16507 self.write_space();
16508 }
16509 self.write_keyword("WHEN");
16510 self.write_space();
16511 self.generate_expression(condition)?;
16512 if multiline_case {
16513 self.write_newline();
16514 self.write_indent();
16515 } else {
16516 self.write_space();
16517 }
16518 self.write_keyword("THEN");
16519 self.write_space();
16520 self.generate_expression(result)?;
16521 }
16522 if let Some(else_) = &case.else_ {
16523 if multiline_case {
16524 self.write_newline();
16525 self.write_indent();
16526 } else {
16527 self.write_space();
16528 }
16529 self.write_keyword("ELSE");
16530 self.write_space();
16531 self.generate_expression(else_)?;
16532 }
16533 if multiline_case {
16534 self.indent_level -= 1;
16535 self.write_newline();
16536 self.write_indent();
16537 } else {
16538 self.write_space();
16539 }
16540 self.write_keyword("END");
16541 for comment in &case.comments {
16543 self.write(" ");
16544 self.write_formatted_comment(comment);
16545 }
16546 Ok(())
16547 }
16548
16549 fn generate_function(&mut self, func: &Function) -> Result<()> {
16550 let normalized_name = self.normalize_func_name(&func.name);
16552
16553 if matches!(self.config.dialect, Some(DialectType::DuckDB))
16555 && func.name.eq_ignore_ascii_case("ARRAY_CONSTRUCT_COMPACT")
16556 {
16557 self.write("LIST_FILTER(");
16558 self.write("[");
16559 for (i, arg) in func.args.iter().enumerate() {
16560 if i > 0 {
16561 self.write(", ");
16562 }
16563 self.generate_expression(arg)?;
16564 }
16565 self.write("], _u -> NOT _u IS NULL)");
16566 return Ok(());
16567 }
16568
16569 if func.name.eq_ignore_ascii_case("STRUCT")
16571 && !matches!(
16572 self.config.dialect,
16573 Some(DialectType::BigQuery)
16574 | Some(DialectType::Spark)
16575 | Some(DialectType::Databricks)
16576 | Some(DialectType::Hive)
16577 | None
16578 )
16579 {
16580 return self.generate_struct_function_cross_dialect(func);
16581 }
16582
16583 if func.name.eq_ignore_ascii_case("__SS_JSON_PATH_QMARK__") && func.args.len() == 2 {
16586 self.generate_expression(&func.args[0])?;
16587 self.write("::?");
16588 if let Expression::Literal(lit) = &func.args[1] {
16590 if let crate::expressions::Literal::String(key) = lit.as_ref() {
16591 self.write(key);
16592 }
16593 } else {
16594 self.generate_expression(&func.args[1])?;
16595 }
16596 return Ok(());
16597 }
16598
16599 if func.name.eq_ignore_ascii_case("__PG_BITWISE_XOR__") && func.args.len() == 2 {
16601 self.generate_expression(&func.args[0])?;
16602 self.write(" # ");
16603 self.generate_expression(&func.args[1])?;
16604 return Ok(());
16605 }
16606
16607 if matches!(
16609 self.config.dialect,
16610 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
16611 ) && func.name.eq_ignore_ascii_case("TRY")
16612 && func.args.len() == 1
16613 {
16614 self.generate_expression(&func.args[0])?;
16615 return Ok(());
16616 }
16617
16618 if self.config.dialect == Some(DialectType::ClickHouse)
16620 && func.name.eq_ignore_ascii_case("TOSTARTOFDAY")
16621 && func.args.len() == 1
16622 {
16623 self.write("dateTrunc('DAY', ");
16624 self.generate_expression(&func.args[0])?;
16625 self.write(")");
16626 return Ok(());
16627 }
16628
16629 if self.config.dialect == Some(DialectType::Redshift)
16631 && func.name.eq_ignore_ascii_case("CONCAT")
16632 && func.args.len() >= 2
16633 {
16634 for (i, arg) in func.args.iter().enumerate() {
16635 if i > 0 {
16636 self.write(" || ");
16637 }
16638 self.generate_expression(arg)?;
16639 }
16640 return Ok(());
16641 }
16642
16643 if self.config.dialect == Some(DialectType::Redshift)
16645 && func.name.eq_ignore_ascii_case("CONCAT_WS")
16646 && func.args.len() >= 2
16647 {
16648 let sep = &func.args[0];
16649 for (i, arg) in func.args.iter().skip(1).enumerate() {
16650 if i > 0 {
16651 self.write(" || ");
16652 self.generate_expression(sep)?;
16653 self.write(" || ");
16654 }
16655 self.generate_expression(arg)?;
16656 }
16657 return Ok(());
16658 }
16659
16660 if self.config.dialect == Some(DialectType::Redshift)
16663 && (func.name.eq_ignore_ascii_case("DATEDIFF") || func.name.eq_ignore_ascii_case("DATE_DIFF"))
16664 && func.args.len() == 3
16665 {
16666 self.write_keyword("DATEDIFF");
16667 self.write("(");
16668 self.write_redshift_date_part(&func.args[0]);
16670 self.write(", ");
16671 self.generate_expression(&func.args[1])?;
16672 self.write(", ");
16673 self.generate_expression(&func.args[2])?;
16674 self.write(")");
16675 return Ok(());
16676 }
16677
16678 if self.config.dialect == Some(DialectType::Redshift)
16681 && (func.name.eq_ignore_ascii_case("DATEADD") || func.name.eq_ignore_ascii_case("DATE_ADD"))
16682 && func.args.len() == 3
16683 {
16684 self.write_keyword("DATEADD");
16685 self.write("(");
16686 self.write_redshift_date_part(&func.args[0]);
16688 self.write(", ");
16689 self.generate_expression(&func.args[1])?;
16690 self.write(", ");
16691 self.generate_expression(&func.args[2])?;
16692 self.write(")");
16693 return Ok(());
16694 }
16695
16696 if func.name.eq_ignore_ascii_case("UUID_STRING")
16698 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
16699 {
16700 let func_name = match self.config.dialect {
16701 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
16702 Some(DialectType::BigQuery) => "GENERATE_UUID",
16703 _ => "UUID",
16704 };
16705 self.write_keyword(func_name);
16706 self.write("()");
16707 return Ok(());
16708 }
16709
16710 if matches!(self.config.dialect, Some(DialectType::Snowflake))
16714 && func.name.eq_ignore_ascii_case("GENERATOR")
16715 {
16716 let has_positional_args = !func.args.is_empty()
16717 && !matches!(&func.args[0], Expression::NamedArgument(_));
16718 if has_positional_args {
16719 let param_names = ["ROWCOUNT", "TIMELIMIT"];
16720 self.write_keyword("GENERATOR");
16721 self.write("(");
16722 for (i, arg) in func.args.iter().enumerate() {
16723 if i > 0 {
16724 self.write(", ");
16725 }
16726 if i < param_names.len() {
16727 self.write_keyword(param_names[i]);
16728 self.write(" => ");
16729 self.generate_expression(arg)?;
16730 } else {
16731 self.generate_expression(arg)?;
16732 }
16733 }
16734 self.write(")");
16735 return Ok(());
16736 }
16737 }
16738
16739 if self.config.dialect == Some(DialectType::Redshift)
16742 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
16743 && func.args.len() == 2
16744 {
16745 self.write_keyword("DATE_TRUNC");
16746 self.write("(");
16747 self.write_redshift_date_part_quoted(&func.args[0]);
16749 self.write(", ");
16750 self.generate_expression(&func.args[1])?;
16751 self.write(")");
16752 return Ok(());
16753 }
16754
16755 if matches!(
16757 self.config.dialect,
16758 Some(DialectType::TSQL) | Some(DialectType::Fabric)
16759 ) && (func.name.eq_ignore_ascii_case("DATE_PART") || func.name.eq_ignore_ascii_case("DATEPART"))
16760 && func.args.len() == 2
16761 {
16762 self.write_keyword("DATEPART");
16763 self.write("(");
16764 self.generate_expression(&func.args[0])?;
16765 self.write(", ");
16766 self.generate_expression(&func.args[1])?;
16767 self.write(")");
16768 return Ok(());
16769 }
16770
16771 if matches!(
16773 self.config.dialect,
16774 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
16775 ) && (func.name.eq_ignore_ascii_case("DATE_PART") || func.name.eq_ignore_ascii_case("DATEPART"))
16776 && func.args.len() == 2
16777 {
16778 self.write_keyword("EXTRACT");
16779 self.write("(");
16780 match &func.args[0] {
16782 Expression::Literal(lit) if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) => {
16783 let crate::expressions::Literal::String(s) = lit.as_ref() else { unreachable!() };
16784 self.write(&s.to_ascii_lowercase());
16785 }
16786 _ => self.generate_expression(&func.args[0])?,
16787 }
16788 self.write_space();
16789 self.write_keyword("FROM");
16790 self.write_space();
16791 self.generate_expression(&func.args[1])?;
16792 self.write(")");
16793 return Ok(());
16794 }
16795
16796 if self.config.dialect == Some(DialectType::Dremio)
16799 && (func.name.eq_ignore_ascii_case("DATE_PART") || func.name.eq_ignore_ascii_case("DATEPART"))
16800 && func.args.len() == 2
16801 {
16802 self.write_keyword("EXTRACT");
16803 self.write("(");
16804 self.generate_expression(&func.args[0])?;
16805 self.write_space();
16806 self.write_keyword("FROM");
16807 self.write_space();
16808 self.generate_dremio_date_expression(&func.args[1])?;
16810 self.write(")");
16811 return Ok(());
16812 }
16813
16814 if self.config.dialect == Some(DialectType::Dremio)
16816 && func.name.eq_ignore_ascii_case("CURRENT_DATE_UTC")
16817 && func.args.is_empty()
16818 {
16819 self.write_keyword("CURRENT_DATE_UTC");
16820 return Ok(());
16821 }
16822
16823 if self.config.dialect == Some(DialectType::Dremio)
16827 && func.name.eq_ignore_ascii_case("DATETYPE")
16828 && func.args.len() == 3
16829 {
16830 fn get_int_literal(expr: &Expression) -> Option<i64> {
16832 if let Expression::Literal(lit) = expr {
16833 if let crate::expressions::Literal::Number(s) = lit.as_ref() {
16834 s.parse::<i64>().ok()
16835 } else { None }
16836 } else {
16837 None
16838 }
16839 }
16840
16841 if let (Some(year), Some(month), Some(day)) = (
16843 get_int_literal(&func.args[0]),
16844 get_int_literal(&func.args[1]),
16845 get_int_literal(&func.args[2]),
16846 ) {
16847 self.write_keyword("DATE");
16849 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
16850 return Ok(());
16851 }
16852
16853 self.write_keyword("CAST");
16855 self.write("(");
16856 self.write_keyword("CONCAT");
16857 self.write("(");
16858 self.generate_expression(&func.args[0])?;
16859 self.write(", '-', ");
16860 self.generate_expression(&func.args[1])?;
16861 self.write(", '-', ");
16862 self.generate_expression(&func.args[2])?;
16863 self.write(")");
16864 self.write_space();
16865 self.write_keyword("AS");
16866 self.write_space();
16867 self.write_keyword("DATE");
16868 self.write(")");
16869 return Ok(());
16870 }
16871
16872 let is_presto_like = matches!(
16875 self.config.dialect,
16876 Some(DialectType::Presto) | Some(DialectType::Trino)
16877 );
16878 if is_presto_like && func.name.eq_ignore_ascii_case("DATE_ADD") && func.args.len() == 3 {
16879 self.write_keyword("DATE_ADD");
16880 self.write("(");
16881 self.generate_expression(&func.args[0])?;
16883 self.write(", ");
16884 let interval = &func.args[1];
16886 let needs_cast = !self.returns_integer_type(interval);
16887 if needs_cast {
16888 self.write_keyword("CAST");
16889 self.write("(");
16890 }
16891 self.generate_expression(interval)?;
16892 if needs_cast {
16893 self.write_space();
16894 self.write_keyword("AS");
16895 self.write_space();
16896 self.write_keyword("BIGINT");
16897 self.write(")");
16898 }
16899 self.write(", ");
16900 self.generate_expression(&func.args[2])?;
16902 self.write(")");
16903 return Ok(());
16904 }
16905
16906 let use_brackets = func.use_bracket_syntax;
16908
16909 let has_ordinality = func.name.len() >= 16
16914 && func.name[func.name.len() - 16..].eq_ignore_ascii_case(" WITH ORDINALITY");
16915 let output_name = if has_ordinality {
16916 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
16917 self.normalize_func_name(base_name)
16918 } else {
16919 normalized_name.clone()
16920 };
16921
16922 if func.name.contains('.') && !has_ordinality {
16925 if func.quoted {
16928 self.write("`");
16929 self.write(&func.name);
16930 self.write("`");
16931 } else {
16932 self.write(&func.name);
16933 }
16934 } else {
16935 self.write(&output_name);
16936 }
16937
16938 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
16941 let needs_parens =
16942 if func.name.eq_ignore_ascii_case("CURRENT_USER")
16943 || func.name.eq_ignore_ascii_case("SESSION_USER")
16944 || func.name.eq_ignore_ascii_case("SYSTEM_USER")
16945 {
16946 matches!(
16947 self.config.dialect,
16948 Some(DialectType::Snowflake)
16949 | Some(DialectType::Spark)
16950 | Some(DialectType::Databricks)
16951 | Some(DialectType::Hive)
16952 )
16953 } else {
16954 false
16955 };
16956 !needs_parens
16957 };
16958 if force_parens {
16959 for comment in &func.trailing_comments {
16961 self.write_space();
16962 self.write_formatted_comment(comment);
16963 }
16964 return Ok(());
16965 }
16966
16967 if func.name.eq_ignore_ascii_case("CUBE") || func.name.eq_ignore_ascii_case("ROLLUP") || func.name.eq_ignore_ascii_case("GROUPING SETS") {
16969 self.write(" (");
16970 } else if use_brackets {
16971 self.write("[");
16972 } else {
16973 self.write("(");
16974 }
16975 if func.distinct {
16976 self.write_keyword("DISTINCT");
16977 self.write_space();
16978 }
16979
16980 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
16982 && (func.name.eq_ignore_ascii_case("TABLE") || func.name.eq_ignore_ascii_case("FLATTEN"));
16983 let is_grouping_func =
16985 func.name.eq_ignore_ascii_case("GROUPING SETS") || func.name.eq_ignore_ascii_case("CUBE") || func.name.eq_ignore_ascii_case("ROLLUP");
16986 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
16987 if is_grouping_func {
16988 true
16989 } else {
16990 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
16992 for arg in &func.args {
16993 let mut temp_gen = Generator::with_arc_config(self.config.clone());
16994 Arc::make_mut(&mut temp_gen.config).pretty = false; temp_gen.generate_expression(arg)?;
16996 expr_strings.push(temp_gen.output);
16997 }
16998 self.too_wide(&expr_strings)
16999 }
17000 } else {
17001 false
17002 };
17003
17004 if should_split {
17005 self.write_newline();
17007 self.indent_level += 1;
17008 for (i, arg) in func.args.iter().enumerate() {
17009 self.write_indent();
17010 self.generate_expression(arg)?;
17011 if i + 1 < func.args.len() {
17012 self.write(",");
17013 }
17014 self.write_newline();
17015 }
17016 self.indent_level -= 1;
17017 self.write_indent();
17018 } else {
17019 for (i, arg) in func.args.iter().enumerate() {
17021 if i > 0 {
17022 self.write(", ");
17023 }
17024 self.generate_expression(arg)?;
17025 }
17026 }
17027
17028 if use_brackets {
17029 self.write("]");
17030 } else {
17031 self.write(")");
17032 }
17033 if has_ordinality {
17035 self.write_space();
17036 self.write_keyword("WITH ORDINALITY");
17037 }
17038 for comment in &func.trailing_comments {
17040 self.write_space();
17041 self.write_formatted_comment(comment);
17042 }
17043 Ok(())
17044 }
17045
17046 fn generate_function_emits(&mut self, fe: &FunctionEmits) -> Result<()> {
17047 self.generate_expression(&fe.this)?;
17048 self.write_keyword(" EMITS ");
17049 self.generate_expression(&fe.emits)?;
17050 Ok(())
17051 }
17052
17053 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
17054 let mut normalized_name = self.normalize_func_name(&func.name);
17056
17057 if func.name.eq_ignore_ascii_case("MAX_BY") || func.name.eq_ignore_ascii_case("MIN_BY") {
17059 let is_max = func.name.eq_ignore_ascii_case("MAX_BY");
17060 match self.config.dialect {
17061 Some(DialectType::ClickHouse) => {
17062 normalized_name = if is_max {
17063 Cow::Borrowed("argMax")
17064 } else {
17065 Cow::Borrowed("argMin")
17066 };
17067 }
17068 Some(DialectType::DuckDB) => {
17069 normalized_name = if is_max {
17070 Cow::Borrowed("ARG_MAX")
17071 } else {
17072 Cow::Borrowed("ARG_MIN")
17073 };
17074 }
17075 _ => {}
17076 }
17077 }
17078 self.write(normalized_name.as_ref());
17079 self.write("(");
17080 if func.distinct {
17081 self.write_keyword("DISTINCT");
17082 self.write_space();
17083 }
17084
17085 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
17089 let needs_multi_arg_transform =
17090 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
17091
17092 if needs_multi_arg_transform {
17093 self.write_keyword("CASE");
17095 for arg in &func.args {
17096 self.write_space();
17097 self.write_keyword("WHEN");
17098 self.write_space();
17099 self.generate_expression(arg)?;
17100 self.write_space();
17101 self.write_keyword("IS NULL THEN NULL");
17102 }
17103 self.write_space();
17104 self.write_keyword("ELSE");
17105 self.write(" (");
17106 for (i, arg) in func.args.iter().enumerate() {
17107 if i > 0 {
17108 self.write(", ");
17109 }
17110 self.generate_expression(arg)?;
17111 }
17112 self.write(")");
17113 self.write_space();
17114 self.write_keyword("END");
17115 } else {
17116 for (i, arg) in func.args.iter().enumerate() {
17117 if i > 0 {
17118 self.write(", ");
17119 }
17120 self.generate_expression(arg)?;
17121 }
17122 }
17123
17124 if self.config.ignore_nulls_in_func
17126 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
17127 {
17128 if let Some(ignore) = func.ignore_nulls {
17129 self.write_space();
17130 if ignore {
17131 self.write_keyword("IGNORE NULLS");
17132 } else {
17133 self.write_keyword("RESPECT NULLS");
17134 }
17135 }
17136 }
17137
17138 if !func.order_by.is_empty() {
17140 self.write_space();
17141 self.write_keyword("ORDER BY");
17142 self.write_space();
17143 for (i, ord) in func.order_by.iter().enumerate() {
17144 if i > 0 {
17145 self.write(", ");
17146 }
17147 self.generate_ordered(ord)?;
17148 }
17149 }
17150
17151 if let Some(limit) = &func.limit {
17153 self.write_space();
17154 self.write_keyword("LIMIT");
17155 self.write_space();
17156 if let Expression::Tuple(t) = limit.as_ref() {
17158 if t.expressions.len() == 2 {
17159 self.generate_expression(&t.expressions[0])?;
17160 self.write(", ");
17161 self.generate_expression(&t.expressions[1])?;
17162 } else {
17163 self.generate_expression(limit)?;
17164 }
17165 } else {
17166 self.generate_expression(limit)?;
17167 }
17168 }
17169
17170 self.write(")");
17171
17172 if !self.config.ignore_nulls_in_func
17174 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
17175 {
17176 if let Some(ignore) = func.ignore_nulls {
17177 self.write_space();
17178 if ignore {
17179 self.write_keyword("IGNORE NULLS");
17180 } else {
17181 self.write_keyword("RESPECT NULLS");
17182 }
17183 }
17184 }
17185
17186 if let Some(filter) = &func.filter {
17187 self.write_space();
17188 self.write_keyword("FILTER");
17189 self.write("(");
17190 self.write_keyword("WHERE");
17191 self.write_space();
17192 self.generate_expression(filter)?;
17193 self.write(")");
17194 }
17195
17196 Ok(())
17197 }
17198
17199 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
17200 self.generate_expression(&wf.this)?;
17201
17202 if let Some(keep) = &wf.keep {
17204 self.write_space();
17205 self.write_keyword("KEEP");
17206 self.write(" (");
17207 self.write_keyword("DENSE_RANK");
17208 self.write_space();
17209 if keep.first {
17210 self.write_keyword("FIRST");
17211 } else {
17212 self.write_keyword("LAST");
17213 }
17214 self.write_space();
17215 self.write_keyword("ORDER BY");
17216 self.write_space();
17217 for (i, ord) in keep.order_by.iter().enumerate() {
17218 if i > 0 {
17219 self.write(", ");
17220 }
17221 self.generate_ordered(ord)?;
17222 }
17223 self.write(")");
17224 }
17225
17226 let has_over = !wf.over.partition_by.is_empty()
17228 || !wf.over.order_by.is_empty()
17229 || wf.over.frame.is_some()
17230 || wf.over.window_name.is_some();
17231
17232 if has_over {
17234 self.write_space();
17235 self.write_keyword("OVER");
17236
17237 let has_specs = !wf.over.partition_by.is_empty()
17239 || !wf.over.order_by.is_empty()
17240 || wf.over.frame.is_some();
17241
17242 if wf.over.window_name.is_some() && !has_specs {
17243 self.write_space();
17245 self.write(&wf.over.window_name.as_ref().unwrap().name);
17246 } else {
17247 self.write(" (");
17249 self.generate_over(&wf.over)?;
17250 self.write(")");
17251 }
17252 } else if wf.keep.is_none() {
17253 self.write_space();
17255 self.write_keyword("OVER");
17256 self.write(" ()");
17257 }
17258
17259 Ok(())
17260 }
17261
17262 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
17264 self.generate_expression(&wg.this)?;
17265 self.write_space();
17266 self.write_keyword("WITHIN GROUP");
17267 self.write(" (");
17268 self.write_keyword("ORDER BY");
17269 self.write_space();
17270 for (i, ord) in wg.order_by.iter().enumerate() {
17271 if i > 0 {
17272 self.write(", ");
17273 }
17274 self.generate_ordered(ord)?;
17275 }
17276 self.write(")");
17277 Ok(())
17278 }
17279
17280 fn generate_over(&mut self, over: &Over) -> Result<()> {
17282 let mut has_content = false;
17283
17284 if let Some(name) = &over.window_name {
17286 self.write(&name.name);
17287 has_content = true;
17288 }
17289
17290 if !over.partition_by.is_empty() {
17292 if has_content {
17293 self.write_space();
17294 }
17295 self.write_keyword("PARTITION BY");
17296 self.write_space();
17297 for (i, expr) in over.partition_by.iter().enumerate() {
17298 if i > 0 {
17299 self.write(", ");
17300 }
17301 self.generate_expression(expr)?;
17302 }
17303 has_content = true;
17304 }
17305
17306 if !over.order_by.is_empty() {
17308 if has_content {
17309 self.write_space();
17310 }
17311 self.write_keyword("ORDER BY");
17312 self.write_space();
17313 for (i, ordered) in over.order_by.iter().enumerate() {
17314 if i > 0 {
17315 self.write(", ");
17316 }
17317 self.generate_ordered(ordered)?;
17318 }
17319 has_content = true;
17320 }
17321
17322 if let Some(frame) = &over.frame {
17324 if has_content {
17325 self.write_space();
17326 }
17327 self.generate_window_frame(frame)?;
17328 }
17329
17330 Ok(())
17331 }
17332
17333 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
17334 let lowercase_frame = self.config.lowercase_window_frame_keywords;
17336
17337 if !lowercase_frame {
17339 if let Some(kind_text) = &frame.kind_text {
17340 self.write(kind_text);
17341 } else {
17342 match frame.kind {
17343 WindowFrameKind::Rows => self.write_keyword("ROWS"),
17344 WindowFrameKind::Range => self.write_keyword("RANGE"),
17345 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
17346 }
17347 }
17348 } else {
17349 match frame.kind {
17350 WindowFrameKind::Rows => self.write("rows"),
17351 WindowFrameKind::Range => self.write("range"),
17352 WindowFrameKind::Groups => self.write("groups"),
17353 }
17354 }
17355
17356 self.write_space();
17359 let should_normalize = self.config.normalize_window_frame_between
17360 && frame.end.is_none()
17361 && matches!(
17362 frame.start,
17363 WindowFrameBound::Preceding(_)
17364 | WindowFrameBound::Following(_)
17365 | WindowFrameBound::UnboundedPreceding
17366 | WindowFrameBound::UnboundedFollowing
17367 );
17368
17369 if let Some(end) = &frame.end {
17370 self.write_keyword("BETWEEN");
17372 self.write_space();
17373 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
17374 self.write_space();
17375 self.write_keyword("AND");
17376 self.write_space();
17377 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
17378 } else if should_normalize {
17379 self.write_keyword("BETWEEN");
17381 self.write_space();
17382 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
17383 self.write_space();
17384 self.write_keyword("AND");
17385 self.write_space();
17386 self.write_keyword("CURRENT ROW");
17387 } else {
17388 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
17390 }
17391
17392 if let Some(exclude) = &frame.exclude {
17394 self.write_space();
17395 self.write_keyword("EXCLUDE");
17396 self.write_space();
17397 match exclude {
17398 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
17399 WindowFrameExclude::Group => self.write_keyword("GROUP"),
17400 WindowFrameExclude::Ties => self.write_keyword("TIES"),
17401 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
17402 }
17403 }
17404
17405 Ok(())
17406 }
17407
17408 fn generate_window_frame_bound(
17409 &mut self,
17410 bound: &WindowFrameBound,
17411 side_text: Option<&str>,
17412 ) -> Result<()> {
17413 let lowercase_frame = self.config.lowercase_window_frame_keywords;
17415
17416 match bound {
17417 WindowFrameBound::CurrentRow => {
17418 self.write_keyword("CURRENT ROW");
17419 }
17420 WindowFrameBound::UnboundedPreceding => {
17421 self.write_keyword("UNBOUNDED");
17422 self.write_space();
17423 if lowercase_frame {
17424 self.write("preceding");
17425 } else if let Some(text) = side_text {
17426 self.write(text);
17427 } else {
17428 self.write_keyword("PRECEDING");
17429 }
17430 }
17431 WindowFrameBound::UnboundedFollowing => {
17432 self.write_keyword("UNBOUNDED");
17433 self.write_space();
17434 if lowercase_frame {
17435 self.write("following");
17436 } else if let Some(text) = side_text {
17437 self.write(text);
17438 } else {
17439 self.write_keyword("FOLLOWING");
17440 }
17441 }
17442 WindowFrameBound::Preceding(expr) => {
17443 self.generate_expression(expr)?;
17444 self.write_space();
17445 if lowercase_frame {
17446 self.write("preceding");
17447 } else if let Some(text) = side_text {
17448 self.write(text);
17449 } else {
17450 self.write_keyword("PRECEDING");
17451 }
17452 }
17453 WindowFrameBound::Following(expr) => {
17454 self.generate_expression(expr)?;
17455 self.write_space();
17456 if lowercase_frame {
17457 self.write("following");
17458 } else if let Some(text) = side_text {
17459 self.write(text);
17460 } else {
17461 self.write_keyword("FOLLOWING");
17462 }
17463 }
17464 WindowFrameBound::BarePreceding => {
17465 if lowercase_frame {
17466 self.write("preceding");
17467 } else if let Some(text) = side_text {
17468 self.write(text);
17469 } else {
17470 self.write_keyword("PRECEDING");
17471 }
17472 }
17473 WindowFrameBound::BareFollowing => {
17474 if lowercase_frame {
17475 self.write("following");
17476 } else if let Some(text) = side_text {
17477 self.write(text);
17478 } else {
17479 self.write_keyword("FOLLOWING");
17480 }
17481 }
17482 WindowFrameBound::Value(expr) => {
17483 self.generate_expression(expr)?;
17485 }
17486 }
17487 Ok(())
17488 }
17489
17490 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
17491 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
17494 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
17495 && !matches!(&interval.this, Some(Expression::Literal(_)));
17496
17497 if self.config.single_string_interval {
17500 if let (
17501 Some(Expression::Literal(lit)),
17502 Some(IntervalUnitSpec::Simple {
17503 ref unit,
17504 ref use_plural,
17505 }),
17506 ) = (&interval.this, &interval.unit)
17507 {
17508 if let Literal::String(ref val) = lit.as_ref() {
17509 self.write_keyword("INTERVAL");
17510 self.write_space();
17511 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
17512 let unit_str = self.interval_unit_str(unit, effective_plural);
17513 self.write("'");
17514 self.write(val);
17515 self.write(" ");
17516 self.write(&unit_str);
17517 self.write("'");
17518 return Ok(());
17519 }
17520 }
17521 }
17522
17523 if !skip_interval_keyword {
17524 self.write_keyword("INTERVAL");
17525 }
17526
17527 if let Some(ref value) = interval.this {
17529 if !skip_interval_keyword {
17530 self.write_space();
17531 }
17532 let needs_parens = interval.unit.is_some()
17536 && matches!(
17537 value,
17538 Expression::Add(_)
17539 | Expression::Sub(_)
17540 | Expression::Mul(_)
17541 | Expression::Div(_)
17542 | Expression::Mod(_)
17543 | Expression::BitwiseAnd(_)
17544 | Expression::BitwiseOr(_)
17545 | Expression::BitwiseXor(_)
17546 );
17547 if needs_parens {
17548 self.write("(");
17549 }
17550 self.generate_expression(value)?;
17551 if needs_parens {
17552 self.write(")");
17553 }
17554 }
17555
17556 if let Some(ref unit_spec) = interval.unit {
17558 self.write_space();
17559 self.write_interval_unit_spec(unit_spec)?;
17560 }
17561
17562 Ok(())
17563 }
17564
17565 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
17567 match (unit, use_plural) {
17568 (IntervalUnit::Year, false) => "YEAR",
17569 (IntervalUnit::Year, true) => "YEARS",
17570 (IntervalUnit::Quarter, false) => "QUARTER",
17571 (IntervalUnit::Quarter, true) => "QUARTERS",
17572 (IntervalUnit::Month, false) => "MONTH",
17573 (IntervalUnit::Month, true) => "MONTHS",
17574 (IntervalUnit::Week, false) => "WEEK",
17575 (IntervalUnit::Week, true) => "WEEKS",
17576 (IntervalUnit::Day, false) => "DAY",
17577 (IntervalUnit::Day, true) => "DAYS",
17578 (IntervalUnit::Hour, false) => "HOUR",
17579 (IntervalUnit::Hour, true) => "HOURS",
17580 (IntervalUnit::Minute, false) => "MINUTE",
17581 (IntervalUnit::Minute, true) => "MINUTES",
17582 (IntervalUnit::Second, false) => "SECOND",
17583 (IntervalUnit::Second, true) => "SECONDS",
17584 (IntervalUnit::Millisecond, false) => "MILLISECOND",
17585 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
17586 (IntervalUnit::Microsecond, false) => "MICROSECOND",
17587 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
17588 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
17589 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
17590 }
17591 }
17592
17593 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
17594 match unit_spec {
17595 IntervalUnitSpec::Simple { unit, use_plural } => {
17596 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
17598 self.write_simple_interval_unit(unit, effective_plural);
17599 }
17600 IntervalUnitSpec::Span(span) => {
17601 self.write_simple_interval_unit(&span.this, false);
17602 self.write_space();
17603 self.write_keyword("TO");
17604 self.write_space();
17605 self.write_simple_interval_unit(&span.expression, false);
17606 }
17607 IntervalUnitSpec::ExprSpan(span) => {
17608 self.generate_expression(&span.this)?;
17610 self.write_space();
17611 self.write_keyword("TO");
17612 self.write_space();
17613 self.generate_expression(&span.expression)?;
17614 }
17615 IntervalUnitSpec::Expr(expr) => {
17616 self.generate_expression(expr)?;
17617 }
17618 }
17619 Ok(())
17620 }
17621
17622 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
17623 match (unit, use_plural) {
17625 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
17626 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
17627 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
17628 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
17629 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
17630 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
17631 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
17632 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
17633 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
17634 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
17635 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
17636 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
17637 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
17638 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
17639 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
17640 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
17641 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
17642 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
17643 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
17644 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
17645 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
17646 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
17647 }
17648 }
17649
17650 fn write_redshift_date_part(&mut self, expr: &Expression) {
17653 let part_str = self.extract_date_part_string(expr);
17654 if let Some(part) = part_str {
17655 let normalized = self.normalize_date_part(&part);
17656 self.write_keyword(&normalized);
17657 } else {
17658 let _ = self.generate_expression(expr);
17660 }
17661 }
17662
17663 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
17666 let part_str = self.extract_date_part_string(expr);
17667 if let Some(part) = part_str {
17668 let normalized = self.normalize_date_part(&part);
17669 self.write("'");
17670 self.write(&normalized);
17671 self.write("'");
17672 } else {
17673 let _ = self.generate_expression(expr);
17675 }
17676 }
17677
17678 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
17680 match expr {
17681 Expression::Literal(lit) if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) => { let crate::expressions::Literal::String(s) = lit.as_ref() else { unreachable!() }; Some(s.clone()) },
17682 Expression::Identifier(id) => Some(id.name.clone()),
17683 Expression::Column(col) if col.table.is_none() => {
17684 Some(col.name.name.clone())
17686 }
17687 _ => None,
17688 }
17689 }
17690
17691 fn normalize_date_part(&self, part: &str) -> String {
17694 let mut buf = [0u8; 64];
17695 let lower: &str = if part.len() <= 64 {
17696 for (i, b) in part.bytes().enumerate() {
17697 buf[i] = b.to_ascii_lowercase();
17698 }
17699 std::str::from_utf8(&buf[..part.len()]).unwrap_or(part)
17700 } else {
17701 return part.to_ascii_uppercase();
17702 };
17703 match lower {
17704 "day" | "days" | "d" => "DAY".to_string(),
17705 "month" | "months" | "mon" | "mm" => "MONTH".to_string(),
17706 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
17707 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
17708 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
17709 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
17710 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
17711 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
17712 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
17713 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
17714 _ => part.to_ascii_uppercase(),
17715 }
17716 }
17717
17718 fn write_datetime_field(&mut self, field: &DateTimeField) {
17719 match field {
17720 DateTimeField::Year => self.write_keyword("YEAR"),
17721 DateTimeField::Month => self.write_keyword("MONTH"),
17722 DateTimeField::Day => self.write_keyword("DAY"),
17723 DateTimeField::Hour => self.write_keyword("HOUR"),
17724 DateTimeField::Minute => self.write_keyword("MINUTE"),
17725 DateTimeField::Second => self.write_keyword("SECOND"),
17726 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
17727 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
17728 DateTimeField::DayOfWeek => {
17729 let name = match self.config.dialect {
17730 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
17731 _ => "DOW",
17732 };
17733 self.write_keyword(name);
17734 }
17735 DateTimeField::DayOfYear => {
17736 let name = match self.config.dialect {
17737 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
17738 _ => "DOY",
17739 };
17740 self.write_keyword(name);
17741 }
17742 DateTimeField::Week => self.write_keyword("WEEK"),
17743 DateTimeField::WeekWithModifier(modifier) => {
17744 self.write_keyword("WEEK");
17745 self.write("(");
17746 self.write(modifier);
17747 self.write(")");
17748 }
17749 DateTimeField::Quarter => self.write_keyword("QUARTER"),
17750 DateTimeField::Epoch => self.write_keyword("EPOCH"),
17751 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
17752 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
17753 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
17754 DateTimeField::Date => self.write_keyword("DATE"),
17755 DateTimeField::Time => self.write_keyword("TIME"),
17756 DateTimeField::Custom(name) => self.write(name),
17757 }
17758 }
17759
17760 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
17762 match field {
17763 DateTimeField::Year => self.write("year"),
17764 DateTimeField::Month => self.write("month"),
17765 DateTimeField::Day => self.write("day"),
17766 DateTimeField::Hour => self.write("hour"),
17767 DateTimeField::Minute => self.write("minute"),
17768 DateTimeField::Second => self.write("second"),
17769 DateTimeField::Millisecond => self.write("millisecond"),
17770 DateTimeField::Microsecond => self.write("microsecond"),
17771 DateTimeField::DayOfWeek => self.write("dow"),
17772 DateTimeField::DayOfYear => self.write("doy"),
17773 DateTimeField::Week => self.write("week"),
17774 DateTimeField::WeekWithModifier(modifier) => {
17775 self.write("week(");
17776 self.write(modifier);
17777 self.write(")");
17778 }
17779 DateTimeField::Quarter => self.write("quarter"),
17780 DateTimeField::Epoch => self.write("epoch"),
17781 DateTimeField::Timezone => self.write("timezone"),
17782 DateTimeField::TimezoneHour => self.write("timezone_hour"),
17783 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
17784 DateTimeField::Date => self.write("date"),
17785 DateTimeField::Time => self.write("time"),
17786 DateTimeField::Custom(name) => self.write(name),
17787 }
17788 }
17789
17790 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
17793 self.write_keyword(name);
17794 self.write("(");
17795 self.generate_expression(arg)?;
17796 self.write(")");
17797 Ok(())
17798 }
17799
17800 fn generate_unary_func(
17802 &mut self,
17803 default_name: &str,
17804 f: &crate::expressions::UnaryFunc,
17805 ) -> Result<()> {
17806 let name = f.original_name.as_deref().unwrap_or(default_name);
17807 self.write_keyword(name);
17808 self.write("(");
17809 self.generate_expression(&f.this)?;
17810 self.write(")");
17811 Ok(())
17812 }
17813
17814 fn generate_sqrt_cbrt(
17816 &mut self,
17817 f: &crate::expressions::UnaryFunc,
17818 func_name: &str,
17819 _op: &str,
17820 ) -> Result<()> {
17821 self.write_keyword(func_name);
17824 self.write("(");
17825 self.generate_expression(&f.this)?;
17826 self.write(")");
17827 Ok(())
17828 }
17829
17830 fn generate_binary_func(
17831 &mut self,
17832 name: &str,
17833 arg1: &Expression,
17834 arg2: &Expression,
17835 ) -> Result<()> {
17836 self.write_keyword(name);
17837 self.write("(");
17838 self.generate_expression(arg1)?;
17839 self.write(", ");
17840 self.generate_expression(arg2)?;
17841 self.write(")");
17842 Ok(())
17843 }
17844
17845 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
17849 let func_name = f.name.as_deref().unwrap_or("CHAR");
17851 self.write_keyword(func_name);
17852 self.write("(");
17853 for (i, arg) in f.args.iter().enumerate() {
17854 if i > 0 {
17855 self.write(", ");
17856 }
17857 self.generate_expression(arg)?;
17858 }
17859 if let Some(ref charset) = f.charset {
17860 self.write(" ");
17861 self.write_keyword("USING");
17862 self.write(" ");
17863 self.write(charset);
17864 }
17865 self.write(")");
17866 Ok(())
17867 }
17868
17869 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
17870 use crate::dialects::DialectType;
17871
17872 match self.config.dialect {
17873 Some(DialectType::Teradata) => {
17874 self.generate_expression(&f.this)?;
17876 self.write(" ** ");
17877 self.generate_expression(&f.expression)?;
17878 Ok(())
17879 }
17880 _ => {
17881 self.generate_binary_func("POWER", &f.this, &f.expression)
17883 }
17884 }
17885 }
17886
17887 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
17888 self.write_func_name(name);
17889 self.write("(");
17890 for (i, arg) in args.iter().enumerate() {
17891 if i > 0 {
17892 self.write(", ");
17893 }
17894 self.generate_expression(arg)?;
17895 }
17896 self.write(")");
17897 Ok(())
17898 }
17899
17900 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
17903 self.write_keyword("CONCAT_WS");
17904 self.write("(");
17905 self.generate_expression(&f.separator)?;
17906 for expr in &f.expressions {
17907 self.write(", ");
17908 self.generate_expression(expr)?;
17909 }
17910 self.write(")");
17911 Ok(())
17912 }
17913
17914 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
17915 if let Expression::Concat(op) = expr {
17916 Self::collect_concat_operands(&op.left, out);
17917 Self::collect_concat_operands(&op.right, out);
17918 } else {
17919 out.push(expr);
17920 }
17921 }
17922
17923 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
17924 let mut operands = Vec::new();
17925 Self::collect_concat_operands(&op.left, &mut operands);
17926 Self::collect_concat_operands(&op.right, &mut operands);
17927
17928 self.write_keyword("CONCAT");
17929 self.write("(");
17930 for (i, operand) in operands.iter().enumerate() {
17931 if i > 0 {
17932 self.write(", ");
17933 }
17934 self.generate_expression(operand)?;
17935 }
17936 self.write(")");
17937 Ok(())
17938 }
17939
17940 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
17941 if let Expression::DPipe(dpipe) = expr {
17942 Self::collect_dpipe_operands(&dpipe.this, out);
17943 Self::collect_dpipe_operands(&dpipe.expression, out);
17944 } else {
17945 out.push(expr);
17946 }
17947 }
17948
17949 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
17950 let mut operands = Vec::new();
17951 Self::collect_dpipe_operands(&e.this, &mut operands);
17952 Self::collect_dpipe_operands(&e.expression, &mut operands);
17953
17954 self.write_keyword("CONCAT");
17955 self.write("(");
17956 for (i, operand) in operands.iter().enumerate() {
17957 if i > 0 {
17958 self.write(", ");
17959 }
17960 self.generate_expression(operand)?;
17961 }
17962 self.write(")");
17963 Ok(())
17964 }
17965
17966 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
17967 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
17969 if is_oracle {
17970 self.write_keyword("SUBSTR");
17971 } else {
17972 self.write_keyword("SUBSTRING");
17973 }
17974 self.write("(");
17975 self.generate_expression(&f.this)?;
17976 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
17978 let use_comma_syntax = matches!(
17980 self.config.dialect,
17981 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
17982 );
17983 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
17984 self.write_space();
17986 self.write_keyword("FROM");
17987 self.write_space();
17988 self.generate_expression(&f.start)?;
17989 if let Some(length) = &f.length {
17990 self.write_space();
17991 self.write_keyword("FOR");
17992 self.write_space();
17993 self.generate_expression(length)?;
17994 }
17995 } else {
17996 self.write(", ");
17998 self.generate_expression(&f.start)?;
17999 if let Some(length) = &f.length {
18000 self.write(", ");
18001 self.generate_expression(length)?;
18002 }
18003 }
18004 self.write(")");
18005 Ok(())
18006 }
18007
18008 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
18009 self.write_keyword("OVERLAY");
18010 self.write("(");
18011 self.generate_expression(&f.this)?;
18012 self.write_space();
18013 self.write_keyword("PLACING");
18014 self.write_space();
18015 self.generate_expression(&f.replacement)?;
18016 self.write_space();
18017 self.write_keyword("FROM");
18018 self.write_space();
18019 self.generate_expression(&f.from)?;
18020 if let Some(length) = &f.length {
18021 self.write_space();
18022 self.write_keyword("FOR");
18023 self.write_space();
18024 self.generate_expression(length)?;
18025 }
18026 self.write(")");
18027 Ok(())
18028 }
18029
18030 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
18031 if f.position_explicit && f.characters.is_none() {
18034 match f.position {
18035 TrimPosition::Leading => {
18036 self.write_keyword("LTRIM");
18037 self.write("(");
18038 self.generate_expression(&f.this)?;
18039 self.write(")");
18040 return Ok(());
18041 }
18042 TrimPosition::Trailing => {
18043 self.write_keyword("RTRIM");
18044 self.write("(");
18045 self.generate_expression(&f.this)?;
18046 self.write(")");
18047 return Ok(());
18048 }
18049 TrimPosition::Both => {
18050 }
18053 }
18054 }
18055
18056 self.write_keyword("TRIM");
18057 self.write("(");
18058 let force_standard = f.characters.is_some()
18061 && !f.sql_standard_syntax
18062 && matches!(
18063 self.config.dialect,
18064 Some(DialectType::Hive)
18065 | Some(DialectType::Spark)
18066 | Some(DialectType::Databricks)
18067 | Some(DialectType::ClickHouse)
18068 );
18069 let use_standard = (f.sql_standard_syntax || force_standard)
18070 && !(f.position_explicit
18071 && f.characters.is_none()
18072 && matches!(f.position, TrimPosition::Both));
18073 if use_standard {
18074 if f.position_explicit {
18077 match f.position {
18078 TrimPosition::Both => self.write_keyword("BOTH"),
18079 TrimPosition::Leading => self.write_keyword("LEADING"),
18080 TrimPosition::Trailing => self.write_keyword("TRAILING"),
18081 }
18082 self.write_space();
18083 }
18084 if let Some(chars) = &f.characters {
18085 self.generate_expression(chars)?;
18086 self.write_space();
18087 }
18088 self.write_keyword("FROM");
18089 self.write_space();
18090 self.generate_expression(&f.this)?;
18091 } else {
18092 self.generate_expression(&f.this)?;
18094 if let Some(chars) = &f.characters {
18095 self.write(", ");
18096 self.generate_expression(chars)?;
18097 }
18098 }
18099 self.write(")");
18100 Ok(())
18101 }
18102
18103 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
18104 self.write_keyword("REPLACE");
18105 self.write("(");
18106 self.generate_expression(&f.this)?;
18107 self.write(", ");
18108 self.generate_expression(&f.old)?;
18109 self.write(", ");
18110 self.generate_expression(&f.new)?;
18111 self.write(")");
18112 Ok(())
18113 }
18114
18115 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
18116 self.write_keyword(name);
18117 self.write("(");
18118 self.generate_expression(&f.this)?;
18119 self.write(", ");
18120 self.generate_expression(&f.length)?;
18121 self.write(")");
18122 Ok(())
18123 }
18124
18125 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
18126 self.write_keyword("REPEAT");
18127 self.write("(");
18128 self.generate_expression(&f.this)?;
18129 self.write(", ");
18130 self.generate_expression(&f.times)?;
18131 self.write(")");
18132 Ok(())
18133 }
18134
18135 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
18136 self.write_keyword(name);
18137 self.write("(");
18138 self.generate_expression(&f.this)?;
18139 self.write(", ");
18140 self.generate_expression(&f.length)?;
18141 if let Some(fill) = &f.fill {
18142 self.write(", ");
18143 self.generate_expression(fill)?;
18144 }
18145 self.write(")");
18146 Ok(())
18147 }
18148
18149 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
18150 self.write_keyword("SPLIT");
18151 self.write("(");
18152 self.generate_expression(&f.this)?;
18153 self.write(", ");
18154 self.generate_expression(&f.delimiter)?;
18155 self.write(")");
18156 Ok(())
18157 }
18158
18159 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
18160 use crate::dialects::DialectType;
18161 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
18163 self.generate_expression(&f.this)?;
18164 self.write(" ~ ");
18165 self.generate_expression(&f.pattern)?;
18166 } else if matches!(self.config.dialect, Some(DialectType::Exasol)) && f.flags.is_none() {
18167 self.generate_expression(&f.this)?;
18169 self.write_keyword(" REGEXP_LIKE ");
18170 self.generate_expression(&f.pattern)?;
18171 } else if matches!(
18172 self.config.dialect,
18173 Some(DialectType::SingleStore)
18174 | Some(DialectType::Spark)
18175 | Some(DialectType::Hive)
18176 | Some(DialectType::Databricks)
18177 ) && f.flags.is_none()
18178 {
18179 self.generate_expression(&f.this)?;
18181 self.write_keyword(" RLIKE ");
18182 self.generate_expression(&f.pattern)?;
18183 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
18184 self.write_keyword("REGEXP");
18186 self.write("(");
18187 self.generate_expression(&f.this)?;
18188 self.write(", ");
18189 self.generate_expression(&f.pattern)?;
18190 if let Some(flags) = &f.flags {
18191 self.write(", ");
18192 self.generate_expression(flags)?;
18193 }
18194 self.write(")");
18195 } else {
18196 self.write_keyword("REGEXP_LIKE");
18197 self.write("(");
18198 self.generate_expression(&f.this)?;
18199 self.write(", ");
18200 self.generate_expression(&f.pattern)?;
18201 if let Some(flags) = &f.flags {
18202 self.write(", ");
18203 self.generate_expression(flags)?;
18204 }
18205 self.write(")");
18206 }
18207 Ok(())
18208 }
18209
18210 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
18211 self.write_keyword("REGEXP_REPLACE");
18212 self.write("(");
18213 self.generate_expression(&f.this)?;
18214 self.write(", ");
18215 self.generate_expression(&f.pattern)?;
18216 self.write(", ");
18217 self.generate_expression(&f.replacement)?;
18218 if let Some(flags) = &f.flags {
18219 self.write(", ");
18220 self.generate_expression(flags)?;
18221 }
18222 self.write(")");
18223 Ok(())
18224 }
18225
18226 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
18227 self.write_keyword("REGEXP_EXTRACT");
18228 self.write("(");
18229 self.generate_expression(&f.this)?;
18230 self.write(", ");
18231 self.generate_expression(&f.pattern)?;
18232 if let Some(group) = &f.group {
18233 self.write(", ");
18234 self.generate_expression(group)?;
18235 }
18236 self.write(")");
18237 Ok(())
18238 }
18239
18240 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
18243 self.write_keyword("ROUND");
18244 self.write("(");
18245 self.generate_expression(&f.this)?;
18246 if let Some(decimals) = &f.decimals {
18247 self.write(", ");
18248 self.generate_expression(decimals)?;
18249 }
18250 self.write(")");
18251 Ok(())
18252 }
18253
18254 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
18255 self.write_keyword("FLOOR");
18256 self.write("(");
18257 self.generate_expression(&f.this)?;
18258 if let Some(to) = &f.to {
18260 self.write(" ");
18261 self.write_keyword("TO");
18262 self.write(" ");
18263 self.generate_expression(to)?;
18264 } else if let Some(scale) = &f.scale {
18265 self.write(", ");
18266 self.generate_expression(scale)?;
18267 }
18268 self.write(")");
18269 Ok(())
18270 }
18271
18272 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
18273 self.write_keyword("CEIL");
18274 self.write("(");
18275 self.generate_expression(&f.this)?;
18276 if let Some(to) = &f.to {
18278 self.write(" ");
18279 self.write_keyword("TO");
18280 self.write(" ");
18281 self.generate_expression(to)?;
18282 } else if let Some(decimals) = &f.decimals {
18283 self.write(", ");
18284 self.generate_expression(decimals)?;
18285 }
18286 self.write(")");
18287 Ok(())
18288 }
18289
18290 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
18291 use crate::expressions::Literal;
18292
18293 if let Some(base) = &f.base {
18294 if self.is_log_base_none() {
18297 if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "2")) {
18298 self.write_func_name("LOG2");
18299 self.write("(");
18300 self.generate_expression(&f.this)?;
18301 self.write(")");
18302 return Ok(());
18303 } else if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "10")) {
18304 self.write_func_name("LOG10");
18305 self.write("(");
18306 self.generate_expression(&f.this)?;
18307 self.write(")");
18308 return Ok(());
18309 }
18310 }
18312
18313 self.write_func_name("LOG");
18314 self.write("(");
18315 if self.is_log_value_first() {
18316 self.generate_expression(&f.this)?;
18318 self.write(", ");
18319 self.generate_expression(base)?;
18320 } else {
18321 self.generate_expression(base)?;
18323 self.write(", ");
18324 self.generate_expression(&f.this)?;
18325 }
18326 self.write(")");
18327 } else {
18328 self.write_func_name("LOG");
18330 self.write("(");
18331 self.generate_expression(&f.this)?;
18332 self.write(")");
18333 }
18334 Ok(())
18335 }
18336
18337 fn is_log_value_first(&self) -> bool {
18340 use crate::dialects::DialectType;
18341 matches!(
18342 self.config.dialect,
18343 Some(DialectType::BigQuery)
18344 | Some(DialectType::TSQL)
18345 | Some(DialectType::Tableau)
18346 | Some(DialectType::Fabric)
18347 )
18348 }
18349
18350 fn is_log_base_none(&self) -> bool {
18353 use crate::dialects::DialectType;
18354 matches!(
18355 self.config.dialect,
18356 Some(DialectType::Presto)
18357 | Some(DialectType::Trino)
18358 | Some(DialectType::ClickHouse)
18359 | Some(DialectType::Athena)
18360 )
18361 }
18362
18363 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
18366 self.write_keyword("CURRENT_TIME");
18367 if let Some(precision) = f.precision {
18368 self.write(&format!("({})", precision));
18369 } else if matches!(
18370 self.config.dialect,
18371 Some(crate::dialects::DialectType::MySQL)
18372 | Some(crate::dialects::DialectType::SingleStore)
18373 | Some(crate::dialects::DialectType::TiDB)
18374 ) {
18375 self.write("()");
18376 }
18377 Ok(())
18378 }
18379
18380 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
18381 use crate::dialects::DialectType;
18382
18383 if f.sysdate {
18385 match self.config.dialect {
18386 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
18387 self.write_keyword("SYSDATE");
18388 return Ok(());
18389 }
18390 Some(DialectType::Snowflake) => {
18391 self.write_keyword("SYSDATE");
18393 self.write("()");
18394 return Ok(());
18395 }
18396 _ => {
18397 }
18399 }
18400 }
18401
18402 self.write_keyword("CURRENT_TIMESTAMP");
18403 if let Some(precision) = f.precision {
18405 self.write(&format!("({})", precision));
18406 } else if matches!(
18407 self.config.dialect,
18408 Some(crate::dialects::DialectType::MySQL)
18409 | Some(crate::dialects::DialectType::SingleStore)
18410 | Some(crate::dialects::DialectType::TiDB)
18411 | Some(crate::dialects::DialectType::Spark)
18412 | Some(crate::dialects::DialectType::Hive)
18413 | Some(crate::dialects::DialectType::Databricks)
18414 | Some(crate::dialects::DialectType::ClickHouse)
18415 | Some(crate::dialects::DialectType::BigQuery)
18416 | Some(crate::dialects::DialectType::Snowflake)
18417 | Some(crate::dialects::DialectType::Exasol)
18418 ) {
18419 self.write("()");
18420 }
18421 Ok(())
18422 }
18423
18424 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
18425 if self.config.dialect == Some(DialectType::Exasol) {
18427 self.write_keyword("CONVERT_TZ");
18428 self.write("(");
18429 self.generate_expression(&f.this)?;
18430 self.write(", 'UTC', ");
18431 self.generate_expression(&f.zone)?;
18432 self.write(")");
18433 return Ok(());
18434 }
18435
18436 self.generate_expression(&f.this)?;
18437 self.write_space();
18438 self.write_keyword("AT TIME ZONE");
18439 self.write_space();
18440 self.generate_expression(&f.zone)?;
18441 Ok(())
18442 }
18443
18444 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
18445 use crate::dialects::DialectType;
18446
18447 let is_presto_like = matches!(
18450 self.config.dialect,
18451 Some(DialectType::Presto) | Some(DialectType::Trino)
18452 );
18453
18454 if is_presto_like {
18455 self.write_keyword(name);
18456 self.write("(");
18457 self.write("'");
18459 self.write_simple_interval_unit(&f.unit, false);
18460 self.write("'");
18461 self.write(", ");
18462 let needs_cast = !self.returns_integer_type(&f.interval);
18464 if needs_cast {
18465 self.write_keyword("CAST");
18466 self.write("(");
18467 }
18468 self.generate_expression(&f.interval)?;
18469 if needs_cast {
18470 self.write_space();
18471 self.write_keyword("AS");
18472 self.write_space();
18473 self.write_keyword("BIGINT");
18474 self.write(")");
18475 }
18476 self.write(", ");
18477 self.generate_expression(&f.this)?;
18478 self.write(")");
18479 } else {
18480 self.write_keyword(name);
18481 self.write("(");
18482 self.generate_expression(&f.this)?;
18483 self.write(", ");
18484 self.write_keyword("INTERVAL");
18485 self.write_space();
18486 self.generate_expression(&f.interval)?;
18487 self.write_space();
18488 self.write_simple_interval_unit(&f.unit, false); self.write(")");
18490 }
18491 Ok(())
18492 }
18493
18494 fn returns_integer_type(&self, expr: &Expression) -> bool {
18497 use crate::expressions::{DataType, Literal};
18498 match expr {
18499 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => { let Literal::Number(n) = lit.as_ref() else { unreachable!() }; !n.contains('.') },
18501
18502 Expression::Floor(f) => self.returns_integer_type(&f.this),
18504
18505 Expression::Round(f) => {
18507 f.decimals.is_none() && self.returns_integer_type(&f.this)
18509 }
18510
18511 Expression::Sign(f) => self.returns_integer_type(&f.this),
18513
18514 Expression::Abs(f) => self.returns_integer_type(&f.this),
18516
18517 Expression::Mul(op) => {
18519 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
18520 }
18521 Expression::Add(op) => {
18522 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
18523 }
18524 Expression::Sub(op) => {
18525 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
18526 }
18527 Expression::Mod(op) => self.returns_integer_type(&op.left),
18528
18529 Expression::Cast(c) => matches!(
18531 &c.to,
18532 DataType::BigInt { .. }
18533 | DataType::Int { .. }
18534 | DataType::SmallInt { .. }
18535 | DataType::TinyInt { .. }
18536 ),
18537
18538 Expression::Neg(op) => self.returns_integer_type(&op.this),
18540
18541 Expression::Paren(p) => self.returns_integer_type(&p.this),
18543
18544 _ => false,
18547 }
18548 }
18549
18550 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
18551 self.write_keyword("DATEDIFF");
18552 self.write("(");
18553 if let Some(unit) = &f.unit {
18554 self.write_simple_interval_unit(unit, false); self.write(", ");
18556 }
18557 self.generate_expression(&f.this)?;
18558 self.write(", ");
18559 self.generate_expression(&f.expression)?;
18560 self.write(")");
18561 Ok(())
18562 }
18563
18564 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
18565 self.write_keyword("DATE_TRUNC");
18566 self.write("('");
18567 self.write_datetime_field(&f.unit);
18568 self.write("', ");
18569 self.generate_expression(&f.this)?;
18570 self.write(")");
18571 Ok(())
18572 }
18573
18574 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
18575 use crate::dialects::DialectType;
18576 use crate::expressions::DateTimeField;
18577
18578 self.write_keyword("LAST_DAY");
18579 self.write("(");
18580 self.generate_expression(&f.this)?;
18581 if let Some(unit) = &f.unit {
18582 self.write(", ");
18583 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
18586 if let DateTimeField::WeekWithModifier(_) = unit {
18587 self.write_keyword("WEEK");
18588 } else {
18589 self.write_datetime_field(unit);
18590 }
18591 } else {
18592 self.write_datetime_field(unit);
18593 }
18594 }
18595 self.write(")");
18596 Ok(())
18597 }
18598
18599 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
18600 if matches!(
18602 self.config.dialect,
18603 Some(DialectType::TSQL) | Some(DialectType::Fabric)
18604 ) {
18605 self.write_keyword("DATEPART");
18606 self.write("(");
18607 self.write_datetime_field(&f.field);
18608 self.write(", ");
18609 self.generate_expression(&f.this)?;
18610 self.write(")");
18611 return Ok(());
18612 }
18613 self.write_keyword("EXTRACT");
18614 self.write("(");
18615 if matches!(
18617 self.config.dialect,
18618 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
18619 ) {
18620 self.write_datetime_field_lower(&f.field);
18621 } else {
18622 self.write_datetime_field(&f.field);
18623 }
18624 self.write_space();
18625 self.write_keyword("FROM");
18626 self.write_space();
18627 self.generate_expression(&f.this)?;
18628 self.write(")");
18629 Ok(())
18630 }
18631
18632 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
18633 self.write_keyword("TO_DATE");
18634 self.write("(");
18635 self.generate_expression(&f.this)?;
18636 if let Some(format) = &f.format {
18637 self.write(", ");
18638 self.generate_expression(format)?;
18639 }
18640 self.write(")");
18641 Ok(())
18642 }
18643
18644 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
18645 self.write_keyword("TO_TIMESTAMP");
18646 self.write("(");
18647 self.generate_expression(&f.this)?;
18648 if let Some(format) = &f.format {
18649 self.write(", ");
18650 self.generate_expression(format)?;
18651 }
18652 self.write(")");
18653 Ok(())
18654 }
18655
18656 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
18659 use crate::dialects::DialectType;
18660
18661 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
18663 self.write_keyword("CASE WHEN");
18664 self.write_space();
18665 self.generate_expression(&f.condition)?;
18666 self.write_space();
18667 self.write_keyword("THEN");
18668 self.write_space();
18669 self.generate_expression(&f.true_value)?;
18670 if let Some(false_val) = &f.false_value {
18671 self.write_space();
18672 self.write_keyword("ELSE");
18673 self.write_space();
18674 self.generate_expression(false_val)?;
18675 }
18676 self.write_space();
18677 self.write_keyword("END");
18678 return Ok(());
18679 }
18680
18681 if self.config.dialect == Some(DialectType::Exasol) {
18683 self.write_keyword("IF");
18684 self.write_space();
18685 self.generate_expression(&f.condition)?;
18686 self.write_space();
18687 self.write_keyword("THEN");
18688 self.write_space();
18689 self.generate_expression(&f.true_value)?;
18690 if let Some(false_val) = &f.false_value {
18691 self.write_space();
18692 self.write_keyword("ELSE");
18693 self.write_space();
18694 self.generate_expression(false_val)?;
18695 }
18696 self.write_space();
18697 self.write_keyword("ENDIF");
18698 return Ok(());
18699 }
18700
18701 let func_name = match self.config.dialect {
18703 Some(DialectType::Snowflake) => "IFF",
18704 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
18705 Some(DialectType::Drill) => "`IF`",
18706 _ => "IF",
18707 };
18708 self.write(func_name);
18709 self.write("(");
18710 self.generate_expression(&f.condition)?;
18711 self.write(", ");
18712 self.generate_expression(&f.true_value)?;
18713 if let Some(false_val) = &f.false_value {
18714 self.write(", ");
18715 self.generate_expression(false_val)?;
18716 }
18717 self.write(")");
18718 Ok(())
18719 }
18720
18721 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
18722 self.write_keyword("NVL2");
18723 self.write("(");
18724 self.generate_expression(&f.this)?;
18725 self.write(", ");
18726 self.generate_expression(&f.true_value)?;
18727 self.write(", ");
18728 self.generate_expression(&f.false_value)?;
18729 self.write(")");
18730 Ok(())
18731 }
18732
18733 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
18736 let count_name = match self.config.normalize_functions {
18738 NormalizeFunctions::Upper => "COUNT".to_string(),
18739 NormalizeFunctions::Lower => "count".to_string(),
18740 NormalizeFunctions::None => f
18741 .original_name
18742 .clone()
18743 .unwrap_or_else(|| "COUNT".to_string()),
18744 };
18745 self.write(&count_name);
18746 self.write("(");
18747 if f.distinct {
18748 self.write_keyword("DISTINCT");
18749 self.write_space();
18750 }
18751 if f.star {
18752 self.write("*");
18753 } else if let Some(ref expr) = f.this {
18754 if let Expression::Tuple(tuple) = expr {
18756 let needs_transform =
18760 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
18761
18762 if needs_transform {
18763 self.write_keyword("CASE");
18765 for e in &tuple.expressions {
18766 self.write_space();
18767 self.write_keyword("WHEN");
18768 self.write_space();
18769 self.generate_expression(e)?;
18770 self.write_space();
18771 self.write_keyword("IS NULL THEN NULL");
18772 }
18773 self.write_space();
18774 self.write_keyword("ELSE");
18775 self.write(" (");
18776 for (i, e) in tuple.expressions.iter().enumerate() {
18777 if i > 0 {
18778 self.write(", ");
18779 }
18780 self.generate_expression(e)?;
18781 }
18782 self.write(")");
18783 self.write_space();
18784 self.write_keyword("END");
18785 } else {
18786 for (i, e) in tuple.expressions.iter().enumerate() {
18787 if i > 0 {
18788 self.write(", ");
18789 }
18790 self.generate_expression(e)?;
18791 }
18792 }
18793 } else {
18794 self.generate_expression(expr)?;
18795 }
18796 }
18797 if let Some(ignore) = f.ignore_nulls {
18799 self.write_space();
18800 if ignore {
18801 self.write_keyword("IGNORE NULLS");
18802 } else {
18803 self.write_keyword("RESPECT NULLS");
18804 }
18805 }
18806 self.write(")");
18807 if let Some(ref filter) = f.filter {
18808 self.write_space();
18809 self.write_keyword("FILTER");
18810 self.write("(");
18811 self.write_keyword("WHERE");
18812 self.write_space();
18813 self.generate_expression(filter)?;
18814 self.write(")");
18815 }
18816 Ok(())
18817 }
18818
18819 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
18820 let func_name: Cow<'_, str> = match self.config.normalize_functions {
18822 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
18823 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
18824 NormalizeFunctions::None => {
18825 if let Some(ref original) = f.name {
18828 Cow::Owned(original.clone())
18829 } else {
18830 Cow::Owned(name.to_ascii_lowercase())
18831 }
18832 }
18833 };
18834 self.write(func_name.as_ref());
18835 self.write("(");
18836 if f.distinct {
18837 self.write_keyword("DISTINCT");
18838 self.write_space();
18839 }
18840 if !matches!(f.this, Expression::Null(_)) {
18842 self.generate_expression(&f.this)?;
18843 }
18844 if self.config.ignore_nulls_in_func
18847 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18848 {
18849 match f.ignore_nulls {
18850 Some(true) => {
18851 self.write_space();
18852 self.write_keyword("IGNORE NULLS");
18853 }
18854 Some(false) => {
18855 self.write_space();
18856 self.write_keyword("RESPECT NULLS");
18857 }
18858 None => {}
18859 }
18860 }
18861 if let Some((ref expr, is_max)) = f.having_max {
18864 self.write_space();
18865 self.write_keyword("HAVING");
18866 self.write_space();
18867 if is_max {
18868 self.write_keyword("MAX");
18869 } else {
18870 self.write_keyword("MIN");
18871 }
18872 self.write_space();
18873 self.generate_expression(expr)?;
18874 }
18875 if !f.order_by.is_empty() {
18877 self.write_space();
18878 self.write_keyword("ORDER BY");
18879 self.write_space();
18880 for (i, ord) in f.order_by.iter().enumerate() {
18881 if i > 0 {
18882 self.write(", ");
18883 }
18884 self.generate_ordered(ord)?;
18885 }
18886 }
18887 if let Some(ref limit) = f.limit {
18889 self.write_space();
18890 self.write_keyword("LIMIT");
18891 self.write_space();
18892 if let Expression::Tuple(t) = limit.as_ref() {
18894 if t.expressions.len() == 2 {
18895 self.generate_expression(&t.expressions[0])?;
18896 self.write(", ");
18897 self.generate_expression(&t.expressions[1])?;
18898 } else {
18899 self.generate_expression(limit)?;
18900 }
18901 } else {
18902 self.generate_expression(limit)?;
18903 }
18904 }
18905 self.write(")");
18906 if !self.config.ignore_nulls_in_func
18909 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18910 {
18911 match f.ignore_nulls {
18912 Some(true) => {
18913 self.write_space();
18914 self.write_keyword("IGNORE NULLS");
18915 }
18916 Some(false) => {
18917 self.write_space();
18918 self.write_keyword("RESPECT NULLS");
18919 }
18920 None => {}
18921 }
18922 }
18923 if let Some(ref filter) = f.filter {
18924 self.write_space();
18925 self.write_keyword("FILTER");
18926 self.write("(");
18927 self.write_keyword("WHERE");
18928 self.write_space();
18929 self.generate_expression(filter)?;
18930 self.write(")");
18931 }
18932 Ok(())
18933 }
18934
18935 fn generate_agg_func_with_ignore_nulls_bool(
18938 &mut self,
18939 name: &str,
18940 f: &AggFunc,
18941 ) -> Result<()> {
18942 if matches!(
18944 self.config.dialect,
18945 Some(DialectType::Hive)
18946 ) && f.ignore_nulls == Some(true)
18947 {
18948 let func_name: Cow<'_, str> = match self.config.normalize_functions {
18950 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
18951 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
18952 NormalizeFunctions::None => {
18953 if let Some(ref original) = f.name {
18954 Cow::Owned(original.clone())
18955 } else {
18956 Cow::Owned(name.to_ascii_lowercase())
18957 }
18958 }
18959 };
18960 self.write(func_name.as_ref());
18961 self.write("(");
18962 if f.distinct {
18963 self.write_keyword("DISTINCT");
18964 self.write_space();
18965 }
18966 if !matches!(f.this, Expression::Null(_)) {
18967 self.generate_expression(&f.this)?;
18968 }
18969 self.write(", ");
18970 self.write_keyword("TRUE");
18971 self.write(")");
18972 return Ok(());
18973 }
18974 self.generate_agg_func(name, f)
18975 }
18976
18977 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
18978 self.write_keyword("GROUP_CONCAT");
18979 self.write("(");
18980 if f.distinct {
18981 self.write_keyword("DISTINCT");
18982 self.write_space();
18983 }
18984 self.generate_expression(&f.this)?;
18985 if let Some(ref order_by) = f.order_by {
18986 self.write_space();
18987 self.write_keyword("ORDER BY");
18988 self.write_space();
18989 for (i, ord) in order_by.iter().enumerate() {
18990 if i > 0 {
18991 self.write(", ");
18992 }
18993 self.generate_ordered(ord)?;
18994 }
18995 }
18996 if let Some(ref sep) = f.separator {
18997 if matches!(
19000 self.config.dialect,
19001 Some(crate::dialects::DialectType::SQLite)
19002 ) {
19003 self.write(", ");
19004 self.generate_expression(sep)?;
19005 } else {
19006 self.write_space();
19007 self.write_keyword("SEPARATOR");
19008 self.write_space();
19009 self.generate_expression(sep)?;
19010 }
19011 }
19012 self.write(")");
19013 if let Some(ref filter) = f.filter {
19014 self.write_space();
19015 self.write_keyword("FILTER");
19016 self.write("(");
19017 self.write_keyword("WHERE");
19018 self.write_space();
19019 self.generate_expression(filter)?;
19020 self.write(")");
19021 }
19022 Ok(())
19023 }
19024
19025 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
19026 let is_tsql = matches!(
19027 self.config.dialect,
19028 Some(crate::dialects::DialectType::TSQL)
19029 );
19030 self.write_keyword("STRING_AGG");
19031 self.write("(");
19032 if f.distinct {
19033 self.write_keyword("DISTINCT");
19034 self.write_space();
19035 }
19036 self.generate_expression(&f.this)?;
19037 if let Some(ref separator) = f.separator {
19038 self.write(", ");
19039 self.generate_expression(separator)?;
19040 }
19041 if !is_tsql {
19043 if let Some(ref order_by) = f.order_by {
19044 self.write_space();
19045 self.write_keyword("ORDER BY");
19046 self.write_space();
19047 for (i, ord) in order_by.iter().enumerate() {
19048 if i > 0 {
19049 self.write(", ");
19050 }
19051 self.generate_ordered(ord)?;
19052 }
19053 }
19054 }
19055 if let Some(ref limit) = f.limit {
19056 self.write_space();
19057 self.write_keyword("LIMIT");
19058 self.write_space();
19059 self.generate_expression(limit)?;
19060 }
19061 self.write(")");
19062 if is_tsql {
19064 if let Some(ref order_by) = f.order_by {
19065 self.write_space();
19066 self.write_keyword("WITHIN GROUP");
19067 self.write(" (");
19068 self.write_keyword("ORDER BY");
19069 self.write_space();
19070 for (i, ord) in order_by.iter().enumerate() {
19071 if i > 0 {
19072 self.write(", ");
19073 }
19074 self.generate_ordered(ord)?;
19075 }
19076 self.write(")");
19077 }
19078 }
19079 if let Some(ref filter) = f.filter {
19080 self.write_space();
19081 self.write_keyword("FILTER");
19082 self.write("(");
19083 self.write_keyword("WHERE");
19084 self.write_space();
19085 self.generate_expression(filter)?;
19086 self.write(")");
19087 }
19088 Ok(())
19089 }
19090
19091 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
19092 use crate::dialects::DialectType;
19093 self.write_keyword("LISTAGG");
19094 self.write("(");
19095 if f.distinct {
19096 self.write_keyword("DISTINCT");
19097 self.write_space();
19098 }
19099 self.generate_expression(&f.this)?;
19100 if let Some(ref sep) = f.separator {
19101 self.write(", ");
19102 self.generate_expression(sep)?;
19103 } else if matches!(
19104 self.config.dialect,
19105 Some(DialectType::Trino) | Some(DialectType::Presto)
19106 ) {
19107 self.write(", ','");
19109 }
19110 if let Some(ref overflow) = f.on_overflow {
19111 self.write_space();
19112 self.write_keyword("ON OVERFLOW");
19113 self.write_space();
19114 match overflow {
19115 ListAggOverflow::Error => self.write_keyword("ERROR"),
19116 ListAggOverflow::Truncate { filler, with_count } => {
19117 self.write_keyword("TRUNCATE");
19118 if let Some(ref fill) = filler {
19119 self.write_space();
19120 self.generate_expression(fill)?;
19121 }
19122 if *with_count {
19123 self.write_space();
19124 self.write_keyword("WITH COUNT");
19125 } else {
19126 self.write_space();
19127 self.write_keyword("WITHOUT COUNT");
19128 }
19129 }
19130 }
19131 }
19132 self.write(")");
19133 if let Some(ref order_by) = f.order_by {
19134 self.write_space();
19135 self.write_keyword("WITHIN GROUP");
19136 self.write(" (");
19137 self.write_keyword("ORDER BY");
19138 self.write_space();
19139 for (i, ord) in order_by.iter().enumerate() {
19140 if i > 0 {
19141 self.write(", ");
19142 }
19143 self.generate_ordered(ord)?;
19144 }
19145 self.write(")");
19146 }
19147 if let Some(ref filter) = f.filter {
19148 self.write_space();
19149 self.write_keyword("FILTER");
19150 self.write("(");
19151 self.write_keyword("WHERE");
19152 self.write_space();
19153 self.generate_expression(filter)?;
19154 self.write(")");
19155 }
19156 Ok(())
19157 }
19158
19159 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
19160 self.write_keyword("SUM_IF");
19161 self.write("(");
19162 self.generate_expression(&f.this)?;
19163 self.write(", ");
19164 self.generate_expression(&f.condition)?;
19165 self.write(")");
19166 if let Some(ref filter) = f.filter {
19167 self.write_space();
19168 self.write_keyword("FILTER");
19169 self.write("(");
19170 self.write_keyword("WHERE");
19171 self.write_space();
19172 self.generate_expression(filter)?;
19173 self.write(")");
19174 }
19175 Ok(())
19176 }
19177
19178 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
19179 self.write_keyword("APPROX_PERCENTILE");
19180 self.write("(");
19181 self.generate_expression(&f.this)?;
19182 self.write(", ");
19183 self.generate_expression(&f.percentile)?;
19184 if let Some(ref acc) = f.accuracy {
19185 self.write(", ");
19186 self.generate_expression(acc)?;
19187 }
19188 self.write(")");
19189 if let Some(ref filter) = f.filter {
19190 self.write_space();
19191 self.write_keyword("FILTER");
19192 self.write("(");
19193 self.write_keyword("WHERE");
19194 self.write_space();
19195 self.generate_expression(filter)?;
19196 self.write(")");
19197 }
19198 Ok(())
19199 }
19200
19201 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
19202 self.write_keyword(name);
19203 self.write("(");
19204 self.generate_expression(&f.percentile)?;
19205 self.write(")");
19206 if let Some(ref order_by) = f.order_by {
19207 self.write_space();
19208 self.write_keyword("WITHIN GROUP");
19209 self.write(" (");
19210 self.write_keyword("ORDER BY");
19211 self.write_space();
19212 self.generate_expression(&f.this)?;
19213 for ord in order_by.iter() {
19214 if ord.desc {
19215 self.write_space();
19216 self.write_keyword("DESC");
19217 }
19218 }
19219 self.write(")");
19220 }
19221 if let Some(ref filter) = f.filter {
19222 self.write_space();
19223 self.write_keyword("FILTER");
19224 self.write("(");
19225 self.write_keyword("WHERE");
19226 self.write_space();
19227 self.generate_expression(filter)?;
19228 self.write(")");
19229 }
19230 Ok(())
19231 }
19232
19233 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
19236 self.write_keyword("NTILE");
19237 self.write("(");
19238 if let Some(num_buckets) = &f.num_buckets {
19239 self.generate_expression(num_buckets)?;
19240 }
19241 if let Some(order_by) = &f.order_by {
19242 self.write_keyword(" ORDER BY ");
19243 for (i, ob) in order_by.iter().enumerate() {
19244 if i > 0 {
19245 self.write(", ");
19246 }
19247 self.generate_ordered(ob)?;
19248 }
19249 }
19250 self.write(")");
19251 Ok(())
19252 }
19253
19254 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
19255 self.write_keyword(name);
19256 self.write("(");
19257 self.generate_expression(&f.this)?;
19258 if let Some(ref offset) = f.offset {
19259 self.write(", ");
19260 self.generate_expression(offset)?;
19261 if let Some(ref default) = f.default {
19262 self.write(", ");
19263 self.generate_expression(default)?;
19264 }
19265 }
19266 if self.config.ignore_nulls_in_func {
19268 match f.ignore_nulls {
19269 Some(true) => {
19270 self.write_space();
19271 self.write_keyword("IGNORE NULLS");
19272 }
19273 Some(false) => {
19274 self.write_space();
19275 self.write_keyword("RESPECT NULLS");
19276 }
19277 None => {}
19278 }
19279 }
19280 self.write(")");
19281 if !self.config.ignore_nulls_in_func {
19283 match f.ignore_nulls {
19284 Some(true) => {
19285 self.write_space();
19286 self.write_keyword("IGNORE NULLS");
19287 }
19288 Some(false) => {
19289 self.write_space();
19290 self.write_keyword("RESPECT NULLS");
19291 }
19292 None => {}
19293 }
19294 }
19295 Ok(())
19296 }
19297
19298 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
19299 self.write_keyword(name);
19300 self.write("(");
19301 self.generate_expression(&f.this)?;
19302 if !f.order_by.is_empty() {
19304 self.write_space();
19305 self.write_keyword("ORDER BY");
19306 self.write_space();
19307 for (i, ordered) in f.order_by.iter().enumerate() {
19308 if i > 0 {
19309 self.write(", ");
19310 }
19311 self.generate_ordered(ordered)?;
19312 }
19313 }
19314 if self.config.ignore_nulls_in_func {
19316 match f.ignore_nulls {
19317 Some(true) => {
19318 self.write_space();
19319 self.write_keyword("IGNORE NULLS");
19320 }
19321 Some(false) => {
19322 self.write_space();
19323 self.write_keyword("RESPECT NULLS");
19324 }
19325 None => {}
19326 }
19327 }
19328 self.write(")");
19329 if !self.config.ignore_nulls_in_func {
19331 match f.ignore_nulls {
19332 Some(true) => {
19333 self.write_space();
19334 self.write_keyword("IGNORE NULLS");
19335 }
19336 Some(false) => {
19337 self.write_space();
19338 self.write_keyword("RESPECT NULLS");
19339 }
19340 None => {}
19341 }
19342 }
19343 Ok(())
19344 }
19345
19346 fn generate_value_func_with_ignore_nulls_bool(
19349 &mut self,
19350 name: &str,
19351 f: &ValueFunc,
19352 ) -> Result<()> {
19353 if matches!(
19354 self.config.dialect,
19355 Some(DialectType::Hive)
19356 ) && f.ignore_nulls == Some(true)
19357 {
19358 self.write_keyword(name);
19359 self.write("(");
19360 self.generate_expression(&f.this)?;
19361 self.write(", ");
19362 self.write_keyword("TRUE");
19363 self.write(")");
19364 return Ok(());
19365 }
19366 self.generate_value_func(name, f)
19367 }
19368
19369 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
19370 self.write_keyword("NTH_VALUE");
19371 self.write("(");
19372 self.generate_expression(&f.this)?;
19373 self.write(", ");
19374 self.generate_expression(&f.offset)?;
19375 if self.config.ignore_nulls_in_func {
19377 match f.ignore_nulls {
19378 Some(true) => {
19379 self.write_space();
19380 self.write_keyword("IGNORE NULLS");
19381 }
19382 Some(false) => {
19383 self.write_space();
19384 self.write_keyword("RESPECT NULLS");
19385 }
19386 None => {}
19387 }
19388 }
19389 self.write(")");
19390 if matches!(
19392 self.config.dialect,
19393 Some(crate::dialects::DialectType::Snowflake)
19394 ) {
19395 match f.from_first {
19396 Some(true) => {
19397 self.write_space();
19398 self.write_keyword("FROM FIRST");
19399 }
19400 Some(false) => {
19401 self.write_space();
19402 self.write_keyword("FROM LAST");
19403 }
19404 None => {}
19405 }
19406 }
19407 if !self.config.ignore_nulls_in_func {
19409 match f.ignore_nulls {
19410 Some(true) => {
19411 self.write_space();
19412 self.write_keyword("IGNORE NULLS");
19413 }
19414 Some(false) => {
19415 self.write_space();
19416 self.write_keyword("RESPECT NULLS");
19417 }
19418 None => {}
19419 }
19420 }
19421 Ok(())
19422 }
19423
19424 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
19427 if matches!(
19430 self.config.dialect,
19431 Some(crate::dialects::DialectType::ClickHouse)
19432 ) {
19433 self.write_keyword("POSITION");
19434 self.write("(");
19435 self.generate_expression(&f.string)?;
19436 self.write(", ");
19437 self.generate_expression(&f.substring)?;
19438 if let Some(ref start) = f.start {
19439 self.write(", ");
19440 self.generate_expression(start)?;
19441 }
19442 self.write(")");
19443 return Ok(());
19444 }
19445
19446 self.write_keyword("POSITION");
19447 self.write("(");
19448 self.generate_expression(&f.substring)?;
19449 self.write_space();
19450 self.write_keyword("IN");
19451 self.write_space();
19452 self.generate_expression(&f.string)?;
19453 if let Some(ref start) = f.start {
19454 self.write(", ");
19455 self.generate_expression(start)?;
19456 }
19457 self.write(")");
19458 Ok(())
19459 }
19460
19461 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
19464 if f.lower.is_some() || f.upper.is_some() {
19466 self.write_keyword("RANDOM");
19467 self.write("(");
19468 if let Some(ref lower) = f.lower {
19469 self.generate_expression(lower)?;
19470 }
19471 if let Some(ref upper) = f.upper {
19472 self.write(", ");
19473 self.generate_expression(upper)?;
19474 }
19475 self.write(")");
19476 return Ok(());
19477 }
19478 let func_name = match self.config.dialect {
19480 Some(crate::dialects::DialectType::Snowflake)
19481 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
19482 _ => "RAND",
19483 };
19484 self.write_keyword(func_name);
19485 self.write("(");
19486 if !matches!(
19488 self.config.dialect,
19489 Some(crate::dialects::DialectType::DuckDB)
19490 ) {
19491 if let Some(ref seed) = f.seed {
19492 self.generate_expression(seed)?;
19493 }
19494 }
19495 self.write(")");
19496 Ok(())
19497 }
19498
19499 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
19500 self.write_keyword("TRUNCATE");
19501 self.write("(");
19502 self.generate_expression(&f.this)?;
19503 if let Some(ref decimals) = f.decimals {
19504 self.write(", ");
19505 self.generate_expression(decimals)?;
19506 }
19507 self.write(")");
19508 Ok(())
19509 }
19510
19511 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
19514 self.write_keyword("DECODE");
19515 self.write("(");
19516 self.generate_expression(&f.this)?;
19517 for (search, result) in &f.search_results {
19518 self.write(", ");
19519 self.generate_expression(search)?;
19520 self.write(", ");
19521 self.generate_expression(result)?;
19522 }
19523 if let Some(ref default) = f.default {
19524 self.write(", ");
19525 self.generate_expression(default)?;
19526 }
19527 self.write(")");
19528 Ok(())
19529 }
19530
19531 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
19534 self.write_keyword(name);
19535 self.write("(");
19536 self.generate_expression(&f.this)?;
19537 self.write(", ");
19538 self.generate_expression(&f.format)?;
19539 self.write(")");
19540 Ok(())
19541 }
19542
19543 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
19544 self.write_keyword("FROM_UNIXTIME");
19545 self.write("(");
19546 self.generate_expression(&f.this)?;
19547 if let Some(ref format) = f.format {
19548 self.write(", ");
19549 self.generate_expression(format)?;
19550 }
19551 self.write(")");
19552 Ok(())
19553 }
19554
19555 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
19556 self.write_keyword("UNIX_TIMESTAMP");
19557 self.write("(");
19558 if let Some(ref expr) = f.this {
19559 self.generate_expression(expr)?;
19560 if let Some(ref format) = f.format {
19561 self.write(", ");
19562 self.generate_expression(format)?;
19563 }
19564 } else if matches!(
19565 self.config.dialect,
19566 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
19567 ) {
19568 self.write_keyword("CURRENT_TIMESTAMP");
19570 self.write("()");
19571 }
19572 self.write(")");
19573 Ok(())
19574 }
19575
19576 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
19577 self.write_keyword("MAKE_DATE");
19578 self.write("(");
19579 self.generate_expression(&f.year)?;
19580 self.write(", ");
19581 self.generate_expression(&f.month)?;
19582 self.write(", ");
19583 self.generate_expression(&f.day)?;
19584 self.write(")");
19585 Ok(())
19586 }
19587
19588 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
19589 self.write_keyword("MAKE_TIMESTAMP");
19590 self.write("(");
19591 self.generate_expression(&f.year)?;
19592 self.write(", ");
19593 self.generate_expression(&f.month)?;
19594 self.write(", ");
19595 self.generate_expression(&f.day)?;
19596 self.write(", ");
19597 self.generate_expression(&f.hour)?;
19598 self.write(", ");
19599 self.generate_expression(&f.minute)?;
19600 self.write(", ");
19601 self.generate_expression(&f.second)?;
19602 if let Some(ref tz) = f.timezone {
19603 self.write(", ");
19604 self.generate_expression(tz)?;
19605 }
19606 self.write(")");
19607 Ok(())
19608 }
19609
19610 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
19612 match expr {
19613 Expression::Struct(s) => {
19614 if s.fields.iter().all(|(name, _)| name.is_some()) {
19615 Some(
19616 s.fields
19617 .iter()
19618 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
19619 .collect(),
19620 )
19621 } else {
19622 None
19623 }
19624 }
19625 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
19626 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
19628 Some(
19629 f.args
19630 .iter()
19631 .filter_map(|a| {
19632 if let Expression::Alias(alias) = a {
19633 Some(alias.alias.name.clone())
19634 } else {
19635 None
19636 }
19637 })
19638 .collect(),
19639 )
19640 } else {
19641 None
19642 }
19643 }
19644 _ => None,
19645 }
19646 }
19647
19648 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
19650 match expr {
19651 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
19652 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
19653 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
19654 }
19655 _ => false,
19656 }
19657 }
19658
19659 fn struct_field_count(expr: &Expression) -> usize {
19661 match expr {
19662 Expression::Struct(s) => s.fields.len(),
19663 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => f.args.len(),
19664 _ => 0,
19665 }
19666 }
19667
19668 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
19670 match expr {
19671 Expression::Struct(s) => {
19672 let mut new_fields = Vec::with_capacity(s.fields.len());
19673 for (i, (name, value)) in s.fields.iter().enumerate() {
19674 if name.is_none() && i < field_names.len() {
19675 new_fields.push((Some(field_names[i].clone()), value.clone()));
19676 } else {
19677 new_fields.push((name.clone(), value.clone()));
19678 }
19679 }
19680 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
19681 }
19682 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
19683 let mut new_args = Vec::with_capacity(f.args.len());
19684 for (i, arg) in f.args.iter().enumerate() {
19685 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
19686 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
19688 this: arg.clone(),
19689 alias: crate::expressions::Identifier::new(field_names[i].clone()),
19690 column_aliases: Vec::new(),
19691 pre_alias_comments: Vec::new(),
19692 trailing_comments: Vec::new(),
19693 inferred_type: None,
19694 })));
19695 } else {
19696 new_args.push(arg.clone());
19697 }
19698 }
19699 Expression::Function(Box::new(crate::expressions::Function {
19700 name: f.name.clone(),
19701 args: new_args,
19702 distinct: f.distinct,
19703 trailing_comments: f.trailing_comments.clone(),
19704 use_bracket_syntax: f.use_bracket_syntax,
19705 no_parens: f.no_parens,
19706 quoted: f.quoted,
19707 span: None,
19708 inferred_type: None,
19709 }))
19710 }
19711 _ => expr.clone(),
19712 }
19713 }
19714
19715 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
19719 let first = match expressions.first() {
19720 Some(e) => e,
19721 None => return expressions.to_vec(),
19722 };
19723
19724 let field_names = match Self::extract_struct_field_names(first) {
19725 Some(names) if !names.is_empty() => names,
19726 _ => return expressions.to_vec(),
19727 };
19728
19729 let mut result = Vec::with_capacity(expressions.len());
19730 for (idx, expr) in expressions.iter().enumerate() {
19731 if idx == 0 {
19732 result.push(expr.clone());
19733 continue;
19734 }
19735 if Self::struct_field_count(expr) == field_names.len()
19737 && Self::struct_has_unnamed_fields(expr)
19738 {
19739 result.push(Self::apply_struct_field_names(expr, &field_names));
19740 } else {
19741 result.push(expr.clone());
19742 }
19743 }
19744 result
19745 }
19746
19747 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
19750 let needs_inheritance = matches!(
19753 self.config.dialect,
19754 Some(DialectType::DuckDB)
19755 | Some(DialectType::Spark)
19756 | Some(DialectType::Databricks)
19757 | Some(DialectType::Hive)
19758 | Some(DialectType::Snowflake)
19759 | Some(DialectType::Presto)
19760 | Some(DialectType::Trino)
19761 );
19762 let propagated: Vec<Expression>;
19763 let expressions = if needs_inheritance && f.expressions.len() > 1 {
19764 propagated = Self::inherit_struct_field_names(&f.expressions);
19765 &propagated
19766 } else {
19767 &f.expressions
19768 };
19769
19770 let should_split = if self.config.pretty && !expressions.is_empty() {
19772 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
19773 for expr in expressions {
19774 let mut temp_gen = Generator::with_arc_config(self.config.clone());
19775 Arc::make_mut(&mut temp_gen.config).pretty = false;
19776 temp_gen.generate_expression(expr)?;
19777 expr_strings.push(temp_gen.output);
19778 }
19779 self.too_wide(&expr_strings)
19780 } else {
19781 false
19782 };
19783
19784 if f.bracket_notation {
19785 let (open, close) = match self.config.dialect {
19789 None
19790 | Some(DialectType::Generic)
19791 | Some(DialectType::Spark)
19792 | Some(DialectType::Databricks)
19793 | Some(DialectType::Hive) => {
19794 self.write_keyword("ARRAY");
19795 ("(", ")")
19796 }
19797 Some(DialectType::Presto)
19798 | Some(DialectType::Trino)
19799 | Some(DialectType::PostgreSQL)
19800 | Some(DialectType::Redshift)
19801 | Some(DialectType::Materialize)
19802 | Some(DialectType::RisingWave)
19803 | Some(DialectType::CockroachDB) => {
19804 self.write_keyword("ARRAY");
19805 ("[", "]")
19806 }
19807 _ => ("[", "]"),
19808 };
19809 self.write(open);
19810 if should_split {
19811 self.write_newline();
19812 self.indent_level += 1;
19813 for (i, expr) in expressions.iter().enumerate() {
19814 self.write_indent();
19815 self.generate_expression(expr)?;
19816 if i + 1 < expressions.len() {
19817 self.write(",");
19818 }
19819 self.write_newline();
19820 }
19821 self.indent_level -= 1;
19822 self.write_indent();
19823 } else {
19824 for (i, expr) in expressions.iter().enumerate() {
19825 if i > 0 {
19826 self.write(", ");
19827 }
19828 self.generate_expression(expr)?;
19829 }
19830 }
19831 self.write(close);
19832 } else {
19833 if f.use_list_keyword {
19835 self.write_keyword("LIST");
19836 } else {
19837 self.write_keyword("ARRAY");
19838 }
19839 let has_subquery = expressions
19842 .iter()
19843 .any(|e| matches!(e, Expression::Select(_)));
19844 let (open, close) = if matches!(
19845 self.config.dialect,
19846 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
19847 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
19848 && has_subquery)
19849 {
19850 ("(", ")")
19851 } else {
19852 ("[", "]")
19853 };
19854 self.write(open);
19855 if should_split {
19856 self.write_newline();
19857 self.indent_level += 1;
19858 for (i, expr) in expressions.iter().enumerate() {
19859 self.write_indent();
19860 self.generate_expression(expr)?;
19861 if i + 1 < expressions.len() {
19862 self.write(",");
19863 }
19864 self.write_newline();
19865 }
19866 self.indent_level -= 1;
19867 self.write_indent();
19868 } else {
19869 for (i, expr) in expressions.iter().enumerate() {
19870 if i > 0 {
19871 self.write(", ");
19872 }
19873 self.generate_expression(expr)?;
19874 }
19875 }
19876 self.write(close);
19877 }
19878 Ok(())
19879 }
19880
19881 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
19882 self.write_keyword("ARRAY_SORT");
19883 self.write("(");
19884 self.generate_expression(&f.this)?;
19885 if let Some(ref comp) = f.comparator {
19886 self.write(", ");
19887 self.generate_expression(comp)?;
19888 }
19889 self.write(")");
19890 Ok(())
19891 }
19892
19893 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
19894 self.write_keyword(name);
19895 self.write("(");
19896 self.generate_expression(&f.this)?;
19897 self.write(", ");
19898 self.generate_expression(&f.separator)?;
19899 if let Some(ref null_rep) = f.null_replacement {
19900 self.write(", ");
19901 self.generate_expression(null_rep)?;
19902 }
19903 self.write(")");
19904 Ok(())
19905 }
19906
19907 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
19908 self.write_keyword("UNNEST");
19909 self.write("(");
19910 self.generate_expression(&f.this)?;
19911 for extra in &f.expressions {
19912 self.write(", ");
19913 self.generate_expression(extra)?;
19914 }
19915 self.write(")");
19916 if f.with_ordinality {
19917 self.write_space();
19918 if self.config.unnest_with_ordinality {
19919 self.write_keyword("WITH ORDINALITY");
19921 } else if f.offset_alias.is_some() {
19922 if let Some(ref alias) = f.alias {
19925 self.write_keyword("AS");
19926 self.write_space();
19927 self.generate_identifier(alias)?;
19928 self.write_space();
19929 }
19930 self.write_keyword("WITH OFFSET");
19931 if let Some(ref offset_alias) = f.offset_alias {
19932 self.write_space();
19933 self.write_keyword("AS");
19934 self.write_space();
19935 self.generate_identifier(offset_alias)?;
19936 }
19937 } else {
19938 self.write_keyword("WITH OFFSET");
19940 if f.alias.is_none() {
19941 self.write(" AS offset");
19942 }
19943 }
19944 }
19945 if let Some(ref alias) = f.alias {
19946 let should_add_alias = if !f.with_ordinality {
19948 true
19949 } else if self.config.unnest_with_ordinality {
19950 true
19952 } else if f.offset_alias.is_some() {
19953 false
19955 } else {
19956 true
19958 };
19959 if should_add_alias {
19960 self.write_space();
19961 self.write_keyword("AS");
19962 self.write_space();
19963 self.generate_identifier(alias)?;
19964 }
19965 }
19966 Ok(())
19967 }
19968
19969 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
19970 self.write_keyword("FILTER");
19971 self.write("(");
19972 self.generate_expression(&f.this)?;
19973 self.write(", ");
19974 self.generate_expression(&f.filter)?;
19975 self.write(")");
19976 Ok(())
19977 }
19978
19979 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
19980 self.write_keyword("TRANSFORM");
19981 self.write("(");
19982 self.generate_expression(&f.this)?;
19983 self.write(", ");
19984 self.generate_expression(&f.transform)?;
19985 self.write(")");
19986 Ok(())
19987 }
19988
19989 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
19990 self.write_keyword(name);
19991 self.write("(");
19992 self.generate_expression(&f.start)?;
19993 self.write(", ");
19994 self.generate_expression(&f.stop)?;
19995 if let Some(ref step) = f.step {
19996 self.write(", ");
19997 self.generate_expression(step)?;
19998 }
19999 self.write(")");
20000 Ok(())
20001 }
20002
20003 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
20006 self.write_keyword("STRUCT");
20007 self.write("(");
20008 for (i, (name, expr)) in f.fields.iter().enumerate() {
20009 if i > 0 {
20010 self.write(", ");
20011 }
20012 if let Some(ref id) = name {
20013 self.generate_identifier(id)?;
20014 self.write(" ");
20015 self.write_keyword("AS");
20016 self.write(" ");
20017 }
20018 self.generate_expression(expr)?;
20019 }
20020 self.write(")");
20021 Ok(())
20022 }
20023
20024 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
20026 let mut names: Vec<Option<String>> = Vec::new();
20029 let mut values: Vec<&Expression> = Vec::new();
20030 let mut all_named = true;
20031
20032 for arg in &func.args {
20033 match arg {
20034 Expression::Alias(a) => {
20035 names.push(Some(a.alias.name.clone()));
20036 values.push(&a.this);
20037 }
20038 _ => {
20039 names.push(None);
20040 values.push(arg);
20041 all_named = false;
20042 }
20043 }
20044 }
20045
20046 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
20047 self.write("{");
20049 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20050 if i > 0 {
20051 self.write(", ");
20052 }
20053 if let Some(n) = name {
20054 self.write("'");
20055 self.write(n);
20056 self.write("'");
20057 } else {
20058 self.write("'_");
20059 self.write(&i.to_string());
20060 self.write("'");
20061 }
20062 self.write(": ");
20063 self.generate_expression(value)?;
20064 }
20065 self.write("}");
20066 return Ok(());
20067 }
20068
20069 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
20070 self.write_keyword("OBJECT_CONSTRUCT");
20072 self.write("(");
20073 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20074 if i > 0 {
20075 self.write(", ");
20076 }
20077 if let Some(n) = name {
20078 self.write("'");
20079 self.write(n);
20080 self.write("'");
20081 } else {
20082 self.write("'_");
20083 self.write(&i.to_string());
20084 self.write("'");
20085 }
20086 self.write(", ");
20087 self.generate_expression(value)?;
20088 }
20089 self.write(")");
20090 return Ok(());
20091 }
20092
20093 if matches!(
20094 self.config.dialect,
20095 Some(DialectType::Presto) | Some(DialectType::Trino)
20096 ) {
20097 if all_named && !names.is_empty() {
20098 self.write_keyword("CAST");
20101 self.write("(");
20102 self.write_keyword("ROW");
20103 self.write("(");
20104 for (i, value) in values.iter().enumerate() {
20105 if i > 0 {
20106 self.write(", ");
20107 }
20108 self.generate_expression(value)?;
20109 }
20110 self.write(")");
20111 self.write(" ");
20112 self.write_keyword("AS");
20113 self.write(" ");
20114 self.write_keyword("ROW");
20115 self.write("(");
20116 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20117 if i > 0 {
20118 self.write(", ");
20119 }
20120 if let Some(n) = name {
20121 self.write(n);
20122 }
20123 self.write(" ");
20124 let type_str = Self::infer_sql_type_for_presto(value);
20125 self.write_keyword(&type_str);
20126 }
20127 self.write(")");
20128 self.write(")");
20129 } else {
20130 self.write_keyword("ROW");
20132 self.write("(");
20133 for (i, value) in values.iter().enumerate() {
20134 if i > 0 {
20135 self.write(", ");
20136 }
20137 self.generate_expression(value)?;
20138 }
20139 self.write(")");
20140 }
20141 return Ok(());
20142 }
20143
20144 self.write_keyword("ROW");
20146 self.write("(");
20147 for (i, value) in values.iter().enumerate() {
20148 if i > 0 {
20149 self.write(", ");
20150 }
20151 self.generate_expression(value)?;
20152 }
20153 self.write(")");
20154 Ok(())
20155 }
20156
20157 fn infer_sql_type_for_presto(expr: &Expression) -> String {
20159 match expr {
20160 Expression::Literal(lit) if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) => "VARCHAR".to_string(),
20161 Expression::Literal(lit) if matches!(lit.as_ref(), crate::expressions::Literal::Number(_)) => {
20162 let crate::expressions::Literal::Number(n) = lit.as_ref() else { unreachable!() };
20163 if n.contains('.') {
20164 "DOUBLE".to_string()
20165 } else {
20166 "INTEGER".to_string()
20167 }
20168 }
20169 Expression::Boolean(_) => "BOOLEAN".to_string(),
20170 Expression::Literal(lit) if matches!(lit.as_ref(), crate::expressions::Literal::Date(_)) => "DATE".to_string(),
20171 Expression::Literal(lit) if matches!(lit.as_ref(), crate::expressions::Literal::Timestamp(_)) => {
20172 "TIMESTAMP".to_string()
20173 }
20174 Expression::Literal(lit) if matches!(lit.as_ref(), crate::expressions::Literal::Datetime(_)) => {
20175 "TIMESTAMP".to_string()
20176 }
20177 Expression::Array(_) | Expression::ArrayFunc(_) => {
20178 "ARRAY(VARCHAR)".to_string()
20180 }
20181 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
20183 Expression::Function(f) => {
20184 if f.name.eq_ignore_ascii_case("STRUCT") {
20185 "ROW".to_string()
20186 } else if f.name.eq_ignore_ascii_case("CURRENT_DATE") {
20187 "DATE".to_string()
20188 } else if f.name.eq_ignore_ascii_case("CURRENT_TIMESTAMP") || f.name.eq_ignore_ascii_case("NOW") {
20189 "TIMESTAMP".to_string()
20190 } else {
20191 "VARCHAR".to_string()
20192 }
20193 }
20194 _ => "VARCHAR".to_string(),
20195 }
20196 }
20197
20198 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
20199 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
20201 self.write_keyword("STRUCT_EXTRACT");
20202 self.write("(");
20203 self.generate_expression(&f.this)?;
20204 self.write(", ");
20205 self.write("'");
20207 self.write(&f.field.name);
20208 self.write("'");
20209 self.write(")");
20210 return Ok(());
20211 }
20212 self.generate_expression(&f.this)?;
20213 self.write(".");
20214 self.generate_identifier(&f.field)
20215 }
20216
20217 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
20218 self.write_keyword("NAMED_STRUCT");
20219 self.write("(");
20220 for (i, (name, value)) in f.pairs.iter().enumerate() {
20221 if i > 0 {
20222 self.write(", ");
20223 }
20224 self.generate_expression(name)?;
20225 self.write(", ");
20226 self.generate_expression(value)?;
20227 }
20228 self.write(")");
20229 Ok(())
20230 }
20231
20232 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
20235 if f.curly_brace_syntax {
20236 if f.with_map_keyword {
20238 self.write_keyword("MAP");
20239 self.write(" ");
20240 }
20241 self.write("{");
20242 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
20243 if i > 0 {
20244 self.write(", ");
20245 }
20246 self.generate_expression(key)?;
20247 self.write(": ");
20248 self.generate_expression(val)?;
20249 }
20250 self.write("}");
20251 } else {
20252 self.write_keyword("MAP");
20254 self.write("(");
20255 self.write_keyword("ARRAY");
20256 self.write("[");
20257 for (i, key) in f.keys.iter().enumerate() {
20258 if i > 0 {
20259 self.write(", ");
20260 }
20261 self.generate_expression(key)?;
20262 }
20263 self.write("], ");
20264 self.write_keyword("ARRAY");
20265 self.write("[");
20266 for (i, val) in f.values.iter().enumerate() {
20267 if i > 0 {
20268 self.write(", ");
20269 }
20270 self.generate_expression(val)?;
20271 }
20272 self.write("])");
20273 }
20274 Ok(())
20275 }
20276
20277 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
20278 self.write_keyword(name);
20279 self.write("(");
20280 self.generate_expression(&f.this)?;
20281 self.write(", ");
20282 self.generate_expression(&f.transform)?;
20283 self.write(")");
20284 Ok(())
20285 }
20286
20287 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
20290 use crate::dialects::DialectType;
20291
20292 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
20294
20295 if use_arrow {
20296 self.generate_expression(&f.this)?;
20298 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
20299 self.write(" ->> ");
20300 } else {
20301 self.write(" -> ");
20302 }
20303 self.generate_expression(&f.path)?;
20304 return Ok(());
20305 }
20306
20307 if f.hash_arrow_syntax
20309 && matches!(
20310 self.config.dialect,
20311 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
20312 )
20313 {
20314 self.generate_expression(&f.this)?;
20315 self.write(" #>> ");
20316 self.generate_expression(&f.path)?;
20317 return Ok(());
20318 }
20319
20320 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
20323 match name {
20324 "JSON_EXTRACT_SCALAR"
20325 | "JSON_EXTRACT_PATH_TEXT"
20326 | "JSON_EXTRACT"
20327 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
20328 _ => name,
20329 }
20330 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
20331 match name {
20332 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
20333 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
20334 _ => name,
20335 }
20336 } else {
20337 name
20338 };
20339
20340 self.write_keyword(func_name);
20341 self.write("(");
20342 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
20344 if let Expression::Cast(ref cast) = f.this {
20345 if matches!(cast.to, crate::expressions::DataType::Json) {
20346 self.generate_expression(&cast.this)?;
20347 } else {
20348 self.generate_expression(&f.this)?;
20349 }
20350 } else {
20351 self.generate_expression(&f.this)?;
20352 }
20353 } else {
20354 self.generate_expression(&f.this)?;
20355 }
20356 if matches!(
20359 self.config.dialect,
20360 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
20361 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
20362 {
20363 if let Expression::Literal(ref lit) = f.path {
20364 if let Literal::String(ref s) = lit.as_ref() {
20365 let parts = Self::decompose_json_path(s);
20366 for part in &parts {
20367 self.write(", '");
20368 self.write(part);
20369 self.write("'");
20370 }
20371 }
20372 } else {
20373 self.write(", ");
20374 self.generate_expression(&f.path)?;
20375 }
20376 } else {
20377 self.write(", ");
20378 self.generate_expression(&f.path)?;
20379 }
20380
20381 if let Some(ref wrapper) = f.wrapper_option {
20384 self.write_space();
20385 self.write_keyword(wrapper);
20386 }
20387 if let Some(ref quotes) = f.quotes_option {
20388 self.write_space();
20389 self.write_keyword(quotes);
20390 if f.on_scalar_string {
20391 self.write_space();
20392 self.write_keyword("ON SCALAR STRING");
20393 }
20394 }
20395 if let Some(ref on_err) = f.on_error {
20396 self.write_space();
20397 self.write_keyword(on_err);
20398 }
20399 if let Some(ref ret_type) = f.returning {
20400 self.write_space();
20401 self.write_keyword("RETURNING");
20402 self.write_space();
20403 self.generate_data_type(ret_type)?;
20404 }
20405
20406 self.write(")");
20407 Ok(())
20408 }
20409
20410 fn dialect_supports_json_arrow(&self) -> bool {
20412 use crate::dialects::DialectType;
20413 match self.config.dialect {
20414 Some(DialectType::PostgreSQL) => true,
20416 Some(DialectType::MySQL) => true,
20417 Some(DialectType::DuckDB) => true,
20418 Some(DialectType::CockroachDB) => true,
20419 Some(DialectType::StarRocks) => true,
20420 Some(DialectType::SQLite) => true,
20421 _ => false,
20423 }
20424 }
20425
20426 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
20427 use crate::dialects::DialectType;
20428
20429 if matches!(
20431 self.config.dialect,
20432 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
20433 ) && name == "JSON_EXTRACT_PATH"
20434 {
20435 self.generate_expression(&f.this)?;
20436 self.write(" #> ");
20437 if f.paths.len() == 1 {
20438 self.generate_expression(&f.paths[0])?;
20439 } else {
20440 self.write_keyword("ARRAY");
20442 self.write("[");
20443 for (i, path) in f.paths.iter().enumerate() {
20444 if i > 0 {
20445 self.write(", ");
20446 }
20447 self.generate_expression(path)?;
20448 }
20449 self.write("]");
20450 }
20451 return Ok(());
20452 }
20453
20454 self.write_keyword(name);
20455 self.write("(");
20456 self.generate_expression(&f.this)?;
20457 for path in &f.paths {
20458 self.write(", ");
20459 self.generate_expression(path)?;
20460 }
20461 self.write(")");
20462 Ok(())
20463 }
20464
20465 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
20466 use crate::dialects::DialectType;
20467
20468 self.write_keyword("JSON_OBJECT");
20469 self.write("(");
20470 if f.star {
20471 self.write("*");
20472 } else {
20473 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
20477 || matches!(
20478 self.config.dialect,
20479 Some(DialectType::BigQuery)
20480 | Some(DialectType::MySQL)
20481 | Some(DialectType::SQLite)
20482 );
20483
20484 for (i, (key, value)) in f.pairs.iter().enumerate() {
20485 if i > 0 {
20486 self.write(", ");
20487 }
20488 self.generate_expression(key)?;
20489 if use_comma_syntax {
20490 self.write(", ");
20491 } else {
20492 self.write(": ");
20493 }
20494 self.generate_expression(value)?;
20495 }
20496 }
20497 if let Some(null_handling) = f.null_handling {
20498 self.write_space();
20499 match null_handling {
20500 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
20501 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
20502 }
20503 }
20504 if f.with_unique_keys {
20505 self.write_space();
20506 self.write_keyword("WITH UNIQUE KEYS");
20507 }
20508 if let Some(ref ret_type) = f.returning_type {
20509 self.write_space();
20510 self.write_keyword("RETURNING");
20511 self.write_space();
20512 self.generate_data_type(ret_type)?;
20513 if f.format_json {
20514 self.write_space();
20515 self.write_keyword("FORMAT JSON");
20516 }
20517 if let Some(ref enc) = f.encoding {
20518 self.write_space();
20519 self.write_keyword("ENCODING");
20520 self.write_space();
20521 self.write(enc);
20522 }
20523 }
20524 self.write(")");
20525 Ok(())
20526 }
20527
20528 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
20529 self.write_keyword(name);
20530 self.write("(");
20531 self.generate_expression(&f.this)?;
20532 for (path, value) in &f.path_values {
20533 self.write(", ");
20534 self.generate_expression(path)?;
20535 self.write(", ");
20536 self.generate_expression(value)?;
20537 }
20538 self.write(")");
20539 Ok(())
20540 }
20541
20542 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
20543 self.write_keyword("JSON_ARRAYAGG");
20544 self.write("(");
20545 self.generate_expression(&f.this)?;
20546 if let Some(ref order_by) = f.order_by {
20547 self.write_space();
20548 self.write_keyword("ORDER BY");
20549 self.write_space();
20550 for (i, ord) in order_by.iter().enumerate() {
20551 if i > 0 {
20552 self.write(", ");
20553 }
20554 self.generate_ordered(ord)?;
20555 }
20556 }
20557 if let Some(null_handling) = f.null_handling {
20558 self.write_space();
20559 match null_handling {
20560 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
20561 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
20562 }
20563 }
20564 self.write(")");
20565 if let Some(ref filter) = f.filter {
20566 self.write_space();
20567 self.write_keyword("FILTER");
20568 self.write("(");
20569 self.write_keyword("WHERE");
20570 self.write_space();
20571 self.generate_expression(filter)?;
20572 self.write(")");
20573 }
20574 Ok(())
20575 }
20576
20577 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
20578 self.write_keyword("JSON_OBJECTAGG");
20579 self.write("(");
20580 self.generate_expression(&f.key)?;
20581 self.write(": ");
20582 self.generate_expression(&f.value)?;
20583 if let Some(null_handling) = f.null_handling {
20584 self.write_space();
20585 match null_handling {
20586 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
20587 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
20588 }
20589 }
20590 self.write(")");
20591 if let Some(ref filter) = f.filter {
20592 self.write_space();
20593 self.write_keyword("FILTER");
20594 self.write("(");
20595 self.write_keyword("WHERE");
20596 self.write_space();
20597 self.generate_expression(filter)?;
20598 self.write(")");
20599 }
20600 Ok(())
20601 }
20602
20603 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
20606 use crate::dialects::DialectType;
20607
20608 if self.config.dialect == Some(DialectType::Redshift) {
20610 self.write_keyword("CAST");
20611 self.write("(");
20612 self.generate_expression(&f.this)?;
20613 self.write_space();
20614 self.write_keyword("AS");
20615 self.write_space();
20616 self.generate_data_type(&f.to)?;
20617 self.write(")");
20618 return Ok(());
20619 }
20620
20621 self.write_keyword("CONVERT");
20622 self.write("(");
20623 self.generate_data_type(&f.to)?;
20624 self.write(", ");
20625 self.generate_expression(&f.this)?;
20626 if let Some(ref style) = f.style {
20627 self.write(", ");
20628 self.generate_expression(style)?;
20629 }
20630 self.write(")");
20631 Ok(())
20632 }
20633
20634 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
20637 if f.colon {
20638 self.write_keyword("LAMBDA");
20640 self.write_space();
20641 for (i, param) in f.parameters.iter().enumerate() {
20642 if i > 0 {
20643 self.write(", ");
20644 }
20645 self.generate_identifier(param)?;
20646 }
20647 self.write(" : ");
20648 } else {
20649 if f.parameters.len() == 1 {
20651 self.generate_identifier(&f.parameters[0])?;
20652 } else {
20653 self.write("(");
20654 for (i, param) in f.parameters.iter().enumerate() {
20655 if i > 0 {
20656 self.write(", ");
20657 }
20658 self.generate_identifier(param)?;
20659 }
20660 self.write(")");
20661 }
20662 self.write(" -> ");
20663 }
20664 self.generate_expression(&f.body)
20665 }
20666
20667 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
20668 self.generate_identifier(&f.name)?;
20669 match f.separator {
20670 NamedArgSeparator::DArrow => self.write(" => "),
20671 NamedArgSeparator::ColonEq => self.write(" := "),
20672 NamedArgSeparator::Eq => self.write(" = "),
20673 }
20674 self.generate_expression(&f.value)
20675 }
20676
20677 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
20678 self.write_keyword(&f.prefix);
20679 self.write(" ");
20680 self.generate_expression(&f.this)
20681 }
20682
20683 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
20684 match f.style {
20685 ParameterStyle::Question => self.write("?"),
20686 ParameterStyle::Dollar => {
20687 self.write("$");
20688 if let Some(idx) = f.index {
20689 self.write(&idx.to_string());
20690 } else if let Some(ref name) = f.name {
20691 self.write(name);
20693 }
20694 }
20695 ParameterStyle::DollarBrace => {
20696 self.write("${");
20698 if let Some(ref name) = f.name {
20699 self.write(name);
20700 }
20701 if let Some(ref expr) = f.expression {
20702 self.write(":");
20703 self.write(expr);
20704 }
20705 self.write("}");
20706 }
20707 ParameterStyle::Colon => {
20708 self.write(":");
20709 if let Some(idx) = f.index {
20710 self.write(&idx.to_string());
20711 } else if let Some(ref name) = f.name {
20712 self.write(name);
20713 }
20714 }
20715 ParameterStyle::At => {
20716 self.write("@");
20717 if let Some(ref name) = f.name {
20718 if f.string_quoted {
20719 self.write("'");
20720 self.write(name);
20721 self.write("'");
20722 } else if f.quoted {
20723 self.write("\"");
20724 self.write(name);
20725 self.write("\"");
20726 } else {
20727 self.write(name);
20728 }
20729 }
20730 }
20731 ParameterStyle::DoubleAt => {
20732 self.write("@@");
20733 if let Some(ref name) = f.name {
20734 self.write(name);
20735 }
20736 }
20737 ParameterStyle::DoubleDollar => {
20738 self.write("$$");
20739 if let Some(ref name) = f.name {
20740 self.write(name);
20741 }
20742 }
20743 ParameterStyle::Percent => {
20744 if let Some(ref name) = f.name {
20745 self.write("%(");
20747 self.write(name);
20748 self.write(")s");
20749 } else {
20750 self.write("%s");
20752 }
20753 }
20754 ParameterStyle::Brace => {
20755 self.write("{");
20758 if let Some(ref name) = f.name {
20759 self.write(name);
20760 }
20761 if let Some(ref expr) = f.expression {
20762 self.write(": ");
20763 self.write(expr);
20764 }
20765 self.write("}");
20766 }
20767 }
20768 Ok(())
20769 }
20770
20771 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
20772 self.write("?");
20773 if let Some(idx) = f.index {
20774 self.write(&idx.to_string());
20775 }
20776 Ok(())
20777 }
20778
20779 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
20780 if f.is_block {
20781 self.write("/*");
20782 self.write(&f.text);
20783 self.write("*/");
20784 } else {
20785 self.write("--");
20786 self.write(&f.text);
20787 }
20788 Ok(())
20789 }
20790
20791 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
20794 self.generate_expression(&f.this)?;
20795 if f.not {
20796 self.write_space();
20797 self.write_keyword("NOT");
20798 }
20799 self.write_space();
20800 self.write_keyword("SIMILAR TO");
20801 self.write_space();
20802 self.generate_expression(&f.pattern)?;
20803 if let Some(ref escape) = f.escape {
20804 self.write_space();
20805 self.write_keyword("ESCAPE");
20806 self.write_space();
20807 self.generate_expression(escape)?;
20808 }
20809 Ok(())
20810 }
20811
20812 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
20813 self.generate_expression(&f.this)?;
20814 self.write_space();
20815 if let Some(op) = &f.op {
20817 match op {
20818 QuantifiedOp::Eq => self.write("="),
20819 QuantifiedOp::Neq => self.write("<>"),
20820 QuantifiedOp::Lt => self.write("<"),
20821 QuantifiedOp::Lte => self.write("<="),
20822 QuantifiedOp::Gt => self.write(">"),
20823 QuantifiedOp::Gte => self.write(">="),
20824 }
20825 self.write_space();
20826 }
20827 self.write_keyword(name);
20828
20829 if matches!(&f.subquery, Expression::Subquery(_)) {
20831 self.write_space();
20832 self.generate_expression(&f.subquery)?;
20833 } else {
20834 self.write("(");
20835
20836 let is_statement = matches!(
20837 &f.subquery,
20838 Expression::Select(_)
20839 | Expression::Union(_)
20840 | Expression::Intersect(_)
20841 | Expression::Except(_)
20842 );
20843
20844 if self.config.pretty && is_statement {
20845 self.write_newline();
20846 self.indent_level += 1;
20847 self.write_indent();
20848 }
20849 self.generate_expression(&f.subquery)?;
20850 if self.config.pretty && is_statement {
20851 self.write_newline();
20852 self.indent_level -= 1;
20853 self.write_indent();
20854 }
20855 self.write(")");
20856 }
20857 Ok(())
20858 }
20859
20860 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
20861 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
20863 self.generate_expression(this)?;
20864 self.write_space();
20865 self.write_keyword("OVERLAPS");
20866 self.write_space();
20867 self.generate_expression(expr)?;
20868 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
20869 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
20870 {
20871 self.write("(");
20873 self.generate_expression(ls)?;
20874 self.write(", ");
20875 self.generate_expression(le)?;
20876 self.write(")");
20877 self.write_space();
20878 self.write_keyword("OVERLAPS");
20879 self.write_space();
20880 self.write("(");
20881 self.generate_expression(rs)?;
20882 self.write(", ");
20883 self.generate_expression(re)?;
20884 self.write(")");
20885 }
20886 Ok(())
20887 }
20888
20889 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
20892 use crate::dialects::DialectType;
20893
20894 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
20896 self.generate_expression(&cast.this)?;
20897 self.write(" !:> ");
20898 self.generate_data_type(&cast.to)?;
20899 return Ok(());
20900 }
20901
20902 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
20904 self.write_keyword("TRYCAST");
20905 self.write("(");
20906 self.generate_expression(&cast.this)?;
20907 self.write_space();
20908 self.write_keyword("AS");
20909 self.write_space();
20910 self.generate_data_type(&cast.to)?;
20911 self.write(")");
20912 return Ok(());
20913 }
20914
20915 let keyword = if matches!(
20917 self.config.dialect,
20918 Some(DialectType::Hive)
20919 | Some(DialectType::MySQL)
20920 | Some(DialectType::SQLite)
20921 | Some(DialectType::Oracle)
20922 | Some(DialectType::ClickHouse)
20923 | Some(DialectType::Redshift)
20924 | Some(DialectType::PostgreSQL)
20925 | Some(DialectType::StarRocks)
20926 | Some(DialectType::Doris)
20927 ) {
20928 "CAST"
20929 } else {
20930 "TRY_CAST"
20931 };
20932
20933 self.write_keyword(keyword);
20934 self.write("(");
20935 self.generate_expression(&cast.this)?;
20936 self.write_space();
20937 self.write_keyword("AS");
20938 self.write_space();
20939 self.generate_data_type(&cast.to)?;
20940
20941 if let Some(format) = &cast.format {
20943 self.write_space();
20944 self.write_keyword("FORMAT");
20945 self.write_space();
20946 self.generate_expression(format)?;
20947 }
20948
20949 self.write(")");
20950 Ok(())
20951 }
20952
20953 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
20954 self.write_keyword("SAFE_CAST");
20955 self.write("(");
20956 self.generate_expression(&cast.this)?;
20957 self.write_space();
20958 self.write_keyword("AS");
20959 self.write_space();
20960 self.generate_data_type(&cast.to)?;
20961
20962 if let Some(format) = &cast.format {
20964 self.write_space();
20965 self.write_keyword("FORMAT");
20966 self.write_space();
20967 self.generate_expression(format)?;
20968 }
20969
20970 self.write(")");
20971 Ok(())
20972 }
20973
20974 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
20977 let needs_parens = matches!(&s.this, Expression::JsonExtract(ref f) if f.arrow_syntax);
20981 if needs_parens {
20982 self.write("(");
20983 }
20984 self.generate_expression(&s.this)?;
20985 if needs_parens {
20986 self.write(")");
20987 }
20988 self.write("[");
20989 self.generate_expression(&s.index)?;
20990 self.write("]");
20991 Ok(())
20992 }
20993
20994 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
20995 self.generate_expression(&d.this)?;
20996 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
20999 && matches!(
21000 &d.this,
21001 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
21002 );
21003 if use_colon {
21004 self.write(":");
21005 } else {
21006 self.write(".");
21007 }
21008 self.generate_identifier(&d.field)
21009 }
21010
21011 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
21012 self.generate_expression(&m.this)?;
21013 self.write(".");
21014 if m.method.quoted {
21017 let q = self.config.identifier_quote;
21018 self.write(&format!("{}{}{}", q, m.method.name, q));
21019 } else {
21020 self.write(&m.method.name);
21021 }
21022 self.write("(");
21023 for (i, arg) in m.args.iter().enumerate() {
21024 if i > 0 {
21025 self.write(", ");
21026 }
21027 self.generate_expression(arg)?;
21028 }
21029 self.write(")");
21030 Ok(())
21031 }
21032
21033 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
21034 let needs_parens = matches!(
21037 &s.this,
21038 Expression::JsonExtract(f) if f.arrow_syntax
21039 ) || matches!(
21040 &s.this,
21041 Expression::JsonExtractScalar(f) if f.arrow_syntax
21042 );
21043
21044 if needs_parens {
21045 self.write("(");
21046 }
21047 self.generate_expression(&s.this)?;
21048 if needs_parens {
21049 self.write(")");
21050 }
21051 self.write("[");
21052 if let Some(start) = &s.start {
21053 self.generate_expression(start)?;
21054 }
21055 self.write(":");
21056 if let Some(end) = &s.end {
21057 self.generate_expression(end)?;
21058 }
21059 self.write("]");
21060 Ok(())
21061 }
21062
21063 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
21064 match &op.left {
21068 Expression::Column(col) => {
21069 if let Some(table) = &col.table {
21072 self.generate_identifier(table)?;
21073 self.write(".");
21074 }
21075 self.generate_identifier(&col.name)?;
21076 if col.join_mark && self.config.supports_column_join_marks {
21078 self.write(" (+)");
21079 }
21080 if op.left_comments.is_empty() {
21082 for comment in &col.trailing_comments {
21083 self.write_space();
21084 self.write_formatted_comment(comment);
21085 }
21086 }
21087 }
21088 Expression::Add(inner_op)
21089 | Expression::Sub(inner_op)
21090 | Expression::Mul(inner_op)
21091 | Expression::Div(inner_op)
21092 | Expression::Concat(inner_op) => {
21093 self.generate_binary_op_no_trailing(inner_op, match &op.left {
21095 Expression::Add(_) => "+",
21096 Expression::Sub(_) => "-",
21097 Expression::Mul(_) => "*",
21098 Expression::Div(_) => "/",
21099 Expression::Concat(_) => "||",
21100 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
21101 })?;
21102 }
21103 _ => {
21104 self.generate_expression(&op.left)?;
21105 }
21106 }
21107 for comment in &op.left_comments {
21109 self.write_space();
21110 self.write_formatted_comment(comment);
21111 }
21112 if self.config.pretty
21113 && matches!(self.config.dialect, Some(DialectType::Snowflake))
21114 && (operator == "AND" || operator == "OR")
21115 {
21116 self.write_newline();
21117 self.write_indent();
21118 self.write_keyword(operator);
21119 } else {
21120 self.write_space();
21121 if operator.chars().all(|c| c.is_alphabetic()) {
21122 self.write_keyword(operator);
21123 } else {
21124 self.write(operator);
21125 }
21126 }
21127 for comment in &op.operator_comments {
21129 self.write_space();
21130 self.write_formatted_comment(comment);
21131 }
21132 self.write_space();
21133 self.generate_expression(&op.right)?;
21134 for comment in &op.trailing_comments {
21136 self.write_space();
21137 self.write_formatted_comment(comment);
21138 }
21139 Ok(())
21140 }
21141
21142 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
21143 let keyword = connector.keyword();
21144 let Some(terms) = self.flatten_connector_terms(op, connector) else {
21145 return self.generate_binary_op(op, keyword);
21146 };
21147
21148 self.generate_expression(terms[0])?;
21149 for term in terms.iter().skip(1) {
21150 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
21151 self.write_newline();
21152 self.write_indent();
21153 self.write_keyword(keyword);
21154 } else {
21155 self.write_space();
21156 self.write_keyword(keyword);
21157 }
21158 self.write_space();
21159 self.generate_expression(term)?;
21160 }
21161
21162 Ok(())
21163 }
21164
21165 fn flatten_connector_terms<'a>(
21166 &self,
21167 root: &'a BinaryOp,
21168 connector: ConnectorOperator,
21169 ) -> Option<Vec<&'a Expression>> {
21170 if !root.left_comments.is_empty()
21171 || !root.operator_comments.is_empty()
21172 || !root.trailing_comments.is_empty()
21173 {
21174 return None;
21175 }
21176
21177 let mut terms = Vec::new();
21178 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
21179
21180 while let Some(expr) = stack.pop() {
21181 match (connector, expr) {
21182 (ConnectorOperator::And, Expression::And(inner))
21183 if inner.left_comments.is_empty()
21184 && inner.operator_comments.is_empty()
21185 && inner.trailing_comments.is_empty() =>
21186 {
21187 stack.push(&inner.right);
21188 stack.push(&inner.left);
21189 }
21190 (ConnectorOperator::Or, Expression::Or(inner))
21191 if inner.left_comments.is_empty()
21192 && inner.operator_comments.is_empty()
21193 && inner.trailing_comments.is_empty() =>
21194 {
21195 stack.push(&inner.right);
21196 stack.push(&inner.left);
21197 }
21198 _ => terms.push(expr),
21199 }
21200 }
21201
21202 if terms.len() > 1 {
21203 Some(terms)
21204 } else {
21205 None
21206 }
21207 }
21208
21209 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
21211 self.generate_expression(&op.left)?;
21212 self.write_space();
21213 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
21215 self.write("`ILIKE`");
21216 } else {
21217 self.write_keyword(operator);
21218 }
21219 if let Some(quantifier) = &op.quantifier {
21220 self.write_space();
21221 self.write_keyword(quantifier);
21222 }
21223 self.write_space();
21224 self.generate_expression(&op.right)?;
21225 if let Some(escape) = &op.escape {
21226 self.write_space();
21227 self.write_keyword("ESCAPE");
21228 self.write_space();
21229 self.generate_expression(escape)?;
21230 }
21231 Ok(())
21232 }
21233
21234 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
21237 use crate::dialects::DialectType;
21238 self.generate_expression(&op.left)?;
21239 self.write_space();
21240 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
21241 self.write("<=>");
21242 } else {
21243 self.write_keyword("IS NOT DISTINCT FROM");
21244 }
21245 self.write_space();
21246 self.generate_expression(&op.right)?;
21247 Ok(())
21248 }
21249
21250 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
21252 self.generate_expression(&op.left)?;
21253 self.write_space();
21254 self.write_keyword("IS DISTINCT FROM");
21255 self.write_space();
21256 self.generate_expression(&op.right)?;
21257 Ok(())
21258 }
21259
21260 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
21262 match &op.left {
21264 Expression::Column(col) => {
21265 if let Some(table) = &col.table {
21266 self.generate_identifier(table)?;
21267 self.write(".");
21268 }
21269 self.generate_identifier(&col.name)?;
21270 if col.join_mark && self.config.supports_column_join_marks {
21272 self.write(" (+)");
21273 }
21274 }
21275 Expression::Add(inner_op)
21276 | Expression::Sub(inner_op)
21277 | Expression::Mul(inner_op)
21278 | Expression::Div(inner_op)
21279 | Expression::Concat(inner_op) => {
21280 self.generate_binary_op_no_trailing(inner_op, match &op.left {
21281 Expression::Add(_) => "+",
21282 Expression::Sub(_) => "-",
21283 Expression::Mul(_) => "*",
21284 Expression::Div(_) => "/",
21285 Expression::Concat(_) => "||",
21286 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
21287 })?;
21288 }
21289 _ => {
21290 self.generate_expression(&op.left)?;
21291 }
21292 }
21293 for comment in &op.left_comments {
21295 self.write_space();
21296 self.write_formatted_comment(comment);
21297 }
21298 self.write_space();
21299 if operator.chars().all(|c| c.is_alphabetic()) {
21300 self.write_keyword(operator);
21301 } else {
21302 self.write(operator);
21303 }
21304 for comment in &op.operator_comments {
21306 self.write_space();
21307 self.write_formatted_comment(comment);
21308 }
21309 self.write_space();
21310 match &op.right {
21313 Expression::Column(col) => {
21314 if let Some(table) = &col.table {
21315 self.generate_identifier(table)?;
21316 self.write(".");
21317 }
21318 self.generate_identifier(&col.name)?;
21319 if col.join_mark && self.config.supports_column_join_marks {
21321 self.write(" (+)");
21322 }
21323 }
21324 _ => {
21325 self.generate_expression(&op.right)?;
21326 }
21327 }
21328 Ok(())
21330 }
21331
21332 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
21333 if operator.chars().all(|c| c.is_alphabetic()) {
21334 self.write_keyword(operator);
21335 self.write_space();
21336 } else {
21337 self.write(operator);
21338 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
21340 self.write_space();
21341 }
21342 }
21343 self.generate_expression(&op.this)
21344 }
21345
21346 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
21347 let is_generic =
21351 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
21352 let use_prefix_not =
21353 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
21354 if use_prefix_not {
21355 self.write_keyword("NOT");
21356 self.write_space();
21357 }
21358 self.generate_expression(&in_expr.this)?;
21359 if in_expr.global {
21360 self.write_space();
21361 self.write_keyword("GLOBAL");
21362 }
21363 if in_expr.not && !use_prefix_not {
21364 self.write_space();
21365 self.write_keyword("NOT");
21366 }
21367 self.write_space();
21368 self.write_keyword("IN");
21369
21370 if let Some(unnest_expr) = &in_expr.unnest {
21372 self.write_space();
21373 self.write_keyword("UNNEST");
21374 self.write("(");
21375 self.generate_expression(unnest_expr)?;
21376 self.write(")");
21377 return Ok(());
21378 }
21379
21380 if let Some(query) = &in_expr.query {
21381 let is_bare = in_expr.expressions.is_empty()
21384 && !matches!(
21385 query,
21386 Expression::Select(_)
21387 | Expression::Union(_)
21388 | Expression::Intersect(_)
21389 | Expression::Except(_)
21390 | Expression::Subquery(_)
21391 );
21392 if is_bare {
21393 self.write_space();
21395 self.generate_expression(query)?;
21396 } else {
21397 self.write(" (");
21399 let is_statement = matches!(
21400 query,
21401 Expression::Select(_)
21402 | Expression::Union(_)
21403 | Expression::Intersect(_)
21404 | Expression::Except(_)
21405 | Expression::Subquery(_)
21406 );
21407 if self.config.pretty && is_statement {
21408 self.write_newline();
21409 self.indent_level += 1;
21410 self.write_indent();
21411 }
21412 self.generate_expression(query)?;
21413 if self.config.pretty && is_statement {
21414 self.write_newline();
21415 self.indent_level -= 1;
21416 self.write_indent();
21417 }
21418 self.write(")");
21419 }
21420 } else {
21421 let is_duckdb = matches!(
21425 self.config.dialect,
21426 Some(crate::dialects::DialectType::DuckDB)
21427 );
21428 let is_clickhouse = matches!(
21429 self.config.dialect,
21430 Some(crate::dialects::DialectType::ClickHouse)
21431 );
21432 let single_expr = in_expr.expressions.len() == 1;
21433 if is_clickhouse && single_expr {
21434 if let Expression::Array(arr) = &in_expr.expressions[0] {
21435 self.write(" (");
21437 for (i, expr) in arr.expressions.iter().enumerate() {
21438 if i > 0 {
21439 self.write(", ");
21440 }
21441 self.generate_expression(expr)?;
21442 }
21443 self.write(")");
21444 } else {
21445 self.write_space();
21446 self.generate_expression(&in_expr.expressions[0])?;
21447 }
21448 } else {
21449 let is_bare_ref = single_expr
21450 && matches!(
21451 &in_expr.expressions[0],
21452 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
21453 );
21454 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
21455 self.write_space();
21458 self.generate_expression(&in_expr.expressions[0])?;
21459 } else {
21460 self.write(" (");
21462 for (i, expr) in in_expr.expressions.iter().enumerate() {
21463 if i > 0 {
21464 self.write(", ");
21465 }
21466 self.generate_expression(expr)?;
21467 }
21468 self.write(")");
21469 }
21470 }
21471 }
21472
21473 Ok(())
21474 }
21475
21476 fn generate_between(&mut self, between: &Between) -> Result<()> {
21477 let use_prefix_not = between.not
21479 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
21480 if use_prefix_not {
21481 self.write_keyword("NOT");
21482 self.write_space();
21483 }
21484 self.generate_expression(&between.this)?;
21485 if between.not && !use_prefix_not {
21486 self.write_space();
21487 self.write_keyword("NOT");
21488 }
21489 self.write_space();
21490 self.write_keyword("BETWEEN");
21491 if let Some(sym) = between.symmetric {
21493 if sym {
21494 self.write(" SYMMETRIC");
21495 } else {
21496 self.write(" ASYMMETRIC");
21497 }
21498 }
21499 self.write_space();
21500 self.generate_expression(&between.low)?;
21501 self.write_space();
21502 self.write_keyword("AND");
21503 self.write_space();
21504 self.generate_expression(&between.high)
21505 }
21506
21507 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
21508 let use_prefix_not = is_null.not
21510 && (self.config.dialect.is_none()
21511 || self.config.dialect == Some(DialectType::Generic)
21512 || is_null.postfix_form);
21513 if use_prefix_not {
21514 self.write_keyword("NOT");
21516 self.write_space();
21517 self.generate_expression(&is_null.this)?;
21518 self.write_space();
21519 self.write_keyword("IS");
21520 self.write_space();
21521 self.write_keyword("NULL");
21522 } else {
21523 self.generate_expression(&is_null.this)?;
21524 self.write_space();
21525 self.write_keyword("IS");
21526 if is_null.not {
21527 self.write_space();
21528 self.write_keyword("NOT");
21529 }
21530 self.write_space();
21531 self.write_keyword("NULL");
21532 }
21533 Ok(())
21534 }
21535
21536 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
21537 self.generate_expression(&is_true.this)?;
21538 self.write_space();
21539 self.write_keyword("IS");
21540 if is_true.not {
21541 self.write_space();
21542 self.write_keyword("NOT");
21543 }
21544 self.write_space();
21545 self.write_keyword("TRUE");
21546 Ok(())
21547 }
21548
21549 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
21550 self.generate_expression(&is_false.this)?;
21551 self.write_space();
21552 self.write_keyword("IS");
21553 if is_false.not {
21554 self.write_space();
21555 self.write_keyword("NOT");
21556 }
21557 self.write_space();
21558 self.write_keyword("FALSE");
21559 Ok(())
21560 }
21561
21562 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
21563 self.generate_expression(&is_json.this)?;
21564 self.write_space();
21565 self.write_keyword("IS");
21566 if is_json.negated {
21567 self.write_space();
21568 self.write_keyword("NOT");
21569 }
21570 self.write_space();
21571 self.write_keyword("JSON");
21572
21573 if let Some(ref json_type) = is_json.json_type {
21575 self.write_space();
21576 self.write_keyword(json_type);
21577 }
21578
21579 match &is_json.unique_keys {
21581 Some(JsonUniqueKeys::With) => {
21582 self.write_space();
21583 self.write_keyword("WITH UNIQUE KEYS");
21584 }
21585 Some(JsonUniqueKeys::Without) => {
21586 self.write_space();
21587 self.write_keyword("WITHOUT UNIQUE KEYS");
21588 }
21589 Some(JsonUniqueKeys::Shorthand) => {
21590 self.write_space();
21591 self.write_keyword("UNIQUE KEYS");
21592 }
21593 None => {}
21594 }
21595
21596 Ok(())
21597 }
21598
21599 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
21600 self.generate_expression(&is_expr.left)?;
21601 self.write_space();
21602 self.write_keyword("IS");
21603 self.write_space();
21604 self.generate_expression(&is_expr.right)
21605 }
21606
21607 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
21608 if exists.not {
21609 self.write_keyword("NOT");
21610 self.write_space();
21611 }
21612 self.write_keyword("EXISTS");
21613 self.write("(");
21614 let is_statement = matches!(
21615 &exists.this,
21616 Expression::Select(_)
21617 | Expression::Union(_)
21618 | Expression::Intersect(_)
21619 | Expression::Except(_)
21620 );
21621 if self.config.pretty && is_statement {
21622 self.write_newline();
21623 self.indent_level += 1;
21624 self.write_indent();
21625 self.generate_expression(&exists.this)?;
21626 self.write_newline();
21627 self.indent_level -= 1;
21628 self.write_indent();
21629 self.write(")");
21630 } else {
21631 self.generate_expression(&exists.this)?;
21632 self.write(")");
21633 }
21634 Ok(())
21635 }
21636
21637 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
21638 self.generate_expression(&op.left)?;
21639 self.write_space();
21640 self.write_keyword("MEMBER OF");
21641 self.write("(");
21642 self.generate_expression(&op.right)?;
21643 self.write(")");
21644 Ok(())
21645 }
21646
21647 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
21648 if subquery.lateral {
21649 self.write_keyword("LATERAL");
21650 self.write_space();
21651 }
21652
21653 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
21657 matches!(
21658 &p.this,
21659 Expression::Select(_)
21660 | Expression::Union(_)
21661 | Expression::Intersect(_)
21662 | Expression::Except(_)
21663 | Expression::Subquery(_)
21664 )
21665 } else {
21666 false
21667 };
21668
21669 let is_statement = matches!(
21671 &subquery.this,
21672 Expression::Select(_)
21673 | Expression::Union(_)
21674 | Expression::Intersect(_)
21675 | Expression::Except(_)
21676 | Expression::Merge(_)
21677 );
21678
21679 if !skip_outer_parens {
21680 self.write("(");
21681 if self.config.pretty && is_statement {
21682 self.write_newline();
21683 self.indent_level += 1;
21684 self.write_indent();
21685 }
21686 }
21687 self.generate_expression(&subquery.this)?;
21688
21689 if subquery.modifiers_inside {
21691 if let Some(order_by) = &subquery.order_by {
21693 self.write_space();
21694 self.write_keyword("ORDER BY");
21695 self.write_space();
21696 for (i, ord) in order_by.expressions.iter().enumerate() {
21697 if i > 0 {
21698 self.write(", ");
21699 }
21700 self.generate_ordered(ord)?;
21701 }
21702 }
21703
21704 if let Some(limit) = &subquery.limit {
21705 self.write_space();
21706 self.write_keyword("LIMIT");
21707 self.write_space();
21708 self.generate_expression(&limit.this)?;
21709 if limit.percent {
21710 self.write_space();
21711 self.write_keyword("PERCENT");
21712 }
21713 }
21714
21715 if let Some(offset) = &subquery.offset {
21716 self.write_space();
21717 self.write_keyword("OFFSET");
21718 self.write_space();
21719 self.generate_expression(&offset.this)?;
21720 }
21721 }
21722
21723 if !skip_outer_parens {
21724 if self.config.pretty && is_statement {
21725 self.write_newline();
21726 self.indent_level -= 1;
21727 self.write_indent();
21728 }
21729 self.write(")");
21730 }
21731
21732 if !subquery.modifiers_inside {
21734 if let Some(order_by) = &subquery.order_by {
21735 self.write_space();
21736 self.write_keyword("ORDER BY");
21737 self.write_space();
21738 for (i, ord) in order_by.expressions.iter().enumerate() {
21739 if i > 0 {
21740 self.write(", ");
21741 }
21742 self.generate_ordered(ord)?;
21743 }
21744 }
21745
21746 if let Some(limit) = &subquery.limit {
21747 self.write_space();
21748 self.write_keyword("LIMIT");
21749 self.write_space();
21750 self.generate_expression(&limit.this)?;
21751 if limit.percent {
21752 self.write_space();
21753 self.write_keyword("PERCENT");
21754 }
21755 }
21756
21757 if let Some(offset) = &subquery.offset {
21758 self.write_space();
21759 self.write_keyword("OFFSET");
21760 self.write_space();
21761 self.generate_expression(&offset.this)?;
21762 }
21763
21764 if let Some(distribute_by) = &subquery.distribute_by {
21766 self.write_space();
21767 self.write_keyword("DISTRIBUTE BY");
21768 self.write_space();
21769 for (i, expr) in distribute_by.expressions.iter().enumerate() {
21770 if i > 0 {
21771 self.write(", ");
21772 }
21773 self.generate_expression(expr)?;
21774 }
21775 }
21776
21777 if let Some(sort_by) = &subquery.sort_by {
21779 self.write_space();
21780 self.write_keyword("SORT BY");
21781 self.write_space();
21782 for (i, ord) in sort_by.expressions.iter().enumerate() {
21783 if i > 0 {
21784 self.write(", ");
21785 }
21786 self.generate_ordered(ord)?;
21787 }
21788 }
21789
21790 if let Some(cluster_by) = &subquery.cluster_by {
21792 self.write_space();
21793 self.write_keyword("CLUSTER BY");
21794 self.write_space();
21795 for (i, ord) in cluster_by.expressions.iter().enumerate() {
21796 if i > 0 {
21797 self.write(", ");
21798 }
21799 self.generate_ordered(ord)?;
21800 }
21801 }
21802 }
21803
21804 if let Some(alias) = &subquery.alias {
21805 self.write_space();
21806 let skip_as = matches!(
21808 self.config.dialect,
21809 Some(crate::dialects::DialectType::Oracle)
21810 );
21811 if !skip_as {
21812 self.write_keyword("AS");
21813 self.write_space();
21814 }
21815 self.generate_identifier(alias)?;
21816 if !subquery.column_aliases.is_empty() {
21817 self.write("(");
21818 for (i, col) in subquery.column_aliases.iter().enumerate() {
21819 if i > 0 {
21820 self.write(", ");
21821 }
21822 self.generate_identifier(col)?;
21823 }
21824 self.write(")");
21825 }
21826 }
21827 for comment in &subquery.trailing_comments {
21829 self.write(" ");
21830 self.write_formatted_comment(comment);
21831 }
21832 Ok(())
21833 }
21834
21835 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
21836 if let Some(ref with) = pivot.with {
21838 self.generate_with(with)?;
21839 self.write_space();
21840 }
21841
21842 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
21843
21844 let is_redshift_unpivot = pivot.unpivot
21848 && pivot.expressions.is_empty()
21849 && pivot.fields.is_empty()
21850 && pivot.using.is_empty()
21851 && pivot.into.is_none()
21852 && !matches!(&pivot.this, Expression::Null(_));
21853
21854 if is_redshift_unpivot {
21855 self.write_keyword("UNPIVOT");
21857 self.write_space();
21858 self.generate_expression(&pivot.this)?;
21859 if let Some(alias) = &pivot.alias {
21861 self.write_space();
21862 self.write_keyword("AS");
21863 self.write_space();
21864 self.write(&alias.name);
21866 }
21867 return Ok(());
21868 }
21869
21870 let is_simplified = !pivot.using.is_empty()
21872 || pivot.into.is_some()
21873 || (pivot.fields.is_empty()
21874 && !pivot.expressions.is_empty()
21875 && !matches!(&pivot.this, Expression::Null(_)));
21876
21877 if is_simplified {
21878 self.write_keyword(direction);
21882 self.write_space();
21883 self.generate_expression(&pivot.this)?;
21884
21885 if !pivot.expressions.is_empty() {
21886 self.write_space();
21887 self.write_keyword("ON");
21888 self.write_space();
21889 for (i, expr) in pivot.expressions.iter().enumerate() {
21890 if i > 0 {
21891 self.write(", ");
21892 }
21893 self.generate_expression(expr)?;
21894 }
21895 }
21896
21897 if let Some(into) = &pivot.into {
21899 self.write_space();
21900 self.write_keyword("INTO");
21901 self.write_space();
21902 self.generate_expression(into)?;
21903 }
21904
21905 if !pivot.using.is_empty() {
21907 self.write_space();
21908 self.write_keyword("USING");
21909 self.write_space();
21910 for (i, expr) in pivot.using.iter().enumerate() {
21911 if i > 0 {
21912 self.write(", ");
21913 }
21914 self.generate_expression(expr)?;
21915 }
21916 }
21917
21918 if let Some(group) = &pivot.group {
21920 self.write_space();
21921 self.generate_expression(group)?;
21922 }
21923 } else {
21924 if !matches!(&pivot.this, Expression::Null(_)) {
21929 self.generate_expression(&pivot.this)?;
21930 self.write_space();
21931 }
21932 self.write_keyword(direction);
21933 self.write("(");
21934
21935 for (i, expr) in pivot.expressions.iter().enumerate() {
21937 if i > 0 {
21938 self.write(", ");
21939 }
21940 self.generate_expression(expr)?;
21941 }
21942
21943 if !pivot.fields.is_empty() {
21945 if !pivot.expressions.is_empty() {
21946 self.write_space();
21947 }
21948 self.write_keyword("FOR");
21949 self.write_space();
21950 for (i, field) in pivot.fields.iter().enumerate() {
21951 if i > 0 {
21952 self.write_space();
21953 }
21954 self.generate_expression(field)?;
21956 }
21957 }
21958
21959 if let Some(default_val) = &pivot.default_on_null {
21961 self.write_space();
21962 self.write_keyword("DEFAULT ON NULL");
21963 self.write(" (");
21964 self.generate_expression(default_val)?;
21965 self.write(")");
21966 }
21967
21968 if let Some(group) = &pivot.group {
21970 self.write_space();
21971 self.generate_expression(group)?;
21972 }
21973
21974 self.write(")");
21975 }
21976
21977 if let Some(alias) = &pivot.alias {
21979 self.write_space();
21980 self.write_keyword("AS");
21981 self.write_space();
21982 self.generate_identifier(alias)?;
21983 }
21984
21985 Ok(())
21986 }
21987
21988 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
21989 self.generate_expression(&unpivot.this)?;
21990 self.write_space();
21991 self.write_keyword("UNPIVOT");
21992 if let Some(include) = unpivot.include_nulls {
21994 self.write_space();
21995 if include {
21996 self.write_keyword("INCLUDE NULLS");
21997 } else {
21998 self.write_keyword("EXCLUDE NULLS");
21999 }
22000 self.write_space();
22001 }
22002 self.write("(");
22003 if unpivot.value_column_parenthesized {
22004 self.write("(");
22005 }
22006 self.generate_identifier(&unpivot.value_column)?;
22007 for extra_col in &unpivot.extra_value_columns {
22009 self.write(", ");
22010 self.generate_identifier(extra_col)?;
22011 }
22012 if unpivot.value_column_parenthesized {
22013 self.write(")");
22014 }
22015 self.write_space();
22016 self.write_keyword("FOR");
22017 self.write_space();
22018 self.generate_identifier(&unpivot.name_column)?;
22019 self.write_space();
22020 self.write_keyword("IN");
22021 self.write(" (");
22022 for (i, col) in unpivot.columns.iter().enumerate() {
22023 if i > 0 {
22024 self.write(", ");
22025 }
22026 self.generate_expression(col)?;
22027 }
22028 self.write("))");
22029 if let Some(alias) = &unpivot.alias {
22030 self.write_space();
22031 self.write_keyword("AS");
22032 self.write_space();
22033 self.generate_identifier(alias)?;
22034 }
22035 Ok(())
22036 }
22037
22038 fn generate_values(&mut self, values: &Values) -> Result<()> {
22039 self.write_keyword("VALUES");
22040 for (i, row) in values.expressions.iter().enumerate() {
22041 if i > 0 {
22042 self.write(",");
22043 }
22044 self.write(" (");
22045 for (j, expr) in row.expressions.iter().enumerate() {
22046 if j > 0 {
22047 self.write(", ");
22048 }
22049 self.generate_expression(expr)?;
22050 }
22051 self.write(")");
22052 }
22053 if let Some(alias) = &values.alias {
22054 self.write_space();
22055 self.write_keyword("AS");
22056 self.write_space();
22057 self.generate_identifier(alias)?;
22058 if !values.column_aliases.is_empty() {
22059 self.write("(");
22060 for (i, col) in values.column_aliases.iter().enumerate() {
22061 if i > 0 {
22062 self.write(", ");
22063 }
22064 self.generate_identifier(col)?;
22065 }
22066 self.write(")");
22067 }
22068 }
22069 Ok(())
22070 }
22071
22072 fn generate_array(&mut self, arr: &Array) -> Result<()> {
22073 let needs_inheritance = matches!(
22075 self.config.dialect,
22076 Some(DialectType::DuckDB)
22077 | Some(DialectType::Spark)
22078 | Some(DialectType::Databricks)
22079 | Some(DialectType::Hive)
22080 | Some(DialectType::Snowflake)
22081 | Some(DialectType::Presto)
22082 | Some(DialectType::Trino)
22083 );
22084 let propagated: Vec<Expression>;
22085 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
22086 propagated = Self::inherit_struct_field_names(&arr.expressions);
22087 &propagated
22088 } else {
22089 &arr.expressions
22090 };
22091
22092 let use_parens =
22095 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
22096 if !self.config.array_bracket_only {
22097 self.write_keyword("ARRAY");
22098 }
22099 if use_parens {
22100 self.write("(");
22101 } else {
22102 self.write("[");
22103 }
22104 for (i, expr) in expressions.iter().enumerate() {
22105 if i > 0 {
22106 self.write(", ");
22107 }
22108 self.generate_expression(expr)?;
22109 }
22110 if use_parens {
22111 self.write(")");
22112 } else {
22113 self.write("]");
22114 }
22115 Ok(())
22116 }
22117
22118 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
22119 if tuple.expressions.len() == 2 {
22122 if let Expression::TableAlias(_) = &tuple.expressions[1] {
22123 self.generate_expression(&tuple.expressions[0])?;
22125 self.write_space();
22126 self.write_keyword("AS");
22127 self.write_space();
22128 self.generate_expression(&tuple.expressions[1])?;
22129 return Ok(());
22130 }
22131 }
22132
22133 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
22136 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
22137 for expr in &tuple.expressions {
22138 expr_strings.push(self.generate_to_string(expr)?);
22139 }
22140 self.too_wide(&expr_strings)
22141 } else {
22142 false
22143 };
22144
22145 if expand_tuple {
22146 self.write("(");
22147 self.write_newline();
22148 self.indent_level += 1;
22149 for (i, expr) in tuple.expressions.iter().enumerate() {
22150 if i > 0 {
22151 self.write(",");
22152 self.write_newline();
22153 }
22154 self.write_indent();
22155 self.generate_expression(expr)?;
22156 }
22157 self.indent_level -= 1;
22158 self.write_newline();
22159 self.write_indent();
22160 self.write(")");
22161 } else {
22162 self.write("(");
22163 for (i, expr) in tuple.expressions.iter().enumerate() {
22164 if i > 0 {
22165 self.write(", ");
22166 }
22167 self.generate_expression(expr)?;
22168 }
22169 self.write(")");
22170 }
22171 Ok(())
22172 }
22173
22174 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
22175 self.generate_expression(&pipe.this)?;
22176 self.write(" |> ");
22177 self.generate_expression(&pipe.expression)?;
22178 Ok(())
22179 }
22180
22181 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
22182 self.generate_expression(&ordered.this)?;
22183 if ordered.desc {
22184 self.write_space();
22185 self.write_keyword("DESC");
22186 } else if ordered.explicit_asc {
22187 self.write_space();
22188 self.write_keyword("ASC");
22189 }
22190 if let Some(nulls_first) = ordered.nulls_first {
22191 let is_asc = !ordered.desc;
22205 let is_nulls_are_large = matches!(
22206 self.config.dialect,
22207 Some(DialectType::Oracle)
22208 | Some(DialectType::PostgreSQL)
22209 | Some(DialectType::Redshift)
22210 | Some(DialectType::Snowflake)
22211 );
22212 let is_nulls_are_last = matches!(
22213 self.config.dialect,
22214 Some(DialectType::Dremio)
22215 | Some(DialectType::DuckDB)
22216 | Some(DialectType::Presto)
22217 | Some(DialectType::Trino)
22218 | Some(DialectType::Athena)
22219 | Some(DialectType::ClickHouse)
22220 | Some(DialectType::Drill)
22221 | Some(DialectType::Exasol)
22222 );
22223
22224 let is_default_nulls = if is_nulls_are_large {
22226 (is_asc && !nulls_first) || (!is_asc && nulls_first)
22228 } else if is_nulls_are_last {
22229 !nulls_first
22231 } else {
22232 false
22233 };
22234
22235 if !is_default_nulls {
22236 self.write_space();
22237 self.write_keyword("NULLS");
22238 self.write_space();
22239 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
22240 }
22241 }
22242 if let Some(ref with_fill) = ordered.with_fill {
22244 self.write_space();
22245 self.generate_with_fill(with_fill)?;
22246 }
22247 Ok(())
22248 }
22249
22250 fn write_clickhouse_type(&mut self, type_str: &str) {
22252 if self.clickhouse_nullable_depth < 0 {
22253 self.write(type_str);
22255 } else {
22256 self.write(&format!("Nullable({})", type_str));
22257 }
22258 }
22259
22260 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
22261 use crate::dialects::DialectType;
22262
22263 match dt {
22264 DataType::Boolean => {
22265 match self.config.dialect {
22267 Some(DialectType::TSQL) => self.write_keyword("BIT"),
22268 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
22270 self.write_keyword("NUMBER(1)")
22272 }
22273 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
22275 }
22276 }
22277 DataType::TinyInt { length } => {
22278 match self.config.dialect {
22282 Some(DialectType::PostgreSQL)
22283 | Some(DialectType::Redshift)
22284 | Some(DialectType::Oracle)
22285 | Some(DialectType::Exasol) => {
22286 self.write_keyword("SMALLINT");
22287 }
22288 Some(DialectType::Teradata) => {
22289 self.write_keyword("BYTEINT");
22291 }
22292 Some(DialectType::Dremio) => {
22293 self.write_keyword("INT");
22295 }
22296 Some(DialectType::ClickHouse) => {
22297 self.write_clickhouse_type("Int8");
22298 }
22299 _ => {
22300 self.write_keyword("TINYINT");
22301 }
22302 }
22303 if let Some(n) = length {
22304 if !matches!(
22305 self.config.dialect,
22306 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
22307 ) {
22308 self.write(&format!("({})", n));
22309 }
22310 }
22311 }
22312 DataType::SmallInt { length } => {
22313 match self.config.dialect {
22315 Some(DialectType::Dremio) => {
22316 self.write_keyword("INT");
22317 }
22318 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
22319 self.write_keyword("INTEGER");
22320 }
22321 Some(DialectType::BigQuery) => {
22322 self.write_keyword("INT64");
22323 }
22324 Some(DialectType::ClickHouse) => {
22325 self.write_clickhouse_type("Int16");
22326 }
22327 _ => {
22328 self.write_keyword("SMALLINT");
22329 if let Some(n) = length {
22330 self.write(&format!("({})", n));
22331 }
22332 }
22333 }
22334 }
22335 DataType::Int {
22336 length,
22337 integer_spelling: _,
22338 } => {
22339 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
22341 self.write_keyword("INT64");
22342 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22343 self.write_clickhouse_type("Int32");
22344 } else {
22345 let use_integer = match self.config.dialect {
22347 Some(DialectType::TSQL)
22348 | Some(DialectType::Fabric)
22349 | Some(DialectType::Presto)
22350 | Some(DialectType::Trino)
22351 | Some(DialectType::SQLite)
22352 | Some(DialectType::Redshift) => true,
22353 _ => false,
22354 };
22355 if use_integer {
22356 self.write_keyword("INTEGER");
22357 } else {
22358 self.write_keyword("INT");
22359 }
22360 if let Some(n) = length {
22361 self.write(&format!("({})", n));
22362 }
22363 }
22364 }
22365 DataType::BigInt { length } => {
22366 match self.config.dialect {
22368 Some(DialectType::Oracle) => {
22369 self.write_keyword("INT");
22371 }
22372 Some(DialectType::ClickHouse) => {
22373 self.write_clickhouse_type("Int64");
22374 }
22375 _ => {
22376 self.write_keyword("BIGINT");
22377 if let Some(n) = length {
22378 self.write(&format!("({})", n));
22379 }
22380 }
22381 }
22382 }
22383 DataType::Float {
22384 precision,
22385 scale,
22386 real_spelling,
22387 } => {
22388 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22392 self.write_clickhouse_type("Float32");
22393 } else if *real_spelling
22394 && !matches!(
22395 self.config.dialect,
22396 Some(DialectType::Spark)
22397 | Some(DialectType::Databricks)
22398 | Some(DialectType::Hive)
22399 | Some(DialectType::Snowflake)
22400 | Some(DialectType::MySQL)
22401 | Some(DialectType::BigQuery)
22402 )
22403 {
22404 self.write_keyword("REAL")
22405 } else {
22406 match self.config.dialect {
22407 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
22408 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
22409 _ => self.write_keyword("FLOAT"),
22410 }
22411 }
22412 if !matches!(
22415 self.config.dialect,
22416 Some(DialectType::Spark)
22417 | Some(DialectType::Databricks)
22418 | Some(DialectType::Hive)
22419 | Some(DialectType::Presto)
22420 | Some(DialectType::Trino)
22421 ) {
22422 if let Some(p) = precision {
22423 self.write(&format!("({}", p));
22424 if let Some(s) = scale {
22425 self.write(&format!(", {})", s));
22426 } else {
22427 self.write(")");
22428 }
22429 }
22430 }
22431 }
22432 DataType::Double { precision, scale } => {
22433 match self.config.dialect {
22435 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22436 self.write_keyword("FLOAT")
22437 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
22439 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
22440 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
22441 Some(DialectType::SQLite) => self.write_keyword("REAL"),
22442 Some(DialectType::PostgreSQL)
22443 | Some(DialectType::Redshift)
22444 | Some(DialectType::Teradata)
22445 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
22446 _ => self.write_keyword("DOUBLE"),
22447 }
22448 if let Some(p) = precision {
22450 self.write(&format!("({}", p));
22451 if let Some(s) = scale {
22452 self.write(&format!(", {})", s));
22453 } else {
22454 self.write(")");
22455 }
22456 }
22457 }
22458 DataType::Decimal { precision, scale } => {
22459 match self.config.dialect {
22461 Some(DialectType::ClickHouse) => {
22462 self.write("Decimal");
22463 if let Some(p) = precision {
22464 self.write(&format!("({}", p));
22465 if let Some(s) = scale {
22466 self.write(&format!(", {}", s));
22467 }
22468 self.write(")");
22469 }
22470 }
22471 Some(DialectType::Oracle) => {
22472 self.write_keyword("NUMBER");
22474 if let Some(p) = precision {
22475 self.write(&format!("({}", p));
22476 if let Some(s) = scale {
22477 self.write(&format!(", {}", s));
22478 }
22479 self.write(")");
22480 }
22481 }
22482 Some(DialectType::BigQuery) => {
22483 self.write_keyword("NUMERIC");
22485 if let Some(p) = precision {
22486 self.write(&format!("({}", p));
22487 if let Some(s) = scale {
22488 self.write(&format!(", {}", s));
22489 }
22490 self.write(")");
22491 }
22492 }
22493 _ => {
22494 self.write_keyword("DECIMAL");
22495 if let Some(p) = precision {
22496 self.write(&format!("({}", p));
22497 if let Some(s) = scale {
22498 self.write(&format!(", {}", s));
22499 }
22500 self.write(")");
22501 }
22502 }
22503 }
22504 }
22505 DataType::Char { length } => {
22506 match self.config.dialect {
22508 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
22509 self.write_keyword("TEXT");
22511 }
22512 Some(DialectType::Hive)
22513 | Some(DialectType::Spark)
22514 | Some(DialectType::Databricks) => {
22515 if length.is_some()
22518 && !matches!(self.config.dialect, Some(DialectType::Hive))
22519 {
22520 self.write_keyword("CHAR");
22521 if let Some(n) = length {
22522 self.write(&format!("({})", n));
22523 }
22524 } else {
22525 self.write_keyword("STRING");
22526 }
22527 }
22528 Some(DialectType::Dremio) => {
22529 self.write_keyword("VARCHAR");
22531 if let Some(n) = length {
22532 self.write(&format!("({})", n));
22533 }
22534 }
22535 _ => {
22536 self.write_keyword("CHAR");
22537 if let Some(n) = length {
22538 self.write(&format!("({})", n));
22539 }
22540 }
22541 }
22542 }
22543 DataType::VarChar {
22544 length,
22545 parenthesized_length,
22546 } => {
22547 match self.config.dialect {
22549 Some(DialectType::Oracle) => {
22550 self.write_keyword("VARCHAR2");
22551 if let Some(n) = length {
22552 self.write(&format!("({})", n));
22553 }
22554 }
22555 Some(DialectType::DuckDB) => {
22556 self.write_keyword("TEXT");
22558 if let Some(n) = length {
22559 self.write(&format!("({})", n));
22560 }
22561 }
22562 Some(DialectType::SQLite) => {
22563 self.write_keyword("TEXT");
22565 if let Some(n) = length {
22566 self.write(&format!("({})", n));
22567 }
22568 }
22569 Some(DialectType::MySQL) if length.is_none() => {
22570 self.write_keyword("TEXT");
22572 }
22573 Some(DialectType::Hive)
22574 | Some(DialectType::Spark)
22575 | Some(DialectType::Databricks)
22576 if length.is_none() =>
22577 {
22578 self.write_keyword("STRING");
22580 }
22581 _ => {
22582 self.write_keyword("VARCHAR");
22583 if let Some(n) = length {
22584 if *parenthesized_length {
22586 self.write(&format!("(({}))", n));
22587 } else {
22588 self.write(&format!("({})", n));
22589 }
22590 }
22591 }
22592 }
22593 }
22594 DataType::Text => {
22595 match self.config.dialect {
22597 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
22598 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22599 self.write_keyword("VARCHAR(MAX)")
22600 }
22601 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
22602 Some(DialectType::Snowflake)
22603 | Some(DialectType::Dremio)
22604 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
22605 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
22606 Some(DialectType::Presto)
22607 | Some(DialectType::Trino)
22608 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
22609 Some(DialectType::Spark)
22610 | Some(DialectType::Databricks)
22611 | Some(DialectType::Hive) => self.write_keyword("STRING"),
22612 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
22613 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
22614 self.write_keyword("STRING")
22615 }
22616 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
22617 _ => self.write_keyword("TEXT"),
22618 }
22619 }
22620 DataType::TextWithLength { length } => {
22621 match self.config.dialect {
22623 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
22624 Some(DialectType::Hive)
22625 | Some(DialectType::Spark)
22626 | Some(DialectType::Databricks) => {
22627 self.write(&format!("VARCHAR({})", length));
22628 }
22629 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
22630 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
22631 Some(DialectType::Snowflake)
22632 | Some(DialectType::Presto)
22633 | Some(DialectType::Trino)
22634 | Some(DialectType::Athena)
22635 | Some(DialectType::Drill)
22636 | Some(DialectType::Dremio) => {
22637 self.write(&format!("VARCHAR({})", length));
22638 }
22639 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22640 self.write(&format!("VARCHAR({})", length))
22641 }
22642 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
22643 self.write(&format!("STRING({})", length))
22644 }
22645 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
22646 _ => self.write(&format!("TEXT({})", length)),
22647 }
22648 }
22649 DataType::String { length } => {
22650 match self.config.dialect {
22652 Some(DialectType::ClickHouse) => {
22653 self.write("String");
22655 if let Some(n) = length {
22656 self.write(&format!("({})", n));
22657 }
22658 }
22659 Some(DialectType::BigQuery)
22660 | Some(DialectType::Hive)
22661 | Some(DialectType::Spark)
22662 | Some(DialectType::Databricks)
22663 | Some(DialectType::StarRocks)
22664 | Some(DialectType::Doris) => {
22665 self.write_keyword("STRING");
22666 if let Some(n) = length {
22667 self.write(&format!("({})", n));
22668 }
22669 }
22670 Some(DialectType::PostgreSQL) => {
22671 if let Some(n) = length {
22673 self.write_keyword("VARCHAR");
22674 self.write(&format!("({})", n));
22675 } else {
22676 self.write_keyword("TEXT");
22677 }
22678 }
22679 Some(DialectType::Redshift) => {
22680 if let Some(n) = length {
22682 self.write_keyword("VARCHAR");
22683 self.write(&format!("({})", n));
22684 } else {
22685 self.write_keyword("VARCHAR(MAX)");
22686 }
22687 }
22688 Some(DialectType::MySQL) => {
22689 if let Some(n) = length {
22691 self.write_keyword("VARCHAR");
22692 self.write(&format!("({})", n));
22693 } else {
22694 self.write_keyword("TEXT");
22695 }
22696 }
22697 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22698 if let Some(n) = length {
22700 self.write_keyword("VARCHAR");
22701 self.write(&format!("({})", n));
22702 } else {
22703 self.write_keyword("VARCHAR(MAX)");
22704 }
22705 }
22706 Some(DialectType::Oracle) => {
22707 self.write_keyword("CLOB");
22709 }
22710 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
22711 self.write_keyword("TEXT");
22713 if let Some(n) = length {
22714 self.write(&format!("({})", n));
22715 }
22716 }
22717 Some(DialectType::Presto)
22718 | Some(DialectType::Trino)
22719 | Some(DialectType::Drill)
22720 | Some(DialectType::Dremio) => {
22721 self.write_keyword("VARCHAR");
22723 if let Some(n) = length {
22724 self.write(&format!("({})", n));
22725 }
22726 }
22727 Some(DialectType::Snowflake) => {
22728 self.write_keyword("STRING");
22731 if let Some(n) = length {
22732 self.write(&format!("({})", n));
22733 }
22734 }
22735 _ => {
22736 self.write_keyword("STRING");
22738 if let Some(n) = length {
22739 self.write(&format!("({})", n));
22740 }
22741 }
22742 }
22743 }
22744 DataType::Binary { length } => {
22745 match self.config.dialect {
22747 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
22748 self.write_keyword("BYTEA");
22749 if let Some(n) = length {
22750 self.write(&format!("({})", n));
22751 }
22752 }
22753 Some(DialectType::Redshift) => {
22754 self.write_keyword("VARBYTE");
22755 if let Some(n) = length {
22756 self.write(&format!("({})", n));
22757 }
22758 }
22759 Some(DialectType::DuckDB)
22760 | Some(DialectType::SQLite)
22761 | Some(DialectType::Oracle) => {
22762 self.write_keyword("BLOB");
22764 if let Some(n) = length {
22765 self.write(&format!("({})", n));
22766 }
22767 }
22768 Some(DialectType::Presto)
22769 | Some(DialectType::Trino)
22770 | Some(DialectType::Athena)
22771 | Some(DialectType::Drill)
22772 | Some(DialectType::Dremio) => {
22773 self.write_keyword("VARBINARY");
22775 if let Some(n) = length {
22776 self.write(&format!("({})", n));
22777 }
22778 }
22779 Some(DialectType::ClickHouse) => {
22780 if self.clickhouse_nullable_depth < 0 {
22782 self.write("BINARY");
22783 } else {
22784 self.write("Nullable(BINARY");
22785 }
22786 if let Some(n) = length {
22787 self.write(&format!("({})", n));
22788 }
22789 if self.clickhouse_nullable_depth >= 0 {
22790 self.write(")");
22791 }
22792 }
22793 _ => {
22794 self.write_keyword("BINARY");
22795 if let Some(n) = length {
22796 self.write(&format!("({})", n));
22797 }
22798 }
22799 }
22800 }
22801 DataType::VarBinary { length } => {
22802 match self.config.dialect {
22804 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
22805 self.write_keyword("BYTEA");
22806 if let Some(n) = length {
22807 self.write(&format!("({})", n));
22808 }
22809 }
22810 Some(DialectType::Redshift) => {
22811 self.write_keyword("VARBYTE");
22812 if let Some(n) = length {
22813 self.write(&format!("({})", n));
22814 }
22815 }
22816 Some(DialectType::DuckDB)
22817 | Some(DialectType::SQLite)
22818 | Some(DialectType::Oracle) => {
22819 self.write_keyword("BLOB");
22821 if let Some(n) = length {
22822 self.write(&format!("({})", n));
22823 }
22824 }
22825 Some(DialectType::Exasol) => {
22826 self.write_keyword("VARCHAR");
22828 }
22829 Some(DialectType::Spark)
22830 | Some(DialectType::Hive)
22831 | Some(DialectType::Databricks) => {
22832 self.write_keyword("BINARY");
22834 if let Some(n) = length {
22835 self.write(&format!("({})", n));
22836 }
22837 }
22838 Some(DialectType::ClickHouse) => {
22839 self.write_clickhouse_type("String");
22841 }
22842 _ => {
22843 self.write_keyword("VARBINARY");
22844 if let Some(n) = length {
22845 self.write(&format!("({})", n));
22846 }
22847 }
22848 }
22849 }
22850 DataType::Blob => {
22851 match self.config.dialect {
22853 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
22854 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
22855 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22856 self.write_keyword("VARBINARY")
22857 }
22858 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
22859 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
22860 Some(DialectType::Presto)
22861 | Some(DialectType::Trino)
22862 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
22863 Some(DialectType::DuckDB) => {
22864 self.write_keyword("VARBINARY");
22867 }
22868 Some(DialectType::Spark)
22869 | Some(DialectType::Databricks)
22870 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
22871 Some(DialectType::ClickHouse) => {
22872 self.write("Nullable(String)");
22876 }
22877 _ => self.write_keyword("BLOB"),
22878 }
22879 }
22880 DataType::Bit { length } => {
22881 match self.config.dialect {
22883 Some(DialectType::Dremio)
22884 | Some(DialectType::Spark)
22885 | Some(DialectType::Databricks)
22886 | Some(DialectType::Hive)
22887 | Some(DialectType::Snowflake)
22888 | Some(DialectType::BigQuery)
22889 | Some(DialectType::Presto)
22890 | Some(DialectType::Trino)
22891 | Some(DialectType::ClickHouse)
22892 | Some(DialectType::Redshift) => {
22893 self.write_keyword("BOOLEAN");
22895 }
22896 _ => {
22897 self.write_keyword("BIT");
22898 if let Some(n) = length {
22899 self.write(&format!("({})", n));
22900 }
22901 }
22902 }
22903 }
22904 DataType::VarBit { length } => {
22905 self.write_keyword("VARBIT");
22906 if let Some(n) = length {
22907 self.write(&format!("({})", n));
22908 }
22909 }
22910 DataType::Date => self.write_keyword("DATE"),
22911 DataType::Time {
22912 precision,
22913 timezone,
22914 } => {
22915 if *timezone {
22916 match self.config.dialect {
22918 Some(DialectType::DuckDB) => {
22919 self.write_keyword("TIMETZ");
22921 }
22922 Some(DialectType::PostgreSQL) => {
22923 self.write_keyword("TIMETZ");
22925 if let Some(p) = precision {
22926 self.write(&format!("({})", p));
22927 }
22928 }
22929 _ => {
22930 self.write_keyword("TIME");
22932 if let Some(p) = precision {
22933 self.write(&format!("({})", p));
22934 }
22935 self.write_keyword(" WITH TIME ZONE");
22936 }
22937 }
22938 } else {
22939 if matches!(
22941 self.config.dialect,
22942 Some(DialectType::Spark)
22943 | Some(DialectType::Databricks)
22944 | Some(DialectType::Hive)
22945 ) {
22946 self.write_keyword("TIMESTAMP");
22947 } else {
22948 self.write_keyword("TIME");
22949 if let Some(p) = precision {
22950 self.write(&format!("({})", p));
22951 }
22952 }
22953 }
22954 }
22955 DataType::Timestamp {
22956 precision,
22957 timezone,
22958 } => {
22959 match self.config.dialect {
22961 Some(DialectType::ClickHouse) => {
22962 self.write("DateTime");
22963 if let Some(p) = precision {
22964 self.write(&format!("({})", p));
22965 }
22966 }
22967 Some(DialectType::TSQL) => {
22968 if *timezone {
22969 self.write_keyword("DATETIMEOFFSET");
22970 } else {
22971 self.write_keyword("DATETIME2");
22972 }
22973 if let Some(p) = precision {
22974 self.write(&format!("({})", p));
22975 }
22976 }
22977 Some(DialectType::MySQL) => {
22978 self.write_keyword("TIMESTAMP");
22980 if let Some(p) = precision {
22981 self.write(&format!("({})", p));
22982 }
22983 }
22984 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
22985 self.write_keyword("DATETIME");
22987 if let Some(p) = precision {
22988 self.write(&format!("({})", p));
22989 }
22990 }
22991 Some(DialectType::BigQuery) => {
22992 if *timezone {
22994 self.write_keyword("TIMESTAMP");
22995 } else {
22996 self.write_keyword("DATETIME");
22997 }
22998 }
22999 Some(DialectType::DuckDB) => {
23000 if *timezone {
23002 self.write_keyword("TIMESTAMPTZ");
23003 } else {
23004 self.write_keyword("TIMESTAMP");
23005 if let Some(p) = precision {
23006 self.write(&format!("({})", p));
23007 }
23008 }
23009 }
23010 _ => {
23011 if *timezone && !self.config.tz_to_with_time_zone {
23012 self.write_keyword("TIMESTAMPTZ");
23014 if let Some(p) = precision {
23015 self.write(&format!("({})", p));
23016 }
23017 } else {
23018 self.write_keyword("TIMESTAMP");
23019 if let Some(p) = precision {
23020 self.write(&format!("({})", p));
23021 }
23022 if *timezone {
23023 self.write_space();
23024 self.write_keyword("WITH TIME ZONE");
23025 }
23026 }
23027 }
23028 }
23029 }
23030 DataType::Interval { unit, to } => {
23031 self.write_keyword("INTERVAL");
23032 if let Some(u) = unit {
23033 self.write_space();
23034 self.write_keyword(u);
23035 }
23036 if let Some(t) = to {
23038 self.write_space();
23039 self.write_keyword("TO");
23040 self.write_space();
23041 self.write_keyword(t);
23042 }
23043 }
23044 DataType::Json => {
23045 match self.config.dialect {
23047 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
23050 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
23051 _ => self.write_keyword("JSON"),
23052 }
23053 }
23054 DataType::JsonB => {
23055 match self.config.dialect {
23057 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
23058 Some(DialectType::Doris) => self.write_keyword("JSONB"),
23059 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
23060 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
23061 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
23064 }
23065 DataType::Uuid => {
23066 match self.config.dialect {
23068 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
23069 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
23070 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
23071 Some(DialectType::BigQuery)
23072 | Some(DialectType::Spark)
23073 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
23074 _ => self.write_keyword("UUID"),
23075 }
23076 }
23077 DataType::Array {
23078 element_type,
23079 dimension,
23080 } => {
23081 match self.config.dialect {
23083 Some(DialectType::PostgreSQL)
23084 | Some(DialectType::Redshift)
23085 | Some(DialectType::DuckDB) => {
23086 self.generate_data_type(element_type)?;
23088 if let Some(dim) = dimension {
23089 self.write(&format!("[{}]", dim));
23090 } else {
23091 self.write("[]");
23092 }
23093 }
23094 Some(DialectType::BigQuery) => {
23095 self.write_keyword("ARRAY<");
23096 self.generate_data_type(element_type)?;
23097 self.write(">");
23098 }
23099 Some(DialectType::Snowflake)
23100 | Some(DialectType::Presto)
23101 | Some(DialectType::Trino)
23102 | Some(DialectType::ClickHouse) => {
23103 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23105 self.write("Array(");
23106 } else {
23107 self.write_keyword("ARRAY(");
23108 }
23109 self.generate_data_type(element_type)?;
23110 self.write(")");
23111 }
23112 Some(DialectType::TSQL)
23113 | Some(DialectType::MySQL)
23114 | Some(DialectType::Oracle) => {
23115 match self.config.dialect {
23118 Some(DialectType::MySQL) => self.write_keyword("JSON"),
23119 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
23120 _ => self.write_keyword("JSON"),
23121 }
23122 }
23123 _ => {
23124 self.write_keyword("ARRAY<");
23126 self.generate_data_type(element_type)?;
23127 self.write(">");
23128 }
23129 }
23130 }
23131 DataType::List { element_type } => {
23132 self.generate_data_type(element_type)?;
23134 self.write_keyword(" LIST");
23135 }
23136 DataType::Map {
23137 key_type,
23138 value_type,
23139 } => {
23140 match self.config.dialect {
23142 Some(DialectType::Materialize) => {
23143 self.write_keyword("MAP[");
23145 self.generate_data_type(key_type)?;
23146 self.write(" => ");
23147 self.generate_data_type(value_type)?;
23148 self.write("]");
23149 }
23150 Some(DialectType::Snowflake)
23151 | Some(DialectType::RisingWave)
23152 | Some(DialectType::DuckDB)
23153 | Some(DialectType::Presto)
23154 | Some(DialectType::Trino)
23155 | Some(DialectType::Athena) => {
23156 self.write_keyword("MAP(");
23157 self.generate_data_type(key_type)?;
23158 self.write(", ");
23159 self.generate_data_type(value_type)?;
23160 self.write(")");
23161 }
23162 Some(DialectType::ClickHouse) => {
23163 self.write("Map(");
23166 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
23168 self.clickhouse_nullable_depth = 0;
23169 self.write(", ");
23170 self.generate_data_type(value_type)?;
23171 self.write(")");
23172 }
23173 _ => {
23174 self.write_keyword("MAP<");
23175 self.generate_data_type(key_type)?;
23176 self.write(", ");
23177 self.generate_data_type(value_type)?;
23178 self.write(">");
23179 }
23180 }
23181 }
23182 DataType::Vector {
23183 element_type,
23184 dimension,
23185 } => {
23186 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
23187 self.write_keyword("VECTOR(");
23189 if let Some(dim) = dimension {
23190 self.write(&dim.to_string());
23191 }
23192 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
23194 DataType::TinyInt { .. } => Some("I8"),
23195 DataType::SmallInt { .. } => Some("I16"),
23196 DataType::Int { .. } => Some("I32"),
23197 DataType::BigInt { .. } => Some("I64"),
23198 DataType::Float { .. } => Some("F32"),
23199 DataType::Double { .. } => Some("F64"),
23200 _ => None,
23201 });
23202 if let Some(alias) = type_alias {
23203 if dimension.is_some() {
23204 self.write(", ");
23205 }
23206 self.write(alias);
23207 }
23208 self.write(")");
23209 } else {
23210 self.write_keyword("VECTOR(");
23212 if let Some(ref et) = element_type {
23213 self.generate_data_type(et)?;
23214 if dimension.is_some() {
23215 self.write(", ");
23216 }
23217 }
23218 if let Some(dim) = dimension {
23219 self.write(&dim.to_string());
23220 }
23221 self.write(")");
23222 }
23223 }
23224 DataType::Object { fields, modifier } => {
23225 self.write_keyword("OBJECT(");
23226 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
23227 if i > 0 {
23228 self.write(", ");
23229 }
23230 self.write(name);
23231 self.write(" ");
23232 self.generate_data_type(dt)?;
23233 if *not_null {
23234 self.write_keyword(" NOT NULL");
23235 }
23236 }
23237 self.write(")");
23238 if let Some(mod_str) = modifier {
23239 self.write(" ");
23240 self.write_keyword(mod_str);
23241 }
23242 }
23243 DataType::Struct { fields, nested } => {
23244 match self.config.dialect {
23246 Some(DialectType::Snowflake) => {
23247 self.write_keyword("OBJECT(");
23249 for (i, field) in fields.iter().enumerate() {
23250 if i > 0 {
23251 self.write(", ");
23252 }
23253 if !field.name.is_empty() {
23254 self.write(&field.name);
23255 self.write(" ");
23256 }
23257 self.generate_data_type(&field.data_type)?;
23258 }
23259 self.write(")");
23260 }
23261 Some(DialectType::Presto) | Some(DialectType::Trino) => {
23262 self.write_keyword("ROW(");
23264 for (i, field) in fields.iter().enumerate() {
23265 if i > 0 {
23266 self.write(", ");
23267 }
23268 if !field.name.is_empty() {
23269 self.write(&field.name);
23270 self.write(" ");
23271 }
23272 self.generate_data_type(&field.data_type)?;
23273 }
23274 self.write(")");
23275 }
23276 Some(DialectType::DuckDB) => {
23277 self.write_keyword("STRUCT(");
23279 for (i, field) in fields.iter().enumerate() {
23280 if i > 0 {
23281 self.write(", ");
23282 }
23283 if !field.name.is_empty() {
23284 self.write(&field.name);
23285 self.write(" ");
23286 }
23287 self.generate_data_type(&field.data_type)?;
23288 }
23289 self.write(")");
23290 }
23291 Some(DialectType::ClickHouse) => {
23292 self.write("Tuple(");
23294 for (i, field) in fields.iter().enumerate() {
23295 if i > 0 {
23296 self.write(", ");
23297 }
23298 if !field.name.is_empty() {
23299 self.write(&field.name);
23300 self.write(" ");
23301 }
23302 self.generate_data_type(&field.data_type)?;
23303 }
23304 self.write(")");
23305 }
23306 Some(DialectType::SingleStore) => {
23307 self.write_keyword("RECORD(");
23309 for (i, field) in fields.iter().enumerate() {
23310 if i > 0 {
23311 self.write(", ");
23312 }
23313 if !field.name.is_empty() {
23314 self.write(&field.name);
23315 self.write(" ");
23316 }
23317 self.generate_data_type(&field.data_type)?;
23318 }
23319 self.write(")");
23320 }
23321 _ => {
23322 let force_angle_brackets = matches!(
23324 self.config.dialect,
23325 Some(DialectType::Hive)
23326 | Some(DialectType::Spark)
23327 | Some(DialectType::Databricks)
23328 );
23329 if *nested && !force_angle_brackets {
23330 self.write_keyword("STRUCT(");
23331 for (i, field) in fields.iter().enumerate() {
23332 if i > 0 {
23333 self.write(", ");
23334 }
23335 if !field.name.is_empty() {
23336 self.write(&field.name);
23337 self.write(" ");
23338 }
23339 self.generate_data_type(&field.data_type)?;
23340 }
23341 self.write(")");
23342 } else {
23343 self.write_keyword("STRUCT<");
23344 for (i, field) in fields.iter().enumerate() {
23345 if i > 0 {
23346 self.write(", ");
23347 }
23348 if !field.name.is_empty() {
23349 self.write(&field.name);
23351 self.write(self.config.struct_field_sep);
23352 }
23353 self.generate_data_type(&field.data_type)?;
23355 if let Some(comment) = &field.comment {
23357 self.write(" COMMENT '");
23358 self.write(comment);
23359 self.write("'");
23360 }
23361 if !field.options.is_empty() {
23363 self.write(" ");
23364 self.generate_options_clause(&field.options)?;
23365 }
23366 }
23367 self.write(">");
23368 }
23369 }
23370 }
23371 }
23372 DataType::Enum {
23373 values,
23374 assignments,
23375 } => {
23376 if self.config.dialect == Some(DialectType::ClickHouse) {
23379 self.write("Enum(");
23380 } else {
23381 self.write_keyword("ENUM(");
23382 }
23383 for (i, val) in values.iter().enumerate() {
23384 if i > 0 {
23385 self.write(", ");
23386 }
23387 self.write("'");
23388 self.write(val);
23389 self.write("'");
23390 if let Some(Some(assignment)) = assignments.get(i) {
23391 self.write(" = ");
23392 self.write(assignment);
23393 }
23394 }
23395 self.write(")");
23396 }
23397 DataType::Set { values } => {
23398 self.write_keyword("SET(");
23400 for (i, val) in values.iter().enumerate() {
23401 if i > 0 {
23402 self.write(", ");
23403 }
23404 self.write("'");
23405 self.write(val);
23406 self.write("'");
23407 }
23408 self.write(")");
23409 }
23410 DataType::Union { fields } => {
23411 self.write_keyword("UNION(");
23413 for (i, (name, dt)) in fields.iter().enumerate() {
23414 if i > 0 {
23415 self.write(", ");
23416 }
23417 if !name.is_empty() {
23418 self.write(name);
23419 self.write(" ");
23420 }
23421 self.generate_data_type(dt)?;
23422 }
23423 self.write(")");
23424 }
23425 DataType::Nullable { inner } => {
23426 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23428 self.write("Nullable(");
23429 let saved_depth = self.clickhouse_nullable_depth;
23431 self.clickhouse_nullable_depth = -1;
23432 self.generate_data_type(inner)?;
23433 self.clickhouse_nullable_depth = saved_depth;
23434 self.write(")");
23435 } else {
23436 match inner.as_ref() {
23438 DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
23439 self.generate_data_type(&DataType::Timestamp {
23440 precision: None,
23441 timezone: false,
23442 })?;
23443 }
23444 _ => {
23445 self.generate_data_type(inner)?;
23446 }
23447 }
23448 }
23449 }
23450 DataType::Custom { name } => {
23451 let name_upper = name.to_ascii_uppercase();
23453 match self.config.dialect {
23454 Some(DialectType::ClickHouse) => {
23455 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
23456 (name_upper[..idx].to_string(), &name[idx..])
23457 } else {
23458 (name_upper.clone(), "")
23459 };
23460 let mapped = match base_upper.as_str() {
23461 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
23462 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
23463 "DATETIME64" => "DateTime64",
23464 "DATE32" => "Date32",
23465 "INT" => "Int32",
23466 "MEDIUMINT" => "Int32",
23467 "INT8" => "Int8",
23468 "INT16" => "Int16",
23469 "INT32" => "Int32",
23470 "INT64" => "Int64",
23471 "INT128" => "Int128",
23472 "INT256" => "Int256",
23473 "UINT8" => "UInt8",
23474 "UINT16" => "UInt16",
23475 "UINT32" => "UInt32",
23476 "UINT64" => "UInt64",
23477 "UINT128" => "UInt128",
23478 "UINT256" => "UInt256",
23479 "FLOAT32" => "Float32",
23480 "FLOAT64" => "Float64",
23481 "DECIMAL32" => "Decimal32",
23482 "DECIMAL64" => "Decimal64",
23483 "DECIMAL128" => "Decimal128",
23484 "DECIMAL256" => "Decimal256",
23485 "ENUM" => "Enum",
23486 "ENUM8" => "Enum8",
23487 "ENUM16" => "Enum16",
23488 "FIXEDSTRING" => "FixedString",
23489 "NESTED" => "Nested",
23490 "LOWCARDINALITY" => "LowCardinality",
23491 "NULLABLE" => "Nullable",
23492 "IPV4" => "IPv4",
23493 "IPV6" => "IPv6",
23494 "POINT" => "Point",
23495 "RING" => "Ring",
23496 "LINESTRING" => "LineString",
23497 "MULTILINESTRING" => "MultiLineString",
23498 "POLYGON" => "Polygon",
23499 "MULTIPOLYGON" => "MultiPolygon",
23500 "AGGREGATEFUNCTION" => "AggregateFunction",
23501 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
23502 "DYNAMIC" => "Dynamic",
23503 _ => "",
23504 };
23505 if mapped.is_empty() {
23506 self.write(name);
23507 } else {
23508 self.write(mapped);
23509 self.write(suffix);
23510 }
23511 }
23512 Some(DialectType::MySQL)
23513 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
23514 {
23515 self.write_keyword("TIMESTAMP");
23517 }
23518 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
23519 self.write_keyword("SQL_VARIANT");
23520 }
23521 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
23522 self.write_keyword("DECIMAL(38, 5)");
23523 }
23524 Some(DialectType::Exasol) => {
23525 match name_upper.as_str() {
23527 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
23529 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
23531 "MEDIUMINT" => self.write_keyword("INT"),
23533 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
23535 self.write_keyword("DECIMAL")
23536 }
23537 "DATETIME" => self.write_keyword("TIMESTAMP"),
23539 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
23540 _ => self.write(name),
23541 }
23542 }
23543 Some(DialectType::Dremio) => {
23544 match name_upper.as_str() {
23546 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
23547 "ARRAY" => self.write_keyword("LIST"),
23548 "NCHAR" => self.write_keyword("VARCHAR"),
23549 _ => self.write(name),
23550 }
23551 }
23552 _ => {
23554 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
23556 (name_upper[..idx].to_string(), Some(&name[idx..]))
23557 } else {
23558 (name_upper.clone(), None)
23559 };
23560
23561 match base_upper.as_str() {
23562 "INT64"
23563 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
23564 {
23565 self.write_keyword("BIGINT");
23566 }
23567 "FLOAT64"
23568 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
23569 {
23570 self.write_keyword("DOUBLE");
23571 }
23572 "BOOL"
23573 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
23574 {
23575 self.write_keyword("BOOLEAN");
23576 }
23577 "BYTES"
23578 if matches!(
23579 self.config.dialect,
23580 Some(DialectType::Spark)
23581 | Some(DialectType::Hive)
23582 | Some(DialectType::Databricks)
23583 ) =>
23584 {
23585 self.write_keyword("BINARY");
23586 }
23587 "BYTES"
23588 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
23589 {
23590 self.write_keyword("VARBINARY");
23591 }
23592 "DATETIME2" | "SMALLDATETIME"
23594 if !matches!(
23595 self.config.dialect,
23596 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23597 ) =>
23598 {
23599 if matches!(
23601 self.config.dialect,
23602 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
23603 ) {
23604 self.write_keyword("TIMESTAMP");
23605 if let Some(args) = _args_str {
23606 self.write(args);
23607 }
23608 } else {
23609 self.write_keyword("TIMESTAMP");
23610 }
23611 }
23612 "DATETIMEOFFSET"
23614 if !matches!(
23615 self.config.dialect,
23616 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23617 ) =>
23618 {
23619 if matches!(
23620 self.config.dialect,
23621 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
23622 ) {
23623 self.write_keyword("TIMESTAMPTZ");
23624 if let Some(args) = _args_str {
23625 self.write(args);
23626 }
23627 } else {
23628 self.write_keyword("TIMESTAMPTZ");
23629 }
23630 }
23631 "UNIQUEIDENTIFIER"
23633 if !matches!(
23634 self.config.dialect,
23635 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23636 ) =>
23637 {
23638 match self.config.dialect {
23639 Some(DialectType::Spark)
23640 | Some(DialectType::Databricks)
23641 | Some(DialectType::Hive) => self.write_keyword("STRING"),
23642 _ => self.write_keyword("UUID"),
23643 }
23644 }
23645 "BIT"
23647 if !matches!(
23648 self.config.dialect,
23649 Some(DialectType::TSQL)
23650 | Some(DialectType::Fabric)
23651 | Some(DialectType::PostgreSQL)
23652 | Some(DialectType::MySQL)
23653 | Some(DialectType::DuckDB)
23654 ) =>
23655 {
23656 self.write_keyword("BOOLEAN");
23657 }
23658 "NVARCHAR"
23660 if !matches!(
23661 self.config.dialect,
23662 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23663 ) =>
23664 {
23665 match self.config.dialect {
23666 Some(DialectType::Oracle) => {
23667 self.write_keyword("NVARCHAR2");
23669 if let Some(args) = _args_str {
23670 self.write(args);
23671 }
23672 }
23673 Some(DialectType::BigQuery) => {
23674 self.write_keyword("STRING");
23676 }
23677 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
23678 self.write_keyword("TEXT");
23679 if let Some(args) = _args_str {
23680 self.write(args);
23681 }
23682 }
23683 Some(DialectType::Hive) => {
23684 self.write_keyword("STRING");
23686 }
23687 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
23688 if _args_str.is_some() {
23689 self.write_keyword("VARCHAR");
23690 self.write(_args_str.unwrap());
23691 } else {
23692 self.write_keyword("STRING");
23693 }
23694 }
23695 _ => {
23696 self.write_keyword("VARCHAR");
23697 if let Some(args) = _args_str {
23698 self.write(args);
23699 }
23700 }
23701 }
23702 }
23703 "NCHAR"
23705 if !matches!(
23706 self.config.dialect,
23707 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23708 ) =>
23709 {
23710 match self.config.dialect {
23711 Some(DialectType::Oracle) => {
23712 self.write_keyword("NCHAR");
23714 if let Some(args) = _args_str {
23715 self.write(args);
23716 }
23717 }
23718 Some(DialectType::BigQuery) => {
23719 self.write_keyword("STRING");
23721 }
23722 Some(DialectType::Hive) => {
23723 self.write_keyword("STRING");
23725 }
23726 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
23727 self.write_keyword("TEXT");
23728 if let Some(args) = _args_str {
23729 self.write(args);
23730 }
23731 }
23732 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
23733 if _args_str.is_some() {
23734 self.write_keyword("CHAR");
23735 self.write(_args_str.unwrap());
23736 } else {
23737 self.write_keyword("STRING");
23738 }
23739 }
23740 _ => {
23741 self.write_keyword("CHAR");
23742 if let Some(args) = _args_str {
23743 self.write(args);
23744 }
23745 }
23746 }
23747 }
23748 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
23751 Some(DialectType::MySQL)
23752 | Some(DialectType::SingleStore)
23753 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
23754 Some(DialectType::Spark)
23755 | Some(DialectType::Databricks)
23756 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
23757 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
23758 Some(DialectType::Presto)
23759 | Some(DialectType::Trino)
23760 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
23761 Some(DialectType::Snowflake)
23762 | Some(DialectType::Redshift)
23763 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
23764 _ => self.write_keyword("TEXT"),
23765 },
23766 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
23769 Some(DialectType::MySQL)
23770 | Some(DialectType::SingleStore)
23771 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
23772 Some(DialectType::Spark)
23773 | Some(DialectType::Databricks)
23774 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
23775 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
23776 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
23777 Some(DialectType::Presto)
23778 | Some(DialectType::Trino)
23779 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
23780 Some(DialectType::Snowflake)
23781 | Some(DialectType::Redshift)
23782 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
23783 _ => self.write_keyword("BLOB"),
23784 },
23785 "LONGVARCHAR" => match self.config.dialect {
23787 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
23788 _ => self.write_keyword("VARCHAR"),
23789 },
23790 "DATETIME" => {
23792 match self.config.dialect {
23793 Some(DialectType::MySQL)
23794 | Some(DialectType::Doris)
23795 | Some(DialectType::StarRocks)
23796 | Some(DialectType::TSQL)
23797 | Some(DialectType::Fabric)
23798 | Some(DialectType::BigQuery)
23799 | Some(DialectType::SQLite)
23800 | Some(DialectType::Snowflake) => {
23801 self.write_keyword("DATETIME");
23802 if let Some(args) = _args_str {
23803 self.write(args);
23804 }
23805 }
23806 Some(_) => {
23807 self.write_keyword("TIMESTAMP");
23809 if let Some(args) = _args_str {
23810 self.write(args);
23811 }
23812 }
23813 None => {
23814 self.write(name);
23816 }
23817 }
23818 }
23819 "VARCHAR2"
23821 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
23822 {
23823 match self.config.dialect {
23824 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23825 self.write_keyword("TEXT");
23826 }
23827 Some(DialectType::Hive)
23828 | Some(DialectType::Spark)
23829 | Some(DialectType::Databricks)
23830 | Some(DialectType::BigQuery)
23831 | Some(DialectType::ClickHouse)
23832 | Some(DialectType::StarRocks)
23833 | Some(DialectType::Doris) => {
23834 self.write_keyword("STRING");
23835 }
23836 _ => {
23837 self.write_keyword("VARCHAR");
23838 if let Some(args) = _args_str {
23839 self.write(args);
23840 }
23841 }
23842 }
23843 }
23844 "NVARCHAR2"
23845 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
23846 {
23847 match self.config.dialect {
23848 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23849 self.write_keyword("TEXT");
23850 }
23851 Some(DialectType::Hive)
23852 | Some(DialectType::Spark)
23853 | Some(DialectType::Databricks)
23854 | Some(DialectType::BigQuery)
23855 | Some(DialectType::ClickHouse)
23856 | Some(DialectType::StarRocks)
23857 | Some(DialectType::Doris) => {
23858 self.write_keyword("STRING");
23859 }
23860 _ => {
23861 self.write_keyword("VARCHAR");
23862 if let Some(args) = _args_str {
23863 self.write(args);
23864 }
23865 }
23866 }
23867 }
23868 _ => self.write(name),
23869 }
23870 }
23871 }
23872 }
23873 DataType::Geometry { subtype, srid } => {
23874 match self.config.dialect {
23876 Some(DialectType::MySQL) => {
23877 if let Some(sub) = subtype {
23879 self.write_keyword(sub);
23880 if let Some(s) = srid {
23881 self.write(" SRID ");
23882 self.write(&s.to_string());
23883 }
23884 } else {
23885 self.write_keyword("GEOMETRY");
23886 }
23887 }
23888 Some(DialectType::BigQuery) => {
23889 self.write_keyword("GEOGRAPHY");
23891 }
23892 Some(DialectType::Teradata) => {
23893 self.write_keyword("ST_GEOMETRY");
23895 if subtype.is_some() || srid.is_some() {
23896 self.write("(");
23897 if let Some(sub) = subtype {
23898 self.write_keyword(sub);
23899 }
23900 if let Some(s) = srid {
23901 if subtype.is_some() {
23902 self.write(", ");
23903 }
23904 self.write(&s.to_string());
23905 }
23906 self.write(")");
23907 }
23908 }
23909 _ => {
23910 self.write_keyword("GEOMETRY");
23912 if subtype.is_some() || srid.is_some() {
23913 self.write("(");
23914 if let Some(sub) = subtype {
23915 self.write_keyword(sub);
23916 }
23917 if let Some(s) = srid {
23918 if subtype.is_some() {
23919 self.write(", ");
23920 }
23921 self.write(&s.to_string());
23922 }
23923 self.write(")");
23924 }
23925 }
23926 }
23927 }
23928 DataType::Geography { subtype, srid } => {
23929 match self.config.dialect {
23931 Some(DialectType::MySQL) => {
23932 if let Some(sub) = subtype {
23934 self.write_keyword(sub);
23935 } else {
23936 self.write_keyword("GEOMETRY");
23937 }
23938 let effective_srid = srid.unwrap_or(4326);
23940 self.write(" SRID ");
23941 self.write(&effective_srid.to_string());
23942 }
23943 Some(DialectType::BigQuery) => {
23944 self.write_keyword("GEOGRAPHY");
23946 }
23947 Some(DialectType::Snowflake) => {
23948 self.write_keyword("GEOGRAPHY");
23950 }
23951 _ => {
23952 self.write_keyword("GEOGRAPHY");
23954 if subtype.is_some() || srid.is_some() {
23955 self.write("(");
23956 if let Some(sub) = subtype {
23957 self.write_keyword(sub);
23958 }
23959 if let Some(s) = srid {
23960 if subtype.is_some() {
23961 self.write(", ");
23962 }
23963 self.write(&s.to_string());
23964 }
23965 self.write(")");
23966 }
23967 }
23968 }
23969 }
23970 DataType::CharacterSet { name } => {
23971 self.write_keyword("CHAR CHARACTER SET ");
23973 self.write(name);
23974 }
23975 _ => self.write("UNKNOWN"),
23976 }
23977 Ok(())
23978 }
23979
23980 #[inline]
23983 fn write(&mut self, s: &str) {
23984 self.output.push_str(s);
23985 }
23986
23987 #[inline]
23988 fn write_space(&mut self) {
23989 self.output.push(' ');
23990 }
23991
23992 #[inline]
23993 fn write_keyword(&mut self, keyword: &str) {
23994 if self.config.uppercase_keywords {
23995 self.output.push_str(keyword);
23996 } else {
23997 for b in keyword.bytes() {
23998 self.output.push(b.to_ascii_lowercase() as char);
23999 }
24000 }
24001 }
24002
24003 fn write_func_name(&mut self, name: &str) {
24005 let normalized = self.normalize_func_name(name);
24006 self.output.push_str(normalized.as_ref());
24007 }
24008
24009 fn convert_strptime_to_exasol_format(format: &str) -> String {
24013 let mut result = String::new();
24014 let chars: Vec<char> = format.chars().collect();
24015 let mut i = 0;
24016 while i < chars.len() {
24017 if chars[i] == '%' && i + 1 < chars.len() {
24018 let spec = chars[i + 1];
24019 let exasol_spec = match spec {
24020 'Y' => "YYYY",
24021 'y' => "YY",
24022 'm' => "MM",
24023 'd' => "DD",
24024 'H' => "HH",
24025 'M' => "MI",
24026 'S' => "SS",
24027 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
24039 result.push('%');
24041 result.push(spec);
24042 i += 2;
24043 continue;
24044 }
24045 };
24046 result.push_str(exasol_spec);
24047 i += 2;
24048 } else {
24049 result.push(chars[i]);
24050 i += 1;
24051 }
24052 }
24053 result
24054 }
24055
24056 fn convert_strptime_to_postgres_format(format: &str) -> String {
24060 let mut result = String::new();
24061 let chars: Vec<char> = format.chars().collect();
24062 let mut i = 0;
24063 while i < chars.len() {
24064 if chars[i] == '%' && i + 1 < chars.len() {
24065 if chars[i + 1] == '-' && i + 2 < chars.len() {
24067 let spec = chars[i + 2];
24068 let pg_spec = match spec {
24069 'd' => "FMDD",
24070 'm' => "FMMM",
24071 'H' => "FMHH24",
24072 'M' => "FMMI",
24073 'S' => "FMSS",
24074 _ => {
24075 result.push('%');
24076 result.push('-');
24077 result.push(spec);
24078 i += 3;
24079 continue;
24080 }
24081 };
24082 result.push_str(pg_spec);
24083 i += 3;
24084 continue;
24085 }
24086 let spec = chars[i + 1];
24087 let pg_spec = match spec {
24088 'Y' => "YYYY",
24089 'y' => "YY",
24090 'm' => "MM",
24091 'd' => "DD",
24092 'H' => "HH24",
24093 'I' => "HH12",
24094 'M' => "MI",
24095 'S' => "SS",
24096 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
24107 result.push('%');
24109 result.push(spec);
24110 i += 2;
24111 continue;
24112 }
24113 };
24114 result.push_str(pg_spec);
24115 i += 2;
24116 } else {
24117 result.push(chars[i]);
24118 i += 1;
24119 }
24120 }
24121 result
24122 }
24123
24124 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
24126 if self.config.limit_only_literals {
24127 if let Some(value) = Self::try_evaluate_constant(expr) {
24128 self.write(&value.to_string());
24129 return Ok(());
24130 }
24131 }
24132 self.generate_expression(expr)
24133 }
24134
24135 fn write_formatted_comment(&mut self, comment: &str) {
24139 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
24142 &comment[2..comment.len() - 2]
24145 } else if comment.starts_with("--") {
24146 &comment[2..]
24149 } else {
24150 comment
24152 };
24153 if content.trim().is_empty() {
24155 return;
24156 }
24157 self.output.push_str("/*");
24159 if !content.starts_with(' ') {
24160 self.output.push(' ');
24161 }
24162 self.output.push_str(content);
24163 if !content.ends_with(' ') {
24164 self.output.push(' ');
24165 }
24166 self.output.push_str("*/");
24167 }
24168
24169 fn escape_block_for_single_quote(&self, block: &str) -> String {
24172 let escape_backslash = matches!(
24173 self.config.dialect,
24174 Some(crate::dialects::DialectType::Snowflake)
24175 );
24176 let mut escaped = String::with_capacity(block.len() + 4);
24177 for ch in block.chars() {
24178 if ch == '\'' {
24179 escaped.push('\\');
24180 escaped.push('\'');
24181 } else if escape_backslash && ch == '\\' {
24182 escaped.push('\\');
24183 escaped.push('\\');
24184 } else {
24185 escaped.push(ch);
24186 }
24187 }
24188 escaped
24189 }
24190
24191 fn write_newline(&mut self) {
24192 self.output.push('\n');
24193 }
24194
24195 fn write_indent(&mut self) {
24196 for _ in 0..self.indent_level {
24197 self.output.push_str(self.config.indent);
24198 }
24199 }
24200
24201 fn too_wide(&self, args: &[String]) -> bool {
24207 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
24208 }
24209
24210 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
24213 let config = GeneratorConfig {
24214 pretty: false,
24215 dialect: self.config.dialect,
24216 ..Default::default()
24217 };
24218 let mut gen = Generator::with_config(config);
24219 gen.generate_expression(expr)?;
24220 Ok(gen.output)
24221 }
24222
24223 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
24226 if self.config.pretty {
24227 self.write_newline();
24228 self.write_indent();
24229 self.write_keyword(keyword);
24230 self.write_newline();
24231 self.indent_level += 1;
24232 self.write_indent();
24233 self.generate_expression(condition)?;
24234 self.indent_level -= 1;
24235 } else {
24236 self.write_space();
24237 self.write_keyword(keyword);
24238 self.write_space();
24239 self.generate_expression(condition)?;
24240 }
24241 Ok(())
24242 }
24243
24244 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
24247 if exprs.is_empty() {
24248 return Ok(());
24249 }
24250
24251 if self.config.pretty {
24252 self.write_newline();
24253 self.write_indent();
24254 self.write_keyword(keyword);
24255 self.write_newline();
24256 self.indent_level += 1;
24257 for (i, expr) in exprs.iter().enumerate() {
24258 if i > 0 {
24259 self.write(",");
24260 self.write_newline();
24261 }
24262 self.write_indent();
24263 self.generate_expression(expr)?;
24264 }
24265 self.indent_level -= 1;
24266 } else {
24267 self.write_space();
24268 self.write_keyword(keyword);
24269 self.write_space();
24270 for (i, expr) in exprs.iter().enumerate() {
24271 if i > 0 {
24272 self.write(", ");
24273 }
24274 self.generate_expression(expr)?;
24275 }
24276 }
24277 Ok(())
24278 }
24279
24280 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
24282 if orderings.is_empty() {
24283 return Ok(());
24284 }
24285
24286 if self.config.pretty {
24287 self.write_newline();
24288 self.write_indent();
24289 self.write_keyword(keyword);
24290 self.write_newline();
24291 self.indent_level += 1;
24292 for (i, ordered) in orderings.iter().enumerate() {
24293 if i > 0 {
24294 self.write(",");
24295 self.write_newline();
24296 }
24297 self.write_indent();
24298 self.generate_ordered(ordered)?;
24299 }
24300 self.indent_level -= 1;
24301 } else {
24302 self.write_space();
24303 self.write_keyword(keyword);
24304 self.write_space();
24305 for (i, ordered) in orderings.iter().enumerate() {
24306 if i > 0 {
24307 self.write(", ");
24308 }
24309 self.generate_ordered(ordered)?;
24310 }
24311 }
24312 Ok(())
24313 }
24314
24315 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
24317 if windows.is_empty() {
24318 return Ok(());
24319 }
24320
24321 if self.config.pretty {
24322 self.write_newline();
24323 self.write_indent();
24324 self.write_keyword("WINDOW");
24325 self.write_newline();
24326 self.indent_level += 1;
24327 for (i, named_window) in windows.iter().enumerate() {
24328 if i > 0 {
24329 self.write(",");
24330 self.write_newline();
24331 }
24332 self.write_indent();
24333 self.generate_identifier(&named_window.name)?;
24334 self.write_space();
24335 self.write_keyword("AS");
24336 self.write(" (");
24337 self.generate_over(&named_window.spec)?;
24338 self.write(")");
24339 }
24340 self.indent_level -= 1;
24341 } else {
24342 self.write_space();
24343 self.write_keyword("WINDOW");
24344 self.write_space();
24345 for (i, named_window) in windows.iter().enumerate() {
24346 if i > 0 {
24347 self.write(", ");
24348 }
24349 self.generate_identifier(&named_window.name)?;
24350 self.write_space();
24351 self.write_keyword("AS");
24352 self.write(" (");
24353 self.generate_over(&named_window.spec)?;
24354 self.write(")");
24355 }
24356 }
24357 Ok(())
24358 }
24359
24360 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
24362 self.write_keyword("AI_AGG");
24364 self.write("(");
24365 self.generate_expression(&e.this)?;
24366 self.write(", ");
24367 self.generate_expression(&e.expression)?;
24368 self.write(")");
24369 Ok(())
24370 }
24371
24372 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
24373 self.write_keyword("AI_CLASSIFY");
24375 self.write("(");
24376 self.generate_expression(&e.this)?;
24377 if let Some(categories) = &e.categories {
24378 self.write(", ");
24379 self.generate_expression(categories)?;
24380 }
24381 if let Some(config) = &e.config {
24382 self.write(", ");
24383 self.generate_expression(config)?;
24384 }
24385 self.write(")");
24386 Ok(())
24387 }
24388
24389 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
24390 self.write_keyword("ADD");
24392 self.write_space();
24393 if e.exists {
24394 self.write_keyword("IF NOT EXISTS");
24395 self.write_space();
24396 }
24397 self.generate_expression(&e.this)?;
24398 if let Some(location) = &e.location {
24399 self.write_space();
24400 self.generate_expression(location)?;
24401 }
24402 Ok(())
24403 }
24404
24405 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
24406 self.write_keyword("ALGORITHM");
24408 self.write("=");
24409 self.generate_expression(&e.this)?;
24410 Ok(())
24411 }
24412
24413 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
24414 self.generate_expression(&e.this)?;
24416 self.write_space();
24417 self.write_keyword("AS");
24418 self.write(" (");
24419 for (i, expr) in e.expressions.iter().enumerate() {
24420 if i > 0 {
24421 self.write(", ");
24422 }
24423 self.generate_expression(expr)?;
24424 }
24425 self.write(")");
24426 Ok(())
24427 }
24428
24429 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
24430 self.write_keyword("ALLOWED_VALUES");
24432 self.write_space();
24433 for (i, expr) in e.expressions.iter().enumerate() {
24434 if i > 0 {
24435 self.write(", ");
24436 }
24437 self.generate_expression(expr)?;
24438 }
24439 Ok(())
24440 }
24441
24442 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
24443 self.write_keyword("ALTER COLUMN");
24445 self.write_space();
24446 self.generate_expression(&e.this)?;
24447
24448 if let Some(dtype) = &e.dtype {
24449 self.write_space();
24450 self.write_keyword("SET DATA TYPE");
24451 self.write_space();
24452 self.generate_expression(dtype)?;
24453 if let Some(collate) = &e.collate {
24454 self.write_space();
24455 self.write_keyword("COLLATE");
24456 self.write_space();
24457 self.generate_expression(collate)?;
24458 }
24459 if let Some(using) = &e.using {
24460 self.write_space();
24461 self.write_keyword("USING");
24462 self.write_space();
24463 self.generate_expression(using)?;
24464 }
24465 } else if let Some(default) = &e.default {
24466 self.write_space();
24467 self.write_keyword("SET DEFAULT");
24468 self.write_space();
24469 self.generate_expression(default)?;
24470 } else if let Some(comment) = &e.comment {
24471 self.write_space();
24472 self.write_keyword("COMMENT");
24473 self.write_space();
24474 self.generate_expression(comment)?;
24475 } else if let Some(drop) = &e.drop {
24476 self.write_space();
24477 self.write_keyword("DROP");
24478 self.write_space();
24479 self.generate_expression(drop)?;
24480 } else if let Some(visible) = &e.visible {
24481 self.write_space();
24482 self.generate_expression(visible)?;
24483 } else if let Some(rename_to) = &e.rename_to {
24484 self.write_space();
24485 self.write_keyword("RENAME TO");
24486 self.write_space();
24487 self.generate_expression(rename_to)?;
24488 } else if let Some(allow_null) = &e.allow_null {
24489 self.write_space();
24490 self.generate_expression(allow_null)?;
24491 }
24492 Ok(())
24493 }
24494
24495 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
24496 self.write_keyword("ALTER SESSION");
24498 self.write_space();
24499 if e.unset.is_some() {
24500 self.write_keyword("UNSET");
24501 } else {
24502 self.write_keyword("SET");
24503 }
24504 self.write_space();
24505 for (i, expr) in e.expressions.iter().enumerate() {
24506 if i > 0 {
24507 self.write(", ");
24508 }
24509 self.generate_expression(expr)?;
24510 }
24511 Ok(())
24512 }
24513
24514 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
24515 self.write_keyword("SET");
24517
24518 if let Some(opt) = &e.option {
24520 self.write_space();
24521 self.generate_expression(opt)?;
24522 }
24523
24524 if !e.expressions.is_empty() {
24527 let is_properties = e
24529 .expressions
24530 .iter()
24531 .any(|expr| matches!(expr, Expression::Eq(_)));
24532 if is_properties && e.option.is_none() {
24533 self.write_space();
24534 self.write_keyword("PROPERTIES");
24535 }
24536 self.write_space();
24537 for (i, expr) in e.expressions.iter().enumerate() {
24538 if i > 0 {
24539 self.write(", ");
24540 }
24541 self.generate_expression(expr)?;
24542 }
24543 }
24544
24545 if let Some(file_format) = &e.file_format {
24547 self.write(" ");
24548 self.write_keyword("STAGE_FILE_FORMAT");
24549 self.write(" = (");
24550 self.generate_space_separated_properties(file_format)?;
24551 self.write(")");
24552 }
24553
24554 if let Some(copy_options) = &e.copy_options {
24556 self.write(" ");
24557 self.write_keyword("STAGE_COPY_OPTIONS");
24558 self.write(" = (");
24559 self.generate_space_separated_properties(copy_options)?;
24560 self.write(")");
24561 }
24562
24563 if let Some(tag) = &e.tag {
24565 self.write(" ");
24566 self.write_keyword("TAG");
24567 self.write(" ");
24568 self.generate_expression(tag)?;
24569 }
24570
24571 Ok(())
24572 }
24573
24574 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
24576 match expr {
24577 Expression::Tuple(t) => {
24578 for (i, prop) in t.expressions.iter().enumerate() {
24579 if i > 0 {
24580 self.write(" ");
24581 }
24582 self.generate_expression(prop)?;
24583 }
24584 }
24585 _ => {
24586 self.generate_expression(expr)?;
24587 }
24588 }
24589 Ok(())
24590 }
24591
24592 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
24593 self.write_keyword("ALTER");
24595 if e.compound.is_some() {
24596 self.write_space();
24597 self.write_keyword("COMPOUND");
24598 }
24599 self.write_space();
24600 self.write_keyword("SORTKEY");
24601 self.write_space();
24602 if let Some(this) = &e.this {
24603 self.generate_expression(this)?;
24604 } else if !e.expressions.is_empty() {
24605 self.write("(");
24606 for (i, expr) in e.expressions.iter().enumerate() {
24607 if i > 0 {
24608 self.write(", ");
24609 }
24610 self.generate_expression(expr)?;
24611 }
24612 self.write(")");
24613 }
24614 Ok(())
24615 }
24616
24617 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
24618 self.write_keyword("ANALYZE");
24620 if !e.options.is_empty() {
24621 self.write_space();
24622 for (i, opt) in e.options.iter().enumerate() {
24623 if i > 0 {
24624 self.write_space();
24625 }
24626 if let Expression::Identifier(id) = opt {
24628 self.write_keyword(&id.name);
24629 } else {
24630 self.generate_expression(opt)?;
24631 }
24632 }
24633 }
24634 if let Some(kind) = &e.kind {
24635 self.write_space();
24636 self.write_keyword(kind);
24637 }
24638 if let Some(this) = &e.this {
24639 self.write_space();
24640 self.generate_expression(this)?;
24641 }
24642 if !e.columns.is_empty() {
24644 self.write("(");
24645 for (i, col) in e.columns.iter().enumerate() {
24646 if i > 0 {
24647 self.write(", ");
24648 }
24649 self.write(col);
24650 }
24651 self.write(")");
24652 }
24653 if let Some(partition) = &e.partition {
24654 self.write_space();
24655 self.generate_expression(partition)?;
24656 }
24657 if let Some(mode) = &e.mode {
24658 self.write_space();
24659 self.generate_expression(mode)?;
24660 }
24661 if let Some(expression) = &e.expression {
24662 self.write_space();
24663 self.generate_expression(expression)?;
24664 }
24665 if !e.properties.is_empty() {
24666 self.write_space();
24667 self.write_keyword(self.config.with_properties_prefix);
24668 self.write(" (");
24669 for (i, prop) in e.properties.iter().enumerate() {
24670 if i > 0 {
24671 self.write(", ");
24672 }
24673 self.generate_expression(prop)?;
24674 }
24675 self.write(")");
24676 }
24677 Ok(())
24678 }
24679
24680 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
24681 self.write_keyword("DELETE");
24683 if let Some(kind) = &e.kind {
24684 self.write_space();
24685 self.write_keyword(kind);
24686 }
24687 self.write_space();
24688 self.write_keyword("STATISTICS");
24689 Ok(())
24690 }
24691
24692 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
24693 if let Expression::Identifier(id) = e.this.as_ref() {
24696 self.write_keyword(&id.name);
24697 } else {
24698 self.generate_expression(&e.this)?;
24699 }
24700 self.write_space();
24701 self.write_keyword("HISTOGRAM ON");
24702 self.write_space();
24703 for (i, expr) in e.expressions.iter().enumerate() {
24704 if i > 0 {
24705 self.write(", ");
24706 }
24707 self.generate_expression(expr)?;
24708 }
24709 if let Some(expression) = &e.expression {
24710 self.write_space();
24711 self.generate_expression(expression)?;
24712 }
24713 if let Some(update_options) = &e.update_options {
24714 self.write_space();
24715 self.generate_expression(update_options)?;
24716 self.write_space();
24717 self.write_keyword("UPDATE");
24718 }
24719 Ok(())
24720 }
24721
24722 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
24723 self.write_keyword("LIST CHAINED ROWS");
24725 if let Some(expression) = &e.expression {
24726 self.write_space();
24727 self.write_keyword("INTO");
24728 self.write_space();
24729 self.generate_expression(expression)?;
24730 }
24731 Ok(())
24732 }
24733
24734 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
24735 self.write_keyword("SAMPLE");
24737 self.write_space();
24738 if let Some(sample) = &e.sample {
24739 self.generate_expression(sample)?;
24740 self.write_space();
24741 }
24742 self.write_keyword(&e.kind);
24743 Ok(())
24744 }
24745
24746 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
24747 self.write_keyword(&e.kind);
24749 if let Some(option) = &e.option {
24750 self.write_space();
24751 self.generate_expression(option)?;
24752 }
24753 self.write_space();
24754 self.write_keyword("STATISTICS");
24755 if let Some(this) = &e.this {
24756 self.write_space();
24757 self.generate_expression(this)?;
24758 }
24759 if !e.expressions.is_empty() {
24760 self.write_space();
24761 for (i, expr) in e.expressions.iter().enumerate() {
24762 if i > 0 {
24763 self.write(", ");
24764 }
24765 self.generate_expression(expr)?;
24766 }
24767 }
24768 Ok(())
24769 }
24770
24771 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
24772 self.write_keyword("VALIDATE");
24774 self.write_space();
24775 self.write_keyword(&e.kind);
24776 if let Some(this) = &e.this {
24777 self.write_space();
24778 if let Expression::Identifier(id) = this.as_ref() {
24780 self.write_keyword(&id.name);
24781 } else {
24782 self.generate_expression(this)?;
24783 }
24784 }
24785 if let Some(expression) = &e.expression {
24786 self.write_space();
24787 self.write_keyword("INTO");
24788 self.write_space();
24789 self.generate_expression(expression)?;
24790 }
24791 Ok(())
24792 }
24793
24794 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
24795 self.write_keyword("WITH");
24797 self.write_space();
24798 for (i, expr) in e.expressions.iter().enumerate() {
24799 if i > 0 {
24800 self.write(", ");
24801 }
24802 self.generate_expression(expr)?;
24803 }
24804 Ok(())
24805 }
24806
24807 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
24808 self.generate_expression(&e.this)?;
24811 self.write("(");
24812 for (i, arg) in e.expressions.iter().enumerate() {
24813 if i > 0 {
24814 self.write(", ");
24815 }
24816 self.generate_expression(arg)?;
24817 }
24818 self.write(")");
24819 Ok(())
24820 }
24821
24822 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
24823 self.generate_expression(&e.this)?;
24825 self.write("(");
24826 for (i, arg) in e.expressions.iter().enumerate() {
24827 if i > 0 {
24828 self.write(", ");
24829 }
24830 self.generate_expression(arg)?;
24831 }
24832 self.write(")");
24833 Ok(())
24834 }
24835
24836 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
24837 self.generate_expression(&e.this)?;
24839 self.write_space();
24840 self.write_keyword("APPLY");
24841 self.write("(");
24842 self.generate_expression(&e.expression)?;
24843 self.write(")");
24844 Ok(())
24845 }
24846
24847 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
24848 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
24850 self.write("(");
24851 self.generate_expression(&e.this)?;
24852 if let Some(percentile) = &e.percentile {
24853 self.write(", ");
24854 self.generate_expression(percentile)?;
24855 }
24856 self.write(")");
24857 Ok(())
24858 }
24859
24860 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
24861 self.write_keyword("APPROX_QUANTILE");
24863 self.write("(");
24864 self.generate_expression(&e.this)?;
24865 if let Some(quantile) = &e.quantile {
24866 self.write(", ");
24867 self.generate_expression(quantile)?;
24868 }
24869 if let Some(accuracy) = &e.accuracy {
24870 self.write(", ");
24871 self.generate_expression(accuracy)?;
24872 }
24873 if let Some(weight) = &e.weight {
24874 self.write(", ");
24875 self.generate_expression(weight)?;
24876 }
24877 self.write(")");
24878 Ok(())
24879 }
24880
24881 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
24882 self.write_keyword("APPROX_QUANTILES");
24884 self.write("(");
24885 self.generate_expression(&e.this)?;
24886 if let Some(expression) = &e.expression {
24887 self.write(", ");
24888 self.generate_expression(expression)?;
24889 }
24890 self.write(")");
24891 Ok(())
24892 }
24893
24894 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
24895 self.write_keyword("APPROX_TOP_K");
24897 self.write("(");
24898 self.generate_expression(&e.this)?;
24899 if let Some(expression) = &e.expression {
24900 self.write(", ");
24901 self.generate_expression(expression)?;
24902 }
24903 if let Some(counters) = &e.counters {
24904 self.write(", ");
24905 self.generate_expression(counters)?;
24906 }
24907 self.write(")");
24908 Ok(())
24909 }
24910
24911 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
24912 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
24914 self.write("(");
24915 self.generate_expression(&e.this)?;
24916 if let Some(expression) = &e.expression {
24917 self.write(", ");
24918 self.generate_expression(expression)?;
24919 }
24920 self.write(")");
24921 Ok(())
24922 }
24923
24924 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
24925 self.write_keyword("APPROX_TOP_K_COMBINE");
24927 self.write("(");
24928 self.generate_expression(&e.this)?;
24929 if let Some(expression) = &e.expression {
24930 self.write(", ");
24931 self.generate_expression(expression)?;
24932 }
24933 self.write(")");
24934 Ok(())
24935 }
24936
24937 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
24938 self.write_keyword("APPROX_TOP_K_ESTIMATE");
24940 self.write("(");
24941 self.generate_expression(&e.this)?;
24942 if let Some(expression) = &e.expression {
24943 self.write(", ");
24944 self.generate_expression(expression)?;
24945 }
24946 self.write(")");
24947 Ok(())
24948 }
24949
24950 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
24951 self.write_keyword("APPROX_TOP_SUM");
24953 self.write("(");
24954 self.generate_expression(&e.this)?;
24955 self.write(", ");
24956 self.generate_expression(&e.expression)?;
24957 if let Some(count) = &e.count {
24958 self.write(", ");
24959 self.generate_expression(count)?;
24960 }
24961 self.write(")");
24962 Ok(())
24963 }
24964
24965 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
24966 self.write_keyword("ARG_MAX");
24968 self.write("(");
24969 self.generate_expression(&e.this)?;
24970 self.write(", ");
24971 self.generate_expression(&e.expression)?;
24972 if let Some(count) = &e.count {
24973 self.write(", ");
24974 self.generate_expression(count)?;
24975 }
24976 self.write(")");
24977 Ok(())
24978 }
24979
24980 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
24981 self.write_keyword("ARG_MIN");
24983 self.write("(");
24984 self.generate_expression(&e.this)?;
24985 self.write(", ");
24986 self.generate_expression(&e.expression)?;
24987 if let Some(count) = &e.count {
24988 self.write(", ");
24989 self.generate_expression(count)?;
24990 }
24991 self.write(")");
24992 Ok(())
24993 }
24994
24995 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
24996 self.write_keyword("ARRAY_ALL");
24998 self.write("(");
24999 self.generate_expression(&e.this)?;
25000 self.write(", ");
25001 self.generate_expression(&e.expression)?;
25002 self.write(")");
25003 Ok(())
25004 }
25005
25006 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
25007 self.write_keyword("ARRAY_ANY");
25009 self.write("(");
25010 self.generate_expression(&e.this)?;
25011 self.write(", ");
25012 self.generate_expression(&e.expression)?;
25013 self.write(")");
25014 Ok(())
25015 }
25016
25017 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
25018 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
25020 self.write("(");
25021 for (i, expr) in e.expressions.iter().enumerate() {
25022 if i > 0 {
25023 self.write(", ");
25024 }
25025 self.generate_expression(expr)?;
25026 }
25027 self.write(")");
25028 Ok(())
25029 }
25030
25031 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
25032 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
25034 self.write("arraySum");
25035 } else {
25036 self.write_keyword("ARRAY_SUM");
25037 }
25038 self.write("(");
25039 self.generate_expression(&e.this)?;
25040 if let Some(expression) = &e.expression {
25041 self.write(", ");
25042 self.generate_expression(expression)?;
25043 }
25044 self.write(")");
25045 Ok(())
25046 }
25047
25048 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
25049 self.generate_expression(&e.this)?;
25051 self.write_space();
25052 self.write_keyword("AT");
25053 self.write_space();
25054 self.generate_expression(&e.expression)?;
25055 Ok(())
25056 }
25057
25058 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
25059 self.write_keyword("ATTACH");
25061 if e.exists {
25062 self.write_space();
25063 self.write_keyword("IF NOT EXISTS");
25064 }
25065 self.write_space();
25066 self.generate_expression(&e.this)?;
25067 if !e.expressions.is_empty() {
25068 self.write(" (");
25069 for (i, expr) in e.expressions.iter().enumerate() {
25070 if i > 0 {
25071 self.write(", ");
25072 }
25073 self.generate_expression(expr)?;
25074 }
25075 self.write(")");
25076 }
25077 Ok(())
25078 }
25079
25080 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
25081 self.generate_expression(&e.this)?;
25084 if let Some(expression) = &e.expression {
25085 self.write_space();
25086 self.generate_expression(expression)?;
25087 }
25088 Ok(())
25089 }
25090
25091 fn generate_auto_increment_keyword(
25095 &mut self,
25096 col: &crate::expressions::ColumnDef,
25097 ) -> Result<()> {
25098 use crate::dialects::DialectType;
25099 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
25100 self.write_keyword("IDENTITY");
25101 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25102 self.write("(");
25103 if let Some(ref start) = col.auto_increment_start {
25104 self.generate_expression(start)?;
25105 } else {
25106 self.write("0");
25107 }
25108 self.write(", ");
25109 if let Some(ref inc) = col.auto_increment_increment {
25110 self.generate_expression(inc)?;
25111 } else {
25112 self.write("1");
25113 }
25114 self.write(")");
25115 }
25116 } else if matches!(
25117 self.config.dialect,
25118 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
25119 ) {
25120 self.write_keyword("AUTOINCREMENT");
25121 if let Some(ref start) = col.auto_increment_start {
25122 self.write_space();
25123 self.write_keyword("START");
25124 self.write_space();
25125 self.generate_expression(start)?;
25126 }
25127 if let Some(ref inc) = col.auto_increment_increment {
25128 self.write_space();
25129 self.write_keyword("INCREMENT");
25130 self.write_space();
25131 self.generate_expression(inc)?;
25132 }
25133 if let Some(order) = col.auto_increment_order {
25134 self.write_space();
25135 if order {
25136 self.write_keyword("ORDER");
25137 } else {
25138 self.write_keyword("NOORDER");
25139 }
25140 }
25141 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
25142 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
25143 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25144 self.write(" (");
25145 let mut first = true;
25146 if let Some(ref start) = col.auto_increment_start {
25147 self.write_keyword("START WITH");
25148 self.write_space();
25149 self.generate_expression(start)?;
25150 first = false;
25151 }
25152 if let Some(ref inc) = col.auto_increment_increment {
25153 if !first {
25154 self.write_space();
25155 }
25156 self.write_keyword("INCREMENT BY");
25157 self.write_space();
25158 self.generate_expression(inc)?;
25159 }
25160 self.write(")");
25161 }
25162 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
25163 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25166 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
25167 } else {
25168 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
25169 }
25170 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25171 self.write(" (");
25172 let mut first = true;
25173 if let Some(ref start) = col.auto_increment_start {
25174 self.write_keyword("START WITH");
25175 self.write_space();
25176 self.generate_expression(start)?;
25177 first = false;
25178 }
25179 if let Some(ref inc) = col.auto_increment_increment {
25180 if !first {
25181 self.write_space();
25182 }
25183 self.write_keyword("INCREMENT BY");
25184 self.write_space();
25185 self.generate_expression(inc)?;
25186 }
25187 self.write(")");
25188 }
25189 } else if matches!(
25190 self.config.dialect,
25191 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25192 ) {
25193 self.write_keyword("IDENTITY");
25194 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25195 self.write("(");
25196 if let Some(ref start) = col.auto_increment_start {
25197 self.generate_expression(start)?;
25198 } else {
25199 self.write("0");
25200 }
25201 self.write(", ");
25202 if let Some(ref inc) = col.auto_increment_increment {
25203 self.generate_expression(inc)?;
25204 } else {
25205 self.write("1");
25206 }
25207 self.write(")");
25208 }
25209 } else {
25210 self.write_keyword("AUTO_INCREMENT");
25211 if let Some(ref start) = col.auto_increment_start {
25212 self.write_space();
25213 self.write_keyword("START");
25214 self.write_space();
25215 self.generate_expression(start)?;
25216 }
25217 if let Some(ref inc) = col.auto_increment_increment {
25218 self.write_space();
25219 self.write_keyword("INCREMENT");
25220 self.write_space();
25221 self.generate_expression(inc)?;
25222 }
25223 if let Some(order) = col.auto_increment_order {
25224 self.write_space();
25225 if order {
25226 self.write_keyword("ORDER");
25227 } else {
25228 self.write_keyword("NOORDER");
25229 }
25230 }
25231 }
25232 Ok(())
25233 }
25234
25235 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
25236 self.write_keyword("AUTO_INCREMENT");
25238 self.write("=");
25239 self.generate_expression(&e.this)?;
25240 Ok(())
25241 }
25242
25243 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
25244 self.write_keyword("AUTO_REFRESH");
25246 self.write("=");
25247 self.generate_expression(&e.this)?;
25248 Ok(())
25249 }
25250
25251 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
25252 self.write_keyword("BACKUP");
25254 self.write_space();
25255 self.generate_expression(&e.this)?;
25256 Ok(())
25257 }
25258
25259 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
25260 self.write_keyword("BASE64_DECODE_BINARY");
25262 self.write("(");
25263 self.generate_expression(&e.this)?;
25264 if let Some(alphabet) = &e.alphabet {
25265 self.write(", ");
25266 self.generate_expression(alphabet)?;
25267 }
25268 self.write(")");
25269 Ok(())
25270 }
25271
25272 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
25273 self.write_keyword("BASE64_DECODE_STRING");
25275 self.write("(");
25276 self.generate_expression(&e.this)?;
25277 if let Some(alphabet) = &e.alphabet {
25278 self.write(", ");
25279 self.generate_expression(alphabet)?;
25280 }
25281 self.write(")");
25282 Ok(())
25283 }
25284
25285 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
25286 self.write_keyword("BASE64_ENCODE");
25288 self.write("(");
25289 self.generate_expression(&e.this)?;
25290 if let Some(max_line_length) = &e.max_line_length {
25291 self.write(", ");
25292 self.generate_expression(max_line_length)?;
25293 }
25294 if let Some(alphabet) = &e.alphabet {
25295 self.write(", ");
25296 self.generate_expression(alphabet)?;
25297 }
25298 self.write(")");
25299 Ok(())
25300 }
25301
25302 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
25303 self.write_keyword("BLOCKCOMPRESSION");
25305 self.write("=");
25306 if let Some(autotemp) = &e.autotemp {
25307 self.write_keyword("AUTOTEMP");
25308 self.write("(");
25309 self.generate_expression(autotemp)?;
25310 self.write(")");
25311 }
25312 if let Some(always) = &e.always {
25313 self.generate_expression(always)?;
25314 }
25315 if let Some(default) = &e.default {
25316 self.generate_expression(default)?;
25317 }
25318 if let Some(manual) = &e.manual {
25319 self.generate_expression(manual)?;
25320 }
25321 if let Some(never) = &e.never {
25322 self.generate_expression(never)?;
25323 }
25324 Ok(())
25325 }
25326
25327 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
25328 self.write("((");
25330 self.generate_expression(&e.this)?;
25331 self.write(") ");
25332 self.write_keyword("AND");
25333 self.write(" (");
25334 self.generate_expression(&e.expression)?;
25335 self.write("))");
25336 Ok(())
25337 }
25338
25339 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
25340 self.write("((");
25342 self.generate_expression(&e.this)?;
25343 self.write(") ");
25344 self.write_keyword("OR");
25345 self.write(" (");
25346 self.generate_expression(&e.expression)?;
25347 self.write("))");
25348 Ok(())
25349 }
25350
25351 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
25352 self.write_keyword("BUILD");
25354 self.write_space();
25355 self.generate_expression(&e.this)?;
25356 Ok(())
25357 }
25358
25359 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
25360 self.generate_expression(&e.this)?;
25362 Ok(())
25363 }
25364
25365 fn generate_case_specific_column_constraint(
25366 &mut self,
25367 e: &CaseSpecificColumnConstraint,
25368 ) -> Result<()> {
25369 if e.not_.is_some() {
25371 self.write_keyword("NOT");
25372 self.write_space();
25373 }
25374 self.write_keyword("CASESPECIFIC");
25375 Ok(())
25376 }
25377
25378 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
25379 self.write_keyword("CAST");
25381 self.write("(");
25382 self.generate_expression(&e.this)?;
25383 if self.config.dialect == Some(DialectType::ClickHouse) {
25384 self.write(", ");
25386 } else {
25387 self.write_space();
25388 self.write_keyword("AS");
25389 self.write_space();
25390 }
25391 if let Some(to) = &e.to {
25392 self.generate_expression(to)?;
25393 }
25394 self.write(")");
25395 Ok(())
25396 }
25397
25398 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
25399 self.write_keyword("CHANGES");
25402 self.write(" (");
25403 if let Some(information) = &e.information {
25404 self.write_keyword("INFORMATION");
25405 self.write(" => ");
25406 self.generate_expression(information)?;
25407 }
25408 self.write(")");
25409 if let Some(at_before) = &e.at_before {
25411 self.write(" ");
25412 self.generate_expression(at_before)?;
25413 }
25414 if let Some(end) = &e.end {
25415 self.write(" ");
25416 self.generate_expression(end)?;
25417 }
25418 Ok(())
25419 }
25420
25421 fn generate_character_set_column_constraint(
25422 &mut self,
25423 e: &CharacterSetColumnConstraint,
25424 ) -> Result<()> {
25425 self.write_keyword("CHARACTER SET");
25427 self.write_space();
25428 self.generate_expression(&e.this)?;
25429 Ok(())
25430 }
25431
25432 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
25433 if e.default.is_some() {
25435 self.write_keyword("DEFAULT");
25436 self.write_space();
25437 }
25438 self.write_keyword("CHARACTER SET");
25439 self.write("=");
25440 self.generate_expression(&e.this)?;
25441 Ok(())
25442 }
25443
25444 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
25445 self.write_keyword("CHECK");
25447 self.write(" (");
25448 self.generate_expression(&e.this)?;
25449 self.write(")");
25450 if e.enforced.is_some() {
25451 self.write_space();
25452 self.write_keyword("ENFORCED");
25453 }
25454 Ok(())
25455 }
25456
25457 fn generate_assume_column_constraint(&mut self, e: &AssumeColumnConstraint) -> Result<()> {
25458 self.write_keyword("ASSUME");
25460 self.write(" (");
25461 self.generate_expression(&e.this)?;
25462 self.write(")");
25463 Ok(())
25464 }
25465
25466 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
25467 self.write_keyword("CHECK_JSON");
25469 self.write("(");
25470 self.generate_expression(&e.this)?;
25471 self.write(")");
25472 Ok(())
25473 }
25474
25475 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
25476 self.write_keyword("CHECK_XML");
25478 self.write("(");
25479 self.generate_expression(&e.this)?;
25480 self.write(")");
25481 Ok(())
25482 }
25483
25484 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
25485 self.write_keyword("CHECKSUM");
25487 self.write("=");
25488 if e.on.is_some() {
25489 self.write_keyword("ON");
25490 } else if e.default.is_some() {
25491 self.write_keyword("DEFAULT");
25492 } else {
25493 self.write_keyword("OFF");
25494 }
25495 Ok(())
25496 }
25497
25498 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
25499 if e.shallow.is_some() {
25501 self.write_keyword("SHALLOW");
25502 self.write_space();
25503 }
25504 if e.copy.is_some() {
25505 self.write_keyword("COPY");
25506 } else {
25507 self.write_keyword("CLONE");
25508 }
25509 self.write_space();
25510 self.generate_expression(&e.this)?;
25511 Ok(())
25512 }
25513
25514 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
25515 self.write_keyword("CLUSTER BY");
25517 self.write(" (");
25518 for (i, ord) in e.expressions.iter().enumerate() {
25519 if i > 0 {
25520 self.write(", ");
25521 }
25522 self.generate_ordered(ord)?;
25523 }
25524 self.write(")");
25525 Ok(())
25526 }
25527
25528 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
25529 self.write_keyword("CLUSTER BY");
25531 self.write_space();
25532 for (i, col) in e.columns.iter().enumerate() {
25533 if i > 0 {
25534 self.write(", ");
25535 }
25536 self.generate_identifier(col)?;
25537 }
25538 Ok(())
25539 }
25540
25541 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
25542 self.write_keyword("CLUSTERED BY");
25544 self.write(" (");
25545 for (i, expr) in e.expressions.iter().enumerate() {
25546 if i > 0 {
25547 self.write(", ");
25548 }
25549 self.generate_expression(expr)?;
25550 }
25551 self.write(")");
25552 if let Some(sorted_by) = &e.sorted_by {
25553 self.write_space();
25554 self.write_keyword("SORTED BY");
25555 self.write(" (");
25556 if let Expression::Tuple(t) = sorted_by.as_ref() {
25558 for (i, expr) in t.expressions.iter().enumerate() {
25559 if i > 0 {
25560 self.write(", ");
25561 }
25562 self.generate_expression(expr)?;
25563 }
25564 } else {
25565 self.generate_expression(sorted_by)?;
25566 }
25567 self.write(")");
25568 }
25569 if let Some(buckets) = &e.buckets {
25570 self.write_space();
25571 self.write_keyword("INTO");
25572 self.write_space();
25573 self.generate_expression(buckets)?;
25574 self.write_space();
25575 self.write_keyword("BUCKETS");
25576 }
25577 Ok(())
25578 }
25579
25580 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
25581 if e.default.is_some() {
25585 self.write_keyword("DEFAULT");
25586 self.write_space();
25587 }
25588 self.write_keyword("COLLATE");
25589 match self.config.dialect {
25591 Some(DialectType::BigQuery) => self.write_space(),
25592 _ => self.write("="),
25593 }
25594 self.generate_expression(&e.this)?;
25595 Ok(())
25596 }
25597
25598 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
25599 match e {
25601 ColumnConstraint::NotNull => {
25602 self.write_keyword("NOT NULL");
25603 }
25604 ColumnConstraint::Null => {
25605 self.write_keyword("NULL");
25606 }
25607 ColumnConstraint::Unique => {
25608 self.write_keyword("UNIQUE");
25609 }
25610 ColumnConstraint::PrimaryKey => {
25611 self.write_keyword("PRIMARY KEY");
25612 }
25613 ColumnConstraint::Default(expr) => {
25614 self.write_keyword("DEFAULT");
25615 self.write_space();
25616 self.generate_expression(expr)?;
25617 }
25618 ColumnConstraint::Check(expr) => {
25619 self.write_keyword("CHECK");
25620 self.write(" (");
25621 self.generate_expression(expr)?;
25622 self.write(")");
25623 }
25624 ColumnConstraint::References(fk_ref) => {
25625 if fk_ref.has_foreign_key_keywords {
25626 self.write_keyword("FOREIGN KEY");
25627 self.write_space();
25628 }
25629 self.write_keyword("REFERENCES");
25630 self.write_space();
25631 self.generate_table(&fk_ref.table)?;
25632 if !fk_ref.columns.is_empty() {
25633 self.write(" (");
25634 for (i, col) in fk_ref.columns.iter().enumerate() {
25635 if i > 0 {
25636 self.write(", ");
25637 }
25638 self.generate_identifier(col)?;
25639 }
25640 self.write(")");
25641 }
25642 }
25643 ColumnConstraint::GeneratedAsIdentity(gen) => {
25644 self.write_keyword("GENERATED");
25645 self.write_space();
25646 if gen.always {
25647 self.write_keyword("ALWAYS");
25648 } else {
25649 self.write_keyword("BY DEFAULT");
25650 if gen.on_null {
25651 self.write_space();
25652 self.write_keyword("ON NULL");
25653 }
25654 }
25655 self.write_space();
25656 self.write_keyword("AS IDENTITY");
25657 }
25658 ColumnConstraint::Collate(collation) => {
25659 self.write_keyword("COLLATE");
25660 self.write_space();
25661 self.generate_identifier(collation)?;
25662 }
25663 ColumnConstraint::Comment(comment) => {
25664 self.write_keyword("COMMENT");
25665 self.write(" '");
25666 self.write(comment);
25667 self.write("'");
25668 }
25669 ColumnConstraint::ComputedColumn(cc) => {
25670 self.generate_computed_column_inline(cc)?;
25671 }
25672 ColumnConstraint::GeneratedAsRow(gar) => {
25673 self.generate_generated_as_row_inline(gar)?;
25674 }
25675 ColumnConstraint::Tags(tags) => {
25676 self.write_keyword("TAG");
25677 self.write(" (");
25678 for (i, expr) in tags.expressions.iter().enumerate() {
25679 if i > 0 {
25680 self.write(", ");
25681 }
25682 self.generate_expression(expr)?;
25683 }
25684 self.write(")");
25685 }
25686 ColumnConstraint::Path(path_expr) => {
25687 self.write_keyword("PATH");
25688 self.write_space();
25689 self.generate_expression(path_expr)?;
25690 }
25691 }
25692 Ok(())
25693 }
25694
25695 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
25696 match e {
25698 ColumnPosition::First => {
25699 self.write_keyword("FIRST");
25700 }
25701 ColumnPosition::After(ident) => {
25702 self.write_keyword("AFTER");
25703 self.write_space();
25704 self.generate_identifier(ident)?;
25705 }
25706 }
25707 Ok(())
25708 }
25709
25710 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
25711 self.generate_expression(&e.this)?;
25713 self.write("(");
25714 self.generate_expression(&e.expression)?;
25715 self.write(")");
25716 Ok(())
25717 }
25718
25719 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
25720 if let Some(ref unpack) = e.unpack {
25723 if let Expression::Boolean(b) = unpack.as_ref() {
25724 if b.value {
25725 self.write("*");
25726 }
25727 }
25728 }
25729 self.write_keyword("COLUMNS");
25730 self.write("(");
25731 self.generate_expression(&e.this)?;
25732 self.write(")");
25733 Ok(())
25734 }
25735
25736 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
25737 self.generate_expression(&e.this)?;
25739 self.write("(");
25740 for (i, expr) in e.expressions.iter().enumerate() {
25741 if i > 0 {
25742 self.write(", ");
25743 }
25744 self.generate_expression(expr)?;
25745 }
25746 self.write(")");
25747 Ok(())
25748 }
25749
25750 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
25751 self.generate_expression(&e.this)?;
25753 self.write("(");
25754 for (i, param) in e.params.iter().enumerate() {
25755 if i > 0 {
25756 self.write(", ");
25757 }
25758 self.generate_expression(param)?;
25759 }
25760 self.write(")(");
25761 for (i, expr) in e.expressions.iter().enumerate() {
25762 if i > 0 {
25763 self.write(", ");
25764 }
25765 self.generate_expression(expr)?;
25766 }
25767 self.write(")");
25768 Ok(())
25769 }
25770
25771 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
25772 self.write_keyword("COMMIT");
25774
25775 if e.this.is_none()
25777 && matches!(
25778 self.config.dialect,
25779 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25780 )
25781 {
25782 self.write_space();
25783 self.write_keyword("TRANSACTION");
25784 }
25785
25786 if let Some(this) = &e.this {
25788 let is_transaction_marker = matches!(
25790 this.as_ref(),
25791 Expression::Identifier(id) if id.name == "TRANSACTION"
25792 );
25793
25794 self.write_space();
25795 self.write_keyword("TRANSACTION");
25796
25797 if !is_transaction_marker {
25799 self.write_space();
25800 self.generate_expression(this)?;
25801 }
25802 }
25803
25804 if let Some(durability) = &e.durability {
25806 self.write_space();
25807 self.write_keyword("WITH");
25808 self.write(" (");
25809 self.write_keyword("DELAYED_DURABILITY");
25810 self.write(" = ");
25811 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
25812 self.write_keyword("ON");
25813 } else {
25814 self.write_keyword("OFF");
25815 }
25816 self.write(")");
25817 }
25818
25819 if let Some(chain) = &e.chain {
25821 self.write_space();
25822 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
25823 self.write_keyword("AND NO CHAIN");
25824 } else {
25825 self.write_keyword("AND CHAIN");
25826 }
25827 }
25828 Ok(())
25829 }
25830
25831 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
25832 self.write("[");
25834 self.generate_expression(&e.this)?;
25835 self.write_space();
25836 self.write_keyword("FOR");
25837 self.write_space();
25838 self.generate_expression(&e.expression)?;
25839 if let Some(pos) = &e.position {
25841 self.write(", ");
25842 self.generate_expression(pos)?;
25843 }
25844 if let Some(iterator) = &e.iterator {
25845 self.write_space();
25846 self.write_keyword("IN");
25847 self.write_space();
25848 self.generate_expression(iterator)?;
25849 }
25850 if let Some(condition) = &e.condition {
25851 self.write_space();
25852 self.write_keyword("IF");
25853 self.write_space();
25854 self.generate_expression(condition)?;
25855 }
25856 self.write("]");
25857 Ok(())
25858 }
25859
25860 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
25861 self.write_keyword("COMPRESS");
25863 self.write("(");
25864 self.generate_expression(&e.this)?;
25865 if let Some(method) = &e.method {
25866 self.write(", '");
25867 self.write(method);
25868 self.write("'");
25869 }
25870 self.write(")");
25871 Ok(())
25872 }
25873
25874 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
25875 self.write_keyword("COMPRESS");
25877 if let Some(this) = &e.this {
25878 self.write_space();
25879 self.generate_expression(this)?;
25880 }
25881 Ok(())
25882 }
25883
25884 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
25885 self.write_keyword("AS");
25887 self.write_space();
25888 self.generate_expression(&e.this)?;
25889 if e.not_null.is_some() {
25890 self.write_space();
25891 self.write_keyword("PERSISTED NOT NULL");
25892 } else if e.persisted.is_some() {
25893 self.write_space();
25894 self.write_keyword("PERSISTED");
25895 }
25896 Ok(())
25897 }
25898
25899 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
25903 let computed_expr = if matches!(
25904 self.config.dialect,
25905 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25906 ) {
25907 match &*cc.expression {
25908 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
25909 {
25910 let wrapped = Expression::Cast(Box::new(Cast {
25911 this: y.this.clone(),
25912 to: DataType::Date,
25913 trailing_comments: Vec::new(),
25914 double_colon_syntax: false,
25915 format: None,
25916 default: None,
25917 inferred_type: None,
25918 }));
25919 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
25920 }
25921 Expression::Function(f)
25922 if f.name.eq_ignore_ascii_case("YEAR")
25923 && f.args.len() == 1
25924 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
25925 {
25926 let wrapped = Expression::Cast(Box::new(Cast {
25927 this: f.args[0].clone(),
25928 to: DataType::Date,
25929 trailing_comments: Vec::new(),
25930 double_colon_syntax: false,
25931 format: None,
25932 default: None,
25933 inferred_type: None,
25934 }));
25935 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
25936 }
25937 _ => *cc.expression.clone(),
25938 }
25939 } else {
25940 *cc.expression.clone()
25941 };
25942
25943 match cc.persistence_kind.as_deref() {
25944 Some("STORED") | Some("VIRTUAL") => {
25945 self.write_keyword("GENERATED ALWAYS AS");
25947 self.write(" (");
25948 self.generate_expression(&computed_expr)?;
25949 self.write(")");
25950 self.write_space();
25951 if cc.persisted {
25952 self.write_keyword("STORED");
25953 } else {
25954 self.write_keyword("VIRTUAL");
25955 }
25956 }
25957 Some("PERSISTED") => {
25958 self.write_keyword("AS");
25960 self.write(" (");
25961 self.generate_expression(&computed_expr)?;
25962 self.write(")");
25963 self.write_space();
25964 self.write_keyword("PERSISTED");
25965 if let Some(ref dt) = cc.data_type {
25967 self.write_space();
25968 self.generate_data_type(dt)?;
25969 }
25970 if cc.not_null {
25971 self.write_space();
25972 self.write_keyword("NOT NULL");
25973 }
25974 }
25975 _ => {
25976 if matches!(
25979 self.config.dialect,
25980 Some(DialectType::Spark)
25981 | Some(DialectType::Databricks)
25982 | Some(DialectType::Hive)
25983 ) {
25984 self.write_keyword("GENERATED ALWAYS AS");
25985 self.write(" (");
25986 self.generate_expression(&computed_expr)?;
25987 self.write(")");
25988 } else if matches!(
25989 self.config.dialect,
25990 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25991 ) {
25992 self.write_keyword("AS");
25993 let omit_parens = matches!(computed_expr, Expression::Year(_))
25994 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
25995 if omit_parens {
25996 self.write_space();
25997 self.generate_expression(&computed_expr)?;
25998 } else {
25999 self.write(" (");
26000 self.generate_expression(&computed_expr)?;
26001 self.write(")");
26002 }
26003 } else {
26004 self.write_keyword("AS");
26005 self.write(" (");
26006 self.generate_expression(&computed_expr)?;
26007 self.write(")");
26008 }
26009 }
26010 }
26011 Ok(())
26012 }
26013
26014 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
26017 self.write_keyword("GENERATED ALWAYS AS ROW ");
26018 if gar.start {
26019 self.write_keyword("START");
26020 } else {
26021 self.write_keyword("END");
26022 }
26023 if gar.hidden {
26024 self.write_space();
26025 self.write_keyword("HIDDEN");
26026 }
26027 Ok(())
26028 }
26029
26030 fn generate_system_versioning_content(
26032 &mut self,
26033 e: &WithSystemVersioningProperty,
26034 ) -> Result<()> {
26035 let mut parts = Vec::new();
26036
26037 if let Some(this) = &e.this {
26038 let mut s = String::from("HISTORY_TABLE=");
26039 let mut gen = Generator::with_arc_config(self.config.clone());
26040 gen.generate_expression(this)?;
26041 s.push_str(&gen.output);
26042 parts.push(s);
26043 }
26044
26045 if let Some(data_consistency) = &e.data_consistency {
26046 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
26047 let mut gen = Generator::with_arc_config(self.config.clone());
26048 gen.generate_expression(data_consistency)?;
26049 s.push_str(&gen.output);
26050 parts.push(s);
26051 }
26052
26053 if let Some(retention_period) = &e.retention_period {
26054 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
26055 let mut gen = Generator::with_arc_config(self.config.clone());
26056 gen.generate_expression(retention_period)?;
26057 s.push_str(&gen.output);
26058 parts.push(s);
26059 }
26060
26061 self.write_keyword("SYSTEM_VERSIONING");
26062 self.write("=");
26063
26064 if !parts.is_empty() {
26065 self.write_keyword("ON");
26066 self.write("(");
26067 self.write(&parts.join(", "));
26068 self.write(")");
26069 } else if e.on.is_some() {
26070 self.write_keyword("ON");
26071 } else {
26072 self.write_keyword("OFF");
26073 }
26074
26075 Ok(())
26076 }
26077
26078 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
26079 if e.else_.is_some() {
26082 self.write_keyword("ELSE");
26083 self.write_space();
26084 } else if let Some(expression) = &e.expression {
26085 self.write_keyword("WHEN");
26086 self.write_space();
26087 self.generate_expression(expression)?;
26088 self.write_space();
26089 self.write_keyword("THEN");
26090 self.write_space();
26091 }
26092
26093 if let Expression::Insert(insert) = e.this.as_ref() {
26096 self.write_keyword("INTO");
26097 self.write_space();
26098 self.generate_table(&insert.table)?;
26099
26100 if !insert.columns.is_empty() {
26102 self.write(" (");
26103 for (i, col) in insert.columns.iter().enumerate() {
26104 if i > 0 {
26105 self.write(", ");
26106 }
26107 self.generate_identifier(col)?;
26108 }
26109 self.write(")");
26110 }
26111
26112 if !insert.values.is_empty() {
26114 self.write_space();
26115 self.write_keyword("VALUES");
26116 for (row_idx, row) in insert.values.iter().enumerate() {
26117 if row_idx > 0 {
26118 self.write(", ");
26119 }
26120 self.write(" (");
26121 for (i, val) in row.iter().enumerate() {
26122 if i > 0 {
26123 self.write(", ");
26124 }
26125 self.generate_expression(val)?;
26126 }
26127 self.write(")");
26128 }
26129 }
26130 } else {
26131 self.generate_expression(&e.this)?;
26133 }
26134 Ok(())
26135 }
26136
26137 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
26138 self.write_keyword("CONSTRAINT");
26140 self.write_space();
26141 self.generate_expression(&e.this)?;
26142 if !e.expressions.is_empty() {
26143 self.write_space();
26144 for (i, expr) in e.expressions.iter().enumerate() {
26145 if i > 0 {
26146 self.write_space();
26147 }
26148 self.generate_expression(expr)?;
26149 }
26150 }
26151 Ok(())
26152 }
26153
26154 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
26155 self.write_keyword("CONVERT_TIMEZONE");
26157 self.write("(");
26158 let mut first = true;
26159 if let Some(source_tz) = &e.source_tz {
26160 self.generate_expression(source_tz)?;
26161 first = false;
26162 }
26163 if let Some(target_tz) = &e.target_tz {
26164 if !first {
26165 self.write(", ");
26166 }
26167 self.generate_expression(target_tz)?;
26168 first = false;
26169 }
26170 if let Some(timestamp) = &e.timestamp {
26171 if !first {
26172 self.write(", ");
26173 }
26174 self.generate_expression(timestamp)?;
26175 }
26176 self.write(")");
26177 Ok(())
26178 }
26179
26180 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
26181 self.write_keyword("CONVERT");
26183 self.write("(");
26184 self.generate_expression(&e.this)?;
26185 if let Some(dest) = &e.dest {
26186 self.write_space();
26187 self.write_keyword("USING");
26188 self.write_space();
26189 self.generate_expression(dest)?;
26190 }
26191 self.write(")");
26192 Ok(())
26193 }
26194
26195 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
26196 self.write_keyword("COPY");
26197 if e.is_into {
26198 self.write_space();
26199 self.write_keyword("INTO");
26200 }
26201 self.write_space();
26202
26203 if let Expression::Literal(lit) = &e.this {
26205 if let Literal::String(s) = lit.as_ref() {
26206 if s.starts_with('@') {
26207 self.write(s);
26208 } else {
26209 self.generate_expression(&e.this)?;
26210 }
26211 }
26212 } else {
26213 self.generate_expression(&e.this)?;
26214 }
26215
26216 if e.kind {
26218 if self.config.pretty {
26220 self.write_newline();
26221 } else {
26222 self.write_space();
26223 }
26224 self.write_keyword("FROM");
26225 self.write_space();
26226 } else if !e.files.is_empty() {
26227 if self.config.pretty {
26229 self.write_newline();
26230 } else {
26231 self.write_space();
26232 }
26233 self.write_keyword("TO");
26234 self.write_space();
26235 }
26236
26237 for (i, file) in e.files.iter().enumerate() {
26239 if i > 0 {
26240 self.write_space();
26241 }
26242 if let Expression::Literal(lit) = file {
26244 if let Literal::String(s) = lit.as_ref() {
26245 if s.starts_with('@') {
26246 self.write(s);
26247 } else {
26248 self.generate_expression(file)?;
26249 }
26250 }
26251 } else if let Expression::Identifier(id) = file {
26252 if id.quoted {
26254 self.write("`");
26255 self.write(&id.name);
26256 self.write("`");
26257 } else {
26258 self.generate_expression(file)?;
26259 }
26260 } else {
26261 self.generate_expression(file)?;
26262 }
26263 }
26264
26265 if !e.with_wrapped {
26267 if let Some(ref creds) = e.credentials {
26268 if let Some(ref storage) = creds.storage {
26269 if self.config.pretty {
26270 self.write_newline();
26271 } else {
26272 self.write_space();
26273 }
26274 self.write_keyword("STORAGE_INTEGRATION");
26275 self.write(" = ");
26276 self.write(storage);
26277 }
26278 if creds.credentials.is_empty() {
26279 if self.config.pretty {
26281 self.write_newline();
26282 } else {
26283 self.write_space();
26284 }
26285 self.write_keyword("CREDENTIALS");
26286 self.write(" = ()");
26287 } else {
26288 if self.config.pretty {
26289 self.write_newline();
26290 } else {
26291 self.write_space();
26292 }
26293 self.write_keyword("CREDENTIALS");
26294 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
26297 self.write(" '");
26299 self.write(&creds.credentials[0].1);
26300 self.write("'");
26301 } else {
26302 self.write(" = (");
26304 for (i, (k, v)) in creds.credentials.iter().enumerate() {
26305 if i > 0 {
26306 self.write_space();
26307 }
26308 self.write(k);
26309 self.write("='");
26310 self.write(v);
26311 self.write("'");
26312 }
26313 self.write(")");
26314 }
26315 }
26316 if let Some(ref encryption) = creds.encryption {
26317 self.write_space();
26318 self.write_keyword("ENCRYPTION");
26319 self.write(" = ");
26320 self.write(encryption);
26321 }
26322 }
26323 }
26324
26325 if !e.params.is_empty() {
26327 if e.with_wrapped {
26328 self.write_space();
26330 self.write_keyword("WITH");
26331 self.write(" (");
26332 for (i, param) in e.params.iter().enumerate() {
26333 if i > 0 {
26334 self.write(", ");
26335 }
26336 self.generate_copy_param_with_format(param)?;
26337 }
26338 self.write(")");
26339 } else {
26340 for param in &e.params {
26344 if self.config.pretty {
26345 self.write_newline();
26346 } else {
26347 self.write_space();
26348 }
26349 self.write(¶m.name);
26351 if let Some(ref value) = param.value {
26352 if param.eq {
26354 self.write(" = ");
26355 } else {
26356 self.write(" ");
26357 }
26358 if !param.values.is_empty() {
26359 self.write("(");
26360 for (i, v) in param.values.iter().enumerate() {
26361 if i > 0 {
26362 self.write_space();
26363 }
26364 self.generate_copy_nested_param(v)?;
26365 }
26366 self.write(")");
26367 } else {
26368 self.generate_copy_param_value(value)?;
26370 }
26371 } else if !param.values.is_empty() {
26372 if param.eq {
26374 self.write(" = (");
26375 } else {
26376 self.write(" (");
26377 }
26378 let is_key_value_pairs = param
26383 .values
26384 .first()
26385 .map_or(false, |v| matches!(v, Expression::Eq(_)));
26386 let sep = if is_key_value_pairs && param.eq {
26387 " "
26388 } else {
26389 ", "
26390 };
26391 for (i, v) in param.values.iter().enumerate() {
26392 if i > 0 {
26393 self.write(sep);
26394 }
26395 self.generate_copy_nested_param(v)?;
26396 }
26397 self.write(")");
26398 }
26399 }
26400 }
26401 }
26402
26403 Ok(())
26404 }
26405
26406 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
26409 self.write_keyword(¶m.name);
26410 if !param.values.is_empty() {
26411 self.write(" = (");
26413 for (i, v) in param.values.iter().enumerate() {
26414 if i > 0 {
26415 self.write(", ");
26416 }
26417 self.generate_copy_nested_param(v)?;
26418 }
26419 self.write(")");
26420 } else if let Some(ref value) = param.value {
26421 if param.eq {
26422 self.write(" = ");
26423 } else {
26424 self.write(" ");
26425 }
26426 self.generate_expression(value)?;
26427 }
26428 Ok(())
26429 }
26430
26431 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
26433 match expr {
26434 Expression::Eq(eq) => {
26435 match &eq.left {
26437 Expression::Column(c) => self.write(&c.name.name),
26438 _ => self.generate_expression(&eq.left)?,
26439 }
26440 self.write("=");
26441 match &eq.right {
26443 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
26444 let Literal::String(s) = lit.as_ref() else { unreachable!() };
26445 self.write("'");
26446 self.write(s);
26447 self.write("'");
26448 }
26449 Expression::Tuple(t) => {
26450 self.write("(");
26452 if self.config.pretty {
26453 self.write_newline();
26454 self.indent_level += 1;
26455 for (i, item) in t.expressions.iter().enumerate() {
26456 if i > 0 {
26457 self.write(", ");
26458 }
26459 self.write_indent();
26460 self.generate_expression(item)?;
26461 }
26462 self.write_newline();
26463 self.indent_level -= 1;
26464 } else {
26465 for (i, item) in t.expressions.iter().enumerate() {
26466 if i > 0 {
26467 self.write(", ");
26468 }
26469 self.generate_expression(item)?;
26470 }
26471 }
26472 self.write(")");
26473 }
26474 _ => self.generate_expression(&eq.right)?,
26475 }
26476 Ok(())
26477 }
26478 Expression::Column(c) => {
26479 self.write(&c.name.name);
26481 Ok(())
26482 }
26483 _ => self.generate_expression(expr),
26484 }
26485 }
26486
26487 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
26490 match expr {
26491 Expression::Column(c) => {
26492 if c.name.quoted {
26494 self.write("\"");
26495 self.write(&c.name.name);
26496 self.write("\"");
26497 } else {
26498 self.write(&c.name.name);
26499 }
26500 Ok(())
26501 }
26502 Expression::Identifier(id) => {
26503 if id.quoted {
26505 self.write("\"");
26506 self.write(&id.name);
26507 self.write("\"");
26508 } else {
26509 self.write(&id.name);
26510 }
26511 Ok(())
26512 }
26513 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
26514 let Literal::String(s) = lit.as_ref() else { unreachable!() };
26515 self.write("'");
26517 self.write(s);
26518 self.write("'");
26519 Ok(())
26520 }
26521 _ => self.generate_expression(expr),
26522 }
26523 }
26524
26525 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
26526 self.write_keyword(&e.name);
26527 if let Some(ref value) = e.value {
26528 if e.eq {
26529 self.write(" = ");
26530 } else {
26531 self.write(" ");
26532 }
26533 self.generate_expression(value)?;
26534 }
26535 if !e.values.is_empty() {
26536 if e.eq {
26537 self.write(" = ");
26538 } else {
26539 self.write(" ");
26540 }
26541 self.write("(");
26542 for (i, v) in e.values.iter().enumerate() {
26543 if i > 0 {
26544 self.write(", ");
26545 }
26546 self.generate_expression(v)?;
26547 }
26548 self.write(")");
26549 }
26550 Ok(())
26551 }
26552
26553 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
26554 self.write_keyword("CORR");
26556 self.write("(");
26557 self.generate_expression(&e.this)?;
26558 self.write(", ");
26559 self.generate_expression(&e.expression)?;
26560 self.write(")");
26561 Ok(())
26562 }
26563
26564 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
26565 self.write_keyword("COSINE_DISTANCE");
26567 self.write("(");
26568 self.generate_expression(&e.this)?;
26569 self.write(", ");
26570 self.generate_expression(&e.expression)?;
26571 self.write(")");
26572 Ok(())
26573 }
26574
26575 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
26576 self.write_keyword("COVAR_POP");
26578 self.write("(");
26579 self.generate_expression(&e.this)?;
26580 self.write(", ");
26581 self.generate_expression(&e.expression)?;
26582 self.write(")");
26583 Ok(())
26584 }
26585
26586 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
26587 self.write_keyword("COVAR_SAMP");
26589 self.write("(");
26590 self.generate_expression(&e.this)?;
26591 self.write(", ");
26592 self.generate_expression(&e.expression)?;
26593 self.write(")");
26594 Ok(())
26595 }
26596
26597 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
26598 self.write_keyword("CREDENTIALS");
26600 self.write(" (");
26601 for (i, (key, value)) in e.credentials.iter().enumerate() {
26602 if i > 0 {
26603 self.write(", ");
26604 }
26605 self.write(key);
26606 self.write("='");
26607 self.write(value);
26608 self.write("'");
26609 }
26610 self.write(")");
26611 Ok(())
26612 }
26613
26614 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
26615 self.write_keyword("CREDENTIALS");
26617 self.write("=(");
26618 for (i, expr) in e.expressions.iter().enumerate() {
26619 if i > 0 {
26620 self.write(", ");
26621 }
26622 self.generate_expression(expr)?;
26623 }
26624 self.write(")");
26625 Ok(())
26626 }
26627
26628 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
26629 use crate::dialects::DialectType;
26630
26631 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
26634 self.generate_expression(&e.this)?;
26635 self.write_space();
26636 self.write_keyword("AS");
26637 self.write_space();
26638 self.generate_identifier(&e.alias)?;
26639 return Ok(());
26640 }
26641 self.write(&e.alias.name);
26642
26643 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
26645
26646 if !e.columns.is_empty() && !skip_cte_columns {
26647 self.write("(");
26648 for (i, col) in e.columns.iter().enumerate() {
26649 if i > 0 {
26650 self.write(", ");
26651 }
26652 self.write(&col.name);
26653 }
26654 self.write(")");
26655 }
26656 if !e.key_expressions.is_empty() {
26658 self.write_space();
26659 self.write_keyword("USING KEY");
26660 self.write(" (");
26661 for (i, key) in e.key_expressions.iter().enumerate() {
26662 if i > 0 {
26663 self.write(", ");
26664 }
26665 self.write(&key.name);
26666 }
26667 self.write(")");
26668 }
26669 self.write_space();
26670 self.write_keyword("AS");
26671 self.write_space();
26672 if let Some(materialized) = e.materialized {
26673 if materialized {
26674 self.write_keyword("MATERIALIZED");
26675 } else {
26676 self.write_keyword("NOT MATERIALIZED");
26677 }
26678 self.write_space();
26679 }
26680 self.write("(");
26681 self.generate_expression(&e.this)?;
26682 self.write(")");
26683 Ok(())
26684 }
26685
26686 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
26687 if e.expressions.is_empty() {
26689 self.write_keyword("WITH CUBE");
26690 } else {
26691 self.write_keyword("CUBE");
26692 self.write("(");
26693 for (i, expr) in e.expressions.iter().enumerate() {
26694 if i > 0 {
26695 self.write(", ");
26696 }
26697 self.generate_expression(expr)?;
26698 }
26699 self.write(")");
26700 }
26701 Ok(())
26702 }
26703
26704 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
26705 self.write_keyword("CURRENT_DATETIME");
26707 if let Some(this) = &e.this {
26708 self.write("(");
26709 self.generate_expression(this)?;
26710 self.write(")");
26711 }
26712 Ok(())
26713 }
26714
26715 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
26716 self.write_keyword("CURRENT_SCHEMA");
26718 Ok(())
26719 }
26720
26721 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
26722 self.write_keyword("CURRENT_SCHEMAS");
26724 self.write("(");
26725 if !matches!(
26727 self.config.dialect,
26728 Some(crate::dialects::DialectType::Snowflake)
26729 ) {
26730 if let Some(this) = &e.this {
26731 self.generate_expression(this)?;
26732 }
26733 }
26734 self.write(")");
26735 Ok(())
26736 }
26737
26738 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
26739 self.write_keyword("CURRENT_USER");
26741 let needs_parens = e.this.is_some()
26743 || matches!(
26744 self.config.dialect,
26745 Some(DialectType::Snowflake)
26746 | Some(DialectType::Spark)
26747 | Some(DialectType::Hive)
26748 | Some(DialectType::DuckDB)
26749 | Some(DialectType::BigQuery)
26750 | Some(DialectType::MySQL)
26751 | Some(DialectType::Databricks)
26752 );
26753 if needs_parens {
26754 self.write("()");
26755 }
26756 Ok(())
26757 }
26758
26759 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
26760 if self.config.dialect == Some(DialectType::Solr) {
26762 self.generate_expression(&e.this)?;
26763 self.write(" ");
26764 self.write_keyword("OR");
26765 self.write(" ");
26766 self.generate_expression(&e.expression)?;
26767 } else if self.config.dialect == Some(DialectType::MySQL) {
26768 self.generate_mysql_concat_from_dpipe(e)?;
26769 } else {
26770 self.generate_expression(&e.this)?;
26772 self.write(" || ");
26773 self.generate_expression(&e.expression)?;
26774 }
26775 Ok(())
26776 }
26777
26778 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
26779 self.write_keyword("DATABLOCKSIZE");
26781 self.write("=");
26782 if let Some(size) = e.size {
26783 self.write(&size.to_string());
26784 if let Some(units) = &e.units {
26785 self.write_space();
26786 self.generate_expression(units)?;
26787 }
26788 } else if e.minimum.is_some() {
26789 self.write_keyword("MINIMUM");
26790 } else if e.maximum.is_some() {
26791 self.write_keyword("MAXIMUM");
26792 } else if e.default.is_some() {
26793 self.write_keyword("DEFAULT");
26794 }
26795 Ok(())
26796 }
26797
26798 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
26799 self.write_keyword("DATA_DELETION");
26801 self.write("=");
26802
26803 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
26804 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
26805
26806 if is_on {
26807 self.write_keyword("ON");
26808 if has_options {
26809 self.write("(");
26810 let mut first = true;
26811 if let Some(filter_column) = &e.filter_column {
26812 self.write_keyword("FILTER_COLUMN");
26813 self.write("=");
26814 self.generate_expression(filter_column)?;
26815 first = false;
26816 }
26817 if let Some(retention_period) = &e.retention_period {
26818 if !first {
26819 self.write(", ");
26820 }
26821 self.write_keyword("RETENTION_PERIOD");
26822 self.write("=");
26823 self.generate_expression(retention_period)?;
26824 }
26825 self.write(")");
26826 }
26827 } else {
26828 self.write_keyword("OFF");
26829 }
26830 Ok(())
26831 }
26832
26833 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
26837 use crate::dialects::DialectType;
26838 use crate::expressions::Literal;
26839
26840 match self.config.dialect {
26841 Some(DialectType::Exasol) => {
26843 self.write_keyword("TO_DATE");
26844 self.write("(");
26845 match &e.this {
26847 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
26848 let Literal::String(s) = lit.as_ref() else { unreachable!() };
26849 self.write("'");
26850 self.write(s);
26851 self.write("'");
26852 }
26853 _ => {
26854 self.generate_expression(&e.this)?;
26855 }
26856 }
26857 self.write(")");
26858 }
26859 _ => {
26861 self.write_keyword("DATE");
26862 self.write("(");
26863 self.generate_expression(&e.this)?;
26864 self.write(")");
26865 }
26866 }
26867 Ok(())
26868 }
26869
26870 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
26871 self.write_keyword("DATE_BIN");
26873 self.write("(");
26874 self.generate_expression(&e.this)?;
26875 self.write(", ");
26876 self.generate_expression(&e.expression)?;
26877 if let Some(origin) = &e.origin {
26878 self.write(", ");
26879 self.generate_expression(origin)?;
26880 }
26881 self.write(")");
26882 Ok(())
26883 }
26884
26885 fn generate_date_format_column_constraint(
26886 &mut self,
26887 e: &DateFormatColumnConstraint,
26888 ) -> Result<()> {
26889 self.write_keyword("FORMAT");
26891 self.write_space();
26892 self.generate_expression(&e.this)?;
26893 Ok(())
26894 }
26895
26896 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
26897 self.write_keyword("DATE_FROM_PARTS");
26899 self.write("(");
26900 let mut first = true;
26901 if let Some(year) = &e.year {
26902 self.generate_expression(year)?;
26903 first = false;
26904 }
26905 if let Some(month) = &e.month {
26906 if !first {
26907 self.write(", ");
26908 }
26909 self.generate_expression(month)?;
26910 first = false;
26911 }
26912 if let Some(day) = &e.day {
26913 if !first {
26914 self.write(", ");
26915 }
26916 self.generate_expression(day)?;
26917 }
26918 self.write(")");
26919 Ok(())
26920 }
26921
26922 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
26923 self.write_keyword("DATETIME");
26925 self.write("(");
26926 self.generate_expression(&e.this)?;
26927 if let Some(expr) = &e.expression {
26928 self.write(", ");
26929 self.generate_expression(expr)?;
26930 }
26931 self.write(")");
26932 Ok(())
26933 }
26934
26935 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
26936 self.write_keyword("DATETIME_ADD");
26938 self.write("(");
26939 self.generate_expression(&e.this)?;
26940 self.write(", ");
26941 self.generate_expression(&e.expression)?;
26942 if let Some(unit) = &e.unit {
26943 self.write(", ");
26944 self.write_keyword(unit);
26945 }
26946 self.write(")");
26947 Ok(())
26948 }
26949
26950 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
26951 self.write_keyword("DATETIME_DIFF");
26953 self.write("(");
26954 self.generate_expression(&e.this)?;
26955 self.write(", ");
26956 self.generate_expression(&e.expression)?;
26957 if let Some(unit) = &e.unit {
26958 self.write(", ");
26959 self.write_keyword(unit);
26960 }
26961 self.write(")");
26962 Ok(())
26963 }
26964
26965 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
26966 self.write_keyword("DATETIME_SUB");
26968 self.write("(");
26969 self.generate_expression(&e.this)?;
26970 self.write(", ");
26971 self.generate_expression(&e.expression)?;
26972 if let Some(unit) = &e.unit {
26973 self.write(", ");
26974 self.write_keyword(unit);
26975 }
26976 self.write(")");
26977 Ok(())
26978 }
26979
26980 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
26981 self.write_keyword("DATETIME_TRUNC");
26983 self.write("(");
26984 self.generate_expression(&e.this)?;
26985 self.write(", ");
26986 self.write_keyword(&e.unit);
26987 if let Some(zone) = &e.zone {
26988 self.write(", ");
26989 self.generate_expression(zone)?;
26990 }
26991 self.write(")");
26992 Ok(())
26993 }
26994
26995 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
26996 self.write_keyword("DAYNAME");
26998 self.write("(");
26999 self.generate_expression(&e.this)?;
27000 self.write(")");
27001 Ok(())
27002 }
27003
27004 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
27005 self.write_keyword("DECLARE");
27007 self.write_space();
27008 if e.replace {
27009 self.write_keyword("OR");
27010 self.write_space();
27011 self.write_keyword("REPLACE");
27012 self.write_space();
27013 }
27014 for (i, expr) in e.expressions.iter().enumerate() {
27015 if i > 0 {
27016 self.write(", ");
27017 }
27018 self.generate_expression(expr)?;
27019 }
27020 Ok(())
27021 }
27022
27023 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
27024 use crate::dialects::DialectType;
27025
27026 self.generate_expression(&e.this)?;
27028 for name in &e.additional_names {
27030 self.write(", ");
27031 self.generate_expression(name)?;
27032 }
27033 if let Some(kind) = &e.kind {
27034 self.write_space();
27035 match self.config.dialect {
27039 Some(DialectType::BigQuery) => {
27040 self.write(kind);
27041 }
27042 Some(DialectType::TSQL) => {
27043 let is_complex_table = kind.starts_with("TABLE")
27047 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
27048 if is_complex_table {
27049 self.write(kind);
27050 } else if kind == "INT" {
27051 self.write("INTEGER");
27052 } else if kind.starts_with("TABLE") {
27053 let normalized = kind
27055 .replace(" INT ", " INTEGER ")
27056 .replace(" INT,", " INTEGER,")
27057 .replace(" INT)", " INTEGER)")
27058 .replace("(INT ", "(INTEGER ");
27059 self.write(&normalized);
27060 } else {
27061 self.write(kind);
27062 }
27063 }
27064 _ => {
27065 if e.has_as {
27066 self.write_keyword("AS");
27067 self.write_space();
27068 }
27069 self.write(kind);
27070 }
27071 }
27072 }
27073 if let Some(default) = &e.default {
27074 match self.config.dialect {
27076 Some(DialectType::BigQuery) => {
27077 self.write_space();
27078 self.write_keyword("DEFAULT");
27079 self.write_space();
27080 }
27081 _ => {
27082 self.write(" = ");
27083 }
27084 }
27085 self.generate_expression(default)?;
27086 }
27087 Ok(())
27088 }
27089
27090 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
27091 self.write_keyword("DECODE");
27093 self.write("(");
27094 for (i, expr) in e.expressions.iter().enumerate() {
27095 if i > 0 {
27096 self.write(", ");
27097 }
27098 self.generate_expression(expr)?;
27099 }
27100 self.write(")");
27101 Ok(())
27102 }
27103
27104 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
27105 self.write_keyword("DECOMPRESS");
27107 self.write("(");
27108 self.generate_expression(&e.this)?;
27109 self.write(", '");
27110 self.write(&e.method);
27111 self.write("')");
27112 Ok(())
27113 }
27114
27115 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
27116 self.write_keyword("DECOMPRESS");
27118 self.write("(");
27119 self.generate_expression(&e.this)?;
27120 self.write(", '");
27121 self.write(&e.method);
27122 self.write("')");
27123 Ok(())
27124 }
27125
27126 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
27127 self.write_keyword("DECRYPT");
27129 self.write("(");
27130 self.generate_expression(&e.this)?;
27131 if let Some(passphrase) = &e.passphrase {
27132 self.write(", ");
27133 self.generate_expression(passphrase)?;
27134 }
27135 if let Some(aad) = &e.aad {
27136 self.write(", ");
27137 self.generate_expression(aad)?;
27138 }
27139 if let Some(method) = &e.encryption_method {
27140 self.write(", ");
27141 self.generate_expression(method)?;
27142 }
27143 self.write(")");
27144 Ok(())
27145 }
27146
27147 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
27148 self.write_keyword("DECRYPT_RAW");
27150 self.write("(");
27151 self.generate_expression(&e.this)?;
27152 if let Some(key) = &e.key {
27153 self.write(", ");
27154 self.generate_expression(key)?;
27155 }
27156 if let Some(iv) = &e.iv {
27157 self.write(", ");
27158 self.generate_expression(iv)?;
27159 }
27160 if let Some(aad) = &e.aad {
27161 self.write(", ");
27162 self.generate_expression(aad)?;
27163 }
27164 if let Some(method) = &e.encryption_method {
27165 self.write(", ");
27166 self.generate_expression(method)?;
27167 }
27168 self.write(")");
27169 Ok(())
27170 }
27171
27172 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
27173 self.write_keyword("DEFINER");
27175 self.write(" = ");
27176 self.generate_expression(&e.this)?;
27177 Ok(())
27178 }
27179
27180 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
27181 self.write_keyword("DETACH");
27183 if e.exists {
27184 self.write_keyword(" DATABASE IF EXISTS");
27185 }
27186 self.write_space();
27187 self.generate_expression(&e.this)?;
27188 Ok(())
27189 }
27190
27191 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
27192 let property_name = match e.this.as_ref() {
27193 Expression::Identifier(id) => id.name.as_str(),
27194 Expression::Var(v) => v.this.as_str(),
27195 _ => "DICTIONARY",
27196 };
27197 self.write_keyword(property_name);
27198 self.write("(");
27199 self.write(&e.kind);
27200 if let Some(settings) = &e.settings {
27201 self.write("(");
27202 if let Expression::Tuple(t) = settings.as_ref() {
27203 if self.config.pretty && !t.expressions.is_empty() {
27204 self.write_newline();
27205 self.indent_level += 1;
27206 for (i, pair) in t.expressions.iter().enumerate() {
27207 if i > 0 {
27208 self.write(",");
27209 self.write_newline();
27210 }
27211 self.write_indent();
27212 if let Expression::Tuple(pair_tuple) = pair {
27213 if let Some(k) = pair_tuple.expressions.first() {
27214 self.generate_expression(k)?;
27215 }
27216 if let Some(v) = pair_tuple.expressions.get(1) {
27217 self.write(" ");
27218 self.generate_expression(v)?;
27219 }
27220 } else {
27221 self.generate_expression(pair)?;
27222 }
27223 }
27224 self.indent_level -= 1;
27225 self.write_newline();
27226 self.write_indent();
27227 } else {
27228 for (i, pair) in t.expressions.iter().enumerate() {
27229 if i > 0 {
27230 self.write(" ");
27232 }
27233 if let Expression::Tuple(pair_tuple) = pair {
27234 if let Some(k) = pair_tuple.expressions.first() {
27235 self.generate_expression(k)?;
27236 }
27237 if let Some(v) = pair_tuple.expressions.get(1) {
27238 self.write(" ");
27239 self.generate_expression(v)?;
27240 }
27241 } else {
27242 self.generate_expression(pair)?;
27243 }
27244 }
27245 }
27246 } else {
27247 self.generate_expression(settings)?;
27248 }
27249 self.write(")");
27250 } else {
27251 self.write("()");
27253 }
27254 self.write(")");
27255 Ok(())
27256 }
27257
27258 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
27259 let property_name = match e.this.as_ref() {
27260 Expression::Identifier(id) => id.name.as_str(),
27261 Expression::Var(v) => v.this.as_str(),
27262 _ => "RANGE",
27263 };
27264 self.write_keyword(property_name);
27265 self.write("(");
27266 if let Some(min) = &e.min {
27267 self.write_keyword("MIN");
27268 self.write_space();
27269 self.generate_expression(min)?;
27270 }
27271 if let Some(max) = &e.max {
27272 self.write_space();
27273 self.write_keyword("MAX");
27274 self.write_space();
27275 self.generate_expression(max)?;
27276 }
27277 self.write(")");
27278 Ok(())
27279 }
27280
27281 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
27282 if e.local.is_some() {
27284 self.write_keyword("LOCAL ");
27285 }
27286 self.write_keyword("DIRECTORY");
27287 self.write_space();
27288 self.generate_expression(&e.this)?;
27289 if let Some(row_format) = &e.row_format {
27290 self.write_space();
27291 self.generate_expression(row_format)?;
27292 }
27293 Ok(())
27294 }
27295
27296 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
27297 self.write_keyword("DISTKEY");
27299 self.write("(");
27300 self.generate_expression(&e.this)?;
27301 self.write(")");
27302 Ok(())
27303 }
27304
27305 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
27306 self.write_keyword("DISTSTYLE");
27308 self.write_space();
27309 self.generate_expression(&e.this)?;
27310 Ok(())
27311 }
27312
27313 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
27314 self.write_keyword("DISTRIBUTE BY");
27316 self.write_space();
27317 for (i, expr) in e.expressions.iter().enumerate() {
27318 if i > 0 {
27319 self.write(", ");
27320 }
27321 self.generate_expression(expr)?;
27322 }
27323 Ok(())
27324 }
27325
27326 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
27327 self.write_keyword("DISTRIBUTED BY");
27329 self.write_space();
27330 self.write(&e.kind);
27331 if !e.expressions.is_empty() {
27332 self.write(" (");
27333 for (i, expr) in e.expressions.iter().enumerate() {
27334 if i > 0 {
27335 self.write(", ");
27336 }
27337 self.generate_expression(expr)?;
27338 }
27339 self.write(")");
27340 }
27341 if let Some(buckets) = &e.buckets {
27342 self.write_space();
27343 self.write_keyword("BUCKETS");
27344 self.write_space();
27345 self.generate_expression(buckets)?;
27346 }
27347 if let Some(order) = &e.order {
27348 self.write_space();
27349 self.generate_expression(order)?;
27350 }
27351 Ok(())
27352 }
27353
27354 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
27355 self.write_keyword("DOT_PRODUCT");
27357 self.write("(");
27358 self.generate_expression(&e.this)?;
27359 self.write(", ");
27360 self.generate_expression(&e.expression)?;
27361 self.write(")");
27362 Ok(())
27363 }
27364
27365 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
27366 self.write_keyword("DROP");
27368 if e.exists {
27369 self.write_keyword(" IF EXISTS ");
27370 } else {
27371 self.write_space();
27372 }
27373 for (i, expr) in e.expressions.iter().enumerate() {
27374 if i > 0 {
27375 self.write(", ");
27376 }
27377 self.generate_expression(expr)?;
27378 }
27379 Ok(())
27380 }
27381
27382 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
27383 self.write_keyword("DUPLICATE KEY");
27385 self.write(" (");
27386 for (i, expr) in e.expressions.iter().enumerate() {
27387 if i > 0 {
27388 self.write(", ");
27389 }
27390 self.generate_expression(expr)?;
27391 }
27392 self.write(")");
27393 Ok(())
27394 }
27395
27396 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
27397 self.write_keyword("ELT");
27399 self.write("(");
27400 self.generate_expression(&e.this)?;
27401 for expr in &e.expressions {
27402 self.write(", ");
27403 self.generate_expression(expr)?;
27404 }
27405 self.write(")");
27406 Ok(())
27407 }
27408
27409 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
27410 self.write_keyword("ENCODE");
27412 self.write("(");
27413 self.generate_expression(&e.this)?;
27414 if let Some(charset) = &e.charset {
27415 self.write(", ");
27416 self.generate_expression(charset)?;
27417 }
27418 self.write(")");
27419 Ok(())
27420 }
27421
27422 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
27423 if e.key.is_some() {
27425 self.write_keyword("KEY ");
27426 }
27427 self.write_keyword("ENCODE");
27428 self.write_space();
27429 self.generate_expression(&e.this)?;
27430 if !e.properties.is_empty() {
27431 self.write(" (");
27432 for (i, prop) in e.properties.iter().enumerate() {
27433 if i > 0 {
27434 self.write(", ");
27435 }
27436 self.generate_expression(prop)?;
27437 }
27438 self.write(")");
27439 }
27440 Ok(())
27441 }
27442
27443 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
27444 self.write_keyword("ENCRYPT");
27446 self.write("(");
27447 self.generate_expression(&e.this)?;
27448 if let Some(passphrase) = &e.passphrase {
27449 self.write(", ");
27450 self.generate_expression(passphrase)?;
27451 }
27452 if let Some(aad) = &e.aad {
27453 self.write(", ");
27454 self.generate_expression(aad)?;
27455 }
27456 if let Some(method) = &e.encryption_method {
27457 self.write(", ");
27458 self.generate_expression(method)?;
27459 }
27460 self.write(")");
27461 Ok(())
27462 }
27463
27464 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
27465 self.write_keyword("ENCRYPT_RAW");
27467 self.write("(");
27468 self.generate_expression(&e.this)?;
27469 if let Some(key) = &e.key {
27470 self.write(", ");
27471 self.generate_expression(key)?;
27472 }
27473 if let Some(iv) = &e.iv {
27474 self.write(", ");
27475 self.generate_expression(iv)?;
27476 }
27477 if let Some(aad) = &e.aad {
27478 self.write(", ");
27479 self.generate_expression(aad)?;
27480 }
27481 if let Some(method) = &e.encryption_method {
27482 self.write(", ");
27483 self.generate_expression(method)?;
27484 }
27485 self.write(")");
27486 Ok(())
27487 }
27488
27489 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
27490 self.write_keyword("ENGINE");
27492 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
27493 self.write("=");
27494 } else {
27495 self.write(" = ");
27496 }
27497 self.generate_expression(&e.this)?;
27498 Ok(())
27499 }
27500
27501 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
27502 self.write_keyword("ENVIRONMENT");
27504 self.write(" (");
27505 for (i, expr) in e.expressions.iter().enumerate() {
27506 if i > 0 {
27507 self.write(", ");
27508 }
27509 self.generate_expression(expr)?;
27510 }
27511 self.write(")");
27512 Ok(())
27513 }
27514
27515 fn generate_ephemeral_column_constraint(
27516 &mut self,
27517 e: &EphemeralColumnConstraint,
27518 ) -> Result<()> {
27519 self.write_keyword("EPHEMERAL");
27521 if let Some(this) = &e.this {
27522 self.write_space();
27523 self.generate_expression(this)?;
27524 }
27525 Ok(())
27526 }
27527
27528 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
27529 self.write_keyword("EQUAL_NULL");
27531 self.write("(");
27532 self.generate_expression(&e.this)?;
27533 self.write(", ");
27534 self.generate_expression(&e.expression)?;
27535 self.write(")");
27536 Ok(())
27537 }
27538
27539 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
27540 use crate::dialects::DialectType;
27541
27542 match self.config.dialect {
27544 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
27545 self.generate_expression(&e.this)?;
27546 self.write(" <-> ");
27547 self.generate_expression(&e.expression)?;
27548 }
27549 _ => {
27550 self.write_keyword("EUCLIDEAN_DISTANCE");
27552 self.write("(");
27553 self.generate_expression(&e.this)?;
27554 self.write(", ");
27555 self.generate_expression(&e.expression)?;
27556 self.write(")");
27557 }
27558 }
27559 Ok(())
27560 }
27561
27562 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
27563 self.write_keyword("EXECUTE AS");
27565 self.write_space();
27566 self.generate_expression(&e.this)?;
27567 Ok(())
27568 }
27569
27570 fn generate_export(&mut self, e: &Export) -> Result<()> {
27571 self.write_keyword("EXPORT DATA");
27573 if let Some(connection) = &e.connection {
27574 self.write_space();
27575 self.write_keyword("WITH CONNECTION");
27576 self.write_space();
27577 self.generate_expression(connection)?;
27578 }
27579 if !e.options.is_empty() {
27580 self.write_space();
27581 self.generate_options_clause(&e.options)?;
27582 }
27583 self.write_space();
27584 self.write_keyword("AS");
27585 self.write_space();
27586 self.generate_expression(&e.this)?;
27587 Ok(())
27588 }
27589
27590 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
27591 self.write_keyword("EXTERNAL");
27593 if let Some(this) = &e.this {
27594 self.write_space();
27595 self.generate_expression(this)?;
27596 }
27597 Ok(())
27598 }
27599
27600 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
27601 if e.no.is_some() {
27603 self.write_keyword("NO ");
27604 }
27605 self.write_keyword("FALLBACK");
27606 if e.protection.is_some() {
27607 self.write_keyword(" PROTECTION");
27608 }
27609 Ok(())
27610 }
27611
27612 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
27613 self.write_keyword("FARM_FINGERPRINT");
27615 self.write("(");
27616 for (i, expr) in e.expressions.iter().enumerate() {
27617 if i > 0 {
27618 self.write(", ");
27619 }
27620 self.generate_expression(expr)?;
27621 }
27622 self.write(")");
27623 Ok(())
27624 }
27625
27626 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
27627 self.write_keyword("FEATURES_AT_TIME");
27629 self.write("(");
27630 self.generate_expression(&e.this)?;
27631 if let Some(time) = &e.time {
27632 self.write(", ");
27633 self.generate_expression(time)?;
27634 }
27635 if let Some(num_rows) = &e.num_rows {
27636 self.write(", ");
27637 self.generate_expression(num_rows)?;
27638 }
27639 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
27640 self.write(", ");
27641 self.generate_expression(ignore_nulls)?;
27642 }
27643 self.write(")");
27644 Ok(())
27645 }
27646
27647 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
27648 let use_limit = !e.percent
27650 && !e.with_ties
27651 && e.count.is_some()
27652 && matches!(
27653 self.config.dialect,
27654 Some(DialectType::Spark)
27655 | Some(DialectType::Hive)
27656 | Some(DialectType::DuckDB)
27657 | Some(DialectType::SQLite)
27658 | Some(DialectType::MySQL)
27659 | Some(DialectType::BigQuery)
27660 | Some(DialectType::Databricks)
27661 | Some(DialectType::StarRocks)
27662 | Some(DialectType::Doris)
27663 | Some(DialectType::Athena)
27664 | Some(DialectType::ClickHouse)
27665 );
27666
27667 if use_limit {
27668 self.write_keyword("LIMIT");
27669 self.write_space();
27670 self.generate_expression(e.count.as_ref().unwrap())?;
27671 return Ok(());
27672 }
27673
27674 self.write_keyword("FETCH");
27676 if !e.direction.is_empty() {
27677 self.write_space();
27678 self.write_keyword(&e.direction);
27679 }
27680 if let Some(count) = &e.count {
27681 self.write_space();
27682 self.generate_expression(count)?;
27683 }
27684 if e.percent {
27686 self.write_keyword(" PERCENT");
27687 }
27688 if e.rows {
27689 self.write_keyword(" ROWS");
27690 }
27691 if e.with_ties {
27692 self.write_keyword(" WITH TIES");
27693 } else if e.rows {
27694 self.write_keyword(" ONLY");
27695 } else {
27696 self.write_keyword(" ROWS ONLY");
27697 }
27698 Ok(())
27699 }
27700
27701 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
27702 if e.hive_format.is_some() {
27706 self.write_keyword("STORED AS");
27708 self.write_space();
27709 if let Some(this) = &e.this {
27710 if let Expression::Identifier(id) = this.as_ref() {
27712 self.write_keyword(&id.name.to_ascii_uppercase());
27713 } else {
27714 self.generate_expression(this)?;
27715 }
27716 }
27717 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
27718 self.write_keyword("STORED AS");
27720 self.write_space();
27721 if let Some(this) = &e.this {
27722 if let Expression::Identifier(id) = this.as_ref() {
27723 self.write_keyword(&id.name.to_ascii_uppercase());
27724 } else {
27725 self.generate_expression(this)?;
27726 }
27727 }
27728 } else if matches!(
27729 self.config.dialect,
27730 Some(DialectType::Spark) | Some(DialectType::Databricks)
27731 ) {
27732 self.write_keyword("USING");
27734 self.write_space();
27735 if let Some(this) = &e.this {
27736 self.generate_expression(this)?;
27737 }
27738 } else {
27739 self.write_keyword("FILE_FORMAT");
27741 self.write(" = ");
27742 if let Some(this) = &e.this {
27743 self.generate_expression(this)?;
27744 } else if !e.expressions.is_empty() {
27745 self.write("(");
27746 for (i, expr) in e.expressions.iter().enumerate() {
27747 if i > 0 {
27748 self.write(", ");
27749 }
27750 self.generate_expression(expr)?;
27751 }
27752 self.write(")");
27753 }
27754 }
27755 Ok(())
27756 }
27757
27758 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
27759 self.generate_expression(&e.this)?;
27761 self.write_space();
27762 self.write_keyword("FILTER");
27763 self.write("(");
27764 self.write_keyword("WHERE");
27765 self.write_space();
27766 self.generate_expression(&e.expression)?;
27767 self.write(")");
27768 Ok(())
27769 }
27770
27771 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
27772 self.write_keyword("FLOAT64");
27774 self.write("(");
27775 self.generate_expression(&e.this)?;
27776 if let Some(expr) = &e.expression {
27777 self.write(", ");
27778 self.generate_expression(expr)?;
27779 }
27780 self.write(")");
27781 Ok(())
27782 }
27783
27784 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
27785 self.write_keyword("FOR");
27787 self.write_space();
27788 self.generate_expression(&e.this)?;
27789 self.write_space();
27790 self.write_keyword("DO");
27791 self.write_space();
27792 self.generate_expression(&e.expression)?;
27793 Ok(())
27794 }
27795
27796 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
27797 self.write_keyword("FOREIGN KEY");
27799 if !e.expressions.is_empty() {
27800 self.write(" (");
27801 for (i, expr) in e.expressions.iter().enumerate() {
27802 if i > 0 {
27803 self.write(", ");
27804 }
27805 self.generate_expression(expr)?;
27806 }
27807 self.write(")");
27808 }
27809 if let Some(reference) = &e.reference {
27810 self.write_space();
27811 self.generate_expression(reference)?;
27812 }
27813 if let Some(delete) = &e.delete {
27814 self.write_space();
27815 self.write_keyword("ON DELETE");
27816 self.write_space();
27817 self.generate_expression(delete)?;
27818 }
27819 if let Some(update) = &e.update {
27820 self.write_space();
27821 self.write_keyword("ON UPDATE");
27822 self.write_space();
27823 self.generate_expression(update)?;
27824 }
27825 if !e.options.is_empty() {
27826 self.write_space();
27827 for (i, opt) in e.options.iter().enumerate() {
27828 if i > 0 {
27829 self.write_space();
27830 }
27831 self.generate_expression(opt)?;
27832 }
27833 }
27834 Ok(())
27835 }
27836
27837 fn generate_format(&mut self, e: &Format) -> Result<()> {
27838 self.write_keyword("FORMAT");
27840 self.write("(");
27841 self.generate_expression(&e.this)?;
27842 for expr in &e.expressions {
27843 self.write(", ");
27844 self.generate_expression(expr)?;
27845 }
27846 self.write(")");
27847 Ok(())
27848 }
27849
27850 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
27851 self.generate_expression(&e.this)?;
27853 self.write(" (");
27854 self.write_keyword("FORMAT");
27855 self.write(" '");
27856 self.write(&e.format);
27857 self.write("')");
27858 Ok(())
27859 }
27860
27861 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
27862 self.write_keyword("FREESPACE");
27864 self.write("=");
27865 self.generate_expression(&e.this)?;
27866 if e.percent.is_some() {
27867 self.write_keyword(" PERCENT");
27868 }
27869 Ok(())
27870 }
27871
27872 fn generate_from(&mut self, e: &From) -> Result<()> {
27873 self.write_keyword("FROM");
27875 self.write_space();
27876
27877 use crate::dialects::DialectType;
27881 let has_tablesample = e
27882 .expressions
27883 .iter()
27884 .any(|expr| matches!(expr, Expression::TableSample(_)));
27885 let is_cross_join_dialect = matches!(
27886 self.config.dialect,
27887 Some(DialectType::BigQuery)
27888 | Some(DialectType::Hive)
27889 | Some(DialectType::Spark)
27890 | Some(DialectType::Databricks)
27891 | Some(DialectType::SQLite)
27892 | Some(DialectType::ClickHouse)
27893 );
27894 let source_is_same_as_target2 = self.config.source_dialect.is_some()
27895 && self.config.source_dialect == self.config.dialect;
27896 let source_is_cross_join_dialect2 = matches!(
27897 self.config.source_dialect,
27898 Some(DialectType::BigQuery)
27899 | Some(DialectType::Hive)
27900 | Some(DialectType::Spark)
27901 | Some(DialectType::Databricks)
27902 | Some(DialectType::SQLite)
27903 | Some(DialectType::ClickHouse)
27904 );
27905 let use_cross_join = !has_tablesample
27906 && is_cross_join_dialect
27907 && (source_is_same_as_target2
27908 || source_is_cross_join_dialect2
27909 || self.config.source_dialect.is_none());
27910
27911 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
27913
27914 for (i, expr) in e.expressions.iter().enumerate() {
27915 if i > 0 {
27916 if use_cross_join {
27917 self.write(" CROSS JOIN ");
27918 } else {
27919 self.write(", ");
27920 }
27921 }
27922 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
27923 self.write("(");
27924 self.generate_expression(expr)?;
27925 self.write(")");
27926 } else {
27927 self.generate_expression(expr)?;
27928 }
27929 }
27930 Ok(())
27931 }
27932
27933 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
27934 self.write_keyword("FROM_BASE");
27936 self.write("(");
27937 self.generate_expression(&e.this)?;
27938 self.write(", ");
27939 self.generate_expression(&e.expression)?;
27940 self.write(")");
27941 Ok(())
27942 }
27943
27944 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
27945 self.generate_expression(&e.this)?;
27947 if let Some(zone) = &e.zone {
27948 self.write_space();
27949 self.write_keyword("AT TIME ZONE");
27950 self.write_space();
27951 self.generate_expression(zone)?;
27952 self.write_space();
27953 self.write_keyword("AT TIME ZONE");
27954 self.write(" 'UTC'");
27955 }
27956 Ok(())
27957 }
27958
27959 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
27960 self.write_keyword("GAP_FILL");
27962 self.write("(");
27963 self.generate_expression(&e.this)?;
27964 if let Some(ts_column) = &e.ts_column {
27965 self.write(", ");
27966 self.generate_expression(ts_column)?;
27967 }
27968 if let Some(bucket_width) = &e.bucket_width {
27969 self.write(", ");
27970 self.generate_expression(bucket_width)?;
27971 }
27972 if let Some(partitioning_columns) = &e.partitioning_columns {
27973 self.write(", ");
27974 self.generate_expression(partitioning_columns)?;
27975 }
27976 if let Some(value_columns) = &e.value_columns {
27977 self.write(", ");
27978 self.generate_expression(value_columns)?;
27979 }
27980 self.write(")");
27981 Ok(())
27982 }
27983
27984 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
27985 self.write_keyword("GENERATE_DATE_ARRAY");
27987 self.write("(");
27988 let mut first = true;
27989 if let Some(start) = &e.start {
27990 self.generate_expression(start)?;
27991 first = false;
27992 }
27993 if let Some(end) = &e.end {
27994 if !first {
27995 self.write(", ");
27996 }
27997 self.generate_expression(end)?;
27998 first = false;
27999 }
28000 if let Some(step) = &e.step {
28001 if !first {
28002 self.write(", ");
28003 }
28004 self.generate_expression(step)?;
28005 }
28006 self.write(")");
28007 Ok(())
28008 }
28009
28010 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
28011 self.write_keyword("ML.GENERATE_EMBEDDING");
28013 self.write("(");
28014 self.generate_expression(&e.this)?;
28015 self.write(", ");
28016 self.generate_expression(&e.expression)?;
28017 if let Some(params) = &e.params_struct {
28018 self.write(", ");
28019 self.generate_expression(params)?;
28020 }
28021 self.write(")");
28022 Ok(())
28023 }
28024
28025 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
28026 let fn_name = match self.config.dialect {
28028 Some(DialectType::Presto)
28029 | Some(DialectType::Trino)
28030 | Some(DialectType::Athena)
28031 | Some(DialectType::Spark)
28032 | Some(DialectType::Databricks)
28033 | Some(DialectType::Hive) => "SEQUENCE",
28034 _ => "GENERATE_SERIES",
28035 };
28036 self.write_keyword(fn_name);
28037 self.write("(");
28038 let mut first = true;
28039 if let Some(start) = &e.start {
28040 self.generate_expression(start)?;
28041 first = false;
28042 }
28043 if let Some(end) = &e.end {
28044 if !first {
28045 self.write(", ");
28046 }
28047 self.generate_expression(end)?;
28048 first = false;
28049 }
28050 if let Some(step) = &e.step {
28051 if !first {
28052 self.write(", ");
28053 }
28054 if matches!(
28057 self.config.dialect,
28058 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
28059 ) {
28060 if let Some(converted) = self.convert_week_interval_to_day(step) {
28061 self.generate_expression(&converted)?;
28062 } else {
28063 self.generate_expression(step)?;
28064 }
28065 } else {
28066 self.generate_expression(step)?;
28067 }
28068 }
28069 self.write(")");
28070 Ok(())
28071 }
28072
28073 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
28076 use crate::expressions::*;
28077 if let Expression::Interval(ref iv) = expr {
28078 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
28080 unit: IntervalUnit::Week,
28081 ..
28082 }) = &iv.unit
28083 {
28084 let count = match &iv.this {
28086 Some(Expression::Literal(lit)) => match lit.as_ref() {
28087 Literal::String(s) | Literal::Number(s) => s.clone(),
28088 _ => return None,
28089 },
28090 _ => return None,
28091 };
28092 (true, count)
28093 } else if iv.unit.is_none() {
28094 if let Some(Expression::Literal(lit)) = &iv.this {
28096 if let Literal::String(s) = lit.as_ref() {
28097 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
28098 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
28099 (true, parts[0].to_string())
28100 } else {
28101 (false, String::new())
28102 }
28103 } else { (false, String::new()) }
28104 } else {
28105 (false, String::new())
28106 }
28107 } else {
28108 (false, String::new())
28109 };
28110
28111 if is_week {
28112 let count_expr = Expression::Literal(Box::new(Literal::Number(count_str)));
28114 let day_interval = Expression::Interval(Box::new(Interval {
28115 this: Some(Expression::Literal(Box::new(Literal::String("7".to_string())))),
28116 unit: Some(IntervalUnitSpec::Simple {
28117 unit: IntervalUnit::Day,
28118 use_plural: false,
28119 }),
28120 }));
28121 let mul = Expression::Mul(Box::new(BinaryOp {
28122 left: count_expr,
28123 right: day_interval,
28124 left_comments: vec![],
28125 operator_comments: vec![],
28126 trailing_comments: vec![],
28127 inferred_type: None,
28128 }));
28129 return Some(Expression::Paren(Box::new(Paren {
28130 this: mul,
28131 trailing_comments: vec![],
28132 })));
28133 }
28134 }
28135 None
28136 }
28137
28138 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
28139 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
28141 self.write("(");
28142 let mut first = true;
28143 if let Some(start) = &e.start {
28144 self.generate_expression(start)?;
28145 first = false;
28146 }
28147 if let Some(end) = &e.end {
28148 if !first {
28149 self.write(", ");
28150 }
28151 self.generate_expression(end)?;
28152 first = false;
28153 }
28154 if let Some(step) = &e.step {
28155 if !first {
28156 self.write(", ");
28157 }
28158 self.generate_expression(step)?;
28159 }
28160 self.write(")");
28161 Ok(())
28162 }
28163
28164 fn generate_generated_as_identity_column_constraint(
28165 &mut self,
28166 e: &GeneratedAsIdentityColumnConstraint,
28167 ) -> Result<()> {
28168 use crate::dialects::DialectType;
28169
28170 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
28172 self.write_keyword("AUTOINCREMENT");
28173 if let Some(start) = &e.start {
28174 self.write_keyword(" START ");
28175 self.generate_expression(start)?;
28176 }
28177 if let Some(increment) = &e.increment {
28178 self.write_keyword(" INCREMENT ");
28179 self.generate_expression(increment)?;
28180 }
28181 return Ok(());
28182 }
28183
28184 self.write_keyword("GENERATED");
28186 if let Some(this) = &e.this {
28187 if let Expression::Boolean(b) = this.as_ref() {
28189 if b.value {
28190 self.write_keyword(" ALWAYS");
28191 } else {
28192 self.write_keyword(" BY DEFAULT");
28193 if e.on_null.is_some() {
28194 self.write_keyword(" ON NULL");
28195 }
28196 }
28197 } else {
28198 self.write_keyword(" ALWAYS");
28199 }
28200 }
28201 self.write_keyword(" AS IDENTITY");
28202 let has_options = e.start.is_some()
28204 || e.increment.is_some()
28205 || e.minvalue.is_some()
28206 || e.maxvalue.is_some();
28207 if has_options {
28208 self.write(" (");
28209 let mut first = true;
28210 if let Some(start) = &e.start {
28211 self.write_keyword("START WITH ");
28212 self.generate_expression(start)?;
28213 first = false;
28214 }
28215 if let Some(increment) = &e.increment {
28216 if !first {
28217 self.write(" ");
28218 }
28219 self.write_keyword("INCREMENT BY ");
28220 self.generate_expression(increment)?;
28221 first = false;
28222 }
28223 if let Some(minvalue) = &e.minvalue {
28224 if !first {
28225 self.write(" ");
28226 }
28227 self.write_keyword("MINVALUE ");
28228 self.generate_expression(minvalue)?;
28229 first = false;
28230 }
28231 if let Some(maxvalue) = &e.maxvalue {
28232 if !first {
28233 self.write(" ");
28234 }
28235 self.write_keyword("MAXVALUE ");
28236 self.generate_expression(maxvalue)?;
28237 }
28238 self.write(")");
28239 }
28240 Ok(())
28241 }
28242
28243 fn generate_generated_as_row_column_constraint(
28244 &mut self,
28245 e: &GeneratedAsRowColumnConstraint,
28246 ) -> Result<()> {
28247 self.write_keyword("GENERATED ALWAYS AS ROW ");
28249 if e.start.is_some() {
28250 self.write_keyword("START");
28251 } else {
28252 self.write_keyword("END");
28253 }
28254 if e.hidden.is_some() {
28255 self.write_keyword(" HIDDEN");
28256 }
28257 Ok(())
28258 }
28259
28260 fn generate_get(&mut self, e: &Get) -> Result<()> {
28261 self.write_keyword("GET");
28263 self.write_space();
28264 self.generate_expression(&e.this)?;
28265 if let Some(target) = &e.target {
28266 self.write_space();
28267 self.generate_expression(target)?;
28268 }
28269 for prop in &e.properties {
28270 self.write_space();
28271 self.generate_expression(prop)?;
28272 }
28273 Ok(())
28274 }
28275
28276 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
28277 self.generate_expression(&e.this)?;
28279 self.write("[");
28280 self.generate_expression(&e.expression)?;
28281 self.write("]");
28282 Ok(())
28283 }
28284
28285 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
28286 self.write_keyword("GETBIT");
28288 self.write("(");
28289 self.generate_expression(&e.this)?;
28290 self.write(", ");
28291 self.generate_expression(&e.expression)?;
28292 self.write(")");
28293 Ok(())
28294 }
28295
28296 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
28297 if e.is_role {
28299 self.write_keyword("ROLE");
28300 self.write_space();
28301 } else if e.is_group {
28302 self.write_keyword("GROUP");
28303 self.write_space();
28304 }
28305 self.write(&e.name.name);
28306 Ok(())
28307 }
28308
28309 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
28310 self.generate_expression(&e.this)?;
28312 if !e.expressions.is_empty() {
28313 self.write("(");
28314 for (i, expr) in e.expressions.iter().enumerate() {
28315 if i > 0 {
28316 self.write(", ");
28317 }
28318 self.generate_expression(expr)?;
28319 }
28320 self.write(")");
28321 }
28322 Ok(())
28323 }
28324
28325 fn generate_group(&mut self, e: &Group) -> Result<()> {
28326 self.write_keyword("GROUP BY");
28328 match e.all {
28330 Some(true) => {
28331 self.write_space();
28332 self.write_keyword("ALL");
28333 }
28334 Some(false) => {
28335 self.write_space();
28336 self.write_keyword("DISTINCT");
28337 }
28338 None => {}
28339 }
28340 if !e.expressions.is_empty() {
28341 self.write_space();
28342 for (i, expr) in e.expressions.iter().enumerate() {
28343 if i > 0 {
28344 self.write(", ");
28345 }
28346 self.generate_expression(expr)?;
28347 }
28348 }
28349 if let Some(cube) = &e.cube {
28351 if !e.expressions.is_empty() {
28352 self.write(", ");
28353 } else {
28354 self.write_space();
28355 }
28356 self.generate_expression(cube)?;
28357 }
28358 if let Some(rollup) = &e.rollup {
28359 if !e.expressions.is_empty() || e.cube.is_some() {
28360 self.write(", ");
28361 } else {
28362 self.write_space();
28363 }
28364 self.generate_expression(rollup)?;
28365 }
28366 if let Some(grouping_sets) = &e.grouping_sets {
28367 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
28368 self.write(", ");
28369 } else {
28370 self.write_space();
28371 }
28372 self.generate_expression(grouping_sets)?;
28373 }
28374 if let Some(totals) = &e.totals {
28375 self.write_space();
28376 self.write_keyword("WITH TOTALS");
28377 self.generate_expression(totals)?;
28378 }
28379 Ok(())
28380 }
28381
28382 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
28383 self.write_keyword("GROUP BY");
28385 match e.all {
28387 Some(true) => {
28388 self.write_space();
28389 self.write_keyword("ALL");
28390 }
28391 Some(false) => {
28392 self.write_space();
28393 self.write_keyword("DISTINCT");
28394 }
28395 None => {}
28396 }
28397
28398 let mut trailing_cube = false;
28401 let mut trailing_rollup = false;
28402 let mut regular_expressions: Vec<&Expression> = Vec::new();
28403
28404 for expr in &e.expressions {
28405 match expr {
28406 Expression::Cube(c) if c.expressions.is_empty() => {
28407 trailing_cube = true;
28408 }
28409 Expression::Rollup(r) if r.expressions.is_empty() => {
28410 trailing_rollup = true;
28411 }
28412 _ => {
28413 regular_expressions.push(expr);
28414 }
28415 }
28416 }
28417
28418 if self.config.pretty {
28420 self.write_newline();
28421 self.indent_level += 1;
28422 for (i, expr) in regular_expressions.iter().enumerate() {
28423 if i > 0 {
28424 self.write(",");
28425 self.write_newline();
28426 }
28427 self.write_indent();
28428 self.generate_expression(expr)?;
28429 }
28430 self.indent_level -= 1;
28431 } else {
28432 self.write_space();
28433 for (i, expr) in regular_expressions.iter().enumerate() {
28434 if i > 0 {
28435 self.write(", ");
28436 }
28437 self.generate_expression(expr)?;
28438 }
28439 }
28440
28441 if trailing_cube {
28443 self.write_space();
28444 self.write_keyword("WITH CUBE");
28445 } else if trailing_rollup {
28446 self.write_space();
28447 self.write_keyword("WITH ROLLUP");
28448 }
28449
28450 if e.totals {
28452 self.write_space();
28453 self.write_keyword("WITH TOTALS");
28454 }
28455
28456 Ok(())
28457 }
28458
28459 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
28460 self.write_keyword("GROUPING");
28462 self.write("(");
28463 for (i, expr) in e.expressions.iter().enumerate() {
28464 if i > 0 {
28465 self.write(", ");
28466 }
28467 self.generate_expression(expr)?;
28468 }
28469 self.write(")");
28470 Ok(())
28471 }
28472
28473 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
28474 self.write_keyword("GROUPING_ID");
28476 self.write("(");
28477 for (i, expr) in e.expressions.iter().enumerate() {
28478 if i > 0 {
28479 self.write(", ");
28480 }
28481 self.generate_expression(expr)?;
28482 }
28483 self.write(")");
28484 Ok(())
28485 }
28486
28487 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
28488 self.write_keyword("GROUPING SETS");
28490 self.write(" (");
28491 for (i, expr) in e.expressions.iter().enumerate() {
28492 if i > 0 {
28493 self.write(", ");
28494 }
28495 self.generate_expression(expr)?;
28496 }
28497 self.write(")");
28498 Ok(())
28499 }
28500
28501 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
28502 self.write_keyword("HASH_AGG");
28504 self.write("(");
28505 self.generate_expression(&e.this)?;
28506 for expr in &e.expressions {
28507 self.write(", ");
28508 self.generate_expression(expr)?;
28509 }
28510 self.write(")");
28511 Ok(())
28512 }
28513
28514 fn generate_having(&mut self, e: &Having) -> Result<()> {
28515 self.write_keyword("HAVING");
28517 self.write_space();
28518 self.generate_expression(&e.this)?;
28519 Ok(())
28520 }
28521
28522 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
28523 self.generate_expression(&e.this)?;
28525 self.write_space();
28526 self.write_keyword("HAVING");
28527 self.write_space();
28528 if e.max.is_some() {
28529 self.write_keyword("MAX");
28530 } else {
28531 self.write_keyword("MIN");
28532 }
28533 self.write_space();
28534 self.generate_expression(&e.expression)?;
28535 Ok(())
28536 }
28537
28538 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
28539 use crate::dialects::DialectType;
28540 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
28542 if let Expression::Literal(ref lit) = *e.this {
28544 if let Literal::String(ref s) = lit.as_ref() {
28545 return self.generate_string_literal(s);
28546 }
28547 }
28548 }
28549 if matches!(
28551 self.config.dialect,
28552 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
28553 ) {
28554 self.write("$");
28555 if let Some(tag) = &e.tag {
28556 self.generate_expression(tag)?;
28557 }
28558 self.write("$");
28559 self.generate_expression(&e.this)?;
28560 self.write("$");
28561 if let Some(tag) = &e.tag {
28562 self.generate_expression(tag)?;
28563 }
28564 self.write("$");
28565 return Ok(());
28566 }
28567 self.write("$");
28569 if let Some(tag) = &e.tag {
28570 self.generate_expression(tag)?;
28571 }
28572 self.write("$");
28573 self.generate_expression(&e.this)?;
28574 self.write("$");
28575 if let Some(tag) = &e.tag {
28576 self.generate_expression(tag)?;
28577 }
28578 self.write("$");
28579 Ok(())
28580 }
28581
28582 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
28583 self.write_keyword("HEX_ENCODE");
28585 self.write("(");
28586 self.generate_expression(&e.this)?;
28587 self.write(")");
28588 Ok(())
28589 }
28590
28591 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
28592 match e.this.as_ref() {
28595 Expression::Identifier(id) => self.write(&id.name),
28596 other => self.generate_expression(other)?,
28597 }
28598 self.write(" (");
28599 self.write(&e.kind);
28600 self.write(" => ");
28601 self.generate_expression(&e.expression)?;
28602 self.write(")");
28603 Ok(())
28604 }
28605
28606 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
28607 self.write_keyword("HLL");
28609 self.write("(");
28610 self.generate_expression(&e.this)?;
28611 for expr in &e.expressions {
28612 self.write(", ");
28613 self.generate_expression(expr)?;
28614 }
28615 self.write(")");
28616 Ok(())
28617 }
28618
28619 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
28620 if e.input_.is_some() && e.output.is_some() {
28622 self.write_keyword("IN OUT");
28623 } else if e.input_.is_some() {
28624 self.write_keyword("IN");
28625 } else if e.output.is_some() {
28626 self.write_keyword("OUT");
28627 }
28628 Ok(())
28629 }
28630
28631 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
28632 self.write_keyword("INCLUDE");
28634 self.write_space();
28635 self.generate_expression(&e.this)?;
28636 if let Some(column_def) = &e.column_def {
28637 self.write_space();
28638 self.generate_expression(column_def)?;
28639 }
28640 if let Some(alias) = &e.alias {
28641 self.write_space();
28642 self.write_keyword("AS");
28643 self.write_space();
28644 self.write(alias);
28645 }
28646 Ok(())
28647 }
28648
28649 fn generate_index(&mut self, e: &Index) -> Result<()> {
28650 if e.unique {
28652 self.write_keyword("UNIQUE");
28653 self.write_space();
28654 }
28655 if e.primary.is_some() {
28656 self.write_keyword("PRIMARY");
28657 self.write_space();
28658 }
28659 if e.amp.is_some() {
28660 self.write_keyword("AMP");
28661 self.write_space();
28662 }
28663 if e.table.is_none() {
28664 self.write_keyword("INDEX");
28665 self.write_space();
28666 }
28667 if let Some(name) = &e.this {
28668 self.generate_expression(name)?;
28669 self.write_space();
28670 }
28671 if let Some(table) = &e.table {
28672 self.write_keyword("ON");
28673 self.write_space();
28674 self.generate_expression(table)?;
28675 }
28676 if !e.params.is_empty() {
28677 self.write("(");
28678 for (i, param) in e.params.iter().enumerate() {
28679 if i > 0 {
28680 self.write(", ");
28681 }
28682 self.generate_expression(param)?;
28683 }
28684 self.write(")");
28685 }
28686 Ok(())
28687 }
28688
28689 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
28690 if let Some(kind) = &e.kind {
28692 self.write(kind);
28693 self.write_space();
28694 }
28695 self.write_keyword("INDEX");
28696 if let Some(this) = &e.this {
28697 self.write_space();
28698 self.generate_expression(this)?;
28699 }
28700 if let Some(index_type) = &e.index_type {
28701 self.write_space();
28702 self.write_keyword("USING");
28703 self.write_space();
28704 self.generate_expression(index_type)?;
28705 }
28706 if !e.expressions.is_empty() {
28707 self.write(" (");
28708 for (i, expr) in e.expressions.iter().enumerate() {
28709 if i > 0 {
28710 self.write(", ");
28711 }
28712 self.generate_expression(expr)?;
28713 }
28714 self.write(")");
28715 }
28716 for opt in &e.options {
28717 self.write_space();
28718 self.generate_expression(opt)?;
28719 }
28720 Ok(())
28721 }
28722
28723 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
28724 if let Some(key_block_size) = &e.key_block_size {
28726 self.write_keyword("KEY_BLOCK_SIZE");
28727 self.write(" = ");
28728 self.generate_expression(key_block_size)?;
28729 } else if let Some(using) = &e.using {
28730 self.write_keyword("USING");
28731 self.write_space();
28732 self.generate_expression(using)?;
28733 } else if let Some(parser) = &e.parser {
28734 self.write_keyword("WITH PARSER");
28735 self.write_space();
28736 self.generate_expression(parser)?;
28737 } else if let Some(comment) = &e.comment {
28738 self.write_keyword("COMMENT");
28739 self.write_space();
28740 self.generate_expression(comment)?;
28741 } else if let Some(visible) = &e.visible {
28742 self.generate_expression(visible)?;
28743 } else if let Some(engine_attr) = &e.engine_attr {
28744 self.write_keyword("ENGINE_ATTRIBUTE");
28745 self.write(" = ");
28746 self.generate_expression(engine_attr)?;
28747 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
28748 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
28749 self.write(" = ");
28750 self.generate_expression(secondary_engine_attr)?;
28751 }
28752 Ok(())
28753 }
28754
28755 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
28756 if let Some(using) = &e.using {
28758 self.write_keyword("USING");
28759 self.write_space();
28760 self.generate_expression(using)?;
28761 }
28762 if !e.columns.is_empty() {
28763 self.write("(");
28764 for (i, col) in e.columns.iter().enumerate() {
28765 if i > 0 {
28766 self.write(", ");
28767 }
28768 self.generate_expression(col)?;
28769 }
28770 self.write(")");
28771 }
28772 if let Some(partition_by) = &e.partition_by {
28773 self.write_space();
28774 self.write_keyword("PARTITION BY");
28775 self.write_space();
28776 self.generate_expression(partition_by)?;
28777 }
28778 if let Some(where_) = &e.where_ {
28779 self.write_space();
28780 self.generate_expression(where_)?;
28781 }
28782 if let Some(include) = &e.include {
28783 self.write_space();
28784 self.write_keyword("INCLUDE");
28785 self.write(" (");
28786 self.generate_expression(include)?;
28787 self.write(")");
28788 }
28789 if let Some(with_storage) = &e.with_storage {
28790 self.write_space();
28791 self.write_keyword("WITH");
28792 self.write(" (");
28793 self.generate_expression(with_storage)?;
28794 self.write(")");
28795 }
28796 if let Some(tablespace) = &e.tablespace {
28797 self.write_space();
28798 self.write_keyword("USING INDEX TABLESPACE");
28799 self.write_space();
28800 self.generate_expression(tablespace)?;
28801 }
28802 Ok(())
28803 }
28804
28805 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
28806 if let Expression::Identifier(id) = &*e.this {
28810 self.write_keyword(&id.name);
28811 } else {
28812 self.generate_expression(&e.this)?;
28813 }
28814 self.write_space();
28815 self.write_keyword("INDEX");
28816 if let Some(target) = &e.target {
28817 self.write_space();
28818 self.write_keyword("FOR");
28819 self.write_space();
28820 if let Expression::Identifier(id) = &**target {
28821 self.write_keyword(&id.name);
28822 } else {
28823 self.generate_expression(target)?;
28824 }
28825 }
28826 self.write(" (");
28828 for (i, expr) in e.expressions.iter().enumerate() {
28829 if i > 0 {
28830 self.write(", ");
28831 }
28832 self.generate_expression(expr)?;
28833 }
28834 self.write(")");
28835 Ok(())
28836 }
28837
28838 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
28839 self.write_keyword("INHERITS");
28841 self.write(" (");
28842 for (i, expr) in e.expressions.iter().enumerate() {
28843 if i > 0 {
28844 self.write(", ");
28845 }
28846 self.generate_expression(expr)?;
28847 }
28848 self.write(")");
28849 Ok(())
28850 }
28851
28852 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
28853 self.write_keyword("INPUT");
28855 self.write("(");
28856 self.generate_expression(&e.this)?;
28857 self.write(")");
28858 Ok(())
28859 }
28860
28861 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
28862 if let Some(input_format) = &e.input_format {
28864 self.write_keyword("INPUTFORMAT");
28865 self.write_space();
28866 self.generate_expression(input_format)?;
28867 }
28868 if let Some(output_format) = &e.output_format {
28869 if e.input_format.is_some() {
28870 self.write(" ");
28871 }
28872 self.write_keyword("OUTPUTFORMAT");
28873 self.write_space();
28874 self.generate_expression(output_format)?;
28875 }
28876 Ok(())
28877 }
28878
28879 fn generate_install(&mut self, e: &Install) -> Result<()> {
28880 if e.force.is_some() {
28882 self.write_keyword("FORCE");
28883 self.write_space();
28884 }
28885 self.write_keyword("INSTALL");
28886 self.write_space();
28887 self.generate_expression(&e.this)?;
28888 if let Some(from) = &e.from_ {
28889 self.write_space();
28890 self.write_keyword("FROM");
28891 self.write_space();
28892 self.generate_expression(from)?;
28893 }
28894 Ok(())
28895 }
28896
28897 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
28898 self.write_keyword("INTERVAL");
28900 self.write_space();
28901 self.generate_expression(&e.expression)?;
28903 if let Some(unit) = &e.unit {
28904 self.write_space();
28905 self.write(unit);
28906 }
28907 Ok(())
28908 }
28909
28910 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
28911 self.write(&format!("{:?}", e.this).to_ascii_uppercase());
28913 self.write_space();
28914 self.write_keyword("TO");
28915 self.write_space();
28916 self.write(&format!("{:?}", e.expression).to_ascii_uppercase());
28917 Ok(())
28918 }
28919
28920 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
28921 self.write_keyword("INTO");
28923 if e.temporary {
28924 self.write_keyword(" TEMPORARY");
28925 }
28926 if e.unlogged.is_some() {
28927 self.write_keyword(" UNLOGGED");
28928 }
28929 if let Some(this) = &e.this {
28930 self.write_space();
28931 self.generate_expression(this)?;
28932 }
28933 if !e.expressions.is_empty() {
28934 self.write(" (");
28935 for (i, expr) in e.expressions.iter().enumerate() {
28936 if i > 0 {
28937 self.write(", ");
28938 }
28939 self.generate_expression(expr)?;
28940 }
28941 self.write(")");
28942 }
28943 Ok(())
28944 }
28945
28946 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
28947 self.generate_expression(&e.this)?;
28949 self.write_space();
28950 self.generate_expression(&e.expression)?;
28951 Ok(())
28952 }
28953
28954 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
28955 self.write_keyword("WITH");
28957 if e.no.is_some() {
28958 self.write_keyword(" NO");
28959 }
28960 if e.concurrent.is_some() {
28961 self.write_keyword(" CONCURRENT");
28962 }
28963 self.write_keyword(" ISOLATED LOADING");
28964 if let Some(target) = &e.target {
28965 self.write_space();
28966 self.generate_expression(target)?;
28967 }
28968 Ok(())
28969 }
28970
28971 fn generate_json(&mut self, e: &JSON) -> Result<()> {
28972 self.write_keyword("JSON");
28974 if let Some(this) = &e.this {
28975 self.write_space();
28976 self.generate_expression(this)?;
28977 }
28978 if let Some(with_) = &e.with_ {
28979 if let Expression::Boolean(b) = with_.as_ref() {
28981 if b.value {
28982 self.write_keyword(" WITH");
28983 } else {
28984 self.write_keyword(" WITHOUT");
28985 }
28986 }
28987 }
28988 if e.unique {
28989 self.write_keyword(" UNIQUE KEYS");
28990 }
28991 Ok(())
28992 }
28993
28994 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
28995 self.write_keyword("JSON_ARRAY");
28997 self.write("(");
28998 for (i, expr) in e.expressions.iter().enumerate() {
28999 if i > 0 {
29000 self.write(", ");
29001 }
29002 self.generate_expression(expr)?;
29003 }
29004 if let Some(null_handling) = &e.null_handling {
29005 self.write_space();
29006 self.generate_expression(null_handling)?;
29007 }
29008 if let Some(return_type) = &e.return_type {
29009 self.write_space();
29010 self.write_keyword("RETURNING");
29011 self.write_space();
29012 self.generate_expression(return_type)?;
29013 }
29014 if e.strict.is_some() {
29015 self.write_space();
29016 self.write_keyword("STRICT");
29017 }
29018 self.write(")");
29019 Ok(())
29020 }
29021
29022 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
29023 self.write_keyword("JSON_ARRAYAGG");
29025 self.write("(");
29026 self.generate_expression(&e.this)?;
29027 if let Some(order) = &e.order {
29028 self.write_space();
29029 if let Expression::OrderBy(ob) = order.as_ref() {
29031 self.write_keyword("ORDER BY");
29032 self.write_space();
29033 for (i, ord) in ob.expressions.iter().enumerate() {
29034 if i > 0 {
29035 self.write(", ");
29036 }
29037 self.generate_ordered(ord)?;
29038 }
29039 } else {
29040 self.generate_expression(order)?;
29042 }
29043 }
29044 if let Some(null_handling) = &e.null_handling {
29045 self.write_space();
29046 self.generate_expression(null_handling)?;
29047 }
29048 if let Some(return_type) = &e.return_type {
29049 self.write_space();
29050 self.write_keyword("RETURNING");
29051 self.write_space();
29052 self.generate_expression(return_type)?;
29053 }
29054 if e.strict.is_some() {
29055 self.write_space();
29056 self.write_keyword("STRICT");
29057 }
29058 self.write(")");
29059 Ok(())
29060 }
29061
29062 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
29063 self.write_keyword("JSON_OBJECTAGG");
29065 self.write("(");
29066 for (i, expr) in e.expressions.iter().enumerate() {
29067 if i > 0 {
29068 self.write(", ");
29069 }
29070 self.generate_expression(expr)?;
29071 }
29072 if let Some(null_handling) = &e.null_handling {
29073 self.write_space();
29074 self.generate_expression(null_handling)?;
29075 }
29076 if let Some(unique_keys) = &e.unique_keys {
29077 self.write_space();
29078 if let Expression::Boolean(b) = unique_keys.as_ref() {
29079 if b.value {
29080 self.write_keyword("WITH UNIQUE KEYS");
29081 } else {
29082 self.write_keyword("WITHOUT UNIQUE KEYS");
29083 }
29084 }
29085 }
29086 if let Some(return_type) = &e.return_type {
29087 self.write_space();
29088 self.write_keyword("RETURNING");
29089 self.write_space();
29090 self.generate_expression(return_type)?;
29091 }
29092 self.write(")");
29093 Ok(())
29094 }
29095
29096 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
29097 self.write_keyword("JSON_ARRAY_APPEND");
29099 self.write("(");
29100 self.generate_expression(&e.this)?;
29101 for expr in &e.expressions {
29102 self.write(", ");
29103 self.generate_expression(expr)?;
29104 }
29105 self.write(")");
29106 Ok(())
29107 }
29108
29109 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
29110 self.write_keyword("JSON_ARRAY_CONTAINS");
29112 self.write("(");
29113 self.generate_expression(&e.this)?;
29114 self.write(", ");
29115 self.generate_expression(&e.expression)?;
29116 self.write(")");
29117 Ok(())
29118 }
29119
29120 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
29121 self.write_keyword("JSON_ARRAY_INSERT");
29123 self.write("(");
29124 self.generate_expression(&e.this)?;
29125 for expr in &e.expressions {
29126 self.write(", ");
29127 self.generate_expression(expr)?;
29128 }
29129 self.write(")");
29130 Ok(())
29131 }
29132
29133 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
29134 self.write_keyword("JSONB_EXISTS");
29136 self.write("(");
29137 self.generate_expression(&e.this)?;
29138 if let Some(path) = &e.path {
29139 self.write(", ");
29140 self.generate_expression(path)?;
29141 }
29142 self.write(")");
29143 Ok(())
29144 }
29145
29146 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
29147 self.write_keyword("JSONB_EXTRACT_SCALAR");
29149 self.write("(");
29150 self.generate_expression(&e.this)?;
29151 self.write(", ");
29152 self.generate_expression(&e.expression)?;
29153 self.write(")");
29154 Ok(())
29155 }
29156
29157 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
29158 self.write_keyword("JSONB_OBJECT_AGG");
29160 self.write("(");
29161 self.generate_expression(&e.this)?;
29162 self.write(", ");
29163 self.generate_expression(&e.expression)?;
29164 self.write(")");
29165 Ok(())
29166 }
29167
29168 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
29169 if let Some(nested_schema) = &e.nested_schema {
29171 self.write_keyword("NESTED");
29172 if let Some(path) = &e.path {
29173 self.write_space();
29174 self.write_keyword("PATH");
29175 self.write_space();
29176 self.generate_expression(path)?;
29177 }
29178 self.write_space();
29179 self.generate_expression(nested_schema)?;
29180 } else {
29181 if let Some(this) = &e.this {
29182 self.generate_expression(this)?;
29183 }
29184 if let Some(kind) = &e.kind {
29185 self.write_space();
29186 self.write(kind);
29187 }
29188 if let Some(path) = &e.path {
29189 self.write_space();
29190 self.write_keyword("PATH");
29191 self.write_space();
29192 self.generate_expression(path)?;
29193 }
29194 if e.ordinality.is_some() {
29195 self.write_keyword(" FOR ORDINALITY");
29196 }
29197 }
29198 Ok(())
29199 }
29200
29201 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
29202 self.write_keyword("JSON_EXISTS");
29204 self.write("(");
29205 self.generate_expression(&e.this)?;
29206 if let Some(path) = &e.path {
29207 self.write(", ");
29208 self.generate_expression(path)?;
29209 }
29210 if let Some(passing) = &e.passing {
29211 self.write_space();
29212 self.write_keyword("PASSING");
29213 self.write_space();
29214 self.generate_expression(passing)?;
29215 }
29216 if let Some(on_condition) = &e.on_condition {
29217 self.write_space();
29218 self.generate_expression(on_condition)?;
29219 }
29220 self.write(")");
29221 Ok(())
29222 }
29223
29224 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
29225 self.generate_expression(&e.this)?;
29226 self.write(".:");
29227 if Self::data_type_has_nested_expressions(&e.to) {
29231 let saved = std::mem::take(&mut self.output);
29233 self.generate_data_type(&e.to)?;
29234 let type_sql = std::mem::replace(&mut self.output, saved);
29235 self.write("\"");
29236 self.write(&type_sql);
29237 self.write("\"");
29238 } else {
29239 self.generate_data_type(&e.to)?;
29240 }
29241 Ok(())
29242 }
29243
29244 fn data_type_has_nested_expressions(dt: &DataType) -> bool {
29247 matches!(
29248 dt,
29249 DataType::Array { .. }
29250 | DataType::Map { .. }
29251 | DataType::Struct { .. }
29252 )
29253 }
29254
29255 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
29256 self.write_keyword("JSON_EXTRACT_ARRAY");
29258 self.write("(");
29259 self.generate_expression(&e.this)?;
29260 if let Some(expr) = &e.expression {
29261 self.write(", ");
29262 self.generate_expression(expr)?;
29263 }
29264 self.write(")");
29265 Ok(())
29266 }
29267
29268 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
29269 if let Some(option) = &e.option {
29271 self.generate_expression(option)?;
29272 self.write_space();
29273 }
29274 self.write_keyword("QUOTES");
29275 if e.scalar.is_some() {
29276 self.write_keyword(" SCALAR_ONLY");
29277 }
29278 Ok(())
29279 }
29280
29281 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
29282 self.write_keyword("JSON_EXTRACT_SCALAR");
29284 self.write("(");
29285 self.generate_expression(&e.this)?;
29286 self.write(", ");
29287 self.generate_expression(&e.expression)?;
29288 self.write(")");
29289 Ok(())
29290 }
29291
29292 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
29293 if e.variant_extract.is_some() {
29297 use crate::dialects::DialectType;
29298 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
29299 self.generate_expression(&e.this)?;
29303 self.write(":");
29304 match e.expression.as_ref() {
29305 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
29306 let Literal::String(s) = lit.as_ref() else { unreachable!() };
29307 self.write_databricks_json_path(s);
29308 }
29309 _ => {
29310 self.generate_expression(&e.expression)?;
29312 }
29313 }
29314 } else {
29315 self.write_keyword("GET_PATH");
29317 self.write("(");
29318 self.generate_expression(&e.this)?;
29319 self.write(", ");
29320 self.generate_expression(&e.expression)?;
29321 self.write(")");
29322 }
29323 } else {
29324 self.write_keyword("JSON_EXTRACT");
29325 self.write("(");
29326 self.generate_expression(&e.this)?;
29327 self.write(", ");
29328 self.generate_expression(&e.expression)?;
29329 for expr in &e.expressions {
29330 self.write(", ");
29331 self.generate_expression(expr)?;
29332 }
29333 self.write(")");
29334 }
29335 Ok(())
29336 }
29337
29338 fn write_databricks_json_path(&mut self, path: &str) {
29342 if path.starts_with("[\"") || path.starts_with("['") {
29345 self.write(path);
29346 return;
29347 }
29348 let mut first = true;
29352 for segment in path.split('.') {
29353 if !first {
29354 self.write(".");
29355 }
29356 first = false;
29357 if let Some(bracket_pos) = segment.find('[') {
29359 let key = &segment[..bracket_pos];
29360 let subscript = &segment[bracket_pos..];
29361 if key.is_empty() {
29362 self.write(segment);
29364 } else if Self::is_safe_json_path_key(key) {
29365 self.write(key);
29366 self.write(subscript);
29367 } else {
29368 self.write("[\"");
29369 self.write(key);
29370 self.write("\"]");
29371 self.write(subscript);
29372 }
29373 } else if Self::is_safe_json_path_key(segment) {
29374 self.write(segment);
29375 } else {
29376 self.write("[\"");
29377 self.write(segment);
29378 self.write("\"]");
29379 }
29380 }
29381 }
29382
29383 fn is_safe_json_path_key(key: &str) -> bool {
29386 if key.is_empty() {
29387 return false;
29388 }
29389 let mut chars = key.chars();
29390 let first = chars.next().unwrap();
29391 if first != '_' && !first.is_ascii_alphabetic() {
29392 return false;
29393 }
29394 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
29395 }
29396
29397 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
29398 if let Some(this) = &e.this {
29401 self.generate_expression(this)?;
29402 self.write_space();
29403 }
29404 self.write_keyword("FORMAT JSON");
29405 Ok(())
29406 }
29407
29408 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
29409 self.generate_expression(&e.this)?;
29411 self.write(": ");
29412 self.generate_expression(&e.expression)?;
29413 Ok(())
29414 }
29415
29416 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
29417 self.write_keyword("JSON_KEYS");
29419 self.write("(");
29420 self.generate_expression(&e.this)?;
29421 if let Some(expr) = &e.expression {
29422 self.write(", ");
29423 self.generate_expression(expr)?;
29424 }
29425 for expr in &e.expressions {
29426 self.write(", ");
29427 self.generate_expression(expr)?;
29428 }
29429 self.write(")");
29430 Ok(())
29431 }
29432
29433 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
29434 self.write_keyword("JSON_KEYS");
29436 self.write("(");
29437 self.generate_expression(&e.this)?;
29438 if let Some(expr) = &e.expression {
29439 self.write(", ");
29440 self.generate_expression(expr)?;
29441 }
29442 self.write(")");
29443 Ok(())
29444 }
29445
29446 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
29447 let mut path_str = String::new();
29450 for expr in &e.expressions {
29451 match expr {
29452 Expression::JSONPathRoot(_) => {
29453 path_str.push('$');
29454 }
29455 Expression::JSONPathKey(k) => {
29456 if let Expression::Literal(lit) =
29458 k.this.as_ref()
29459 {
29460 if let crate::expressions::Literal::String(s) = lit.as_ref() {
29461 path_str.push('.');
29462 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
29464 if needs_quoting {
29465 path_str.push('"');
29466 path_str.push_str(s);
29467 path_str.push('"');
29468 } else {
29469 path_str.push_str(s);
29470 }
29471 }
29472 }
29473 }
29474 Expression::JSONPathSubscript(s) => {
29475 if let Expression::Literal(lit) =
29477 s.this.as_ref()
29478 {
29479 if let crate::expressions::Literal::Number(n) = lit.as_ref() {
29480 path_str.push('[');
29481 path_str.push_str(n);
29482 path_str.push(']');
29483 }
29484 }
29485 }
29486 _ => {
29487 let mut temp_gen = Self::with_arc_config(self.config.clone());
29489 temp_gen.generate_expression(expr)?;
29490 path_str.push_str(&temp_gen.output);
29491 }
29492 }
29493 }
29494 self.write("'");
29496 self.write(&path_str);
29497 self.write("'");
29498 Ok(())
29499 }
29500
29501 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
29502 self.write("?(");
29504 self.generate_expression(&e.this)?;
29505 self.write(")");
29506 Ok(())
29507 }
29508
29509 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
29510 self.write(".");
29512 self.generate_expression(&e.this)?;
29513 Ok(())
29514 }
29515
29516 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
29517 self.write("..");
29519 if let Some(this) = &e.this {
29520 self.generate_expression(this)?;
29521 }
29522 Ok(())
29523 }
29524
29525 fn generate_json_path_root(&mut self) -> Result<()> {
29526 self.write("$");
29528 Ok(())
29529 }
29530
29531 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
29532 self.write("(");
29534 self.generate_expression(&e.this)?;
29535 self.write(")");
29536 Ok(())
29537 }
29538
29539 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
29540 self.generate_expression(&e.this)?;
29542 Ok(())
29543 }
29544
29545 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
29546 self.write("[");
29548 if let Some(start) = &e.start {
29549 self.generate_expression(start)?;
29550 }
29551 self.write(":");
29552 if let Some(end) = &e.end {
29553 self.generate_expression(end)?;
29554 }
29555 if let Some(step) = &e.step {
29556 self.write(":");
29557 self.generate_expression(step)?;
29558 }
29559 self.write("]");
29560 Ok(())
29561 }
29562
29563 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
29564 self.write("[");
29566 self.generate_expression(&e.this)?;
29567 self.write("]");
29568 Ok(())
29569 }
29570
29571 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
29572 self.write("[");
29574 for (i, expr) in e.expressions.iter().enumerate() {
29575 if i > 0 {
29576 self.write(", ");
29577 }
29578 self.generate_expression(expr)?;
29579 }
29580 self.write("]");
29581 Ok(())
29582 }
29583
29584 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
29585 self.write_keyword("JSON_REMOVE");
29587 self.write("(");
29588 self.generate_expression(&e.this)?;
29589 for expr in &e.expressions {
29590 self.write(", ");
29591 self.generate_expression(expr)?;
29592 }
29593 self.write(")");
29594 Ok(())
29595 }
29596
29597 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
29598 self.write_keyword("COLUMNS");
29601 self.write("(");
29602
29603 if self.config.pretty && !e.expressions.is_empty() {
29604 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
29606 for expr in &e.expressions {
29607 let mut temp_gen = Generator::with_arc_config(self.config.clone());
29608 temp_gen.generate_expression(expr)?;
29609 expr_strings.push(temp_gen.output);
29610 }
29611
29612 if self.too_wide(&expr_strings) {
29614 self.write_newline();
29616 self.indent_level += 1;
29617 for (i, expr_str) in expr_strings.iter().enumerate() {
29618 if i > 0 {
29619 self.write(",");
29620 self.write_newline();
29621 }
29622 self.write_indent();
29623 self.write(expr_str);
29624 }
29625 self.write_newline();
29626 self.indent_level -= 1;
29627 self.write_indent();
29628 } else {
29629 for (i, expr_str) in expr_strings.iter().enumerate() {
29631 if i > 0 {
29632 self.write(", ");
29633 }
29634 self.write(expr_str);
29635 }
29636 }
29637 } else {
29638 for (i, expr) in e.expressions.iter().enumerate() {
29640 if i > 0 {
29641 self.write(", ");
29642 }
29643 self.generate_expression(expr)?;
29644 }
29645 }
29646 self.write(")");
29647 Ok(())
29648 }
29649
29650 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
29651 self.write_keyword("JSON_SET");
29653 self.write("(");
29654 self.generate_expression(&e.this)?;
29655 for expr in &e.expressions {
29656 self.write(", ");
29657 self.generate_expression(expr)?;
29658 }
29659 self.write(")");
29660 Ok(())
29661 }
29662
29663 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
29664 self.write_keyword("JSON_STRIP_NULLS");
29666 self.write("(");
29667 self.generate_expression(&e.this)?;
29668 if let Some(expr) = &e.expression {
29669 self.write(", ");
29670 self.generate_expression(expr)?;
29671 }
29672 self.write(")");
29673 Ok(())
29674 }
29675
29676 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
29677 self.write_keyword("JSON_TABLE");
29679 self.write("(");
29680 self.generate_expression(&e.this)?;
29681 if let Some(path) = &e.path {
29682 self.write(", ");
29683 self.generate_expression(path)?;
29684 }
29685 if let Some(error_handling) = &e.error_handling {
29686 self.write_space();
29687 self.generate_expression(error_handling)?;
29688 }
29689 if let Some(empty_handling) = &e.empty_handling {
29690 self.write_space();
29691 self.generate_expression(empty_handling)?;
29692 }
29693 if let Some(schema) = &e.schema {
29694 self.write_space();
29695 self.generate_expression(schema)?;
29696 }
29697 self.write(")");
29698 Ok(())
29699 }
29700
29701 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
29702 self.write_keyword("JSON_TYPE");
29704 self.write("(");
29705 self.generate_expression(&e.this)?;
29706 self.write(")");
29707 Ok(())
29708 }
29709
29710 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
29711 self.write_keyword("JSON_VALUE");
29713 self.write("(");
29714 self.generate_expression(&e.this)?;
29715 if let Some(path) = &e.path {
29716 self.write(", ");
29717 self.generate_expression(path)?;
29718 }
29719 if let Some(returning) = &e.returning {
29720 self.write_space();
29721 self.write_keyword("RETURNING");
29722 self.write_space();
29723 self.generate_expression(returning)?;
29724 }
29725 if let Some(on_condition) = &e.on_condition {
29726 self.write_space();
29727 self.generate_expression(on_condition)?;
29728 }
29729 self.write(")");
29730 Ok(())
29731 }
29732
29733 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
29734 self.write_keyword("JSON_VALUE_ARRAY");
29736 self.write("(");
29737 self.generate_expression(&e.this)?;
29738 self.write(")");
29739 Ok(())
29740 }
29741
29742 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
29743 self.write_keyword("JAROWINKLER_SIMILARITY");
29745 self.write("(");
29746 self.generate_expression(&e.this)?;
29747 self.write(", ");
29748 self.generate_expression(&e.expression)?;
29749 self.write(")");
29750 Ok(())
29751 }
29752
29753 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
29754 self.generate_expression(&e.this)?;
29756 self.write("(");
29757 for (i, expr) in e.expressions.iter().enumerate() {
29758 if i > 0 {
29759 self.write(", ");
29760 }
29761 self.generate_expression(expr)?;
29762 }
29763 self.write(")");
29764 Ok(())
29765 }
29766
29767 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
29768 if e.no.is_some() {
29770 self.write_keyword("NO ");
29771 }
29772 if let Some(local) = &e.local {
29773 self.generate_expression(local)?;
29774 self.write_space();
29775 }
29776 if e.dual.is_some() {
29777 self.write_keyword("DUAL ");
29778 }
29779 if e.before.is_some() {
29780 self.write_keyword("BEFORE ");
29781 }
29782 if e.after.is_some() {
29783 self.write_keyword("AFTER ");
29784 }
29785 self.write_keyword("JOURNAL");
29786 Ok(())
29787 }
29788
29789 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
29790 self.write_keyword("LANGUAGE");
29792 self.write_space();
29793 self.generate_expression(&e.this)?;
29794 Ok(())
29795 }
29796
29797 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
29798 if e.view.is_some() {
29800 self.write_keyword("LATERAL VIEW");
29802 if e.outer.is_some() {
29803 self.write_space();
29804 self.write_keyword("OUTER");
29805 }
29806 self.write_space();
29807 self.generate_expression(&e.this)?;
29808 if let Some(alias) = &e.alias {
29809 self.write_space();
29810 self.write(alias);
29811 }
29812 } else {
29813 self.write_keyword("LATERAL");
29815 self.write_space();
29816 self.generate_expression(&e.this)?;
29817 if e.ordinality.is_some() {
29818 self.write_space();
29819 self.write_keyword("WITH ORDINALITY");
29820 }
29821 if let Some(alias) = &e.alias {
29822 self.write_space();
29823 self.write_keyword("AS");
29824 self.write_space();
29825 self.write(alias);
29826 if !e.column_aliases.is_empty() {
29827 self.write("(");
29828 for (i, col) in e.column_aliases.iter().enumerate() {
29829 if i > 0 {
29830 self.write(", ");
29831 }
29832 self.write(col);
29833 }
29834 self.write(")");
29835 }
29836 }
29837 }
29838 Ok(())
29839 }
29840
29841 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
29842 self.write_keyword("LIKE");
29844 self.write_space();
29845 self.generate_expression(&e.this)?;
29846 for expr in &e.expressions {
29847 self.write_space();
29848 self.generate_expression(expr)?;
29849 }
29850 Ok(())
29851 }
29852
29853 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
29854 self.write_keyword("LIMIT");
29855 self.write_space();
29856 self.write_limit_expr(&e.this)?;
29857 if e.percent {
29858 self.write_space();
29859 self.write_keyword("PERCENT");
29860 }
29861 for comment in &e.comments {
29863 self.write(" ");
29864 self.write_formatted_comment(comment);
29865 }
29866 Ok(())
29867 }
29868
29869 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
29870 if e.percent.is_some() {
29872 self.write_keyword(" PERCENT");
29873 }
29874 if e.rows.is_some() {
29875 self.write_keyword(" ROWS");
29876 }
29877 if e.with_ties.is_some() {
29878 self.write_keyword(" WITH TIES");
29879 } else if e.rows.is_some() {
29880 self.write_keyword(" ONLY");
29881 }
29882 Ok(())
29883 }
29884
29885 fn generate_list(&mut self, e: &List) -> Result<()> {
29886 use crate::dialects::DialectType;
29887 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
29888
29889 if e.expressions.len() == 1 {
29891 if let Expression::Select(_) = &e.expressions[0] {
29892 self.write_keyword("LIST");
29893 self.write("(");
29894 self.generate_expression(&e.expressions[0])?;
29895 self.write(")");
29896 return Ok(());
29897 }
29898 }
29899
29900 if is_materialize {
29902 self.write_keyword("LIST");
29903 self.write("[");
29904 for (i, expr) in e.expressions.iter().enumerate() {
29905 if i > 0 {
29906 self.write(", ");
29907 }
29908 self.generate_expression(expr)?;
29909 }
29910 self.write("]");
29911 } else {
29912 self.write_keyword("LIST");
29914 self.write("(");
29915 for (i, expr) in e.expressions.iter().enumerate() {
29916 if i > 0 {
29917 self.write(", ");
29918 }
29919 self.generate_expression(expr)?;
29920 }
29921 self.write(")");
29922 }
29923 Ok(())
29924 }
29925
29926 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
29927 if let Expression::Select(_) = &*e.this {
29929 self.write_keyword("MAP");
29930 self.write("(");
29931 self.generate_expression(&e.this)?;
29932 self.write(")");
29933 return Ok(());
29934 }
29935
29936 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
29937
29938 self.write_keyword("MAP");
29940 if is_duckdb {
29941 self.write(" {");
29942 } else {
29943 self.write("[");
29944 }
29945 if let Expression::Struct(s) = &*e.this {
29946 for (i, (_, expr)) in s.fields.iter().enumerate() {
29947 if i > 0 {
29948 self.write(", ");
29949 }
29950 if let Expression::PropertyEQ(op) = expr {
29951 self.generate_expression(&op.left)?;
29952 if is_duckdb {
29953 self.write(": ");
29954 } else {
29955 self.write(" => ");
29956 }
29957 self.generate_expression(&op.right)?;
29958 } else {
29959 self.generate_expression(expr)?;
29960 }
29961 }
29962 }
29963 if is_duckdb {
29964 self.write("}");
29965 } else {
29966 self.write("]");
29967 }
29968 Ok(())
29969 }
29970
29971 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
29972 self.write_keyword("LOCALTIME");
29974 if let Some(precision) = &e.this {
29975 self.write("(");
29976 self.generate_expression(precision)?;
29977 self.write(")");
29978 }
29979 Ok(())
29980 }
29981
29982 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
29983 self.write_keyword("LOCALTIMESTAMP");
29985 if let Some(precision) = &e.this {
29986 self.write("(");
29987 self.generate_expression(precision)?;
29988 self.write(")");
29989 }
29990 Ok(())
29991 }
29992
29993 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
29994 self.write_keyword("LOCATION");
29996 self.write_space();
29997 self.generate_expression(&e.this)?;
29998 Ok(())
29999 }
30000
30001 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
30002 if e.update.is_some() {
30004 if e.key.is_some() {
30005 self.write_keyword("FOR NO KEY UPDATE");
30006 } else {
30007 self.write_keyword("FOR UPDATE");
30008 }
30009 } else {
30010 if e.key.is_some() {
30011 self.write_keyword("FOR KEY SHARE");
30012 } else {
30013 self.write_keyword("FOR SHARE");
30014 }
30015 }
30016 if !e.expressions.is_empty() {
30017 self.write_keyword(" OF ");
30018 for (i, expr) in e.expressions.iter().enumerate() {
30019 if i > 0 {
30020 self.write(", ");
30021 }
30022 self.generate_expression(expr)?;
30023 }
30024 }
30025 if let Some(wait) = &e.wait {
30030 match wait.as_ref() {
30031 Expression::Boolean(b) => {
30032 if b.value {
30033 self.write_keyword(" NOWAIT");
30034 } else {
30035 self.write_keyword(" SKIP LOCKED");
30036 }
30037 }
30038 _ => {
30039 self.write_keyword(" WAIT ");
30041 self.generate_expression(wait)?;
30042 }
30043 }
30044 }
30045 Ok(())
30046 }
30047
30048 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
30049 self.write_keyword("LOCK");
30051 self.write_space();
30052 self.generate_expression(&e.this)?;
30053 Ok(())
30054 }
30055
30056 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
30057 self.write_keyword("LOCKING");
30059 self.write_space();
30060 self.write(&e.kind);
30061 if let Some(this) = &e.this {
30062 self.write_space();
30063 self.generate_expression(this)?;
30064 }
30065 if let Some(for_or_in) = &e.for_or_in {
30066 self.write_space();
30067 self.generate_expression(for_or_in)?;
30068 }
30069 if let Some(lock_type) = &e.lock_type {
30070 self.write_space();
30071 self.generate_expression(lock_type)?;
30072 }
30073 if e.override_.is_some() {
30074 self.write_keyword(" OVERRIDE");
30075 }
30076 Ok(())
30077 }
30078
30079 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
30080 self.generate_expression(&e.this)?;
30082 self.write_space();
30083 self.generate_expression(&e.expression)?;
30084 Ok(())
30085 }
30086
30087 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
30088 if e.no.is_some() {
30090 self.write_keyword("NO ");
30091 }
30092 self.write_keyword("LOG");
30093 Ok(())
30094 }
30095
30096 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
30097 self.write_keyword("MD5");
30099 self.write("(");
30100 self.generate_expression(&e.this)?;
30101 for expr in &e.expressions {
30102 self.write(", ");
30103 self.generate_expression(expr)?;
30104 }
30105 self.write(")");
30106 Ok(())
30107 }
30108
30109 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
30110 self.write_keyword("ML.FORECAST");
30112 self.write("(");
30113 self.generate_expression(&e.this)?;
30114 if let Some(expression) = &e.expression {
30115 self.write(", ");
30116 self.generate_expression(expression)?;
30117 }
30118 if let Some(params) = &e.params_struct {
30119 self.write(", ");
30120 self.generate_expression(params)?;
30121 }
30122 self.write(")");
30123 Ok(())
30124 }
30125
30126 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
30127 self.write_keyword("ML.TRANSLATE");
30129 self.write("(");
30130 self.generate_expression(&e.this)?;
30131 self.write(", ");
30132 self.generate_expression(&e.expression)?;
30133 if let Some(params) = &e.params_struct {
30134 self.write(", ");
30135 self.generate_expression(params)?;
30136 }
30137 self.write(")");
30138 Ok(())
30139 }
30140
30141 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
30142 self.write_keyword("MAKE_INTERVAL");
30144 self.write("(");
30145 let mut first = true;
30146 if let Some(year) = &e.year {
30147 self.write("years => ");
30148 self.generate_expression(year)?;
30149 first = false;
30150 }
30151 if let Some(month) = &e.month {
30152 if !first {
30153 self.write(", ");
30154 }
30155 self.write("months => ");
30156 self.generate_expression(month)?;
30157 first = false;
30158 }
30159 if let Some(week) = &e.week {
30160 if !first {
30161 self.write(", ");
30162 }
30163 self.write("weeks => ");
30164 self.generate_expression(week)?;
30165 first = false;
30166 }
30167 if let Some(day) = &e.day {
30168 if !first {
30169 self.write(", ");
30170 }
30171 self.write("days => ");
30172 self.generate_expression(day)?;
30173 first = false;
30174 }
30175 if let Some(hour) = &e.hour {
30176 if !first {
30177 self.write(", ");
30178 }
30179 self.write("hours => ");
30180 self.generate_expression(hour)?;
30181 first = false;
30182 }
30183 if let Some(minute) = &e.minute {
30184 if !first {
30185 self.write(", ");
30186 }
30187 self.write("mins => ");
30188 self.generate_expression(minute)?;
30189 first = false;
30190 }
30191 if let Some(second) = &e.second {
30192 if !first {
30193 self.write(", ");
30194 }
30195 self.write("secs => ");
30196 self.generate_expression(second)?;
30197 }
30198 self.write(")");
30199 Ok(())
30200 }
30201
30202 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
30203 self.write_keyword("MANHATTAN_DISTANCE");
30205 self.write("(");
30206 self.generate_expression(&e.this)?;
30207 self.write(", ");
30208 self.generate_expression(&e.expression)?;
30209 self.write(")");
30210 Ok(())
30211 }
30212
30213 fn generate_map(&mut self, e: &Map) -> Result<()> {
30214 self.write_keyword("MAP");
30216 self.write("(");
30217 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
30218 if i > 0 {
30219 self.write(", ");
30220 }
30221 self.generate_expression(key)?;
30222 self.write(", ");
30223 self.generate_expression(value)?;
30224 }
30225 self.write(")");
30226 Ok(())
30227 }
30228
30229 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
30230 self.write_keyword("MAP_CAT");
30232 self.write("(");
30233 self.generate_expression(&e.this)?;
30234 self.write(", ");
30235 self.generate_expression(&e.expression)?;
30236 self.write(")");
30237 Ok(())
30238 }
30239
30240 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
30241 self.write_keyword("MAP_DELETE");
30243 self.write("(");
30244 self.generate_expression(&e.this)?;
30245 for expr in &e.expressions {
30246 self.write(", ");
30247 self.generate_expression(expr)?;
30248 }
30249 self.write(")");
30250 Ok(())
30251 }
30252
30253 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
30254 self.write_keyword("MAP_INSERT");
30256 self.write("(");
30257 self.generate_expression(&e.this)?;
30258 if let Some(key) = &e.key {
30259 self.write(", ");
30260 self.generate_expression(key)?;
30261 }
30262 if let Some(value) = &e.value {
30263 self.write(", ");
30264 self.generate_expression(value)?;
30265 }
30266 if let Some(update_flag) = &e.update_flag {
30267 self.write(", ");
30268 self.generate_expression(update_flag)?;
30269 }
30270 self.write(")");
30271 Ok(())
30272 }
30273
30274 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
30275 self.write_keyword("MAP_PICK");
30277 self.write("(");
30278 self.generate_expression(&e.this)?;
30279 for expr in &e.expressions {
30280 self.write(", ");
30281 self.generate_expression(expr)?;
30282 }
30283 self.write(")");
30284 Ok(())
30285 }
30286
30287 fn generate_masking_policy_column_constraint(
30288 &mut self,
30289 e: &MaskingPolicyColumnConstraint,
30290 ) -> Result<()> {
30291 self.write_keyword("MASKING POLICY");
30293 self.write_space();
30294 self.generate_expression(&e.this)?;
30295 if !e.expressions.is_empty() {
30296 self.write_keyword(" USING");
30297 self.write(" (");
30298 for (i, expr) in e.expressions.iter().enumerate() {
30299 if i > 0 {
30300 self.write(", ");
30301 }
30302 self.generate_expression(expr)?;
30303 }
30304 self.write(")");
30305 }
30306 Ok(())
30307 }
30308
30309 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
30310 if matches!(
30311 self.config.dialect,
30312 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
30313 ) {
30314 if e.expressions.len() > 1 {
30315 self.write("(");
30316 }
30317 for (i, expr) in e.expressions.iter().enumerate() {
30318 if i > 0 {
30319 self.write_keyword(" OR ");
30320 }
30321 self.generate_expression(expr)?;
30322 self.write_space();
30323 self.write("@@");
30324 self.write_space();
30325 self.generate_expression(&e.this)?;
30326 }
30327 if e.expressions.len() > 1 {
30328 self.write(")");
30329 }
30330 return Ok(());
30331 }
30332
30333 self.write_keyword("MATCH");
30335 self.write("(");
30336 for (i, expr) in e.expressions.iter().enumerate() {
30337 if i > 0 {
30338 self.write(", ");
30339 }
30340 self.generate_expression(expr)?;
30341 }
30342 self.write(")");
30343 self.write_keyword(" AGAINST");
30344 self.write("(");
30345 self.generate_expression(&e.this)?;
30346 if let Some(modifier) = &e.modifier {
30347 self.write_space();
30348 self.generate_expression(modifier)?;
30349 }
30350 self.write(")");
30351 Ok(())
30352 }
30353
30354 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
30355 if let Some(window_frame) = &e.window_frame {
30357 self.write(&format!("{:?}", window_frame).to_ascii_uppercase());
30358 self.write_space();
30359 }
30360 self.generate_expression(&e.this)?;
30361 Ok(())
30362 }
30363
30364 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
30365 self.write_keyword("MATERIALIZED");
30367 if let Some(this) = &e.this {
30368 self.write_space();
30369 self.generate_expression(this)?;
30370 }
30371 Ok(())
30372 }
30373
30374 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
30375 if let Some(with_) = &e.with_ {
30378 self.generate_expression(with_)?;
30379 self.write_space();
30380 }
30381 self.write_keyword("MERGE INTO");
30382 self.write_space();
30383 self.generate_expression(&e.this)?;
30384
30385 if self.config.pretty {
30387 self.write_newline();
30388 self.write_indent();
30389 } else {
30390 self.write_space();
30391 }
30392 self.write_keyword("USING");
30393 self.write_space();
30394 self.generate_expression(&e.using)?;
30395
30396 if let Some(on) = &e.on {
30398 if self.config.pretty {
30399 self.write_newline();
30400 self.write_indent();
30401 } else {
30402 self.write_space();
30403 }
30404 self.write_keyword("ON");
30405 self.write_space();
30406 self.generate_expression(on)?;
30407 }
30408 if let Some(using_cond) = &e.using_cond {
30410 self.write_space();
30411 self.write_keyword("USING");
30412 self.write_space();
30413 self.write("(");
30414 if let Expression::Tuple(tuple) = using_cond.as_ref() {
30416 for (i, col) in tuple.expressions.iter().enumerate() {
30417 if i > 0 {
30418 self.write(", ");
30419 }
30420 self.generate_expression(col)?;
30421 }
30422 } else {
30423 self.generate_expression(using_cond)?;
30424 }
30425 self.write(")");
30426 }
30427 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
30429 if matches!(
30430 self.config.dialect,
30431 Some(crate::DialectType::PostgreSQL)
30432 | Some(crate::DialectType::Redshift)
30433 | Some(crate::DialectType::Trino)
30434 | Some(crate::DialectType::Presto)
30435 | Some(crate::DialectType::Athena)
30436 ) {
30437 let mut names = Vec::new();
30438 match e.this.as_ref() {
30439 Expression::Alias(a) => {
30440 if let Expression::Table(t) = &a.this {
30442 names.push(t.name.name.clone());
30443 } else if let Expression::Identifier(id) = &a.this {
30444 names.push(id.name.clone());
30445 }
30446 names.push(a.alias.name.clone());
30447 }
30448 Expression::Table(t) => {
30449 names.push(t.name.name.clone());
30450 }
30451 Expression::Identifier(id) => {
30452 names.push(id.name.clone());
30453 }
30454 _ => {}
30455 }
30456 self.merge_strip_qualifiers = names;
30457 }
30458
30459 if let Some(whens) = &e.whens {
30461 if self.config.pretty {
30462 self.write_newline();
30463 self.write_indent();
30464 } else {
30465 self.write_space();
30466 }
30467 self.generate_expression(whens)?;
30468 }
30469
30470 self.merge_strip_qualifiers = saved_merge_strip;
30472
30473 if let Some(returning) = &e.returning {
30475 if self.config.pretty {
30476 self.write_newline();
30477 self.write_indent();
30478 } else {
30479 self.write_space();
30480 }
30481 self.generate_expression(returning)?;
30482 }
30483 Ok(())
30484 }
30485
30486 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
30487 if e.no.is_some() {
30489 self.write_keyword("NO MERGEBLOCKRATIO");
30490 } else if e.default.is_some() {
30491 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
30492 } else {
30493 self.write_keyword("MERGEBLOCKRATIO");
30494 self.write("=");
30495 if let Some(this) = &e.this {
30496 self.generate_expression(this)?;
30497 }
30498 if e.percent.is_some() {
30499 self.write_keyword(" PERCENT");
30500 }
30501 }
30502 Ok(())
30503 }
30504
30505 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
30506 self.write_keyword("TTL");
30508 let pretty_clickhouse = self.config.pretty
30509 && matches!(
30510 self.config.dialect,
30511 Some(crate::dialects::DialectType::ClickHouse)
30512 );
30513
30514 if pretty_clickhouse {
30515 self.write_newline();
30516 self.indent_level += 1;
30517 for (i, expr) in e.expressions.iter().enumerate() {
30518 if i > 0 {
30519 self.write(",");
30520 self.write_newline();
30521 }
30522 self.write_indent();
30523 self.generate_expression(expr)?;
30524 }
30525 self.indent_level -= 1;
30526 } else {
30527 self.write_space();
30528 for (i, expr) in e.expressions.iter().enumerate() {
30529 if i > 0 {
30530 self.write(", ");
30531 }
30532 self.generate_expression(expr)?;
30533 }
30534 }
30535
30536 if let Some(where_) = &e.where_ {
30537 if pretty_clickhouse {
30538 self.write_newline();
30539 if let Expression::Where(w) = where_.as_ref() {
30540 self.write_indent();
30541 self.write_keyword("WHERE");
30542 self.write_newline();
30543 self.indent_level += 1;
30544 self.write_indent();
30545 self.generate_expression(&w.this)?;
30546 self.indent_level -= 1;
30547 } else {
30548 self.write_indent();
30549 self.generate_expression(where_)?;
30550 }
30551 } else {
30552 self.write_space();
30553 self.generate_expression(where_)?;
30554 }
30555 }
30556 if let Some(group) = &e.group {
30557 if pretty_clickhouse {
30558 self.write_newline();
30559 if let Expression::Group(g) = group.as_ref() {
30560 self.write_indent();
30561 self.write_keyword("GROUP BY");
30562 self.write_newline();
30563 self.indent_level += 1;
30564 for (i, expr) in g.expressions.iter().enumerate() {
30565 if i > 0 {
30566 self.write(",");
30567 self.write_newline();
30568 }
30569 self.write_indent();
30570 self.generate_expression(expr)?;
30571 }
30572 self.indent_level -= 1;
30573 } else {
30574 self.write_indent();
30575 self.generate_expression(group)?;
30576 }
30577 } else {
30578 self.write_space();
30579 self.generate_expression(group)?;
30580 }
30581 }
30582 if let Some(aggregates) = &e.aggregates {
30583 if pretty_clickhouse {
30584 self.write_newline();
30585 self.write_indent();
30586 self.write_keyword("SET");
30587 self.write_newline();
30588 self.indent_level += 1;
30589 if let Expression::Tuple(t) = aggregates.as_ref() {
30590 for (i, agg) in t.expressions.iter().enumerate() {
30591 if i > 0 {
30592 self.write(",");
30593 self.write_newline();
30594 }
30595 self.write_indent();
30596 self.generate_expression(agg)?;
30597 }
30598 } else {
30599 self.write_indent();
30600 self.generate_expression(aggregates)?;
30601 }
30602 self.indent_level -= 1;
30603 } else {
30604 self.write_space();
30605 self.write_keyword("SET");
30606 self.write_space();
30607 self.generate_expression(aggregates)?;
30608 }
30609 }
30610 Ok(())
30611 }
30612
30613 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
30614 self.generate_expression(&e.this)?;
30616 if e.delete.is_some() {
30617 self.write_keyword(" DELETE");
30618 }
30619 if let Some(recompress) = &e.recompress {
30620 self.write_keyword(" RECOMPRESS ");
30621 self.generate_expression(recompress)?;
30622 }
30623 if let Some(to_disk) = &e.to_disk {
30624 self.write_keyword(" TO DISK ");
30625 self.generate_expression(to_disk)?;
30626 }
30627 if let Some(to_volume) = &e.to_volume {
30628 self.write_keyword(" TO VOLUME ");
30629 self.generate_expression(to_volume)?;
30630 }
30631 Ok(())
30632 }
30633
30634 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
30635 self.write_keyword("MINHASH");
30637 self.write("(");
30638 self.generate_expression(&e.this)?;
30639 for expr in &e.expressions {
30640 self.write(", ");
30641 self.generate_expression(expr)?;
30642 }
30643 self.write(")");
30644 Ok(())
30645 }
30646
30647 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
30648 self.generate_expression(&e.this)?;
30650 self.write("!");
30651 self.generate_expression(&e.expression)?;
30652 Ok(())
30653 }
30654
30655 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
30656 self.write_keyword("MONTHNAME");
30658 self.write("(");
30659 self.generate_expression(&e.this)?;
30660 self.write(")");
30661 Ok(())
30662 }
30663
30664 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
30665 for comment in &e.leading_comments {
30667 self.write_formatted_comment(comment);
30668 if self.config.pretty {
30669 self.write_newline();
30670 self.write_indent();
30671 } else {
30672 self.write_space();
30673 }
30674 }
30675 self.write_keyword("INSERT");
30677 self.write_space();
30678 self.write(&e.kind);
30679 if self.config.pretty {
30680 self.indent_level += 1;
30681 for expr in &e.expressions {
30682 self.write_newline();
30683 self.write_indent();
30684 self.generate_expression(expr)?;
30685 }
30686 self.indent_level -= 1;
30687 } else {
30688 for expr in &e.expressions {
30689 self.write_space();
30690 self.generate_expression(expr)?;
30691 }
30692 }
30693 if let Some(source) = &e.source {
30694 if self.config.pretty {
30695 self.write_newline();
30696 self.write_indent();
30697 } else {
30698 self.write_space();
30699 }
30700 self.generate_expression(source)?;
30701 }
30702 Ok(())
30703 }
30704
30705 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
30706 self.write_keyword("NEXT VALUE FOR");
30708 self.write_space();
30709 self.generate_expression(&e.this)?;
30710 if let Some(order) = &e.order {
30711 self.write_space();
30712 self.write_keyword("OVER");
30713 self.write(" (");
30714 self.generate_expression(order)?;
30715 self.write(")");
30716 }
30717 Ok(())
30718 }
30719
30720 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
30721 self.write_keyword("NORMAL");
30723 self.write("(");
30724 self.generate_expression(&e.this)?;
30725 if let Some(stddev) = &e.stddev {
30726 self.write(", ");
30727 self.generate_expression(stddev)?;
30728 }
30729 if let Some(gen) = &e.gen {
30730 self.write(", ");
30731 self.generate_expression(gen)?;
30732 }
30733 self.write(")");
30734 Ok(())
30735 }
30736
30737 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
30738 if e.is_casefold.is_some() {
30740 self.write_keyword("NORMALIZE_AND_CASEFOLD");
30741 } else {
30742 self.write_keyword("NORMALIZE");
30743 }
30744 self.write("(");
30745 self.generate_expression(&e.this)?;
30746 if let Some(form) = &e.form {
30747 self.write(", ");
30748 self.generate_expression(form)?;
30749 }
30750 self.write(")");
30751 Ok(())
30752 }
30753
30754 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
30755 if e.allow_null.is_none() {
30757 self.write_keyword("NOT ");
30758 }
30759 self.write_keyword("NULL");
30760 Ok(())
30761 }
30762
30763 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
30764 self.write_keyword("NULLIF");
30766 self.write("(");
30767 self.generate_expression(&e.this)?;
30768 self.write(", ");
30769 self.generate_expression(&e.expression)?;
30770 self.write(")");
30771 Ok(())
30772 }
30773
30774 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
30775 self.write_keyword("FORMAT");
30777 self.write("(");
30778 self.generate_expression(&e.this)?;
30779 self.write(", '");
30780 self.write(&e.format);
30781 self.write("'");
30782 if let Some(culture) = &e.culture {
30783 self.write(", ");
30784 self.generate_expression(culture)?;
30785 }
30786 self.write(")");
30787 Ok(())
30788 }
30789
30790 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
30791 self.write_keyword("OBJECT_AGG");
30793 self.write("(");
30794 self.generate_expression(&e.this)?;
30795 self.write(", ");
30796 self.generate_expression(&e.expression)?;
30797 self.write(")");
30798 Ok(())
30799 }
30800
30801 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
30802 self.generate_expression(&e.this)?;
30804 Ok(())
30805 }
30806
30807 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
30808 self.write_keyword("OBJECT_INSERT");
30810 self.write("(");
30811 self.generate_expression(&e.this)?;
30812 if let Some(key) = &e.key {
30813 self.write(", ");
30814 self.generate_expression(key)?;
30815 }
30816 if let Some(value) = &e.value {
30817 self.write(", ");
30818 self.generate_expression(value)?;
30819 }
30820 if let Some(update_flag) = &e.update_flag {
30821 self.write(", ");
30822 self.generate_expression(update_flag)?;
30823 }
30824 self.write(")");
30825 Ok(())
30826 }
30827
30828 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
30829 self.write_keyword("OFFSET");
30831 self.write_space();
30832 self.generate_expression(&e.this)?;
30833 if e.rows == Some(true)
30835 && matches!(
30836 self.config.dialect,
30837 Some(crate::dialects::DialectType::TSQL)
30838 | Some(crate::dialects::DialectType::Oracle)
30839 )
30840 {
30841 self.write_space();
30842 self.write_keyword("ROWS");
30843 }
30844 Ok(())
30845 }
30846
30847 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
30848 self.write_keyword("QUALIFY");
30850 self.write_space();
30851 self.generate_expression(&e.this)?;
30852 Ok(())
30853 }
30854
30855 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
30856 self.write_keyword("ON CLUSTER");
30858 self.write_space();
30859 self.generate_expression(&e.this)?;
30860 Ok(())
30861 }
30862
30863 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
30864 self.write_keyword("ON COMMIT");
30866 if e.delete.is_some() {
30867 self.write_keyword(" DELETE ROWS");
30868 } else {
30869 self.write_keyword(" PRESERVE ROWS");
30870 }
30871 Ok(())
30872 }
30873
30874 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
30875 if let Some(empty) = &e.empty {
30877 self.generate_expression(empty)?;
30878 self.write_keyword(" ON EMPTY");
30879 }
30880 if let Some(error) = &e.error {
30881 if e.empty.is_some() {
30882 self.write_space();
30883 }
30884 self.generate_expression(error)?;
30885 self.write_keyword(" ON ERROR");
30886 }
30887 if let Some(null) = &e.null {
30888 if e.empty.is_some() || e.error.is_some() {
30889 self.write_space();
30890 }
30891 self.generate_expression(null)?;
30892 self.write_keyword(" ON NULL");
30893 }
30894 Ok(())
30895 }
30896
30897 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
30898 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
30900 return Ok(());
30901 }
30902 if e.duplicate.is_some() {
30904 self.write_keyword("ON DUPLICATE KEY UPDATE");
30906 for (i, expr) in e.expressions.iter().enumerate() {
30907 if i > 0 {
30908 self.write(",");
30909 }
30910 self.write_space();
30911 self.generate_expression(expr)?;
30912 }
30913 return Ok(());
30914 } else {
30915 self.write_keyword("ON CONFLICT");
30916 }
30917 if let Some(constraint) = &e.constraint {
30918 self.write_keyword(" ON CONSTRAINT ");
30919 self.generate_expression(constraint)?;
30920 }
30921 if let Some(conflict_keys) = &e.conflict_keys {
30922 if let Expression::Tuple(t) = conflict_keys.as_ref() {
30924 self.write("(");
30925 for (i, expr) in t.expressions.iter().enumerate() {
30926 if i > 0 {
30927 self.write(", ");
30928 }
30929 self.generate_expression(expr)?;
30930 }
30931 self.write(")");
30932 } else {
30933 self.write("(");
30934 self.generate_expression(conflict_keys)?;
30935 self.write(")");
30936 }
30937 }
30938 if let Some(index_predicate) = &e.index_predicate {
30939 self.write_keyword(" WHERE ");
30940 self.generate_expression(index_predicate)?;
30941 }
30942 if let Some(action) = &e.action {
30943 if let Expression::Identifier(id) = action.as_ref() {
30945 if id.name.eq_ignore_ascii_case("NOTHING") {
30946 self.write_keyword(" DO NOTHING");
30947 } else {
30948 self.write_keyword(" DO ");
30949 self.generate_expression(action)?;
30950 }
30951 } else if let Expression::Tuple(t) = action.as_ref() {
30952 self.write_keyword(" DO UPDATE SET ");
30954 for (i, expr) in t.expressions.iter().enumerate() {
30955 if i > 0 {
30956 self.write(", ");
30957 }
30958 self.generate_expression(expr)?;
30959 }
30960 } else {
30961 self.write_keyword(" DO ");
30962 self.generate_expression(action)?;
30963 }
30964 }
30965 if let Some(where_) = &e.where_ {
30967 self.write_keyword(" WHERE ");
30968 self.generate_expression(where_)?;
30969 }
30970 Ok(())
30971 }
30972
30973 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
30974 self.write_keyword("ON");
30976 self.write_space();
30977 self.generate_expression(&e.this)?;
30978 Ok(())
30979 }
30980
30981 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
30982 self.generate_expression(&e.this)?;
30984 self.write_space();
30985 self.generate_expression(&e.expression)?;
30986 Ok(())
30987 }
30988
30989 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
30990 self.write_keyword("OPENJSON");
30992 self.write("(");
30993 self.generate_expression(&e.this)?;
30994 if let Some(path) = &e.path {
30995 self.write(", ");
30996 self.generate_expression(path)?;
30997 }
30998 self.write(")");
30999 if !e.expressions.is_empty() {
31000 self.write_keyword(" WITH");
31001 if self.config.pretty {
31002 self.write(" (\n");
31003 self.indent_level += 2;
31004 for (i, expr) in e.expressions.iter().enumerate() {
31005 if i > 0 {
31006 self.write(",\n");
31007 }
31008 self.write_indent();
31009 self.generate_expression(expr)?;
31010 }
31011 self.write("\n");
31012 self.indent_level -= 2;
31013 self.write(")");
31014 } else {
31015 self.write(" (");
31016 for (i, expr) in e.expressions.iter().enumerate() {
31017 if i > 0 {
31018 self.write(", ");
31019 }
31020 self.generate_expression(expr)?;
31021 }
31022 self.write(")");
31023 }
31024 }
31025 Ok(())
31026 }
31027
31028 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
31029 self.generate_expression(&e.this)?;
31031 self.write_space();
31032 if let Some(ref dt) = e.data_type {
31034 self.generate_data_type(dt)?;
31035 } else if !e.kind.is_empty() {
31036 self.write(&e.kind);
31037 }
31038 if let Some(path) = &e.path {
31039 self.write_space();
31040 self.generate_expression(path)?;
31041 }
31042 if e.as_json.is_some() {
31043 self.write_keyword(" AS JSON");
31044 }
31045 Ok(())
31046 }
31047
31048 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
31049 self.generate_expression(&e.this)?;
31051 self.write_space();
31052 if let Some(op) = &e.operator {
31053 self.write_keyword("OPERATOR");
31054 self.write("(");
31055 self.generate_expression(op)?;
31056 self.write(")");
31057 }
31058 for comment in &e.comments {
31060 self.write_space();
31061 self.write_formatted_comment(comment);
31062 }
31063 self.write_space();
31064 self.generate_expression(&e.expression)?;
31065 Ok(())
31066 }
31067
31068 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
31069 self.write_keyword("ORDER BY");
31071 let pretty_clickhouse_single_paren = self.config.pretty
31072 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
31073 && e.expressions.len() == 1
31074 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
31075 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
31076 && e.expressions.len() == 1
31077 && matches!(e.expressions[0].this, Expression::Tuple(_))
31078 && !e.expressions[0].desc
31079 && e.expressions[0].nulls_first.is_none();
31080
31081 if pretty_clickhouse_single_paren {
31082 self.write_space();
31083 if let Expression::Paren(p) = &e.expressions[0].this {
31084 self.write("(");
31085 self.write_newline();
31086 self.indent_level += 1;
31087 self.write_indent();
31088 self.generate_expression(&p.this)?;
31089 self.indent_level -= 1;
31090 self.write_newline();
31091 self.write(")");
31092 }
31093 return Ok(());
31094 }
31095
31096 if clickhouse_single_tuple {
31097 self.write_space();
31098 if let Expression::Tuple(t) = &e.expressions[0].this {
31099 self.write("(");
31100 for (i, expr) in t.expressions.iter().enumerate() {
31101 if i > 0 {
31102 self.write(", ");
31103 }
31104 self.generate_expression(expr)?;
31105 }
31106 self.write(")");
31107 }
31108 return Ok(());
31109 }
31110
31111 self.write_space();
31112 for (i, ordered) in e.expressions.iter().enumerate() {
31113 if i > 0 {
31114 self.write(", ");
31115 }
31116 self.generate_expression(&ordered.this)?;
31117 if ordered.desc {
31118 self.write_space();
31119 self.write_keyword("DESC");
31120 } else if ordered.explicit_asc {
31121 self.write_space();
31122 self.write_keyword("ASC");
31123 }
31124 if let Some(nulls_first) = ordered.nulls_first {
31125 let skip_nulls_last =
31127 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
31128 if !skip_nulls_last {
31129 self.write_space();
31130 self.write_keyword("NULLS");
31131 self.write_space();
31132 if nulls_first {
31133 self.write_keyword("FIRST");
31134 } else {
31135 self.write_keyword("LAST");
31136 }
31137 }
31138 }
31139 }
31140 Ok(())
31141 }
31142
31143 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
31144 self.write_keyword("OUTPUT");
31146 self.write("(");
31147 if self.config.pretty {
31148 self.indent_level += 1;
31149 self.write_newline();
31150 self.write_indent();
31151 self.generate_expression(&e.this)?;
31152 self.indent_level -= 1;
31153 self.write_newline();
31154 } else {
31155 self.generate_expression(&e.this)?;
31156 }
31157 self.write(")");
31158 Ok(())
31159 }
31160
31161 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
31162 self.write_keyword("TRUNCATE");
31164 if let Some(this) = &e.this {
31165 self.write_space();
31166 self.generate_expression(this)?;
31167 }
31168 if e.with_count.is_some() {
31169 self.write_keyword(" WITH COUNT");
31170 } else {
31171 self.write_keyword(" WITHOUT COUNT");
31172 }
31173 Ok(())
31174 }
31175
31176 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
31177 self.generate_expression(&e.this)?;
31179 self.write("(");
31180 for (i, expr) in e.expressions.iter().enumerate() {
31181 if i > 0 {
31182 self.write(", ");
31183 }
31184 self.generate_expression(expr)?;
31185 }
31186 self.write(")(");
31187 for (i, param) in e.params.iter().enumerate() {
31188 if i > 0 {
31189 self.write(", ");
31190 }
31191 self.generate_expression(param)?;
31192 }
31193 self.write(")");
31194 Ok(())
31195 }
31196
31197 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
31198 self.write_keyword("PARSE_DATETIME");
31200 self.write("(");
31201 if let Some(format) = &e.format {
31202 self.write("'");
31203 self.write(format);
31204 self.write("', ");
31205 }
31206 self.generate_expression(&e.this)?;
31207 if let Some(zone) = &e.zone {
31208 self.write(", ");
31209 self.generate_expression(zone)?;
31210 }
31211 self.write(")");
31212 Ok(())
31213 }
31214
31215 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
31216 self.write_keyword("PARSE_IP");
31218 self.write("(");
31219 self.generate_expression(&e.this)?;
31220 if let Some(type_) = &e.type_ {
31221 self.write(", ");
31222 self.generate_expression(type_)?;
31223 }
31224 if let Some(permissive) = &e.permissive {
31225 self.write(", ");
31226 self.generate_expression(permissive)?;
31227 }
31228 self.write(")");
31229 Ok(())
31230 }
31231
31232 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
31233 self.write_keyword("PARSE_JSON");
31235 self.write("(");
31236 self.generate_expression(&e.this)?;
31237 if let Some(expression) = &e.expression {
31238 self.write(", ");
31239 self.generate_expression(expression)?;
31240 }
31241 self.write(")");
31242 Ok(())
31243 }
31244
31245 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
31246 self.write_keyword("PARSE_TIME");
31248 self.write("(");
31249 self.write(&format!("'{}'", e.format));
31250 self.write(", ");
31251 self.generate_expression(&e.this)?;
31252 self.write(")");
31253 Ok(())
31254 }
31255
31256 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
31257 self.write_keyword("PARSE_URL");
31259 self.write("(");
31260 self.generate_expression(&e.this)?;
31261 if let Some(part) = &e.part_to_extract {
31262 self.write(", ");
31263 self.generate_expression(part)?;
31264 }
31265 if let Some(key) = &e.key {
31266 self.write(", ");
31267 self.generate_expression(key)?;
31268 }
31269 if let Some(permissive) = &e.permissive {
31270 self.write(", ");
31271 self.generate_expression(permissive)?;
31272 }
31273 self.write(")");
31274 Ok(())
31275 }
31276
31277 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
31278 if e.subpartition {
31280 self.write_keyword("SUBPARTITION");
31281 } else {
31282 self.write_keyword("PARTITION");
31283 }
31284 self.write("(");
31285 for (i, expr) in e.expressions.iter().enumerate() {
31286 if i > 0 {
31287 self.write(", ");
31288 }
31289 self.generate_expression(expr)?;
31290 }
31291 self.write(")");
31292 Ok(())
31293 }
31294
31295 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
31296 if let Some(this) = &e.this {
31298 if let Some(expression) = &e.expression {
31299 self.write_keyword("WITH");
31301 self.write(" (");
31302 self.write_keyword("MODULUS");
31303 self.write_space();
31304 self.generate_expression(this)?;
31305 self.write(", ");
31306 self.write_keyword("REMAINDER");
31307 self.write_space();
31308 self.generate_expression(expression)?;
31309 self.write(")");
31310 } else {
31311 self.write_keyword("IN");
31313 self.write(" (");
31314 self.generate_partition_bound_values(this)?;
31315 self.write(")");
31316 }
31317 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
31318 self.write_keyword("FROM");
31320 self.write(" (");
31321 self.generate_partition_bound_values(from)?;
31322 self.write(") ");
31323 self.write_keyword("TO");
31324 self.write(" (");
31325 self.generate_partition_bound_values(to)?;
31326 self.write(")");
31327 }
31328 Ok(())
31329 }
31330
31331 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
31334 if let Expression::Tuple(t) = expr {
31335 for (i, e) in t.expressions.iter().enumerate() {
31336 if i > 0 {
31337 self.write(", ");
31338 }
31339 self.generate_expression(e)?;
31340 }
31341 Ok(())
31342 } else {
31343 self.generate_expression(expr)
31344 }
31345 }
31346
31347 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
31348 self.write_keyword("PARTITION BY LIST");
31350 if let Some(partition_exprs) = &e.partition_expressions {
31351 self.write(" (");
31352 self.generate_doris_partition_expressions(partition_exprs)?;
31354 self.write(")");
31355 }
31356 if let Some(create_exprs) = &e.create_expressions {
31357 self.write(" (");
31358 self.generate_doris_partition_definitions(create_exprs)?;
31360 self.write(")");
31361 }
31362 Ok(())
31363 }
31364
31365 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
31366 self.write_keyword("PARTITION BY RANGE");
31368 if let Some(partition_exprs) = &e.partition_expressions {
31369 self.write(" (");
31370 self.generate_doris_partition_expressions(partition_exprs)?;
31372 self.write(")");
31373 }
31374 if let Some(create_exprs) = &e.create_expressions {
31375 self.write(" (");
31376 self.generate_doris_partition_definitions(create_exprs)?;
31378 self.write(")");
31379 }
31380 Ok(())
31381 }
31382
31383 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
31385 if let Expression::Tuple(t) = expr {
31386 for (i, e) in t.expressions.iter().enumerate() {
31387 if i > 0 {
31388 self.write(", ");
31389 }
31390 self.generate_expression(e)?;
31391 }
31392 } else {
31393 self.generate_expression(expr)?;
31394 }
31395 Ok(())
31396 }
31397
31398 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
31400 match expr {
31401 Expression::Tuple(t) => {
31402 for (i, part) in t.expressions.iter().enumerate() {
31404 if i > 0 {
31405 self.write(", ");
31406 }
31407 if let Expression::Partition(p) = part {
31409 for (j, inner) in p.expressions.iter().enumerate() {
31410 if j > 0 {
31411 self.write(", ");
31412 }
31413 self.generate_expression(inner)?;
31414 }
31415 } else {
31416 self.generate_expression(part)?;
31417 }
31418 }
31419 }
31420 Expression::PartitionByRangePropertyDynamic(_) => {
31421 self.generate_expression(expr)?;
31423 }
31424 _ => {
31425 self.generate_expression(expr)?;
31426 }
31427 }
31428 Ok(())
31429 }
31430
31431 fn generate_partition_by_range_property_dynamic(
31432 &mut self,
31433 e: &PartitionByRangePropertyDynamic,
31434 ) -> Result<()> {
31435 if e.use_start_end {
31436 if let Some(start) = &e.start {
31438 self.write_keyword("START");
31439 self.write(" (");
31440 self.generate_expression(start)?;
31441 self.write(")");
31442 }
31443 if let Some(end) = &e.end {
31444 self.write_space();
31445 self.write_keyword("END");
31446 self.write(" (");
31447 self.generate_expression(end)?;
31448 self.write(")");
31449 }
31450 if let Some(every) = &e.every {
31451 self.write_space();
31452 self.write_keyword("EVERY");
31453 self.write(" (");
31454 self.generate_doris_interval(every)?;
31456 self.write(")");
31457 }
31458 } else {
31459 if let Some(start) = &e.start {
31461 self.write_keyword("FROM");
31462 self.write(" (");
31463 self.generate_expression(start)?;
31464 self.write(")");
31465 }
31466 if let Some(end) = &e.end {
31467 self.write_space();
31468 self.write_keyword("TO");
31469 self.write(" (");
31470 self.generate_expression(end)?;
31471 self.write(")");
31472 }
31473 if let Some(every) = &e.every {
31474 self.write_space();
31475 self.generate_doris_interval(every)?;
31477 }
31478 }
31479 Ok(())
31480 }
31481
31482 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
31484 if let Expression::Interval(interval) = expr {
31485 self.write_keyword("INTERVAL");
31486 if let Some(ref value) = interval.this {
31487 self.write_space();
31488 match value {
31492 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()) =>
31493 {
31494 if let Literal::String(s) = lit.as_ref() {
31495 self.write(s);
31496 }
31497 }
31498 _ => {
31499 self.generate_expression(value)?;
31500 }
31501 }
31502 }
31503 if let Some(ref unit_spec) = interval.unit {
31504 self.write_space();
31505 self.write_interval_unit_spec(unit_spec)?;
31506 }
31507 Ok(())
31508 } else {
31509 self.generate_expression(expr)
31510 }
31511 }
31512
31513 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
31514 self.write_keyword("TRUNCATE");
31516 self.write("(");
31517 self.generate_expression(&e.expression)?;
31518 self.write(", ");
31519 self.generate_expression(&e.this)?;
31520 self.write(")");
31521 Ok(())
31522 }
31523
31524 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
31525 self.write_keyword("PARTITION");
31527 self.write_space();
31528 self.generate_expression(&e.this)?;
31529 self.write_space();
31530 self.write_keyword("VALUES IN");
31531 self.write(" (");
31532 for (i, expr) in e.expressions.iter().enumerate() {
31533 if i > 0 {
31534 self.write(", ");
31535 }
31536 self.generate_expression(expr)?;
31537 }
31538 self.write(")");
31539 Ok(())
31540 }
31541
31542 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
31543 if e.expressions.is_empty() && e.expression.is_some() {
31546 self.generate_expression(&e.this)?;
31548 self.write_space();
31549 self.write_keyword("TO");
31550 self.write_space();
31551 self.generate_expression(e.expression.as_ref().unwrap())?;
31552 return Ok(());
31553 }
31554
31555 self.write_keyword("PARTITION");
31557 self.write_space();
31558 self.generate_expression(&e.this)?;
31559 self.write_space();
31560
31561 if e.expressions.len() == 1 {
31563 self.write_keyword("VALUES LESS THAN");
31565 self.write(" (");
31566 self.generate_expression(&e.expressions[0])?;
31567 self.write(")");
31568 } else if !e.expressions.is_empty() {
31569 self.write_keyword("VALUES");
31571 self.write(" [");
31572 for (i, expr) in e.expressions.iter().enumerate() {
31573 if i > 0 {
31574 self.write(", ");
31575 }
31576 if let Expression::Tuple(t) = expr {
31578 self.write("(");
31579 for (j, inner) in t.expressions.iter().enumerate() {
31580 if j > 0 {
31581 self.write(", ");
31582 }
31583 self.generate_expression(inner)?;
31584 }
31585 self.write(")");
31586 } else {
31587 self.write("(");
31588 self.generate_expression(expr)?;
31589 self.write(")");
31590 }
31591 }
31592 self.write(")");
31593 }
31594 Ok(())
31595 }
31596
31597 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
31598 self.write_keyword("BUCKET");
31600 self.write("(");
31601 self.generate_expression(&e.this)?;
31602 self.write(", ");
31603 self.generate_expression(&e.expression)?;
31604 self.write(")");
31605 Ok(())
31606 }
31607
31608 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
31609 self.write_keyword("PARTITION BY");
31611 self.write_space();
31612 for (i, expr) in e.expressions.iter().enumerate() {
31613 if i > 0 {
31614 self.write(", ");
31615 }
31616 self.generate_expression(expr)?;
31617 }
31618 Ok(())
31619 }
31620
31621 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
31622 if matches!(
31624 self.config.dialect,
31625 Some(crate::dialects::DialectType::Teradata)
31626 | Some(crate::dialects::DialectType::ClickHouse)
31627 ) {
31628 self.write_keyword("PARTITION BY");
31629 } else {
31630 self.write_keyword("PARTITIONED BY");
31631 }
31632 self.write_space();
31633 if self.config.pretty {
31635 if let Expression::Tuple(ref tuple) = *e.this {
31636 self.write("(");
31637 self.write_newline();
31638 self.indent_level += 1;
31639 for (i, expr) in tuple.expressions.iter().enumerate() {
31640 if i > 0 {
31641 self.write(",");
31642 self.write_newline();
31643 }
31644 self.write_indent();
31645 self.generate_expression(expr)?;
31646 }
31647 self.indent_level -= 1;
31648 self.write_newline();
31649 self.write(")");
31650 } else {
31651 self.generate_expression(&e.this)?;
31652 }
31653 } else {
31654 self.generate_expression(&e.this)?;
31655 }
31656 Ok(())
31657 }
31658
31659 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
31660 self.write_keyword("PARTITION OF");
31662 self.write_space();
31663 self.generate_expression(&e.this)?;
31664 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
31666 self.write_space();
31667 self.write_keyword("FOR VALUES");
31668 self.write_space();
31669 self.generate_expression(&e.expression)?;
31670 } else {
31671 self.write_space();
31672 self.write_keyword("DEFAULT");
31673 }
31674 Ok(())
31675 }
31676
31677 fn generate_period_for_system_time_constraint(
31678 &mut self,
31679 e: &PeriodForSystemTimeConstraint,
31680 ) -> Result<()> {
31681 self.write_keyword("PERIOD FOR SYSTEM_TIME");
31683 self.write(" (");
31684 self.generate_expression(&e.this)?;
31685 self.write(", ");
31686 self.generate_expression(&e.expression)?;
31687 self.write(")");
31688 Ok(())
31689 }
31690
31691 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
31692 self.generate_expression(&e.this)?;
31695 self.write_space();
31696 self.write_keyword("AS");
31697 self.write_space();
31698 if self.config.unpivot_aliases_are_identifiers {
31700 match &e.alias {
31701 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
31702 let Literal::String(s) = lit.as_ref() else { unreachable!() };
31703 self.generate_identifier(&Identifier::new(s.clone()))?;
31705 }
31706 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
31707 let Literal::Number(n) = lit.as_ref() else { unreachable!() };
31708 let mut id = Identifier::new(n.clone());
31710 id.quoted = true;
31711 self.generate_identifier(&id)?;
31712 }
31713 other => {
31714 self.generate_expression(other)?;
31715 }
31716 }
31717 } else {
31718 self.generate_expression(&e.alias)?;
31719 }
31720 Ok(())
31721 }
31722
31723 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
31724 self.write_keyword("ANY");
31726 if let Some(this) = &e.this {
31727 self.write_space();
31728 self.generate_expression(this)?;
31729 }
31730 Ok(())
31731 }
31732
31733 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
31734 self.write_keyword("ML.PREDICT");
31736 self.write("(");
31737 self.write_keyword("MODEL");
31738 self.write_space();
31739 self.generate_expression(&e.this)?;
31740 self.write(", ");
31741 self.generate_expression(&e.expression)?;
31742 if let Some(params) = &e.params_struct {
31743 self.write(", ");
31744 self.generate_expression(params)?;
31745 }
31746 self.write(")");
31747 Ok(())
31748 }
31749
31750 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
31751 self.write_keyword("PREVIOUS_DAY");
31753 self.write("(");
31754 self.generate_expression(&e.this)?;
31755 self.write(", ");
31756 self.generate_expression(&e.expression)?;
31757 self.write(")");
31758 Ok(())
31759 }
31760
31761 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
31762 self.write_keyword("PRIMARY KEY");
31764 if let Some(name) = &e.this {
31765 self.write_space();
31766 self.generate_expression(name)?;
31767 }
31768 if !e.expressions.is_empty() {
31769 self.write(" (");
31770 for (i, expr) in e.expressions.iter().enumerate() {
31771 if i > 0 {
31772 self.write(", ");
31773 }
31774 self.generate_expression(expr)?;
31775 }
31776 self.write(")");
31777 }
31778 if let Some(include) = &e.include {
31779 self.write_space();
31780 self.generate_expression(include)?;
31781 }
31782 if !e.options.is_empty() {
31783 self.write_space();
31784 for (i, opt) in e.options.iter().enumerate() {
31785 if i > 0 {
31786 self.write_space();
31787 }
31788 self.generate_expression(opt)?;
31789 }
31790 }
31791 Ok(())
31792 }
31793
31794 fn generate_primary_key_column_constraint(
31795 &mut self,
31796 _e: &PrimaryKeyColumnConstraint,
31797 ) -> Result<()> {
31798 self.write_keyword("PRIMARY KEY");
31800 Ok(())
31801 }
31802
31803 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
31804 self.write_keyword("PATH");
31806 self.write_space();
31807 self.generate_expression(&e.this)?;
31808 Ok(())
31809 }
31810
31811 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
31812 self.write_keyword("PROJECTION");
31814 self.write_space();
31815 self.generate_expression(&e.this)?;
31816 self.write(" (");
31817 self.generate_expression(&e.expression)?;
31818 self.write(")");
31819 Ok(())
31820 }
31821
31822 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
31823 for (i, prop) in e.expressions.iter().enumerate() {
31825 if i > 0 {
31826 self.write(", ");
31827 }
31828 self.generate_expression(prop)?;
31829 }
31830 Ok(())
31831 }
31832
31833 fn generate_property(&mut self, e: &Property) -> Result<()> {
31834 self.generate_expression(&e.this)?;
31836 if let Some(value) = &e.value {
31837 self.write("=");
31838 self.generate_expression(value)?;
31839 }
31840 Ok(())
31841 }
31842
31843 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
31844 self.write_keyword("OPTIONS");
31845 if e.entries.is_empty() {
31846 self.write(" ()");
31847 return Ok(());
31848 }
31849
31850 if self.config.pretty {
31851 self.write(" (");
31852 self.write_newline();
31853 self.indent_level += 1;
31854 for (i, entry) in e.entries.iter().enumerate() {
31855 if i > 0 {
31856 self.write(",");
31857 self.write_newline();
31858 }
31859 self.write_indent();
31860 self.generate_identifier(&entry.key)?;
31861 self.write("=");
31862 self.generate_expression(&entry.value)?;
31863 }
31864 self.indent_level -= 1;
31865 self.write_newline();
31866 self.write(")");
31867 } else {
31868 self.write(" (");
31869 for (i, entry) in e.entries.iter().enumerate() {
31870 if i > 0 {
31871 self.write(", ");
31872 }
31873 self.generate_identifier(&entry.key)?;
31874 self.write("=");
31875 self.generate_expression(&entry.value)?;
31876 }
31877 self.write(")");
31878 }
31879 Ok(())
31880 }
31881
31882 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
31884 self.write_keyword("OPTIONS");
31885 self.write(" (");
31886 for (i, opt) in options.iter().enumerate() {
31887 if i > 0 {
31888 self.write(", ");
31889 }
31890 self.generate_option_expression(opt)?;
31891 }
31892 self.write(")");
31893 Ok(())
31894 }
31895
31896 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
31898 self.write_keyword("PROPERTIES");
31899 self.write(" (");
31900 for (i, prop) in properties.iter().enumerate() {
31901 if i > 0 {
31902 self.write(", ");
31903 }
31904 self.generate_option_expression(prop)?;
31905 }
31906 self.write(")");
31907 Ok(())
31908 }
31909
31910 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
31912 self.write_keyword("ENVIRONMENT");
31913 self.write(" (");
31914 for (i, env_item) in environment.iter().enumerate() {
31915 if i > 0 {
31916 self.write(", ");
31917 }
31918 self.generate_environment_expression(env_item)?;
31919 }
31920 self.write(")");
31921 Ok(())
31922 }
31923
31924 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
31926 match expr {
31927 Expression::Eq(eq) => {
31928 self.generate_expression(&eq.left)?;
31930 self.write(" = ");
31931 self.generate_expression(&eq.right)?;
31932 Ok(())
31933 }
31934 _ => self.generate_expression(expr),
31935 }
31936 }
31937
31938 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
31940 self.write_keyword("TBLPROPERTIES");
31941 if self.config.pretty {
31942 self.write(" (");
31943 self.write_newline();
31944 self.indent_level += 1;
31945 for (i, opt) in options.iter().enumerate() {
31946 if i > 0 {
31947 self.write(",");
31948 self.write_newline();
31949 }
31950 self.write_indent();
31951 self.generate_option_expression(opt)?;
31952 }
31953 self.indent_level -= 1;
31954 self.write_newline();
31955 self.write(")");
31956 } else {
31957 self.write(" (");
31958 for (i, opt) in options.iter().enumerate() {
31959 if i > 0 {
31960 self.write(", ");
31961 }
31962 self.generate_option_expression(opt)?;
31963 }
31964 self.write(")");
31965 }
31966 Ok(())
31967 }
31968
31969 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
31971 match expr {
31972 Expression::Eq(eq) => {
31973 self.generate_expression(&eq.left)?;
31975 self.write("=");
31976 self.generate_expression(&eq.right)?;
31977 Ok(())
31978 }
31979 _ => self.generate_expression(expr),
31980 }
31981 }
31982
31983 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
31984 self.generate_expression(&e.this)?;
31986 Ok(())
31987 }
31988
31989 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
31990 self.write_keyword("PUT");
31992 self.write_space();
31993
31994 if e.source_quoted {
31996 self.write("'");
31997 self.write(&e.source);
31998 self.write("'");
31999 } else {
32000 self.write(&e.source);
32001 }
32002
32003 self.write_space();
32004
32005 if let Expression::Literal(lit) = &e.target {
32007 if let Literal::String(s) = lit.as_ref() {
32008 self.write(s);
32009 }
32010 } else {
32011 self.generate_expression(&e.target)?;
32012 }
32013
32014 for param in &e.params {
32016 self.write_space();
32017 self.write(¶m.name);
32018 if let Some(ref value) = param.value {
32019 self.write("=");
32020 self.generate_expression(value)?;
32021 }
32022 }
32023
32024 Ok(())
32025 }
32026
32027 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
32028 self.write_keyword("QUANTILE");
32030 self.write("(");
32031 self.generate_expression(&e.this)?;
32032 if let Some(quantile) = &e.quantile {
32033 self.write(", ");
32034 self.generate_expression(quantile)?;
32035 }
32036 self.write(")");
32037 Ok(())
32038 }
32039
32040 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
32041 if matches!(
32043 self.config.dialect,
32044 Some(crate::dialects::DialectType::Teradata)
32045 ) {
32046 self.write_keyword("SET");
32047 self.write_space();
32048 }
32049 self.write_keyword("QUERY_BAND");
32050 self.write(" = ");
32051 self.generate_expression(&e.this)?;
32052 if e.update.is_some() {
32053 self.write_space();
32054 self.write_keyword("UPDATE");
32055 }
32056 if let Some(scope) = &e.scope {
32057 self.write_space();
32058 self.write_keyword("FOR");
32059 self.write_space();
32060 self.generate_expression(scope)?;
32061 }
32062 Ok(())
32063 }
32064
32065 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
32066 self.generate_expression(&e.this)?;
32068 if let Some(expression) = &e.expression {
32069 self.write(" = ");
32070 self.generate_expression(expression)?;
32071 }
32072 Ok(())
32073 }
32074
32075 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
32076 self.write_keyword("TRANSFORM");
32078 self.write("(");
32079 for (i, expr) in e.expressions.iter().enumerate() {
32080 if i > 0 {
32081 self.write(", ");
32082 }
32083 self.generate_expression(expr)?;
32084 }
32085 self.write(")");
32086 if let Some(row_format_before) = &e.row_format_before {
32087 self.write_space();
32088 self.generate_expression(row_format_before)?;
32089 }
32090 if let Some(record_writer) = &e.record_writer {
32091 self.write_space();
32092 self.write_keyword("RECORDWRITER");
32093 self.write_space();
32094 self.generate_expression(record_writer)?;
32095 }
32096 if let Some(command_script) = &e.command_script {
32097 self.write_space();
32098 self.write_keyword("USING");
32099 self.write_space();
32100 self.generate_expression(command_script)?;
32101 }
32102 if let Some(schema) = &e.schema {
32103 self.write_space();
32104 self.write_keyword("AS");
32105 self.write_space();
32106 self.generate_expression(schema)?;
32107 }
32108 if let Some(row_format_after) = &e.row_format_after {
32109 self.write_space();
32110 self.generate_expression(row_format_after)?;
32111 }
32112 if let Some(record_reader) = &e.record_reader {
32113 self.write_space();
32114 self.write_keyword("RECORDREADER");
32115 self.write_space();
32116 self.generate_expression(record_reader)?;
32117 }
32118 Ok(())
32119 }
32120
32121 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
32122 self.write_keyword("RANDN");
32124 self.write("(");
32125 if let Some(this) = &e.this {
32126 self.generate_expression(this)?;
32127 }
32128 self.write(")");
32129 Ok(())
32130 }
32131
32132 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
32133 self.write_keyword("RANDSTR");
32135 self.write("(");
32136 self.generate_expression(&e.this)?;
32137 if let Some(generator) = &e.generator {
32138 self.write(", ");
32139 self.generate_expression(generator)?;
32140 }
32141 self.write(")");
32142 Ok(())
32143 }
32144
32145 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
32146 self.write_keyword("RANGE_BUCKET");
32148 self.write("(");
32149 self.generate_expression(&e.this)?;
32150 self.write(", ");
32151 self.generate_expression(&e.expression)?;
32152 self.write(")");
32153 Ok(())
32154 }
32155
32156 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
32157 self.write_keyword("RANGE_N");
32159 self.write("(");
32160 self.generate_expression(&e.this)?;
32161 self.write_space();
32162 self.write_keyword("BETWEEN");
32163 self.write_space();
32164 for (i, expr) in e.expressions.iter().enumerate() {
32165 if i > 0 {
32166 self.write(", ");
32167 }
32168 self.generate_expression(expr)?;
32169 }
32170 if let Some(each) = &e.each {
32171 self.write_space();
32172 self.write_keyword("EACH");
32173 self.write_space();
32174 self.generate_expression(each)?;
32175 }
32176 self.write(")");
32177 Ok(())
32178 }
32179
32180 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
32181 self.write_keyword("READ_CSV");
32183 self.write("(");
32184 self.generate_expression(&e.this)?;
32185 for expr in &e.expressions {
32186 self.write(", ");
32187 self.generate_expression(expr)?;
32188 }
32189 self.write(")");
32190 Ok(())
32191 }
32192
32193 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
32194 self.write_keyword("READ_PARQUET");
32196 self.write("(");
32197 for (i, expr) in e.expressions.iter().enumerate() {
32198 if i > 0 {
32199 self.write(", ");
32200 }
32201 self.generate_expression(expr)?;
32202 }
32203 self.write(")");
32204 Ok(())
32205 }
32206
32207 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
32208 if e.kind == "CYCLE" {
32211 self.write_keyword("CYCLE");
32212 } else {
32213 self.write_keyword("SEARCH");
32214 self.write_space();
32215 self.write(&e.kind);
32216 self.write_space();
32217 self.write_keyword("FIRST BY");
32218 }
32219 self.write_space();
32220 self.generate_expression(&e.this)?;
32221 self.write_space();
32222 self.write_keyword("SET");
32223 self.write_space();
32224 self.generate_expression(&e.expression)?;
32225 if let Some(using) = &e.using {
32226 self.write_space();
32227 self.write_keyword("USING");
32228 self.write_space();
32229 self.generate_expression(using)?;
32230 }
32231 Ok(())
32232 }
32233
32234 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
32235 self.write_keyword("REDUCE");
32237 self.write("(");
32238 self.generate_expression(&e.this)?;
32239 if let Some(initial) = &e.initial {
32240 self.write(", ");
32241 self.generate_expression(initial)?;
32242 }
32243 if let Some(merge) = &e.merge {
32244 self.write(", ");
32245 self.generate_expression(merge)?;
32246 }
32247 if let Some(finish) = &e.finish {
32248 self.write(", ");
32249 self.generate_expression(finish)?;
32250 }
32251 self.write(")");
32252 Ok(())
32253 }
32254
32255 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
32256 self.write_keyword("REFERENCES");
32258 self.write_space();
32259 self.generate_expression(&e.this)?;
32260 if !e.expressions.is_empty() {
32261 self.write(" (");
32262 for (i, expr) in e.expressions.iter().enumerate() {
32263 if i > 0 {
32264 self.write(", ");
32265 }
32266 self.generate_expression(expr)?;
32267 }
32268 self.write(")");
32269 }
32270 for opt in &e.options {
32271 self.write_space();
32272 self.generate_expression(opt)?;
32273 }
32274 Ok(())
32275 }
32276
32277 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
32278 self.write_keyword("REFRESH");
32280 if !e.kind.is_empty() {
32281 self.write_space();
32282 self.write_keyword(&e.kind);
32283 }
32284 self.write_space();
32285 self.generate_expression(&e.this)?;
32286 Ok(())
32287 }
32288
32289 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
32290 self.write_keyword("REFRESH");
32292 self.write_space();
32293 self.write_keyword(&e.method);
32294
32295 if let Some(ref kind) = e.kind {
32296 self.write_space();
32297 self.write_keyword("ON");
32298 self.write_space();
32299 self.write_keyword(kind);
32300
32301 if let Some(ref every) = e.every {
32303 self.write_space();
32304 self.write_keyword("EVERY");
32305 self.write_space();
32306 self.generate_expression(every)?;
32307 if let Some(ref unit) = e.unit {
32308 self.write_space();
32309 self.write_keyword(unit);
32310 }
32311 }
32312
32313 if let Some(ref starts) = e.starts {
32315 self.write_space();
32316 self.write_keyword("STARTS");
32317 self.write_space();
32318 self.generate_expression(starts)?;
32319 }
32320 }
32321 Ok(())
32322 }
32323
32324 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
32325 self.write_keyword("REGEXP_COUNT");
32327 self.write("(");
32328 self.generate_expression(&e.this)?;
32329 self.write(", ");
32330 self.generate_expression(&e.expression)?;
32331 if let Some(position) = &e.position {
32332 self.write(", ");
32333 self.generate_expression(position)?;
32334 }
32335 if let Some(parameters) = &e.parameters {
32336 self.write(", ");
32337 self.generate_expression(parameters)?;
32338 }
32339 self.write(")");
32340 Ok(())
32341 }
32342
32343 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
32344 self.write_keyword("REGEXP_EXTRACT_ALL");
32346 self.write("(");
32347 self.generate_expression(&e.this)?;
32348 self.write(", ");
32349 self.generate_expression(&e.expression)?;
32350 if let Some(group) = &e.group {
32351 self.write(", ");
32352 self.generate_expression(group)?;
32353 }
32354 self.write(")");
32355 Ok(())
32356 }
32357
32358 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
32359 self.write_keyword("REGEXP_FULL_MATCH");
32361 self.write("(");
32362 self.generate_expression(&e.this)?;
32363 self.write(", ");
32364 self.generate_expression(&e.expression)?;
32365 self.write(")");
32366 Ok(())
32367 }
32368
32369 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
32370 use crate::dialects::DialectType;
32371 if matches!(
32373 self.config.dialect,
32374 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
32375 ) && e.flag.is_none()
32376 {
32377 self.generate_expression(&e.this)?;
32378 self.write(" ~* ");
32379 self.generate_expression(&e.expression)?;
32380 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
32381 self.write_keyword("REGEXP_LIKE");
32383 self.write("(");
32384 self.generate_expression(&e.this)?;
32385 self.write(", ");
32386 self.generate_expression(&e.expression)?;
32387 self.write(", ");
32388 if let Some(flag) = &e.flag {
32389 self.generate_expression(flag)?;
32390 } else {
32391 self.write("'i'");
32392 }
32393 self.write(")");
32394 } else {
32395 self.generate_expression(&e.this)?;
32397 self.write_space();
32398 self.write_keyword("REGEXP_ILIKE");
32399 self.write_space();
32400 self.generate_expression(&e.expression)?;
32401 if let Some(flag) = &e.flag {
32402 self.write(", ");
32403 self.generate_expression(flag)?;
32404 }
32405 }
32406 Ok(())
32407 }
32408
32409 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
32410 self.write_keyword("REGEXP_INSTR");
32412 self.write("(");
32413 self.generate_expression(&e.this)?;
32414 self.write(", ");
32415 self.generate_expression(&e.expression)?;
32416 if let Some(position) = &e.position {
32417 self.write(", ");
32418 self.generate_expression(position)?;
32419 }
32420 if let Some(occurrence) = &e.occurrence {
32421 self.write(", ");
32422 self.generate_expression(occurrence)?;
32423 }
32424 if let Some(option) = &e.option {
32425 self.write(", ");
32426 self.generate_expression(option)?;
32427 }
32428 if let Some(parameters) = &e.parameters {
32429 self.write(", ");
32430 self.generate_expression(parameters)?;
32431 }
32432 if let Some(group) = &e.group {
32433 self.write(", ");
32434 self.generate_expression(group)?;
32435 }
32436 self.write(")");
32437 Ok(())
32438 }
32439
32440 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
32441 self.write_keyword("REGEXP_SPLIT");
32443 self.write("(");
32444 self.generate_expression(&e.this)?;
32445 self.write(", ");
32446 self.generate_expression(&e.expression)?;
32447 if let Some(limit) = &e.limit {
32448 self.write(", ");
32449 self.generate_expression(limit)?;
32450 }
32451 self.write(")");
32452 Ok(())
32453 }
32454
32455 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
32456 self.write_keyword("REGR_AVGX");
32458 self.write("(");
32459 self.generate_expression(&e.this)?;
32460 self.write(", ");
32461 self.generate_expression(&e.expression)?;
32462 self.write(")");
32463 Ok(())
32464 }
32465
32466 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
32467 self.write_keyword("REGR_AVGY");
32469 self.write("(");
32470 self.generate_expression(&e.this)?;
32471 self.write(", ");
32472 self.generate_expression(&e.expression)?;
32473 self.write(")");
32474 Ok(())
32475 }
32476
32477 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
32478 self.write_keyword("REGR_COUNT");
32480 self.write("(");
32481 self.generate_expression(&e.this)?;
32482 self.write(", ");
32483 self.generate_expression(&e.expression)?;
32484 self.write(")");
32485 Ok(())
32486 }
32487
32488 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
32489 self.write_keyword("REGR_INTERCEPT");
32491 self.write("(");
32492 self.generate_expression(&e.this)?;
32493 self.write(", ");
32494 self.generate_expression(&e.expression)?;
32495 self.write(")");
32496 Ok(())
32497 }
32498
32499 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
32500 self.write_keyword("REGR_R2");
32502 self.write("(");
32503 self.generate_expression(&e.this)?;
32504 self.write(", ");
32505 self.generate_expression(&e.expression)?;
32506 self.write(")");
32507 Ok(())
32508 }
32509
32510 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
32511 self.write_keyword("REGR_SLOPE");
32513 self.write("(");
32514 self.generate_expression(&e.this)?;
32515 self.write(", ");
32516 self.generate_expression(&e.expression)?;
32517 self.write(")");
32518 Ok(())
32519 }
32520
32521 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
32522 self.write_keyword("REGR_SXX");
32524 self.write("(");
32525 self.generate_expression(&e.this)?;
32526 self.write(", ");
32527 self.generate_expression(&e.expression)?;
32528 self.write(")");
32529 Ok(())
32530 }
32531
32532 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
32533 self.write_keyword("REGR_SXY");
32535 self.write("(");
32536 self.generate_expression(&e.this)?;
32537 self.write(", ");
32538 self.generate_expression(&e.expression)?;
32539 self.write(")");
32540 Ok(())
32541 }
32542
32543 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
32544 self.write_keyword("REGR_SYY");
32546 self.write("(");
32547 self.generate_expression(&e.this)?;
32548 self.write(", ");
32549 self.generate_expression(&e.expression)?;
32550 self.write(")");
32551 Ok(())
32552 }
32553
32554 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
32555 self.write_keyword("REGR_VALX");
32557 self.write("(");
32558 self.generate_expression(&e.this)?;
32559 self.write(", ");
32560 self.generate_expression(&e.expression)?;
32561 self.write(")");
32562 Ok(())
32563 }
32564
32565 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
32566 self.write_keyword("REGR_VALY");
32568 self.write("(");
32569 self.generate_expression(&e.this)?;
32570 self.write(", ");
32571 self.generate_expression(&e.expression)?;
32572 self.write(")");
32573 Ok(())
32574 }
32575
32576 fn generate_remote_with_connection_model_property(
32577 &mut self,
32578 e: &RemoteWithConnectionModelProperty,
32579 ) -> Result<()> {
32580 self.write_keyword("REMOTE WITH CONNECTION");
32582 self.write_space();
32583 self.generate_expression(&e.this)?;
32584 Ok(())
32585 }
32586
32587 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
32588 self.write_keyword("RENAME COLUMN");
32590 if e.exists {
32591 self.write_space();
32592 self.write_keyword("IF EXISTS");
32593 }
32594 self.write_space();
32595 self.generate_expression(&e.this)?;
32596 if let Some(to) = &e.to {
32597 self.write_space();
32598 self.write_keyword("TO");
32599 self.write_space();
32600 self.generate_expression(to)?;
32601 }
32602 Ok(())
32603 }
32604
32605 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
32606 self.write_keyword("REPLACE PARTITION");
32608 self.write_space();
32609 self.generate_expression(&e.expression)?;
32610 if let Some(source) = &e.source {
32611 self.write_space();
32612 self.write_keyword("FROM");
32613 self.write_space();
32614 self.generate_expression(source)?;
32615 }
32616 Ok(())
32617 }
32618
32619 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
32620 let keyword = match self.config.dialect {
32623 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
32624 _ => "RETURNING",
32625 };
32626 self.write_keyword(keyword);
32627 self.write_space();
32628 for (i, expr) in e.expressions.iter().enumerate() {
32629 if i > 0 {
32630 self.write(", ");
32631 }
32632 self.generate_expression(expr)?;
32633 }
32634 if let Some(into) = &e.into {
32635 self.write_space();
32636 self.write_keyword("INTO");
32637 self.write_space();
32638 self.generate_expression(into)?;
32639 }
32640 Ok(())
32641 }
32642
32643 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
32644 self.write_space();
32646 self.write_keyword("OUTPUT");
32647 self.write_space();
32648 for (i, expr) in output.columns.iter().enumerate() {
32649 if i > 0 {
32650 self.write(", ");
32651 }
32652 self.generate_expression(expr)?;
32653 }
32654 if let Some(into_table) = &output.into_table {
32655 self.write_space();
32656 self.write_keyword("INTO");
32657 self.write_space();
32658 self.generate_expression(into_table)?;
32659 }
32660 Ok(())
32661 }
32662
32663 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
32664 self.write_keyword("RETURNS");
32666 if e.is_table.is_some() {
32667 self.write_space();
32668 self.write_keyword("TABLE");
32669 }
32670 if let Some(table) = &e.table {
32671 self.write_space();
32672 self.generate_expression(table)?;
32673 } else if let Some(this) = &e.this {
32674 self.write_space();
32675 self.generate_expression(this)?;
32676 }
32677 if e.null.is_some() {
32678 self.write_space();
32679 self.write_keyword("NULL ON NULL INPUT");
32680 }
32681 Ok(())
32682 }
32683
32684 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
32685 self.write_keyword("ROLLBACK");
32687
32688 if e.this.is_none()
32690 && matches!(
32691 self.config.dialect,
32692 Some(DialectType::TSQL) | Some(DialectType::Fabric)
32693 )
32694 {
32695 self.write_space();
32696 self.write_keyword("TRANSACTION");
32697 }
32698
32699 if let Some(this) = &e.this {
32701 let is_transaction_marker = matches!(
32703 this.as_ref(),
32704 Expression::Identifier(id) if id.name == "TRANSACTION"
32705 );
32706
32707 self.write_space();
32708 self.write_keyword("TRANSACTION");
32709
32710 if !is_transaction_marker {
32712 self.write_space();
32713 self.generate_expression(this)?;
32714 }
32715 }
32716
32717 if let Some(savepoint) = &e.savepoint {
32719 self.write_space();
32720 self.write_keyword("TO");
32721 self.write_space();
32722 self.generate_expression(savepoint)?;
32723 }
32724 Ok(())
32725 }
32726
32727 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
32728 if e.expressions.is_empty() {
32730 self.write_keyword("WITH ROLLUP");
32731 } else {
32732 self.write_keyword("ROLLUP");
32733 self.write("(");
32734 for (i, expr) in e.expressions.iter().enumerate() {
32735 if i > 0 {
32736 self.write(", ");
32737 }
32738 self.generate_expression(expr)?;
32739 }
32740 self.write(")");
32741 }
32742 Ok(())
32743 }
32744
32745 fn generate_row_format_delimited_property(
32746 &mut self,
32747 e: &RowFormatDelimitedProperty,
32748 ) -> Result<()> {
32749 self.write_keyword("ROW FORMAT DELIMITED");
32751 if let Some(fields) = &e.fields {
32752 self.write_space();
32753 self.write_keyword("FIELDS TERMINATED BY");
32754 self.write_space();
32755 self.generate_expression(fields)?;
32756 }
32757 if let Some(escaped) = &e.escaped {
32758 self.write_space();
32759 self.write_keyword("ESCAPED BY");
32760 self.write_space();
32761 self.generate_expression(escaped)?;
32762 }
32763 if let Some(items) = &e.collection_items {
32764 self.write_space();
32765 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
32766 self.write_space();
32767 self.generate_expression(items)?;
32768 }
32769 if let Some(keys) = &e.map_keys {
32770 self.write_space();
32771 self.write_keyword("MAP KEYS TERMINATED BY");
32772 self.write_space();
32773 self.generate_expression(keys)?;
32774 }
32775 if let Some(lines) = &e.lines {
32776 self.write_space();
32777 self.write_keyword("LINES TERMINATED BY");
32778 self.write_space();
32779 self.generate_expression(lines)?;
32780 }
32781 if let Some(null) = &e.null {
32782 self.write_space();
32783 self.write_keyword("NULL DEFINED AS");
32784 self.write_space();
32785 self.generate_expression(null)?;
32786 }
32787 if let Some(serde) = &e.serde {
32788 self.write_space();
32789 self.generate_expression(serde)?;
32790 }
32791 Ok(())
32792 }
32793
32794 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
32795 self.write_keyword("ROW FORMAT");
32797 self.write_space();
32798 self.generate_expression(&e.this)?;
32799 Ok(())
32800 }
32801
32802 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
32803 self.write_keyword("ROW FORMAT SERDE");
32805 self.write_space();
32806 self.generate_expression(&e.this)?;
32807 if let Some(props) = &e.serde_properties {
32808 self.write_space();
32809 self.generate_expression(props)?;
32811 }
32812 Ok(())
32813 }
32814
32815 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
32816 self.write_keyword("SHA2");
32818 self.write("(");
32819 self.generate_expression(&e.this)?;
32820 if let Some(length) = e.length {
32821 self.write(", ");
32822 self.write(&length.to_string());
32823 }
32824 self.write(")");
32825 Ok(())
32826 }
32827
32828 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
32829 self.write_keyword("SHA2_DIGEST");
32831 self.write("(");
32832 self.generate_expression(&e.this)?;
32833 if let Some(length) = e.length {
32834 self.write(", ");
32835 self.write(&length.to_string());
32836 }
32837 self.write(")");
32838 Ok(())
32839 }
32840
32841 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
32842 let name = if matches!(
32843 self.config.dialect,
32844 Some(crate::dialects::DialectType::Spark)
32845 | Some(crate::dialects::DialectType::Databricks)
32846 ) {
32847 "TRY_ADD"
32848 } else {
32849 "SAFE_ADD"
32850 };
32851 self.write_keyword(name);
32852 self.write("(");
32853 self.generate_expression(&e.this)?;
32854 self.write(", ");
32855 self.generate_expression(&e.expression)?;
32856 self.write(")");
32857 Ok(())
32858 }
32859
32860 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
32861 self.write_keyword("SAFE_DIVIDE");
32863 self.write("(");
32864 self.generate_expression(&e.this)?;
32865 self.write(", ");
32866 self.generate_expression(&e.expression)?;
32867 self.write(")");
32868 Ok(())
32869 }
32870
32871 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
32872 let name = if matches!(
32873 self.config.dialect,
32874 Some(crate::dialects::DialectType::Spark)
32875 | Some(crate::dialects::DialectType::Databricks)
32876 ) {
32877 "TRY_MULTIPLY"
32878 } else {
32879 "SAFE_MULTIPLY"
32880 };
32881 self.write_keyword(name);
32882 self.write("(");
32883 self.generate_expression(&e.this)?;
32884 self.write(", ");
32885 self.generate_expression(&e.expression)?;
32886 self.write(")");
32887 Ok(())
32888 }
32889
32890 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
32891 let name = if matches!(
32892 self.config.dialect,
32893 Some(crate::dialects::DialectType::Spark)
32894 | Some(crate::dialects::DialectType::Databricks)
32895 ) {
32896 "TRY_SUBTRACT"
32897 } else {
32898 "SAFE_SUBTRACT"
32899 };
32900 self.write_keyword(name);
32901 self.write("(");
32902 self.generate_expression(&e.this)?;
32903 self.write(", ");
32904 self.generate_expression(&e.expression)?;
32905 self.write(")");
32906 Ok(())
32907 }
32908
32909 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
32912 if matches!(sample.method, SampleMethod::Bucket) {
32914 self.write(" (");
32915 self.write_keyword("BUCKET");
32916 self.write_space();
32917 if let Some(ref num) = sample.bucket_numerator {
32918 self.generate_expression(num)?;
32919 }
32920 self.write_space();
32921 self.write_keyword("OUT OF");
32922 self.write_space();
32923 if let Some(ref denom) = sample.bucket_denominator {
32924 self.generate_expression(denom)?;
32925 }
32926 if let Some(ref field) = sample.bucket_field {
32927 self.write_space();
32928 self.write_keyword("ON");
32929 self.write_space();
32930 self.generate_expression(field)?;
32931 }
32932 self.write(")");
32933 return Ok(());
32934 }
32935
32936 let is_snowflake = matches!(
32938 self.config.dialect,
32939 Some(crate::dialects::DialectType::Snowflake)
32940 );
32941 let is_postgres = matches!(
32942 self.config.dialect,
32943 Some(crate::dialects::DialectType::PostgreSQL)
32944 | Some(crate::dialects::DialectType::Redshift)
32945 );
32946 let is_databricks = matches!(
32948 self.config.dialect,
32949 Some(crate::dialects::DialectType::Databricks)
32950 );
32951 let is_spark = matches!(
32952 self.config.dialect,
32953 Some(crate::dialects::DialectType::Spark)
32954 );
32955 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
32956 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
32958 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
32959 self.write_space();
32960 if !sample.explicit_method && (is_snowflake || force_method) {
32961 self.write_keyword("BERNOULLI");
32963 } else {
32964 match sample.method {
32965 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
32966 SampleMethod::System => self.write_keyword("SYSTEM"),
32967 SampleMethod::Block => self.write_keyword("BLOCK"),
32968 SampleMethod::Row => self.write_keyword("ROW"),
32969 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
32970 SampleMethod::Percent => self.write_keyword("SYSTEM"),
32971 SampleMethod::Bucket => {} }
32973 }
32974 }
32975
32976 let emit_size_no_parens = !self.config.tablesample_requires_parens;
32978 if emit_size_no_parens {
32979 self.write_space();
32980 match &sample.size {
32981 Expression::Tuple(tuple) => {
32982 for (i, expr) in tuple.expressions.iter().enumerate() {
32983 if i > 0 {
32984 self.write(", ");
32985 }
32986 self.generate_expression(expr)?;
32987 }
32988 }
32989 expr => self.generate_expression(expr)?,
32990 }
32991 } else {
32992 self.write(" (");
32993 self.generate_expression(&sample.size)?;
32994 }
32995
32996 let is_rows_method = matches!(
32998 sample.method,
32999 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
33000 );
33001 let is_percent = matches!(
33002 sample.method,
33003 SampleMethod::Percent
33004 | SampleMethod::System
33005 | SampleMethod::Bernoulli
33006 | SampleMethod::Block
33007 );
33008
33009 let is_presto = matches!(
33013 self.config.dialect,
33014 Some(crate::dialects::DialectType::Presto)
33015 | Some(crate::dialects::DialectType::Trino)
33016 | Some(crate::dialects::DialectType::Athena)
33017 );
33018 let should_output_unit = if is_databricks || is_spark {
33019 is_percent || is_rows_method || sample.unit_after_size
33021 } else if is_snowflake || is_postgres || is_presto {
33022 sample.unit_after_size
33023 } else {
33024 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
33025 };
33026
33027 if should_output_unit {
33028 self.write_space();
33029 if sample.is_percent {
33030 self.write_keyword("PERCENT");
33031 } else if is_rows_method && !sample.unit_after_size {
33032 self.write_keyword("ROWS");
33033 } else if sample.unit_after_size {
33034 match sample.method {
33035 SampleMethod::Percent
33036 | SampleMethod::System
33037 | SampleMethod::Bernoulli
33038 | SampleMethod::Block => {
33039 self.write_keyword("PERCENT");
33040 }
33041 SampleMethod::Row | SampleMethod::Reservoir => {
33042 self.write_keyword("ROWS");
33043 }
33044 _ => self.write_keyword("ROWS"),
33045 }
33046 } else {
33047 self.write_keyword("PERCENT");
33048 }
33049 }
33050
33051 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
33052 if let Some(ref offset) = sample.offset {
33053 self.write_space();
33054 self.write_keyword("OFFSET");
33055 self.write_space();
33056 self.generate_expression(offset)?;
33057 }
33058 }
33059 if !emit_size_no_parens {
33060 self.write(")");
33061 }
33062
33063 Ok(())
33064 }
33065
33066 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
33067 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
33069 self.write_keyword("SAMPLE BY");
33070 } else {
33071 self.write_keyword("SAMPLE");
33072 }
33073 self.write_space();
33074 self.generate_expression(&e.this)?;
33075 Ok(())
33076 }
33077
33078 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
33079 if let Some(this) = &e.this {
33081 self.generate_expression(this)?;
33082 }
33083 if !e.expressions.is_empty() {
33084 if e.this.is_some() {
33086 self.write_space();
33087 }
33088 self.write("(");
33089 for (i, expr) in e.expressions.iter().enumerate() {
33090 if i > 0 {
33091 self.write(", ");
33092 }
33093 self.generate_expression(expr)?;
33094 }
33095 self.write(")");
33096 }
33097 Ok(())
33098 }
33099
33100 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
33101 self.write_keyword("COMMENT");
33103 self.write_space();
33104 self.generate_expression(&e.this)?;
33105 Ok(())
33106 }
33107
33108 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
33109 if let Some(this) = &e.this {
33111 self.generate_expression(this)?;
33112 self.write("::");
33113 }
33114 self.generate_expression(&e.expression)?;
33115 Ok(())
33116 }
33117
33118 fn generate_search(&mut self, e: &Search) -> Result<()> {
33119 self.write_keyword("SEARCH");
33121 self.write("(");
33122 self.generate_expression(&e.this)?;
33123 self.write(", ");
33124 self.generate_expression(&e.expression)?;
33125 if let Some(json_scope) = &e.json_scope {
33126 self.write(", ");
33127 self.generate_expression(json_scope)?;
33128 }
33129 if let Some(analyzer) = &e.analyzer {
33130 self.write(", ");
33131 self.generate_expression(analyzer)?;
33132 }
33133 if let Some(analyzer_options) = &e.analyzer_options {
33134 self.write(", ");
33135 self.generate_expression(analyzer_options)?;
33136 }
33137 if let Some(search_mode) = &e.search_mode {
33138 self.write(", ");
33139 self.generate_expression(search_mode)?;
33140 }
33141 self.write(")");
33142 Ok(())
33143 }
33144
33145 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
33146 self.write_keyword("SEARCH_IP");
33148 self.write("(");
33149 self.generate_expression(&e.this)?;
33150 self.write(", ");
33151 self.generate_expression(&e.expression)?;
33152 self.write(")");
33153 Ok(())
33154 }
33155
33156 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
33157 self.write_keyword("SECURITY");
33159 self.write_space();
33160 self.generate_expression(&e.this)?;
33161 Ok(())
33162 }
33163
33164 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
33165 self.write("SEMANTIC_VIEW(");
33167
33168 if self.config.pretty {
33169 self.write_newline();
33171 self.indent_level += 1;
33172 self.write_indent();
33173 self.generate_expression(&e.this)?;
33174
33175 if let Some(metrics) = &e.metrics {
33176 self.write_newline();
33177 self.write_indent();
33178 self.write_keyword("METRICS");
33179 self.write_space();
33180 self.generate_semantic_view_tuple(metrics)?;
33181 }
33182 if let Some(dimensions) = &e.dimensions {
33183 self.write_newline();
33184 self.write_indent();
33185 self.write_keyword("DIMENSIONS");
33186 self.write_space();
33187 self.generate_semantic_view_tuple(dimensions)?;
33188 }
33189 if let Some(facts) = &e.facts {
33190 self.write_newline();
33191 self.write_indent();
33192 self.write_keyword("FACTS");
33193 self.write_space();
33194 self.generate_semantic_view_tuple(facts)?;
33195 }
33196 if let Some(where_) = &e.where_ {
33197 self.write_newline();
33198 self.write_indent();
33199 self.write_keyword("WHERE");
33200 self.write_space();
33201 self.generate_expression(where_)?;
33202 }
33203 self.write_newline();
33204 self.indent_level -= 1;
33205 self.write_indent();
33206 } else {
33207 self.generate_expression(&e.this)?;
33209 if let Some(metrics) = &e.metrics {
33210 self.write_space();
33211 self.write_keyword("METRICS");
33212 self.write_space();
33213 self.generate_semantic_view_tuple(metrics)?;
33214 }
33215 if let Some(dimensions) = &e.dimensions {
33216 self.write_space();
33217 self.write_keyword("DIMENSIONS");
33218 self.write_space();
33219 self.generate_semantic_view_tuple(dimensions)?;
33220 }
33221 if let Some(facts) = &e.facts {
33222 self.write_space();
33223 self.write_keyword("FACTS");
33224 self.write_space();
33225 self.generate_semantic_view_tuple(facts)?;
33226 }
33227 if let Some(where_) = &e.where_ {
33228 self.write_space();
33229 self.write_keyword("WHERE");
33230 self.write_space();
33231 self.generate_expression(where_)?;
33232 }
33233 }
33234 self.write(")");
33235 Ok(())
33236 }
33237
33238 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
33240 if let Expression::Tuple(t) = expr {
33241 for (i, e) in t.expressions.iter().enumerate() {
33242 if i > 0 {
33243 self.write(", ");
33244 }
33245 self.generate_expression(e)?;
33246 }
33247 } else {
33248 self.generate_expression(expr)?;
33249 }
33250 Ok(())
33251 }
33252
33253 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
33254 if let Some(start) = &e.start {
33256 self.write_keyword("START WITH");
33257 self.write_space();
33258 self.generate_expression(start)?;
33259 }
33260 if let Some(increment) = &e.increment {
33261 self.write_space();
33262 self.write_keyword("INCREMENT BY");
33263 self.write_space();
33264 self.generate_expression(increment)?;
33265 }
33266 if let Some(minvalue) = &e.minvalue {
33267 self.write_space();
33268 self.write_keyword("MINVALUE");
33269 self.write_space();
33270 self.generate_expression(minvalue)?;
33271 }
33272 if let Some(maxvalue) = &e.maxvalue {
33273 self.write_space();
33274 self.write_keyword("MAXVALUE");
33275 self.write_space();
33276 self.generate_expression(maxvalue)?;
33277 }
33278 if let Some(cache) = &e.cache {
33279 self.write_space();
33280 self.write_keyword("CACHE");
33281 self.write_space();
33282 self.generate_expression(cache)?;
33283 }
33284 if let Some(owned) = &e.owned {
33285 self.write_space();
33286 self.write_keyword("OWNED BY");
33287 self.write_space();
33288 self.generate_expression(owned)?;
33289 }
33290 for opt in &e.options {
33291 self.write_space();
33292 self.generate_expression(opt)?;
33293 }
33294 Ok(())
33295 }
33296
33297 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
33298 if e.with_.is_some() {
33300 self.write_keyword("WITH");
33301 self.write_space();
33302 }
33303 self.write_keyword("SERDEPROPERTIES");
33304 self.write(" (");
33305 for (i, expr) in e.expressions.iter().enumerate() {
33306 if i > 0 {
33307 self.write(", ");
33308 }
33309 match expr {
33311 Expression::Eq(eq) => {
33312 self.generate_expression(&eq.left)?;
33313 self.write("=");
33314 self.generate_expression(&eq.right)?;
33315 }
33316 _ => self.generate_expression(expr)?,
33317 }
33318 }
33319 self.write(")");
33320 Ok(())
33321 }
33322
33323 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
33324 self.write("@@");
33326 if let Some(kind) = &e.kind {
33327 self.write(kind);
33328 self.write(".");
33329 }
33330 self.generate_expression(&e.this)?;
33331 Ok(())
33332 }
33333
33334 fn generate_set(&mut self, e: &Set) -> Result<()> {
33335 if e.unset.is_some() {
33337 self.write_keyword("UNSET");
33338 } else {
33339 self.write_keyword("SET");
33340 }
33341 if e.tag.is_some() {
33342 self.write_space();
33343 self.write_keyword("TAG");
33344 }
33345 if !e.expressions.is_empty() {
33346 self.write_space();
33347 for (i, expr) in e.expressions.iter().enumerate() {
33348 if i > 0 {
33349 self.write(", ");
33350 }
33351 self.generate_expression(expr)?;
33352 }
33353 }
33354 Ok(())
33355 }
33356
33357 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
33358 self.write_keyword("SET");
33360 self.write_space();
33361 self.generate_expression(&e.this)?;
33362 Ok(())
33363 }
33364
33365 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
33366 if let Some(kind) = &e.kind {
33368 self.write_keyword(kind);
33369 self.write_space();
33370 }
33371 self.generate_expression(&e.name)?;
33372 self.write(" = ");
33373 self.generate_expression(&e.value)?;
33374 Ok(())
33375 }
33376
33377 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
33378 if let Some(with_) = &e.with_ {
33380 self.generate_expression(with_)?;
33381 self.write_space();
33382 }
33383 self.generate_expression(&e.this)?;
33384 self.write_space();
33385 if let Some(kind) = &e.kind {
33387 self.write_keyword(kind);
33388 }
33389 if e.distinct {
33390 self.write_space();
33391 self.write_keyword("DISTINCT");
33392 } else {
33393 self.write_space();
33394 self.write_keyword("ALL");
33395 }
33396 if e.by_name.is_some() {
33397 self.write_space();
33398 self.write_keyword("BY NAME");
33399 }
33400 self.write_space();
33401 self.generate_expression(&e.expression)?;
33402 Ok(())
33403 }
33404
33405 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
33406 if e.multi.is_some() {
33408 self.write_keyword("MULTISET");
33409 } else {
33410 self.write_keyword("SET");
33411 }
33412 Ok(())
33413 }
33414
33415 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
33416 self.write_keyword("SETTINGS");
33418 if self.config.pretty && e.expressions.len() > 1 {
33419 self.indent_level += 1;
33421 for (i, expr) in e.expressions.iter().enumerate() {
33422 if i > 0 {
33423 self.write(",");
33424 }
33425 self.write_newline();
33426 self.write_indent();
33427 self.generate_expression(expr)?;
33428 }
33429 self.indent_level -= 1;
33430 } else {
33431 self.write_space();
33432 for (i, expr) in e.expressions.iter().enumerate() {
33433 if i > 0 {
33434 self.write(", ");
33435 }
33436 self.generate_expression(expr)?;
33437 }
33438 }
33439 Ok(())
33440 }
33441
33442 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
33443 self.write_keyword("SHARING");
33445 if let Some(this) = &e.this {
33446 self.write(" = ");
33447 self.generate_expression(this)?;
33448 }
33449 Ok(())
33450 }
33451
33452 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
33453 if let Some(begin) = &e.this {
33455 self.generate_expression(begin)?;
33456 }
33457 self.write(":");
33458 if let Some(end) = &e.expression {
33459 self.generate_expression(end)?;
33460 }
33461 if let Some(step) = &e.step {
33462 self.write(":");
33463 self.generate_expression(step)?;
33464 }
33465 Ok(())
33466 }
33467
33468 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
33469 self.write_keyword("SORT_ARRAY");
33471 self.write("(");
33472 self.generate_expression(&e.this)?;
33473 if let Some(asc) = &e.asc {
33474 self.write(", ");
33475 self.generate_expression(asc)?;
33476 }
33477 self.write(")");
33478 Ok(())
33479 }
33480
33481 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
33482 self.write_keyword("SORT BY");
33484 self.write_space();
33485 for (i, expr) in e.expressions.iter().enumerate() {
33486 if i > 0 {
33487 self.write(", ");
33488 }
33489 self.generate_ordered(expr)?;
33490 }
33491 Ok(())
33492 }
33493
33494 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
33495 if e.compound.is_some() {
33497 self.write_keyword("COMPOUND");
33498 self.write_space();
33499 }
33500 self.write_keyword("SORTKEY");
33501 self.write("(");
33502 if let Expression::Tuple(t) = e.this.as_ref() {
33504 for (i, expr) in t.expressions.iter().enumerate() {
33505 if i > 0 {
33506 self.write(", ");
33507 }
33508 self.generate_expression(expr)?;
33509 }
33510 } else {
33511 self.generate_expression(&e.this)?;
33512 }
33513 self.write(")");
33514 Ok(())
33515 }
33516
33517 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
33518 self.write_keyword("SPLIT_PART");
33520 self.write("(");
33521 self.generate_expression(&e.this)?;
33522 if let Some(delimiter) = &e.delimiter {
33523 self.write(", ");
33524 self.generate_expression(delimiter)?;
33525 }
33526 if let Some(part_index) = &e.part_index {
33527 self.write(", ");
33528 self.generate_expression(part_index)?;
33529 }
33530 self.write(")");
33531 Ok(())
33532 }
33533
33534 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
33535 self.generate_expression(&e.this)?;
33537 Ok(())
33538 }
33539
33540 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
33541 self.write_keyword("SQL SECURITY");
33543 self.write_space();
33544 self.generate_expression(&e.this)?;
33545 Ok(())
33546 }
33547
33548 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
33549 self.write_keyword("ST_DISTANCE");
33551 self.write("(");
33552 self.generate_expression(&e.this)?;
33553 self.write(", ");
33554 self.generate_expression(&e.expression)?;
33555 if let Some(use_spheroid) = &e.use_spheroid {
33556 self.write(", ");
33557 self.generate_expression(use_spheroid)?;
33558 }
33559 self.write(")");
33560 Ok(())
33561 }
33562
33563 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
33564 self.write_keyword("ST_POINT");
33566 self.write("(");
33567 self.generate_expression(&e.this)?;
33568 self.write(", ");
33569 self.generate_expression(&e.expression)?;
33570 self.write(")");
33571 Ok(())
33572 }
33573
33574 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
33575 self.generate_expression(&e.this)?;
33577 Ok(())
33578 }
33579
33580 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
33581 self.write_keyword("STANDARD_HASH");
33583 self.write("(");
33584 self.generate_expression(&e.this)?;
33585 if let Some(expression) = &e.expression {
33586 self.write(", ");
33587 self.generate_expression(expression)?;
33588 }
33589 self.write(")");
33590 Ok(())
33591 }
33592
33593 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
33594 self.write_keyword("STORED BY");
33596 self.write_space();
33597 self.generate_expression(&e.this)?;
33598 Ok(())
33599 }
33600
33601 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
33602 use crate::dialects::DialectType;
33605 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33606 self.write_keyword("CHARINDEX");
33608 self.write("(");
33609 if let Some(substr) = &e.substr {
33610 self.generate_expression(substr)?;
33611 self.write(", ");
33612 }
33613 self.generate_expression(&e.this)?;
33614 if let Some(position) = &e.position {
33615 self.write(", ");
33616 self.generate_expression(position)?;
33617 }
33618 self.write(")");
33619 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
33620 self.write_keyword("POSITION");
33621 self.write("(");
33622 self.generate_expression(&e.this)?;
33623 if let Some(substr) = &e.substr {
33624 self.write(", ");
33625 self.generate_expression(substr)?;
33626 }
33627 if let Some(position) = &e.position {
33628 self.write(", ");
33629 self.generate_expression(position)?;
33630 }
33631 if let Some(occurrence) = &e.occurrence {
33632 self.write(", ");
33633 self.generate_expression(occurrence)?;
33634 }
33635 self.write(")");
33636 } else if matches!(
33637 self.config.dialect,
33638 Some(DialectType::SQLite)
33639 | Some(DialectType::Oracle)
33640 | Some(DialectType::BigQuery)
33641 | Some(DialectType::Teradata)
33642 ) {
33643 self.write_keyword("INSTR");
33644 self.write("(");
33645 self.generate_expression(&e.this)?;
33646 if let Some(substr) = &e.substr {
33647 self.write(", ");
33648 self.generate_expression(substr)?;
33649 }
33650 if let Some(position) = &e.position {
33651 self.write(", ");
33652 self.generate_expression(position)?;
33653 } else if e.occurrence.is_some() {
33654 self.write(", 1");
33657 }
33658 if let Some(occurrence) = &e.occurrence {
33659 self.write(", ");
33660 self.generate_expression(occurrence)?;
33661 }
33662 self.write(")");
33663 } else if matches!(
33664 self.config.dialect,
33665 Some(DialectType::MySQL)
33666 | Some(DialectType::SingleStore)
33667 | Some(DialectType::Doris)
33668 | Some(DialectType::StarRocks)
33669 | Some(DialectType::Hive)
33670 | Some(DialectType::Spark)
33671 | Some(DialectType::Databricks)
33672 ) {
33673 self.write_keyword("LOCATE");
33675 self.write("(");
33676 if let Some(substr) = &e.substr {
33677 self.generate_expression(substr)?;
33678 self.write(", ");
33679 }
33680 self.generate_expression(&e.this)?;
33681 if let Some(position) = &e.position {
33682 self.write(", ");
33683 self.generate_expression(position)?;
33684 }
33685 self.write(")");
33686 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
33687 self.write_keyword("CHARINDEX");
33689 self.write("(");
33690 if let Some(substr) = &e.substr {
33691 self.generate_expression(substr)?;
33692 self.write(", ");
33693 }
33694 self.generate_expression(&e.this)?;
33695 if let Some(position) = &e.position {
33696 self.write(", ");
33697 self.generate_expression(position)?;
33698 }
33699 self.write(")");
33700 } else if matches!(
33701 self.config.dialect,
33702 Some(DialectType::PostgreSQL)
33703 | Some(DialectType::Materialize)
33704 | Some(DialectType::RisingWave)
33705 | Some(DialectType::Redshift)
33706 ) {
33707 self.write_keyword("POSITION");
33709 self.write("(");
33710 if let Some(substr) = &e.substr {
33711 self.generate_expression(substr)?;
33712 self.write(" IN ");
33713 }
33714 self.generate_expression(&e.this)?;
33715 self.write(")");
33716 } else {
33717 self.write_keyword("STRPOS");
33718 self.write("(");
33719 self.generate_expression(&e.this)?;
33720 if let Some(substr) = &e.substr {
33721 self.write(", ");
33722 self.generate_expression(substr)?;
33723 }
33724 if let Some(position) = &e.position {
33725 self.write(", ");
33726 self.generate_expression(position)?;
33727 }
33728 if let Some(occurrence) = &e.occurrence {
33729 self.write(", ");
33730 self.generate_expression(occurrence)?;
33731 }
33732 self.write(")");
33733 }
33734 Ok(())
33735 }
33736
33737 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
33738 match self.config.dialect {
33739 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
33740 self.write_keyword("TO_DATE");
33742 self.write("(");
33743 self.generate_expression(&e.this)?;
33744 if let Some(format) = &e.format {
33745 self.write(", '");
33746 self.write(&Self::strftime_to_java_format(format));
33747 self.write("'");
33748 }
33749 self.write(")");
33750 }
33751 Some(DialectType::DuckDB) => {
33752 self.write_keyword("CAST");
33754 self.write("(");
33755 self.write_keyword("STRPTIME");
33756 self.write("(");
33757 self.generate_expression(&e.this)?;
33758 if let Some(format) = &e.format {
33759 self.write(", '");
33760 self.write(format);
33761 self.write("'");
33762 }
33763 self.write(")");
33764 self.write_keyword(" AS ");
33765 self.write_keyword("DATE");
33766 self.write(")");
33767 }
33768 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
33769 self.write_keyword("TO_DATE");
33771 self.write("(");
33772 self.generate_expression(&e.this)?;
33773 if let Some(format) = &e.format {
33774 self.write(", '");
33775 self.write(&Self::strftime_to_postgres_format(format));
33776 self.write("'");
33777 }
33778 self.write(")");
33779 }
33780 Some(DialectType::BigQuery) => {
33781 self.write_keyword("PARSE_DATE");
33783 self.write("(");
33784 if let Some(format) = &e.format {
33785 self.write("'");
33786 self.write(format);
33787 self.write("'");
33788 self.write(", ");
33789 }
33790 self.generate_expression(&e.this)?;
33791 self.write(")");
33792 }
33793 Some(DialectType::Teradata) => {
33794 self.write_keyword("CAST");
33796 self.write("(");
33797 self.generate_expression(&e.this)?;
33798 self.write_keyword(" AS ");
33799 self.write_keyword("DATE");
33800 if let Some(format) = &e.format {
33801 self.write_keyword(" FORMAT ");
33802 self.write("'");
33803 self.write(&Self::strftime_to_teradata_format(format));
33804 self.write("'");
33805 }
33806 self.write(")");
33807 }
33808 _ => {
33809 self.write_keyword("STR_TO_DATE");
33811 self.write("(");
33812 self.generate_expression(&e.this)?;
33813 if let Some(format) = &e.format {
33814 self.write(", '");
33815 self.write(format);
33816 self.write("'");
33817 }
33818 self.write(")");
33819 }
33820 }
33821 Ok(())
33822 }
33823
33824 fn strftime_to_teradata_format(fmt: &str) -> String {
33826 let mut result = String::with_capacity(fmt.len() * 2);
33827 let bytes = fmt.as_bytes();
33828 let len = bytes.len();
33829 let mut i = 0;
33830 while i < len {
33831 if bytes[i] == b'%' && i + 1 < len {
33832 let replacement = match bytes[i + 1] {
33833 b'Y' => "YYYY",
33834 b'y' => "YY",
33835 b'm' => "MM",
33836 b'B' => "MMMM",
33837 b'b' => "MMM",
33838 b'd' => "DD",
33839 b'j' => "DDD",
33840 b'H' => "HH",
33841 b'M' => "MI",
33842 b'S' => "SS",
33843 b'f' => "SSSSSS",
33844 b'A' => "EEEE",
33845 b'a' => "EEE",
33846 _ => {
33847 result.push('%');
33848 i += 1;
33849 continue;
33850 }
33851 };
33852 result.push_str(replacement);
33853 i += 2;
33854 } else {
33855 result.push(bytes[i] as char);
33856 i += 1;
33857 }
33858 }
33859 result
33860 }
33861
33862 pub fn strftime_to_java_format_static(fmt: &str) -> String {
33865 Self::strftime_to_java_format(fmt)
33866 }
33867
33868 fn strftime_to_java_format(fmt: &str) -> String {
33870 let mut result = String::with_capacity(fmt.len() * 2);
33871 let bytes = fmt.as_bytes();
33872 let len = bytes.len();
33873 let mut i = 0;
33874 while i < len {
33875 if bytes[i] == b'%' && i + 1 < len {
33876 if bytes[i + 1] == b'-' && i + 2 < len {
33878 let replacement = match bytes[i + 2] {
33879 b'd' => "d",
33880 b'm' => "M",
33881 b'H' => "H",
33882 b'M' => "m",
33883 b'S' => "s",
33884 _ => {
33885 result.push('%');
33886 i += 1;
33887 continue;
33888 }
33889 };
33890 result.push_str(replacement);
33891 i += 3;
33892 } else {
33893 let replacement = match bytes[i + 1] {
33894 b'Y' => "yyyy",
33895 b'y' => "yy",
33896 b'm' => "MM",
33897 b'B' => "MMMM",
33898 b'b' => "MMM",
33899 b'd' => "dd",
33900 b'j' => "DDD",
33901 b'H' => "HH",
33902 b'M' => "mm",
33903 b'S' => "ss",
33904 b'f' => "SSSSSS",
33905 b'A' => "EEEE",
33906 b'a' => "EEE",
33907 _ => {
33908 result.push('%');
33909 i += 1;
33910 continue;
33911 }
33912 };
33913 result.push_str(replacement);
33914 i += 2;
33915 }
33916 } else {
33917 result.push(bytes[i] as char);
33918 i += 1;
33919 }
33920 }
33921 result
33922 }
33923
33924 fn strftime_to_tsql_format(fmt: &str) -> String {
33927 let mut result = String::with_capacity(fmt.len() * 2);
33928 let bytes = fmt.as_bytes();
33929 let len = bytes.len();
33930 let mut i = 0;
33931 while i < len {
33932 if bytes[i] == b'%' && i + 1 < len {
33933 if bytes[i + 1] == b'-' && i + 2 < len {
33935 let replacement = match bytes[i + 2] {
33936 b'd' => "d",
33937 b'm' => "M",
33938 b'H' => "H",
33939 b'M' => "m",
33940 b'S' => "s",
33941 _ => {
33942 result.push('%');
33943 i += 1;
33944 continue;
33945 }
33946 };
33947 result.push_str(replacement);
33948 i += 3;
33949 } else {
33950 let replacement = match bytes[i + 1] {
33951 b'Y' => "yyyy",
33952 b'y' => "yy",
33953 b'm' => "MM",
33954 b'B' => "MMMM",
33955 b'b' => "MMM",
33956 b'd' => "dd",
33957 b'j' => "DDD",
33958 b'H' => "HH",
33959 b'M' => "mm",
33960 b'S' => "ss",
33961 b'f' => "ffffff",
33962 b'A' => "dddd",
33963 b'a' => "ddd",
33964 _ => {
33965 result.push('%');
33966 i += 1;
33967 continue;
33968 }
33969 };
33970 result.push_str(replacement);
33971 i += 2;
33972 }
33973 } else {
33974 result.push(bytes[i] as char);
33975 i += 1;
33976 }
33977 }
33978 result
33979 }
33980
33981 fn decompose_json_path(path: &str) -> Vec<String> {
33984 let mut parts = Vec::new();
33985 let path = if path.starts_with("$.") {
33987 &path[2..]
33988 } else if path.starts_with('$') {
33989 &path[1..]
33990 } else {
33991 path
33992 };
33993 if path.is_empty() {
33994 return parts;
33995 }
33996 let mut current = String::new();
33997 let chars: Vec<char> = path.chars().collect();
33998 let mut i = 0;
33999 while i < chars.len() {
34000 match chars[i] {
34001 '.' => {
34002 if !current.is_empty() {
34003 parts.push(current.clone());
34004 current.clear();
34005 }
34006 i += 1;
34007 }
34008 '[' => {
34009 if !current.is_empty() {
34010 parts.push(current.clone());
34011 current.clear();
34012 }
34013 i += 1;
34014 let mut bracket_content = String::new();
34016 while i < chars.len() && chars[i] != ']' {
34017 if chars[i] == '"' || chars[i] == '\'' {
34019 let quote = chars[i];
34020 i += 1;
34021 while i < chars.len() && chars[i] != quote {
34022 bracket_content.push(chars[i]);
34023 i += 1;
34024 }
34025 if i < chars.len() {
34026 i += 1;
34027 } } else {
34029 bracket_content.push(chars[i]);
34030 i += 1;
34031 }
34032 }
34033 if i < chars.len() {
34034 i += 1;
34035 } if bracket_content != "*" {
34038 parts.push(bracket_content);
34039 }
34040 }
34041 _ => {
34042 current.push(chars[i]);
34043 i += 1;
34044 }
34045 }
34046 }
34047 if !current.is_empty() {
34048 parts.push(current);
34049 }
34050 parts
34051 }
34052
34053 fn strftime_to_postgres_format(fmt: &str) -> String {
34055 let mut result = String::with_capacity(fmt.len() * 2);
34056 let bytes = fmt.as_bytes();
34057 let len = bytes.len();
34058 let mut i = 0;
34059 while i < len {
34060 if bytes[i] == b'%' && i + 1 < len {
34061 if bytes[i + 1] == b'-' && i + 2 < len {
34063 let replacement = match bytes[i + 2] {
34064 b'd' => "FMDD",
34065 b'm' => "FMMM",
34066 b'H' => "FMHH24",
34067 b'M' => "FMMI",
34068 b'S' => "FMSS",
34069 _ => {
34070 result.push('%');
34071 i += 1;
34072 continue;
34073 }
34074 };
34075 result.push_str(replacement);
34076 i += 3;
34077 } else {
34078 let replacement = match bytes[i + 1] {
34079 b'Y' => "YYYY",
34080 b'y' => "YY",
34081 b'm' => "MM",
34082 b'B' => "Month",
34083 b'b' => "Mon",
34084 b'd' => "DD",
34085 b'j' => "DDD",
34086 b'H' => "HH24",
34087 b'M' => "MI",
34088 b'S' => "SS",
34089 b'f' => "US",
34090 b'A' => "Day",
34091 b'a' => "Dy",
34092 _ => {
34093 result.push('%');
34094 i += 1;
34095 continue;
34096 }
34097 };
34098 result.push_str(replacement);
34099 i += 2;
34100 }
34101 } else {
34102 result.push(bytes[i] as char);
34103 i += 1;
34104 }
34105 }
34106 result
34107 }
34108
34109 fn strftime_to_snowflake_format(fmt: &str) -> String {
34111 let mut result = String::with_capacity(fmt.len() * 2);
34112 let bytes = fmt.as_bytes();
34113 let len = bytes.len();
34114 let mut i = 0;
34115 while i < len {
34116 if bytes[i] == b'%' && i + 1 < len {
34117 if bytes[i + 1] == b'-' && i + 2 < len {
34119 let replacement = match bytes[i + 2] {
34120 b'd' => "dd",
34121 b'm' => "mm",
34122 _ => {
34123 result.push('%');
34124 i += 1;
34125 continue;
34126 }
34127 };
34128 result.push_str(replacement);
34129 i += 3;
34130 } else {
34131 let replacement = match bytes[i + 1] {
34132 b'Y' => "yyyy",
34133 b'y' => "yy",
34134 b'm' => "mm",
34135 b'd' => "DD",
34136 b'H' => "hh24",
34137 b'M' => "mi",
34138 b'S' => "ss",
34139 b'f' => "ff",
34140 _ => {
34141 result.push('%');
34142 i += 1;
34143 continue;
34144 }
34145 };
34146 result.push_str(replacement);
34147 i += 2;
34148 }
34149 } else {
34150 result.push(bytes[i] as char);
34151 i += 1;
34152 }
34153 }
34154 result
34155 }
34156
34157 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
34158 self.write_keyword("STR_TO_MAP");
34160 self.write("(");
34161 self.generate_expression(&e.this)?;
34162 let needs_defaults = matches!(
34164 self.config.dialect,
34165 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
34166 );
34167 if let Some(pair_delim) = &e.pair_delim {
34168 self.write(", ");
34169 self.generate_expression(pair_delim)?;
34170 } else if needs_defaults {
34171 self.write(", ','");
34172 }
34173 if let Some(key_value_delim) = &e.key_value_delim {
34174 self.write(", ");
34175 self.generate_expression(key_value_delim)?;
34176 } else if needs_defaults {
34177 self.write(", ':'");
34178 }
34179 self.write(")");
34180 Ok(())
34181 }
34182
34183 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
34184 let is_strftime = e.format.contains('%');
34186 let to_strftime = |f: &str| -> String {
34188 if is_strftime {
34189 f.to_string()
34190 } else {
34191 Self::snowflake_format_to_strftime(f)
34192 }
34193 };
34194 let to_java = |f: &str| -> String {
34196 if is_strftime {
34197 Self::strftime_to_java_format(f)
34198 } else {
34199 Self::snowflake_format_to_spark(f)
34200 }
34201 };
34202 let to_pg = |f: &str| -> String {
34204 if is_strftime {
34205 Self::strftime_to_postgres_format(f)
34206 } else {
34207 Self::convert_strptime_to_postgres_format(f)
34208 }
34209 };
34210
34211 match self.config.dialect {
34212 Some(DialectType::Exasol) => {
34213 self.write_keyword("TO_DATE");
34214 self.write("(");
34215 self.generate_expression(&e.this)?;
34216 self.write(", '");
34217 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
34218 self.write("'");
34219 self.write(")");
34220 }
34221 Some(DialectType::BigQuery) => {
34222 let fmt = to_strftime(&e.format);
34224 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
34226 self.write_keyword("PARSE_TIMESTAMP");
34227 self.write("('");
34228 self.write(&fmt);
34229 self.write("', ");
34230 self.generate_expression(&e.this)?;
34231 self.write(")");
34232 }
34233 Some(DialectType::Hive) => {
34234 let java_fmt = to_java(&e.format);
34237 if java_fmt == "yyyy-MM-dd HH:mm:ss"
34238 || java_fmt == "yyyy-MM-dd"
34239 || e.format == "yyyy-MM-dd HH:mm:ss"
34240 || e.format == "yyyy-MM-dd"
34241 {
34242 self.write_keyword("CAST");
34243 self.write("(");
34244 self.generate_expression(&e.this)?;
34245 self.write(" ");
34246 self.write_keyword("AS TIMESTAMP");
34247 self.write(")");
34248 } else {
34249 self.write_keyword("CAST");
34251 self.write("(");
34252 self.write_keyword("FROM_UNIXTIME");
34253 self.write("(");
34254 self.write_keyword("UNIX_TIMESTAMP");
34255 self.write("(");
34256 self.generate_expression(&e.this)?;
34257 self.write(", '");
34258 self.write(&java_fmt);
34259 self.write("')");
34260 self.write(") ");
34261 self.write_keyword("AS TIMESTAMP");
34262 self.write(")");
34263 }
34264 }
34265 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
34266 let java_fmt = to_java(&e.format);
34268 self.write_keyword("TO_TIMESTAMP");
34269 self.write("(");
34270 self.generate_expression(&e.this)?;
34271 self.write(", '");
34272 self.write(&java_fmt);
34273 self.write("')");
34274 }
34275 Some(DialectType::MySQL) => {
34276 let mut fmt = to_strftime(&e.format);
34278 fmt = fmt.replace("%-d", "%e");
34280 fmt = fmt.replace("%-m", "%c");
34281 fmt = fmt.replace("%H:%M:%S", "%T");
34282 self.write_keyword("STR_TO_DATE");
34283 self.write("(");
34284 self.generate_expression(&e.this)?;
34285 self.write(", '");
34286 self.write(&fmt);
34287 self.write("')");
34288 }
34289 Some(DialectType::Drill) => {
34290 let java_fmt = to_java(&e.format);
34292 let java_fmt = java_fmt.replace('T', "''T''");
34294 self.write_keyword("TO_TIMESTAMP");
34295 self.write("(");
34296 self.generate_expression(&e.this)?;
34297 self.write(", '");
34298 self.write(&java_fmt);
34299 self.write("')");
34300 }
34301 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
34302 let mut fmt = to_strftime(&e.format);
34304 fmt = fmt.replace("%-d", "%e");
34306 fmt = fmt.replace("%-m", "%c");
34307 fmt = fmt.replace("%H:%M:%S", "%T");
34308 self.write_keyword("DATE_PARSE");
34309 self.write("(");
34310 self.generate_expression(&e.this)?;
34311 self.write(", '");
34312 self.write(&fmt);
34313 self.write("')");
34314 }
34315 Some(DialectType::DuckDB) => {
34316 let fmt = to_strftime(&e.format);
34318 self.write_keyword("STRPTIME");
34319 self.write("(");
34320 self.generate_expression(&e.this)?;
34321 self.write(", '");
34322 self.write(&fmt);
34323 self.write("')");
34324 }
34325 Some(DialectType::PostgreSQL)
34326 | Some(DialectType::Redshift)
34327 | Some(DialectType::Materialize) => {
34328 let pg_fmt = to_pg(&e.format);
34330 self.write_keyword("TO_TIMESTAMP");
34331 self.write("(");
34332 self.generate_expression(&e.this)?;
34333 self.write(", '");
34334 self.write(&pg_fmt);
34335 self.write("')");
34336 }
34337 Some(DialectType::Oracle) => {
34338 let pg_fmt = to_pg(&e.format);
34340 self.write_keyword("TO_TIMESTAMP");
34341 self.write("(");
34342 self.generate_expression(&e.this)?;
34343 self.write(", '");
34344 self.write(&pg_fmt);
34345 self.write("')");
34346 }
34347 Some(DialectType::Snowflake) => {
34348 self.write_keyword("TO_TIMESTAMP");
34350 self.write("(");
34351 self.generate_expression(&e.this)?;
34352 self.write(", '");
34353 self.write(&e.format);
34354 self.write("')");
34355 }
34356 _ => {
34357 self.write_keyword("STR_TO_TIME");
34359 self.write("(");
34360 self.generate_expression(&e.this)?;
34361 self.write(", '");
34362 self.write(&e.format);
34363 self.write("'");
34364 self.write(")");
34365 }
34366 }
34367 Ok(())
34368 }
34369
34370 fn snowflake_format_to_strftime(format: &str) -> String {
34372 let mut result = String::new();
34373 let chars: Vec<char> = format.chars().collect();
34374 let mut i = 0;
34375 while i < chars.len() {
34376 let remaining = &format[i..];
34377 if remaining.starts_with("yyyy") {
34378 result.push_str("%Y");
34379 i += 4;
34380 } else if remaining.starts_with("yy") {
34381 result.push_str("%y");
34382 i += 2;
34383 } else if remaining.starts_with("mmmm") {
34384 result.push_str("%B"); i += 4;
34386 } else if remaining.starts_with("mon") {
34387 result.push_str("%b"); i += 3;
34389 } else if remaining.starts_with("mm") {
34390 result.push_str("%m");
34391 i += 2;
34392 } else if remaining.starts_with("DD") {
34393 result.push_str("%d");
34394 i += 2;
34395 } else if remaining.starts_with("dy") {
34396 result.push_str("%a"); i += 2;
34398 } else if remaining.starts_with("hh24") {
34399 result.push_str("%H");
34400 i += 4;
34401 } else if remaining.starts_with("hh12") {
34402 result.push_str("%I");
34403 i += 4;
34404 } else if remaining.starts_with("hh") {
34405 result.push_str("%H");
34406 i += 2;
34407 } else if remaining.starts_with("mi") {
34408 result.push_str("%M");
34409 i += 2;
34410 } else if remaining.starts_with("ss") {
34411 result.push_str("%S");
34412 i += 2;
34413 } else if remaining.starts_with("ff") {
34414 result.push_str("%f");
34416 i += 2;
34417 while i < chars.len() && chars[i].is_ascii_digit() {
34419 i += 1;
34420 }
34421 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
34422 result.push_str("%p");
34423 i += 2;
34424 } else if remaining.starts_with("tz") {
34425 result.push_str("%Z");
34426 i += 2;
34427 } else {
34428 result.push(chars[i]);
34429 i += 1;
34430 }
34431 }
34432 result
34433 }
34434
34435 fn snowflake_format_to_spark(format: &str) -> String {
34437 let mut result = String::new();
34438 let chars: Vec<char> = format.chars().collect();
34439 let mut i = 0;
34440 while i < chars.len() {
34441 let remaining = &format[i..];
34442 if remaining.starts_with("yyyy") {
34443 result.push_str("yyyy");
34444 i += 4;
34445 } else if remaining.starts_with("yy") {
34446 result.push_str("yy");
34447 i += 2;
34448 } else if remaining.starts_with("mmmm") {
34449 result.push_str("MMMM"); i += 4;
34451 } else if remaining.starts_with("mon") {
34452 result.push_str("MMM"); i += 3;
34454 } else if remaining.starts_with("mm") {
34455 result.push_str("MM");
34456 i += 2;
34457 } else if remaining.starts_with("DD") {
34458 result.push_str("dd");
34459 i += 2;
34460 } else if remaining.starts_with("dy") {
34461 result.push_str("EEE"); i += 2;
34463 } else if remaining.starts_with("hh24") {
34464 result.push_str("HH");
34465 i += 4;
34466 } else if remaining.starts_with("hh12") {
34467 result.push_str("hh");
34468 i += 4;
34469 } else if remaining.starts_with("hh") {
34470 result.push_str("HH");
34471 i += 2;
34472 } else if remaining.starts_with("mi") {
34473 result.push_str("mm");
34474 i += 2;
34475 } else if remaining.starts_with("ss") {
34476 result.push_str("ss");
34477 i += 2;
34478 } else if remaining.starts_with("ff") {
34479 result.push_str("SSS"); i += 2;
34481 while i < chars.len() && chars[i].is_ascii_digit() {
34483 i += 1;
34484 }
34485 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
34486 result.push_str("a");
34487 i += 2;
34488 } else if remaining.starts_with("tz") {
34489 result.push_str("z");
34490 i += 2;
34491 } else {
34492 result.push(chars[i]);
34493 i += 1;
34494 }
34495 }
34496 result
34497 }
34498
34499 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
34500 match self.config.dialect {
34501 Some(DialectType::DuckDB) => {
34502 self.write_keyword("EPOCH");
34504 self.write("(");
34505 self.write_keyword("STRPTIME");
34506 self.write("(");
34507 if let Some(this) = &e.this {
34508 self.generate_expression(this)?;
34509 }
34510 if let Some(format) = &e.format {
34511 self.write(", '");
34512 self.write(format);
34513 self.write("'");
34514 }
34515 self.write("))");
34516 }
34517 Some(DialectType::Hive) => {
34518 self.write_keyword("UNIX_TIMESTAMP");
34520 self.write("(");
34521 if let Some(this) = &e.this {
34522 self.generate_expression(this)?;
34523 }
34524 if let Some(format) = &e.format {
34525 let java_fmt = Self::strftime_to_java_format(format);
34526 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
34527 self.write(", '");
34528 self.write(&java_fmt);
34529 self.write("'");
34530 }
34531 }
34532 self.write(")");
34533 }
34534 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
34535 self.write_keyword("UNIX_TIMESTAMP");
34537 self.write("(");
34538 if let Some(this) = &e.this {
34539 self.generate_expression(this)?;
34540 }
34541 if let Some(format) = &e.format {
34542 self.write(", '");
34543 self.write(format);
34544 self.write("'");
34545 }
34546 self.write(")");
34547 }
34548 Some(DialectType::Presto) | Some(DialectType::Trino) => {
34549 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
34552 let java_fmt = Self::strftime_to_java_format(c_fmt);
34553 self.write_keyword("TO_UNIXTIME");
34554 self.write("(");
34555 self.write_keyword("COALESCE");
34556 self.write("(");
34557 self.write_keyword("TRY");
34558 self.write("(");
34559 self.write_keyword("DATE_PARSE");
34560 self.write("(");
34561 self.write_keyword("CAST");
34562 self.write("(");
34563 if let Some(this) = &e.this {
34564 self.generate_expression(this)?;
34565 }
34566 self.write(" ");
34567 self.write_keyword("AS VARCHAR");
34568 self.write("), '");
34569 self.write(c_fmt);
34570 self.write("')), ");
34571 self.write_keyword("PARSE_DATETIME");
34572 self.write("(");
34573 self.write_keyword("DATE_FORMAT");
34574 self.write("(");
34575 self.write_keyword("CAST");
34576 self.write("(");
34577 if let Some(this) = &e.this {
34578 self.generate_expression(this)?;
34579 }
34580 self.write(" ");
34581 self.write_keyword("AS TIMESTAMP");
34582 self.write("), '");
34583 self.write(c_fmt);
34584 self.write("'), '");
34585 self.write(&java_fmt);
34586 self.write("')))");
34587 }
34588 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
34589 self.write_keyword("UNIX_TIMESTAMP");
34591 self.write("(");
34592 if let Some(this) = &e.this {
34593 self.generate_expression(this)?;
34594 }
34595 if let Some(format) = &e.format {
34596 let java_fmt = Self::strftime_to_java_format(format);
34597 self.write(", '");
34598 self.write(&java_fmt);
34599 self.write("'");
34600 }
34601 self.write(")");
34602 }
34603 _ => {
34604 self.write_keyword("STR_TO_UNIX");
34606 self.write("(");
34607 if let Some(this) = &e.this {
34608 self.generate_expression(this)?;
34609 }
34610 if let Some(format) = &e.format {
34611 self.write(", '");
34612 self.write(format);
34613 self.write("'");
34614 }
34615 self.write(")");
34616 }
34617 }
34618 Ok(())
34619 }
34620
34621 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
34622 self.write_keyword("STRING_TO_ARRAY");
34624 self.write("(");
34625 self.generate_expression(&e.this)?;
34626 if let Some(expression) = &e.expression {
34627 self.write(", ");
34628 self.generate_expression(expression)?;
34629 }
34630 if let Some(null_val) = &e.null {
34631 self.write(", ");
34632 self.generate_expression(null_val)?;
34633 }
34634 self.write(")");
34635 Ok(())
34636 }
34637
34638 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
34639 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
34640 self.write_keyword("OBJECT_CONSTRUCT");
34642 self.write("(");
34643 for (i, (name, expr)) in e.fields.iter().enumerate() {
34644 if i > 0 {
34645 self.write(", ");
34646 }
34647 if let Some(name) = name {
34648 self.write("'");
34649 self.write(name);
34650 self.write("'");
34651 self.write(", ");
34652 } else {
34653 self.write("'_");
34654 self.write(&i.to_string());
34655 self.write("'");
34656 self.write(", ");
34657 }
34658 self.generate_expression(expr)?;
34659 }
34660 self.write(")");
34661 } else if self.config.struct_curly_brace_notation {
34662 self.write("{");
34664 for (i, (name, expr)) in e.fields.iter().enumerate() {
34665 if i > 0 {
34666 self.write(", ");
34667 }
34668 if let Some(name) = name {
34669 self.write("'");
34671 self.write(name);
34672 self.write("'");
34673 self.write(": ");
34674 } else {
34675 self.write("'_");
34677 self.write(&i.to_string());
34678 self.write("'");
34679 self.write(": ");
34680 }
34681 self.generate_expression(expr)?;
34682 }
34683 self.write("}");
34684 } else {
34685 let value_as_name = matches!(
34689 self.config.dialect,
34690 Some(DialectType::BigQuery)
34691 | Some(DialectType::Spark)
34692 | Some(DialectType::Databricks)
34693 | Some(DialectType::Hive)
34694 );
34695 self.write_keyword("STRUCT");
34696 self.write("(");
34697 for (i, (name, expr)) in e.fields.iter().enumerate() {
34698 if i > 0 {
34699 self.write(", ");
34700 }
34701 if let Some(name) = name {
34702 if value_as_name {
34703 self.generate_expression(expr)?;
34705 self.write_space();
34706 self.write_keyword("AS");
34707 self.write_space();
34708 let needs_quoting = name.contains(' ') || name.contains('-');
34710 if needs_quoting {
34711 if matches!(
34712 self.config.dialect,
34713 Some(DialectType::Spark)
34714 | Some(DialectType::Databricks)
34715 | Some(DialectType::Hive)
34716 ) {
34717 self.write("`");
34718 self.write(name);
34719 self.write("`");
34720 } else {
34721 self.write(name);
34722 }
34723 } else {
34724 self.write(name);
34725 }
34726 } else {
34727 self.write(name);
34729 self.write_space();
34730 self.write_keyword("AS");
34731 self.write_space();
34732 self.generate_expression(expr)?;
34733 }
34734 } else {
34735 self.generate_expression(expr)?;
34736 }
34737 }
34738 self.write(")");
34739 }
34740 Ok(())
34741 }
34742
34743 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
34744 self.write_keyword("STUFF");
34746 self.write("(");
34747 self.generate_expression(&e.this)?;
34748 if let Some(start) = &e.start {
34749 self.write(", ");
34750 self.generate_expression(start)?;
34751 }
34752 if let Some(length) = e.length {
34753 self.write(", ");
34754 self.write(&length.to_string());
34755 }
34756 self.write(", ");
34757 self.generate_expression(&e.expression)?;
34758 self.write(")");
34759 Ok(())
34760 }
34761
34762 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
34763 self.write_keyword("SUBSTRING_INDEX");
34765 self.write("(");
34766 self.generate_expression(&e.this)?;
34767 if let Some(delimiter) = &e.delimiter {
34768 self.write(", ");
34769 self.generate_expression(delimiter)?;
34770 }
34771 if let Some(count) = &e.count {
34772 self.write(", ");
34773 self.generate_expression(count)?;
34774 }
34775 self.write(")");
34776 Ok(())
34777 }
34778
34779 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
34780 self.write_keyword("SUMMARIZE");
34782 if e.table.is_some() {
34783 self.write_space();
34784 self.write_keyword("TABLE");
34785 }
34786 self.write_space();
34787 self.generate_expression(&e.this)?;
34788 Ok(())
34789 }
34790
34791 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
34792 self.write_keyword("SYSTIMESTAMP");
34794 Ok(())
34795 }
34796
34797 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
34798 if let Some(this) = &e.this {
34800 self.generate_expression(this)?;
34801 }
34802 if !e.columns.is_empty() {
34803 self.write("(");
34804 for (i, col) in e.columns.iter().enumerate() {
34805 if i > 0 {
34806 self.write(", ");
34807 }
34808 self.generate_expression(col)?;
34809 }
34810 self.write(")");
34811 }
34812 Ok(())
34813 }
34814
34815 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
34816 self.write_keyword("TABLE");
34818 self.write("(");
34819 self.generate_expression(&e.this)?;
34820 self.write(")");
34821 if let Some(alias) = &e.alias {
34822 self.write_space();
34823 self.write_keyword("AS");
34824 self.write_space();
34825 self.write(alias);
34826 }
34827 Ok(())
34828 }
34829
34830 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
34831 self.write_keyword("ROWS FROM");
34833 self.write(" (");
34834 for (i, expr) in e.expressions.iter().enumerate() {
34835 if i > 0 {
34836 self.write(", ");
34837 }
34838 match expr {
34842 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
34843 self.generate_expression(&tuple.expressions[0])?;
34845 self.write_space();
34846 self.write_keyword("AS");
34847 self.write_space();
34848 self.generate_expression(&tuple.expressions[1])?;
34849 }
34850 _ => {
34851 self.generate_expression(expr)?;
34852 }
34853 }
34854 }
34855 self.write(")");
34856 if e.ordinality {
34857 self.write_space();
34858 self.write_keyword("WITH ORDINALITY");
34859 }
34860 if let Some(alias) = &e.alias {
34861 self.write_space();
34862 self.write_keyword("AS");
34863 self.write_space();
34864 self.generate_expression(alias)?;
34865 }
34866 Ok(())
34867 }
34868
34869 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
34870 use crate::dialects::DialectType;
34871
34872 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
34874 if self.config.alias_post_tablesample {
34876 if let Expression::Subquery(ref s) = **this {
34878 if let Some(ref alias) = s.alias {
34879 let mut subquery_no_alias = (**s).clone();
34881 subquery_no_alias.alias = None;
34882 subquery_no_alias.column_aliases = Vec::new();
34883 self.generate_expression(&Expression::Subquery(Box::new(
34884 subquery_no_alias,
34885 )))?;
34886 self.write_space();
34887 self.write_keyword("TABLESAMPLE");
34888 self.generate_sample_body(sample)?;
34889 if let Some(ref seed) = sample.seed {
34890 self.write_space();
34891 let use_seed = sample.use_seed_keyword
34892 && !matches!(
34893 self.config.dialect,
34894 Some(crate::dialects::DialectType::Databricks)
34895 | Some(crate::dialects::DialectType::Spark)
34896 );
34897 if use_seed {
34898 self.write_keyword("SEED");
34899 } else {
34900 self.write_keyword("REPEATABLE");
34901 }
34902 self.write(" (");
34903 self.generate_expression(seed)?;
34904 self.write(")");
34905 }
34906 self.write_space();
34907 self.write_keyword("AS");
34908 self.write_space();
34909 self.generate_identifier(alias)?;
34910 return Ok(());
34911 }
34912 } else if let Expression::Alias(ref a) = **this {
34913 self.generate_expression(&a.this)?;
34915 self.write_space();
34916 self.write_keyword("TABLESAMPLE");
34917 self.generate_sample_body(sample)?;
34918 if let Some(ref seed) = sample.seed {
34919 self.write_space();
34920 let use_seed = sample.use_seed_keyword
34921 && !matches!(
34922 self.config.dialect,
34923 Some(crate::dialects::DialectType::Databricks)
34924 | Some(crate::dialects::DialectType::Spark)
34925 );
34926 if use_seed {
34927 self.write_keyword("SEED");
34928 } else {
34929 self.write_keyword("REPEATABLE");
34930 }
34931 self.write(" (");
34932 self.generate_expression(seed)?;
34933 self.write(")");
34934 }
34935 self.write_space();
34937 self.write_keyword("AS");
34938 self.write_space();
34939 self.generate_identifier(&a.alias)?;
34940 return Ok(());
34941 }
34942 }
34943 self.generate_expression(this)?;
34945 self.write_space();
34946 self.write_keyword("TABLESAMPLE");
34947 self.generate_sample_body(sample)?;
34948 if let Some(ref seed) = sample.seed {
34950 self.write_space();
34951 let use_seed = sample.use_seed_keyword
34953 && !matches!(
34954 self.config.dialect,
34955 Some(crate::dialects::DialectType::Databricks)
34956 | Some(crate::dialects::DialectType::Spark)
34957 );
34958 if use_seed {
34959 self.write_keyword("SEED");
34960 } else {
34961 self.write_keyword("REPEATABLE");
34962 }
34963 self.write(" (");
34964 self.generate_expression(seed)?;
34965 self.write(")");
34966 }
34967 return Ok(());
34968 }
34969
34970 self.write_keyword("TABLESAMPLE");
34972 if let Some(method) = &e.method {
34973 self.write_space();
34974 self.write_keyword(method);
34975 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
34976 self.write_space();
34978 self.write_keyword("BERNOULLI");
34979 }
34980 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
34981 self.write_space();
34982 self.write_keyword("BUCKET");
34983 self.write_space();
34984 self.generate_expression(numerator)?;
34985 self.write_space();
34986 self.write_keyword("OUT OF");
34987 self.write_space();
34988 self.generate_expression(denominator)?;
34989 if let Some(field) = &e.bucket_field {
34990 self.write_space();
34991 self.write_keyword("ON");
34992 self.write_space();
34993 self.generate_expression(field)?;
34994 }
34995 } else if !e.expressions.is_empty() {
34996 self.write(" (");
34997 for (i, expr) in e.expressions.iter().enumerate() {
34998 if i > 0 {
34999 self.write(", ");
35000 }
35001 self.generate_expression(expr)?;
35002 }
35003 self.write(")");
35004 } else if let Some(percent) = &e.percent {
35005 self.write(" (");
35006 self.generate_expression(percent)?;
35007 self.write_space();
35008 self.write_keyword("PERCENT");
35009 self.write(")");
35010 }
35011 Ok(())
35012 }
35013
35014 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
35015 if let Some(prefix) = &e.prefix {
35017 self.generate_expression(prefix)?;
35018 }
35019 if let Some(this) = &e.this {
35020 self.generate_expression(this)?;
35021 }
35022 if let Some(postfix) = &e.postfix {
35023 self.generate_expression(postfix)?;
35024 }
35025 Ok(())
35026 }
35027
35028 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
35029 self.write_keyword("TAG");
35031 self.write(" (");
35032 for (i, expr) in e.expressions.iter().enumerate() {
35033 if i > 0 {
35034 self.write(", ");
35035 }
35036 self.generate_expression(expr)?;
35037 }
35038 self.write(")");
35039 Ok(())
35040 }
35041
35042 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
35043 if let Some(this) = &e.this {
35045 self.generate_expression(this)?;
35046 self.write_space();
35047 }
35048 self.write_keyword("TEMPORARY");
35049 Ok(())
35050 }
35051
35052 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
35055 self.write_keyword("TIME");
35057 self.write("(");
35058 self.generate_expression(&e.this)?;
35059 self.write(")");
35060 Ok(())
35061 }
35062
35063 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
35064 self.write_keyword("TIME_ADD");
35066 self.write("(");
35067 self.generate_expression(&e.this)?;
35068 self.write(", ");
35069 self.generate_expression(&e.expression)?;
35070 if let Some(unit) = &e.unit {
35071 self.write(", ");
35072 self.write_keyword(unit);
35073 }
35074 self.write(")");
35075 Ok(())
35076 }
35077
35078 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
35079 self.write_keyword("TIME_DIFF");
35081 self.write("(");
35082 self.generate_expression(&e.this)?;
35083 self.write(", ");
35084 self.generate_expression(&e.expression)?;
35085 if let Some(unit) = &e.unit {
35086 self.write(", ");
35087 self.write_keyword(unit);
35088 }
35089 self.write(")");
35090 Ok(())
35091 }
35092
35093 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
35094 self.write_keyword("TIME_FROM_PARTS");
35096 self.write("(");
35097 let mut first = true;
35098 if let Some(hour) = &e.hour {
35099 self.generate_expression(hour)?;
35100 first = false;
35101 }
35102 if let Some(minute) = &e.min {
35103 if !first {
35104 self.write(", ");
35105 }
35106 self.generate_expression(minute)?;
35107 first = false;
35108 }
35109 if let Some(second) = &e.sec {
35110 if !first {
35111 self.write(", ");
35112 }
35113 self.generate_expression(second)?;
35114 first = false;
35115 }
35116 if let Some(ns) = &e.nano {
35117 if !first {
35118 self.write(", ");
35119 }
35120 self.generate_expression(ns)?;
35121 }
35122 self.write(")");
35123 Ok(())
35124 }
35125
35126 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
35127 self.write_keyword("TIME_SLICE");
35129 self.write("(");
35130 self.generate_expression(&e.this)?;
35131 self.write(", ");
35132 self.generate_expression(&e.expression)?;
35133 self.write(", ");
35134 self.write_keyword(&e.unit);
35135 self.write(")");
35136 Ok(())
35137 }
35138
35139 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
35140 self.write_keyword("TIME_STR_TO_TIME");
35142 self.write("(");
35143 self.generate_expression(&e.this)?;
35144 self.write(")");
35145 Ok(())
35146 }
35147
35148 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
35149 self.write_keyword("TIME_SUB");
35151 self.write("(");
35152 self.generate_expression(&e.this)?;
35153 self.write(", ");
35154 self.generate_expression(&e.expression)?;
35155 if let Some(unit) = &e.unit {
35156 self.write(", ");
35157 self.write_keyword(unit);
35158 }
35159 self.write(")");
35160 Ok(())
35161 }
35162
35163 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
35164 match self.config.dialect {
35165 Some(DialectType::Exasol) => {
35166 self.write_keyword("TO_CHAR");
35168 self.write("(");
35169 self.generate_expression(&e.this)?;
35170 self.write(", '");
35171 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
35172 self.write("'");
35173 self.write(")");
35174 }
35175 Some(DialectType::PostgreSQL)
35176 | Some(DialectType::Redshift)
35177 | Some(DialectType::Materialize) => {
35178 self.write_keyword("TO_CHAR");
35180 self.write("(");
35181 self.generate_expression(&e.this)?;
35182 self.write(", '");
35183 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
35184 self.write("'");
35185 self.write(")");
35186 }
35187 Some(DialectType::Oracle) => {
35188 self.write_keyword("TO_CHAR");
35190 self.write("(");
35191 self.generate_expression(&e.this)?;
35192 self.write(", '");
35193 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
35194 self.write("'");
35195 self.write(")");
35196 }
35197 Some(DialectType::Drill) => {
35198 self.write_keyword("TO_CHAR");
35200 self.write("(");
35201 self.generate_expression(&e.this)?;
35202 self.write(", '");
35203 self.write(&Self::strftime_to_java_format(&e.format));
35204 self.write("'");
35205 self.write(")");
35206 }
35207 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
35208 self.write_keyword("FORMAT");
35210 self.write("(");
35211 self.generate_expression(&e.this)?;
35212 self.write(", '");
35213 self.write(&Self::strftime_to_tsql_format(&e.format));
35214 self.write("'");
35215 self.write(")");
35216 }
35217 Some(DialectType::DuckDB) => {
35218 self.write_keyword("STRFTIME");
35220 self.write("(");
35221 self.generate_expression(&e.this)?;
35222 self.write(", '");
35223 self.write(&e.format);
35224 self.write("'");
35225 self.write(")");
35226 }
35227 Some(DialectType::BigQuery) => {
35228 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
35231 self.write_keyword("FORMAT_DATE");
35232 self.write("('");
35233 self.write(&fmt);
35234 self.write("', ");
35235 self.generate_expression(&e.this)?;
35236 self.write(")");
35237 }
35238 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35239 self.write_keyword("DATE_FORMAT");
35241 self.write("(");
35242 self.generate_expression(&e.this)?;
35243 self.write(", '");
35244 self.write(&Self::strftime_to_java_format(&e.format));
35245 self.write("'");
35246 self.write(")");
35247 }
35248 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
35249 self.write_keyword("DATE_FORMAT");
35251 self.write("(");
35252 self.generate_expression(&e.this)?;
35253 self.write(", '");
35254 self.write(&e.format);
35255 self.write("'");
35256 self.write(")");
35257 }
35258 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35259 self.write_keyword("DATE_FORMAT");
35261 self.write("(");
35262 self.generate_expression(&e.this)?;
35263 self.write(", '");
35264 self.write(&e.format);
35265 self.write("'");
35266 self.write(")");
35267 }
35268 _ => {
35269 self.write_keyword("TIME_TO_STR");
35271 self.write("(");
35272 self.generate_expression(&e.this)?;
35273 self.write(", '");
35274 self.write(&e.format);
35275 self.write("'");
35276 self.write(")");
35277 }
35278 }
35279 Ok(())
35280 }
35281
35282 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
35283 match self.config.dialect {
35284 Some(DialectType::DuckDB) => {
35285 self.write_keyword("EPOCH");
35287 self.write("(");
35288 self.generate_expression(&e.this)?;
35289 self.write(")");
35290 }
35291 Some(DialectType::Hive)
35292 | Some(DialectType::Spark)
35293 | Some(DialectType::Databricks)
35294 | Some(DialectType::Doris)
35295 | Some(DialectType::StarRocks)
35296 | Some(DialectType::Drill) => {
35297 self.write_keyword("UNIX_TIMESTAMP");
35299 self.write("(");
35300 self.generate_expression(&e.this)?;
35301 self.write(")");
35302 }
35303 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35304 self.write_keyword("TO_UNIXTIME");
35306 self.write("(");
35307 self.generate_expression(&e.this)?;
35308 self.write(")");
35309 }
35310 _ => {
35311 self.write_keyword("TIME_TO_UNIX");
35313 self.write("(");
35314 self.generate_expression(&e.this)?;
35315 self.write(")");
35316 }
35317 }
35318 Ok(())
35319 }
35320
35321 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
35322 match self.config.dialect {
35323 Some(DialectType::Hive) => {
35324 self.write_keyword("TO_DATE");
35326 self.write("(");
35327 self.generate_expression(&e.this)?;
35328 self.write(")");
35329 }
35330 _ => {
35331 self.write_keyword("TIME_STR_TO_DATE");
35333 self.write("(");
35334 self.generate_expression(&e.this)?;
35335 self.write(")");
35336 }
35337 }
35338 Ok(())
35339 }
35340
35341 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
35342 self.write_keyword("TIME_TRUNC");
35344 self.write("(");
35345 self.generate_expression(&e.this)?;
35346 self.write(", ");
35347 self.write_keyword(&e.unit);
35348 self.write(")");
35349 Ok(())
35350 }
35351
35352 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
35353 if let Some(unit) = &e.unit {
35355 self.write_keyword(unit);
35356 }
35357 Ok(())
35358 }
35359
35360 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
35364 use crate::dialects::DialectType;
35365 use crate::expressions::Literal;
35366
35367 match self.config.dialect {
35368 Some(DialectType::Exasol) => {
35370 self.write_keyword("TO_TIMESTAMP");
35371 self.write("(");
35372 if let Some(this) = &e.this {
35374 match this.as_ref() {
35375 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
35376 let Literal::String(s) = lit.as_ref() else { unreachable!() };
35377 self.write("'");
35378 self.write(s);
35379 self.write("'");
35380 }
35381 _ => {
35382 self.generate_expression(this)?;
35383 }
35384 }
35385 }
35386 self.write(")");
35387 }
35388 _ => {
35390 self.write_keyword("TIMESTAMP");
35391 self.write("(");
35392 if let Some(this) = &e.this {
35393 self.generate_expression(this)?;
35394 }
35395 if let Some(zone) = &e.zone {
35396 self.write(", ");
35397 self.generate_expression(zone)?;
35398 }
35399 self.write(")");
35400 }
35401 }
35402 Ok(())
35403 }
35404
35405 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
35406 self.write_keyword("TIMESTAMP_ADD");
35408 self.write("(");
35409 self.generate_expression(&e.this)?;
35410 self.write(", ");
35411 self.generate_expression(&e.expression)?;
35412 if let Some(unit) = &e.unit {
35413 self.write(", ");
35414 self.write_keyword(unit);
35415 }
35416 self.write(")");
35417 Ok(())
35418 }
35419
35420 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
35421 self.write_keyword("TIMESTAMP_DIFF");
35423 self.write("(");
35424 self.generate_expression(&e.this)?;
35425 self.write(", ");
35426 self.generate_expression(&e.expression)?;
35427 if let Some(unit) = &e.unit {
35428 self.write(", ");
35429 self.write_keyword(unit);
35430 }
35431 self.write(")");
35432 Ok(())
35433 }
35434
35435 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
35436 self.write_keyword("TIMESTAMP_FROM_PARTS");
35438 self.write("(");
35439 if let Some(this) = &e.this {
35440 self.generate_expression(this)?;
35441 }
35442 if let Some(expression) = &e.expression {
35443 self.write(", ");
35444 self.generate_expression(expression)?;
35445 }
35446 if let Some(zone) = &e.zone {
35447 self.write(", ");
35448 self.generate_expression(zone)?;
35449 }
35450 if let Some(milli) = &e.milli {
35451 self.write(", ");
35452 self.generate_expression(milli)?;
35453 }
35454 self.write(")");
35455 Ok(())
35456 }
35457
35458 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
35459 self.write_keyword("TIMESTAMP_SUB");
35461 self.write("(");
35462 self.generate_expression(&e.this)?;
35463 self.write(", ");
35464 self.write_keyword("INTERVAL");
35465 self.write_space();
35466 self.generate_expression(&e.expression)?;
35467 if let Some(unit) = &e.unit {
35468 self.write_space();
35469 self.write_keyword(unit);
35470 }
35471 self.write(")");
35472 Ok(())
35473 }
35474
35475 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
35476 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
35478 self.write("(");
35479 if let Some(zone) = &e.zone {
35480 self.generate_expression(zone)?;
35481 }
35482 self.write(")");
35483 Ok(())
35484 }
35485
35486 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
35487 self.write_keyword("TO_BINARY");
35489 self.write("(");
35490 self.generate_expression(&e.this)?;
35491 if let Some(format) = &e.format {
35492 self.write(", '");
35493 self.write(format);
35494 self.write("'");
35495 }
35496 self.write(")");
35497 Ok(())
35498 }
35499
35500 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
35501 self.write_keyword("TO_BOOLEAN");
35503 self.write("(");
35504 self.generate_expression(&e.this)?;
35505 self.write(")");
35506 Ok(())
35507 }
35508
35509 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
35510 self.write_keyword("TO_CHAR");
35512 self.write("(");
35513 self.generate_expression(&e.this)?;
35514 if let Some(format) = &e.format {
35515 self.write(", '");
35516 self.write(format);
35517 self.write("'");
35518 }
35519 if let Some(nlsparam) = &e.nlsparam {
35520 self.write(", ");
35521 self.generate_expression(nlsparam)?;
35522 }
35523 self.write(")");
35524 Ok(())
35525 }
35526
35527 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
35528 self.write_keyword("TO_DECFLOAT");
35530 self.write("(");
35531 self.generate_expression(&e.this)?;
35532 if let Some(format) = &e.format {
35533 self.write(", '");
35534 self.write(format);
35535 self.write("'");
35536 }
35537 self.write(")");
35538 Ok(())
35539 }
35540
35541 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
35542 self.write_keyword("TO_DOUBLE");
35544 self.write("(");
35545 self.generate_expression(&e.this)?;
35546 if let Some(format) = &e.format {
35547 self.write(", '");
35548 self.write(format);
35549 self.write("'");
35550 }
35551 self.write(")");
35552 Ok(())
35553 }
35554
35555 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
35556 self.write_keyword("TO_FILE");
35558 self.write("(");
35559 self.generate_expression(&e.this)?;
35560 if let Some(path) = &e.path {
35561 self.write(", ");
35562 self.generate_expression(path)?;
35563 }
35564 self.write(")");
35565 Ok(())
35566 }
35567
35568 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
35569 let is_safe = e.safe.is_some();
35572 if is_safe {
35573 self.write_keyword("TRY_TO_NUMBER");
35574 } else {
35575 self.write_keyword("TO_NUMBER");
35576 }
35577 self.write("(");
35578 self.generate_expression(&e.this)?;
35579 if let Some(format) = &e.format {
35580 self.write(", ");
35581 self.generate_expression(format)?;
35582 }
35583 if let Some(nlsparam) = &e.nlsparam {
35584 self.write(", ");
35585 self.generate_expression(nlsparam)?;
35586 }
35587 if let Some(precision) = &e.precision {
35588 self.write(", ");
35589 self.generate_expression(precision)?;
35590 }
35591 if let Some(scale) = &e.scale {
35592 self.write(", ");
35593 self.generate_expression(scale)?;
35594 }
35595 self.write(")");
35596 Ok(())
35597 }
35598
35599 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
35600 self.write_keyword("TO_TABLE");
35602 self.write_space();
35603 self.generate_expression(&e.this)?;
35604 Ok(())
35605 }
35606
35607 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
35608 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
35610 Expression::Identifier(id) => id.name.clone(),
35611 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => { let Literal::String(s) = lit.as_ref() else { unreachable!() }; s.clone() },
35612 _ => String::new(),
35613 });
35614
35615 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
35616 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
35617 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
35618 matches!(m.as_ref(), Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)))
35619 });
35620
35621 let use_start_transaction = matches!(
35623 self.config.dialect,
35624 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
35625 );
35626 let strip_transaction = matches!(
35628 self.config.dialect,
35629 Some(DialectType::Snowflake)
35630 | Some(DialectType::PostgreSQL)
35631 | Some(DialectType::Redshift)
35632 | Some(DialectType::MySQL)
35633 | Some(DialectType::Hive)
35634 | Some(DialectType::Spark)
35635 | Some(DialectType::Databricks)
35636 | Some(DialectType::DuckDB)
35637 | Some(DialectType::Oracle)
35638 | Some(DialectType::Doris)
35639 | Some(DialectType::StarRocks)
35640 | Some(DialectType::Materialize)
35641 | Some(DialectType::ClickHouse)
35642 );
35643
35644 if is_start || use_start_transaction {
35645 self.write_keyword("START TRANSACTION");
35647 if let Some(modes) = &e.modes {
35648 self.write_space();
35649 self.generate_expression(modes)?;
35650 }
35651 } else {
35652 self.write_keyword("BEGIN");
35654
35655 let is_kind = e.this.as_ref().map_or(false, |t| {
35657 if let Expression::Identifier(id) = t.as_ref() {
35658 id.name.eq_ignore_ascii_case("DEFERRED")
35659 || id.name.eq_ignore_ascii_case("IMMEDIATE")
35660 || id.name.eq_ignore_ascii_case("EXCLUSIVE")
35661 } else {
35662 false
35663 }
35664 });
35665
35666 if is_kind {
35668 if let Some(this) = &e.this {
35669 self.write_space();
35670 if let Expression::Identifier(id) = this.as_ref() {
35671 self.write_keyword(&id.name);
35672 }
35673 }
35674 }
35675
35676 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
35678 self.write_space();
35679 self.write_keyword("TRANSACTION");
35680 }
35681
35682 if !is_kind {
35684 if let Some(this) = &e.this {
35685 self.write_space();
35686 self.generate_expression(this)?;
35687 }
35688 }
35689
35690 if has_with_mark {
35692 self.write_space();
35693 self.write_keyword("WITH MARK");
35694 if let Some(Expression::Literal(lit)) = e.mark.as_deref() {
35695 if let Literal::String(desc) = lit.as_ref() {
35696 if !desc.is_empty() {
35697 self.write_space();
35698 self.write(&format!("'{}'", desc));
35699 }
35700 }
35701 }
35702 }
35703
35704 if let Some(modes) = &e.modes {
35706 self.write_space();
35707 self.generate_expression(modes)?;
35708 }
35709 }
35710 Ok(())
35711 }
35712
35713 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
35714 self.write_keyword("TRANSFORM");
35716 self.write("(");
35717 self.generate_expression(&e.this)?;
35718 self.write(", ");
35719 self.generate_expression(&e.expression)?;
35720 self.write(")");
35721 Ok(())
35722 }
35723
35724 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
35725 self.write_keyword("TRANSFORM");
35727 self.write("(");
35728 if self.config.pretty && !e.expressions.is_empty() {
35729 self.indent_level += 1;
35730 for (i, expr) in e.expressions.iter().enumerate() {
35731 if i > 0 {
35732 self.write(",");
35733 }
35734 self.write_newline();
35735 self.write_indent();
35736 self.generate_expression(expr)?;
35737 }
35738 self.indent_level -= 1;
35739 self.write_newline();
35740 self.write(")");
35741 } else {
35742 for (i, expr) in e.expressions.iter().enumerate() {
35743 if i > 0 {
35744 self.write(", ");
35745 }
35746 self.generate_expression(expr)?;
35747 }
35748 self.write(")");
35749 }
35750 Ok(())
35751 }
35752
35753 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
35754 use crate::dialects::DialectType;
35755 if let Some(this) = &e.this {
35757 self.generate_expression(this)?;
35758 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
35759 self.write_space();
35760 }
35761 }
35762 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
35763 self.write_keyword("TRANSIENT");
35764 }
35765 Ok(())
35766 }
35767
35768 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
35769 self.write_keyword("TRANSLATE");
35771 self.write("(");
35772 self.generate_expression(&e.this)?;
35773 if let Some(from) = &e.from_ {
35774 self.write(", ");
35775 self.generate_expression(from)?;
35776 }
35777 if let Some(to) = &e.to {
35778 self.write(", ");
35779 self.generate_expression(to)?;
35780 }
35781 self.write(")");
35782 Ok(())
35783 }
35784
35785 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
35786 self.write_keyword("TRANSLATE");
35788 self.write("(");
35789 self.generate_expression(&e.this)?;
35790 self.write_space();
35791 self.write_keyword("USING");
35792 self.write_space();
35793 self.generate_expression(&e.expression)?;
35794 if e.with_error.is_some() {
35795 self.write_space();
35796 self.write_keyword("WITH ERROR");
35797 }
35798 self.write(")");
35799 Ok(())
35800 }
35801
35802 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
35803 self.write_keyword("TRUNCATE TABLE");
35805 self.write_space();
35806 for (i, expr) in e.expressions.iter().enumerate() {
35807 if i > 0 {
35808 self.write(", ");
35809 }
35810 self.generate_expression(expr)?;
35811 }
35812 Ok(())
35813 }
35814
35815 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
35816 self.write_keyword("TRY_BASE64_DECODE_BINARY");
35818 self.write("(");
35819 self.generate_expression(&e.this)?;
35820 if let Some(alphabet) = &e.alphabet {
35821 self.write(", ");
35822 self.generate_expression(alphabet)?;
35823 }
35824 self.write(")");
35825 Ok(())
35826 }
35827
35828 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
35829 self.write_keyword("TRY_BASE64_DECODE_STRING");
35831 self.write("(");
35832 self.generate_expression(&e.this)?;
35833 if let Some(alphabet) = &e.alphabet {
35834 self.write(", ");
35835 self.generate_expression(alphabet)?;
35836 }
35837 self.write(")");
35838 Ok(())
35839 }
35840
35841 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
35842 self.write_keyword("TRY_TO_DECFLOAT");
35844 self.write("(");
35845 self.generate_expression(&e.this)?;
35846 if let Some(format) = &e.format {
35847 self.write(", '");
35848 self.write(format);
35849 self.write("'");
35850 }
35851 self.write(")");
35852 Ok(())
35853 }
35854
35855 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
35856 self.write_keyword("TS_OR_DS_ADD");
35858 self.write("(");
35859 self.generate_expression(&e.this)?;
35860 self.write(", ");
35861 self.generate_expression(&e.expression)?;
35862 if let Some(unit) = &e.unit {
35863 self.write(", ");
35864 self.write_keyword(unit);
35865 }
35866 if let Some(return_type) = &e.return_type {
35867 self.write(", ");
35868 self.generate_expression(return_type)?;
35869 }
35870 self.write(")");
35871 Ok(())
35872 }
35873
35874 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
35875 self.write_keyword("TS_OR_DS_DIFF");
35877 self.write("(");
35878 self.generate_expression(&e.this)?;
35879 self.write(", ");
35880 self.generate_expression(&e.expression)?;
35881 if let Some(unit) = &e.unit {
35882 self.write(", ");
35883 self.write_keyword(unit);
35884 }
35885 self.write(")");
35886 Ok(())
35887 }
35888
35889 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
35890 let default_time_format = "%Y-%m-%d %H:%M:%S";
35891 let default_date_format = "%Y-%m-%d";
35892 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
35893 f != default_time_format && f != default_date_format
35894 });
35895
35896 if has_non_default_format {
35897 let fmt = e.format.as_ref().unwrap();
35899 match self.config.dialect {
35900 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
35901 let str_to_time = crate::expressions::StrToTime {
35904 this: Box::new((*e.this).clone()),
35905 format: fmt.clone(),
35906 zone: None,
35907 safe: None,
35908 target_type: None,
35909 };
35910 self.generate_str_to_time(&str_to_time)?;
35911 }
35912 Some(DialectType::Hive)
35913 | Some(DialectType::Spark)
35914 | Some(DialectType::Databricks) => {
35915 self.write_keyword("TO_DATE");
35917 self.write("(");
35918 self.generate_expression(&e.this)?;
35919 self.write(", '");
35920 self.write(&Self::strftime_to_java_format(fmt));
35921 self.write("')");
35922 }
35923 Some(DialectType::Snowflake) => {
35924 self.write_keyword("TO_DATE");
35926 self.write("(");
35927 self.generate_expression(&e.this)?;
35928 self.write(", '");
35929 self.write(&Self::strftime_to_snowflake_format(fmt));
35930 self.write("')");
35931 }
35932 Some(DialectType::Doris) => {
35933 self.write_keyword("TO_DATE");
35935 self.write("(");
35936 self.generate_expression(&e.this)?;
35937 self.write(")");
35938 }
35939 _ => {
35940 self.write_keyword("CAST");
35942 self.write("(");
35943 let str_to_time = crate::expressions::StrToTime {
35944 this: Box::new((*e.this).clone()),
35945 format: fmt.clone(),
35946 zone: None,
35947 safe: None,
35948 target_type: None,
35949 };
35950 self.generate_str_to_time(&str_to_time)?;
35951 self.write_keyword(" AS ");
35952 self.write_keyword("DATE");
35953 self.write(")");
35954 }
35955 }
35956 } else {
35957 match self.config.dialect {
35959 Some(DialectType::MySQL)
35960 | Some(DialectType::SQLite)
35961 | Some(DialectType::StarRocks) => {
35962 self.write_keyword("DATE");
35964 self.write("(");
35965 self.generate_expression(&e.this)?;
35966 self.write(")");
35967 }
35968 Some(DialectType::Hive)
35969 | Some(DialectType::Spark)
35970 | Some(DialectType::Databricks)
35971 | Some(DialectType::Snowflake)
35972 | Some(DialectType::Doris) => {
35973 self.write_keyword("TO_DATE");
35975 self.write("(");
35976 self.generate_expression(&e.this)?;
35977 self.write(")");
35978 }
35979 Some(DialectType::Presto)
35980 | Some(DialectType::Trino)
35981 | Some(DialectType::Athena) => {
35982 self.write_keyword("CAST");
35984 self.write("(");
35985 self.write_keyword("CAST");
35986 self.write("(");
35987 self.generate_expression(&e.this)?;
35988 self.write_keyword(" AS ");
35989 self.write_keyword("TIMESTAMP");
35990 self.write(")");
35991 self.write_keyword(" AS ");
35992 self.write_keyword("DATE");
35993 self.write(")");
35994 }
35995 Some(DialectType::ClickHouse) => {
35996 self.write_keyword("CAST");
35998 self.write("(");
35999 self.generate_expression(&e.this)?;
36000 self.write_keyword(" AS ");
36001 self.write("Nullable(DATE)");
36002 self.write(")");
36003 }
36004 _ => {
36005 self.write_keyword("CAST");
36007 self.write("(");
36008 self.generate_expression(&e.this)?;
36009 self.write_keyword(" AS ");
36010 self.write_keyword("DATE");
36011 self.write(")");
36012 }
36013 }
36014 }
36015 Ok(())
36016 }
36017
36018 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
36019 self.write_keyword("TS_OR_DS_TO_TIME");
36021 self.write("(");
36022 self.generate_expression(&e.this)?;
36023 if let Some(format) = &e.format {
36024 self.write(", '");
36025 self.write(format);
36026 self.write("'");
36027 }
36028 self.write(")");
36029 Ok(())
36030 }
36031
36032 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
36033 self.write_keyword("UNHEX");
36035 self.write("(");
36036 self.generate_expression(&e.this)?;
36037 if let Some(expression) = &e.expression {
36038 self.write(", ");
36039 self.generate_expression(expression)?;
36040 }
36041 self.write(")");
36042 Ok(())
36043 }
36044
36045 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
36046 self.write("U&");
36048 self.generate_expression(&e.this)?;
36049 if let Some(escape) = &e.escape {
36050 self.write_space();
36051 self.write_keyword("UESCAPE");
36052 self.write_space();
36053 self.generate_expression(escape)?;
36054 }
36055 Ok(())
36056 }
36057
36058 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
36059 self.write_keyword("UNIFORM");
36061 self.write("(");
36062 self.generate_expression(&e.this)?;
36063 self.write(", ");
36064 self.generate_expression(&e.expression)?;
36065 if let Some(gen) = &e.gen {
36066 self.write(", ");
36067 self.generate_expression(gen)?;
36068 }
36069 if let Some(seed) = &e.seed {
36070 self.write(", ");
36071 self.generate_expression(seed)?;
36072 }
36073 self.write(")");
36074 Ok(())
36075 }
36076
36077 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
36078 self.write_keyword("UNIQUE");
36080 if e.nulls.is_some() {
36082 self.write(" NULLS NOT DISTINCT");
36083 }
36084 if let Some(this) = &e.this {
36085 self.write_space();
36086 self.generate_expression(this)?;
36087 }
36088 if let Some(index_type) = &e.index_type {
36089 self.write(" USING ");
36090 self.generate_expression(index_type)?;
36091 }
36092 if let Some(on_conflict) = &e.on_conflict {
36093 self.write_space();
36094 self.generate_expression(on_conflict)?;
36095 }
36096 for opt in &e.options {
36097 self.write_space();
36098 self.generate_expression(opt)?;
36099 }
36100 Ok(())
36101 }
36102
36103 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
36104 self.write_keyword("UNIQUE KEY");
36106 self.write(" (");
36107 for (i, expr) in e.expressions.iter().enumerate() {
36108 if i > 0 {
36109 self.write(", ");
36110 }
36111 self.generate_expression(expr)?;
36112 }
36113 self.write(")");
36114 Ok(())
36115 }
36116
36117 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
36118 self.write_keyword("ROLLUP");
36120 self.write(" (");
36121 for (i, index) in e.expressions.iter().enumerate() {
36122 if i > 0 {
36123 self.write(", ");
36124 }
36125 self.generate_identifier(&index.name)?;
36126 self.write("(");
36127 for (j, col) in index.expressions.iter().enumerate() {
36128 if j > 0 {
36129 self.write(", ");
36130 }
36131 self.generate_identifier(col)?;
36132 }
36133 self.write(")");
36134 }
36135 self.write(")");
36136 Ok(())
36137 }
36138
36139 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
36140 match self.config.dialect {
36141 Some(DialectType::DuckDB) => {
36142 self.write_keyword("STRFTIME");
36144 self.write("(");
36145 self.write_keyword("TO_TIMESTAMP");
36146 self.write("(");
36147 self.generate_expression(&e.this)?;
36148 self.write("), '");
36149 if let Some(format) = &e.format {
36150 self.write(format);
36151 }
36152 self.write("')");
36153 }
36154 Some(DialectType::Hive) => {
36155 self.write_keyword("FROM_UNIXTIME");
36157 self.write("(");
36158 self.generate_expression(&e.this)?;
36159 if let Some(format) = &e.format {
36160 if format != "yyyy-MM-dd HH:mm:ss" {
36161 self.write(", '");
36162 self.write(format);
36163 self.write("'");
36164 }
36165 }
36166 self.write(")");
36167 }
36168 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36169 self.write_keyword("DATE_FORMAT");
36171 self.write("(");
36172 self.write_keyword("FROM_UNIXTIME");
36173 self.write("(");
36174 self.generate_expression(&e.this)?;
36175 self.write("), '");
36176 if let Some(format) = &e.format {
36177 self.write(format);
36178 }
36179 self.write("')");
36180 }
36181 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36182 self.write_keyword("FROM_UNIXTIME");
36184 self.write("(");
36185 self.generate_expression(&e.this)?;
36186 if let Some(format) = &e.format {
36187 self.write(", '");
36188 self.write(format);
36189 self.write("'");
36190 }
36191 self.write(")");
36192 }
36193 _ => {
36194 self.write_keyword("UNIX_TO_STR");
36196 self.write("(");
36197 self.generate_expression(&e.this)?;
36198 if let Some(format) = &e.format {
36199 self.write(", '");
36200 self.write(format);
36201 self.write("'");
36202 }
36203 self.write(")");
36204 }
36205 }
36206 Ok(())
36207 }
36208
36209 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
36210 use crate::dialects::DialectType;
36211 let scale = e.scale.unwrap_or(0); match self.config.dialect {
36214 Some(DialectType::Snowflake) => {
36215 self.write_keyword("TO_TIMESTAMP");
36217 self.write("(");
36218 self.generate_expression(&e.this)?;
36219 if let Some(s) = e.scale {
36220 if s > 0 {
36221 self.write(", ");
36222 self.write(&s.to_string());
36223 }
36224 }
36225 self.write(")");
36226 }
36227 Some(DialectType::BigQuery) => {
36228 match scale {
36231 0 => {
36232 self.write_keyword("TIMESTAMP_SECONDS");
36233 self.write("(");
36234 self.generate_expression(&e.this)?;
36235 self.write(")");
36236 }
36237 3 => {
36238 self.write_keyword("TIMESTAMP_MILLIS");
36239 self.write("(");
36240 self.generate_expression(&e.this)?;
36241 self.write(")");
36242 }
36243 6 => {
36244 self.write_keyword("TIMESTAMP_MICROS");
36245 self.write("(");
36246 self.generate_expression(&e.this)?;
36247 self.write(")");
36248 }
36249 _ => {
36250 self.write_keyword("TIMESTAMP_SECONDS");
36252 self.write("(CAST(");
36253 self.generate_expression(&e.this)?;
36254 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
36255 }
36256 }
36257 }
36258 Some(DialectType::Spark) => {
36259 match scale {
36264 0 => {
36265 self.write_keyword("CAST");
36266 self.write("(");
36267 self.write_keyword("FROM_UNIXTIME");
36268 self.write("(");
36269 self.generate_expression(&e.this)?;
36270 self.write(") ");
36271 self.write_keyword("AS TIMESTAMP");
36272 self.write(")");
36273 }
36274 3 => {
36275 self.write_keyword("TIMESTAMP_MILLIS");
36276 self.write("(");
36277 self.generate_expression(&e.this)?;
36278 self.write(")");
36279 }
36280 6 => {
36281 self.write_keyword("TIMESTAMP_MICROS");
36282 self.write("(");
36283 self.generate_expression(&e.this)?;
36284 self.write(")");
36285 }
36286 _ => {
36287 self.write_keyword("TIMESTAMP_SECONDS");
36288 self.write("(");
36289 self.generate_expression(&e.this)?;
36290 self.write(&format!(" / POWER(10, {}))", scale));
36291 }
36292 }
36293 }
36294 Some(DialectType::Databricks) => {
36295 match scale {
36299 0 => {
36300 self.write_keyword("CAST");
36301 self.write("(");
36302 self.write_keyword("FROM_UNIXTIME");
36303 self.write("(");
36304 self.generate_expression(&e.this)?;
36305 self.write(") ");
36306 self.write_keyword("AS TIMESTAMP");
36307 self.write(")");
36308 }
36309 3 => {
36310 self.write_keyword("TIMESTAMP_MILLIS");
36311 self.write("(");
36312 self.generate_expression(&e.this)?;
36313 self.write(")");
36314 }
36315 6 => {
36316 self.write_keyword("TIMESTAMP_MICROS");
36317 self.write("(");
36318 self.generate_expression(&e.this)?;
36319 self.write(")");
36320 }
36321 _ => {
36322 self.write_keyword("TIMESTAMP_SECONDS");
36323 self.write("(");
36324 self.generate_expression(&e.this)?;
36325 self.write(&format!(" / POWER(10, {}))", scale));
36326 }
36327 }
36328 }
36329 Some(DialectType::Hive) => {
36330 if scale == 0 {
36332 self.write_keyword("FROM_UNIXTIME");
36333 self.write("(");
36334 self.generate_expression(&e.this)?;
36335 self.write(")");
36336 } else {
36337 self.write_keyword("FROM_UNIXTIME");
36338 self.write("(");
36339 self.generate_expression(&e.this)?;
36340 self.write(&format!(" / POWER(10, {})", scale));
36341 self.write(")");
36342 }
36343 }
36344 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36345 if scale == 0 {
36348 self.write_keyword("FROM_UNIXTIME");
36349 self.write("(");
36350 self.generate_expression(&e.this)?;
36351 self.write(")");
36352 } else {
36353 self.write_keyword("FROM_UNIXTIME");
36354 self.write("(CAST(");
36355 self.generate_expression(&e.this)?;
36356 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
36357 }
36358 }
36359 Some(DialectType::DuckDB) => {
36360 match scale {
36364 0 => {
36365 self.write_keyword("TO_TIMESTAMP");
36366 self.write("(");
36367 self.generate_expression(&e.this)?;
36368 self.write(")");
36369 }
36370 3 => {
36371 self.write_keyword("EPOCH_MS");
36372 self.write("(");
36373 self.generate_expression(&e.this)?;
36374 self.write(")");
36375 }
36376 6 => {
36377 self.write_keyword("MAKE_TIMESTAMP");
36378 self.write("(");
36379 self.generate_expression(&e.this)?;
36380 self.write(")");
36381 }
36382 _ => {
36383 self.write_keyword("TO_TIMESTAMP");
36384 self.write("(");
36385 self.generate_expression(&e.this)?;
36386 self.write(&format!(" / POWER(10, {}))", scale));
36387 self.write_keyword(" AT TIME ZONE");
36388 self.write(" 'UTC'");
36389 }
36390 }
36391 }
36392 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
36393 self.write_keyword("FROM_UNIXTIME");
36395 self.write("(");
36396 self.generate_expression(&e.this)?;
36397 self.write(")");
36398 }
36399 Some(DialectType::Oracle) => {
36400 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
36402 self.generate_expression(&e.this)?;
36403 self.write(" / 86400)");
36404 }
36405 Some(DialectType::Redshift) => {
36406 self.write("(TIMESTAMP 'epoch' + ");
36409 if scale == 0 {
36410 self.generate_expression(&e.this)?;
36411 } else {
36412 self.write("(");
36413 self.generate_expression(&e.this)?;
36414 self.write(&format!(" / POWER(10, {}))", scale));
36415 }
36416 self.write(" * INTERVAL '1 SECOND')");
36417 }
36418 Some(DialectType::Exasol) => {
36419 self.write_keyword("FROM_POSIX_TIME");
36421 self.write("(");
36422 self.generate_expression(&e.this)?;
36423 self.write(")");
36424 }
36425 _ => {
36426 self.write_keyword("TO_TIMESTAMP");
36428 self.write("(");
36429 self.generate_expression(&e.this)?;
36430 if let Some(s) = e.scale {
36431 self.write(", ");
36432 self.write(&s.to_string());
36433 }
36434 self.write(")");
36435 }
36436 }
36437 Ok(())
36438 }
36439
36440 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
36441 if !matches!(&*e.this, Expression::Null(_)) {
36443 self.write_keyword("NAME");
36444 self.write_space();
36445 self.generate_expression(&e.this)?;
36446 }
36447 if !e.expressions.is_empty() {
36448 self.write_space();
36449 self.write_keyword("VALUE");
36450 self.write_space();
36451 for (i, expr) in e.expressions.iter().enumerate() {
36452 if i > 0 {
36453 self.write(", ");
36454 }
36455 self.generate_expression(expr)?;
36456 }
36457 }
36458 Ok(())
36459 }
36460
36461 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
36462 if e.wrapped.is_some() {
36464 self.write("(");
36465 }
36466 self.generate_expression(&e.this)?;
36467 if e.wrapped.is_some() {
36468 self.write(")");
36469 }
36470 self.write("(");
36471 for (i, expr) in e.expressions.iter().enumerate() {
36472 if i > 0 {
36473 self.write(", ");
36474 }
36475 self.generate_expression(expr)?;
36476 }
36477 self.write(")");
36478 Ok(())
36479 }
36480
36481 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
36482 self.write_keyword("USING TEMPLATE");
36484 self.write_space();
36485 self.generate_expression(&e.this)?;
36486 Ok(())
36487 }
36488
36489 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
36490 self.write_keyword("UTC_TIME");
36492 Ok(())
36493 }
36494
36495 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
36496 if matches!(self.config.dialect, Some(crate::dialects::DialectType::ClickHouse)) {
36497 self.write_keyword("CURRENT_TIMESTAMP");
36498 self.write("('UTC')");
36499 } else {
36500 self.write_keyword("UTC_TIMESTAMP");
36501 }
36502 Ok(())
36503 }
36504
36505 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
36506 use crate::dialects::DialectType;
36507 let func_name = match self.config.dialect {
36509 Some(DialectType::Snowflake) => "UUID_STRING",
36510 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
36511 Some(DialectType::BigQuery) => "GENERATE_UUID",
36512 _ => {
36513 if let Some(name) = &e.name {
36514 name.as_str()
36515 } else {
36516 "UUID"
36517 }
36518 }
36519 };
36520 self.write_keyword(func_name);
36521 self.write("(");
36522 if let Some(this) = &e.this {
36523 self.generate_expression(this)?;
36524 }
36525 self.write(")");
36526 Ok(())
36527 }
36528
36529 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
36530 self.write_keyword("MAP");
36532 self.write("(");
36533 let mut first = true;
36534 for (k, v) in e.keys.iter().zip(e.values.iter()) {
36535 if !first {
36536 self.write(", ");
36537 }
36538 self.generate_expression(k)?;
36539 self.write(", ");
36540 self.generate_expression(v)?;
36541 first = false;
36542 }
36543 self.write(")");
36544 Ok(())
36545 }
36546
36547 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
36548 self.write_keyword("VECTOR_SEARCH");
36550 self.write("(");
36551 self.generate_expression(&e.this)?;
36552 if let Some(col) = &e.column_to_search {
36553 self.write(", ");
36554 self.generate_expression(col)?;
36555 }
36556 if let Some(query_table) = &e.query_table {
36557 self.write(", ");
36558 self.generate_expression(query_table)?;
36559 }
36560 if let Some(query_col) = &e.query_column_to_search {
36561 self.write(", ");
36562 self.generate_expression(query_col)?;
36563 }
36564 if let Some(top_k) = &e.top_k {
36565 self.write(", ");
36566 self.generate_expression(top_k)?;
36567 }
36568 if let Some(dist_type) = &e.distance_type {
36569 self.write(", ");
36570 self.generate_expression(dist_type)?;
36571 }
36572 self.write(")");
36573 Ok(())
36574 }
36575
36576 fn generate_version(&mut self, e: &Version) -> Result<()> {
36577 use crate::dialects::DialectType;
36583 let skip_for = matches!(
36584 self.config.dialect,
36585 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
36586 );
36587 if !skip_for {
36588 self.write_keyword("FOR");
36589 self.write_space();
36590 }
36591 match e.this.as_ref() {
36593 Expression::Identifier(ident) => {
36594 self.write_keyword(&ident.name);
36595 }
36596 _ => {
36597 self.generate_expression(&e.this)?;
36598 }
36599 }
36600 self.write_space();
36601 self.write_keyword(&e.kind);
36602 if let Some(expression) = &e.expression {
36603 self.write_space();
36604 self.generate_expression(expression)?;
36605 }
36606 Ok(())
36607 }
36608
36609 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
36610 self.generate_expression(&e.this)?;
36612 Ok(())
36613 }
36614
36615 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
36616 if e.this.is_some() {
36618 self.write_keyword("NOT VOLATILE");
36619 } else {
36620 self.write_keyword("VOLATILE");
36621 }
36622 Ok(())
36623 }
36624
36625 fn generate_watermark_column_constraint(
36626 &mut self,
36627 e: &WatermarkColumnConstraint,
36628 ) -> Result<()> {
36629 self.write_keyword("WATERMARK FOR");
36631 self.write_space();
36632 self.generate_expression(&e.this)?;
36633 self.write_space();
36634 self.write_keyword("AS");
36635 self.write_space();
36636 self.generate_expression(&e.expression)?;
36637 Ok(())
36638 }
36639
36640 fn generate_week(&mut self, e: &Week) -> Result<()> {
36641 self.write_keyword("WEEK");
36643 self.write("(");
36644 self.generate_expression(&e.this)?;
36645 if let Some(mode) = &e.mode {
36646 self.write(", ");
36647 self.generate_expression(mode)?;
36648 }
36649 self.write(")");
36650 Ok(())
36651 }
36652
36653 fn generate_when(&mut self, e: &When) -> Result<()> {
36654 self.write_keyword("WHEN");
36658 self.write_space();
36659
36660 if let Some(matched) = &e.matched {
36662 match matched.as_ref() {
36664 Expression::Boolean(b) if b.value => {
36665 self.write_keyword("MATCHED");
36666 }
36667 _ => {
36668 self.write_keyword("NOT MATCHED");
36669 }
36670 }
36671 } else {
36672 self.write_keyword("NOT MATCHED");
36673 }
36674
36675 if self.config.matched_by_source {
36680 if let Some(source) = &e.source {
36681 if let Expression::Boolean(b) = source.as_ref() {
36682 if b.value {
36683 self.write_space();
36685 self.write_keyword("BY SOURCE");
36686 }
36687 } else {
36689 self.write_space();
36691 self.write_keyword("BY SOURCE");
36692 }
36693 }
36694 }
36695
36696 if let Some(condition) = &e.condition {
36698 self.write_space();
36699 self.write_keyword("AND");
36700 self.write_space();
36701 self.generate_expression(condition)?;
36702 }
36703
36704 self.write_space();
36705 self.write_keyword("THEN");
36706 self.write_space();
36707
36708 self.generate_merge_action(&e.then)?;
36711
36712 Ok(())
36713 }
36714
36715 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
36716 match action {
36717 Expression::Tuple(tuple) => {
36718 let elements = &tuple.expressions;
36719 if elements.is_empty() {
36720 return self.generate_expression(action);
36721 }
36722 match &elements[0] {
36724 Expression::Var(v) if v.this == "INSERT" => {
36725 self.write_keyword("INSERT");
36726 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
36728 self.write(" *");
36729 } else {
36730 let mut values_idx = 1;
36731 if elements.len() > 1 {
36733 if let Expression::Tuple(cols) = &elements[1] {
36734 if elements.len() > 2 {
36736 self.write(" (");
36738 for (i, col) in cols.expressions.iter().enumerate() {
36739 if i > 0 {
36740 self.write(", ");
36741 }
36742 if !self.merge_strip_qualifiers.is_empty() {
36744 let stripped = self.strip_merge_qualifier(col);
36745 self.generate_expression(&stripped)?;
36746 } else {
36747 self.generate_expression(col)?;
36748 }
36749 }
36750 self.write(")");
36751 values_idx = 2;
36752 } else {
36753 values_idx = 1;
36755 }
36756 }
36757 }
36758 if values_idx < elements.len() {
36760 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
36762 if !is_row {
36763 self.write_space();
36764 self.write_keyword("VALUES");
36765 }
36766 self.write(" ");
36767 if let Expression::Tuple(vals) = &elements[values_idx] {
36768 self.write("(");
36769 for (i, val) in vals.expressions.iter().enumerate() {
36770 if i > 0 {
36771 self.write(", ");
36772 }
36773 self.generate_expression(val)?;
36774 }
36775 self.write(")");
36776 } else {
36777 self.generate_expression(&elements[values_idx])?;
36778 }
36779 }
36780 } }
36782 Expression::Var(v) if v.this == "UPDATE" => {
36783 self.write_keyword("UPDATE");
36784 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
36786 self.write(" *");
36787 } else if elements.len() > 1 {
36788 self.write_space();
36789 self.write_keyword("SET");
36790 if self.config.pretty {
36792 self.write_newline();
36793 self.indent_level += 1;
36794 self.write_indent();
36795 } else {
36796 self.write_space();
36797 }
36798 if let Expression::Tuple(assignments) = &elements[1] {
36799 for (i, assignment) in assignments.expressions.iter().enumerate() {
36800 if i > 0 {
36801 if self.config.pretty {
36802 self.write(",");
36803 self.write_newline();
36804 self.write_indent();
36805 } else {
36806 self.write(", ");
36807 }
36808 }
36809 if !self.merge_strip_qualifiers.is_empty() {
36811 self.generate_merge_set_assignment(assignment)?;
36812 } else {
36813 self.generate_expression(assignment)?;
36814 }
36815 }
36816 } else {
36817 self.generate_expression(&elements[1])?;
36818 }
36819 if self.config.pretty {
36820 self.indent_level -= 1;
36821 }
36822 }
36823 }
36824 _ => {
36825 self.generate_expression(action)?;
36827 }
36828 }
36829 }
36830 Expression::Var(v)
36831 if v.this == "INSERT"
36832 || v.this == "UPDATE"
36833 || v.this == "DELETE"
36834 || v.this == "DO NOTHING" =>
36835 {
36836 self.write_keyword(&v.this);
36837 }
36838 _ => {
36839 self.generate_expression(action)?;
36840 }
36841 }
36842 Ok(())
36843 }
36844
36845 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
36847 match assignment {
36848 Expression::Eq(eq) => {
36849 let stripped_left = self.strip_merge_qualifier(&eq.left);
36851 self.generate_expression(&stripped_left)?;
36852 self.write(" = ");
36853 self.generate_expression(&eq.right)?;
36854 Ok(())
36855 }
36856 other => self.generate_expression(other),
36857 }
36858 }
36859
36860 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
36862 match expr {
36863 Expression::Column(col) => {
36864 if let Some(ref table_ident) = col.table {
36865 if self
36866 .merge_strip_qualifiers
36867 .iter()
36868 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
36869 {
36870 let mut col = col.clone();
36872 col.table = None;
36873 return Expression::Column(col);
36874 }
36875 }
36876 expr.clone()
36877 }
36878 Expression::Dot(dot) => {
36879 if let Expression::Identifier(id) = &dot.this {
36881 if self
36882 .merge_strip_qualifiers
36883 .iter()
36884 .any(|n| n.eq_ignore_ascii_case(&id.name))
36885 {
36886 return Expression::Identifier(dot.field.clone());
36887 }
36888 }
36889 expr.clone()
36890 }
36891 _ => expr.clone(),
36892 }
36893 }
36894
36895 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
36896 for (i, expr) in e.expressions.iter().enumerate() {
36898 if i > 0 {
36899 if self.config.pretty {
36901 self.write_newline();
36902 self.write_indent();
36903 } else {
36904 self.write_space();
36905 }
36906 }
36907 self.generate_expression(expr)?;
36908 }
36909 Ok(())
36910 }
36911
36912 fn generate_where(&mut self, e: &Where) -> Result<()> {
36913 self.write_keyword("WHERE");
36915 self.write_space();
36916 self.generate_expression(&e.this)?;
36917 Ok(())
36918 }
36919
36920 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
36921 self.write_keyword("WIDTH_BUCKET");
36923 self.write("(");
36924 self.generate_expression(&e.this)?;
36925 if let Some(min_value) = &e.min_value {
36926 self.write(", ");
36927 self.generate_expression(min_value)?;
36928 }
36929 if let Some(max_value) = &e.max_value {
36930 self.write(", ");
36931 self.generate_expression(max_value)?;
36932 }
36933 if let Some(num_buckets) = &e.num_buckets {
36934 self.write(", ");
36935 self.generate_expression(num_buckets)?;
36936 }
36937 self.write(")");
36938 Ok(())
36939 }
36940
36941 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
36942 self.generate_window_spec(e)
36944 }
36945
36946 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
36947 let mut has_content = false;
36949
36950 if !e.partition_by.is_empty() {
36952 self.write_keyword("PARTITION BY");
36953 self.write_space();
36954 for (i, expr) in e.partition_by.iter().enumerate() {
36955 if i > 0 {
36956 self.write(", ");
36957 }
36958 self.generate_expression(expr)?;
36959 }
36960 has_content = true;
36961 }
36962
36963 if !e.order_by.is_empty() {
36965 if has_content {
36966 self.write_space();
36967 }
36968 self.write_keyword("ORDER BY");
36969 self.write_space();
36970 for (i, ordered) in e.order_by.iter().enumerate() {
36971 if i > 0 {
36972 self.write(", ");
36973 }
36974 self.generate_expression(&ordered.this)?;
36975 if ordered.desc {
36976 self.write_space();
36977 self.write_keyword("DESC");
36978 } else if ordered.explicit_asc {
36979 self.write_space();
36980 self.write_keyword("ASC");
36981 }
36982 if let Some(nulls_first) = ordered.nulls_first {
36983 self.write_space();
36984 self.write_keyword("NULLS");
36985 self.write_space();
36986 if nulls_first {
36987 self.write_keyword("FIRST");
36988 } else {
36989 self.write_keyword("LAST");
36990 }
36991 }
36992 }
36993 has_content = true;
36994 }
36995
36996 if let Some(frame) = &e.frame {
36998 if has_content {
36999 self.write_space();
37000 }
37001 self.generate_window_frame(frame)?;
37002 }
37003
37004 Ok(())
37005 }
37006
37007 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
37008 self.write_keyword("WITH");
37010 self.write_space();
37011 if e.no.is_some() {
37012 self.write_keyword("NO");
37013 self.write_space();
37014 }
37015 self.write_keyword("DATA");
37016
37017 if let Some(statistics) = &e.statistics {
37019 self.write_space();
37020 self.write_keyword("AND");
37021 self.write_space();
37022 match statistics.as_ref() {
37024 Expression::Boolean(b) if !b.value => {
37025 self.write_keyword("NO");
37026 self.write_space();
37027 }
37028 _ => {}
37029 }
37030 self.write_keyword("STATISTICS");
37031 }
37032 Ok(())
37033 }
37034
37035 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
37036 self.write_keyword("WITH FILL");
37038
37039 if let Some(from_) = &e.from_ {
37040 self.write_space();
37041 self.write_keyword("FROM");
37042 self.write_space();
37043 self.generate_expression(from_)?;
37044 }
37045
37046 if let Some(to) = &e.to {
37047 self.write_space();
37048 self.write_keyword("TO");
37049 self.write_space();
37050 self.generate_expression(to)?;
37051 }
37052
37053 if let Some(step) = &e.step {
37054 self.write_space();
37055 self.write_keyword("STEP");
37056 self.write_space();
37057 self.generate_expression(step)?;
37058 }
37059
37060 if let Some(staleness) = &e.staleness {
37061 self.write_space();
37062 self.write_keyword("STALENESS");
37063 self.write_space();
37064 self.generate_expression(staleness)?;
37065 }
37066
37067 if let Some(interpolate) = &e.interpolate {
37068 self.write_space();
37069 self.write_keyword("INTERPOLATE");
37070 self.write(" (");
37071 self.generate_interpolate_item(interpolate)?;
37073 self.write(")");
37074 }
37075
37076 Ok(())
37077 }
37078
37079 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
37081 match expr {
37082 Expression::Alias(alias) => {
37083 self.generate_identifier(&alias.alias)?;
37085 self.write_space();
37086 self.write_keyword("AS");
37087 self.write_space();
37088 self.generate_expression(&alias.this)?;
37089 }
37090 Expression::Tuple(tuple) => {
37091 for (i, item) in tuple.expressions.iter().enumerate() {
37092 if i > 0 {
37093 self.write(", ");
37094 }
37095 self.generate_interpolate_item(item)?;
37096 }
37097 }
37098 other => {
37099 self.generate_expression(other)?;
37100 }
37101 }
37102 Ok(())
37103 }
37104
37105 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
37106 self.write_keyword("WITH JOURNAL TABLE");
37108 self.write("=");
37109 self.generate_expression(&e.this)?;
37110 Ok(())
37111 }
37112
37113 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
37114 self.generate_expression(&e.this)?;
37116 self.write_space();
37117 self.write_keyword("WITH");
37118 self.write_space();
37119 self.write_keyword(&e.op);
37120 Ok(())
37121 }
37122
37123 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
37124 self.write_keyword("WITH");
37126 self.write_space();
37127 for (i, expr) in e.expressions.iter().enumerate() {
37128 if i > 0 {
37129 self.write(", ");
37130 }
37131 self.generate_expression(expr)?;
37132 }
37133 Ok(())
37134 }
37135
37136 fn generate_with_schema_binding_property(
37137 &mut self,
37138 e: &WithSchemaBindingProperty,
37139 ) -> Result<()> {
37140 self.write_keyword("WITH");
37142 self.write_space();
37143 self.generate_expression(&e.this)?;
37144 Ok(())
37145 }
37146
37147 fn generate_with_system_versioning_property(
37148 &mut self,
37149 e: &WithSystemVersioningProperty,
37150 ) -> Result<()> {
37151 let mut parts = Vec::new();
37157
37158 if let Some(this) = &e.this {
37159 let mut s = String::from("HISTORY_TABLE=");
37161 let mut gen = Generator::new();
37162 gen.generate_expression(this)?;
37163 s.push_str(&gen.output);
37164 parts.push(s);
37165 }
37166
37167 if let Some(data_consistency) = &e.data_consistency {
37168 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
37169 let mut gen = Generator::new();
37170 gen.generate_expression(data_consistency)?;
37171 s.push_str(&gen.output);
37172 parts.push(s);
37173 }
37174
37175 if let Some(retention_period) = &e.retention_period {
37176 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
37177 let mut gen = Generator::new();
37178 gen.generate_expression(retention_period)?;
37179 s.push_str(&gen.output);
37180 parts.push(s);
37181 }
37182
37183 self.write_keyword("SYSTEM_VERSIONING");
37184 self.write("=");
37185
37186 if !parts.is_empty() {
37187 self.write_keyword("ON");
37188 self.write("(");
37189 self.write(&parts.join(", "));
37190 self.write(")");
37191 } else if e.on.is_some() {
37192 self.write_keyword("ON");
37193 } else {
37194 self.write_keyword("OFF");
37195 }
37196
37197 if e.with_.is_some() {
37199 let inner = self.output.clone();
37200 self.output.clear();
37201 self.write("WITH(");
37202 self.write(&inner);
37203 self.write(")");
37204 }
37205
37206 Ok(())
37207 }
37208
37209 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
37210 self.write_keyword("WITH");
37212 self.write(" (");
37213 for (i, expr) in e.expressions.iter().enumerate() {
37214 if i > 0 {
37215 self.write(", ");
37216 }
37217 self.generate_expression(expr)?;
37218 }
37219 self.write(")");
37220 Ok(())
37221 }
37222
37223 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
37224 self.write_keyword("XMLELEMENT");
37227 self.write("(");
37228
37229 if e.evalname.is_some() {
37230 self.write_keyword("EVALNAME");
37231 } else {
37232 self.write_keyword("NAME");
37233 }
37234 self.write_space();
37235 self.generate_expression(&e.this)?;
37236
37237 for expr in &e.expressions {
37238 self.write(", ");
37239 self.generate_expression(expr)?;
37240 }
37241 self.write(")");
37242 Ok(())
37243 }
37244
37245 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
37246 self.write_keyword("XMLGET");
37248 self.write("(");
37249 self.generate_expression(&e.this)?;
37250 self.write(", ");
37251 self.generate_expression(&e.expression)?;
37252 if let Some(instance) = &e.instance {
37253 self.write(", ");
37254 self.generate_expression(instance)?;
37255 }
37256 self.write(")");
37257 Ok(())
37258 }
37259
37260 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
37261 self.generate_expression(&e.this)?;
37263 if let Some(expression) = &e.expression {
37264 self.write("(");
37265 self.generate_expression(expression)?;
37266 self.write(")");
37267 }
37268 Ok(())
37269 }
37270
37271 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
37272 self.write_keyword("XMLTABLE");
37274 self.write("(");
37275
37276 if self.config.pretty {
37277 self.indent_level += 1;
37278 self.write_newline();
37279 self.write_indent();
37280 self.generate_expression(&e.this)?;
37281
37282 if let Some(passing) = &e.passing {
37283 self.write_newline();
37284 self.write_indent();
37285 self.write_keyword("PASSING");
37286 if let Expression::Tuple(tuple) = passing.as_ref() {
37287 for expr in &tuple.expressions {
37288 self.write_newline();
37289 self.indent_level += 1;
37290 self.write_indent();
37291 self.generate_expression(expr)?;
37292 self.indent_level -= 1;
37293 }
37294 } else {
37295 self.write_newline();
37296 self.indent_level += 1;
37297 self.write_indent();
37298 self.generate_expression(passing)?;
37299 self.indent_level -= 1;
37300 }
37301 }
37302
37303 if e.by_ref.is_some() {
37304 self.write_newline();
37305 self.write_indent();
37306 self.write_keyword("RETURNING SEQUENCE BY REF");
37307 }
37308
37309 if !e.columns.is_empty() {
37310 self.write_newline();
37311 self.write_indent();
37312 self.write_keyword("COLUMNS");
37313 for (i, col) in e.columns.iter().enumerate() {
37314 self.write_newline();
37315 self.indent_level += 1;
37316 self.write_indent();
37317 self.generate_expression(col)?;
37318 self.indent_level -= 1;
37319 if i < e.columns.len() - 1 {
37320 self.write(",");
37321 }
37322 }
37323 }
37324
37325 self.indent_level -= 1;
37326 self.write_newline();
37327 self.write_indent();
37328 self.write(")");
37329 return Ok(());
37330 }
37331
37332 if let Some(namespaces) = &e.namespaces {
37334 self.write_keyword("XMLNAMESPACES");
37335 self.write("(");
37336 if let Expression::Tuple(tuple) = namespaces.as_ref() {
37338 for (i, expr) in tuple.expressions.iter().enumerate() {
37339 if i > 0 {
37340 self.write(", ");
37341 }
37342 if !matches!(expr, Expression::Alias(_)) {
37345 self.write_keyword("DEFAULT");
37346 self.write_space();
37347 }
37348 self.generate_expression(expr)?;
37349 }
37350 } else {
37351 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
37353 self.write_keyword("DEFAULT");
37354 self.write_space();
37355 }
37356 self.generate_expression(namespaces)?;
37357 }
37358 self.write("), ");
37359 }
37360
37361 self.generate_expression(&e.this)?;
37363
37364 if let Some(passing) = &e.passing {
37366 self.write_space();
37367 self.write_keyword("PASSING");
37368 self.write_space();
37369 if let Expression::Tuple(tuple) = passing.as_ref() {
37371 for (i, expr) in tuple.expressions.iter().enumerate() {
37372 if i > 0 {
37373 self.write(", ");
37374 }
37375 self.generate_expression(expr)?;
37376 }
37377 } else {
37378 self.generate_expression(passing)?;
37379 }
37380 }
37381
37382 if e.by_ref.is_some() {
37384 self.write_space();
37385 self.write_keyword("RETURNING SEQUENCE BY REF");
37386 }
37387
37388 if !e.columns.is_empty() {
37390 self.write_space();
37391 self.write_keyword("COLUMNS");
37392 self.write_space();
37393 for (i, col) in e.columns.iter().enumerate() {
37394 if i > 0 {
37395 self.write(", ");
37396 }
37397 self.generate_expression(col)?;
37398 }
37399 }
37400
37401 self.write(")");
37402 Ok(())
37403 }
37404
37405 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
37406 if let Some(this) = &e.this {
37409 self.generate_expression(this)?;
37410 if let Some(expression) = &e.expression {
37411 self.write_space();
37412 self.write_keyword("XOR");
37413 self.write_space();
37414 self.generate_expression(expression)?;
37415 }
37416 }
37417
37418 for (i, expr) in e.expressions.iter().enumerate() {
37420 if i > 0 || e.this.is_some() {
37421 self.write_space();
37422 self.write_keyword("XOR");
37423 self.write_space();
37424 }
37425 self.generate_expression(expr)?;
37426 }
37427 Ok(())
37428 }
37429
37430 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
37431 self.write_keyword("ZIPF");
37433 self.write("(");
37434 self.generate_expression(&e.this)?;
37435 if let Some(elementcount) = &e.elementcount {
37436 self.write(", ");
37437 self.generate_expression(elementcount)?;
37438 }
37439 if let Some(gen) = &e.gen {
37440 self.write(", ");
37441 self.generate_expression(gen)?;
37442 }
37443 self.write(")");
37444 Ok(())
37445 }
37446}
37447
37448impl Default for Generator {
37449 fn default() -> Self {
37450 Self::new()
37451 }
37452}
37453
37454#[cfg(test)]
37455mod tests {
37456 use super::*;
37457 use crate::parser::Parser;
37458
37459 fn roundtrip(sql: &str) -> String {
37460 let ast = Parser::parse_sql(sql).unwrap();
37461 Generator::sql(&ast[0]).unwrap()
37462 }
37463
37464 #[test]
37465 fn test_simple_select() {
37466 let result = roundtrip("SELECT 1");
37467 assert_eq!(result, "SELECT 1");
37468 }
37469
37470 #[test]
37471 fn test_select_from() {
37472 let result = roundtrip("SELECT a, b FROM t");
37473 assert_eq!(result, "SELECT a, b FROM t");
37474 }
37475
37476 #[test]
37477 fn test_select_where() {
37478 let result = roundtrip("SELECT * FROM t WHERE x = 1");
37479 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
37480 }
37481
37482 #[test]
37483 fn test_select_join() {
37484 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
37485 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
37486 }
37487
37488 #[test]
37489 fn test_insert() {
37490 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
37491 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
37492 }
37493
37494 #[test]
37495 fn test_pretty_print() {
37496 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
37497 let result = Generator::pretty_sql(&ast[0]).unwrap();
37498 assert!(result.contains('\n'));
37499 }
37500
37501 #[test]
37502 fn test_window_function() {
37503 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
37504 assert_eq!(
37505 result,
37506 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
37507 );
37508 }
37509
37510 #[test]
37511 fn test_window_function_with_frame() {
37512 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
37513 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
37514 }
37515
37516 #[test]
37517 fn test_aggregate_with_filter() {
37518 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
37519 assert_eq!(
37520 result,
37521 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
37522 );
37523 }
37524
37525 #[test]
37526 fn test_subscript() {
37527 let result = roundtrip("SELECT arr[0]");
37528 assert_eq!(result, "SELECT arr[0]");
37529 }
37530
37531 #[test]
37533 fn test_create_table() {
37534 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
37535 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
37536 }
37537
37538 #[test]
37539 fn test_create_table_with_constraints() {
37540 let result = roundtrip(
37541 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
37542 );
37543 assert_eq!(
37544 result,
37545 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
37546 );
37547 }
37548
37549 #[test]
37550 fn test_create_table_if_not_exists() {
37551 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
37552 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
37553 }
37554
37555 #[test]
37556 fn test_drop_table() {
37557 let result = roundtrip("DROP TABLE users");
37558 assert_eq!(result, "DROP TABLE users");
37559 }
37560
37561 #[test]
37562 fn test_drop_table_if_exists_cascade() {
37563 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
37564 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
37565 }
37566
37567 #[test]
37568 fn test_alter_table_add_column() {
37569 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
37570 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
37571 }
37572
37573 #[test]
37574 fn test_alter_table_drop_column() {
37575 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
37576 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
37577 }
37578
37579 #[test]
37580 fn test_create_index() {
37581 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
37582 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
37583 }
37584
37585 #[test]
37586 fn test_create_unique_index() {
37587 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
37588 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
37589 }
37590
37591 #[test]
37592 fn test_drop_index() {
37593 let result = roundtrip("DROP INDEX idx_name");
37594 assert_eq!(result, "DROP INDEX idx_name");
37595 }
37596
37597 #[test]
37598 fn test_create_view() {
37599 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
37600 assert_eq!(
37601 result,
37602 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
37603 );
37604 }
37605
37606 #[test]
37607 fn test_drop_view() {
37608 let result = roundtrip("DROP VIEW active_users");
37609 assert_eq!(result, "DROP VIEW active_users");
37610 }
37611
37612 #[test]
37613 fn test_truncate() {
37614 let result = roundtrip("TRUNCATE TABLE users");
37615 assert_eq!(result, "TRUNCATE TABLE users");
37616 }
37617
37618 #[test]
37619 fn test_string_literal_escaping_default() {
37620 let result = roundtrip("SELECT 'hello'");
37622 assert_eq!(result, "SELECT 'hello'");
37623
37624 let result = roundtrip("SELECT 'it''s a test'");
37626 assert_eq!(result, "SELECT 'it''s a test'");
37627 }
37628
37629 #[test]
37630 fn test_not_in_style_prefix_default_generic() {
37631 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
37632 assert_eq!(
37633 result,
37634 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
37635 );
37636 }
37637
37638 #[test]
37639 fn test_not_in_style_infix_generic_override() {
37640 let ast =
37641 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
37642 .unwrap();
37643 let config = GeneratorConfig {
37644 not_in_style: NotInStyle::Infix,
37645 ..Default::default()
37646 };
37647 let mut gen = Generator::with_config(config);
37648 let result = gen.generate(&ast[0]).unwrap();
37649 assert_eq!(
37650 result,
37651 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
37652 );
37653 }
37654
37655 #[test]
37656 fn test_string_literal_escaping_mysql() {
37657 use crate::dialects::DialectType;
37658
37659 let config = GeneratorConfig {
37660 dialect: Some(DialectType::MySQL),
37661 ..Default::default()
37662 };
37663
37664 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
37665 let mut gen = Generator::with_config(config.clone());
37666 let result = gen.generate(&ast[0]).unwrap();
37667 assert_eq!(result, "SELECT 'hello'");
37668
37669 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
37671 let mut gen = Generator::with_config(config.clone());
37672 let result = gen.generate(&ast[0]).unwrap();
37673 assert_eq!(result, "SELECT 'it''s'");
37674 }
37675
37676 #[test]
37677 fn test_string_literal_escaping_postgres() {
37678 use crate::dialects::DialectType;
37679
37680 let config = GeneratorConfig {
37681 dialect: Some(DialectType::PostgreSQL),
37682 ..Default::default()
37683 };
37684
37685 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
37686 let mut gen = Generator::with_config(config.clone());
37687 let result = gen.generate(&ast[0]).unwrap();
37688 assert_eq!(result, "SELECT 'hello'");
37689
37690 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
37692 let mut gen = Generator::with_config(config.clone());
37693 let result = gen.generate(&ast[0]).unwrap();
37694 assert_eq!(result, "SELECT 'it''s'");
37695 }
37696
37697 #[test]
37698 fn test_string_literal_escaping_bigquery() {
37699 use crate::dialects::DialectType;
37700
37701 let config = GeneratorConfig {
37702 dialect: Some(DialectType::BigQuery),
37703 ..Default::default()
37704 };
37705
37706 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
37707 let mut gen = Generator::with_config(config.clone());
37708 let result = gen.generate(&ast[0]).unwrap();
37709 assert_eq!(result, "SELECT 'hello'");
37710
37711 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
37713 let mut gen = Generator::with_config(config.clone());
37714 let result = gen.generate(&ast[0]).unwrap();
37715 assert_eq!(result, "SELECT 'it\\'s'");
37716 }
37717
37718 #[test]
37719 fn test_generate_deep_and_chain_without_stack_growth() {
37720 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
37721 Expression::column("c0"),
37722 Expression::number(0),
37723 )));
37724
37725 for i in 1..2500 {
37726 let predicate = Expression::Eq(Box::new(BinaryOp::new(
37727 Expression::column(format!("c{i}")),
37728 Expression::number(i as i64),
37729 )));
37730 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
37731 }
37732
37733 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
37734 assert!(sql.contains("c2499 = 2499"), "{}", sql);
37735 }
37736
37737 #[test]
37738 fn test_generate_deep_or_chain_without_stack_growth() {
37739 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
37740 Expression::column("c0"),
37741 Expression::number(0),
37742 )));
37743
37744 for i in 1..2500 {
37745 let predicate = Expression::Eq(Box::new(BinaryOp::new(
37746 Expression::column(format!("c{i}")),
37747 Expression::number(i as i64),
37748 )));
37749 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
37750 }
37751
37752 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
37753 assert!(sql.contains("c2499 = 2499"), "{}", sql);
37754 }
37755}