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(_)) => {
2247 let Literal::Number(n) = lit.as_ref() else {
2248 unreachable!()
2249 };
2250 n.parse::<i64>().ok()
2251 }
2252 Expression::Add(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::Sub(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::Mul(op) => {
2263 let left = Self::try_evaluate_constant(&op.left)?;
2264 let right = Self::try_evaluate_constant(&op.right)?;
2265 Some(left * right)
2266 }
2267 Expression::Div(op) => {
2268 let left = Self::try_evaluate_constant(&op.left)?;
2269 let right = Self::try_evaluate_constant(&op.right)?;
2270 if right != 0 {
2271 Some(left / right)
2272 } else {
2273 None
2274 }
2275 }
2276 Expression::Paren(p) => Self::try_evaluate_constant(&p.this),
2277 _ => None,
2278 }
2279 }
2280
2281 fn is_reserved_keyword(&self, name: &str) -> bool {
2283 use crate::dialects::DialectType;
2284 let mut buf = [0u8; 128];
2285 let lower_ref: &str = if name.len() <= 128 {
2286 for (i, b) in name.bytes().enumerate() {
2287 buf[i] = b.to_ascii_lowercase();
2288 }
2289 std::str::from_utf8(&buf[..name.len()]).unwrap_or(name)
2291 } else {
2292 return false;
2293 };
2294
2295 match self.config.dialect {
2296 Some(DialectType::BigQuery) => reserved_keywords::BIGQUERY_RESERVED.contains(lower_ref),
2297 Some(DialectType::MySQL) | Some(DialectType::TiDB) => {
2298 reserved_keywords::MYSQL_RESERVED.contains(lower_ref)
2299 }
2300 Some(DialectType::Doris) => reserved_keywords::DORIS_RESERVED.contains(lower_ref),
2301 Some(DialectType::SingleStore) => {
2302 reserved_keywords::SINGLESTORE_RESERVED.contains(lower_ref)
2303 }
2304 Some(DialectType::StarRocks) => {
2305 reserved_keywords::STARROCKS_RESERVED.contains(lower_ref)
2306 }
2307 Some(DialectType::PostgreSQL)
2308 | Some(DialectType::CockroachDB)
2309 | Some(DialectType::Materialize)
2310 | Some(DialectType::RisingWave) => {
2311 reserved_keywords::POSTGRES_RESERVED.contains(lower_ref)
2312 }
2313 Some(DialectType::Redshift) => reserved_keywords::REDSHIFT_RESERVED.contains(lower_ref),
2314 Some(DialectType::Snowflake) => false,
2317 Some(DialectType::ClickHouse) => false,
2319 Some(DialectType::DuckDB) => reserved_keywords::DUCKDB_RESERVED.contains(lower_ref),
2320 Some(DialectType::Teradata) => false,
2322 Some(DialectType::TSQL)
2324 | Some(DialectType::Fabric)
2325 | Some(DialectType::Oracle)
2326 | Some(DialectType::Spark)
2327 | Some(DialectType::Databricks)
2328 | Some(DialectType::Hive)
2329 | Some(DialectType::Solr) => false,
2330 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
2331 reserved_keywords::PRESTO_TRINO_RESERVED.contains(lower_ref)
2332 }
2333 Some(DialectType::SQLite) => reserved_keywords::SQLITE_RESERVED.contains(lower_ref),
2334 Some(DialectType::Generic) | None => false,
2336 _ => reserved_keywords::SQL_RESERVED.contains(lower_ref),
2338 }
2339 }
2340
2341 fn normalize_func_name<'a>(&self, name: &'a str) -> Cow<'a, str> {
2343 match self.config.normalize_functions {
2344 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
2345 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
2346 NormalizeFunctions::None => Cow::Borrowed(name),
2347 }
2348 }
2349
2350 pub fn generate(&mut self, expr: &Expression) -> Result<String> {
2359 self.output.clear();
2360 self.unsupported_messages.clear();
2361 self.generate_expression(expr)?;
2362 if self.config.unsupported_level == UnsupportedLevel::Raise
2363 && !self.unsupported_messages.is_empty()
2364 {
2365 return Err(crate::error::Error::generate(
2366 self.format_unsupported_messages(),
2367 ));
2368 }
2369 Ok(std::mem::take(&mut self.output))
2370 }
2371
2372 pub fn unsupported_messages(&self) -> &[String] {
2374 &self.unsupported_messages
2375 }
2376
2377 fn unsupported(&mut self, message: impl Into<String>) -> Result<()> {
2378 let message = message.into();
2379 if self.config.unsupported_level == UnsupportedLevel::Immediate {
2380 return Err(crate::error::Error::generate(message));
2381 }
2382 self.unsupported_messages.push(message);
2383 Ok(())
2384 }
2385
2386 fn write_unsupported_comment(&mut self, message: &str) -> Result<()> {
2387 self.unsupported(message.to_string())?;
2388 self.write("/* ");
2389 self.write(message);
2390 self.write(" */");
2391 Ok(())
2392 }
2393
2394 fn format_unsupported_messages(&self) -> String {
2395 let limit = self.config.max_unsupported.max(1);
2396 if self.unsupported_messages.len() <= limit {
2397 return self.unsupported_messages.join("; ");
2398 }
2399
2400 let mut messages = self
2401 .unsupported_messages
2402 .iter()
2403 .take(limit)
2404 .cloned()
2405 .collect::<Vec<_>>();
2406 messages.push(format!(
2407 "... and {} more",
2408 self.unsupported_messages.len() - limit
2409 ));
2410 messages.join("; ")
2411 }
2412
2413 pub fn sql(expr: &Expression) -> Result<String> {
2419 let mut gen = Generator::new();
2420 gen.generate(expr)
2421 }
2422
2423 pub fn pretty_sql(expr: &Expression) -> Result<String> {
2428 let config = GeneratorConfig {
2429 pretty: true,
2430 ..Default::default()
2431 };
2432 let mut gen = Generator::with_config(config);
2433 let mut sql = gen.generate(expr)?;
2434 if !sql.ends_with(';') {
2436 sql.push(';');
2437 }
2438 Ok(sql)
2439 }
2440
2441 fn generate_expression(&mut self, expr: &Expression) -> Result<()> {
2442 match expr {
2443 Expression::Select(select) => self.generate_select(select),
2444 Expression::Union(union) => self.generate_union(union),
2445 Expression::Intersect(intersect) => self.generate_intersect(intersect),
2446 Expression::Except(except) => self.generate_except(except),
2447 Expression::Insert(insert) => self.generate_insert(insert),
2448 Expression::Update(update) => self.generate_update(update),
2449 Expression::Delete(delete) => self.generate_delete(delete),
2450 Expression::Literal(lit) => self.generate_literal(lit),
2451 Expression::Boolean(b) => self.generate_boolean(b),
2452 Expression::Null(_) => {
2453 self.write_keyword("NULL");
2454 Ok(())
2455 }
2456 Expression::Identifier(id) => self.generate_identifier(id),
2457 Expression::Column(col) => self.generate_column(col),
2458 Expression::Pseudocolumn(pc) => self.generate_pseudocolumn(pc),
2459 Expression::Connect(c) => self.generate_connect_expr(c),
2460 Expression::Prior(p) => self.generate_prior(p),
2461 Expression::ConnectByRoot(cbr) => self.generate_connect_by_root(cbr),
2462 Expression::MatchRecognize(mr) => self.generate_match_recognize(mr),
2463 Expression::Table(table) => self.generate_table(table),
2464 Expression::StageReference(sr) => self.generate_stage_reference(sr),
2465 Expression::HistoricalData(hd) => self.generate_historical_data(hd),
2466 Expression::JoinedTable(jt) => self.generate_joined_table(jt),
2467 Expression::Star(star) => self.generate_star(star),
2468 Expression::BracedWildcard(expr) => self.generate_braced_wildcard(expr),
2469 Expression::Alias(alias) => self.generate_alias(alias),
2470 Expression::Cast(cast) => self.generate_cast(cast),
2471 Expression::Collation(coll) => self.generate_collation(coll),
2472 Expression::Case(case) => self.generate_case(case),
2473 Expression::Function(func) => self.generate_function(func),
2474 Expression::FunctionEmits(fe) => self.generate_function_emits(fe),
2475 Expression::AggregateFunction(func) => self.generate_aggregate_function(func),
2476 Expression::WindowFunction(wf) => self.generate_window_function(wf),
2477 Expression::WithinGroup(wg) => self.generate_within_group(wg),
2478 Expression::Interval(interval) => self.generate_interval(interval),
2479
2480 Expression::ConcatWs(f) => self.generate_concat_ws(f),
2482 Expression::Substring(f) => self.generate_substring(f),
2483 Expression::Upper(f) => self.generate_unary_func("UPPER", f),
2484 Expression::Lower(f) => self.generate_unary_func("LOWER", f),
2485 Expression::Length(f) => self.generate_unary_func("LENGTH", f),
2486 Expression::Trim(f) => self.generate_trim(f),
2487 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
2488 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
2489 Expression::Replace(f) => self.generate_replace(f),
2490 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
2491 Expression::Left(f) => self.generate_left_right("LEFT", f),
2492 Expression::Right(f) => self.generate_left_right("RIGHT", f),
2493 Expression::Repeat(f) => self.generate_repeat(f),
2494 Expression::Lpad(f) => self.generate_pad("LPAD", f),
2495 Expression::Rpad(f) => self.generate_pad("RPAD", f),
2496 Expression::Split(f) => self.generate_split(f),
2497 Expression::RegexpLike(f) => self.generate_regexp_like(f),
2498 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
2499 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
2500 Expression::Overlay(f) => self.generate_overlay(f),
2501
2502 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
2504 Expression::Round(f) => self.generate_round(f),
2505 Expression::Floor(f) => self.generate_floor(f),
2506 Expression::Ceil(f) => self.generate_ceil(f),
2507 Expression::Power(f) => self.generate_power(f),
2508 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
2509 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
2510 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
2511 Expression::Log(f) => self.generate_log(f),
2512 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
2513 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
2514 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
2515 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
2516
2517 Expression::CurrentDate(_) => {
2519 self.write_keyword("CURRENT_DATE");
2520 Ok(())
2521 }
2522 Expression::CurrentTime(f) => self.generate_current_time(f),
2523 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
2524 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
2525 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
2526 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
2527 Expression::DateDiff(f) => self.generate_datediff(f),
2528 Expression::DateTrunc(f) => self.generate_date_trunc(f),
2529 Expression::Extract(f) => self.generate_extract(f),
2530 Expression::ToDate(f) => self.generate_to_date(f),
2531 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
2532
2533 Expression::Coalesce(f) => {
2535 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
2537 self.generate_vararg_func(func_name, &f.expressions)
2538 }
2539 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
2540 Expression::IfFunc(f) => self.generate_if_func(f),
2541 Expression::IfNull(f) => self.generate_ifnull(f),
2542 Expression::Nvl(f) => self.generate_nvl(f),
2543 Expression::Nvl2(f) => self.generate_nvl2(f),
2544
2545 Expression::TryCast(cast) => self.generate_try_cast(cast),
2547 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
2548
2549 Expression::Count(f) => self.generate_count(f),
2551 Expression::Sum(f) => self.generate_agg_func("SUM", f),
2552 Expression::Avg(f) => self.generate_agg_func("AVG", f),
2553 Expression::Min(f) => self.generate_agg_func("MIN", f),
2554 Expression::Max(f) => self.generate_agg_func("MAX", f),
2555 Expression::GroupConcat(f) => self.generate_group_concat(f),
2556 Expression::StringAgg(f) => self.generate_string_agg(f),
2557 Expression::ListAgg(f) => self.generate_listagg(f),
2558 Expression::ArrayAgg(f) => {
2559 let override_name = f
2562 .name
2563 .as_ref()
2564 .filter(|n| !n.eq_ignore_ascii_case("ARRAY_AGG"))
2565 .map(|n| n.to_ascii_uppercase());
2566 match override_name {
2567 Some(name) => self.generate_agg_func(&name, f),
2568 None => self.generate_agg_func("ARRAY_AGG", f),
2569 }
2570 }
2571 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
2572 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
2573 Expression::SumIf(f) => self.generate_sum_if(f),
2574 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
2575 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
2576 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
2577 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
2578 Expression::VarPop(f) => {
2579 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
2580 "VARIANCE_POP"
2581 } else {
2582 "VAR_POP"
2583 };
2584 self.generate_agg_func(name, f)
2585 }
2586 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
2587 Expression::Skewness(f) => {
2588 let name = match self.config.dialect {
2589 Some(DialectType::Snowflake) => "SKEW",
2590 _ => "SKEWNESS",
2591 };
2592 self.generate_agg_func(name, f)
2593 }
2594 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
2595 Expression::Mode(f) => self.generate_agg_func("MODE", f),
2596 Expression::First(f) => self.generate_agg_func_with_ignore_nulls_bool("FIRST", f),
2597 Expression::Last(f) => self.generate_agg_func_with_ignore_nulls_bool("LAST", f),
2598 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
2599 Expression::ApproxDistinct(f) => {
2600 match self.config.dialect {
2601 Some(DialectType::Hive)
2602 | Some(DialectType::Spark)
2603 | Some(DialectType::Databricks)
2604 | Some(DialectType::BigQuery) => {
2605 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2607 }
2608 Some(DialectType::Redshift) => {
2609 self.write_keyword("APPROXIMATE COUNT");
2611 self.write("(");
2612 self.write_keyword("DISTINCT");
2613 self.write(" ");
2614 self.generate_expression(&f.this)?;
2615 self.write(")");
2616 Ok(())
2617 }
2618 _ => self.generate_agg_func("APPROX_DISTINCT", f),
2619 }
2620 }
2621 Expression::ApproxCountDistinct(f) => {
2622 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2623 }
2624 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
2625 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
2626 Expression::LogicalAnd(f) => {
2627 let name = match self.config.dialect {
2628 Some(DialectType::Snowflake) => "BOOLAND_AGG",
2629 Some(DialectType::Spark)
2630 | Some(DialectType::Databricks)
2631 | Some(DialectType::PostgreSQL)
2632 | Some(DialectType::DuckDB)
2633 | Some(DialectType::Redshift) => "BOOL_AND",
2634 Some(DialectType::Oracle)
2635 | Some(DialectType::SQLite)
2636 | Some(DialectType::MySQL) => "MIN",
2637 _ => "BOOL_AND",
2638 };
2639 self.generate_agg_func(name, f)
2640 }
2641 Expression::LogicalOr(f) => {
2642 let name = match self.config.dialect {
2643 Some(DialectType::Snowflake) => "BOOLOR_AGG",
2644 Some(DialectType::Spark)
2645 | Some(DialectType::Databricks)
2646 | Some(DialectType::PostgreSQL)
2647 | Some(DialectType::DuckDB)
2648 | Some(DialectType::Redshift) => "BOOL_OR",
2649 Some(DialectType::Oracle)
2650 | Some(DialectType::SQLite)
2651 | Some(DialectType::MySQL) => "MAX",
2652 _ => "BOOL_OR",
2653 };
2654 self.generate_agg_func(name, f)
2655 }
2656
2657 Expression::RowNumber(_) => {
2659 if self.config.dialect == Some(DialectType::ClickHouse) {
2660 self.write("row_number");
2661 } else {
2662 self.write_keyword("ROW_NUMBER");
2663 }
2664 self.write("()");
2665 Ok(())
2666 }
2667 Expression::Rank(r) => {
2668 self.write_keyword("RANK");
2669 self.write("(");
2670 if !r.args.is_empty() {
2672 for (i, arg) in r.args.iter().enumerate() {
2673 if i > 0 {
2674 self.write(", ");
2675 }
2676 self.generate_expression(arg)?;
2677 }
2678 } else if let Some(order_by) = &r.order_by {
2679 self.write_keyword(" ORDER BY ");
2681 for (i, ob) in order_by.iter().enumerate() {
2682 if i > 0 {
2683 self.write(", ");
2684 }
2685 self.generate_ordered(ob)?;
2686 }
2687 }
2688 self.write(")");
2689 Ok(())
2690 }
2691 Expression::DenseRank(dr) => {
2692 self.write_keyword("DENSE_RANK");
2693 self.write("(");
2694 for (i, arg) in dr.args.iter().enumerate() {
2696 if i > 0 {
2697 self.write(", ");
2698 }
2699 self.generate_expression(arg)?;
2700 }
2701 self.write(")");
2702 Ok(())
2703 }
2704 Expression::NTile(f) => self.generate_ntile(f),
2705 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
2706 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
2707 Expression::FirstValue(f) => {
2708 self.generate_value_func_with_ignore_nulls_bool("FIRST_VALUE", f)
2709 }
2710 Expression::LastValue(f) => {
2711 self.generate_value_func_with_ignore_nulls_bool("LAST_VALUE", f)
2712 }
2713 Expression::NthValue(f) => self.generate_nth_value(f),
2714 Expression::PercentRank(pr) => {
2715 self.write_keyword("PERCENT_RANK");
2716 self.write("(");
2717 if !pr.args.is_empty() {
2719 for (i, arg) in pr.args.iter().enumerate() {
2720 if i > 0 {
2721 self.write(", ");
2722 }
2723 self.generate_expression(arg)?;
2724 }
2725 } else if let Some(order_by) = &pr.order_by {
2726 self.write_keyword(" ORDER BY ");
2728 for (i, ob) in order_by.iter().enumerate() {
2729 if i > 0 {
2730 self.write(", ");
2731 }
2732 self.generate_ordered(ob)?;
2733 }
2734 }
2735 self.write(")");
2736 Ok(())
2737 }
2738 Expression::CumeDist(cd) => {
2739 self.write_keyword("CUME_DIST");
2740 self.write("(");
2741 if !cd.args.is_empty() {
2743 for (i, arg) in cd.args.iter().enumerate() {
2744 if i > 0 {
2745 self.write(", ");
2746 }
2747 self.generate_expression(arg)?;
2748 }
2749 } else if let Some(order_by) = &cd.order_by {
2750 self.write_keyword(" ORDER BY ");
2752 for (i, ob) in order_by.iter().enumerate() {
2753 if i > 0 {
2754 self.write(", ");
2755 }
2756 self.generate_ordered(ob)?;
2757 }
2758 }
2759 self.write(")");
2760 Ok(())
2761 }
2762 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
2763 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
2764
2765 Expression::Contains(f) => {
2767 self.generate_binary_func("CONTAINS", &f.this, &f.expression)
2768 }
2769 Expression::StartsWith(f) => {
2770 let name = match self.config.dialect {
2771 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
2772 _ => "STARTS_WITH",
2773 };
2774 self.generate_binary_func(name, &f.this, &f.expression)
2775 }
2776 Expression::EndsWith(f) => {
2777 let name = match self.config.dialect {
2778 Some(DialectType::Snowflake) => "ENDSWITH",
2779 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
2780 Some(DialectType::ClickHouse) => "endsWith",
2781 _ => "ENDS_WITH",
2782 };
2783 self.generate_binary_func(name, &f.this, &f.expression)
2784 }
2785 Expression::Position(f) => self.generate_position(f),
2786 Expression::Initcap(f) => match self.config.dialect {
2787 Some(DialectType::Presto)
2788 | Some(DialectType::Trino)
2789 | Some(DialectType::Athena) => {
2790 self.write_keyword("REGEXP_REPLACE");
2791 self.write("(");
2792 self.generate_expression(&f.this)?;
2793 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
2794 Ok(())
2795 }
2796 _ => self.generate_simple_func("INITCAP", &f.this),
2797 },
2798 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
2799 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
2800 Expression::CharFunc(f) => self.generate_char_func(f),
2801 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
2802 Expression::Levenshtein(f) => {
2803 self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression)
2804 }
2805
2806 Expression::ModFunc(f) => self.generate_mod_func(f),
2808 Expression::Random(_) => {
2809 self.write_keyword("RANDOM");
2810 self.write("()");
2811 Ok(())
2812 }
2813 Expression::Rand(f) => self.generate_rand(f),
2814 Expression::TruncFunc(f) => self.generate_truncate_func(f),
2815 Expression::Pi(_) => {
2816 self.write_keyword("PI");
2817 self.write("()");
2818 Ok(())
2819 }
2820 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
2821 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
2822 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
2823 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
2824 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
2825 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
2826 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
2827 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
2828 Expression::Atan2(f) => {
2829 let name = f.original_name.as_deref().unwrap_or("ATAN2");
2830 self.generate_binary_func(name, &f.this, &f.expression)
2831 }
2832
2833 Expression::Decode(f) => self.generate_decode(f),
2835
2836 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
2838 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
2839 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
2840 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
2841 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
2842 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
2843 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
2844 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
2845 Expression::DayOfWeek(f) => {
2846 let name = match self.config.dialect {
2847 Some(DialectType::Presto)
2848 | Some(DialectType::Trino)
2849 | Some(DialectType::Athena) => "DAY_OF_WEEK",
2850 Some(DialectType::DuckDB) => "ISODOW",
2851 _ => "DAYOFWEEK",
2852 };
2853 self.generate_simple_func(name, &f.this)
2854 }
2855 Expression::DayOfMonth(f) => {
2856 let name = match self.config.dialect {
2857 Some(DialectType::Presto)
2858 | Some(DialectType::Trino)
2859 | Some(DialectType::Athena) => "DAY_OF_MONTH",
2860 _ => "DAYOFMONTH",
2861 };
2862 self.generate_simple_func(name, &f.this)
2863 }
2864 Expression::DayOfYear(f) => {
2865 let name = match self.config.dialect {
2866 Some(DialectType::Presto)
2867 | Some(DialectType::Trino)
2868 | Some(DialectType::Athena) => "DAY_OF_YEAR",
2869 _ => "DAYOFYEAR",
2870 };
2871 self.generate_simple_func(name, &f.this)
2872 }
2873 Expression::WeekOfYear(f) => {
2874 let name = match self.config.dialect {
2876 Some(DialectType::Hive)
2877 | Some(DialectType::DuckDB)
2878 | Some(DialectType::Spark)
2879 | Some(DialectType::Databricks)
2880 | Some(DialectType::MySQL) => "WEEKOFYEAR",
2881 _ => "WEEK_OF_YEAR",
2882 };
2883 self.generate_simple_func(name, &f.this)
2884 }
2885 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
2886 Expression::AddMonths(f) => {
2887 self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression)
2888 }
2889 Expression::MonthsBetween(f) => {
2890 self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression)
2891 }
2892 Expression::LastDay(f) => self.generate_last_day(f),
2893 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
2894 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
2895 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
2896 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
2897 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
2898 Expression::MakeDate(f) => self.generate_make_date(f),
2899 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
2900 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
2901
2902 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
2904 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
2905 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
2906 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
2907 Expression::ArrayContains(f) => {
2908 self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression)
2909 }
2910 Expression::ArrayPosition(f) => {
2911 self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression)
2912 }
2913 Expression::ArrayAppend(f) => {
2914 self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression)
2915 }
2916 Expression::ArrayPrepend(f) => {
2917 self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression)
2918 }
2919 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
2920 Expression::ArraySort(f) => self.generate_array_sort(f),
2921 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
2922 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
2923 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
2924 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
2925 Expression::Unnest(f) => self.generate_unnest(f),
2926 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
2927 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
2928 Expression::ArrayFilter(f) => self.generate_array_filter(f),
2929 Expression::ArrayTransform(f) => self.generate_array_transform(f),
2930 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
2931 Expression::ArrayCompact(f) => {
2932 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
2933 self.write("LIST_FILTER(");
2935 self.generate_expression(&f.this)?;
2936 self.write(", _u -> NOT _u IS NULL)");
2937 Ok(())
2938 } else {
2939 self.generate_simple_func("ARRAY_COMPACT", &f.this)
2940 }
2941 }
2942 Expression::ArrayIntersect(f) => {
2943 let func_name = f.original_name.as_deref().unwrap_or("ARRAY_INTERSECT");
2944 self.generate_vararg_func(func_name, &f.expressions)
2945 }
2946 Expression::ArrayUnion(f) => {
2947 self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression)
2948 }
2949 Expression::ArrayExcept(f) => {
2950 self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression)
2951 }
2952 Expression::ArrayRemove(f) => {
2953 self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression)
2954 }
2955 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
2956 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
2957 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
2958
2959 Expression::StructFunc(f) => self.generate_struct_constructor(f),
2961 Expression::StructExtract(f) => self.generate_struct_extract(f),
2962 Expression::NamedStruct(f) => self.generate_named_struct(f),
2963
2964 Expression::MapFunc(f) => self.generate_map_constructor(f),
2966 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
2967 Expression::MapFromArrays(f) => {
2968 self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression)
2969 }
2970 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
2971 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
2972 Expression::MapContainsKey(f) => {
2973 self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression)
2974 }
2975 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
2976 Expression::ElementAt(f) => {
2977 self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression)
2978 }
2979 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
2980 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
2981
2982 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
2984 Expression::JsonExtractScalar(f) => {
2985 self.generate_json_extract("JSON_EXTRACT_SCALAR", f)
2986 }
2987 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
2988 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
2989 Expression::JsonObject(f) => self.generate_json_object(f),
2990 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
2991 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
2992 Expression::JsonArrayLength(f) => {
2993 self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this)
2994 }
2995 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
2996 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
2997 Expression::ParseJson(f) => {
2998 let name = match self.config.dialect {
2999 Some(DialectType::Presto)
3000 | Some(DialectType::Trino)
3001 | Some(DialectType::Athena) => "JSON_PARSE",
3002 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
3003 self.write_keyword("CAST");
3005 self.write("(");
3006 self.generate_expression(&f.this)?;
3007 self.write_keyword(" AS ");
3008 self.write_keyword("JSON");
3009 self.write(")");
3010 return Ok(());
3011 }
3012 Some(DialectType::Hive)
3013 | Some(DialectType::Spark)
3014 | Some(DialectType::MySQL)
3015 | Some(DialectType::SingleStore)
3016 | Some(DialectType::TiDB)
3017 | Some(DialectType::TSQL) => {
3018 self.generate_expression(&f.this)?;
3020 return Ok(());
3021 }
3022 Some(DialectType::DuckDB) => "JSON",
3023 _ => "PARSE_JSON",
3024 };
3025 self.generate_simple_func(name, &f.this)
3026 }
3027 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
3028 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
3029 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
3030 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
3031 Expression::JsonMergePatch(f) => {
3032 self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression)
3033 }
3034 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
3035 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
3036
3037 Expression::Convert(f) => self.generate_convert(f),
3039 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
3040
3041 Expression::Lambda(f) => self.generate_lambda(f),
3043 Expression::Parameter(f) => self.generate_parameter(f),
3044 Expression::Placeholder(f) => self.generate_placeholder(f),
3045 Expression::NamedArgument(f) => self.generate_named_argument(f),
3046 Expression::TableArgument(f) => self.generate_table_argument(f),
3047 Expression::SqlComment(f) => self.generate_sql_comment(f),
3048
3049 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
3051 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
3052 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
3053 Expression::SimilarTo(f) => self.generate_similar_to(f),
3054 Expression::Any(f) => self.generate_quantified("ANY", f),
3055 Expression::All(f) => self.generate_quantified("ALL", f),
3056 Expression::Overlaps(f) => self.generate_overlaps(f),
3057
3058 Expression::BitwiseLeftShift(op) => {
3060 if matches!(
3061 self.config.dialect,
3062 Some(DialectType::Presto) | Some(DialectType::Trino)
3063 ) {
3064 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_LEFT");
3065 self.write("(");
3066 self.generate_expression(&op.left)?;
3067 self.write(", ");
3068 self.generate_expression(&op.right)?;
3069 self.write(")");
3070 Ok(())
3071 } else if matches!(
3072 self.config.dialect,
3073 Some(DialectType::Spark) | Some(DialectType::Databricks)
3074 ) {
3075 self.write_keyword("SHIFTLEFT");
3076 self.write("(");
3077 self.generate_expression(&op.left)?;
3078 self.write(", ");
3079 self.generate_expression(&op.right)?;
3080 self.write(")");
3081 Ok(())
3082 } else {
3083 self.generate_binary_op(op, "<<")
3084 }
3085 }
3086 Expression::BitwiseRightShift(op) => {
3087 if matches!(
3088 self.config.dialect,
3089 Some(DialectType::Presto) | Some(DialectType::Trino)
3090 ) {
3091 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_RIGHT");
3092 self.write("(");
3093 self.generate_expression(&op.left)?;
3094 self.write(", ");
3095 self.generate_expression(&op.right)?;
3096 self.write(")");
3097 Ok(())
3098 } else if matches!(
3099 self.config.dialect,
3100 Some(DialectType::Spark) | Some(DialectType::Databricks)
3101 ) {
3102 self.write_keyword("SHIFTRIGHT");
3103 self.write("(");
3104 self.generate_expression(&op.left)?;
3105 self.write(", ");
3106 self.generate_expression(&op.right)?;
3107 self.write(")");
3108 Ok(())
3109 } else {
3110 self.generate_binary_op(op, ">>")
3111 }
3112 }
3113 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
3114 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
3115 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
3116
3117 Expression::Subscript(s) => self.generate_subscript(s),
3119 Expression::Dot(d) => self.generate_dot_access(d),
3120 Expression::MethodCall(m) => self.generate_method_call(m),
3121 Expression::ArraySlice(s) => self.generate_array_slice(s),
3122
3123 Expression::And(op) => self.generate_connector_op(op, ConnectorOperator::And),
3124 Expression::Or(op) => self.generate_connector_op(op, ConnectorOperator::Or),
3125 Expression::Add(op) => self.generate_binary_op(op, "+"),
3126 Expression::Sub(op) => self.generate_binary_op(op, "-"),
3127 Expression::Mul(op) => self.generate_binary_op(op, "*"),
3128 Expression::Div(op) => self.generate_binary_op(op, "/"),
3129 Expression::IntDiv(f) => {
3130 use crate::dialects::DialectType;
3131 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
3132 self.generate_expression(&f.this)?;
3134 self.write(" // ");
3135 self.generate_expression(&f.expression)?;
3136 Ok(())
3137 } else if matches!(
3138 self.config.dialect,
3139 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
3140 ) {
3141 self.generate_expression(&f.this)?;
3143 self.write(" ");
3144 self.write_keyword("DIV");
3145 self.write(" ");
3146 self.generate_expression(&f.expression)?;
3147 Ok(())
3148 } else {
3149 self.write_keyword("DIV");
3151 self.write("(");
3152 self.generate_expression(&f.this)?;
3153 self.write(", ");
3154 self.generate_expression(&f.expression)?;
3155 self.write(")");
3156 Ok(())
3157 }
3158 }
3159 Expression::Mod(op) => {
3160 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
3161 self.generate_binary_op(op, "MOD")
3162 } else {
3163 self.generate_binary_op(op, "%")
3164 }
3165 }
3166 Expression::Eq(op) => self.generate_binary_op(op, "="),
3167 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
3168 Expression::Lt(op) => self.generate_binary_op(op, "<"),
3169 Expression::Lte(op) => self.generate_binary_op(op, "<="),
3170 Expression::Gt(op) => self.generate_binary_op(op, ">"),
3171 Expression::Gte(op) => self.generate_binary_op(op, ">="),
3172 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
3173 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
3174 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
3175 Expression::Concat(op) => {
3176 if self.config.dialect == Some(DialectType::Solr) {
3178 self.generate_binary_op(op, "OR")
3179 } else if self.config.dialect == Some(DialectType::MySQL) {
3180 self.generate_mysql_concat_from_concat(op)
3181 } else {
3182 self.generate_binary_op(op, "||")
3183 }
3184 }
3185 Expression::BitwiseAnd(op) => {
3186 if matches!(
3188 self.config.dialect,
3189 Some(DialectType::Presto) | Some(DialectType::Trino)
3190 ) {
3191 self.write_keyword("BITWISE_AND");
3192 self.write("(");
3193 self.generate_expression(&op.left)?;
3194 self.write(", ");
3195 self.generate_expression(&op.right)?;
3196 self.write(")");
3197 Ok(())
3198 } else {
3199 self.generate_binary_op(op, "&")
3200 }
3201 }
3202 Expression::BitwiseOr(op) => {
3203 if matches!(
3205 self.config.dialect,
3206 Some(DialectType::Presto) | Some(DialectType::Trino)
3207 ) {
3208 self.write_keyword("BITWISE_OR");
3209 self.write("(");
3210 self.generate_expression(&op.left)?;
3211 self.write(", ");
3212 self.generate_expression(&op.right)?;
3213 self.write(")");
3214 Ok(())
3215 } else {
3216 self.generate_binary_op(op, "|")
3217 }
3218 }
3219 Expression::BitwiseXor(op) => {
3220 if matches!(
3222 self.config.dialect,
3223 Some(DialectType::Presto) | Some(DialectType::Trino)
3224 ) {
3225 self.write_keyword("BITWISE_XOR");
3226 self.write("(");
3227 self.generate_expression(&op.left)?;
3228 self.write(", ");
3229 self.generate_expression(&op.right)?;
3230 self.write(")");
3231 Ok(())
3232 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
3233 self.generate_binary_op(op, "#")
3234 } else {
3235 self.generate_binary_op(op, "^")
3236 }
3237 }
3238 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
3239 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
3240 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
3241 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
3242 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
3243 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
3244 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
3245 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
3246 Expression::JSONBContains(f) => {
3247 self.generate_expression(&f.this)?;
3249 self.write_space();
3250 self.write("?");
3251 self.write_space();
3252 self.generate_expression(&f.expression)
3253 }
3254 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
3255 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
3256 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
3257 Expression::Not(op) => self.generate_unary_op(op, "NOT"),
3258 Expression::Neg(op) => self.generate_unary_op(op, "-"),
3259 Expression::BitwiseNot(op) => {
3260 if matches!(
3262 self.config.dialect,
3263 Some(DialectType::Presto) | Some(DialectType::Trino)
3264 ) {
3265 self.write_keyword("BITWISE_NOT");
3266 self.write("(");
3267 self.generate_expression(&op.this)?;
3268 self.write(")");
3269 Ok(())
3270 } else {
3271 self.generate_unary_op(op, "~")
3272 }
3273 }
3274 Expression::In(in_expr) => self.generate_in(in_expr),
3275 Expression::Between(between) => self.generate_between(between),
3276 Expression::IsNull(is_null) => self.generate_is_null(is_null),
3277 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
3278 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
3279 Expression::IsJson(is_json) => self.generate_is_json(is_json),
3280 Expression::Is(is_expr) => self.generate_is(is_expr),
3281 Expression::Exists(exists) => self.generate_exists(exists),
3282 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
3283 Expression::Subquery(subquery) => self.generate_subquery(subquery),
3284 Expression::Paren(paren) => {
3285 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
3287
3288 if !skip_parens {
3289 self.write("(");
3290 if self.config.pretty {
3291 self.write_newline();
3292 self.indent_level += 1;
3293 self.write_indent();
3294 }
3295 }
3296 self.generate_expression(&paren.this)?;
3297 if !skip_parens {
3298 if self.config.pretty {
3299 self.write_newline();
3300 self.indent_level -= 1;
3301 self.write_indent();
3302 }
3303 self.write(")");
3304 }
3305 for comment in &paren.trailing_comments {
3307 self.write(" ");
3308 self.write_formatted_comment(comment);
3309 }
3310 Ok(())
3311 }
3312 Expression::Array(arr) => self.generate_array(arr),
3313 Expression::Tuple(tuple) => self.generate_tuple(tuple),
3314 Expression::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
3315 Expression::Ordered(ordered) => self.generate_ordered(ordered),
3316 Expression::DataType(dt) => self.generate_data_type(dt),
3317 Expression::Raw(raw) => {
3318 self.write(&raw.sql);
3319 Ok(())
3320 }
3321 Expression::CreateTask(task) => self.generate_create_task(task),
3322 Expression::Command(cmd) => {
3323 self.write(&cmd.this);
3324 Ok(())
3325 }
3326 Expression::Kill(kill) => {
3327 self.write_keyword("KILL");
3328 if let Some(kind) = &kill.kind {
3329 self.write_space();
3330 self.write_keyword(kind);
3331 }
3332 self.write_space();
3333 self.generate_expression(&kill.this)?;
3334 Ok(())
3335 }
3336 Expression::Execute(exec) => {
3337 self.write_keyword("EXECUTE");
3338 self.write_space();
3339 self.generate_expression(&exec.this)?;
3340 for (i, param) in exec.parameters.iter().enumerate() {
3341 if i == 0 {
3342 self.write_space();
3343 } else {
3344 self.write(", ");
3345 }
3346 self.write(¶m.name);
3347 if !param.positional {
3349 self.write(" = ");
3350 self.generate_expression(¶m.value)?;
3351 }
3352 if param.output {
3353 self.write_space();
3354 self.write_keyword("OUTPUT");
3355 }
3356 }
3357 if let Some(ref suffix) = exec.suffix {
3358 self.write_space();
3359 self.write(suffix);
3360 }
3361 Ok(())
3362 }
3363 Expression::Annotated(annotated) => {
3364 self.generate_expression(&annotated.this)?;
3365 for comment in &annotated.trailing_comments {
3366 self.write(" ");
3367 self.write_formatted_comment(comment);
3368 }
3369 Ok(())
3370 }
3371
3372 Expression::CreateTable(ct) => self.generate_create_table(ct),
3374 Expression::DropTable(dt) => self.generate_drop_table(dt),
3375 Expression::Undrop(u) => self.generate_undrop(u),
3376 Expression::AlterTable(at) => self.generate_alter_table(at),
3377 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3378 Expression::DropIndex(di) => self.generate_drop_index(di),
3379 Expression::CreateView(cv) => self.generate_create_view(cv),
3380 Expression::DropView(dv) => self.generate_drop_view(dv),
3381 Expression::AlterView(av) => self.generate_alter_view(av),
3382 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3383 Expression::Truncate(tr) => self.generate_truncate(tr),
3384 Expression::Use(u) => self.generate_use(u),
3385 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3387 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3388 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3389 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3390 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3391 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3392 Expression::DropFunction(df) => self.generate_drop_function(df),
3393 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3394 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3395 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3396 Expression::CreateSynonym(cs) => {
3397 self.write_keyword("CREATE SYNONYM");
3398 self.write_space();
3399 self.generate_table(&cs.name)?;
3400 self.write_space();
3401 self.write_keyword("FOR");
3402 self.write_space();
3403 self.generate_table(&cs.target)?;
3404 Ok(())
3405 }
3406 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3407 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3408 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3409 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3410 Expression::CreateType(ct) => self.generate_create_type(ct),
3411 Expression::DropType(dt) => self.generate_drop_type(dt),
3412 Expression::Describe(d) => self.generate_describe(d),
3413 Expression::Show(s) => self.generate_show(s),
3414
3415 Expression::Cache(c) => self.generate_cache(c),
3417 Expression::Uncache(u) => self.generate_uncache(u),
3418 Expression::LoadData(l) => self.generate_load_data(l),
3419 Expression::Pragma(p) => self.generate_pragma(p),
3420 Expression::Grant(g) => self.generate_grant(g),
3421 Expression::Revoke(r) => self.generate_revoke(r),
3422 Expression::Comment(c) => self.generate_comment(c),
3423 Expression::SetStatement(s) => self.generate_set_statement(s),
3424
3425 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3427 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3428
3429 Expression::Values(values) => self.generate_values(values),
3431
3432 Expression::AIAgg(e) => self.generate_ai_agg(e),
3434 Expression::AIClassify(e) => self.generate_ai_classify(e),
3435 Expression::AddPartition(e) => self.generate_add_partition(e),
3436 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3437 Expression::Aliases(e) => self.generate_aliases(e),
3438 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3439 Expression::AlterColumn(e) => self.generate_alter_column(e),
3440 Expression::AlterSession(e) => self.generate_alter_session(e),
3441 Expression::AlterSet(e) => self.generate_alter_set(e),
3442 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3443 Expression::Analyze(e) => self.generate_analyze(e),
3444 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3445 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3446 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3447 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3448 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3449 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3450 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3451 Expression::Anonymous(e) => self.generate_anonymous(e),
3452 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3453 Expression::Apply(e) => self.generate_apply(e),
3454 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3455 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3456 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3457 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3458 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3459 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3460 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3461 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3462 Expression::ArgMax(e) => self.generate_arg_max(e),
3463 Expression::ArgMin(e) => self.generate_arg_min(e),
3464 Expression::ArrayAll(e) => self.generate_array_all(e),
3465 Expression::ArrayAny(e) => self.generate_array_any(e),
3466 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3467 Expression::ArraySum(e) => self.generate_array_sum(e),
3468 Expression::AtIndex(e) => self.generate_at_index(e),
3469 Expression::Attach(e) => self.generate_attach(e),
3470 Expression::AttachOption(e) => self.generate_attach_option(e),
3471 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3472 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3473 Expression::BackupProperty(e) => self.generate_backup_property(e),
3474 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3475 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3476 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3477 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3478 Expression::Booland(e) => self.generate_booland(e),
3479 Expression::Boolor(e) => self.generate_boolor(e),
3480 Expression::BuildProperty(e) => self.generate_build_property(e),
3481 Expression::ByteString(e) => self.generate_byte_string(e),
3482 Expression::CaseSpecificColumnConstraint(e) => {
3483 self.generate_case_specific_column_constraint(e)
3484 }
3485 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3486 Expression::Changes(e) => self.generate_changes(e),
3487 Expression::CharacterSetColumnConstraint(e) => {
3488 self.generate_character_set_column_constraint(e)
3489 }
3490 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3491 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3492 Expression::AssumeColumnConstraint(e) => self.generate_assume_column_constraint(e),
3493 Expression::CheckJson(e) => self.generate_check_json(e),
3494 Expression::CheckXml(e) => self.generate_check_xml(e),
3495 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3496 Expression::Clone(e) => self.generate_clone(e),
3497 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3498 Expression::ClusterByColumnsProperty(e) => self.generate_cluster_by_columns_property(e),
3499 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3500 Expression::CollateProperty(e) => self.generate_collate_property(e),
3501 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3502 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3503 Expression::ColumnPosition(e) => self.generate_column_position(e),
3504 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3505 Expression::Columns(e) => self.generate_columns(e),
3506 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3507 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3508 Expression::Commit(e) => self.generate_commit(e),
3509 Expression::Comprehension(e) => self.generate_comprehension(e),
3510 Expression::Compress(e) => self.generate_compress(e),
3511 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3512 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3513 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3514 Expression::Constraint(e) => self.generate_constraint(e),
3515 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3516 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3517 Expression::Copy(e) => self.generate_copy(e),
3518 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3519 Expression::Corr(e) => self.generate_corr(e),
3520 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3521 Expression::CovarPop(e) => self.generate_covar_pop(e),
3522 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3523 Expression::Credentials(e) => self.generate_credentials(e),
3524 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3525 Expression::Cte(e) => self.generate_cte(e),
3526 Expression::Cube(e) => self.generate_cube(e),
3527 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3528 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3529 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3530 Expression::CurrentUser(e) => self.generate_current_user(e),
3531 Expression::DPipe(e) => self.generate_d_pipe(e),
3532 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3533 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3534 Expression::Date(e) => self.generate_date_func(e),
3535 Expression::DateBin(e) => self.generate_date_bin(e),
3536 Expression::DateFormatColumnConstraint(e) => {
3537 self.generate_date_format_column_constraint(e)
3538 }
3539 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3540 Expression::Datetime(e) => self.generate_datetime(e),
3541 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3542 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3543 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3544 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3545 Expression::Dayname(e) => self.generate_dayname(e),
3546 Expression::Declare(e) => self.generate_declare(e),
3547 Expression::DeclareItem(e) => self.generate_declare_item(e),
3548 Expression::DecodeCase(e) => self.generate_decode_case(e),
3549 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3550 Expression::DecompressString(e) => self.generate_decompress_string(e),
3551 Expression::Decrypt(e) => self.generate_decrypt(e),
3552 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3553 Expression::DefaultColumnConstraint(e) => {
3554 self.write_keyword("DEFAULT");
3555 self.write_space();
3556 self.generate_expression(&e.this)?;
3557 if let Some(ref col) = e.for_column {
3558 self.write_space();
3559 self.write_keyword("FOR");
3560 self.write_space();
3561 self.generate_identifier(col)?;
3562 }
3563 Ok(())
3564 }
3565 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3566 Expression::Detach(e) => self.generate_detach(e),
3567 Expression::DictProperty(e) => self.generate_dict_property(e),
3568 Expression::DictRange(e) => self.generate_dict_range(e),
3569 Expression::Directory(e) => self.generate_directory(e),
3570 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3571 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3572 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3573 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3574 Expression::DotProduct(e) => self.generate_dot_product(e),
3575 Expression::DropPartition(e) => self.generate_drop_partition(e),
3576 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3577 Expression::Elt(e) => self.generate_elt(e),
3578 Expression::Encode(e) => self.generate_encode(e),
3579 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3580 Expression::Encrypt(e) => self.generate_encrypt(e),
3581 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3582 Expression::EngineProperty(e) => self.generate_engine_property(e),
3583 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3584 Expression::EphemeralColumnConstraint(e) => {
3585 self.generate_ephemeral_column_constraint(e)
3586 }
3587 Expression::EqualNull(e) => self.generate_equal_null(e),
3588 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3589 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3590 Expression::Export(e) => self.generate_export(e),
3591 Expression::ExternalProperty(e) => self.generate_external_property(e),
3592 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3593 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3594 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3595 Expression::Fetch(e) => self.generate_fetch(e),
3596 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3597 Expression::Filter(e) => self.generate_filter(e),
3598 Expression::Float64(e) => self.generate_float64(e),
3599 Expression::ForIn(e) => self.generate_for_in(e),
3600 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3601 Expression::Format(e) => self.generate_format(e),
3602 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3603 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3604 Expression::From(e) => self.generate_from(e),
3605 Expression::FromBase(e) => self.generate_from_base(e),
3606 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3607 Expression::GapFill(e) => self.generate_gap_fill(e),
3608 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3609 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3610 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3611 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3612 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3613 self.generate_generated_as_identity_column_constraint(e)
3614 }
3615 Expression::GeneratedAsRowColumnConstraint(e) => {
3616 self.generate_generated_as_row_column_constraint(e)
3617 }
3618 Expression::Get(e) => self.generate_get(e),
3619 Expression::GetExtract(e) => self.generate_get_extract(e),
3620 Expression::Getbit(e) => self.generate_getbit(e),
3621 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3622 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3623 Expression::Group(e) => self.generate_group(e),
3624 Expression::GroupBy(e) => self.generate_group_by(e),
3625 Expression::Grouping(e) => self.generate_grouping(e),
3626 Expression::GroupingId(e) => self.generate_grouping_id(e),
3627 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3628 Expression::HashAgg(e) => self.generate_hash_agg(e),
3629 Expression::Having(e) => self.generate_having(e),
3630 Expression::HavingMax(e) => self.generate_having_max(e),
3631 Expression::Heredoc(e) => self.generate_heredoc(e),
3632 Expression::HexEncode(e) => self.generate_hex_encode(e),
3633 Expression::Hll(e) => self.generate_hll(e),
3634 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3635 Expression::IncludeProperty(e) => self.generate_include_property(e),
3636 Expression::Index(e) => self.generate_index(e),
3637 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3638 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3639 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3640 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3641 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3642 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3643 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3644 Expression::Install(e) => self.generate_install(e),
3645 Expression::IntervalOp(e) => self.generate_interval_op(e),
3646 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3647 Expression::IntoClause(e) => self.generate_into_clause(e),
3648 Expression::Introducer(e) => self.generate_introducer(e),
3649 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3650 Expression::JSON(e) => self.generate_json(e),
3651 Expression::JSONArray(e) => self.generate_json_array(e),
3652 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3653 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3654 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3655 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3656 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3657 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3658 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3659 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3660 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3661 Expression::JSONExists(e) => self.generate_json_exists(e),
3662 Expression::JSONCast(e) => self.generate_json_cast(e),
3663 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3664 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3665 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3666 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3667 Expression::JSONFormat(e) => self.generate_json_format(e),
3668 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3669 Expression::JSONKeys(e) => self.generate_json_keys(e),
3670 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3671 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3672 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3673 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3674 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3675 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3676 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3677 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3678 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3679 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3680 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3681 Expression::JSONRemove(e) => self.generate_json_remove(e),
3682 Expression::JSONSchema(e) => self.generate_json_schema(e),
3683 Expression::JSONSet(e) => self.generate_json_set(e),
3684 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3685 Expression::JSONTable(e) => self.generate_json_table(e),
3686 Expression::JSONType(e) => self.generate_json_type(e),
3687 Expression::JSONValue(e) => self.generate_json_value(e),
3688 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3689 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3690 Expression::JoinHint(e) => self.generate_join_hint(e),
3691 Expression::JournalProperty(e) => self.generate_journal_property(e),
3692 Expression::LanguageProperty(e) => self.generate_language_property(e),
3693 Expression::Lateral(e) => self.generate_lateral(e),
3694 Expression::LikeProperty(e) => self.generate_like_property(e),
3695 Expression::Limit(e) => self.generate_limit(e),
3696 Expression::LimitOptions(e) => self.generate_limit_options(e),
3697 Expression::List(e) => self.generate_list(e),
3698 Expression::ToMap(e) => self.generate_tomap(e),
3699 Expression::Localtime(e) => self.generate_localtime(e),
3700 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3701 Expression::LocationProperty(e) => self.generate_location_property(e),
3702 Expression::Lock(e) => self.generate_lock(e),
3703 Expression::LockProperty(e) => self.generate_lock_property(e),
3704 Expression::LockingProperty(e) => self.generate_locking_property(e),
3705 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3706 Expression::LogProperty(e) => self.generate_log_property(e),
3707 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3708 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3709 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3710 Expression::MakeInterval(e) => self.generate_make_interval(e),
3711 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3712 Expression::Map(e) => self.generate_map(e),
3713 Expression::MapCat(e) => self.generate_map_cat(e),
3714 Expression::MapDelete(e) => self.generate_map_delete(e),
3715 Expression::MapInsert(e) => self.generate_map_insert(e),
3716 Expression::MapPick(e) => self.generate_map_pick(e),
3717 Expression::MaskingPolicyColumnConstraint(e) => {
3718 self.generate_masking_policy_column_constraint(e)
3719 }
3720 Expression::MatchAgainst(e) => self.generate_match_against(e),
3721 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3722 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3723 Expression::Merge(e) => self.generate_merge(e),
3724 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3725 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3726 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3727 Expression::Minhash(e) => self.generate_minhash(e),
3728 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3729 Expression::Monthname(e) => self.generate_monthname(e),
3730 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3731 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3732 Expression::Normal(e) => self.generate_normal(e),
3733 Expression::Normalize(e) => self.generate_normalize(e),
3734 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3735 Expression::Nullif(e) => self.generate_nullif(e),
3736 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3737 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3738 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3739 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3740 Expression::Offset(e) => self.generate_offset(e),
3741 Expression::Qualify(e) => self.generate_qualify(e),
3742 Expression::OnCluster(e) => self.generate_on_cluster(e),
3743 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3744 Expression::OnCondition(e) => self.generate_on_condition(e),
3745 Expression::OnConflict(e) => self.generate_on_conflict(e),
3746 Expression::OnProperty(e) => self.generate_on_property(e),
3747 Expression::Opclass(e) => self.generate_opclass(e),
3748 Expression::OpenJSON(e) => self.generate_open_json(e),
3749 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3750 Expression::Operator(e) => self.generate_operator(e),
3751 Expression::OrderBy(e) => self.generate_order_by(e),
3752 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3753 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3754 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3755 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3756 Expression::ParseIp(e) => self.generate_parse_ip(e),
3757 Expression::ParseJSON(e) => self.generate_parse_json(e),
3758 Expression::ParseTime(e) => self.generate_parse_time(e),
3759 Expression::ParseUrl(e) => self.generate_parse_url(e),
3760 Expression::Partition(e) => self.generate_partition_expr(e),
3761 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3762 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3763 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3764 Expression::PartitionByRangePropertyDynamic(e) => {
3765 self.generate_partition_by_range_property_dynamic(e)
3766 }
3767 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3768 Expression::PartitionList(e) => self.generate_partition_list(e),
3769 Expression::PartitionRange(e) => self.generate_partition_range(e),
3770 Expression::PartitionByProperty(e) => self.generate_partition_by_property(e),
3771 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3772 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3773 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3774 Expression::PeriodForSystemTimeConstraint(e) => {
3775 self.generate_period_for_system_time_constraint(e)
3776 }
3777 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3778 Expression::PivotAny(e) => self.generate_pivot_any(e),
3779 Expression::Predict(e) => self.generate_predict(e),
3780 Expression::PreviousDay(e) => self.generate_previous_day(e),
3781 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3782 Expression::PrimaryKeyColumnConstraint(e) => {
3783 self.generate_primary_key_column_constraint(e)
3784 }
3785 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3786 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3787 Expression::OptionsProperty(e) => self.generate_options_property(e),
3788 Expression::Properties(e) => self.generate_properties(e),
3789 Expression::Property(e) => self.generate_property(e),
3790 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3791 Expression::Put(e) => self.generate_put(e),
3792 Expression::Quantile(e) => self.generate_quantile(e),
3793 Expression::QueryBand(e) => self.generate_query_band(e),
3794 Expression::QueryOption(e) => self.generate_query_option(e),
3795 Expression::QueryTransform(e) => self.generate_query_transform(e),
3796 Expression::Randn(e) => self.generate_randn(e),
3797 Expression::Randstr(e) => self.generate_randstr(e),
3798 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3799 Expression::RangeN(e) => self.generate_range_n(e),
3800 Expression::ReadCSV(e) => self.generate_read_csv(e),
3801 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3802 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3803 Expression::Reduce(e) => self.generate_reduce(e),
3804 Expression::Reference(e) => self.generate_reference(e),
3805 Expression::Refresh(e) => self.generate_refresh(e),
3806 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3807 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3808 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3809 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3810 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3811 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3812 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3813 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3814 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3815 Expression::RegrCount(e) => self.generate_regr_count(e),
3816 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3817 Expression::RegrR2(e) => self.generate_regr_r2(e),
3818 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3819 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3820 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3821 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3822 Expression::RegrValx(e) => self.generate_regr_valx(e),
3823 Expression::RegrValy(e) => self.generate_regr_valy(e),
3824 Expression::RemoteWithConnectionModelProperty(e) => {
3825 self.generate_remote_with_connection_model_property(e)
3826 }
3827 Expression::RenameColumn(e) => self.generate_rename_column(e),
3828 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3829 Expression::Returning(e) => self.generate_returning(e),
3830 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3831 Expression::Rollback(e) => self.generate_rollback(e),
3832 Expression::Rollup(e) => self.generate_rollup(e),
3833 Expression::RowFormatDelimitedProperty(e) => {
3834 self.generate_row_format_delimited_property(e)
3835 }
3836 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3837 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3838 Expression::SHA2(e) => self.generate_sha2(e),
3839 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3840 Expression::SafeAdd(e) => self.generate_safe_add(e),
3841 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3842 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3843 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3844 Expression::SampleProperty(e) => self.generate_sample_property(e),
3845 Expression::Schema(e) => self.generate_schema(e),
3846 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3847 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3848 Expression::Search(e) => self.generate_search(e),
3849 Expression::SearchIp(e) => self.generate_search_ip(e),
3850 Expression::SecurityProperty(e) => self.generate_security_property(e),
3851 Expression::SemanticView(e) => self.generate_semantic_view(e),
3852 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3853 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3854 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3855 Expression::Set(e) => self.generate_set(e),
3856 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3857 Expression::SetItem(e) => self.generate_set_item(e),
3858 Expression::SetOperation(e) => self.generate_set_operation(e),
3859 Expression::SetProperty(e) => self.generate_set_property(e),
3860 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3861 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3862 Expression::Slice(e) => self.generate_slice(e),
3863 Expression::SortArray(e) => self.generate_sort_array(e),
3864 Expression::SortBy(e) => self.generate_sort_by(e),
3865 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3866 Expression::SplitPart(e) => self.generate_split_part(e),
3867 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3868 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3869 Expression::StDistance(e) => self.generate_st_distance(e),
3870 Expression::StPoint(e) => self.generate_st_point(e),
3871 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3872 Expression::StandardHash(e) => self.generate_standard_hash(e),
3873 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3874 Expression::StrPosition(e) => self.generate_str_position(e),
3875 Expression::StrToDate(e) => self.generate_str_to_date(e),
3876 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3877 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3878 Expression::StrToMap(e) => self.generate_str_to_map(e),
3879 Expression::StrToTime(e) => self.generate_str_to_time(e),
3880 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3881 Expression::StringToArray(e) => self.generate_string_to_array(e),
3882 Expression::Struct(e) => self.generate_struct(e),
3883 Expression::Stuff(e) => self.generate_stuff(e),
3884 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3885 Expression::Summarize(e) => self.generate_summarize(e),
3886 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3887 Expression::TableAlias(e) => self.generate_table_alias(e),
3888 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3889 Expression::RowsFrom(e) => self.generate_rows_from(e),
3890 Expression::TableSample(e) => self.generate_table_sample(e),
3891 Expression::Tag(e) => self.generate_tag(e),
3892 Expression::Tags(e) => self.generate_tags(e),
3893 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3894 Expression::Time(e) => self.generate_time_func(e),
3895 Expression::TimeAdd(e) => self.generate_time_add(e),
3896 Expression::TimeDiff(e) => self.generate_time_diff(e),
3897 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3898 Expression::TimeSlice(e) => self.generate_time_slice(e),
3899 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3900 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3901 Expression::TimeSub(e) => self.generate_time_sub(e),
3902 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3903 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3904 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3905 Expression::TimeUnit(e) => self.generate_time_unit(e),
3906 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3907 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3908 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3909 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3910 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3911 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3912 Expression::ToBinary(e) => self.generate_to_binary(e),
3913 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3914 Expression::ToChar(e) => self.generate_to_char(e),
3915 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3916 Expression::ToDouble(e) => self.generate_to_double(e),
3917 Expression::ToFile(e) => self.generate_to_file(e),
3918 Expression::ToNumber(e) => self.generate_to_number(e),
3919 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3920 Expression::Transaction(e) => self.generate_transaction(e),
3921 Expression::Transform(e) => self.generate_transform(e),
3922 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3923 Expression::TransientProperty(e) => self.generate_transient_property(e),
3924 Expression::Translate(e) => self.generate_translate(e),
3925 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
3926 Expression::TruncateTable(e) => self.generate_truncate_table(e),
3927 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
3928 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
3929 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
3930 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
3931 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
3932 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
3933 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
3934 Expression::Unhex(e) => self.generate_unhex(e),
3935 Expression::UnicodeString(e) => self.generate_unicode_string(e),
3936 Expression::Uniform(e) => self.generate_uniform(e),
3937 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
3938 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
3939 Expression::RollupProperty(e) => self.generate_rollup_property(e),
3940 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
3941 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
3942 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
3943 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
3944 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
3945 Expression::UtcTime(e) => self.generate_utc_time(e),
3946 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
3947 Expression::Uuid(e) => self.generate_uuid(e),
3948 Expression::Var(v) => {
3949 if matches!(self.config.dialect, Some(DialectType::MySQL))
3950 && v.this.len() > 2
3951 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
3952 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
3953 {
3954 return self.generate_identifier(&Identifier {
3955 name: v.this.clone(),
3956 quoted: true,
3957 trailing_comments: Vec::new(),
3958 span: None,
3959 });
3960 }
3961 self.write(&v.this);
3962 Ok(())
3963 }
3964 Expression::Variadic(e) => {
3965 self.write_keyword("VARIADIC");
3966 self.write_space();
3967 self.generate_expression(&e.this)?;
3968 Ok(())
3969 }
3970 Expression::VarMap(e) => self.generate_var_map(e),
3971 Expression::VectorSearch(e) => self.generate_vector_search(e),
3972 Expression::Version(e) => self.generate_version(e),
3973 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
3974 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
3975 Expression::WatermarkColumnConstraint(e) => {
3976 self.generate_watermark_column_constraint(e)
3977 }
3978 Expression::Week(e) => self.generate_week(e),
3979 Expression::When(e) => self.generate_when(e),
3980 Expression::Whens(e) => self.generate_whens(e),
3981 Expression::Where(e) => self.generate_where(e),
3982 Expression::WidthBucket(e) => self.generate_width_bucket(e),
3983 Expression::Window(e) => self.generate_window(e),
3984 Expression::WindowSpec(e) => self.generate_window_spec(e),
3985 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
3986 Expression::WithFill(e) => self.generate_with_fill(e),
3987 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
3988 Expression::WithOperator(e) => self.generate_with_operator(e),
3989 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
3990 Expression::WithSchemaBindingProperty(e) => {
3991 self.generate_with_schema_binding_property(e)
3992 }
3993 Expression::WithSystemVersioningProperty(e) => {
3994 self.generate_with_system_versioning_property(e)
3995 }
3996 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
3997 Expression::XMLElement(e) => self.generate_xml_element(e),
3998 Expression::XMLGet(e) => self.generate_xml_get(e),
3999 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
4000 Expression::XMLTable(e) => self.generate_xml_table(e),
4001 Expression::Xor(e) => self.generate_xor(e),
4002 Expression::Zipf(e) => self.generate_zipf(e),
4003 _ => self.write_unsupported_comment("unsupported expression"),
4004 }
4005 }
4006
4007 fn generate_select(&mut self, select: &Select) -> Result<()> {
4008 use crate::dialects::DialectType;
4009
4010 if let Some(exclude) = &select.exclude {
4014 if !exclude.is_empty() && !matches!(self.config.dialect, Some(DialectType::Redshift)) {
4015 let mut inner_select = select.clone();
4017 inner_select.exclude = None;
4018 let inner_expr = Expression::Select(Box::new(inner_select));
4019
4020 let subquery = crate::expressions::Subquery {
4022 this: inner_expr,
4023 alias: None,
4024 column_aliases: Vec::new(),
4025 order_by: None,
4026 limit: None,
4027 offset: None,
4028 distribute_by: None,
4029 sort_by: None,
4030 cluster_by: None,
4031 lateral: false,
4032 modifiers_inside: false,
4033 trailing_comments: Vec::new(),
4034 inferred_type: None,
4035 };
4036
4037 let star = Expression::Star(crate::expressions::Star {
4039 table: None,
4040 except: Some(
4041 exclude
4042 .iter()
4043 .map(|e| match e {
4044 Expression::Column(col) => col.name.clone(),
4045 Expression::Identifier(id) => id.clone(),
4046 _ => crate::expressions::Identifier::new("unknown".to_string()),
4047 })
4048 .collect(),
4049 ),
4050 replace: None,
4051 rename: None,
4052 trailing_comments: Vec::new(),
4053 span: None,
4054 });
4055
4056 let outer_select = Select {
4057 expressions: vec![star],
4058 from: Some(crate::expressions::From {
4059 expressions: vec![Expression::Subquery(Box::new(subquery))],
4060 }),
4061 ..Select::new()
4062 };
4063
4064 return self.generate_select(&outer_select);
4065 }
4066 }
4067
4068 for comment in &select.leading_comments {
4070 self.write_formatted_comment(comment);
4071 self.write(" ");
4072 }
4073
4074 if let Some(with) = &select.with {
4076 self.generate_with(with)?;
4077 if self.config.pretty {
4078 self.write_newline();
4079 self.write_indent();
4080 } else {
4081 self.write_space();
4082 }
4083 }
4084
4085 for comment in &select.post_select_comments {
4088 self.write_formatted_comment(comment);
4089 self.write(" ");
4090 }
4091
4092 self.write_keyword("SELECT");
4093
4094 if let Some(hint) = &select.hint {
4096 self.generate_hint(hint)?;
4097 }
4098
4099 let use_top_from_limit = matches!(self.config.dialect, Some(DialectType::TSQL))
4103 && select.top.is_none()
4104 && select.limit.is_some()
4105 && select.offset.is_none(); let is_top_dialect = matches!(
4110 self.config.dialect,
4111 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
4112 );
4113 let keep_top_verbatim = !is_top_dialect
4114 && select.limit.is_none()
4115 && select
4116 .top
4117 .as_ref()
4118 .map_or(false, |top| top.percent || top.with_ties);
4119
4120 if select.distinct && (is_top_dialect || select.top.is_some()) {
4121 self.write_space();
4122 self.write_keyword("DISTINCT");
4123 }
4124
4125 if is_top_dialect || keep_top_verbatim {
4126 if let Some(top) = &select.top {
4127 self.write_space();
4128 self.write_keyword("TOP");
4129 if top.parenthesized {
4130 self.write(" (");
4131 self.generate_expression(&top.this)?;
4132 self.write(")");
4133 } else {
4134 self.write_space();
4135 self.generate_expression(&top.this)?;
4136 }
4137 if top.percent {
4138 self.write_space();
4139 self.write_keyword("PERCENT");
4140 }
4141 if top.with_ties {
4142 self.write_space();
4143 self.write_keyword("WITH TIES");
4144 }
4145 } else if use_top_from_limit {
4146 if let Some(limit) = &select.limit {
4148 self.write_space();
4149 self.write_keyword("TOP");
4150 let is_simple_literal = matches!(&limit.this, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)));
4152 if is_simple_literal {
4153 self.write_space();
4154 self.generate_expression(&limit.this)?;
4155 } else {
4156 self.write(" (");
4157 self.generate_expression(&limit.this)?;
4158 self.write(")");
4159 }
4160 }
4161 }
4162 }
4163
4164 if select.distinct && !is_top_dialect && select.top.is_none() {
4165 self.write_space();
4166 self.write_keyword("DISTINCT");
4167 }
4168
4169 if let Some(distinct_on) = &select.distinct_on {
4171 self.write_space();
4172 self.write_keyword("ON");
4173 self.write(" (");
4174 for (i, expr) in distinct_on.iter().enumerate() {
4175 if i > 0 {
4176 self.write(", ");
4177 }
4178 self.generate_expression(expr)?;
4179 }
4180 self.write(")");
4181 }
4182
4183 for modifier in &select.operation_modifiers {
4185 self.write_space();
4186 self.write_keyword(modifier);
4187 }
4188
4189 if let Some(kind) = &select.kind {
4191 self.write_space();
4192 self.write_keyword("AS");
4193 self.write_space();
4194 self.write_keyword(kind);
4195 }
4196
4197 if !select.expressions.is_empty() {
4199 if self.config.pretty {
4200 self.write_newline();
4201 self.indent_level += 1;
4202 } else {
4203 self.write_space();
4204 }
4205 }
4206
4207 for (i, expr) in select.expressions.iter().enumerate() {
4208 if i > 0 {
4209 self.write(",");
4210 if self.config.pretty {
4211 self.write_newline();
4212 } else {
4213 self.write_space();
4214 }
4215 }
4216 if self.config.pretty {
4217 self.write_indent();
4218 }
4219 self.generate_expression(expr)?;
4220 }
4221
4222 if self.config.pretty && !select.expressions.is_empty() {
4223 self.indent_level -= 1;
4224 }
4225
4226 if let Some(exclude) = &select.exclude {
4231 if !exclude.is_empty() && matches!(self.config.dialect, Some(DialectType::Redshift)) {
4232 self.write_space();
4233 self.write_keyword("EXCLUDE");
4234 self.write(" (");
4235 for (i, col) in exclude.iter().enumerate() {
4236 if i > 0 {
4237 self.write(", ");
4238 }
4239 self.generate_expression(col)?;
4240 }
4241 self.write(")");
4242 }
4243 }
4244
4245 if let Some(into) = &select.into {
4248 if self.config.pretty {
4249 self.write_newline();
4250 self.write_indent();
4251 } else {
4252 self.write_space();
4253 }
4254 if into.bulk_collect {
4255 self.write_keyword("BULK COLLECT INTO");
4256 } else {
4257 self.write_keyword("INTO");
4258 }
4259 if into.temporary {
4260 self.write_space();
4261 self.write_keyword("TEMPORARY");
4262 }
4263 if into.unlogged {
4264 self.write_space();
4265 self.write_keyword("UNLOGGED");
4266 }
4267 self.write_space();
4268 if !into.expressions.is_empty() {
4270 for (i, expr) in into.expressions.iter().enumerate() {
4271 if i > 0 {
4272 self.write(", ");
4273 }
4274 self.generate_expression(expr)?;
4275 }
4276 } else {
4277 self.generate_expression(&into.this)?;
4278 }
4279 }
4280
4281 if let Some(from) = &select.from {
4283 if self.config.pretty {
4284 self.write_newline();
4285 self.write_indent();
4286 } else {
4287 self.write_space();
4288 }
4289 self.write_keyword("FROM");
4290 self.write_space();
4291
4292 let has_tablesample = from
4297 .expressions
4298 .iter()
4299 .any(|e| matches!(e, Expression::TableSample(_)));
4300 let is_cross_join_dialect = matches!(
4301 self.config.dialect,
4302 Some(DialectType::BigQuery)
4303 | Some(DialectType::Hive)
4304 | Some(DialectType::Spark)
4305 | Some(DialectType::Databricks)
4306 | Some(DialectType::SQLite)
4307 | Some(DialectType::ClickHouse)
4308 );
4309 let source_is_same_as_target = self.config.source_dialect.is_some()
4312 && self.config.source_dialect == self.config.dialect;
4313 let source_is_cross_join_dialect = matches!(
4314 self.config.source_dialect,
4315 Some(DialectType::BigQuery)
4316 | Some(DialectType::Hive)
4317 | Some(DialectType::Spark)
4318 | Some(DialectType::Databricks)
4319 | Some(DialectType::SQLite)
4320 | Some(DialectType::ClickHouse)
4321 );
4322 let use_cross_join = !has_tablesample
4323 && is_cross_join_dialect
4324 && (source_is_same_as_target
4325 || source_is_cross_join_dialect
4326 || self.config.source_dialect.is_none());
4327
4328 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4330
4331 for (i, expr) in from.expressions.iter().enumerate() {
4332 if i > 0 {
4333 if use_cross_join {
4334 self.write(" CROSS JOIN ");
4335 } else {
4336 self.write(", ");
4337 }
4338 }
4339 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4340 self.write("(");
4341 self.generate_expression(expr)?;
4342 self.write(")");
4343 } else {
4344 self.generate_expression(expr)?;
4345 }
4346 let leading = Self::extract_table_leading_comments(expr);
4349 for comment in &leading {
4350 self.write_space();
4351 self.write_formatted_comment(comment);
4352 }
4353 }
4354 }
4355
4356 if self.config.pretty {
4360 self.generate_joins_with_nesting(&select.joins)?;
4361 } else {
4362 for join in &select.joins {
4363 self.generate_join(join)?;
4364 }
4365 for join in select.joins.iter().rev() {
4367 if join.deferred_condition {
4368 self.generate_join_condition(join)?;
4369 }
4370 }
4371 }
4372
4373 for (lv_idx, lateral_view) in select.lateral_views.iter().enumerate() {
4375 self.generate_lateral_view(lateral_view, lv_idx)?;
4376 }
4377
4378 if let Some(prewhere) = &select.prewhere {
4380 self.write_clause_condition("PREWHERE", prewhere)?;
4381 }
4382
4383 if let Some(where_clause) = &select.where_clause {
4385 self.write_clause_condition("WHERE", &where_clause.this)?;
4386 }
4387
4388 if let Some(connect) = &select.connect {
4390 self.generate_connect(connect)?;
4391 }
4392
4393 if let Some(group_by) = &select.group_by {
4395 if self.config.pretty {
4396 for comment in &group_by.comments {
4398 self.write_newline();
4399 self.write_indent();
4400 self.write_formatted_comment(comment);
4401 }
4402 self.write_newline();
4403 self.write_indent();
4404 } else {
4405 self.write_space();
4406 for comment in &group_by.comments {
4408 self.write_formatted_comment(comment);
4409 self.write_space();
4410 }
4411 }
4412 self.write_keyword("GROUP BY");
4413 match group_by.all {
4415 Some(true) => {
4416 self.write_space();
4417 self.write_keyword("ALL");
4418 }
4419 Some(false) => {
4420 self.write_space();
4421 self.write_keyword("DISTINCT");
4422 }
4423 None => {}
4424 }
4425 if !group_by.expressions.is_empty() {
4426 let mut trailing_cube = false;
4429 let mut trailing_rollup = false;
4430 let mut plain_expressions: Vec<&Expression> = Vec::new();
4431 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4432 let mut cube_expressions: Vec<&Expression> = Vec::new();
4433 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4434
4435 for expr in &group_by.expressions {
4436 match expr {
4437 Expression::Cube(c) if c.expressions.is_empty() => {
4438 trailing_cube = true;
4439 }
4440 Expression::Rollup(r) if r.expressions.is_empty() => {
4441 trailing_rollup = true;
4442 }
4443 Expression::Function(f) if f.name == "CUBE" => {
4444 cube_expressions.push(expr);
4445 }
4446 Expression::Function(f) if f.name == "ROLLUP" => {
4447 rollup_expressions.push(expr);
4448 }
4449 Expression::Function(f) if f.name == "GROUPING SETS" => {
4450 grouping_sets_expressions.push(expr);
4451 }
4452 _ => {
4453 plain_expressions.push(expr);
4454 }
4455 }
4456 }
4457
4458 let mut regular_expressions: Vec<&Expression> = Vec::new();
4460 regular_expressions.extend(plain_expressions);
4461 regular_expressions.extend(grouping_sets_expressions);
4462 regular_expressions.extend(cube_expressions);
4463 regular_expressions.extend(rollup_expressions);
4464
4465 if self.config.pretty {
4466 self.write_newline();
4467 self.indent_level += 1;
4468 self.write_indent();
4469 } else {
4470 self.write_space();
4471 }
4472
4473 for (i, expr) in regular_expressions.iter().enumerate() {
4474 if i > 0 {
4475 if self.config.pretty {
4476 self.write(",");
4477 self.write_newline();
4478 self.write_indent();
4479 } else {
4480 self.write(", ");
4481 }
4482 }
4483 self.generate_expression(expr)?;
4484 }
4485
4486 if self.config.pretty {
4487 self.indent_level -= 1;
4488 }
4489
4490 if trailing_cube {
4492 self.write_space();
4493 self.write_keyword("WITH CUBE");
4494 } else if trailing_rollup {
4495 self.write_space();
4496 self.write_keyword("WITH ROLLUP");
4497 }
4498 }
4499
4500 if group_by.totals {
4502 self.write_space();
4503 self.write_keyword("WITH TOTALS");
4504 }
4505 }
4506
4507 if let Some(having) = &select.having {
4509 if self.config.pretty {
4510 for comment in &having.comments {
4512 self.write_newline();
4513 self.write_indent();
4514 self.write_formatted_comment(comment);
4515 }
4516 } else {
4517 for comment in &having.comments {
4518 self.write_space();
4519 self.write_formatted_comment(comment);
4520 }
4521 }
4522 self.write_clause_condition("HAVING", &having.this)?;
4523 }
4524
4525 if select.qualify_after_window {
4527 if let Some(windows) = &select.windows {
4529 self.write_window_clause(windows)?;
4530 }
4531 if let Some(qualify) = &select.qualify {
4532 self.write_clause_condition("QUALIFY", &qualify.this)?;
4533 }
4534 } else {
4535 if let Some(qualify) = &select.qualify {
4537 self.write_clause_condition("QUALIFY", &qualify.this)?;
4538 }
4539 if let Some(windows) = &select.windows {
4540 self.write_window_clause(windows)?;
4541 }
4542 }
4543
4544 if let Some(distribute_by) = &select.distribute_by {
4546 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4547 }
4548
4549 if let Some(cluster_by) = &select.cluster_by {
4551 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4552 }
4553
4554 if let Some(sort_by) = &select.sort_by {
4556 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4557 }
4558
4559 if let Some(order_by) = &select.order_by {
4561 if self.config.pretty {
4562 for comment in &order_by.comments {
4564 self.write_newline();
4565 self.write_indent();
4566 self.write_formatted_comment(comment);
4567 }
4568 } else {
4569 for comment in &order_by.comments {
4570 self.write_space();
4571 self.write_formatted_comment(comment);
4572 }
4573 }
4574 let keyword = if order_by.siblings {
4575 "ORDER SIBLINGS BY"
4576 } else {
4577 "ORDER BY"
4578 };
4579 self.write_order_clause(keyword, &order_by.expressions)?;
4580 }
4581
4582 if select.order_by.is_none()
4584 && select.fetch.is_some()
4585 && matches!(
4586 self.config.dialect,
4587 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4588 )
4589 {
4590 if self.config.pretty {
4591 self.write_newline();
4592 self.write_indent();
4593 } else {
4594 self.write_space();
4595 }
4596 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4597 }
4598
4599 let is_presto_like = matches!(
4604 self.config.dialect,
4605 Some(DialectType::Presto) | Some(DialectType::Trino)
4606 );
4607
4608 if is_presto_like && select.offset.is_some() {
4609 if let Some(offset) = &select.offset {
4611 if self.config.pretty {
4612 self.write_newline();
4613 self.write_indent();
4614 } else {
4615 self.write_space();
4616 }
4617 self.write_keyword("OFFSET");
4618 self.write_space();
4619 self.write_limit_expr(&offset.this)?;
4620 if offset.rows == Some(true) {
4621 self.write_space();
4622 self.write_keyword("ROWS");
4623 }
4624 }
4625 if let Some(limit) = &select.limit {
4626 if self.config.pretty {
4627 self.write_newline();
4628 self.write_indent();
4629 } else {
4630 self.write_space();
4631 }
4632 self.write_keyword("LIMIT");
4633 self.write_space();
4634 self.write_limit_expr(&limit.this)?;
4635 if limit.percent {
4636 self.write_space();
4637 self.write_keyword("PERCENT");
4638 }
4639 for comment in &limit.comments {
4641 self.write(" ");
4642 self.write_formatted_comment(comment);
4643 }
4644 }
4645 } else {
4646 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
4648 !fetch.percent
4649 && !fetch.with_ties
4650 && fetch.count.is_some()
4651 && matches!(
4652 self.config.dialect,
4653 Some(DialectType::Spark)
4654 | Some(DialectType::Hive)
4655 | Some(DialectType::DuckDB)
4656 | Some(DialectType::SQLite)
4657 | Some(DialectType::MySQL)
4658 | Some(DialectType::BigQuery)
4659 | Some(DialectType::Databricks)
4660 | Some(DialectType::StarRocks)
4661 | Some(DialectType::Doris)
4662 | Some(DialectType::Athena)
4663 | Some(DialectType::ClickHouse)
4664 | Some(DialectType::Redshift)
4665 )
4666 });
4667
4668 if let Some(limit) = &select.limit {
4670 if !matches!(self.config.dialect, Some(DialectType::TSQL)) {
4672 if self.config.pretty {
4673 self.write_newline();
4674 self.write_indent();
4675 } else {
4676 self.write_space();
4677 }
4678 self.write_keyword("LIMIT");
4679 self.write_space();
4680 self.write_limit_expr(&limit.this)?;
4681 if limit.percent {
4682 self.write_space();
4683 self.write_keyword("PERCENT");
4684 }
4685 for comment in &limit.comments {
4687 self.write(" ");
4688 self.write_formatted_comment(comment);
4689 }
4690 }
4691 }
4692
4693 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
4695 if let Some(top) = &select.top {
4696 if !top.percent && !top.with_ties {
4697 if self.config.pretty {
4698 self.write_newline();
4699 self.write_indent();
4700 } else {
4701 self.write_space();
4702 }
4703 self.write_keyword("LIMIT");
4704 self.write_space();
4705 self.generate_expression(&top.this)?;
4706 }
4707 }
4708 }
4709
4710 if fetch_as_limit && select.offset.is_some() {
4713 if let Some(fetch) = &select.fetch {
4714 if self.config.pretty {
4715 self.write_newline();
4716 self.write_indent();
4717 } else {
4718 self.write_space();
4719 }
4720 self.write_keyword("LIMIT");
4721 self.write_space();
4722 self.generate_expression(fetch.count.as_ref().unwrap())?;
4723 }
4724 }
4725
4726 if let Some(offset) = &select.offset {
4730 if self.config.pretty {
4731 self.write_newline();
4732 self.write_indent();
4733 } else {
4734 self.write_space();
4735 }
4736 if matches!(self.config.dialect, Some(DialectType::TSQL)) {
4737 self.write_keyword("OFFSET");
4739 self.write_space();
4740 self.write_limit_expr(&offset.this)?;
4741 self.write_space();
4742 self.write_keyword("ROWS");
4743 if let Some(limit) = &select.limit {
4745 self.write_space();
4746 self.write_keyword("FETCH NEXT");
4747 self.write_space();
4748 self.write_limit_expr(&limit.this)?;
4749 self.write_space();
4750 self.write_keyword("ROWS ONLY");
4751 }
4752 } else {
4753 self.write_keyword("OFFSET");
4754 self.write_space();
4755 self.write_limit_expr(&offset.this)?;
4756 if offset.rows == Some(true) {
4758 self.write_space();
4759 self.write_keyword("ROWS");
4760 }
4761 }
4762 }
4763 }
4764
4765 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4767 if let Some(limit_by) = &select.limit_by {
4768 if !limit_by.is_empty() {
4769 self.write_space();
4770 self.write_keyword("BY");
4771 self.write_space();
4772 for (i, expr) in limit_by.iter().enumerate() {
4773 if i > 0 {
4774 self.write(", ");
4775 }
4776 self.generate_expression(expr)?;
4777 }
4778 }
4779 }
4780 }
4781
4782 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4784 if let Some(settings) = &select.settings {
4785 if self.config.pretty {
4786 self.write_newline();
4787 self.write_indent();
4788 } else {
4789 self.write_space();
4790 }
4791 self.write_keyword("SETTINGS");
4792 self.write_space();
4793 for (i, expr) in settings.iter().enumerate() {
4794 if i > 0 {
4795 self.write(", ");
4796 }
4797 self.generate_expression(expr)?;
4798 }
4799 }
4800
4801 if let Some(format_expr) = &select.format {
4802 if self.config.pretty {
4803 self.write_newline();
4804 self.write_indent();
4805 } else {
4806 self.write_space();
4807 }
4808 self.write_keyword("FORMAT");
4809 self.write_space();
4810 self.generate_expression(format_expr)?;
4811 }
4812 }
4813
4814 if let Some(fetch) = &select.fetch {
4816 let fetch_already_as_limit = select.offset.is_some()
4818 && !fetch.percent
4819 && !fetch.with_ties
4820 && fetch.count.is_some()
4821 && matches!(
4822 self.config.dialect,
4823 Some(DialectType::Spark)
4824 | Some(DialectType::Hive)
4825 | Some(DialectType::DuckDB)
4826 | Some(DialectType::SQLite)
4827 | Some(DialectType::MySQL)
4828 | Some(DialectType::BigQuery)
4829 | Some(DialectType::Databricks)
4830 | Some(DialectType::StarRocks)
4831 | Some(DialectType::Doris)
4832 | Some(DialectType::Athena)
4833 | Some(DialectType::ClickHouse)
4834 | Some(DialectType::Redshift)
4835 );
4836
4837 if fetch_already_as_limit {
4838 } else {
4840 if self.config.pretty {
4841 self.write_newline();
4842 self.write_indent();
4843 } else {
4844 self.write_space();
4845 }
4846
4847 let use_limit = !fetch.percent
4849 && !fetch.with_ties
4850 && fetch.count.is_some()
4851 && matches!(
4852 self.config.dialect,
4853 Some(DialectType::Spark)
4854 | Some(DialectType::Hive)
4855 | Some(DialectType::DuckDB)
4856 | Some(DialectType::SQLite)
4857 | Some(DialectType::MySQL)
4858 | Some(DialectType::BigQuery)
4859 | Some(DialectType::Databricks)
4860 | Some(DialectType::StarRocks)
4861 | Some(DialectType::Doris)
4862 | Some(DialectType::Athena)
4863 | Some(DialectType::ClickHouse)
4864 | Some(DialectType::Redshift)
4865 );
4866
4867 if use_limit {
4868 self.write_keyword("LIMIT");
4869 self.write_space();
4870 self.generate_expression(fetch.count.as_ref().unwrap())?;
4871 } else {
4872 self.write_keyword("FETCH");
4873 self.write_space();
4874 self.write_keyword(&fetch.direction);
4875 if let Some(ref count) = fetch.count {
4876 self.write_space();
4877 self.generate_expression(count)?;
4878 }
4879 if fetch.percent {
4880 self.write_space();
4881 self.write_keyword("PERCENT");
4882 }
4883 if fetch.rows {
4884 self.write_space();
4885 self.write_keyword("ROWS");
4886 }
4887 if fetch.with_ties {
4888 self.write_space();
4889 self.write_keyword("WITH TIES");
4890 } else {
4891 self.write_space();
4892 self.write_keyword("ONLY");
4893 }
4894 }
4895 } }
4897
4898 if let Some(sample) = &select.sample {
4900 use crate::dialects::DialectType;
4901 if self.config.pretty {
4902 self.write_newline();
4903 } else {
4904 self.write_space();
4905 }
4906
4907 if sample.is_using_sample {
4908 self.write_keyword("USING SAMPLE");
4910 self.generate_sample_body(sample)?;
4911 } else {
4912 self.write_keyword("TABLESAMPLE");
4913
4914 let snowflake_bernoulli =
4916 matches!(self.config.dialect, Some(DialectType::Snowflake))
4917 && !sample.explicit_method;
4918 if snowflake_bernoulli {
4919 self.write_space();
4920 self.write_keyword("BERNOULLI");
4921 }
4922
4923 if matches!(sample.method, SampleMethod::Bucket) {
4925 self.write_space();
4926 self.write("(");
4927 self.write_keyword("BUCKET");
4928 self.write_space();
4929 if let Some(ref num) = sample.bucket_numerator {
4930 self.generate_expression(num)?;
4931 }
4932 self.write_space();
4933 self.write_keyword("OUT OF");
4934 self.write_space();
4935 if let Some(ref denom) = sample.bucket_denominator {
4936 self.generate_expression(denom)?;
4937 }
4938 if let Some(ref field) = sample.bucket_field {
4939 self.write_space();
4940 self.write_keyword("ON");
4941 self.write_space();
4942 self.generate_expression(field)?;
4943 }
4944 self.write(")");
4945 } else if sample.unit_after_size {
4946 if sample.explicit_method && sample.method_before_size {
4948 self.write_space();
4949 match sample.method {
4950 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4951 SampleMethod::System => self.write_keyword("SYSTEM"),
4952 SampleMethod::Block => self.write_keyword("BLOCK"),
4953 SampleMethod::Row => self.write_keyword("ROW"),
4954 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4955 _ => {}
4956 }
4957 }
4958 self.write(" (");
4959 self.generate_expression(&sample.size)?;
4960 self.write_space();
4961 match sample.method {
4962 SampleMethod::Percent => self.write_keyword("PERCENT"),
4963 SampleMethod::Row => self.write_keyword("ROWS"),
4964 SampleMethod::Reservoir => self.write_keyword("ROWS"),
4965 _ => {
4966 self.write_keyword("PERCENT");
4967 }
4968 }
4969 self.write(")");
4970 } else {
4971 self.write_space();
4973 match sample.method {
4974 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4975 SampleMethod::System => self.write_keyword("SYSTEM"),
4976 SampleMethod::Block => self.write_keyword("BLOCK"),
4977 SampleMethod::Row => self.write_keyword("ROW"),
4978 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
4979 SampleMethod::Bucket => {}
4980 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4981 }
4982 self.write(" (");
4983 self.generate_expression(&sample.size)?;
4984 if matches!(sample.method, SampleMethod::Percent) {
4985 self.write_space();
4986 self.write_keyword("PERCENT");
4987 }
4988 self.write(")");
4989 }
4990 }
4991
4992 if let Some(seed) = &sample.seed {
4993 self.write_space();
4994 let use_seed = sample.use_seed_keyword
4996 && !matches!(
4997 self.config.dialect,
4998 Some(crate::dialects::DialectType::Databricks)
4999 | Some(crate::dialects::DialectType::Spark)
5000 );
5001 if use_seed {
5002 self.write_keyword("SEED");
5003 } else {
5004 self.write_keyword("REPEATABLE");
5005 }
5006 self.write(" (");
5007 self.generate_expression(seed)?;
5008 self.write(")");
5009 }
5010 }
5011
5012 if self.config.locking_reads_supported {
5015 for lock in &select.locks {
5016 if self.config.pretty {
5017 self.write_newline();
5018 self.write_indent();
5019 } else {
5020 self.write_space();
5021 }
5022 self.generate_lock(lock)?;
5023 }
5024 }
5025
5026 if !select.for_xml.is_empty() {
5028 if self.config.pretty {
5029 self.write_newline();
5030 self.write_indent();
5031 } else {
5032 self.write_space();
5033 }
5034 self.write_keyword("FOR XML");
5035 for (i, opt) in select.for_xml.iter().enumerate() {
5036 if self.config.pretty {
5037 if i > 0 {
5038 self.write(",");
5039 }
5040 self.write_newline();
5041 self.write_indent();
5042 self.write(" "); } else {
5044 if i > 0 {
5045 self.write(",");
5046 }
5047 self.write_space();
5048 }
5049 self.generate_for_xml_option(opt)?;
5050 }
5051 }
5052
5053 if !select.for_json.is_empty() {
5055 if self.config.pretty {
5056 self.write_newline();
5057 self.write_indent();
5058 } else {
5059 self.write_space();
5060 }
5061 self.write_keyword("FOR JSON");
5062 for (i, opt) in select.for_json.iter().enumerate() {
5063 if self.config.pretty {
5064 if i > 0 {
5065 self.write(",");
5066 }
5067 self.write_newline();
5068 self.write_indent();
5069 self.write(" "); } else {
5071 if i > 0 {
5072 self.write(",");
5073 }
5074 self.write_space();
5075 }
5076 self.generate_for_xml_option(opt)?;
5077 }
5078 }
5079
5080 if let Some(ref option) = select.option {
5082 if matches!(
5083 self.config.dialect,
5084 Some(crate::dialects::DialectType::TSQL)
5085 | Some(crate::dialects::DialectType::Fabric)
5086 ) {
5087 self.write_space();
5088 self.write(option);
5089 }
5090 }
5091
5092 Ok(())
5093 }
5094
5095 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
5097 match opt {
5098 Expression::QueryOption(qo) => {
5099 if let Expression::Var(var) = &*qo.this {
5101 self.write(&var.this);
5102 } else {
5103 self.generate_expression(&qo.this)?;
5104 }
5105 if let Some(expr) = &qo.expression {
5107 self.write("(");
5108 self.generate_expression(expr)?;
5109 self.write(")");
5110 }
5111 }
5112 _ => {
5113 self.generate_expression(opt)?;
5114 }
5115 }
5116 Ok(())
5117 }
5118
5119 fn generate_with(&mut self, with: &With) -> Result<()> {
5120 use crate::dialects::DialectType;
5121
5122 for comment in &with.leading_comments {
5124 self.write_formatted_comment(comment);
5125 self.write(" ");
5126 }
5127 self.write_keyword("WITH");
5128 if with.recursive && self.config.cte_recursive_keyword_required {
5129 self.write_space();
5130 self.write_keyword("RECURSIVE");
5131 }
5132 self.write_space();
5133
5134 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
5136
5137 for (i, cte) in with.ctes.iter().enumerate() {
5138 if i > 0 {
5139 self.write(",");
5140 if self.config.pretty {
5141 self.write_space();
5142 } else {
5143 self.write(" ");
5144 }
5145 }
5146 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
5147 self.generate_expression(&cte.this)?;
5148 self.write_space();
5149 self.write_keyword("AS");
5150 self.write_space();
5151 self.generate_identifier(&cte.alias)?;
5152 continue;
5153 }
5154 self.generate_identifier(&cte.alias)?;
5155 for comment in &cte.comments {
5157 self.write_space();
5158 self.write_formatted_comment(comment);
5159 }
5160 if !cte.columns.is_empty() && !skip_cte_columns {
5161 self.write("(");
5162 for (j, col) in cte.columns.iter().enumerate() {
5163 if j > 0 {
5164 self.write(", ");
5165 }
5166 self.generate_identifier(col)?;
5167 }
5168 self.write(")");
5169 }
5170 if !cte.key_expressions.is_empty() {
5172 self.write_space();
5173 self.write_keyword("USING KEY");
5174 self.write(" (");
5175 for (i, key) in cte.key_expressions.iter().enumerate() {
5176 if i > 0 {
5177 self.write(", ");
5178 }
5179 self.generate_identifier(key)?;
5180 }
5181 self.write(")");
5182 }
5183 self.write_space();
5184 self.write_keyword("AS");
5185 if let Some(materialized) = cte.materialized {
5187 self.write_space();
5188 if materialized {
5189 self.write_keyword("MATERIALIZED");
5190 } else {
5191 self.write_keyword("NOT MATERIALIZED");
5192 }
5193 }
5194 self.write(" (");
5195 if self.config.pretty {
5196 self.write_newline();
5197 self.indent_level += 1;
5198 self.write_indent();
5199 }
5200 let wrap_values_in_select = matches!(
5203 self.config.dialect,
5204 Some(DialectType::Spark) | Some(DialectType::Databricks)
5205 ) && matches!(&cte.this, Expression::Values(_));
5206
5207 if wrap_values_in_select {
5208 self.write_keyword("SELECT");
5209 self.write(" * ");
5210 self.write_keyword("FROM");
5211 self.write_space();
5212 }
5213 self.generate_expression(&cte.this)?;
5214 if self.config.pretty {
5215 self.write_newline();
5216 self.indent_level -= 1;
5217 self.write_indent();
5218 }
5219 self.write(")");
5220 }
5221
5222 if let Some(search) = &with.search {
5224 self.write_space();
5225 self.generate_expression(search)?;
5226 }
5227
5228 Ok(())
5229 }
5230
5231 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
5235 let mut i = 0;
5236 while i < joins.len() {
5237 if joins[i].deferred_condition {
5238 let parent_group = joins[i].nesting_group;
5239
5240 self.generate_join_without_condition(&joins[i])?;
5243
5244 let child_start = i + 1;
5246 let mut child_end = child_start;
5247 while child_end < joins.len()
5248 && !joins[child_end].deferred_condition
5249 && joins[child_end].nesting_group == parent_group
5250 {
5251 child_end += 1;
5252 }
5253
5254 if child_start < child_end {
5256 self.indent_level += 1;
5257 for j in child_start..child_end {
5258 self.generate_join(&joins[j])?;
5259 }
5260 self.indent_level -= 1;
5261 }
5262
5263 self.generate_join_condition(&joins[i])?;
5265
5266 i = child_end;
5267 } else {
5268 self.generate_join(&joins[i])?;
5270 i += 1;
5271 }
5272 }
5273 Ok(())
5274 }
5275
5276 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5279 let mut join_copy = join.clone();
5282 join_copy.on = None;
5283 join_copy.using = Vec::new();
5284 join_copy.deferred_condition = false;
5285 self.generate_join(&join_copy)
5286 }
5287
5288 fn generate_join(&mut self, join: &Join) -> Result<()> {
5289 if join.kind == JoinKind::Implicit {
5291 self.write(",");
5292 if self.config.pretty {
5293 self.write_newline();
5294 self.write_indent();
5295 } else {
5296 self.write_space();
5297 }
5298 self.generate_expression(&join.this)?;
5299 return Ok(());
5300 }
5301
5302 if self.config.pretty {
5303 self.write_newline();
5304 self.write_indent();
5305 } else {
5306 self.write_space();
5307 }
5308
5309 let hint_str = if self.config.join_hints {
5312 join.join_hint
5313 .as_ref()
5314 .map(|h| format!(" {}", h))
5315 .unwrap_or_default()
5316 } else {
5317 String::new()
5318 };
5319
5320 let clickhouse_join_keyword =
5321 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5322 if let Some(hint) = &join.join_hint {
5323 let mut global = false;
5324 let mut strictness: Option<&'static str> = None;
5325 for part in hint.split_whitespace() {
5326 if part.eq_ignore_ascii_case("GLOBAL") {
5327 global = true;
5328 } else if part.eq_ignore_ascii_case("ANY") {
5329 strictness = Some("ANY");
5330 } else if part.eq_ignore_ascii_case("ASOF") {
5331 strictness = Some("ASOF");
5332 } else if part.eq_ignore_ascii_case("SEMI") {
5333 strictness = Some("SEMI");
5334 } else if part.eq_ignore_ascii_case("ANTI") {
5335 strictness = Some("ANTI");
5336 }
5337 }
5338
5339 if global || strictness.is_some() {
5340 let join_type = match join.kind {
5341 JoinKind::Left => {
5342 if join.use_outer_keyword {
5343 "LEFT OUTER"
5344 } else if join.use_inner_keyword {
5345 "LEFT INNER"
5346 } else {
5347 "LEFT"
5348 }
5349 }
5350 JoinKind::Right => {
5351 if join.use_outer_keyword {
5352 "RIGHT OUTER"
5353 } else if join.use_inner_keyword {
5354 "RIGHT INNER"
5355 } else {
5356 "RIGHT"
5357 }
5358 }
5359 JoinKind::Full => {
5360 if join.use_outer_keyword {
5361 "FULL OUTER"
5362 } else {
5363 "FULL"
5364 }
5365 }
5366 JoinKind::Inner => {
5367 if join.use_inner_keyword {
5368 "INNER"
5369 } else {
5370 ""
5371 }
5372 }
5373 _ => "",
5374 };
5375
5376 let mut parts = Vec::new();
5377 if global {
5378 parts.push("GLOBAL");
5379 }
5380 if !join_type.is_empty() {
5381 parts.push(join_type);
5382 }
5383 if let Some(strict) = strictness {
5384 parts.push(strict);
5385 }
5386 parts.push("JOIN");
5387 Some(parts.join(" "))
5388 } else {
5389 None
5390 }
5391 } else {
5392 None
5393 }
5394 } else {
5395 None
5396 };
5397
5398 if !join.comments.is_empty() {
5402 if self.config.pretty {
5403 let trimmed = self.output.trim_end().len();
5408 self.output.truncate(trimmed);
5409 for comment in &join.comments {
5410 self.write_newline();
5411 self.write_indent();
5412 self.write_formatted_comment(comment);
5413 }
5414 self.write_newline();
5415 self.write_indent();
5416 } else {
5417 for comment in &join.comments {
5418 self.write_formatted_comment(comment);
5419 self.write_space();
5420 }
5421 }
5422 }
5423
5424 let directed_str = if join.directed { " DIRECTED" } else { "" };
5425
5426 if let Some(keyword) = clickhouse_join_keyword {
5427 self.write_keyword(&keyword);
5428 } else {
5429 match join.kind {
5430 JoinKind::Inner => {
5431 if join.use_inner_keyword {
5432 if hint_str.is_empty() && directed_str.is_empty() {
5433 self.write_keyword("INNER JOIN");
5434 } else {
5435 self.write_keyword("INNER");
5436 if !hint_str.is_empty() {
5437 self.write_keyword(&hint_str);
5438 }
5439 if !directed_str.is_empty() {
5440 self.write_keyword(directed_str);
5441 }
5442 self.write_keyword(" JOIN");
5443 }
5444 } else {
5445 if !hint_str.is_empty() {
5446 self.write_keyword(hint_str.trim());
5447 self.write_keyword(" ");
5448 }
5449 if !directed_str.is_empty() {
5450 self.write_keyword("DIRECTED ");
5451 }
5452 self.write_keyword("JOIN");
5453 }
5454 }
5455 JoinKind::Left => {
5456 if join.use_outer_keyword {
5457 if hint_str.is_empty() && directed_str.is_empty() {
5458 self.write_keyword("LEFT OUTER JOIN");
5459 } else {
5460 self.write_keyword("LEFT OUTER");
5461 if !hint_str.is_empty() {
5462 self.write_keyword(&hint_str);
5463 }
5464 if !directed_str.is_empty() {
5465 self.write_keyword(directed_str);
5466 }
5467 self.write_keyword(" JOIN");
5468 }
5469 } else if join.use_inner_keyword {
5470 if hint_str.is_empty() && directed_str.is_empty() {
5471 self.write_keyword("LEFT INNER JOIN");
5472 } else {
5473 self.write_keyword("LEFT INNER");
5474 if !hint_str.is_empty() {
5475 self.write_keyword(&hint_str);
5476 }
5477 if !directed_str.is_empty() {
5478 self.write_keyword(directed_str);
5479 }
5480 self.write_keyword(" JOIN");
5481 }
5482 } else {
5483 if hint_str.is_empty() && directed_str.is_empty() {
5484 self.write_keyword("LEFT JOIN");
5485 } else {
5486 self.write_keyword("LEFT");
5487 if !hint_str.is_empty() {
5488 self.write_keyword(&hint_str);
5489 }
5490 if !directed_str.is_empty() {
5491 self.write_keyword(directed_str);
5492 }
5493 self.write_keyword(" JOIN");
5494 }
5495 }
5496 }
5497 JoinKind::Right => {
5498 if join.use_outer_keyword {
5499 if hint_str.is_empty() && directed_str.is_empty() {
5500 self.write_keyword("RIGHT OUTER JOIN");
5501 } else {
5502 self.write_keyword("RIGHT OUTER");
5503 if !hint_str.is_empty() {
5504 self.write_keyword(&hint_str);
5505 }
5506 if !directed_str.is_empty() {
5507 self.write_keyword(directed_str);
5508 }
5509 self.write_keyword(" JOIN");
5510 }
5511 } else if join.use_inner_keyword {
5512 if hint_str.is_empty() && directed_str.is_empty() {
5513 self.write_keyword("RIGHT INNER JOIN");
5514 } else {
5515 self.write_keyword("RIGHT INNER");
5516 if !hint_str.is_empty() {
5517 self.write_keyword(&hint_str);
5518 }
5519 if !directed_str.is_empty() {
5520 self.write_keyword(directed_str);
5521 }
5522 self.write_keyword(" JOIN");
5523 }
5524 } else {
5525 if hint_str.is_empty() && directed_str.is_empty() {
5526 self.write_keyword("RIGHT JOIN");
5527 } else {
5528 self.write_keyword("RIGHT");
5529 if !hint_str.is_empty() {
5530 self.write_keyword(&hint_str);
5531 }
5532 if !directed_str.is_empty() {
5533 self.write_keyword(directed_str);
5534 }
5535 self.write_keyword(" JOIN");
5536 }
5537 }
5538 }
5539 JoinKind::Full => {
5540 if join.use_outer_keyword {
5541 if hint_str.is_empty() && directed_str.is_empty() {
5542 self.write_keyword("FULL OUTER JOIN");
5543 } else {
5544 self.write_keyword("FULL OUTER");
5545 if !hint_str.is_empty() {
5546 self.write_keyword(&hint_str);
5547 }
5548 if !directed_str.is_empty() {
5549 self.write_keyword(directed_str);
5550 }
5551 self.write_keyword(" JOIN");
5552 }
5553 } else {
5554 if hint_str.is_empty() && directed_str.is_empty() {
5555 self.write_keyword("FULL JOIN");
5556 } else {
5557 self.write_keyword("FULL");
5558 if !hint_str.is_empty() {
5559 self.write_keyword(&hint_str);
5560 }
5561 if !directed_str.is_empty() {
5562 self.write_keyword(directed_str);
5563 }
5564 self.write_keyword(" JOIN");
5565 }
5566 }
5567 }
5568 JoinKind::Outer => {
5569 if directed_str.is_empty() {
5570 self.write_keyword("OUTER JOIN");
5571 } else {
5572 self.write_keyword("OUTER");
5573 self.write_keyword(directed_str);
5574 self.write_keyword(" JOIN");
5575 }
5576 }
5577 JoinKind::Cross => {
5578 if directed_str.is_empty() {
5579 self.write_keyword("CROSS JOIN");
5580 } else {
5581 self.write_keyword("CROSS");
5582 self.write_keyword(directed_str);
5583 self.write_keyword(" JOIN");
5584 }
5585 }
5586 JoinKind::Natural => {
5587 if join.use_inner_keyword {
5588 if directed_str.is_empty() {
5589 self.write_keyword("NATURAL INNER JOIN");
5590 } else {
5591 self.write_keyword("NATURAL INNER");
5592 self.write_keyword(directed_str);
5593 self.write_keyword(" JOIN");
5594 }
5595 } else {
5596 if directed_str.is_empty() {
5597 self.write_keyword("NATURAL JOIN");
5598 } else {
5599 self.write_keyword("NATURAL");
5600 self.write_keyword(directed_str);
5601 self.write_keyword(" JOIN");
5602 }
5603 }
5604 }
5605 JoinKind::NaturalLeft => {
5606 if join.use_outer_keyword {
5607 if directed_str.is_empty() {
5608 self.write_keyword("NATURAL LEFT OUTER JOIN");
5609 } else {
5610 self.write_keyword("NATURAL LEFT OUTER");
5611 self.write_keyword(directed_str);
5612 self.write_keyword(" JOIN");
5613 }
5614 } else {
5615 if directed_str.is_empty() {
5616 self.write_keyword("NATURAL LEFT JOIN");
5617 } else {
5618 self.write_keyword("NATURAL LEFT");
5619 self.write_keyword(directed_str);
5620 self.write_keyword(" JOIN");
5621 }
5622 }
5623 }
5624 JoinKind::NaturalRight => {
5625 if join.use_outer_keyword {
5626 if directed_str.is_empty() {
5627 self.write_keyword("NATURAL RIGHT OUTER JOIN");
5628 } else {
5629 self.write_keyword("NATURAL RIGHT OUTER");
5630 self.write_keyword(directed_str);
5631 self.write_keyword(" JOIN");
5632 }
5633 } else {
5634 if directed_str.is_empty() {
5635 self.write_keyword("NATURAL RIGHT JOIN");
5636 } else {
5637 self.write_keyword("NATURAL RIGHT");
5638 self.write_keyword(directed_str);
5639 self.write_keyword(" JOIN");
5640 }
5641 }
5642 }
5643 JoinKind::NaturalFull => {
5644 if join.use_outer_keyword {
5645 if directed_str.is_empty() {
5646 self.write_keyword("NATURAL FULL OUTER JOIN");
5647 } else {
5648 self.write_keyword("NATURAL FULL OUTER");
5649 self.write_keyword(directed_str);
5650 self.write_keyword(" JOIN");
5651 }
5652 } else {
5653 if directed_str.is_empty() {
5654 self.write_keyword("NATURAL FULL JOIN");
5655 } else {
5656 self.write_keyword("NATURAL FULL");
5657 self.write_keyword(directed_str);
5658 self.write_keyword(" JOIN");
5659 }
5660 }
5661 }
5662 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
5663 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
5664 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
5665 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
5666 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
5667 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
5668 JoinKind::CrossApply => {
5669 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5671 self.write_keyword("CROSS APPLY");
5672 } else {
5673 self.write_keyword("INNER JOIN LATERAL");
5674 }
5675 }
5676 JoinKind::OuterApply => {
5677 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5679 self.write_keyword("OUTER APPLY");
5680 } else {
5681 self.write_keyword("LEFT JOIN LATERAL");
5682 }
5683 }
5684 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
5685 JoinKind::AsOfLeft => {
5686 if join.use_outer_keyword {
5687 self.write_keyword("ASOF LEFT OUTER JOIN");
5688 } else {
5689 self.write_keyword("ASOF LEFT JOIN");
5690 }
5691 }
5692 JoinKind::AsOfRight => {
5693 if join.use_outer_keyword {
5694 self.write_keyword("ASOF RIGHT OUTER JOIN");
5695 } else {
5696 self.write_keyword("ASOF RIGHT JOIN");
5697 }
5698 }
5699 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
5700 JoinKind::LeftLateral => {
5701 if join.use_outer_keyword {
5702 self.write_keyword("LEFT OUTER LATERAL JOIN");
5703 } else {
5704 self.write_keyword("LEFT LATERAL JOIN");
5705 }
5706 }
5707 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
5708 JoinKind::Implicit => {
5709 use crate::dialects::DialectType;
5713 let is_cj_dialect = matches!(
5714 self.config.dialect,
5715 Some(DialectType::BigQuery)
5716 | Some(DialectType::Hive)
5717 | Some(DialectType::Spark)
5718 | Some(DialectType::Databricks)
5719 );
5720 let source_is_same = self.config.source_dialect.is_some()
5721 && self.config.source_dialect == self.config.dialect;
5722 let source_is_cj = matches!(
5723 self.config.source_dialect,
5724 Some(DialectType::BigQuery)
5725 | Some(DialectType::Hive)
5726 | Some(DialectType::Spark)
5727 | Some(DialectType::Databricks)
5728 );
5729 if is_cj_dialect
5730 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
5731 {
5732 self.write_keyword("CROSS JOIN");
5733 } else {
5734 self.output.truncate(self.output.trim_end().len());
5738 self.write(",");
5739 }
5740 }
5741 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
5742 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
5743 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
5744 JoinKind::Positional => self.write_keyword("POSITIONAL JOIN"),
5745 }
5746 }
5747
5748 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
5750 self.write_space();
5751 match &join.this {
5752 Expression::Tuple(t) => {
5753 for (i, item) in t.expressions.iter().enumerate() {
5754 if i > 0 {
5755 self.write(", ");
5756 }
5757 self.generate_expression(item)?;
5758 }
5759 }
5760 other => {
5761 self.generate_expression(other)?;
5762 }
5763 }
5764 } else {
5765 self.write_space();
5766 self.generate_expression(&join.this)?;
5767 }
5768
5769 if !join.deferred_condition {
5771 if let Some(match_cond) = &join.match_condition {
5773 self.write_space();
5774 self.write_keyword("MATCH_CONDITION");
5775 self.write(" (");
5776 self.generate_expression(match_cond)?;
5777 self.write(")");
5778 }
5779
5780 if let Some(on) = &join.on {
5781 if self.config.pretty {
5782 self.write_newline();
5783 self.indent_level += 1;
5784 self.write_indent();
5785 self.write_keyword("ON");
5786 self.write_space();
5787 self.generate_join_on_condition(on)?;
5788 self.indent_level -= 1;
5789 } else {
5790 self.write_space();
5791 self.write_keyword("ON");
5792 self.write_space();
5793 self.generate_expression(on)?;
5794 }
5795 }
5796
5797 if !join.using.is_empty() {
5798 if self.config.pretty {
5799 self.write_newline();
5800 self.indent_level += 1;
5801 self.write_indent();
5802 self.write_keyword("USING");
5803 self.write(" (");
5804 for (i, col) in join.using.iter().enumerate() {
5805 if i > 0 {
5806 self.write(", ");
5807 }
5808 self.generate_identifier(col)?;
5809 }
5810 self.write(")");
5811 self.indent_level -= 1;
5812 } else {
5813 self.write_space();
5814 self.write_keyword("USING");
5815 self.write(" (");
5816 for (i, col) in join.using.iter().enumerate() {
5817 if i > 0 {
5818 self.write(", ");
5819 }
5820 self.generate_identifier(col)?;
5821 }
5822 self.write(")");
5823 }
5824 }
5825 }
5826
5827 for pivot in &join.pivots {
5829 self.write_space();
5830 self.generate_expression(pivot)?;
5831 }
5832
5833 Ok(())
5834 }
5835
5836 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
5838 if let Some(match_cond) = &join.match_condition {
5840 self.write_space();
5841 self.write_keyword("MATCH_CONDITION");
5842 self.write(" (");
5843 self.generate_expression(match_cond)?;
5844 self.write(")");
5845 }
5846
5847 if let Some(on) = &join.on {
5848 if self.config.pretty {
5849 self.write_newline();
5850 self.indent_level += 1;
5851 self.write_indent();
5852 self.write_keyword("ON");
5853 self.write_space();
5854 self.generate_join_on_condition(on)?;
5856 self.indent_level -= 1;
5857 } else {
5858 self.write_space();
5859 self.write_keyword("ON");
5860 self.write_space();
5861 self.generate_expression(on)?;
5862 }
5863 }
5864
5865 if !join.using.is_empty() {
5866 if self.config.pretty {
5867 self.write_newline();
5868 self.indent_level += 1;
5869 self.write_indent();
5870 self.write_keyword("USING");
5871 self.write(" (");
5872 for (i, col) in join.using.iter().enumerate() {
5873 if i > 0 {
5874 self.write(", ");
5875 }
5876 self.generate_identifier(col)?;
5877 }
5878 self.write(")");
5879 self.indent_level -= 1;
5880 } else {
5881 self.write_space();
5882 self.write_keyword("USING");
5883 self.write(" (");
5884 for (i, col) in join.using.iter().enumerate() {
5885 if i > 0 {
5886 self.write(", ");
5887 }
5888 self.generate_identifier(col)?;
5889 }
5890 self.write(")");
5891 }
5892 }
5893
5894 for pivot in &join.pivots {
5896 self.write_space();
5897 self.generate_expression(pivot)?;
5898 }
5899
5900 Ok(())
5901 }
5902
5903 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
5905 if let Expression::And(and_op) = expr {
5906 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
5907 self.generate_expression(conditions[0])?;
5908 for condition in conditions.iter().skip(1) {
5909 self.write_newline();
5910 self.write_indent();
5911 self.write_keyword("AND");
5912 self.write_space();
5913 self.generate_expression(condition)?;
5914 }
5915 return Ok(());
5916 }
5917 }
5918
5919 self.generate_expression(expr)
5920 }
5921
5922 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
5923 self.write("(");
5925 self.generate_expression(&jt.left)?;
5926
5927 for join in &jt.joins {
5929 self.generate_join(join)?;
5930 }
5931
5932 for (lv_idx, lv) in jt.lateral_views.iter().enumerate() {
5934 self.generate_lateral_view(lv, lv_idx)?;
5935 }
5936
5937 self.write(")");
5938
5939 if let Some(alias) = &jt.alias {
5941 self.write_space();
5942 self.write_keyword("AS");
5943 self.write_space();
5944 self.generate_identifier(alias)?;
5945 }
5946
5947 Ok(())
5948 }
5949
5950 fn generate_lateral_view(&mut self, lv: &LateralView, lv_index: usize) -> Result<()> {
5951 use crate::dialects::DialectType;
5952
5953 if self.config.pretty {
5954 self.write_newline();
5955 self.write_indent();
5956 } else {
5957 self.write_space();
5958 }
5959
5960 let use_lateral_join = matches!(
5963 self.config.dialect,
5964 Some(DialectType::PostgreSQL)
5965 | Some(DialectType::DuckDB)
5966 | Some(DialectType::Snowflake)
5967 | Some(DialectType::TSQL)
5968 | Some(DialectType::Presto)
5969 | Some(DialectType::Trino)
5970 | Some(DialectType::Athena)
5971 );
5972
5973 let use_unnest = matches!(
5975 self.config.dialect,
5976 Some(DialectType::DuckDB)
5977 | Some(DialectType::Presto)
5978 | Some(DialectType::Trino)
5979 | Some(DialectType::Athena)
5980 );
5981
5982 let (is_posexplode, is_inline, func_args) = match &lv.this {
5984 Expression::Explode(uf) => {
5985 (false, false, vec![uf.this.clone()])
5987 }
5988 Expression::Unnest(uf) => {
5989 let mut args = vec![uf.this.clone()];
5990 args.extend(uf.expressions.clone());
5991 (false, false, args)
5992 }
5993 Expression::Function(func) => {
5994 if func.name.eq_ignore_ascii_case("POSEXPLODE")
5995 || func.name.eq_ignore_ascii_case("POSEXPLODE_OUTER")
5996 {
5997 (true, false, func.args.clone())
5998 } else if func.name.eq_ignore_ascii_case("INLINE") {
5999 (false, true, func.args.clone())
6000 } else if func.name.eq_ignore_ascii_case("EXPLODE")
6001 || func.name.eq_ignore_ascii_case("EXPLODE_OUTER")
6002 {
6003 (false, false, func.args.clone())
6004 } else {
6005 (false, false, vec![])
6006 }
6007 }
6008 _ => (false, false, vec![]),
6009 };
6010
6011 if use_lateral_join {
6012 if lv.outer {
6014 self.write_keyword("LEFT JOIN LATERAL");
6015 } else {
6016 self.write_keyword("CROSS JOIN");
6017 }
6018 self.write_space();
6019
6020 if use_unnest && !func_args.is_empty() {
6021 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6024 func_args
6026 .iter()
6027 .map(|a| {
6028 if let Expression::Function(ref f) = a {
6029 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() == 1 {
6030 return Expression::ArrayFunc(Box::new(
6031 crate::expressions::ArrayConstructor {
6032 expressions: f.args.clone(),
6033 bracket_notation: true,
6034 use_list_keyword: false,
6035 },
6036 ));
6037 }
6038 }
6039 a.clone()
6040 })
6041 .collect::<Vec<_>>()
6042 } else if matches!(
6043 self.config.dialect,
6044 Some(DialectType::Presto)
6045 | Some(DialectType::Trino)
6046 | Some(DialectType::Athena)
6047 ) {
6048 func_args
6050 .iter()
6051 .map(|a| {
6052 if let Expression::Function(ref f) = a {
6053 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() >= 1 {
6054 return Expression::ArrayFunc(Box::new(
6055 crate::expressions::ArrayConstructor {
6056 expressions: f.args.clone(),
6057 bracket_notation: true,
6058 use_list_keyword: false,
6059 },
6060 ));
6061 }
6062 }
6063 a.clone()
6064 })
6065 .collect::<Vec<_>>()
6066 } else {
6067 func_args
6068 };
6069
6070 if is_posexplode {
6072 self.write_keyword("LATERAL");
6073 self.write(" (");
6074 self.write_keyword("SELECT");
6075 self.write_space();
6076
6077 let pos_alias = if !lv.column_aliases.is_empty() {
6080 lv.column_aliases[0].clone()
6081 } else {
6082 Identifier::new("pos")
6083 };
6084 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
6085 lv.column_aliases[1..].to_vec()
6086 } else {
6087 vec![Identifier::new("col")]
6088 };
6089
6090 self.generate_identifier(&pos_alias)?;
6092 self.write(" - 1");
6093 self.write_space();
6094 self.write_keyword("AS");
6095 self.write_space();
6096 self.generate_identifier(&pos_alias)?;
6097
6098 for data_col in &data_aliases {
6100 self.write(", ");
6101 self.generate_identifier(data_col)?;
6102 }
6103
6104 self.write_space();
6105 self.write_keyword("FROM");
6106 self.write_space();
6107 self.write_keyword("UNNEST");
6108 self.write("(");
6109 for (i, arg) in unnest_args.iter().enumerate() {
6110 if i > 0 {
6111 self.write(", ");
6112 }
6113 self.generate_expression(arg)?;
6114 }
6115 self.write(")");
6116 self.write_space();
6117 self.write_keyword("WITH ORDINALITY");
6118 self.write_space();
6119 self.write_keyword("AS");
6120 self.write_space();
6121
6122 let table_alias_ident = lv
6124 .table_alias
6125 .clone()
6126 .unwrap_or_else(|| Identifier::new("t"));
6127 self.generate_identifier(&table_alias_ident)?;
6128 self.write("(");
6129 for (i, data_col) in data_aliases.iter().enumerate() {
6130 if i > 0 {
6131 self.write(", ");
6132 }
6133 self.generate_identifier(data_col)?;
6134 }
6135 self.write(", ");
6136 self.generate_identifier(&pos_alias)?;
6137 self.write("))");
6138 } else if is_inline && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6139 self.write_keyword("LATERAL");
6141 self.write(" (");
6142 self.write_keyword("SELECT");
6143 self.write_space();
6144 self.write_keyword("UNNEST");
6145 self.write("(");
6146 for (i, arg) in unnest_args.iter().enumerate() {
6147 if i > 0 {
6148 self.write(", ");
6149 }
6150 self.generate_expression(arg)?;
6151 }
6152 self.write(", ");
6153 self.write_keyword("max_depth");
6154 self.write(" => 2))");
6155
6156 if let Some(alias) = &lv.table_alias {
6158 self.write_space();
6159 self.write_keyword("AS");
6160 self.write_space();
6161 self.generate_identifier(alias)?;
6162 if !lv.column_aliases.is_empty() {
6163 self.write("(");
6164 for (i, col) in lv.column_aliases.iter().enumerate() {
6165 if i > 0 {
6166 self.write(", ");
6167 }
6168 self.generate_identifier(col)?;
6169 }
6170 self.write(")");
6171 }
6172 } else if !lv.column_aliases.is_empty() {
6173 self.write_space();
6175 self.write_keyword("AS");
6176 self.write_space();
6177 self.write(&format!("_u_{}", lv_index));
6178 self.write("(");
6179 for (i, col) in lv.column_aliases.iter().enumerate() {
6180 if i > 0 {
6181 self.write(", ");
6182 }
6183 self.generate_identifier(col)?;
6184 }
6185 self.write(")");
6186 }
6187 } else {
6188 self.write_keyword("UNNEST");
6189 self.write("(");
6190 for (i, arg) in unnest_args.iter().enumerate() {
6191 if i > 0 {
6192 self.write(", ");
6193 }
6194 self.generate_expression(arg)?;
6195 }
6196 self.write(")");
6197
6198 if let Some(alias) = &lv.table_alias {
6200 self.write_space();
6201 self.write_keyword("AS");
6202 self.write_space();
6203 self.generate_identifier(alias)?;
6204 if !lv.column_aliases.is_empty() {
6205 self.write("(");
6206 for (i, col) in lv.column_aliases.iter().enumerate() {
6207 if i > 0 {
6208 self.write(", ");
6209 }
6210 self.generate_identifier(col)?;
6211 }
6212 self.write(")");
6213 }
6214 } else if !lv.column_aliases.is_empty() {
6215 self.write_space();
6216 self.write_keyword("AS");
6217 self.write(" t(");
6218 for (i, col) in lv.column_aliases.iter().enumerate() {
6219 if i > 0 {
6220 self.write(", ");
6221 }
6222 self.generate_identifier(col)?;
6223 }
6224 self.write(")");
6225 }
6226 }
6227 } else {
6228 if !lv.outer {
6230 self.write_keyword("LATERAL");
6231 self.write_space();
6232 }
6233 self.generate_expression(&lv.this)?;
6234
6235 if let Some(alias) = &lv.table_alias {
6237 self.write_space();
6238 self.write_keyword("AS");
6239 self.write_space();
6240 self.generate_identifier(alias)?;
6241 if !lv.column_aliases.is_empty() {
6242 self.write("(");
6243 for (i, col) in lv.column_aliases.iter().enumerate() {
6244 if i > 0 {
6245 self.write(", ");
6246 }
6247 self.generate_identifier(col)?;
6248 }
6249 self.write(")");
6250 }
6251 } else if !lv.column_aliases.is_empty() {
6252 self.write_space();
6253 self.write_keyword("AS");
6254 self.write(" t(");
6255 for (i, col) in lv.column_aliases.iter().enumerate() {
6256 if i > 0 {
6257 self.write(", ");
6258 }
6259 self.generate_identifier(col)?;
6260 }
6261 self.write(")");
6262 }
6263 }
6264
6265 if lv.outer {
6267 self.write_space();
6268 self.write_keyword("ON TRUE");
6269 }
6270 } else {
6271 self.write_keyword("LATERAL VIEW");
6273 if lv.outer {
6274 self.write_space();
6275 self.write_keyword("OUTER");
6276 }
6277 if self.config.pretty {
6278 self.write_newline();
6279 self.write_indent();
6280 } else {
6281 self.write_space();
6282 }
6283 self.generate_expression(&lv.this)?;
6284
6285 if let Some(alias) = &lv.table_alias {
6287 self.write_space();
6288 self.generate_identifier(alias)?;
6289 }
6290
6291 if !lv.column_aliases.is_empty() {
6293 self.write_space();
6294 self.write_keyword("AS");
6295 self.write_space();
6296 for (i, col) in lv.column_aliases.iter().enumerate() {
6297 if i > 0 {
6298 self.write(", ");
6299 }
6300 self.generate_identifier(col)?;
6301 }
6302 }
6303 }
6304
6305 Ok(())
6306 }
6307
6308 fn generate_union(&mut self, outermost: &Union) -> Result<()> {
6309 let mut chain: Vec<&Union> = vec![outermost];
6314 let mut leftmost: &Expression = &outermost.left;
6315 while let Expression::Union(inner) = leftmost {
6316 chain.push(inner);
6317 leftmost = &inner.left;
6318 }
6319 if let Some(with) = &outermost.with {
6324 self.generate_with(with)?;
6325 self.write_space();
6326 }
6327
6328 self.generate_expression(leftmost)?;
6330
6331 for union in chain.iter().rev() {
6333 self.generate_union_step(union)?;
6334 }
6335 Ok(())
6336 }
6337
6338 fn generate_union_step(&mut self, union: &Union) -> Result<()> {
6340 if self.config.pretty {
6341 self.write_newline();
6342 self.write_indent();
6343 } else {
6344 self.write_space();
6345 }
6346
6347 if let Some(side) = &union.side {
6349 self.write_keyword(side);
6350 self.write_space();
6351 }
6352 if let Some(kind) = &union.kind {
6353 self.write_keyword(kind);
6354 self.write_space();
6355 }
6356
6357 self.write_keyword("UNION");
6358 if union.all {
6359 self.write_space();
6360 self.write_keyword("ALL");
6361 } else if union.distinct {
6362 self.write_space();
6363 self.write_keyword("DISTINCT");
6364 }
6365
6366 if union.corresponding || union.by_name {
6369 self.write_space();
6370 self.write_keyword("BY NAME");
6371 }
6372 if !union.on_columns.is_empty() {
6373 self.write_space();
6374 self.write_keyword("ON");
6375 self.write(" (");
6376 for (i, col) in union.on_columns.iter().enumerate() {
6377 if i > 0 {
6378 self.write(", ");
6379 }
6380 self.generate_expression(col)?;
6381 }
6382 self.write(")");
6383 }
6384
6385 if self.config.pretty {
6386 self.write_newline();
6387 self.write_indent();
6388 } else {
6389 self.write_space();
6390 }
6391 self.generate_expression(&union.right)?;
6392 if let Some(order_by) = &union.order_by {
6394 if self.config.pretty {
6395 self.write_newline();
6396 } else {
6397 self.write_space();
6398 }
6399 self.write_keyword("ORDER BY");
6400 self.write_space();
6401 for (i, ordered) in order_by.expressions.iter().enumerate() {
6402 if i > 0 {
6403 self.write(", ");
6404 }
6405 self.generate_ordered(ordered)?;
6406 }
6407 }
6408 if let Some(limit) = &union.limit {
6409 if self.config.pretty {
6410 self.write_newline();
6411 } else {
6412 self.write_space();
6413 }
6414 self.write_keyword("LIMIT");
6415 self.write_space();
6416 self.generate_expression(limit)?;
6417 }
6418 if let Some(offset) = &union.offset {
6419 if self.config.pretty {
6420 self.write_newline();
6421 } else {
6422 self.write_space();
6423 }
6424 self.write_keyword("OFFSET");
6425 self.write_space();
6426 self.generate_expression(offset)?;
6427 }
6428 if let Some(distribute_by) = &union.distribute_by {
6430 self.write_space();
6431 self.write_keyword("DISTRIBUTE BY");
6432 self.write_space();
6433 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6434 if i > 0 {
6435 self.write(", ");
6436 }
6437 self.generate_expression(expr)?;
6438 }
6439 }
6440 if let Some(sort_by) = &union.sort_by {
6442 self.write_space();
6443 self.write_keyword("SORT BY");
6444 self.write_space();
6445 for (i, ord) in sort_by.expressions.iter().enumerate() {
6446 if i > 0 {
6447 self.write(", ");
6448 }
6449 self.generate_ordered(ord)?;
6450 }
6451 }
6452 if let Some(cluster_by) = &union.cluster_by {
6454 self.write_space();
6455 self.write_keyword("CLUSTER BY");
6456 self.write_space();
6457 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6458 if i > 0 {
6459 self.write(", ");
6460 }
6461 self.generate_ordered(ord)?;
6462 }
6463 }
6464 Ok(())
6465 }
6466
6467 fn generate_intersect(&mut self, outermost: &Intersect) -> Result<()> {
6468 let mut chain: Vec<&Intersect> = vec![outermost];
6470 let mut leftmost: &Expression = &outermost.left;
6471 while let Expression::Intersect(inner) = leftmost {
6472 chain.push(inner);
6473 leftmost = &inner.left;
6474 }
6475
6476 if let Some(with) = &outermost.with {
6477 self.generate_with(with)?;
6478 self.write_space();
6479 }
6480
6481 self.generate_expression(leftmost)?;
6482
6483 for intersect in chain.iter().rev() {
6484 self.generate_intersect_step(intersect)?;
6485 }
6486 Ok(())
6487 }
6488
6489 fn generate_intersect_step(&mut self, intersect: &Intersect) -> Result<()> {
6491 if self.config.pretty {
6492 self.write_newline();
6493 self.write_indent();
6494 } else {
6495 self.write_space();
6496 }
6497
6498 if let Some(side) = &intersect.side {
6500 self.write_keyword(side);
6501 self.write_space();
6502 }
6503 if let Some(kind) = &intersect.kind {
6504 self.write_keyword(kind);
6505 self.write_space();
6506 }
6507
6508 self.write_keyword("INTERSECT");
6509 if intersect.all {
6510 self.write_space();
6511 self.write_keyword("ALL");
6512 } else if intersect.distinct {
6513 self.write_space();
6514 self.write_keyword("DISTINCT");
6515 }
6516
6517 if intersect.corresponding || intersect.by_name {
6520 self.write_space();
6521 self.write_keyword("BY NAME");
6522 }
6523 if !intersect.on_columns.is_empty() {
6524 self.write_space();
6525 self.write_keyword("ON");
6526 self.write(" (");
6527 for (i, col) in intersect.on_columns.iter().enumerate() {
6528 if i > 0 {
6529 self.write(", ");
6530 }
6531 self.generate_expression(col)?;
6532 }
6533 self.write(")");
6534 }
6535
6536 if self.config.pretty {
6537 self.write_newline();
6538 self.write_indent();
6539 } else {
6540 self.write_space();
6541 }
6542 self.generate_expression(&intersect.right)?;
6543 if let Some(order_by) = &intersect.order_by {
6545 if self.config.pretty {
6546 self.write_newline();
6547 } else {
6548 self.write_space();
6549 }
6550 self.write_keyword("ORDER BY");
6551 self.write_space();
6552 for (i, ordered) in order_by.expressions.iter().enumerate() {
6553 if i > 0 {
6554 self.write(", ");
6555 }
6556 self.generate_ordered(ordered)?;
6557 }
6558 }
6559 if let Some(limit) = &intersect.limit {
6560 if self.config.pretty {
6561 self.write_newline();
6562 } else {
6563 self.write_space();
6564 }
6565 self.write_keyword("LIMIT");
6566 self.write_space();
6567 self.generate_expression(limit)?;
6568 }
6569 if let Some(offset) = &intersect.offset {
6570 if self.config.pretty {
6571 self.write_newline();
6572 } else {
6573 self.write_space();
6574 }
6575 self.write_keyword("OFFSET");
6576 self.write_space();
6577 self.generate_expression(offset)?;
6578 }
6579 if let Some(distribute_by) = &intersect.distribute_by {
6581 self.write_space();
6582 self.write_keyword("DISTRIBUTE BY");
6583 self.write_space();
6584 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6585 if i > 0 {
6586 self.write(", ");
6587 }
6588 self.generate_expression(expr)?;
6589 }
6590 }
6591 if let Some(sort_by) = &intersect.sort_by {
6593 self.write_space();
6594 self.write_keyword("SORT BY");
6595 self.write_space();
6596 for (i, ord) in sort_by.expressions.iter().enumerate() {
6597 if i > 0 {
6598 self.write(", ");
6599 }
6600 self.generate_ordered(ord)?;
6601 }
6602 }
6603 if let Some(cluster_by) = &intersect.cluster_by {
6605 self.write_space();
6606 self.write_keyword("CLUSTER BY");
6607 self.write_space();
6608 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6609 if i > 0 {
6610 self.write(", ");
6611 }
6612 self.generate_ordered(ord)?;
6613 }
6614 }
6615 Ok(())
6616 }
6617
6618 fn generate_except(&mut self, outermost: &Except) -> Result<()> {
6619 let mut chain: Vec<&Except> = vec![outermost];
6621 let mut leftmost: &Expression = &outermost.left;
6622 while let Expression::Except(inner) = leftmost {
6623 chain.push(inner);
6624 leftmost = &inner.left;
6625 }
6626
6627 if let Some(with) = &outermost.with {
6628 self.generate_with(with)?;
6629 self.write_space();
6630 }
6631
6632 self.generate_expression(leftmost)?;
6633
6634 for except in chain.iter().rev() {
6635 self.generate_except_step(except)?;
6636 }
6637 Ok(())
6638 }
6639
6640 fn generate_except_step(&mut self, except: &Except) -> Result<()> {
6642 use crate::dialects::DialectType;
6643
6644 if self.config.pretty {
6645 self.write_newline();
6646 self.write_indent();
6647 } else {
6648 self.write_space();
6649 }
6650
6651 if let Some(side) = &except.side {
6653 self.write_keyword(side);
6654 self.write_space();
6655 }
6656 if let Some(kind) = &except.kind {
6657 self.write_keyword(kind);
6658 self.write_space();
6659 }
6660
6661 match self.config.dialect {
6663 Some(DialectType::Oracle) if !except.all => {
6664 self.write_keyword("MINUS");
6665 }
6666 Some(DialectType::ClickHouse) => {
6667 self.write_keyword("EXCEPT");
6669 if except.distinct {
6670 self.write_space();
6671 self.write_keyword("DISTINCT");
6672 }
6673 }
6674 Some(DialectType::BigQuery) => {
6675 self.write_keyword("EXCEPT");
6677 if except.all {
6678 self.write_space();
6679 self.write_keyword("ALL");
6680 } else {
6681 self.write_space();
6682 self.write_keyword("DISTINCT");
6683 }
6684 }
6685 _ => {
6686 self.write_keyword("EXCEPT");
6687 if except.all {
6688 self.write_space();
6689 self.write_keyword("ALL");
6690 } else if except.distinct {
6691 self.write_space();
6692 self.write_keyword("DISTINCT");
6693 }
6694 }
6695 }
6696
6697 if except.corresponding || except.by_name {
6700 self.write_space();
6701 self.write_keyword("BY NAME");
6702 }
6703 if !except.on_columns.is_empty() {
6704 self.write_space();
6705 self.write_keyword("ON");
6706 self.write(" (");
6707 for (i, col) in except.on_columns.iter().enumerate() {
6708 if i > 0 {
6709 self.write(", ");
6710 }
6711 self.generate_expression(col)?;
6712 }
6713 self.write(")");
6714 }
6715
6716 if self.config.pretty {
6717 self.write_newline();
6718 self.write_indent();
6719 } else {
6720 self.write_space();
6721 }
6722 self.generate_expression(&except.right)?;
6723 if let Some(order_by) = &except.order_by {
6725 if self.config.pretty {
6726 self.write_newline();
6727 } else {
6728 self.write_space();
6729 }
6730 self.write_keyword("ORDER BY");
6731 self.write_space();
6732 for (i, ordered) in order_by.expressions.iter().enumerate() {
6733 if i > 0 {
6734 self.write(", ");
6735 }
6736 self.generate_ordered(ordered)?;
6737 }
6738 }
6739 if let Some(limit) = &except.limit {
6740 if self.config.pretty {
6741 self.write_newline();
6742 } else {
6743 self.write_space();
6744 }
6745 self.write_keyword("LIMIT");
6746 self.write_space();
6747 self.generate_expression(limit)?;
6748 }
6749 if let Some(offset) = &except.offset {
6750 if self.config.pretty {
6751 self.write_newline();
6752 } else {
6753 self.write_space();
6754 }
6755 self.write_keyword("OFFSET");
6756 self.write_space();
6757 self.generate_expression(offset)?;
6758 }
6759 if let Some(distribute_by) = &except.distribute_by {
6761 self.write_space();
6762 self.write_keyword("DISTRIBUTE BY");
6763 self.write_space();
6764 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6765 if i > 0 {
6766 self.write(", ");
6767 }
6768 self.generate_expression(expr)?;
6769 }
6770 }
6771 if let Some(sort_by) = &except.sort_by {
6773 self.write_space();
6774 self.write_keyword("SORT BY");
6775 self.write_space();
6776 for (i, ord) in sort_by.expressions.iter().enumerate() {
6777 if i > 0 {
6778 self.write(", ");
6779 }
6780 self.generate_ordered(ord)?;
6781 }
6782 }
6783 if let Some(cluster_by) = &except.cluster_by {
6785 self.write_space();
6786 self.write_keyword("CLUSTER BY");
6787 self.write_space();
6788 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6789 if i > 0 {
6790 self.write(", ");
6791 }
6792 self.generate_ordered(ord)?;
6793 }
6794 }
6795 Ok(())
6796 }
6797
6798 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
6799 let prepend_query_cte = if insert.with.is_none() {
6801 use crate::dialects::DialectType;
6802 let should_prepend = matches!(
6803 self.config.dialect,
6804 Some(DialectType::TSQL)
6805 | Some(DialectType::Fabric)
6806 | Some(DialectType::Spark)
6807 | Some(DialectType::Databricks)
6808 | Some(DialectType::Hive)
6809 );
6810 if should_prepend {
6811 if let Some(Expression::Select(select)) = &insert.query {
6812 select.with.clone()
6813 } else {
6814 None
6815 }
6816 } else {
6817 None
6818 }
6819 } else {
6820 None
6821 };
6822
6823 if let Some(with) = &insert.with {
6825 self.generate_with(with)?;
6826 self.write_space();
6827 } else if let Some(with) = &prepend_query_cte {
6828 self.generate_with(with)?;
6829 self.write_space();
6830 }
6831
6832 for comment in &insert.leading_comments {
6834 self.write_formatted_comment(comment);
6835 self.write(" ");
6836 }
6837
6838 if let Some(dir) = &insert.directory {
6840 self.write_keyword("INSERT OVERWRITE");
6841 if dir.local {
6842 self.write_space();
6843 self.write_keyword("LOCAL");
6844 }
6845 self.write_space();
6846 self.write_keyword("DIRECTORY");
6847 self.write_space();
6848 self.write("'");
6849 self.write(&dir.path);
6850 self.write("'");
6851
6852 if let Some(row_format) = &dir.row_format {
6854 self.write_space();
6855 self.write_keyword("ROW FORMAT");
6856 if row_format.delimited {
6857 self.write_space();
6858 self.write_keyword("DELIMITED");
6859 }
6860 if let Some(val) = &row_format.fields_terminated_by {
6861 self.write_space();
6862 self.write_keyword("FIELDS TERMINATED BY");
6863 self.write_space();
6864 self.write("'");
6865 self.write(val);
6866 self.write("'");
6867 }
6868 if let Some(val) = &row_format.collection_items_terminated_by {
6869 self.write_space();
6870 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
6871 self.write_space();
6872 self.write("'");
6873 self.write(val);
6874 self.write("'");
6875 }
6876 if let Some(val) = &row_format.map_keys_terminated_by {
6877 self.write_space();
6878 self.write_keyword("MAP KEYS TERMINATED BY");
6879 self.write_space();
6880 self.write("'");
6881 self.write(val);
6882 self.write("'");
6883 }
6884 if let Some(val) = &row_format.lines_terminated_by {
6885 self.write_space();
6886 self.write_keyword("LINES TERMINATED BY");
6887 self.write_space();
6888 self.write("'");
6889 self.write(val);
6890 self.write("'");
6891 }
6892 if let Some(val) = &row_format.null_defined_as {
6893 self.write_space();
6894 self.write_keyword("NULL DEFINED AS");
6895 self.write_space();
6896 self.write("'");
6897 self.write(val);
6898 self.write("'");
6899 }
6900 }
6901
6902 if let Some(format) = &dir.stored_as {
6904 self.write_space();
6905 self.write_keyword("STORED AS");
6906 self.write_space();
6907 self.write_keyword(format);
6908 }
6909
6910 if let Some(query) = &insert.query {
6912 self.write_space();
6913 self.generate_expression(query)?;
6914 }
6915
6916 return Ok(());
6917 }
6918
6919 if insert.is_replace {
6920 self.write_keyword("REPLACE INTO");
6922 } else if insert.overwrite {
6923 self.write_keyword("INSERT");
6925 if let Some(ref hint) = insert.hint {
6927 self.generate_hint(hint)?;
6928 }
6929 self.write(&self.config.insert_overwrite.to_ascii_uppercase());
6930 } else if let Some(ref action) = insert.conflict_action {
6931 self.write_keyword("INSERT OR");
6933 self.write_space();
6934 self.write_keyword(action);
6935 self.write_space();
6936 self.write_keyword("INTO");
6937 } else if insert.ignore {
6938 self.write_keyword("INSERT IGNORE INTO");
6940 } else {
6941 self.write_keyword("INSERT");
6942 if let Some(ref hint) = insert.hint {
6944 self.generate_hint(hint)?;
6945 }
6946 self.write_space();
6947 self.write_keyword("INTO");
6948 }
6949 if let Some(ref func) = insert.function_target {
6951 self.write_space();
6952 self.write_keyword("FUNCTION");
6953 self.write_space();
6954 self.generate_expression(func)?;
6955 } else {
6956 self.write_space();
6957 self.generate_table(&insert.table)?;
6958 }
6959
6960 if let Some(ref alias) = insert.alias {
6962 self.write_space();
6963 if insert.alias_explicit_as {
6964 self.write_keyword("AS");
6965 self.write_space();
6966 }
6967 self.generate_identifier(alias)?;
6968 }
6969
6970 if insert.if_exists {
6972 self.write_space();
6973 self.write_keyword("IF EXISTS");
6974 }
6975
6976 if let Some(ref replace_where) = insert.replace_where {
6978 if self.config.pretty {
6979 self.write_newline();
6980 self.write_indent();
6981 } else {
6982 self.write_space();
6983 }
6984 self.write_keyword("REPLACE WHERE");
6985 self.write_space();
6986 self.generate_expression(replace_where)?;
6987 }
6988
6989 if !insert.partition.is_empty() {
6991 self.write_space();
6992 self.write_keyword("PARTITION");
6993 self.write("(");
6994 for (i, (col, val)) in insert.partition.iter().enumerate() {
6995 if i > 0 {
6996 self.write(", ");
6997 }
6998 self.generate_identifier(col)?;
6999 if let Some(v) = val {
7000 self.write(" = ");
7001 self.generate_expression(v)?;
7002 }
7003 }
7004 self.write(")");
7005 }
7006
7007 if let Some(ref partition_by) = insert.partition_by {
7009 self.write_space();
7010 self.write_keyword("PARTITION BY");
7011 self.write_space();
7012 self.generate_expression(partition_by)?;
7013 }
7014
7015 if !insert.settings.is_empty() {
7017 self.write_space();
7018 self.write_keyword("SETTINGS");
7019 self.write_space();
7020 for (i, setting) in insert.settings.iter().enumerate() {
7021 if i > 0 {
7022 self.write(", ");
7023 }
7024 self.generate_expression(setting)?;
7025 }
7026 }
7027
7028 if !insert.columns.is_empty() {
7029 if insert.alias.is_some() && insert.alias_explicit_as {
7030 self.write("(");
7032 } else {
7033 self.write(" (");
7035 }
7036 for (i, col) in insert.columns.iter().enumerate() {
7037 if i > 0 {
7038 self.write(", ");
7039 }
7040 self.generate_identifier(col)?;
7041 }
7042 self.write(")");
7043 }
7044
7045 if let Some(ref output) = insert.output {
7047 self.generate_output_clause(output)?;
7048 }
7049
7050 if insert.by_name {
7052 self.write_space();
7053 self.write_keyword("BY NAME");
7054 }
7055
7056 if insert.default_values {
7057 self.write_space();
7058 self.write_keyword("DEFAULT VALUES");
7059 } else if let Some(query) = &insert.query {
7060 if self.config.pretty {
7061 self.write_newline();
7062 } else {
7063 self.write_space();
7064 }
7065 if prepend_query_cte.is_some() {
7067 if let Expression::Select(select) = query {
7068 let mut select_no_with = select.clone();
7069 select_no_with.with = None;
7070 self.generate_select(&select_no_with)?;
7071 } else {
7072 self.generate_expression(query)?;
7073 }
7074 } else {
7075 self.generate_expression(query)?;
7076 }
7077 } else if !insert.values.is_empty() {
7078 if self.config.pretty {
7079 self.write_newline();
7081 self.write_keyword("VALUES");
7082 self.write_newline();
7083 self.indent_level += 1;
7084 for (i, row) in insert.values.iter().enumerate() {
7085 if i > 0 {
7086 self.write(",");
7087 self.write_newline();
7088 }
7089 self.write_indent();
7090 self.write("(");
7091 for (j, val) in row.iter().enumerate() {
7092 if j > 0 {
7093 self.write(", ");
7094 }
7095 self.generate_expression(val)?;
7096 }
7097 self.write(")");
7098 }
7099 self.indent_level -= 1;
7100 } else {
7101 self.write_space();
7103 self.write_keyword("VALUES");
7104 for (i, row) in insert.values.iter().enumerate() {
7105 if i > 0 {
7106 self.write(",");
7107 }
7108 self.write(" (");
7109 for (j, val) in row.iter().enumerate() {
7110 if j > 0 {
7111 self.write(", ");
7112 }
7113 self.generate_expression(val)?;
7114 }
7115 self.write(")");
7116 }
7117 }
7118 }
7119
7120 if let Some(ref source) = insert.source {
7122 self.write_space();
7123 self.write_keyword("TABLE");
7124 self.write_space();
7125 self.generate_expression(source)?;
7126 }
7127
7128 if let Some(alias) = &insert.source_alias {
7130 self.write_space();
7131 self.write_keyword("AS");
7132 self.write_space();
7133 self.generate_identifier(alias)?;
7134 }
7135
7136 if let Some(on_conflict) = &insert.on_conflict {
7138 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
7139 self.write_space();
7140 self.generate_expression(on_conflict)?;
7141 }
7142 }
7143
7144 if !insert.returning.is_empty() {
7146 self.write_space();
7147 self.write_keyword("RETURNING");
7148 self.write_space();
7149 for (i, expr) in insert.returning.iter().enumerate() {
7150 if i > 0 {
7151 self.write(", ");
7152 }
7153 self.generate_expression(expr)?;
7154 }
7155 }
7156
7157 Ok(())
7158 }
7159
7160 fn generate_update(&mut self, update: &Update) -> Result<()> {
7161 for comment in &update.leading_comments {
7163 self.write_formatted_comment(comment);
7164 self.write(" ");
7165 }
7166
7167 if let Some(ref with) = update.with {
7169 self.generate_with(with)?;
7170 self.write_space();
7171 }
7172
7173 self.write_keyword("UPDATE");
7174 self.write_space();
7175 self.generate_table(&update.table)?;
7176
7177 let mysql_like_update_from = matches!(
7178 self.config.dialect,
7179 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
7180 ) && update.from_clause.is_some();
7181
7182 let mut set_pairs = update.set.clone();
7183
7184 let mut pre_set_joins = update.table_joins.clone();
7186 if mysql_like_update_from {
7187 let target_name = update
7188 .table
7189 .alias
7190 .as_ref()
7191 .map(|a| a.name.clone())
7192 .unwrap_or_else(|| update.table.name.name.clone());
7193
7194 for (col, _) in &mut set_pairs {
7195 if !col.name.contains('.') {
7196 col.name = format!("{}.{}", target_name, col.name);
7197 }
7198 }
7199
7200 if let Some(from_clause) = &update.from_clause {
7201 for table_expr in &from_clause.expressions {
7202 pre_set_joins.push(crate::expressions::Join {
7203 this: table_expr.clone(),
7204 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7205 value: true,
7206 })),
7207 using: Vec::new(),
7208 kind: crate::expressions::JoinKind::Inner,
7209 use_inner_keyword: false,
7210 use_outer_keyword: false,
7211 deferred_condition: false,
7212 join_hint: None,
7213 match_condition: None,
7214 pivots: Vec::new(),
7215 comments: Vec::new(),
7216 nesting_group: 0,
7217 directed: false,
7218 });
7219 }
7220 }
7221 for join in &update.from_joins {
7222 let mut join = join.clone();
7223 if join.on.is_none() && join.using.is_empty() {
7224 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7225 value: true,
7226 }));
7227 }
7228 pre_set_joins.push(join);
7229 }
7230 }
7231
7232 for extra_table in &update.extra_tables {
7234 self.write(", ");
7235 self.generate_table(extra_table)?;
7236 }
7237
7238 for join in &pre_set_joins {
7240 self.generate_join(join)?;
7242 }
7243
7244 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
7246 if teradata_from_before_set && !mysql_like_update_from {
7247 if let Some(ref from_clause) = update.from_clause {
7248 self.write_space();
7249 self.write_keyword("FROM");
7250 self.write_space();
7251 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7252 if i > 0 {
7253 self.write(", ");
7254 }
7255 self.generate_expression(table_expr)?;
7256 }
7257 }
7258 for join in &update.from_joins {
7259 self.generate_join(join)?;
7260 }
7261 }
7262
7263 self.write_space();
7264 self.write_keyword("SET");
7265 self.write_space();
7266
7267 for (i, (col, val)) in set_pairs.iter().enumerate() {
7268 if i > 0 {
7269 self.write(", ");
7270 }
7271 self.generate_identifier(col)?;
7272 self.write(" = ");
7273 self.generate_expression(val)?;
7274 }
7275
7276 if let Some(ref output) = update.output {
7278 self.generate_output_clause(output)?;
7279 }
7280
7281 if !mysql_like_update_from && !teradata_from_before_set {
7283 if let Some(ref from_clause) = update.from_clause {
7284 self.write_space();
7285 self.write_keyword("FROM");
7286 self.write_space();
7287 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7289 if i > 0 {
7290 self.write(", ");
7291 }
7292 self.generate_expression(table_expr)?;
7293 }
7294 }
7295 }
7296
7297 if !mysql_like_update_from && !teradata_from_before_set {
7298 for join in &update.from_joins {
7300 self.generate_join(join)?;
7301 }
7302 }
7303
7304 if let Some(where_clause) = &update.where_clause {
7305 self.write_space();
7306 self.write_keyword("WHERE");
7307 self.write_space();
7308 self.generate_expression(&where_clause.this)?;
7309 }
7310
7311 if !update.returning.is_empty() {
7313 self.write_space();
7314 self.write_keyword("RETURNING");
7315 self.write_space();
7316 for (i, expr) in update.returning.iter().enumerate() {
7317 if i > 0 {
7318 self.write(", ");
7319 }
7320 self.generate_expression(expr)?;
7321 }
7322 }
7323
7324 if let Some(ref order_by) = update.order_by {
7326 self.write_space();
7327 self.generate_order_by(order_by)?;
7328 }
7329
7330 if let Some(ref limit) = update.limit {
7332 self.write_space();
7333 self.write_keyword("LIMIT");
7334 self.write_space();
7335 self.generate_expression(limit)?;
7336 }
7337
7338 Ok(())
7339 }
7340
7341 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
7342 if let Some(with) = &delete.with {
7344 self.generate_with(with)?;
7345 self.write_space();
7346 }
7347
7348 for comment in &delete.leading_comments {
7350 self.write_formatted_comment(comment);
7351 self.write(" ");
7352 }
7353
7354 if !delete.tables.is_empty() && !delete.tables_from_using {
7356 self.write_keyword("DELETE");
7358 self.write_space();
7359 for (i, tbl) in delete.tables.iter().enumerate() {
7360 if i > 0 {
7361 self.write(", ");
7362 }
7363 self.generate_table(tbl)?;
7364 }
7365 if let Some(ref output) = delete.output {
7367 self.generate_output_clause(output)?;
7368 }
7369 self.write_space();
7370 self.write_keyword("FROM");
7371 self.write_space();
7372 self.generate_table(&delete.table)?;
7373 } else if !delete.tables.is_empty() && delete.tables_from_using {
7374 self.write_keyword("DELETE FROM");
7376 self.write_space();
7377 for (i, tbl) in delete.tables.iter().enumerate() {
7378 if i > 0 {
7379 self.write(", ");
7380 }
7381 self.generate_table(tbl)?;
7382 }
7383 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
7384 self.write_keyword("DELETE");
7386 self.write_space();
7387 self.generate_table(&delete.table)?;
7388 } else {
7389 self.write_keyword("DELETE FROM");
7390 self.write_space();
7391 self.generate_table(&delete.table)?;
7392 }
7393
7394 if let Some(ref on_cluster) = delete.on_cluster {
7396 self.write_space();
7397 self.generate_on_cluster(on_cluster)?;
7398 }
7399
7400 if let Some(ref idx) = delete.force_index {
7402 self.write_space();
7403 self.write_keyword("FORCE INDEX");
7404 self.write(" (");
7405 self.write(idx);
7406 self.write(")");
7407 }
7408
7409 if let Some(ref alias) = delete.alias {
7411 self.write_space();
7412 if delete.alias_explicit_as
7413 || matches!(self.config.dialect, Some(DialectType::BigQuery))
7414 {
7415 self.write_keyword("AS");
7416 self.write_space();
7417 }
7418 self.generate_identifier(alias)?;
7419 }
7420
7421 if !delete.tables_from_using {
7423 for join in &delete.joins {
7424 self.generate_join(join)?;
7425 }
7426 }
7427
7428 if !delete.using.is_empty() {
7430 self.write_space();
7431 self.write_keyword("USING");
7432 for (i, table) in delete.using.iter().enumerate() {
7433 if i > 0 {
7434 self.write(",");
7435 }
7436 self.write_space();
7437 if !table.hints.is_empty() && table.name.is_empty() {
7439 self.generate_expression(&table.hints[0])?;
7441 if let Some(ref alias) = table.alias {
7442 self.write_space();
7443 if table.alias_explicit_as {
7444 self.write_keyword("AS");
7445 self.write_space();
7446 }
7447 self.generate_identifier(alias)?;
7448 if !table.column_aliases.is_empty() {
7449 self.write("(");
7450 for (j, col_alias) in table.column_aliases.iter().enumerate() {
7451 if j > 0 {
7452 self.write(", ");
7453 }
7454 self.generate_identifier(col_alias)?;
7455 }
7456 self.write(")");
7457 }
7458 }
7459 } else {
7460 self.generate_table(table)?;
7461 }
7462 }
7463 }
7464
7465 if delete.tables_from_using {
7467 for join in &delete.joins {
7468 self.generate_join(join)?;
7469 }
7470 }
7471
7472 let output_already_emitted =
7474 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
7475 if !output_already_emitted {
7476 if let Some(ref output) = delete.output {
7477 self.generate_output_clause(output)?;
7478 }
7479 }
7480
7481 if let Some(where_clause) = &delete.where_clause {
7482 self.write_space();
7483 self.write_keyword("WHERE");
7484 self.write_space();
7485 self.generate_expression(&where_clause.this)?;
7486 }
7487
7488 if let Some(ref order_by) = delete.order_by {
7490 self.write_space();
7491 self.generate_order_by(order_by)?;
7492 }
7493
7494 if let Some(ref limit) = delete.limit {
7496 self.write_space();
7497 self.write_keyword("LIMIT");
7498 self.write_space();
7499 self.generate_expression(limit)?;
7500 }
7501
7502 if !delete.returning.is_empty() {
7504 self.write_space();
7505 self.write_keyword("RETURNING");
7506 self.write_space();
7507 for (i, expr) in delete.returning.iter().enumerate() {
7508 if i > 0 {
7509 self.write(", ");
7510 }
7511 self.generate_expression(expr)?;
7512 }
7513 }
7514
7515 Ok(())
7516 }
7517
7518 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
7521 let saved_athena_hive_context = self.athena_hive_context;
7525 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
7526 if matches!(
7527 self.config.dialect,
7528 Some(crate::dialects::DialectType::Athena)
7529 ) {
7530 let is_external = ct
7534 .table_modifier
7535 .as_ref()
7536 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
7537 .unwrap_or(false);
7538 let has_as_select = ct.as_select.is_some();
7539 self.athena_hive_context = is_external || !has_as_select;
7540 }
7541
7542 if matches!(
7544 self.config.dialect,
7545 Some(crate::dialects::DialectType::TSQL)
7546 ) {
7547 if let Some(ref query) = ct.as_select {
7548 if let Some(with_cte) = &ct.with_cte {
7550 self.generate_with(with_cte)?;
7551 self.write_space();
7552 }
7553
7554 self.write_keyword("SELECT");
7556 self.write(" * ");
7557 self.write_keyword("INTO");
7558 self.write_space();
7559
7560 if ct.temporary {
7562 self.write("#");
7563 }
7564 self.generate_table(&ct.name)?;
7565
7566 self.write_space();
7567 self.write_keyword("FROM");
7568 self.write(" (");
7569 let aliased_query = Self::add_column_aliases_to_query(query.clone());
7571 self.generate_expression(&aliased_query)?;
7572 self.write(") ");
7573 self.write_keyword("AS");
7574 self.write(" temp");
7575 return Ok(());
7576 }
7577 }
7578
7579 if let Some(with_cte) = &ct.with_cte {
7581 self.generate_with(with_cte)?;
7582 self.write_space();
7583 }
7584
7585 for comment in &ct.leading_comments {
7587 self.write_formatted_comment(comment);
7588 self.write(" ");
7589 }
7590 self.write_keyword("CREATE");
7591
7592 if ct.or_replace {
7593 self.write_space();
7594 self.write_keyword("OR REPLACE");
7595 }
7596
7597 if ct.temporary {
7598 self.write_space();
7599 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
7601 self.write_keyword("GLOBAL TEMPORARY");
7602 } else {
7603 self.write_keyword("TEMPORARY");
7604 }
7605 }
7606
7607 let is_dictionary = ct
7609 .table_modifier
7610 .as_ref()
7611 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
7612 .unwrap_or(false);
7613 if let Some(ref modifier) = ct.table_modifier {
7614 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
7616 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
7617 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
7619 || modifier.eq_ignore_ascii_case("SET")
7620 || modifier.eq_ignore_ascii_case("MULTISET")
7621 || modifier.to_ascii_uppercase().contains("VOLATILE")
7622 || modifier.to_ascii_uppercase().starts_with("SET ")
7623 || modifier.to_ascii_uppercase().starts_with("MULTISET ");
7624 let skip_teradata =
7625 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
7626 if !skip_transient && !skip_teradata {
7627 self.write_space();
7628 self.write_keyword(modifier);
7629 }
7630 }
7631
7632 if !is_dictionary {
7633 self.write_space();
7634 self.write_keyword("TABLE");
7635 }
7636
7637 if ct.if_not_exists {
7638 self.write_space();
7639 self.write_keyword("IF NOT EXISTS");
7640 }
7641
7642 self.write_space();
7643 self.generate_table(&ct.name)?;
7644
7645 if let Some(ref uuid) = ct.uuid {
7647 self.write_space();
7648 self.write_keyword("UUID");
7649 self.write(" '");
7650 self.write(uuid);
7651 self.write("'");
7652 }
7653
7654 if let Some(ref on_cluster) = ct.on_cluster {
7656 self.write_space();
7657 self.generate_on_cluster(on_cluster)?;
7658 }
7659
7660 if matches!(
7662 self.config.dialect,
7663 Some(crate::dialects::DialectType::Teradata)
7664 ) && !ct.teradata_post_name_options.is_empty()
7665 {
7666 for opt in &ct.teradata_post_name_options {
7667 self.write(", ");
7668 self.write(opt);
7669 }
7670 }
7671
7672 if ct.copy_grants {
7674 self.write_space();
7675 self.write_keyword("COPY GRANTS");
7676 }
7677
7678 if let Some(ref using_template) = ct.using_template {
7680 self.write_space();
7681 self.write_keyword("USING TEMPLATE");
7682 self.write_space();
7683 self.generate_expression(using_template)?;
7684 return Ok(());
7685 }
7686
7687 if let Some(ref clone_source) = ct.clone_source {
7689 self.write_space();
7690 if ct.is_copy && self.config.supports_table_copy {
7691 self.write_keyword("COPY");
7693 } else if ct.shallow_clone {
7694 self.write_keyword("SHALLOW CLONE");
7695 } else {
7696 self.write_keyword("CLONE");
7697 }
7698 self.write_space();
7699 self.generate_table(clone_source)?;
7700 if let Some(ref at_clause) = ct.clone_at_clause {
7702 self.write_space();
7703 self.generate_expression(at_clause)?;
7704 }
7705 return Ok(());
7706 }
7707
7708 if let Some(ref partition_of) = ct.partition_of {
7712 self.write_space();
7713
7714 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
7716 self.write_keyword("PARTITION OF");
7718 self.write_space();
7719 self.generate_expression(&pop.this)?;
7720
7721 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7723 self.write(" (");
7724 let mut first = true;
7725 for col in &ct.columns {
7726 if !first {
7727 self.write(", ");
7728 }
7729 first = false;
7730 self.generate_column_def(col)?;
7731 }
7732 for constraint in &ct.constraints {
7733 if !first {
7734 self.write(", ");
7735 }
7736 first = false;
7737 self.generate_table_constraint(constraint)?;
7738 }
7739 self.write(")");
7740 }
7741
7742 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
7744 self.write_space();
7745 self.write_keyword("FOR VALUES");
7746 self.write_space();
7747 self.generate_expression(&pop.expression)?;
7748 } else {
7749 self.write_space();
7750 self.write_keyword("DEFAULT");
7751 }
7752 } else {
7753 self.generate_expression(partition_of)?;
7755
7756 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7758 self.write(" (");
7759 let mut first = true;
7760 for col in &ct.columns {
7761 if !first {
7762 self.write(", ");
7763 }
7764 first = false;
7765 self.generate_column_def(col)?;
7766 }
7767 for constraint in &ct.constraints {
7768 if !first {
7769 self.write(", ");
7770 }
7771 first = false;
7772 self.generate_table_constraint(constraint)?;
7773 }
7774 self.write(")");
7775 }
7776 }
7777
7778 for prop in &ct.properties {
7780 self.write_space();
7781 self.generate_expression(prop)?;
7782 }
7783
7784 return Ok(());
7785 }
7786
7787 self.sqlite_inline_pk_columns.clear();
7790 if matches!(
7791 self.config.dialect,
7792 Some(crate::dialects::DialectType::SQLite)
7793 ) {
7794 for constraint in &ct.constraints {
7795 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7796 if columns.len() == 1 && name.is_none() {
7798 let pk_col_name = columns[0].name.to_ascii_lowercase();
7799 if ct
7801 .columns
7802 .iter()
7803 .any(|c| c.name.name.to_ascii_lowercase() == pk_col_name)
7804 {
7805 self.sqlite_inline_pk_columns.insert(pk_col_name);
7806 }
7807 }
7808 }
7809 }
7810 }
7811
7812 if !ct.columns.is_empty() {
7814 if self.config.pretty {
7815 self.write(" (");
7817 self.write_newline();
7818 self.indent_level += 1;
7819 for (i, col) in ct.columns.iter().enumerate() {
7820 if i > 0 {
7821 self.write(",");
7822 self.write_newline();
7823 }
7824 self.write_indent();
7825 self.generate_column_def(col)?;
7826 }
7827 for constraint in &ct.constraints {
7829 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7831 if columns.len() == 1
7832 && name.is_none()
7833 && self
7834 .sqlite_inline_pk_columns
7835 .contains(&columns[0].name.to_ascii_lowercase())
7836 {
7837 continue;
7838 }
7839 }
7840 self.write(",");
7841 self.write_newline();
7842 self.write_indent();
7843 self.generate_table_constraint(constraint)?;
7844 }
7845 self.indent_level -= 1;
7846 self.write_newline();
7847 self.write(")");
7848 } else {
7849 self.write(" (");
7850 for (i, col) in ct.columns.iter().enumerate() {
7851 if i > 0 {
7852 self.write(", ");
7853 }
7854 self.generate_column_def(col)?;
7855 }
7856 let mut first_constraint = true;
7858 for constraint in &ct.constraints {
7859 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7861 if columns.len() == 1
7862 && name.is_none()
7863 && self
7864 .sqlite_inline_pk_columns
7865 .contains(&columns[0].name.to_ascii_lowercase())
7866 {
7867 continue;
7868 }
7869 }
7870 if first_constraint {
7871 self.write(", ");
7872 first_constraint = false;
7873 } else {
7874 self.write(", ");
7875 }
7876 self.generate_table_constraint(constraint)?;
7877 }
7878 self.write(")");
7879 }
7880 } else if !ct.constraints.is_empty() {
7881 let has_like_only = ct
7883 .constraints
7884 .iter()
7885 .all(|c| matches!(c, TableConstraint::Like { .. }));
7886 let has_tags_only = ct
7887 .constraints
7888 .iter()
7889 .all(|c| matches!(c, TableConstraint::Tags(_)));
7890 let is_pg_like = matches!(
7894 self.config.dialect,
7895 Some(crate::dialects::DialectType::PostgreSQL)
7896 | Some(crate::dialects::DialectType::CockroachDB)
7897 | Some(crate::dialects::DialectType::Materialize)
7898 | Some(crate::dialects::DialectType::RisingWave)
7899 | Some(crate::dialects::DialectType::Redshift)
7900 | Some(crate::dialects::DialectType::Presto)
7901 | Some(crate::dialects::DialectType::Trino)
7902 | Some(crate::dialects::DialectType::Athena)
7903 );
7904 let use_parens = if has_like_only {
7905 is_pg_like
7906 } else {
7907 !has_tags_only
7908 };
7909 if self.config.pretty && use_parens {
7910 self.write(" (");
7911 self.write_newline();
7912 self.indent_level += 1;
7913 for (i, constraint) in ct.constraints.iter().enumerate() {
7914 if i > 0 {
7915 self.write(",");
7916 self.write_newline();
7917 }
7918 self.write_indent();
7919 self.generate_table_constraint(constraint)?;
7920 }
7921 self.indent_level -= 1;
7922 self.write_newline();
7923 self.write(")");
7924 } else {
7925 if use_parens {
7926 self.write(" (");
7927 } else {
7928 self.write_space();
7929 }
7930 for (i, constraint) in ct.constraints.iter().enumerate() {
7931 if i > 0 {
7932 self.write(", ");
7933 }
7934 self.generate_table_constraint(constraint)?;
7935 }
7936 if use_parens {
7937 self.write(")");
7938 }
7939 }
7940 }
7941
7942 if let Some(ref on_prop) = ct.on_property {
7944 self.write(" ");
7945 self.write_keyword("ON");
7946 self.write(" ");
7947 self.generate_expression(&on_prop.this)?;
7948 }
7949
7950 if !is_clickhouse {
7953 for prop in &ct.properties {
7954 if let Expression::SchemaCommentProperty(_) = prop {
7955 if self.config.pretty {
7956 self.write_newline();
7957 } else {
7958 self.write_space();
7959 }
7960 self.generate_expression(prop)?;
7961 }
7962 }
7963 }
7964
7965 if !ct.with_properties.is_empty() {
7967 let is_snowflake_special_table = matches!(
7969 self.config.dialect,
7970 Some(crate::dialects::DialectType::Snowflake)
7971 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
7972 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
7973 if is_snowflake_special_table {
7974 for (key, value) in &ct.with_properties {
7975 self.write_space();
7976 self.write(key);
7977 self.write("=");
7978 self.write(value);
7979 }
7980 } else if self.config.pretty {
7981 self.write_newline();
7982 self.write_keyword("WITH");
7983 self.write(" (");
7984 self.write_newline();
7985 self.indent_level += 1;
7986 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7987 if i > 0 {
7988 self.write(",");
7989 self.write_newline();
7990 }
7991 self.write_indent();
7992 self.write(key);
7993 self.write("=");
7994 self.write(value);
7995 }
7996 self.indent_level -= 1;
7997 self.write_newline();
7998 self.write(")");
7999 } else {
8000 self.write_space();
8001 self.write_keyword("WITH");
8002 self.write(" (");
8003 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8004 if i > 0 {
8005 self.write(", ");
8006 }
8007 self.write(key);
8008 self.write("=");
8009 self.write(value);
8010 }
8011 self.write(")");
8012 }
8013 }
8014
8015 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
8016 if is_clickhouse && ct.as_select.is_some() {
8017 let mut pre = Vec::new();
8018 let mut post = Vec::new();
8019 for prop in &ct.properties {
8020 if matches!(prop, Expression::SchemaCommentProperty(_)) {
8021 post.push(prop);
8022 } else {
8023 pre.push(prop);
8024 }
8025 }
8026 (pre, post)
8027 } else {
8028 (ct.properties.iter().collect(), Vec::new())
8029 };
8030
8031 for prop in pre_as_properties {
8033 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
8035 continue;
8036 }
8037 if self.config.pretty {
8038 self.write_newline();
8039 } else {
8040 self.write_space();
8041 }
8042 if let Expression::Properties(props) = prop {
8046 let is_hive_dialect = matches!(
8047 self.config.dialect,
8048 Some(crate::dialects::DialectType::Hive)
8049 | Some(crate::dialects::DialectType::Spark)
8050 | Some(crate::dialects::DialectType::Databricks)
8051 | Some(crate::dialects::DialectType::Athena)
8052 );
8053 let is_doris_starrocks = matches!(
8054 self.config.dialect,
8055 Some(crate::dialects::DialectType::Doris)
8056 | Some(crate::dialects::DialectType::StarRocks)
8057 );
8058 if is_hive_dialect {
8059 self.generate_tblproperties_clause(&props.expressions)?;
8060 } else if is_doris_starrocks {
8061 self.generate_properties_clause(&props.expressions)?;
8062 } else {
8063 self.generate_options_clause(&props.expressions)?;
8064 }
8065 } else {
8066 self.generate_expression(prop)?;
8067 }
8068 }
8069
8070 for prop in &ct.post_table_properties {
8072 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
8073 self.write(" WITH(");
8074 self.generate_system_versioning_content(svp)?;
8075 self.write(")");
8076 } else if let Expression::Properties(props) = prop {
8077 let is_doris_starrocks = matches!(
8079 self.config.dialect,
8080 Some(crate::dialects::DialectType::Doris)
8081 | Some(crate::dialects::DialectType::StarRocks)
8082 );
8083 self.write_space();
8084 if is_doris_starrocks {
8085 self.generate_properties_clause(&props.expressions)?;
8086 } else {
8087 self.generate_options_clause(&props.expressions)?;
8088 }
8089 } else {
8090 self.write_space();
8091 self.generate_expression(prop)?;
8092 }
8093 }
8094
8095 if let Some(ref rollup) = ct.rollup {
8098 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
8099 self.write_space();
8100 self.generate_rollup_property(rollup)?;
8101 }
8102 }
8103
8104 let is_mysql_compatible = matches!(
8108 self.config.dialect,
8109 Some(DialectType::MySQL)
8110 | Some(DialectType::SingleStore)
8111 | Some(DialectType::Doris)
8112 | Some(DialectType::StarRocks)
8113 | None
8114 );
8115 let is_hive_compatible = matches!(
8116 self.config.dialect,
8117 Some(DialectType::Hive)
8118 | Some(DialectType::Spark)
8119 | Some(DialectType::Databricks)
8120 | Some(DialectType::Athena)
8121 );
8122 let mysql_pretty_options =
8123 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
8124 for (key, value) in &ct.mysql_table_options {
8125 let should_output = if is_mysql_compatible {
8127 true
8128 } else if is_hive_compatible && key == "COMMENT" {
8129 true } else {
8131 false
8132 };
8133 if should_output {
8134 if mysql_pretty_options {
8135 self.write_newline();
8136 self.write_indent();
8137 } else {
8138 self.write_space();
8139 }
8140 self.write_keyword(key);
8141 if key == "COMMENT" && !self.config.schema_comment_with_eq {
8143 self.write_space();
8144 } else {
8145 self.write("=");
8146 }
8147 self.write(value);
8148 }
8149 }
8150
8151 if ct.temporary
8153 && matches!(
8154 self.config.dialect,
8155 Some(DialectType::Spark) | Some(DialectType::Databricks)
8156 )
8157 && ct.as_select.is_none()
8158 {
8159 self.write_space();
8160 self.write_keyword("USING PARQUET");
8161 }
8162
8163 if !ct.inherits.is_empty() {
8165 self.write_space();
8166 self.write_keyword("INHERITS");
8167 self.write(" (");
8168 for (i, parent) in ct.inherits.iter().enumerate() {
8169 if i > 0 {
8170 self.write(", ");
8171 }
8172 self.generate_table(parent)?;
8173 }
8174 self.write(")");
8175 }
8176
8177 if let Some(ref query) = ct.as_select {
8179 self.write_space();
8180 self.write_keyword("AS");
8181 self.write_space();
8182 if ct.as_select_parenthesized {
8183 self.write("(");
8184 }
8185 self.generate_expression(query)?;
8186 if ct.as_select_parenthesized {
8187 self.write(")");
8188 }
8189
8190 if let Some(with_data) = ct.with_data {
8192 self.write_space();
8193 self.write_keyword("WITH");
8194 if !with_data {
8195 self.write_space();
8196 self.write_keyword("NO");
8197 }
8198 self.write_space();
8199 self.write_keyword("DATA");
8200 }
8201
8202 if let Some(with_statistics) = ct.with_statistics {
8204 self.write_space();
8205 self.write_keyword("AND");
8206 if !with_statistics {
8207 self.write_space();
8208 self.write_keyword("NO");
8209 }
8210 self.write_space();
8211 self.write_keyword("STATISTICS");
8212 }
8213
8214 for index in &ct.teradata_indexes {
8216 self.write_space();
8217 match index.kind {
8218 TeradataIndexKind::NoPrimary => {
8219 self.write_keyword("NO PRIMARY INDEX");
8220 }
8221 TeradataIndexKind::Primary => {
8222 self.write_keyword("PRIMARY INDEX");
8223 }
8224 TeradataIndexKind::PrimaryAmp => {
8225 self.write_keyword("PRIMARY AMP INDEX");
8226 }
8227 TeradataIndexKind::Unique => {
8228 self.write_keyword("UNIQUE INDEX");
8229 }
8230 TeradataIndexKind::UniquePrimary => {
8231 self.write_keyword("UNIQUE PRIMARY INDEX");
8232 }
8233 TeradataIndexKind::Secondary => {
8234 self.write_keyword("INDEX");
8235 }
8236 }
8237 if let Some(ref name) = index.name {
8239 self.write_space();
8240 self.write(name);
8241 }
8242 if !index.columns.is_empty() {
8244 self.write(" (");
8245 for (i, col) in index.columns.iter().enumerate() {
8246 if i > 0 {
8247 self.write(", ");
8248 }
8249 self.write(col);
8250 }
8251 self.write(")");
8252 }
8253 }
8254
8255 if let Some(ref on_commit) = ct.on_commit {
8257 self.write_space();
8258 self.write_keyword("ON COMMIT");
8259 self.write_space();
8260 match on_commit {
8261 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8262 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8263 }
8264 }
8265
8266 if !post_as_properties.is_empty() {
8267 for prop in post_as_properties {
8268 self.write_space();
8269 self.generate_expression(prop)?;
8270 }
8271 }
8272
8273 self.athena_hive_context = saved_athena_hive_context;
8275 return Ok(());
8276 }
8277
8278 if let Some(ref on_commit) = ct.on_commit {
8280 self.write_space();
8281 self.write_keyword("ON COMMIT");
8282 self.write_space();
8283 match on_commit {
8284 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8285 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8286 }
8287 }
8288
8289 self.athena_hive_context = saved_athena_hive_context;
8291
8292 Ok(())
8293 }
8294
8295 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
8298 self.generate_identifier(&col.name)?;
8300 if !matches!(col.data_type, DataType::Unknown) {
8302 self.write_space();
8303 self.generate_data_type(&col.data_type)?;
8304 }
8305 for constraint in &col.constraints {
8307 if let ColumnConstraint::Path(path_expr) = constraint {
8308 self.write_space();
8309 self.write_keyword("PATH");
8310 self.write_space();
8311 self.generate_expression(path_expr)?;
8312 }
8313 }
8314 Ok(())
8315 }
8316
8317 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
8318 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8320 && col
8321 .constraints
8322 .iter()
8323 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8324 let omit_computed_type = !self.config.computed_column_with_type
8326 && col
8327 .constraints
8328 .iter()
8329 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8330
8331 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
8334
8335 let has_no_type = col.no_type
8338 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8339 && col.constraints.is_empty());
8340
8341 self.generate_identifier(&col.name)?;
8342
8343 let serial_expansion = if matches!(
8345 self.config.dialect,
8346 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
8347 ) {
8348 if let DataType::Custom { ref name } = col.data_type {
8349 if name.eq_ignore_ascii_case("SERIAL") {
8350 Some("INT")
8351 } else if name.eq_ignore_ascii_case("BIGSERIAL") {
8352 Some("BIGINT")
8353 } else if name.eq_ignore_ascii_case("SMALLSERIAL") {
8354 Some("SMALLINT")
8355 } else {
8356 None
8357 }
8358 } else {
8359 None
8360 }
8361 } else {
8362 None
8363 };
8364
8365 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
8366 {
8367 self.write_space();
8368 let saved_nullable_depth = self.clickhouse_nullable_depth;
8371 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
8372 self.clickhouse_nullable_depth = -1;
8373 }
8374 if let Some(int_type) = serial_expansion {
8375 self.write_keyword(int_type);
8377 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8378 let unsigned_type = match &col.data_type {
8380 DataType::Int { .. } => Some("UINTEGER"),
8381 DataType::BigInt { .. } => Some("UBIGINT"),
8382 DataType::SmallInt { .. } => Some("USMALLINT"),
8383 DataType::TinyInt { .. } => Some("UTINYINT"),
8384 _ => None,
8385 };
8386 if let Some(utype) = unsigned_type {
8387 self.write_keyword(utype);
8388 } else {
8389 self.generate_data_type(&col.data_type)?;
8390 }
8391 } else {
8392 self.generate_data_type(&col.data_type)?;
8393 }
8394 self.clickhouse_nullable_depth = saved_nullable_depth;
8395 }
8396
8397 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8400 self.write_space();
8401 self.write_keyword("UNSIGNED");
8402 }
8403 if col.zerofill {
8404 self.write_space();
8405 self.write_keyword("ZEROFILL");
8406 }
8407
8408 if let Some(ref charset) = col.character_set {
8412 self.write_space();
8413 self.write_keyword("CHARACTER SET");
8414 self.write_space();
8415 self.write(charset);
8416 }
8417
8418 if col.uppercase {
8419 self.write_space();
8420 self.write_keyword("UPPERCASE");
8421 }
8422
8423 if let Some(casespecific) = col.casespecific {
8424 self.write_space();
8425 if casespecific {
8426 self.write_keyword("CASESPECIFIC");
8427 } else {
8428 self.write_keyword("NOT CASESPECIFIC");
8429 }
8430 }
8431
8432 if let Some(ref format) = col.format {
8433 self.write_space();
8434 self.write_keyword("FORMAT");
8435 self.write(" '");
8436 self.write(format);
8437 self.write("'");
8438 }
8439
8440 if let Some(ref title) = col.title {
8441 self.write_space();
8442 self.write_keyword("TITLE");
8443 self.write(" '");
8444 self.write(title);
8445 self.write("'");
8446 }
8447
8448 if let Some(length) = col.inline_length {
8449 self.write_space();
8450 self.write_keyword("INLINE LENGTH");
8451 self.write(" ");
8452 self.write(&length.to_string());
8453 }
8454
8455 if let Some(ref compress) = col.compress {
8456 self.write_space();
8457 self.write_keyword("COMPRESS");
8458 if !compress.is_empty() {
8459 if compress.len() == 1 {
8461 if let Expression::Literal(lit) = &compress[0] {
8462 if let Literal::String(_) = lit.as_ref() {
8463 self.write_space();
8464 self.generate_expression(&compress[0])?;
8465 }
8466 } else {
8467 self.write(" (");
8468 self.generate_expression(&compress[0])?;
8469 self.write(")");
8470 }
8471 } else {
8472 self.write(" (");
8473 for (i, val) in compress.iter().enumerate() {
8474 if i > 0 {
8475 self.write(", ");
8476 }
8477 self.generate_expression(val)?;
8478 }
8479 self.write(")");
8480 }
8481 }
8482 }
8483
8484 if !col.constraint_order.is_empty() {
8487 let mut references_idx = 0;
8490 let mut check_idx = 0;
8491 let mut generated_idx = 0;
8492 let mut collate_idx = 0;
8493 let mut comment_idx = 0;
8494 let defer_not_null_after_identity = false;
8497 let mut pending_not_null_after_identity = false;
8498
8499 for constraint_type in &col.constraint_order {
8500 match constraint_type {
8501 ConstraintType::PrimaryKey => {
8502 if col.primary_key
8504 && !matches!(self.config.dialect, Some(DialectType::Materialize))
8505 {
8506 if let Some(ref cname) = col.primary_key_constraint_name {
8507 self.write_space();
8508 self.write_keyword("CONSTRAINT");
8509 self.write_space();
8510 self.write(cname);
8511 }
8512 self.write_space();
8513 self.write_keyword("PRIMARY KEY");
8514 if let Some(ref order) = col.primary_key_order {
8515 self.write_space();
8516 match order {
8517 SortOrder::Asc => self.write_keyword("ASC"),
8518 SortOrder::Desc => self.write_keyword("DESC"),
8519 }
8520 }
8521 }
8522 }
8523 ConstraintType::Unique => {
8524 if col.unique {
8525 if let Some(ref cname) = col.unique_constraint_name {
8526 self.write_space();
8527 self.write_keyword("CONSTRAINT");
8528 self.write_space();
8529 self.write(cname);
8530 }
8531 self.write_space();
8532 self.write_keyword("UNIQUE");
8533 if col.unique_nulls_not_distinct {
8535 self.write(" NULLS NOT DISTINCT");
8536 }
8537 }
8538 }
8539 ConstraintType::NotNull => {
8540 if col.nullable == Some(false) {
8541 if defer_not_null_after_identity {
8542 pending_not_null_after_identity = true;
8543 continue;
8544 }
8545 if let Some(ref cname) = col.not_null_constraint_name {
8546 self.write_space();
8547 self.write_keyword("CONSTRAINT");
8548 self.write_space();
8549 self.write(cname);
8550 }
8551 self.write_space();
8552 self.write_keyword("NOT NULL");
8553 }
8554 }
8555 ConstraintType::Null => {
8556 if col.nullable == Some(true) {
8557 self.write_space();
8558 self.write_keyword("NULL");
8559 }
8560 }
8561 ConstraintType::Default => {
8562 if let Some(ref default) = col.default {
8563 self.write_space();
8564 self.write_keyword("DEFAULT");
8565 self.write_space();
8566 self.generate_expression(default)?;
8567 }
8568 }
8569 ConstraintType::AutoIncrement => {
8570 if col.auto_increment {
8571 if matches!(
8573 self.config.dialect,
8574 Some(crate::dialects::DialectType::DuckDB)
8575 ) {
8576 } else if matches!(
8578 self.config.dialect,
8579 Some(crate::dialects::DialectType::Materialize)
8580 ) {
8581 if !matches!(col.nullable, Some(false)) {
8583 self.write_space();
8584 self.write_keyword("NOT NULL");
8585 }
8586 } else if matches!(
8587 self.config.dialect,
8588 Some(crate::dialects::DialectType::PostgreSQL)
8589 ) {
8590 self.write_space();
8592 self.generate_auto_increment_keyword(col)?;
8593 } else {
8594 self.write_space();
8595 self.generate_auto_increment_keyword(col)?;
8596 if pending_not_null_after_identity {
8597 self.write_space();
8598 self.write_keyword("NOT NULL");
8599 pending_not_null_after_identity = false;
8600 }
8601 }
8602 } }
8604 ConstraintType::References => {
8605 while references_idx < col.constraints.len() {
8607 if let ColumnConstraint::References(fk_ref) =
8608 &col.constraints[references_idx]
8609 {
8610 if let Some(ref name) = fk_ref.constraint_name {
8612 self.write_space();
8613 self.write_keyword("CONSTRAINT");
8614 self.write_space();
8615 self.write(name);
8616 }
8617 self.write_space();
8618 if fk_ref.has_foreign_key_keywords {
8619 self.write_keyword("FOREIGN KEY");
8620 self.write_space();
8621 }
8622 self.write_keyword("REFERENCES");
8623 self.write_space();
8624 self.generate_table(&fk_ref.table)?;
8625 if !fk_ref.columns.is_empty() {
8626 self.write(" (");
8627 for (i, c) in fk_ref.columns.iter().enumerate() {
8628 if i > 0 {
8629 self.write(", ");
8630 }
8631 self.generate_identifier(c)?;
8632 }
8633 self.write(")");
8634 }
8635 self.generate_referential_actions(fk_ref)?;
8636 references_idx += 1;
8637 break;
8638 }
8639 references_idx += 1;
8640 }
8641 }
8642 ConstraintType::Check => {
8643 while check_idx < col.constraints.len() {
8645 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
8646 if check_idx == 0 {
8648 if let Some(ref cname) = col.check_constraint_name {
8649 self.write_space();
8650 self.write_keyword("CONSTRAINT");
8651 self.write_space();
8652 self.write(cname);
8653 }
8654 }
8655 self.write_space();
8656 self.write_keyword("CHECK");
8657 self.write(" (");
8658 self.generate_expression(expr)?;
8659 self.write(")");
8660 check_idx += 1;
8661 break;
8662 }
8663 check_idx += 1;
8664 }
8665 }
8666 ConstraintType::GeneratedAsIdentity => {
8667 while generated_idx < col.constraints.len() {
8669 if let ColumnConstraint::GeneratedAsIdentity(gen) =
8670 &col.constraints[generated_idx]
8671 {
8672 self.write_space();
8673 if matches!(
8675 self.config.dialect,
8676 Some(crate::dialects::DialectType::Redshift)
8677 ) {
8678 self.write_keyword("IDENTITY");
8679 self.write("(");
8680 if let Some(ref start) = gen.start {
8681 self.generate_expression(start)?;
8682 } else {
8683 self.write("0");
8684 }
8685 self.write(", ");
8686 if let Some(ref incr) = gen.increment {
8687 self.generate_expression(incr)?;
8688 } else {
8689 self.write("1");
8690 }
8691 self.write(")");
8692 } else {
8693 self.write_keyword("GENERATED");
8694 if gen.always {
8695 self.write_space();
8696 self.write_keyword("ALWAYS");
8697 } else {
8698 self.write_space();
8699 self.write_keyword("BY DEFAULT");
8700 if gen.on_null {
8701 self.write_space();
8702 self.write_keyword("ON NULL");
8703 }
8704 }
8705 self.write_space();
8706 self.write_keyword("AS IDENTITY");
8707
8708 let has_options = gen.start.is_some()
8709 || gen.increment.is_some()
8710 || gen.minvalue.is_some()
8711 || gen.maxvalue.is_some()
8712 || gen.cycle.is_some();
8713 if has_options {
8714 self.write(" (");
8715 let mut first = true;
8716 if let Some(ref start) = gen.start {
8717 if !first {
8718 self.write(" ");
8719 }
8720 first = false;
8721 self.write_keyword("START WITH");
8722 self.write_space();
8723 self.generate_expression(start)?;
8724 }
8725 if let Some(ref incr) = gen.increment {
8726 if !first {
8727 self.write(" ");
8728 }
8729 first = false;
8730 self.write_keyword("INCREMENT BY");
8731 self.write_space();
8732 self.generate_expression(incr)?;
8733 }
8734 if let Some(ref minv) = gen.minvalue {
8735 if !first {
8736 self.write(" ");
8737 }
8738 first = false;
8739 self.write_keyword("MINVALUE");
8740 self.write_space();
8741 self.generate_expression(minv)?;
8742 }
8743 if let Some(ref maxv) = gen.maxvalue {
8744 if !first {
8745 self.write(" ");
8746 }
8747 first = false;
8748 self.write_keyword("MAXVALUE");
8749 self.write_space();
8750 self.generate_expression(maxv)?;
8751 }
8752 if let Some(cycle) = gen.cycle {
8753 if !first {
8754 self.write(" ");
8755 }
8756 if cycle {
8757 self.write_keyword("CYCLE");
8758 } else {
8759 self.write_keyword("NO CYCLE");
8760 }
8761 }
8762 self.write(")");
8763 }
8764 }
8765 generated_idx += 1;
8766 break;
8767 }
8768 generated_idx += 1;
8769 }
8770 }
8771 ConstraintType::Collate => {
8772 while collate_idx < col.constraints.len() {
8774 if let ColumnConstraint::Collate(collation) =
8775 &col.constraints[collate_idx]
8776 {
8777 self.write_space();
8778 self.write_keyword("COLLATE");
8779 self.write_space();
8780 self.generate_identifier(collation)?;
8781 collate_idx += 1;
8782 break;
8783 }
8784 collate_idx += 1;
8785 }
8786 }
8787 ConstraintType::Comment => {
8788 while comment_idx < col.constraints.len() {
8790 if let ColumnConstraint::Comment(comment) =
8791 &col.constraints[comment_idx]
8792 {
8793 self.write_space();
8794 self.write_keyword("COMMENT");
8795 self.write_space();
8796 self.generate_string_literal(comment)?;
8797 comment_idx += 1;
8798 break;
8799 }
8800 comment_idx += 1;
8801 }
8802 }
8803 ConstraintType::Tags => {
8804 for constraint in &col.constraints {
8806 if let ColumnConstraint::Tags(tags) = constraint {
8807 self.write_space();
8808 self.write_keyword("TAG");
8809 self.write(" (");
8810 for (i, expr) in tags.expressions.iter().enumerate() {
8811 if i > 0 {
8812 self.write(", ");
8813 }
8814 self.generate_expression(expr)?;
8815 }
8816 self.write(")");
8817 break;
8818 }
8819 }
8820 }
8821 ConstraintType::ComputedColumn => {
8822 for constraint in &col.constraints {
8824 if let ColumnConstraint::ComputedColumn(cc) = constraint {
8825 self.write_space();
8826 self.generate_computed_column_inline(cc)?;
8827 break;
8828 }
8829 }
8830 }
8831 ConstraintType::GeneratedAsRow => {
8832 for constraint in &col.constraints {
8834 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
8835 self.write_space();
8836 self.generate_generated_as_row_inline(gar)?;
8837 break;
8838 }
8839 }
8840 }
8841 ConstraintType::OnUpdate => {
8842 if let Some(ref expr) = col.on_update {
8843 self.write_space();
8844 self.write_keyword("ON UPDATE");
8845 self.write_space();
8846 self.generate_expression(expr)?;
8847 }
8848 }
8849 ConstraintType::Encode => {
8850 if let Some(ref encoding) = col.encoding {
8851 self.write_space();
8852 self.write_keyword("ENCODE");
8853 self.write_space();
8854 self.write(encoding);
8855 }
8856 }
8857 ConstraintType::Path => {
8858 for constraint in &col.constraints {
8860 if let ColumnConstraint::Path(path_expr) = constraint {
8861 self.write_space();
8862 self.write_keyword("PATH");
8863 self.write_space();
8864 self.generate_expression(path_expr)?;
8865 break;
8866 }
8867 }
8868 }
8869 }
8870 }
8871 if pending_not_null_after_identity {
8872 self.write_space();
8873 self.write_keyword("NOT NULL");
8874 }
8875 } else {
8876 if col.primary_key {
8878 self.write_space();
8879 self.write_keyword("PRIMARY KEY");
8880 if let Some(ref order) = col.primary_key_order {
8881 self.write_space();
8882 match order {
8883 SortOrder::Asc => self.write_keyword("ASC"),
8884 SortOrder::Desc => self.write_keyword("DESC"),
8885 }
8886 }
8887 }
8888
8889 if col.unique {
8890 self.write_space();
8891 self.write_keyword("UNIQUE");
8892 if col.unique_nulls_not_distinct {
8894 self.write(" NULLS NOT DISTINCT");
8895 }
8896 }
8897
8898 match col.nullable {
8899 Some(false) => {
8900 self.write_space();
8901 self.write_keyword("NOT NULL");
8902 }
8903 Some(true) => {
8904 self.write_space();
8905 self.write_keyword("NULL");
8906 }
8907 None => {}
8908 }
8909
8910 if let Some(ref default) = col.default {
8911 self.write_space();
8912 self.write_keyword("DEFAULT");
8913 self.write_space();
8914 self.generate_expression(default)?;
8915 }
8916
8917 if col.auto_increment {
8918 self.write_space();
8919 self.generate_auto_increment_keyword(col)?;
8920 }
8921
8922 for constraint in &col.constraints {
8924 match constraint {
8925 ColumnConstraint::References(fk_ref) => {
8926 self.write_space();
8927 if fk_ref.has_foreign_key_keywords {
8928 self.write_keyword("FOREIGN KEY");
8929 self.write_space();
8930 }
8931 self.write_keyword("REFERENCES");
8932 self.write_space();
8933 self.generate_table(&fk_ref.table)?;
8934 if !fk_ref.columns.is_empty() {
8935 self.write(" (");
8936 for (i, c) in fk_ref.columns.iter().enumerate() {
8937 if i > 0 {
8938 self.write(", ");
8939 }
8940 self.generate_identifier(c)?;
8941 }
8942 self.write(")");
8943 }
8944 self.generate_referential_actions(fk_ref)?;
8945 }
8946 ColumnConstraint::Check(expr) => {
8947 self.write_space();
8948 self.write_keyword("CHECK");
8949 self.write(" (");
8950 self.generate_expression(expr)?;
8951 self.write(")");
8952 }
8953 ColumnConstraint::GeneratedAsIdentity(gen) => {
8954 self.write_space();
8955 if matches!(
8957 self.config.dialect,
8958 Some(crate::dialects::DialectType::Redshift)
8959 ) {
8960 self.write_keyword("IDENTITY");
8961 self.write("(");
8962 if let Some(ref start) = gen.start {
8963 self.generate_expression(start)?;
8964 } else {
8965 self.write("0");
8966 }
8967 self.write(", ");
8968 if let Some(ref incr) = gen.increment {
8969 self.generate_expression(incr)?;
8970 } else {
8971 self.write("1");
8972 }
8973 self.write(")");
8974 } else {
8975 self.write_keyword("GENERATED");
8976 if gen.always {
8977 self.write_space();
8978 self.write_keyword("ALWAYS");
8979 } else {
8980 self.write_space();
8981 self.write_keyword("BY DEFAULT");
8982 if gen.on_null {
8983 self.write_space();
8984 self.write_keyword("ON NULL");
8985 }
8986 }
8987 self.write_space();
8988 self.write_keyword("AS IDENTITY");
8989
8990 let has_options = gen.start.is_some()
8991 || gen.increment.is_some()
8992 || gen.minvalue.is_some()
8993 || gen.maxvalue.is_some()
8994 || gen.cycle.is_some();
8995 if has_options {
8996 self.write(" (");
8997 let mut first = true;
8998 if let Some(ref start) = gen.start {
8999 if !first {
9000 self.write(" ");
9001 }
9002 first = false;
9003 self.write_keyword("START WITH");
9004 self.write_space();
9005 self.generate_expression(start)?;
9006 }
9007 if let Some(ref incr) = gen.increment {
9008 if !first {
9009 self.write(" ");
9010 }
9011 first = false;
9012 self.write_keyword("INCREMENT BY");
9013 self.write_space();
9014 self.generate_expression(incr)?;
9015 }
9016 if let Some(ref minv) = gen.minvalue {
9017 if !first {
9018 self.write(" ");
9019 }
9020 first = false;
9021 self.write_keyword("MINVALUE");
9022 self.write_space();
9023 self.generate_expression(minv)?;
9024 }
9025 if let Some(ref maxv) = gen.maxvalue {
9026 if !first {
9027 self.write(" ");
9028 }
9029 first = false;
9030 self.write_keyword("MAXVALUE");
9031 self.write_space();
9032 self.generate_expression(maxv)?;
9033 }
9034 if let Some(cycle) = gen.cycle {
9035 if !first {
9036 self.write(" ");
9037 }
9038 if cycle {
9039 self.write_keyword("CYCLE");
9040 } else {
9041 self.write_keyword("NO CYCLE");
9042 }
9043 }
9044 self.write(")");
9045 }
9046 }
9047 }
9048 ColumnConstraint::Collate(collation) => {
9049 self.write_space();
9050 self.write_keyword("COLLATE");
9051 self.write_space();
9052 self.generate_identifier(collation)?;
9053 }
9054 ColumnConstraint::Comment(comment) => {
9055 self.write_space();
9056 self.write_keyword("COMMENT");
9057 self.write_space();
9058 self.generate_string_literal(comment)?;
9059 }
9060 ColumnConstraint::Path(path_expr) => {
9061 self.write_space();
9062 self.write_keyword("PATH");
9063 self.write_space();
9064 self.generate_expression(path_expr)?;
9065 }
9066 _ => {} }
9068 }
9069
9070 if let Some(ref encoding) = col.encoding {
9072 self.write_space();
9073 self.write_keyword("ENCODE");
9074 self.write_space();
9075 self.write(encoding);
9076 }
9077 }
9078
9079 if let Some(ref codec) = col.codec {
9081 self.write_space();
9082 self.write_keyword("CODEC");
9083 self.write("(");
9084 self.write(codec);
9085 self.write(")");
9086 }
9087
9088 if let Some(ref ephemeral) = col.ephemeral {
9090 self.write_space();
9091 self.write_keyword("EPHEMERAL");
9092 if let Some(ref expr) = ephemeral {
9093 self.write_space();
9094 self.generate_expression(expr)?;
9095 }
9096 }
9097
9098 if let Some(ref mat_expr) = col.materialized_expr {
9100 self.write_space();
9101 self.write_keyword("MATERIALIZED");
9102 self.write_space();
9103 self.generate_expression(mat_expr)?;
9104 }
9105
9106 if let Some(ref alias_expr) = col.alias_expr {
9108 self.write_space();
9109 self.write_keyword("ALIAS");
9110 self.write_space();
9111 self.generate_expression(alias_expr)?;
9112 }
9113
9114 if let Some(ref ttl_expr) = col.ttl_expr {
9116 self.write_space();
9117 self.write_keyword("TTL");
9118 self.write_space();
9119 self.generate_expression(ttl_expr)?;
9120 }
9121
9122 if col.not_for_replication
9124 && matches!(
9125 self.config.dialect,
9126 Some(crate::dialects::DialectType::TSQL)
9127 | Some(crate::dialects::DialectType::Fabric)
9128 )
9129 {
9130 self.write_space();
9131 self.write_keyword("NOT FOR REPLICATION");
9132 }
9133
9134 if !col.options.is_empty() {
9136 self.write_space();
9137 self.generate_options_clause(&col.options)?;
9138 }
9139
9140 if !col.primary_key
9143 && self
9144 .sqlite_inline_pk_columns
9145 .contains(&col.name.name.to_ascii_lowercase())
9146 {
9147 self.write_space();
9148 self.write_keyword("PRIMARY KEY");
9149 }
9150
9151 if serial_expansion.is_some() {
9154 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
9155 self.write_space();
9156 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
9157 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
9158 self.write_space();
9159 self.write_keyword("NOT NULL");
9160 }
9161 }
9162
9163 Ok(())
9164 }
9165
9166 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
9167 match constraint {
9168 TableConstraint::PrimaryKey {
9169 name,
9170 columns,
9171 include_columns,
9172 modifiers,
9173 has_constraint_keyword,
9174 } => {
9175 if let Some(ref n) = name {
9176 if *has_constraint_keyword {
9177 self.write_keyword("CONSTRAINT");
9178 self.write_space();
9179 self.generate_identifier(n)?;
9180 self.write_space();
9181 }
9182 }
9183 self.write_keyword("PRIMARY KEY");
9184 if let Some(ref clustered) = modifiers.clustered {
9186 self.write_space();
9187 self.write_keyword(clustered);
9188 }
9189 if let Some(ref n) = name {
9191 if !*has_constraint_keyword {
9192 self.write_space();
9193 self.generate_identifier(n)?;
9194 }
9195 }
9196 self.write(" (");
9197 for (i, col) in columns.iter().enumerate() {
9198 if i > 0 {
9199 self.write(", ");
9200 }
9201 self.generate_identifier(col)?;
9202 }
9203 self.write(")");
9204 if !include_columns.is_empty() {
9205 self.write_space();
9206 self.write_keyword("INCLUDE");
9207 self.write(" (");
9208 for (i, col) in include_columns.iter().enumerate() {
9209 if i > 0 {
9210 self.write(", ");
9211 }
9212 self.generate_identifier(col)?;
9213 }
9214 self.write(")");
9215 }
9216 self.generate_constraint_modifiers(modifiers);
9217 }
9218 TableConstraint::Unique {
9219 name,
9220 columns,
9221 columns_parenthesized,
9222 modifiers,
9223 has_constraint_keyword,
9224 nulls_not_distinct,
9225 } => {
9226 if let Some(ref n) = name {
9227 if *has_constraint_keyword {
9228 self.write_keyword("CONSTRAINT");
9229 self.write_space();
9230 self.generate_identifier(n)?;
9231 self.write_space();
9232 }
9233 }
9234 self.write_keyword("UNIQUE");
9235 if let Some(ref clustered) = modifiers.clustered {
9237 self.write_space();
9238 self.write_keyword(clustered);
9239 }
9240 if *nulls_not_distinct {
9242 self.write(" NULLS NOT DISTINCT");
9243 }
9244 if let Some(ref n) = name {
9246 if !*has_constraint_keyword {
9247 self.write_space();
9248 self.generate_identifier(n)?;
9249 }
9250 }
9251 if *columns_parenthesized {
9252 self.write(" (");
9253 for (i, col) in columns.iter().enumerate() {
9254 if i > 0 {
9255 self.write(", ");
9256 }
9257 self.generate_identifier(col)?;
9258 }
9259 self.write(")");
9260 } else {
9261 for col in columns.iter() {
9263 self.write_space();
9264 self.generate_identifier(col)?;
9265 }
9266 }
9267 self.generate_constraint_modifiers(modifiers);
9268 }
9269 TableConstraint::ForeignKey {
9270 name,
9271 columns,
9272 references,
9273 on_delete,
9274 on_update,
9275 modifiers,
9276 } => {
9277 if let Some(ref n) = name {
9278 self.write_keyword("CONSTRAINT");
9279 self.write_space();
9280 self.generate_identifier(n)?;
9281 self.write_space();
9282 }
9283 self.write_keyword("FOREIGN KEY");
9284 self.write(" (");
9285 for (i, col) in columns.iter().enumerate() {
9286 if i > 0 {
9287 self.write(", ");
9288 }
9289 self.generate_identifier(col)?;
9290 }
9291 self.write(")");
9292 if let Some(ref refs) = references {
9293 self.write(" ");
9294 self.write_keyword("REFERENCES");
9295 self.write_space();
9296 self.generate_table(&refs.table)?;
9297 if !refs.columns.is_empty() {
9298 if self.config.pretty {
9299 self.write(" (");
9300 self.write_newline();
9301 self.indent_level += 1;
9302 for (i, col) in refs.columns.iter().enumerate() {
9303 if i > 0 {
9304 self.write(",");
9305 self.write_newline();
9306 }
9307 self.write_indent();
9308 self.generate_identifier(col)?;
9309 }
9310 self.indent_level -= 1;
9311 self.write_newline();
9312 self.write_indent();
9313 self.write(")");
9314 } else {
9315 self.write(" (");
9316 for (i, col) in refs.columns.iter().enumerate() {
9317 if i > 0 {
9318 self.write(", ");
9319 }
9320 self.generate_identifier(col)?;
9321 }
9322 self.write(")");
9323 }
9324 }
9325 self.generate_referential_actions(refs)?;
9326 } else {
9327 if let Some(ref action) = on_delete {
9329 self.write_space();
9330 self.write_keyword("ON DELETE");
9331 self.write_space();
9332 self.generate_referential_action(action);
9333 }
9334 if let Some(ref action) = on_update {
9335 self.write_space();
9336 self.write_keyword("ON UPDATE");
9337 self.write_space();
9338 self.generate_referential_action(action);
9339 }
9340 }
9341 self.generate_constraint_modifiers(modifiers);
9342 }
9343 TableConstraint::Check {
9344 name,
9345 expression,
9346 modifiers,
9347 } => {
9348 if let Some(ref n) = name {
9349 self.write_keyword("CONSTRAINT");
9350 self.write_space();
9351 self.generate_identifier(n)?;
9352 self.write_space();
9353 }
9354 self.write_keyword("CHECK");
9355 self.write(" (");
9356 self.generate_expression(expression)?;
9357 self.write(")");
9358 self.generate_constraint_modifiers(modifiers);
9359 }
9360 TableConstraint::Assume { name, expression } => {
9361 if let Some(ref n) = name {
9362 self.write_keyword("CONSTRAINT");
9363 self.write_space();
9364 self.generate_identifier(n)?;
9365 self.write_space();
9366 }
9367 self.write_keyword("ASSUME");
9368 self.write(" (");
9369 self.generate_expression(expression)?;
9370 self.write(")");
9371 }
9372 TableConstraint::Default {
9373 name,
9374 expression,
9375 column,
9376 } => {
9377 if let Some(ref n) = name {
9378 self.write_keyword("CONSTRAINT");
9379 self.write_space();
9380 self.generate_identifier(n)?;
9381 self.write_space();
9382 }
9383 self.write_keyword("DEFAULT");
9384 self.write_space();
9385 self.generate_expression(expression)?;
9386 self.write_space();
9387 self.write_keyword("FOR");
9388 self.write_space();
9389 self.generate_identifier(column)?;
9390 }
9391 TableConstraint::Index {
9392 name,
9393 columns,
9394 kind,
9395 modifiers,
9396 use_key_keyword,
9397 expression,
9398 index_type,
9399 granularity,
9400 } => {
9401 if expression.is_some() {
9403 self.write_keyword("INDEX");
9404 if let Some(ref n) = name {
9405 self.write_space();
9406 self.generate_identifier(n)?;
9407 }
9408 if let Some(ref expr) = expression {
9409 self.write_space();
9410 self.generate_expression(expr)?;
9411 }
9412 if let Some(ref idx_type) = index_type {
9413 self.write_space();
9414 self.write_keyword("TYPE");
9415 self.write_space();
9416 self.generate_expression(idx_type)?;
9417 }
9418 if let Some(ref gran) = granularity {
9419 self.write_space();
9420 self.write_keyword("GRANULARITY");
9421 self.write_space();
9422 self.generate_expression(gran)?;
9423 }
9424 } else {
9425 use crate::dialects::DialectType;
9429 let index_keyword = if *use_key_keyword
9430 && !matches!(self.config.dialect, Some(DialectType::MySQL))
9431 {
9432 "KEY"
9433 } else {
9434 "INDEX"
9435 };
9436
9437 if let Some(ref k) = kind {
9439 self.write_keyword(k);
9440 if k != "UNIQUE" {
9442 self.write_space();
9443 self.write_keyword(index_keyword);
9444 }
9445 } else {
9446 self.write_keyword(index_keyword);
9447 }
9448
9449 if modifiers.using_before_columns && name.is_none() {
9451 if let Some(ref using) = modifiers.using {
9452 self.write_space();
9453 self.write_keyword("USING");
9454 self.write_space();
9455 self.write_keyword(using);
9456 }
9457 }
9458
9459 if let Some(ref n) = name {
9461 self.write_space();
9462 self.generate_identifier(n)?;
9463 }
9464
9465 if modifiers.using_before_columns && name.is_some() {
9467 if let Some(ref using) = modifiers.using {
9468 self.write_space();
9469 self.write_keyword("USING");
9470 self.write_space();
9471 self.write_keyword(using);
9472 }
9473 }
9474
9475 self.write(" (");
9477 for (i, col) in columns.iter().enumerate() {
9478 if i > 0 {
9479 self.write(", ");
9480 }
9481 self.generate_identifier(col)?;
9482 }
9483 self.write(")");
9484
9485 if !modifiers.using_before_columns {
9487 if let Some(ref using) = modifiers.using {
9488 self.write_space();
9489 self.write_keyword("USING");
9490 self.write_space();
9491 self.write_keyword(using);
9492 }
9493 }
9494
9495 self.generate_constraint_modifiers_without_using(modifiers);
9497 }
9498 }
9499 TableConstraint::Projection { name, expression } => {
9500 self.write_keyword("PROJECTION");
9502 self.write_space();
9503 self.generate_identifier(name)?;
9504 self.write(" (");
9505 self.generate_expression(expression)?;
9506 self.write(")");
9507 }
9508 TableConstraint::Like { source, options } => {
9509 self.write_keyword("LIKE");
9510 self.write_space();
9511 self.generate_table(source)?;
9512 for (action, prop) in options {
9513 self.write_space();
9514 match action {
9515 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
9516 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
9517 }
9518 self.write_space();
9519 self.write_keyword(prop);
9520 }
9521 }
9522 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
9523 self.write_keyword("PERIOD FOR SYSTEM_TIME");
9524 self.write(" (");
9525 self.generate_identifier(start_col)?;
9526 self.write(", ");
9527 self.generate_identifier(end_col)?;
9528 self.write(")");
9529 }
9530 TableConstraint::Exclude {
9531 name,
9532 using,
9533 elements,
9534 include_columns,
9535 where_clause,
9536 with_params,
9537 using_index_tablespace,
9538 modifiers: _,
9539 } => {
9540 if let Some(ref n) = name {
9541 self.write_keyword("CONSTRAINT");
9542 self.write_space();
9543 self.generate_identifier(n)?;
9544 self.write_space();
9545 }
9546 self.write_keyword("EXCLUDE");
9547 if let Some(ref method) = using {
9548 self.write_space();
9549 self.write_keyword("USING");
9550 self.write_space();
9551 self.write(method);
9552 self.write("(");
9553 } else {
9554 self.write(" (");
9555 }
9556 for (i, elem) in elements.iter().enumerate() {
9557 if i > 0 {
9558 self.write(", ");
9559 }
9560 self.write(&elem.expression);
9561 self.write_space();
9562 self.write_keyword("WITH");
9563 self.write_space();
9564 self.write(&elem.operator);
9565 }
9566 self.write(")");
9567 if !include_columns.is_empty() {
9568 self.write_space();
9569 self.write_keyword("INCLUDE");
9570 self.write(" (");
9571 for (i, col) in include_columns.iter().enumerate() {
9572 if i > 0 {
9573 self.write(", ");
9574 }
9575 self.generate_identifier(col)?;
9576 }
9577 self.write(")");
9578 }
9579 if !with_params.is_empty() {
9580 self.write_space();
9581 self.write_keyword("WITH");
9582 self.write(" (");
9583 for (i, (key, val)) in with_params.iter().enumerate() {
9584 if i > 0 {
9585 self.write(", ");
9586 }
9587 self.write(key);
9588 self.write("=");
9589 self.write(val);
9590 }
9591 self.write(")");
9592 }
9593 if let Some(ref tablespace) = using_index_tablespace {
9594 self.write_space();
9595 self.write_keyword("USING INDEX TABLESPACE");
9596 self.write_space();
9597 self.write(tablespace);
9598 }
9599 if let Some(ref where_expr) = where_clause {
9600 self.write_space();
9601 self.write_keyword("WHERE");
9602 self.write(" (");
9603 self.generate_expression(where_expr)?;
9604 self.write(")");
9605 }
9606 }
9607 TableConstraint::Tags(tags) => {
9608 self.write_keyword("TAG");
9609 self.write(" (");
9610 for (i, expr) in tags.expressions.iter().enumerate() {
9611 if i > 0 {
9612 self.write(", ");
9613 }
9614 self.generate_expression(expr)?;
9615 }
9616 self.write(")");
9617 }
9618 TableConstraint::InitiallyDeferred { deferred } => {
9619 self.write_keyword("INITIALLY");
9620 self.write_space();
9621 if *deferred {
9622 self.write_keyword("DEFERRED");
9623 } else {
9624 self.write_keyword("IMMEDIATE");
9625 }
9626 }
9627 }
9628 Ok(())
9629 }
9630
9631 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9632 if let Some(using) = &modifiers.using {
9634 self.write_space();
9635 self.write_keyword("USING");
9636 self.write_space();
9637 self.write_keyword(using);
9638 }
9639 if let Some(enforced) = modifiers.enforced {
9641 self.write_space();
9642 if enforced {
9643 self.write_keyword("ENFORCED");
9644 } else {
9645 self.write_keyword("NOT ENFORCED");
9646 }
9647 }
9648 if let Some(deferrable) = modifiers.deferrable {
9650 self.write_space();
9651 if deferrable {
9652 self.write_keyword("DEFERRABLE");
9653 } else {
9654 self.write_keyword("NOT DEFERRABLE");
9655 }
9656 }
9657 if let Some(initially_deferred) = modifiers.initially_deferred {
9659 self.write_space();
9660 if initially_deferred {
9661 self.write_keyword("INITIALLY DEFERRED");
9662 } else {
9663 self.write_keyword("INITIALLY IMMEDIATE");
9664 }
9665 }
9666 if modifiers.norely {
9668 self.write_space();
9669 self.write_keyword("NORELY");
9670 }
9671 if modifiers.rely {
9673 self.write_space();
9674 self.write_keyword("RELY");
9675 }
9676 if modifiers.not_valid {
9678 self.write_space();
9679 self.write_keyword("NOT VALID");
9680 }
9681 if let Some(on_conflict) = &modifiers.on_conflict {
9683 self.write_space();
9684 self.write_keyword("ON CONFLICT");
9685 self.write_space();
9686 self.write_keyword(on_conflict);
9687 }
9688 if !modifiers.with_options.is_empty() {
9690 self.write_space();
9691 self.write_keyword("WITH");
9692 self.write(" (");
9693 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
9694 if i > 0 {
9695 self.write(", ");
9696 }
9697 self.write(key);
9698 self.write("=");
9699 self.write(value);
9700 }
9701 self.write(")");
9702 }
9703 if let Some(ref fg) = modifiers.on_filegroup {
9705 self.write_space();
9706 self.write_keyword("ON");
9707 self.write_space();
9708 let _ = self.generate_identifier(fg);
9709 }
9710 }
9711
9712 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
9714 if let Some(enforced) = modifiers.enforced {
9716 self.write_space();
9717 if enforced {
9718 self.write_keyword("ENFORCED");
9719 } else {
9720 self.write_keyword("NOT ENFORCED");
9721 }
9722 }
9723 if let Some(deferrable) = modifiers.deferrable {
9725 self.write_space();
9726 if deferrable {
9727 self.write_keyword("DEFERRABLE");
9728 } else {
9729 self.write_keyword("NOT DEFERRABLE");
9730 }
9731 }
9732 if let Some(initially_deferred) = modifiers.initially_deferred {
9734 self.write_space();
9735 if initially_deferred {
9736 self.write_keyword("INITIALLY DEFERRED");
9737 } else {
9738 self.write_keyword("INITIALLY IMMEDIATE");
9739 }
9740 }
9741 if modifiers.norely {
9743 self.write_space();
9744 self.write_keyword("NORELY");
9745 }
9746 if modifiers.rely {
9748 self.write_space();
9749 self.write_keyword("RELY");
9750 }
9751 if modifiers.not_valid {
9753 self.write_space();
9754 self.write_keyword("NOT VALID");
9755 }
9756 if let Some(on_conflict) = &modifiers.on_conflict {
9758 self.write_space();
9759 self.write_keyword("ON CONFLICT");
9760 self.write_space();
9761 self.write_keyword(on_conflict);
9762 }
9763 self.generate_index_specific_modifiers(modifiers);
9765 }
9766
9767 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9769 if let Some(ref comment) = modifiers.comment {
9770 self.write_space();
9771 self.write_keyword("COMMENT");
9772 self.write(" '");
9773 self.write(comment);
9774 self.write("'");
9775 }
9776 if let Some(visible) = modifiers.visible {
9777 self.write_space();
9778 if visible {
9779 self.write_keyword("VISIBLE");
9780 } else {
9781 self.write_keyword("INVISIBLE");
9782 }
9783 }
9784 if let Some(ref attr) = modifiers.engine_attribute {
9785 self.write_space();
9786 self.write_keyword("ENGINE_ATTRIBUTE");
9787 self.write(" = '");
9788 self.write(attr);
9789 self.write("'");
9790 }
9791 if let Some(ref parser) = modifiers.with_parser {
9792 self.write_space();
9793 self.write_keyword("WITH PARSER");
9794 self.write_space();
9795 self.write(parser);
9796 }
9797 }
9798
9799 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
9800 if !fk_ref.match_after_actions {
9802 if let Some(ref match_type) = fk_ref.match_type {
9803 self.write_space();
9804 self.write_keyword("MATCH");
9805 self.write_space();
9806 match match_type {
9807 MatchType::Full => self.write_keyword("FULL"),
9808 MatchType::Partial => self.write_keyword("PARTIAL"),
9809 MatchType::Simple => self.write_keyword("SIMPLE"),
9810 }
9811 }
9812 }
9813
9814 if fk_ref.on_update_first {
9816 if let Some(ref action) = fk_ref.on_update {
9817 self.write_space();
9818 self.write_keyword("ON UPDATE");
9819 self.write_space();
9820 self.generate_referential_action(action);
9821 }
9822 if let Some(ref action) = fk_ref.on_delete {
9823 self.write_space();
9824 self.write_keyword("ON DELETE");
9825 self.write_space();
9826 self.generate_referential_action(action);
9827 }
9828 } else {
9829 if let Some(ref action) = fk_ref.on_delete {
9830 self.write_space();
9831 self.write_keyword("ON DELETE");
9832 self.write_space();
9833 self.generate_referential_action(action);
9834 }
9835 if let Some(ref action) = fk_ref.on_update {
9836 self.write_space();
9837 self.write_keyword("ON UPDATE");
9838 self.write_space();
9839 self.generate_referential_action(action);
9840 }
9841 }
9842
9843 if fk_ref.match_after_actions {
9845 if let Some(ref match_type) = fk_ref.match_type {
9846 self.write_space();
9847 self.write_keyword("MATCH");
9848 self.write_space();
9849 match match_type {
9850 MatchType::Full => self.write_keyword("FULL"),
9851 MatchType::Partial => self.write_keyword("PARTIAL"),
9852 MatchType::Simple => self.write_keyword("SIMPLE"),
9853 }
9854 }
9855 }
9856
9857 if let Some(deferrable) = fk_ref.deferrable {
9859 self.write_space();
9860 if deferrable {
9861 self.write_keyword("DEFERRABLE");
9862 } else {
9863 self.write_keyword("NOT DEFERRABLE");
9864 }
9865 }
9866
9867 Ok(())
9868 }
9869
9870 fn generate_referential_action(&mut self, action: &ReferentialAction) {
9871 match action {
9872 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
9873 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
9874 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
9875 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
9876 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
9877 }
9878 }
9879
9880 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
9881 if let Some(ref object_id_args) = dt.object_id_args {
9883 if matches!(
9884 self.config.dialect,
9885 Some(crate::dialects::DialectType::TSQL)
9886 | Some(crate::dialects::DialectType::Fabric)
9887 ) {
9888 self.write_keyword("IF NOT OBJECT_ID");
9889 self.write("(");
9890 self.write(object_id_args);
9891 self.write(")");
9892 self.write_space();
9893 self.write_keyword("IS NULL BEGIN DROP TABLE");
9894 self.write_space();
9895 for (i, table) in dt.names.iter().enumerate() {
9896 if i > 0 {
9897 self.write(", ");
9898 }
9899 self.generate_table(table)?;
9900 }
9901 self.write("; ");
9902 self.write_keyword("END");
9903 return Ok(());
9904 }
9905 }
9906
9907 let saved_athena_hive_context = self.athena_hive_context;
9909 if matches!(
9910 self.config.dialect,
9911 Some(crate::dialects::DialectType::Athena)
9912 ) {
9913 self.athena_hive_context = true;
9914 }
9915
9916 for comment in &dt.leading_comments {
9918 self.write_formatted_comment(comment);
9919 self.write_space();
9920 }
9921 if dt.iceberg {
9922 self.write_keyword("DROP ICEBERG TABLE");
9923 } else {
9924 self.write_keyword("DROP TABLE");
9925 }
9926
9927 if dt.if_exists {
9928 self.write_space();
9929 self.write_keyword("IF EXISTS");
9930 }
9931
9932 self.write_space();
9933 for (i, table) in dt.names.iter().enumerate() {
9934 if i > 0 {
9935 self.write(", ");
9936 }
9937 self.generate_table(table)?;
9938 }
9939
9940 if dt.cascade_constraints {
9941 self.write_space();
9942 self.write_keyword("CASCADE CONSTRAINTS");
9943 } else if dt.cascade {
9944 self.write_space();
9945 self.write_keyword("CASCADE");
9946 }
9947
9948 if dt.restrict {
9949 self.write_space();
9950 self.write_keyword("RESTRICT");
9951 }
9952
9953 if dt.purge {
9954 self.write_space();
9955 self.write_keyword("PURGE");
9956 }
9957
9958 if dt.sync {
9959 self.write_space();
9960 self.write_keyword("SYNC");
9961 }
9962
9963 self.athena_hive_context = saved_athena_hive_context;
9965
9966 Ok(())
9967 }
9968
9969 fn generate_undrop(&mut self, u: &Undrop) -> Result<()> {
9970 self.write_keyword("UNDROP");
9971 self.write_space();
9972 self.write_keyword(&u.kind);
9973 if u.if_exists {
9974 self.write_space();
9975 self.write_keyword("IF EXISTS");
9976 }
9977 self.write_space();
9978 self.generate_table(&u.name)?;
9979 Ok(())
9980 }
9981
9982 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
9983 let saved_athena_hive_context = self.athena_hive_context;
9985 if matches!(
9986 self.config.dialect,
9987 Some(crate::dialects::DialectType::Athena)
9988 ) {
9989 self.athena_hive_context = true;
9990 }
9991
9992 self.write_keyword("ALTER");
9993 if let Some(ref modifier) = at.table_modifier {
9995 if !matches!(
9996 self.config.dialect,
9997 Some(crate::dialects::DialectType::DuckDB)
9998 ) {
9999 self.write_space();
10000 self.write_keyword(modifier);
10001 }
10002 }
10003 self.write(" ");
10004 self.write_keyword("TABLE");
10005 if at.if_exists {
10006 self.write_space();
10007 self.write_keyword("IF EXISTS");
10008 }
10009 self.write_space();
10010 self.generate_table(&at.name)?;
10011
10012 if let Some(ref on_cluster) = at.on_cluster {
10014 self.write_space();
10015 self.generate_on_cluster(on_cluster)?;
10016 }
10017
10018 if let Some(ref partition) = at.partition {
10020 self.write_space();
10021 self.write_keyword("PARTITION");
10022 self.write("(");
10023 for (i, (key, value)) in partition.iter().enumerate() {
10024 if i > 0 {
10025 self.write(", ");
10026 }
10027 self.generate_identifier(key)?;
10028 self.write(" = ");
10029 self.generate_expression(value)?;
10030 }
10031 self.write(")");
10032 }
10033
10034 if let Some(ref with_check) = at.with_check {
10036 self.write_space();
10037 self.write_keyword(with_check);
10038 }
10039
10040 if self.config.pretty {
10041 self.write_newline();
10043 self.indent_level += 1;
10044 for (i, action) in at.actions.iter().enumerate() {
10045 let is_continuation = i > 0
10047 && matches!(
10048 (&at.actions[i - 1], action),
10049 (
10050 AlterTableAction::AddColumn { .. },
10051 AlterTableAction::AddColumn { .. }
10052 ) | (
10053 AlterTableAction::AddConstraint(_),
10054 AlterTableAction::AddConstraint(_)
10055 )
10056 );
10057 if i > 0 {
10058 self.write(",");
10059 self.write_newline();
10060 }
10061 self.write_indent();
10062 self.generate_alter_action_with_continuation(action, is_continuation)?;
10063 }
10064 self.indent_level -= 1;
10065 } else {
10066 for (i, action) in at.actions.iter().enumerate() {
10067 let is_continuation = i > 0
10069 && matches!(
10070 (&at.actions[i - 1], action),
10071 (
10072 AlterTableAction::AddColumn { .. },
10073 AlterTableAction::AddColumn { .. }
10074 ) | (
10075 AlterTableAction::AddConstraint(_),
10076 AlterTableAction::AddConstraint(_)
10077 )
10078 );
10079 if i > 0 {
10080 self.write(",");
10081 }
10082 self.write_space();
10083 self.generate_alter_action_with_continuation(action, is_continuation)?;
10084 }
10085 }
10086
10087 if let Some(ref algorithm) = at.algorithm {
10089 self.write(", ");
10090 self.write_keyword("ALGORITHM");
10091 self.write("=");
10092 self.write_keyword(algorithm);
10093 }
10094 if let Some(ref lock) = at.lock {
10095 self.write(", ");
10096 self.write_keyword("LOCK");
10097 self.write("=");
10098 self.write_keyword(lock);
10099 }
10100
10101 self.athena_hive_context = saved_athena_hive_context;
10103
10104 Ok(())
10105 }
10106
10107 fn generate_alter_action_with_continuation(
10108 &mut self,
10109 action: &AlterTableAction,
10110 is_continuation: bool,
10111 ) -> Result<()> {
10112 match action {
10113 AlterTableAction::AddColumn {
10114 column,
10115 if_not_exists,
10116 position,
10117 } => {
10118 use crate::dialects::DialectType;
10119 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
10123 let is_tsql_like = matches!(
10124 self.config.dialect,
10125 Some(DialectType::TSQL) | Some(DialectType::Fabric)
10126 );
10127 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
10129
10130 if is_continuation && (is_snowflake || is_tsql_like) {
10131 } else if is_snowflake {
10133 self.write_keyword("ADD");
10134 self.write_space();
10135 } else if is_athena {
10136 self.write_keyword("ADD COLUMNS");
10138 self.write(" (");
10139 } else if self.config.alter_table_include_column_keyword {
10140 self.write_keyword("ADD COLUMN");
10141 self.write_space();
10142 } else {
10143 self.write_keyword("ADD");
10145 self.write_space();
10146 }
10147
10148 if *if_not_exists {
10149 self.write_keyword("IF NOT EXISTS");
10150 self.write_space();
10151 }
10152 self.generate_column_def(column)?;
10153
10154 if is_athena {
10156 self.write(")");
10157 }
10158
10159 if let Some(pos) = position {
10161 self.write_space();
10162 match pos {
10163 ColumnPosition::First => self.write_keyword("FIRST"),
10164 ColumnPosition::After(col_name) => {
10165 self.write_keyword("AFTER");
10166 self.write_space();
10167 self.generate_identifier(col_name)?;
10168 }
10169 }
10170 }
10171 }
10172 AlterTableAction::DropColumn {
10173 name,
10174 if_exists,
10175 cascade,
10176 } => {
10177 self.write_keyword("DROP COLUMN");
10178 if *if_exists {
10179 self.write_space();
10180 self.write_keyword("IF EXISTS");
10181 }
10182 self.write_space();
10183 self.generate_identifier(name)?;
10184 if *cascade {
10185 self.write_space();
10186 self.write_keyword("CASCADE");
10187 }
10188 }
10189 AlterTableAction::DropColumns { names } => {
10190 self.write_keyword("DROP COLUMNS");
10191 self.write(" (");
10192 for (i, name) in names.iter().enumerate() {
10193 if i > 0 {
10194 self.write(", ");
10195 }
10196 self.generate_identifier(name)?;
10197 }
10198 self.write(")");
10199 }
10200 AlterTableAction::RenameColumn {
10201 old_name,
10202 new_name,
10203 if_exists,
10204 } => {
10205 self.write_keyword("RENAME COLUMN");
10206 if *if_exists {
10207 self.write_space();
10208 self.write_keyword("IF EXISTS");
10209 }
10210 self.write_space();
10211 self.generate_identifier(old_name)?;
10212 self.write_space();
10213 self.write_keyword("TO");
10214 self.write_space();
10215 self.generate_identifier(new_name)?;
10216 }
10217 AlterTableAction::AlterColumn {
10218 name,
10219 action,
10220 use_modify_keyword,
10221 } => {
10222 use crate::dialects::DialectType;
10223 let use_modify = *use_modify_keyword
10226 || (matches!(self.config.dialect, Some(DialectType::MySQL))
10227 && matches!(action, AlterColumnAction::SetDataType { .. }));
10228 if use_modify {
10229 self.write_keyword("MODIFY COLUMN");
10230 self.write_space();
10231 self.generate_identifier(name)?;
10232 if let AlterColumnAction::SetDataType {
10234 data_type,
10235 using: _,
10236 collate,
10237 } = action
10238 {
10239 self.write_space();
10240 self.generate_data_type(data_type)?;
10241 if let Some(collate_name) = collate {
10243 self.write_space();
10244 self.write_keyword("COLLATE");
10245 self.write_space();
10246 self.write(&format!("'{}'", collate_name));
10248 }
10249 } else {
10250 self.write_space();
10251 self.generate_alter_column_action(action)?;
10252 }
10253 } else if matches!(self.config.dialect, Some(DialectType::Hive))
10254 && matches!(action, AlterColumnAction::SetDataType { .. })
10255 {
10256 self.write_keyword("CHANGE COLUMN");
10258 self.write_space();
10259 self.generate_identifier(name)?;
10260 self.write_space();
10261 self.generate_identifier(name)?;
10262 if let AlterColumnAction::SetDataType { data_type, .. } = action {
10263 self.write_space();
10264 self.generate_data_type(data_type)?;
10265 }
10266 } else {
10267 self.write_keyword("ALTER COLUMN");
10268 self.write_space();
10269 self.generate_identifier(name)?;
10270 self.write_space();
10271 self.generate_alter_column_action(action)?;
10272 }
10273 }
10274 AlterTableAction::RenameTable(new_name) => {
10275 let mysql_like = matches!(
10277 self.config.dialect,
10278 Some(DialectType::MySQL)
10279 | Some(DialectType::Doris)
10280 | Some(DialectType::StarRocks)
10281 | Some(DialectType::SingleStore)
10282 );
10283 if mysql_like {
10284 self.write_keyword("RENAME");
10285 } else {
10286 self.write_keyword("RENAME TO");
10287 }
10288 self.write_space();
10289 let rename_table_with_db = !matches!(
10291 self.config.dialect,
10292 Some(DialectType::Doris)
10293 | Some(DialectType::DuckDB)
10294 | Some(DialectType::BigQuery)
10295 | Some(DialectType::PostgreSQL)
10296 );
10297 if !rename_table_with_db {
10298 let mut stripped = new_name.clone();
10299 stripped.schema = None;
10300 stripped.catalog = None;
10301 self.generate_table(&stripped)?;
10302 } else {
10303 self.generate_table(new_name)?;
10304 }
10305 }
10306 AlterTableAction::AddConstraint(constraint) => {
10307 if !is_continuation {
10310 self.write_keyword("ADD");
10311 self.write_space();
10312 }
10313 self.generate_table_constraint(constraint)?;
10314 }
10315 AlterTableAction::DropConstraint { name, if_exists } => {
10316 self.write_keyword("DROP CONSTRAINT");
10317 if *if_exists {
10318 self.write_space();
10319 self.write_keyword("IF EXISTS");
10320 }
10321 self.write_space();
10322 self.generate_identifier(name)?;
10323 }
10324 AlterTableAction::DropForeignKey { name } => {
10325 self.write_keyword("DROP FOREIGN KEY");
10326 self.write_space();
10327 self.generate_identifier(name)?;
10328 }
10329 AlterTableAction::DropPartition {
10330 partitions,
10331 if_exists,
10332 } => {
10333 self.write_keyword("DROP");
10334 if *if_exists {
10335 self.write_space();
10336 self.write_keyword("IF EXISTS");
10337 }
10338 for (i, partition) in partitions.iter().enumerate() {
10339 if i > 0 {
10340 self.write(",");
10341 }
10342 self.write_space();
10343 self.write_keyword("PARTITION");
10344 if partition.len() == 1 && partition[0].0.name == "__expr__" {
10346 self.write_space();
10348 self.generate_expression(&partition[0].1)?;
10349 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
10350 self.write_space();
10352 self.write_keyword("ALL");
10353 } else if partition.len() == 1 && partition[0].0.name == "ID" {
10354 self.write_space();
10356 self.write_keyword("ID");
10357 self.write_space();
10358 self.generate_expression(&partition[0].1)?;
10359 } else {
10360 self.write("(");
10362 for (j, (key, value)) in partition.iter().enumerate() {
10363 if j > 0 {
10364 self.write(", ");
10365 }
10366 self.generate_identifier(key)?;
10367 self.write(" = ");
10368 self.generate_expression(value)?;
10369 }
10370 self.write(")");
10371 }
10372 }
10373 }
10374 AlterTableAction::Delete { where_clause } => {
10375 self.write_keyword("DELETE");
10376 self.write_space();
10377 self.write_keyword("WHERE");
10378 self.write_space();
10379 self.generate_expression(where_clause)?;
10380 }
10381 AlterTableAction::SwapWith(target) => {
10382 self.write_keyword("SWAP WITH");
10383 self.write_space();
10384 self.generate_table(target)?;
10385 }
10386 AlterTableAction::SetProperty { properties } => {
10387 use crate::dialects::DialectType;
10388 self.write_keyword("SET");
10389 let is_trino_presto = matches!(
10391 self.config.dialect,
10392 Some(DialectType::Trino) | Some(DialectType::Presto)
10393 );
10394 if is_trino_presto {
10395 self.write_space();
10396 self.write_keyword("PROPERTIES");
10397 }
10398 let eq = if is_trino_presto { " = " } else { "=" };
10399 for (i, (key, value)) in properties.iter().enumerate() {
10400 if i > 0 {
10401 self.write(",");
10402 }
10403 self.write_space();
10404 if key.contains(' ') {
10406 self.generate_string_literal(key)?;
10407 } else {
10408 self.write(key);
10409 }
10410 self.write(eq);
10411 self.generate_expression(value)?;
10412 }
10413 }
10414 AlterTableAction::UnsetProperty { properties } => {
10415 self.write_keyword("UNSET");
10416 for (i, name) in properties.iter().enumerate() {
10417 if i > 0 {
10418 self.write(",");
10419 }
10420 self.write_space();
10421 self.write(name);
10422 }
10423 }
10424 AlterTableAction::ClusterBy { expressions } => {
10425 self.write_keyword("CLUSTER BY");
10426 self.write(" (");
10427 for (i, expr) in expressions.iter().enumerate() {
10428 if i > 0 {
10429 self.write(", ");
10430 }
10431 self.generate_expression(expr)?;
10432 }
10433 self.write(")");
10434 }
10435 AlterTableAction::SetTag { expressions } => {
10436 self.write_keyword("SET TAG");
10437 for (i, (key, value)) in expressions.iter().enumerate() {
10438 if i > 0 {
10439 self.write(",");
10440 }
10441 self.write_space();
10442 self.write(key);
10443 self.write(" = ");
10444 self.generate_expression(value)?;
10445 }
10446 }
10447 AlterTableAction::UnsetTag { names } => {
10448 self.write_keyword("UNSET TAG");
10449 for (i, name) in names.iter().enumerate() {
10450 if i > 0 {
10451 self.write(",");
10452 }
10453 self.write_space();
10454 self.write(name);
10455 }
10456 }
10457 AlterTableAction::SetOptions { expressions } => {
10458 self.write_keyword("SET");
10459 self.write(" (");
10460 for (i, expr) in expressions.iter().enumerate() {
10461 if i > 0 {
10462 self.write(", ");
10463 }
10464 self.generate_expression(expr)?;
10465 }
10466 self.write(")");
10467 }
10468 AlterTableAction::AlterIndex { name, visible } => {
10469 self.write_keyword("ALTER INDEX");
10470 self.write_space();
10471 self.generate_identifier(name)?;
10472 self.write_space();
10473 if *visible {
10474 self.write_keyword("VISIBLE");
10475 } else {
10476 self.write_keyword("INVISIBLE");
10477 }
10478 }
10479 AlterTableAction::SetAttribute { attribute } => {
10480 self.write_keyword("SET");
10481 self.write_space();
10482 self.write_keyword(attribute);
10483 }
10484 AlterTableAction::SetStageFileFormat { options } => {
10485 self.write_keyword("SET");
10486 self.write_space();
10487 self.write_keyword("STAGE_FILE_FORMAT");
10488 self.write(" = (");
10489 if let Some(opts) = options {
10490 self.generate_space_separated_properties(opts)?;
10491 }
10492 self.write(")");
10493 }
10494 AlterTableAction::SetStageCopyOptions { options } => {
10495 self.write_keyword("SET");
10496 self.write_space();
10497 self.write_keyword("STAGE_COPY_OPTIONS");
10498 self.write(" = (");
10499 if let Some(opts) = options {
10500 self.generate_space_separated_properties(opts)?;
10501 }
10502 self.write(")");
10503 }
10504 AlterTableAction::AddColumns { columns, cascade } => {
10505 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
10508 if is_oracle {
10509 self.write_keyword("ADD");
10510 } else {
10511 self.write_keyword("ADD COLUMNS");
10512 }
10513 self.write(" (");
10514 for (i, col) in columns.iter().enumerate() {
10515 if i > 0 {
10516 self.write(", ");
10517 }
10518 self.generate_column_def(col)?;
10519 }
10520 self.write(")");
10521 if *cascade {
10522 self.write_space();
10523 self.write_keyword("CASCADE");
10524 }
10525 }
10526 AlterTableAction::ChangeColumn {
10527 old_name,
10528 new_name,
10529 data_type,
10530 comment,
10531 cascade,
10532 } => {
10533 use crate::dialects::DialectType;
10534 let is_spark = matches!(
10535 self.config.dialect,
10536 Some(DialectType::Spark) | Some(DialectType::Databricks)
10537 );
10538 let is_rename = old_name.name != new_name.name;
10539
10540 if is_spark {
10541 if is_rename {
10542 self.write_keyword("RENAME COLUMN");
10544 self.write_space();
10545 self.generate_identifier(old_name)?;
10546 self.write_space();
10547 self.write_keyword("TO");
10548 self.write_space();
10549 self.generate_identifier(new_name)?;
10550 } else if comment.is_some() {
10551 self.write_keyword("ALTER COLUMN");
10553 self.write_space();
10554 self.generate_identifier(old_name)?;
10555 self.write_space();
10556 self.write_keyword("COMMENT");
10557 self.write_space();
10558 self.write("'");
10559 self.write(comment.as_ref().unwrap());
10560 self.write("'");
10561 } else if data_type.is_some() {
10562 self.write_keyword("ALTER COLUMN");
10564 self.write_space();
10565 self.generate_identifier(old_name)?;
10566 self.write_space();
10567 self.write_keyword("TYPE");
10568 self.write_space();
10569 self.generate_data_type(data_type.as_ref().unwrap())?;
10570 } else {
10571 self.write_keyword("CHANGE COLUMN");
10573 self.write_space();
10574 self.generate_identifier(old_name)?;
10575 self.write_space();
10576 self.generate_identifier(new_name)?;
10577 }
10578 } else {
10579 if data_type.is_some() {
10581 self.write_keyword("CHANGE COLUMN");
10582 } else {
10583 self.write_keyword("CHANGE");
10584 }
10585 self.write_space();
10586 self.generate_identifier(old_name)?;
10587 self.write_space();
10588 self.generate_identifier(new_name)?;
10589 if let Some(ref dt) = data_type {
10590 self.write_space();
10591 self.generate_data_type(dt)?;
10592 }
10593 if let Some(ref c) = comment {
10594 self.write_space();
10595 self.write_keyword("COMMENT");
10596 self.write_space();
10597 self.write("'");
10598 self.write(c);
10599 self.write("'");
10600 }
10601 if *cascade {
10602 self.write_space();
10603 self.write_keyword("CASCADE");
10604 }
10605 }
10606 }
10607 AlterTableAction::AddPartition {
10608 partition,
10609 if_not_exists,
10610 location,
10611 } => {
10612 self.write_keyword("ADD");
10613 self.write_space();
10614 if *if_not_exists {
10615 self.write_keyword("IF NOT EXISTS");
10616 self.write_space();
10617 }
10618 self.generate_expression(partition)?;
10619 if let Some(ref loc) = location {
10620 self.write_space();
10621 self.write_keyword("LOCATION");
10622 self.write_space();
10623 self.generate_expression(loc)?;
10624 }
10625 }
10626 AlterTableAction::AlterSortKey {
10627 this,
10628 expressions,
10629 compound,
10630 } => {
10631 self.write_keyword("ALTER");
10633 if *compound {
10634 self.write_space();
10635 self.write_keyword("COMPOUND");
10636 }
10637 self.write_space();
10638 self.write_keyword("SORTKEY");
10639 self.write_space();
10640 if let Some(style) = this {
10641 self.write_keyword(style);
10642 } else if !expressions.is_empty() {
10643 self.write("(");
10644 for (i, expr) in expressions.iter().enumerate() {
10645 if i > 0 {
10646 self.write(", ");
10647 }
10648 self.generate_expression(expr)?;
10649 }
10650 self.write(")");
10651 }
10652 }
10653 AlterTableAction::AlterDistStyle { style, distkey } => {
10654 self.write_keyword("ALTER");
10656 self.write_space();
10657 self.write_keyword("DISTSTYLE");
10658 self.write_space();
10659 self.write_keyword(style);
10660 if let Some(col) = distkey {
10661 self.write_space();
10662 self.write_keyword("DISTKEY");
10663 self.write_space();
10664 self.generate_identifier(col)?;
10665 }
10666 }
10667 AlterTableAction::SetTableProperties { properties } => {
10668 self.write_keyword("SET TABLE PROPERTIES");
10670 self.write(" (");
10671 for (i, (key, value)) in properties.iter().enumerate() {
10672 if i > 0 {
10673 self.write(", ");
10674 }
10675 self.generate_expression(key)?;
10676 self.write(" = ");
10677 self.generate_expression(value)?;
10678 }
10679 self.write(")");
10680 }
10681 AlterTableAction::SetLocation { location } => {
10682 self.write_keyword("SET LOCATION");
10684 self.write_space();
10685 self.write("'");
10686 self.write(location);
10687 self.write("'");
10688 }
10689 AlterTableAction::SetFileFormat { format } => {
10690 self.write_keyword("SET FILE FORMAT");
10692 self.write_space();
10693 self.write_keyword(format);
10694 }
10695 AlterTableAction::ReplacePartition { partition, source } => {
10696 self.write_keyword("REPLACE PARTITION");
10698 self.write_space();
10699 self.generate_expression(partition)?;
10700 if let Some(src) = source {
10701 self.write_space();
10702 self.write_keyword("FROM");
10703 self.write_space();
10704 self.generate_expression(src)?;
10705 }
10706 }
10707 AlterTableAction::Raw { sql } => {
10708 self.write(sql);
10709 }
10710 }
10711 Ok(())
10712 }
10713
10714 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
10715 match action {
10716 AlterColumnAction::SetDataType {
10717 data_type,
10718 using,
10719 collate,
10720 } => {
10721 use crate::dialects::DialectType;
10722 let is_no_prefix = matches!(
10727 self.config.dialect,
10728 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
10729 );
10730 let is_type_only = matches!(
10731 self.config.dialect,
10732 Some(DialectType::Redshift)
10733 | Some(DialectType::Spark)
10734 | Some(DialectType::Databricks)
10735 );
10736 if is_type_only {
10737 self.write_keyword("TYPE");
10738 self.write_space();
10739 } else if !is_no_prefix {
10740 self.write_keyword("SET DATA TYPE");
10741 self.write_space();
10742 }
10743 self.generate_data_type(data_type)?;
10744 if let Some(ref collation) = collate {
10745 self.write_space();
10746 self.write_keyword("COLLATE");
10747 self.write_space();
10748 self.write(collation);
10749 }
10750 if let Some(ref using_expr) = using {
10751 self.write_space();
10752 self.write_keyword("USING");
10753 self.write_space();
10754 self.generate_expression(using_expr)?;
10755 }
10756 }
10757 AlterColumnAction::SetDefault(expr) => {
10758 self.write_keyword("SET DEFAULT");
10759 self.write_space();
10760 self.generate_expression(expr)?;
10761 }
10762 AlterColumnAction::DropDefault => {
10763 self.write_keyword("DROP DEFAULT");
10764 }
10765 AlterColumnAction::SetNotNull => {
10766 self.write_keyword("SET NOT NULL");
10767 }
10768 AlterColumnAction::DropNotNull => {
10769 self.write_keyword("DROP NOT NULL");
10770 }
10771 AlterColumnAction::Comment(comment) => {
10772 self.write_keyword("COMMENT");
10773 self.write_space();
10774 self.generate_string_literal(comment)?;
10775 }
10776 AlterColumnAction::SetVisible => {
10777 self.write_keyword("SET VISIBLE");
10778 }
10779 AlterColumnAction::SetInvisible => {
10780 self.write_keyword("SET INVISIBLE");
10781 }
10782 }
10783 Ok(())
10784 }
10785
10786 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
10787 self.write_keyword("CREATE");
10788
10789 if ci.unique {
10790 self.write_space();
10791 self.write_keyword("UNIQUE");
10792 }
10793
10794 if let Some(ref clustered) = ci.clustered {
10796 self.write_space();
10797 self.write_keyword(clustered);
10798 }
10799
10800 self.write_space();
10801 self.write_keyword("INDEX");
10802
10803 if ci.concurrently {
10805 self.write_space();
10806 self.write_keyword("CONCURRENTLY");
10807 }
10808
10809 if ci.if_not_exists {
10810 self.write_space();
10811 self.write_keyword("IF NOT EXISTS");
10812 }
10813
10814 if !ci.name.name.is_empty() {
10816 self.write_space();
10817 self.generate_identifier(&ci.name)?;
10818 }
10819 self.write_space();
10820 self.write_keyword("ON");
10821 if matches!(self.config.dialect, Some(DialectType::Hive)) {
10823 self.write_space();
10824 self.write_keyword("TABLE");
10825 }
10826 self.write_space();
10827 self.generate_table(&ci.table)?;
10828
10829 if !ci.columns.is_empty() || ci.using.is_some() {
10832 let space_before_paren = false;
10833
10834 if let Some(ref using) = ci.using {
10835 self.write_space();
10836 self.write_keyword("USING");
10837 self.write_space();
10838 self.write(using);
10839 if space_before_paren {
10840 self.write(" (");
10841 } else {
10842 self.write("(");
10843 }
10844 } else {
10845 if space_before_paren {
10846 self.write(" (");
10847 } else {
10848 self.write("(");
10849 }
10850 }
10851 for (i, col) in ci.columns.iter().enumerate() {
10852 if i > 0 {
10853 self.write(", ");
10854 }
10855 self.generate_identifier(&col.column)?;
10856 if let Some(ref opclass) = col.opclass {
10857 self.write_space();
10858 self.write(opclass);
10859 }
10860 if col.desc {
10861 self.write_space();
10862 self.write_keyword("DESC");
10863 } else if col.asc {
10864 self.write_space();
10865 self.write_keyword("ASC");
10866 }
10867 if let Some(nulls_first) = col.nulls_first {
10868 self.write_space();
10869 self.write_keyword("NULLS");
10870 self.write_space();
10871 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
10872 }
10873 }
10874 self.write(")");
10875 }
10876
10877 if !ci.include_columns.is_empty() {
10879 self.write_space();
10880 self.write_keyword("INCLUDE");
10881 self.write(" (");
10882 for (i, col) in ci.include_columns.iter().enumerate() {
10883 if i > 0 {
10884 self.write(", ");
10885 }
10886 self.generate_identifier(col)?;
10887 }
10888 self.write(")");
10889 }
10890
10891 if !ci.with_options.is_empty() {
10893 self.write_space();
10894 self.write_keyword("WITH");
10895 self.write(" (");
10896 for (i, (key, value)) in ci.with_options.iter().enumerate() {
10897 if i > 0 {
10898 self.write(", ");
10899 }
10900 self.write(key);
10901 self.write("=");
10902 self.write(value);
10903 }
10904 self.write(")");
10905 }
10906
10907 if let Some(ref where_clause) = ci.where_clause {
10909 self.write_space();
10910 self.write_keyword("WHERE");
10911 self.write_space();
10912 self.generate_expression(where_clause)?;
10913 }
10914
10915 if let Some(ref on_fg) = ci.on_filegroup {
10917 self.write_space();
10918 self.write_keyword("ON");
10919 self.write_space();
10920 self.write(on_fg);
10921 }
10922
10923 Ok(())
10924 }
10925
10926 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
10927 self.write_keyword("DROP INDEX");
10928
10929 if di.concurrently {
10930 self.write_space();
10931 self.write_keyword("CONCURRENTLY");
10932 }
10933
10934 if di.if_exists {
10935 self.write_space();
10936 self.write_keyword("IF EXISTS");
10937 }
10938
10939 self.write_space();
10940 self.generate_identifier(&di.name)?;
10941
10942 if let Some(ref table) = di.table {
10943 self.write_space();
10944 self.write_keyword("ON");
10945 self.write_space();
10946 self.generate_table(table)?;
10947 }
10948
10949 Ok(())
10950 }
10951
10952 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
10953 self.write_keyword("CREATE");
10954
10955 if let Some(ref algorithm) = cv.algorithm {
10957 self.write_space();
10958 self.write_keyword("ALGORITHM");
10959 self.write("=");
10960 self.write_keyword(algorithm);
10961 }
10962
10963 if let Some(ref definer) = cv.definer {
10965 self.write_space();
10966 self.write_keyword("DEFINER");
10967 self.write("=");
10968 self.write(definer);
10969 }
10970
10971 if cv.security_sql_style && !cv.security_after_name {
10973 if let Some(ref security) = cv.security {
10974 self.write_space();
10975 self.write_keyword("SQL SECURITY");
10976 self.write_space();
10977 match security {
10978 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10979 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10980 FunctionSecurity::None => self.write_keyword("NONE"),
10981 }
10982 }
10983 }
10984
10985 if cv.or_alter {
10986 self.write_space();
10987 self.write_keyword("OR ALTER");
10988 } else if cv.or_replace {
10989 self.write_space();
10990 self.write_keyword("OR REPLACE");
10991 }
10992
10993 if cv.temporary {
10994 self.write_space();
10995 self.write_keyword("TEMPORARY");
10996 }
10997
10998 if cv.materialized {
10999 self.write_space();
11000 self.write_keyword("MATERIALIZED");
11001 }
11002
11003 if cv.secure {
11005 self.write_space();
11006 self.write_keyword("SECURE");
11007 }
11008
11009 self.write_space();
11010 self.write_keyword("VIEW");
11011
11012 if cv.if_not_exists {
11013 self.write_space();
11014 self.write_keyword("IF NOT EXISTS");
11015 }
11016
11017 self.write_space();
11018 self.generate_table(&cv.name)?;
11019
11020 if let Some(ref on_cluster) = cv.on_cluster {
11022 self.write_space();
11023 self.generate_on_cluster(on_cluster)?;
11024 }
11025
11026 if let Some(ref to_table) = cv.to_table {
11028 self.write_space();
11029 self.write_keyword("TO");
11030 self.write_space();
11031 self.generate_table(to_table)?;
11032 }
11033
11034 if !cv.materialized {
11037 if !cv.columns.is_empty() {
11039 self.write(" (");
11040 for (i, col) in cv.columns.iter().enumerate() {
11041 if i > 0 {
11042 self.write(", ");
11043 }
11044 self.generate_identifier(&col.name)?;
11045 if !col.options.is_empty() {
11047 self.write_space();
11048 self.generate_options_clause(&col.options)?;
11049 }
11050 if let Some(ref comment) = col.comment {
11051 self.write_space();
11052 self.write_keyword("COMMENT");
11053 self.write_space();
11054 self.generate_string_literal(comment)?;
11055 }
11056 }
11057 self.write(")");
11058 }
11059
11060 if !cv.security_sql_style || cv.security_after_name {
11063 if let Some(ref security) = cv.security {
11064 self.write_space();
11065 if cv.security_sql_style {
11066 self.write_keyword("SQL SECURITY");
11067 } else {
11068 self.write_keyword("SECURITY");
11069 }
11070 self.write_space();
11071 match security {
11072 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11073 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11074 FunctionSecurity::None => self.write_keyword("NONE"),
11075 }
11076 }
11077 }
11078
11079 if cv.copy_grants {
11081 self.write_space();
11082 self.write_keyword("COPY GRANTS");
11083 }
11084 } else {
11085 if cv.copy_grants {
11087 self.write_space();
11088 self.write_keyword("COPY GRANTS");
11089 }
11090
11091 if let Some(ref schema) = cv.schema {
11093 self.write(" (");
11094 for (i, expr) in schema.expressions.iter().enumerate() {
11095 if i > 0 {
11096 self.write(", ");
11097 }
11098 self.generate_expression(expr)?;
11099 }
11100 self.write(")");
11101 } else if !cv.columns.is_empty() {
11102 self.write(" (");
11104 for (i, col) in cv.columns.iter().enumerate() {
11105 if i > 0 {
11106 self.write(", ");
11107 }
11108 self.generate_identifier(&col.name)?;
11109 if !col.options.is_empty() {
11111 self.write_space();
11112 self.generate_options_clause(&col.options)?;
11113 }
11114 if let Some(ref comment) = col.comment {
11115 self.write_space();
11116 self.write_keyword("COMMENT");
11117 self.write_space();
11118 self.generate_string_literal(comment)?;
11119 }
11120 }
11121 self.write(")");
11122 }
11123
11124 if let Some(ref unique_key) = cv.unique_key {
11126 self.write_space();
11127 self.write_keyword("KEY");
11128 self.write(" (");
11129 for (i, expr) in unique_key.expressions.iter().enumerate() {
11130 if i > 0 {
11131 self.write(", ");
11132 }
11133 self.generate_expression(expr)?;
11134 }
11135 self.write(")");
11136 }
11137 }
11138
11139 if let Some(ref comment) = cv.comment {
11141 self.write_space();
11142 self.write_keyword("COMMENT");
11143 self.write("=");
11144 self.generate_string_literal(comment)?;
11145 }
11146
11147 if !cv.tags.is_empty() {
11149 self.write_space();
11150 self.write_keyword("TAG");
11151 self.write(" (");
11152 for (i, (name, value)) in cv.tags.iter().enumerate() {
11153 if i > 0 {
11154 self.write(", ");
11155 }
11156 self.write(name);
11157 self.write("='");
11158 self.write(value);
11159 self.write("'");
11160 }
11161 self.write(")");
11162 }
11163
11164 if !cv.options.is_empty() {
11166 self.write_space();
11167 self.generate_options_clause(&cv.options)?;
11168 }
11169
11170 if let Some(ref build) = cv.build {
11172 self.write_space();
11173 self.write_keyword("BUILD");
11174 self.write_space();
11175 self.write_keyword(build);
11176 }
11177
11178 if let Some(ref refresh) = cv.refresh {
11180 self.write_space();
11181 self.generate_refresh_trigger_property(refresh)?;
11182 }
11183
11184 if let Some(auto_refresh) = cv.auto_refresh {
11186 self.write_space();
11187 self.write_keyword("AUTO REFRESH");
11188 self.write_space();
11189 if auto_refresh {
11190 self.write_keyword("YES");
11191 } else {
11192 self.write_keyword("NO");
11193 }
11194 }
11195
11196 for prop in &cv.table_properties {
11198 self.write_space();
11199 self.generate_expression(prop)?;
11200 }
11201
11202 if !matches!(&cv.query, Expression::Null(_)) {
11204 self.write_space();
11205 self.write_keyword("AS");
11206 self.write_space();
11207
11208 if let Some(ref mode) = cv.locking_mode {
11210 self.write_keyword("LOCKING");
11211 self.write_space();
11212 self.write_keyword(mode);
11213 if let Some(ref access) = cv.locking_access {
11214 self.write_space();
11215 self.write_keyword("FOR");
11216 self.write_space();
11217 self.write_keyword(access);
11218 }
11219 self.write_space();
11220 }
11221
11222 if cv.query_parenthesized {
11223 self.write("(");
11224 }
11225 self.generate_expression(&cv.query)?;
11226 if cv.query_parenthesized {
11227 self.write(")");
11228 }
11229 }
11230
11231 if cv.no_schema_binding {
11233 self.write_space();
11234 self.write_keyword("WITH NO SCHEMA BINDING");
11235 }
11236
11237 Ok(())
11238 }
11239
11240 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
11241 self.write_keyword("DROP");
11242
11243 if dv.materialized {
11244 self.write_space();
11245 self.write_keyword("MATERIALIZED");
11246 }
11247
11248 self.write_space();
11249 self.write_keyword("VIEW");
11250
11251 if dv.if_exists {
11252 self.write_space();
11253 self.write_keyword("IF EXISTS");
11254 }
11255
11256 self.write_space();
11257 self.generate_table(&dv.name)?;
11258
11259 Ok(())
11260 }
11261
11262 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
11263 match tr.target {
11264 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
11265 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
11266 }
11267 if tr.if_exists {
11268 self.write_space();
11269 self.write_keyword("IF EXISTS");
11270 }
11271 self.write_space();
11272 self.generate_table(&tr.table)?;
11273
11274 if let Some(ref on_cluster) = tr.on_cluster {
11276 self.write_space();
11277 self.generate_on_cluster(on_cluster)?;
11278 }
11279
11280 if !tr.extra_tables.is_empty() {
11282 let skip_first = if let Some(first) = tr.extra_tables.first() {
11284 first.table.name == tr.table.name && first.star
11285 } else {
11286 false
11287 };
11288
11289 let strip_star = matches!(
11291 self.config.dialect,
11292 Some(crate::dialects::DialectType::PostgreSQL)
11293 | Some(crate::dialects::DialectType::Redshift)
11294 );
11295 if skip_first && !strip_star {
11296 self.write("*");
11297 }
11298
11299 for (i, entry) in tr.extra_tables.iter().enumerate() {
11301 if i == 0 && skip_first {
11302 continue; }
11304 self.write(", ");
11305 self.generate_table(&entry.table)?;
11306 if entry.star && !strip_star {
11307 self.write("*");
11308 }
11309 }
11310 }
11311
11312 if let Some(identity) = &tr.identity {
11314 self.write_space();
11315 match identity {
11316 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
11317 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
11318 }
11319 }
11320
11321 if tr.cascade {
11322 self.write_space();
11323 self.write_keyword("CASCADE");
11324 }
11325
11326 if tr.restrict {
11327 self.write_space();
11328 self.write_keyword("RESTRICT");
11329 }
11330
11331 if let Some(ref partition) = tr.partition {
11333 self.write_space();
11334 self.generate_expression(partition)?;
11335 }
11336
11337 Ok(())
11338 }
11339
11340 fn generate_use(&mut self, u: &Use) -> Result<()> {
11341 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
11343 self.write_keyword("DATABASE");
11344 self.write_space();
11345 self.generate_identifier(&u.this)?;
11346 return Ok(());
11347 }
11348
11349 self.write_keyword("USE");
11350
11351 if let Some(kind) = &u.kind {
11352 self.write_space();
11353 match kind {
11354 UseKind::Database => self.write_keyword("DATABASE"),
11355 UseKind::Schema => self.write_keyword("SCHEMA"),
11356 UseKind::Role => self.write_keyword("ROLE"),
11357 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
11358 UseKind::Catalog => self.write_keyword("CATALOG"),
11359 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
11360 }
11361 }
11362
11363 self.write_space();
11364 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
11367 self.write(&u.this.name);
11368 } else {
11369 self.generate_identifier(&u.this)?;
11370 }
11371 Ok(())
11372 }
11373
11374 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
11375 self.write_keyword("CACHE");
11376 if c.lazy {
11377 self.write_space();
11378 self.write_keyword("LAZY");
11379 }
11380 self.write_space();
11381 self.write_keyword("TABLE");
11382 self.write_space();
11383 self.generate_identifier(&c.table)?;
11384
11385 if !c.options.is_empty() {
11387 self.write_space();
11388 self.write_keyword("OPTIONS");
11389 self.write("(");
11390 for (i, (key, value)) in c.options.iter().enumerate() {
11391 if i > 0 {
11392 self.write(", ");
11393 }
11394 self.generate_expression(key)?;
11395 self.write(" = ");
11396 self.generate_expression(value)?;
11397 }
11398 self.write(")");
11399 }
11400
11401 if let Some(query) = &c.query {
11403 self.write_space();
11404 self.write_keyword("AS");
11405 self.write_space();
11406 self.generate_expression(query)?;
11407 }
11408
11409 Ok(())
11410 }
11411
11412 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
11413 self.write_keyword("UNCACHE TABLE");
11414 if u.if_exists {
11415 self.write_space();
11416 self.write_keyword("IF EXISTS");
11417 }
11418 self.write_space();
11419 self.generate_identifier(&u.table)?;
11420 Ok(())
11421 }
11422
11423 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
11424 self.write_keyword("LOAD DATA");
11425 if l.local {
11426 self.write_space();
11427 self.write_keyword("LOCAL");
11428 }
11429 self.write_space();
11430 self.write_keyword("INPATH");
11431 self.write_space();
11432 self.write("'");
11433 self.write(&l.inpath);
11434 self.write("'");
11435
11436 if l.overwrite {
11437 self.write_space();
11438 self.write_keyword("OVERWRITE");
11439 }
11440
11441 self.write_space();
11442 self.write_keyword("INTO TABLE");
11443 self.write_space();
11444 self.generate_expression(&l.table)?;
11445
11446 if !l.partition.is_empty() {
11448 self.write_space();
11449 self.write_keyword("PARTITION");
11450 self.write("(");
11451 for (i, (col, val)) in l.partition.iter().enumerate() {
11452 if i > 0 {
11453 self.write(", ");
11454 }
11455 self.generate_identifier(col)?;
11456 self.write(" = ");
11457 self.generate_expression(val)?;
11458 }
11459 self.write(")");
11460 }
11461
11462 if let Some(fmt) = &l.input_format {
11464 self.write_space();
11465 self.write_keyword("INPUTFORMAT");
11466 self.write_space();
11467 self.write("'");
11468 self.write(fmt);
11469 self.write("'");
11470 }
11471
11472 if let Some(serde) = &l.serde {
11474 self.write_space();
11475 self.write_keyword("SERDE");
11476 self.write_space();
11477 self.write("'");
11478 self.write(serde);
11479 self.write("'");
11480 }
11481
11482 Ok(())
11483 }
11484
11485 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
11486 self.write_keyword("PRAGMA");
11487 self.write_space();
11488
11489 if let Some(schema) = &p.schema {
11491 self.generate_identifier(schema)?;
11492 self.write(".");
11493 }
11494
11495 self.generate_identifier(&p.name)?;
11497
11498 if let Some(value) = &p.value {
11500 self.write(" = ");
11501 self.generate_expression(value)?;
11502 } else if !p.args.is_empty() {
11503 self.write("(");
11504 for (i, arg) in p.args.iter().enumerate() {
11505 if i > 0 {
11506 self.write(", ");
11507 }
11508 self.generate_expression(arg)?;
11509 }
11510 self.write(")");
11511 }
11512
11513 Ok(())
11514 }
11515
11516 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
11517 self.write_keyword("GRANT");
11518 self.write_space();
11519
11520 for (i, privilege) in g.privileges.iter().enumerate() {
11522 if i > 0 {
11523 self.write(", ");
11524 }
11525 self.write_keyword(&privilege.name);
11526 if !privilege.columns.is_empty() {
11528 self.write("(");
11529 for (j, col) in privilege.columns.iter().enumerate() {
11530 if j > 0 {
11531 self.write(", ");
11532 }
11533 self.write(col);
11534 }
11535 self.write(")");
11536 }
11537 }
11538
11539 self.write_space();
11540 self.write_keyword("ON");
11541 self.write_space();
11542
11543 if let Some(kind) = &g.kind {
11545 self.write_keyword(kind);
11546 self.write_space();
11547 }
11548
11549 {
11551 use crate::dialects::DialectType;
11552 let should_upper = matches!(
11553 self.config.dialect,
11554 Some(DialectType::PostgreSQL)
11555 | Some(DialectType::CockroachDB)
11556 | Some(DialectType::Materialize)
11557 | Some(DialectType::RisingWave)
11558 ) && (g.kind.as_deref() == Some("FUNCTION")
11559 || g.kind.as_deref() == Some("PROCEDURE"));
11560 if should_upper {
11561 use crate::expressions::Identifier;
11562 let upper_id = Identifier {
11563 name: g.securable.name.to_ascii_uppercase(),
11564 quoted: g.securable.quoted,
11565 ..g.securable.clone()
11566 };
11567 self.generate_identifier(&upper_id)?;
11568 } else {
11569 self.generate_identifier(&g.securable)?;
11570 }
11571 }
11572
11573 if !g.function_params.is_empty() {
11575 self.write("(");
11576 for (i, param) in g.function_params.iter().enumerate() {
11577 if i > 0 {
11578 self.write(", ");
11579 }
11580 self.write(param);
11581 }
11582 self.write(")");
11583 }
11584
11585 self.write_space();
11586 self.write_keyword("TO");
11587 self.write_space();
11588
11589 for (i, principal) in g.principals.iter().enumerate() {
11591 if i > 0 {
11592 self.write(", ");
11593 }
11594 if principal.is_role {
11595 self.write_keyword("ROLE");
11596 self.write_space();
11597 } else if principal.is_group {
11598 self.write_keyword("GROUP");
11599 self.write_space();
11600 } else if principal.is_share {
11601 self.write_keyword("SHARE");
11602 self.write_space();
11603 }
11604 self.generate_identifier(&principal.name)?;
11605 }
11606
11607 if g.grant_option {
11609 self.write_space();
11610 self.write_keyword("WITH GRANT OPTION");
11611 }
11612
11613 if let Some(ref principal) = g.as_principal {
11615 self.write_space();
11616 self.write_keyword("AS");
11617 self.write_space();
11618 self.generate_identifier(principal)?;
11619 }
11620
11621 Ok(())
11622 }
11623
11624 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
11625 self.write_keyword("REVOKE");
11626 self.write_space();
11627
11628 if r.grant_option {
11630 self.write_keyword("GRANT OPTION FOR");
11631 self.write_space();
11632 }
11633
11634 for (i, privilege) in r.privileges.iter().enumerate() {
11636 if i > 0 {
11637 self.write(", ");
11638 }
11639 self.write_keyword(&privilege.name);
11640 if !privilege.columns.is_empty() {
11642 self.write("(");
11643 for (j, col) in privilege.columns.iter().enumerate() {
11644 if j > 0 {
11645 self.write(", ");
11646 }
11647 self.write(col);
11648 }
11649 self.write(")");
11650 }
11651 }
11652
11653 self.write_space();
11654 self.write_keyword("ON");
11655 self.write_space();
11656
11657 if let Some(kind) = &r.kind {
11659 self.write_keyword(kind);
11660 self.write_space();
11661 }
11662
11663 {
11665 use crate::dialects::DialectType;
11666 let should_upper = matches!(
11667 self.config.dialect,
11668 Some(DialectType::PostgreSQL)
11669 | Some(DialectType::CockroachDB)
11670 | Some(DialectType::Materialize)
11671 | Some(DialectType::RisingWave)
11672 ) && (r.kind.as_deref() == Some("FUNCTION")
11673 || r.kind.as_deref() == Some("PROCEDURE"));
11674 if should_upper {
11675 use crate::expressions::Identifier;
11676 let upper_id = Identifier {
11677 name: r.securable.name.to_ascii_uppercase(),
11678 quoted: r.securable.quoted,
11679 ..r.securable.clone()
11680 };
11681 self.generate_identifier(&upper_id)?;
11682 } else {
11683 self.generate_identifier(&r.securable)?;
11684 }
11685 }
11686
11687 if !r.function_params.is_empty() {
11689 self.write("(");
11690 for (i, param) in r.function_params.iter().enumerate() {
11691 if i > 0 {
11692 self.write(", ");
11693 }
11694 self.write(param);
11695 }
11696 self.write(")");
11697 }
11698
11699 self.write_space();
11700 self.write_keyword("FROM");
11701 self.write_space();
11702
11703 for (i, principal) in r.principals.iter().enumerate() {
11705 if i > 0 {
11706 self.write(", ");
11707 }
11708 if principal.is_role {
11709 self.write_keyword("ROLE");
11710 self.write_space();
11711 } else if principal.is_group {
11712 self.write_keyword("GROUP");
11713 self.write_space();
11714 } else if principal.is_share {
11715 self.write_keyword("SHARE");
11716 self.write_space();
11717 }
11718 self.generate_identifier(&principal.name)?;
11719 }
11720
11721 if r.cascade {
11723 self.write_space();
11724 self.write_keyword("CASCADE");
11725 } else if r.restrict {
11726 self.write_space();
11727 self.write_keyword("RESTRICT");
11728 }
11729
11730 Ok(())
11731 }
11732
11733 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
11734 self.write_keyword("COMMENT");
11735
11736 if c.exists {
11738 self.write_space();
11739 self.write_keyword("IF EXISTS");
11740 }
11741
11742 self.write_space();
11743 self.write_keyword("ON");
11744
11745 if c.materialized {
11747 self.write_space();
11748 self.write_keyword("MATERIALIZED");
11749 }
11750
11751 self.write_space();
11752 self.write_keyword(&c.kind);
11753 self.write_space();
11754
11755 self.generate_expression(&c.this)?;
11757
11758 self.write_space();
11759 self.write_keyword("IS");
11760 self.write_space();
11761
11762 self.generate_expression(&c.expression)?;
11764
11765 Ok(())
11766 }
11767
11768 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
11769 self.write_keyword("SET");
11770
11771 for (i, item) in s.items.iter().enumerate() {
11772 if i > 0 {
11773 self.write(",");
11774 }
11775 self.write_space();
11776
11777 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
11779 if let Some(ref kind) = item.kind {
11780 if has_variable_kind {
11784 if matches!(
11785 self.config.dialect,
11786 Some(DialectType::Spark | DialectType::Databricks | DialectType::DuckDB)
11787 ) {
11788 self.write_keyword("VARIABLE");
11789 self.write_space();
11790 }
11791 } else {
11792 self.write_keyword(kind);
11793 self.write_space();
11794 }
11795 }
11796
11797 let name_str = match &item.name {
11799 Expression::Identifier(id) => Some(id.name.as_str()),
11800 _ => None,
11801 };
11802
11803 let is_transaction = name_str == Some("TRANSACTION");
11804 let is_character_set = name_str == Some("CHARACTER SET");
11805 let is_names = name_str == Some("NAMES");
11806 let is_collate = name_str == Some("COLLATE");
11807 let is_value_only =
11808 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
11809
11810 if is_transaction {
11811 self.write_keyword("TRANSACTION");
11813 if let Expression::Identifier(id) = &item.value {
11814 if !id.name.is_empty() {
11815 self.write_space();
11816 self.write(&id.name);
11817 }
11818 }
11819 } else if is_character_set {
11820 self.write_keyword("CHARACTER SET");
11822 self.write_space();
11823 self.generate_set_value(&item.value)?;
11824 } else if is_names {
11825 self.write_keyword("NAMES");
11827 self.write_space();
11828 self.generate_set_value(&item.value)?;
11829 } else if is_collate {
11830 self.write_keyword("COLLATE");
11832 self.write_space();
11833 self.generate_set_value(&item.value)?;
11834 } else if has_variable_kind {
11835 if let Some(ns) = name_str {
11838 self.write(ns);
11839 } else {
11840 self.generate_expression(&item.name)?;
11841 }
11842 self.write(" = ");
11843 self.generate_set_value(&item.value)?;
11844 } else if is_value_only {
11845 self.generate_expression(&item.name)?;
11847 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
11848 self.generate_expression(&item.name)?;
11850 self.write_space();
11851 self.generate_set_value(&item.value)?;
11852 } else {
11853 match &item.name {
11856 Expression::Identifier(id) => {
11857 self.write(&id.name);
11858 }
11859 _ => {
11860 self.generate_expression(&item.name)?;
11861 }
11862 }
11863 self.write(" = ");
11864 self.generate_set_value(&item.value)?;
11865 }
11866 }
11867
11868 Ok(())
11869 }
11870
11871 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
11874 if let Expression::Identifier(id) = value {
11875 match id.name.as_str() {
11876 "DEFAULT" | "ON" | "OFF" => {
11877 self.write_keyword(&id.name);
11878 return Ok(());
11879 }
11880 _ => {}
11881 }
11882 }
11883 self.generate_expression(value)
11884 }
11885
11886 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
11889 self.write_keyword("ALTER");
11890 if let Some(ref algorithm) = av.algorithm {
11892 self.write_space();
11893 self.write_keyword("ALGORITHM");
11894 self.write(" = ");
11895 self.write_keyword(algorithm);
11896 }
11897 if let Some(ref definer) = av.definer {
11898 self.write_space();
11899 self.write_keyword("DEFINER");
11900 self.write(" = ");
11901 self.write(definer);
11902 }
11903 if let Some(ref sql_security) = av.sql_security {
11904 self.write_space();
11905 self.write_keyword("SQL SECURITY");
11906 self.write(" = ");
11907 self.write_keyword(sql_security);
11908 }
11909 self.write_space();
11910 self.write_keyword("VIEW");
11911 self.write_space();
11912 self.generate_table(&av.name)?;
11913
11914 if !av.columns.is_empty() {
11916 self.write(" (");
11917 for (i, col) in av.columns.iter().enumerate() {
11918 if i > 0 {
11919 self.write(", ");
11920 }
11921 self.generate_identifier(&col.name)?;
11922 if let Some(ref comment) = col.comment {
11923 self.write_space();
11924 self.write_keyword("COMMENT");
11925 self.write(" ");
11926 self.generate_string_literal(comment)?;
11927 }
11928 }
11929 self.write(")");
11930 }
11931
11932 if let Some(ref opt) = av.with_option {
11934 self.write_space();
11935 self.write_keyword("WITH");
11936 self.write_space();
11937 self.write_keyword(opt);
11938 }
11939
11940 for action in &av.actions {
11941 self.write_space();
11942 match action {
11943 AlterViewAction::Rename(new_name) => {
11944 self.write_keyword("RENAME TO");
11945 self.write_space();
11946 self.generate_table(new_name)?;
11947 }
11948 AlterViewAction::OwnerTo(owner) => {
11949 self.write_keyword("OWNER TO");
11950 self.write_space();
11951 self.generate_identifier(owner)?;
11952 }
11953 AlterViewAction::SetSchema(schema) => {
11954 self.write_keyword("SET SCHEMA");
11955 self.write_space();
11956 self.generate_identifier(schema)?;
11957 }
11958 AlterViewAction::SetAuthorization(auth) => {
11959 self.write_keyword("SET AUTHORIZATION");
11960 self.write_space();
11961 self.write(auth);
11962 }
11963 AlterViewAction::AlterColumn { name, action } => {
11964 self.write_keyword("ALTER COLUMN");
11965 self.write_space();
11966 self.generate_identifier(name)?;
11967 self.write_space();
11968 self.generate_alter_column_action(action)?;
11969 }
11970 AlterViewAction::AsSelect(query) => {
11971 self.write_keyword("AS");
11972 self.write_space();
11973 self.generate_expression(query)?;
11974 }
11975 AlterViewAction::SetTblproperties(props) => {
11976 self.write_keyword("SET TBLPROPERTIES");
11977 self.write(" (");
11978 for (i, (key, value)) in props.iter().enumerate() {
11979 if i > 0 {
11980 self.write(", ");
11981 }
11982 self.generate_string_literal(key)?;
11983 self.write("=");
11984 self.generate_string_literal(value)?;
11985 }
11986 self.write(")");
11987 }
11988 AlterViewAction::UnsetTblproperties(keys) => {
11989 self.write_keyword("UNSET TBLPROPERTIES");
11990 self.write(" (");
11991 for (i, key) in keys.iter().enumerate() {
11992 if i > 0 {
11993 self.write(", ");
11994 }
11995 self.generate_string_literal(key)?;
11996 }
11997 self.write(")");
11998 }
11999 }
12000 }
12001
12002 Ok(())
12003 }
12004
12005 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
12006 self.write_keyword("ALTER INDEX");
12007 self.write_space();
12008 self.generate_identifier(&ai.name)?;
12009
12010 if let Some(table) = &ai.table {
12011 self.write_space();
12012 self.write_keyword("ON");
12013 self.write_space();
12014 self.generate_table(table)?;
12015 }
12016
12017 for action in &ai.actions {
12018 self.write_space();
12019 match action {
12020 AlterIndexAction::Rename(new_name) => {
12021 self.write_keyword("RENAME TO");
12022 self.write_space();
12023 self.generate_identifier(new_name)?;
12024 }
12025 AlterIndexAction::SetTablespace(tablespace) => {
12026 self.write_keyword("SET TABLESPACE");
12027 self.write_space();
12028 self.generate_identifier(tablespace)?;
12029 }
12030 AlterIndexAction::Visible(visible) => {
12031 if *visible {
12032 self.write_keyword("VISIBLE");
12033 } else {
12034 self.write_keyword("INVISIBLE");
12035 }
12036 }
12037 }
12038 }
12039
12040 Ok(())
12041 }
12042
12043 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
12044 for comment in &cs.leading_comments {
12046 self.write_formatted_comment(comment);
12047 self.write_space();
12048 }
12049
12050 let saved_athena_hive_context = self.athena_hive_context;
12052 if matches!(
12053 self.config.dialect,
12054 Some(crate::dialects::DialectType::Athena)
12055 ) {
12056 self.athena_hive_context = true;
12057 }
12058
12059 self.write_keyword("CREATE SCHEMA");
12060
12061 if cs.if_not_exists {
12062 self.write_space();
12063 self.write_keyword("IF NOT EXISTS");
12064 }
12065
12066 self.write_space();
12067 for (i, part) in cs.name.iter().enumerate() {
12068 if i > 0 {
12069 self.write(".");
12070 }
12071 self.generate_identifier(part)?;
12072 }
12073
12074 if let Some(ref clone_parts) = cs.clone_from {
12075 self.write_keyword(" CLONE ");
12076 for (i, part) in clone_parts.iter().enumerate() {
12077 if i > 0 {
12078 self.write(".");
12079 }
12080 self.generate_identifier(part)?;
12081 }
12082 }
12083
12084 if let Some(ref at_clause) = cs.at_clause {
12085 self.write_space();
12086 self.generate_expression(at_clause)?;
12087 }
12088
12089 if let Some(auth) = &cs.authorization {
12090 self.write_space();
12091 self.write_keyword("AUTHORIZATION");
12092 self.write_space();
12093 self.generate_identifier(auth)?;
12094 }
12095
12096 let with_properties: Vec<_> = cs
12099 .properties
12100 .iter()
12101 .filter(|p| matches!(p, Expression::Property(_)))
12102 .collect();
12103 let other_properties: Vec<_> = cs
12104 .properties
12105 .iter()
12106 .filter(|p| !matches!(p, Expression::Property(_)))
12107 .collect();
12108
12109 if !with_properties.is_empty() {
12111 self.write_space();
12112 self.write_keyword("WITH");
12113 self.write(" (");
12114 for (i, prop) in with_properties.iter().enumerate() {
12115 if i > 0 {
12116 self.write(", ");
12117 }
12118 self.generate_expression(prop)?;
12119 }
12120 self.write(")");
12121 }
12122
12123 for prop in other_properties {
12125 self.write_space();
12126 self.generate_expression(prop)?;
12127 }
12128
12129 self.athena_hive_context = saved_athena_hive_context;
12131
12132 Ok(())
12133 }
12134
12135 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
12136 self.write_keyword("DROP SCHEMA");
12137
12138 if ds.if_exists {
12139 self.write_space();
12140 self.write_keyword("IF EXISTS");
12141 }
12142
12143 self.write_space();
12144 self.generate_identifier(&ds.name)?;
12145
12146 if ds.cascade {
12147 self.write_space();
12148 self.write_keyword("CASCADE");
12149 }
12150
12151 Ok(())
12152 }
12153
12154 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
12155 self.write_keyword("DROP NAMESPACE");
12156
12157 if dn.if_exists {
12158 self.write_space();
12159 self.write_keyword("IF EXISTS");
12160 }
12161
12162 self.write_space();
12163 self.generate_identifier(&dn.name)?;
12164
12165 if dn.cascade {
12166 self.write_space();
12167 self.write_keyword("CASCADE");
12168 }
12169
12170 Ok(())
12171 }
12172
12173 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
12174 self.write_keyword("CREATE DATABASE");
12175
12176 if cd.if_not_exists {
12177 self.write_space();
12178 self.write_keyword("IF NOT EXISTS");
12179 }
12180
12181 self.write_space();
12182 self.generate_identifier(&cd.name)?;
12183
12184 if let Some(ref clone_src) = cd.clone_from {
12185 self.write_keyword(" CLONE ");
12186 self.generate_identifier(clone_src)?;
12187 }
12188
12189 if let Some(ref at_clause) = cd.at_clause {
12191 self.write_space();
12192 self.generate_expression(at_clause)?;
12193 }
12194
12195 for option in &cd.options {
12196 self.write_space();
12197 match option {
12198 DatabaseOption::CharacterSet(charset) => {
12199 self.write_keyword("CHARACTER SET");
12200 self.write(" = ");
12201 self.write(&format!("'{}'", charset));
12202 }
12203 DatabaseOption::Collate(collate) => {
12204 self.write_keyword("COLLATE");
12205 self.write(" = ");
12206 self.write(&format!("'{}'", collate));
12207 }
12208 DatabaseOption::Owner(owner) => {
12209 self.write_keyword("OWNER");
12210 self.write(" = ");
12211 self.generate_identifier(owner)?;
12212 }
12213 DatabaseOption::Template(template) => {
12214 self.write_keyword("TEMPLATE");
12215 self.write(" = ");
12216 self.generate_identifier(template)?;
12217 }
12218 DatabaseOption::Encoding(encoding) => {
12219 self.write_keyword("ENCODING");
12220 self.write(" = ");
12221 self.write(&format!("'{}'", encoding));
12222 }
12223 DatabaseOption::Location(location) => {
12224 self.write_keyword("LOCATION");
12225 self.write(" = ");
12226 self.write(&format!("'{}'", location));
12227 }
12228 }
12229 }
12230
12231 Ok(())
12232 }
12233
12234 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
12235 self.write_keyword("DROP DATABASE");
12236
12237 if dd.if_exists {
12238 self.write_space();
12239 self.write_keyword("IF EXISTS");
12240 }
12241
12242 self.write_space();
12243 self.generate_identifier(&dd.name)?;
12244
12245 if dd.sync {
12246 self.write_space();
12247 self.write_keyword("SYNC");
12248 }
12249
12250 Ok(())
12251 }
12252
12253 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
12254 self.write_keyword("CREATE");
12255
12256 if cf.or_alter {
12257 self.write_space();
12258 self.write_keyword("OR ALTER");
12259 } else if cf.or_replace {
12260 self.write_space();
12261 self.write_keyword("OR REPLACE");
12262 }
12263
12264 if cf.temporary {
12265 self.write_space();
12266 self.write_keyword("TEMPORARY");
12267 }
12268
12269 self.write_space();
12270 if cf.is_table_function {
12271 self.write_keyword("TABLE FUNCTION");
12272 } else {
12273 self.write_keyword("FUNCTION");
12274 }
12275
12276 if cf.if_not_exists {
12277 self.write_space();
12278 self.write_keyword("IF NOT EXISTS");
12279 }
12280
12281 self.write_space();
12282 self.generate_table(&cf.name)?;
12283 if cf.has_parens {
12284 let func_multiline = self.config.pretty
12285 && matches!(
12286 self.config.dialect,
12287 Some(crate::dialects::DialectType::TSQL)
12288 | Some(crate::dialects::DialectType::Fabric)
12289 )
12290 && !cf.parameters.is_empty();
12291 if func_multiline {
12292 self.write("(\n");
12293 self.indent_level += 2;
12294 self.write_indent();
12295 self.generate_function_parameters(&cf.parameters)?;
12296 self.write("\n");
12297 self.indent_level -= 2;
12298 self.write(")");
12299 } else {
12300 self.write("(");
12301 self.generate_function_parameters(&cf.parameters)?;
12302 self.write(")");
12303 }
12304 }
12305
12306 let use_multiline = self.config.pretty
12309 && matches!(
12310 self.config.dialect,
12311 Some(crate::dialects::DialectType::BigQuery)
12312 | Some(crate::dialects::DialectType::TSQL)
12313 | Some(crate::dialects::DialectType::Fabric)
12314 );
12315
12316 if cf.language_first {
12317 if let Some(lang) = &cf.language {
12319 if use_multiline {
12320 self.write_newline();
12321 } else {
12322 self.write_space();
12323 }
12324 self.write_keyword("LANGUAGE");
12325 self.write_space();
12326 self.write(lang);
12327 }
12328
12329 if let Some(sql_data) = &cf.sql_data_access {
12331 self.write_space();
12332 match sql_data {
12333 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12334 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12335 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12336 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12337 }
12338 }
12339
12340 if let Some(ref rtb) = cf.returns_table_body {
12341 if use_multiline {
12342 self.write_newline();
12343 } else {
12344 self.write_space();
12345 }
12346 self.write_keyword("RETURNS");
12347 self.write_space();
12348 self.write(rtb);
12349 } else if let Some(return_type) = &cf.return_type {
12350 if use_multiline {
12351 self.write_newline();
12352 } else {
12353 self.write_space();
12354 }
12355 self.write_keyword("RETURNS");
12356 self.write_space();
12357 self.generate_data_type(return_type)?;
12358 }
12359 } else {
12360 let is_duckdb = matches!(
12363 self.config.dialect,
12364 Some(crate::dialects::DialectType::DuckDB)
12365 );
12366 if let Some(ref rtb) = cf.returns_table_body {
12367 if !(is_duckdb && rtb.is_empty()) {
12368 if use_multiline {
12369 self.write_newline();
12370 } else {
12371 self.write_space();
12372 }
12373 self.write_keyword("RETURNS");
12374 self.write_space();
12375 self.write(rtb);
12376 }
12377 } else if let Some(return_type) = &cf.return_type {
12378 if !is_duckdb {
12380 let is_table_return = matches!(return_type, crate::expressions::DataType::Custom { ref name } if name.eq_ignore_ascii_case("TABLE"));
12381 if use_multiline {
12382 self.write_newline();
12383 } else {
12384 self.write_space();
12385 }
12386 self.write_keyword("RETURNS");
12387 self.write_space();
12388 if is_table_return {
12389 self.write_keyword("TABLE");
12390 } else {
12391 self.generate_data_type(return_type)?;
12392 }
12393 }
12394 }
12395 }
12396
12397 if !cf.property_order.is_empty() {
12399 let is_bigquery = matches!(
12401 self.config.dialect,
12402 Some(crate::dialects::DialectType::BigQuery)
12403 );
12404 let property_order = if is_bigquery {
12405 let mut reordered = Vec::new();
12407 let mut has_as = false;
12408 let mut has_options = false;
12409 for prop in &cf.property_order {
12410 match prop {
12411 FunctionPropertyKind::As => has_as = true,
12412 FunctionPropertyKind::Options => has_options = true,
12413 _ => {}
12414 }
12415 }
12416 if has_as && has_options {
12417 for prop in &cf.property_order {
12419 if *prop != FunctionPropertyKind::As
12420 && *prop != FunctionPropertyKind::Options
12421 {
12422 reordered.push(*prop);
12423 }
12424 }
12425 reordered.push(FunctionPropertyKind::Options);
12426 reordered.push(FunctionPropertyKind::As);
12427 reordered
12428 } else {
12429 cf.property_order.clone()
12430 }
12431 } else {
12432 cf.property_order.clone()
12433 };
12434
12435 for prop in &property_order {
12436 match prop {
12437 FunctionPropertyKind::Set => {
12438 self.generate_function_set_options(cf)?;
12439 }
12440 FunctionPropertyKind::As => {
12441 self.generate_function_body(cf)?;
12442 }
12443 FunctionPropertyKind::Language => {
12444 if !cf.language_first {
12445 if let Some(lang) = &cf.language {
12447 let use_multiline = self.config.pretty
12449 && matches!(
12450 self.config.dialect,
12451 Some(crate::dialects::DialectType::BigQuery)
12452 );
12453 if use_multiline {
12454 self.write_newline();
12455 } else {
12456 self.write_space();
12457 }
12458 self.write_keyword("LANGUAGE");
12459 self.write_space();
12460 self.write(lang);
12461 }
12462 }
12463 }
12464 FunctionPropertyKind::Determinism => {
12465 self.generate_function_determinism(cf)?;
12466 }
12467 FunctionPropertyKind::NullInput => {
12468 self.generate_function_null_input(cf)?;
12469 }
12470 FunctionPropertyKind::Security => {
12471 self.generate_function_security(cf)?;
12472 }
12473 FunctionPropertyKind::SqlDataAccess => {
12474 if !cf.language_first {
12475 self.generate_function_sql_data_access(cf)?;
12477 }
12478 }
12479 FunctionPropertyKind::Options => {
12480 if !cf.options.is_empty() {
12481 self.write_space();
12482 self.generate_options_clause(&cf.options)?;
12483 }
12484 }
12485 FunctionPropertyKind::Environment => {
12486 if !cf.environment.is_empty() {
12487 self.write_space();
12488 self.generate_environment_clause(&cf.environment)?;
12489 }
12490 }
12491 FunctionPropertyKind::Handler => {
12492 if let Some(ref h) = cf.handler {
12493 self.write_space();
12494 self.write_keyword("HANDLER");
12495 self.write_space();
12496 self.write("'");
12497 self.write(h);
12498 self.write("'");
12499 }
12500 }
12501 FunctionPropertyKind::ParameterStyle => {
12502 if let Some(ref ps) = cf.parameter_style {
12503 self.write_space();
12504 self.write_keyword("PARAMETER STYLE");
12505 self.write_space();
12506 self.write_keyword(ps);
12507 }
12508 }
12509 }
12510 }
12511
12512 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
12514 {
12515 self.write_space();
12516 self.generate_options_clause(&cf.options)?;
12517 }
12518
12519 if !cf.environment.is_empty()
12521 && !cf
12522 .property_order
12523 .contains(&FunctionPropertyKind::Environment)
12524 {
12525 self.write_space();
12526 self.generate_environment_clause(&cf.environment)?;
12527 }
12528 } else {
12529 if matches!(
12532 self.config.dialect,
12533 Some(crate::dialects::DialectType::BigQuery)
12534 ) {
12535 self.generate_function_determinism(cf)?;
12536 }
12537
12538 let use_multiline = self.config.pretty
12540 && matches!(
12541 self.config.dialect,
12542 Some(crate::dialects::DialectType::BigQuery)
12543 );
12544
12545 if !cf.language_first {
12546 if let Some(lang) = &cf.language {
12547 if use_multiline {
12548 self.write_newline();
12549 } else {
12550 self.write_space();
12551 }
12552 self.write_keyword("LANGUAGE");
12553 self.write_space();
12554 self.write(lang);
12555 }
12556
12557 self.generate_function_sql_data_access(cf)?;
12559 }
12560
12561 if !matches!(
12563 self.config.dialect,
12564 Some(crate::dialects::DialectType::BigQuery)
12565 ) {
12566 self.generate_function_determinism(cf)?;
12567 }
12568
12569 self.generate_function_null_input(cf)?;
12570 self.generate_function_security(cf)?;
12571 self.generate_function_set_options(cf)?;
12572
12573 if !cf.options.is_empty() {
12575 self.write_space();
12576 self.generate_options_clause(&cf.options)?;
12577 }
12578
12579 if !cf.environment.is_empty() {
12581 self.write_space();
12582 self.generate_environment_clause(&cf.environment)?;
12583 }
12584
12585 self.generate_function_body(cf)?;
12586 }
12587
12588 Ok(())
12589 }
12590
12591 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
12593 for opt in &cf.set_options {
12594 self.write_space();
12595 self.write_keyword("SET");
12596 self.write_space();
12597 self.write(&opt.name);
12598 match &opt.value {
12599 FunctionSetValue::Value { value, use_to } => {
12600 if *use_to {
12601 self.write(" TO ");
12602 } else {
12603 self.write(" = ");
12604 }
12605 self.write(value);
12606 }
12607 FunctionSetValue::FromCurrent => {
12608 self.write_space();
12609 self.write_keyword("FROM CURRENT");
12610 }
12611 }
12612 }
12613 Ok(())
12614 }
12615
12616 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
12618 if let Some(body) = &cf.body {
12619 self.write_space();
12621 let use_multiline = self.config.pretty
12623 && matches!(
12624 self.config.dialect,
12625 Some(crate::dialects::DialectType::BigQuery)
12626 );
12627 match body {
12628 FunctionBody::Block(block) => {
12629 self.write_keyword("AS");
12630 if matches!(
12631 self.config.dialect,
12632 Some(crate::dialects::DialectType::TSQL)
12633 ) {
12634 self.write(" BEGIN ");
12635 self.write(block);
12636 self.write(" END");
12637 } else if matches!(
12638 self.config.dialect,
12639 Some(crate::dialects::DialectType::PostgreSQL)
12640 ) {
12641 self.write(" $$");
12642 self.write(block);
12643 self.write("$$");
12644 } else {
12645 let escaped = self.escape_block_for_single_quote(block);
12647 if use_multiline {
12649 self.write_newline();
12650 } else {
12651 self.write(" ");
12652 }
12653 self.write("'");
12654 self.write(&escaped);
12655 self.write("'");
12656 }
12657 }
12658 FunctionBody::StringLiteral(s) => {
12659 self.write_keyword("AS");
12660 if use_multiline {
12662 self.write_newline();
12663 } else {
12664 self.write(" ");
12665 }
12666 self.write("'");
12667 self.write(s);
12668 self.write("'");
12669 }
12670 FunctionBody::Expression(expr) => {
12671 self.write_keyword("AS");
12672 self.write_space();
12673 self.generate_expression(expr)?;
12674 }
12675 FunctionBody::External(name) => {
12676 self.write_keyword("EXTERNAL NAME");
12677 self.write(" '");
12678 self.write(name);
12679 self.write("'");
12680 }
12681 FunctionBody::Return(expr) => {
12682 if matches!(
12683 self.config.dialect,
12684 Some(crate::dialects::DialectType::DuckDB)
12685 ) {
12686 self.write_keyword("AS");
12688 self.write_space();
12689 let is_table_return = cf.returns_table_body.is_some()
12691 || matches!(&cf.return_type, Some(crate::expressions::DataType::Custom { ref name }) if name.eq_ignore_ascii_case("TABLE"));
12692 if is_table_return {
12693 self.write_keyword("TABLE");
12694 self.write_space();
12695 }
12696 self.generate_expression(expr)?;
12697 } else {
12698 if self.config.create_function_return_as {
12699 self.write_keyword("AS");
12700 if self.config.pretty
12702 && matches!(
12703 self.config.dialect,
12704 Some(crate::dialects::DialectType::TSQL)
12705 | Some(crate::dialects::DialectType::Fabric)
12706 )
12707 {
12708 self.write_newline();
12709 } else {
12710 self.write_space();
12711 }
12712 }
12713 self.write_keyword("RETURN");
12714 self.write_space();
12715 self.generate_expression(expr)?;
12716 }
12717 }
12718 FunctionBody::Statements(stmts) => {
12719 self.write_keyword("AS");
12720 self.write(" BEGIN ");
12721 for (i, stmt) in stmts.iter().enumerate() {
12722 if i > 0 {
12723 self.write(" ");
12724 }
12725 self.generate_expression(stmt)?;
12726 self.write(";");
12727 }
12728 self.write(" END");
12729 }
12730 FunctionBody::RawBlock(text) => {
12731 self.write_newline();
12732 self.write(text);
12733 }
12734 FunctionBody::DollarQuoted { content, tag } => {
12735 self.write_keyword("AS");
12736 self.write(" ");
12737 let supports_dollar_quoting = matches!(
12739 self.config.dialect,
12740 Some(crate::dialects::DialectType::PostgreSQL)
12741 | Some(crate::dialects::DialectType::Databricks)
12742 | Some(crate::dialects::DialectType::Redshift)
12743 | Some(crate::dialects::DialectType::DuckDB)
12744 );
12745 if supports_dollar_quoting {
12746 self.write("$");
12748 if let Some(t) = tag {
12749 self.write(t);
12750 }
12751 self.write("$");
12752 self.write(content);
12753 self.write("$");
12754 if let Some(t) = tag {
12755 self.write(t);
12756 }
12757 self.write("$");
12758 } else {
12759 let escaped = self.escape_block_for_single_quote(content);
12761 self.write("'");
12762 self.write(&escaped);
12763 self.write("'");
12764 }
12765 }
12766 }
12767 }
12768 Ok(())
12769 }
12770
12771 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
12773 if let Some(det) = cf.deterministic {
12774 self.write_space();
12775 if matches!(
12776 self.config.dialect,
12777 Some(crate::dialects::DialectType::BigQuery)
12778 ) {
12779 if det {
12781 self.write_keyword("DETERMINISTIC");
12782 } else {
12783 self.write_keyword("NOT DETERMINISTIC");
12784 }
12785 } else {
12786 if det {
12788 self.write_keyword("IMMUTABLE");
12789 } else {
12790 self.write_keyword("VOLATILE");
12791 }
12792 }
12793 }
12794 Ok(())
12795 }
12796
12797 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
12799 if let Some(returns_null) = cf.returns_null_on_null_input {
12800 self.write_space();
12801 if returns_null {
12802 if cf.strict {
12803 self.write_keyword("STRICT");
12804 } else {
12805 self.write_keyword("RETURNS NULL ON NULL INPUT");
12806 }
12807 } else {
12808 self.write_keyword("CALLED ON NULL INPUT");
12809 }
12810 }
12811 Ok(())
12812 }
12813
12814 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
12816 if let Some(security) = &cf.security {
12817 self.write_space();
12818 if matches!(
12820 self.config.dialect,
12821 Some(crate::dialects::DialectType::MySQL)
12822 ) {
12823 self.write_keyword("SQL SECURITY");
12824 } else {
12825 self.write_keyword("SECURITY");
12826 }
12827 self.write_space();
12828 match security {
12829 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12830 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12831 FunctionSecurity::None => self.write_keyword("NONE"),
12832 }
12833 }
12834 Ok(())
12835 }
12836
12837 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
12839 if let Some(sql_data) = &cf.sql_data_access {
12840 self.write_space();
12841 match sql_data {
12842 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12843 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12844 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12845 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12846 }
12847 }
12848 Ok(())
12849 }
12850
12851 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
12852 for (i, param) in params.iter().enumerate() {
12853 if i > 0 {
12854 self.write(", ");
12855 }
12856
12857 if let Some(mode) = ¶m.mode {
12858 if let Some(text) = ¶m.mode_text {
12859 self.write(text);
12860 } else {
12861 match mode {
12862 ParameterMode::In => self.write_keyword("IN"),
12863 ParameterMode::Out => self.write_keyword("OUT"),
12864 ParameterMode::InOut => self.write_keyword("INOUT"),
12865 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
12866 }
12867 }
12868 self.write_space();
12869 }
12870
12871 if let Some(name) = ¶m.name {
12872 self.generate_identifier(name)?;
12873 let skip_type =
12875 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
12876 if !skip_type {
12877 self.write_space();
12878 self.generate_data_type(¶m.data_type)?;
12879 }
12880 } else {
12881 self.generate_data_type(¶m.data_type)?;
12882 }
12883
12884 if let Some(default) = ¶m.default {
12885 if self.config.parameter_default_equals {
12886 self.write(" = ");
12887 } else {
12888 self.write(" DEFAULT ");
12889 }
12890 self.generate_expression(default)?;
12891 }
12892 }
12893
12894 Ok(())
12895 }
12896
12897 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
12898 self.write_keyword("DROP FUNCTION");
12899
12900 if df.if_exists {
12901 self.write_space();
12902 self.write_keyword("IF EXISTS");
12903 }
12904
12905 self.write_space();
12906 self.generate_table(&df.name)?;
12907
12908 if let Some(params) = &df.parameters {
12909 self.write(" (");
12910 for (i, dt) in params.iter().enumerate() {
12911 if i > 0 {
12912 self.write(", ");
12913 }
12914 self.generate_data_type(dt)?;
12915 }
12916 self.write(")");
12917 }
12918
12919 if df.cascade {
12920 self.write_space();
12921 self.write_keyword("CASCADE");
12922 }
12923
12924 Ok(())
12925 }
12926
12927 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
12928 self.write_keyword("CREATE");
12929
12930 if cp.or_alter {
12931 self.write_space();
12932 self.write_keyword("OR ALTER");
12933 } else if cp.or_replace {
12934 self.write_space();
12935 self.write_keyword("OR REPLACE");
12936 }
12937
12938 self.write_space();
12939 if cp.use_proc_keyword {
12940 self.write_keyword("PROC");
12941 } else {
12942 self.write_keyword("PROCEDURE");
12943 }
12944
12945 if cp.if_not_exists {
12946 self.write_space();
12947 self.write_keyword("IF NOT EXISTS");
12948 }
12949
12950 self.write_space();
12951 self.generate_table(&cp.name)?;
12952 if cp.has_parens {
12953 self.write("(");
12954 self.generate_function_parameters(&cp.parameters)?;
12955 self.write(")");
12956 } else if !cp.parameters.is_empty() {
12957 self.write_space();
12959 self.generate_function_parameters(&cp.parameters)?;
12960 }
12961
12962 if let Some(return_type) = &cp.return_type {
12964 self.write_space();
12965 self.write_keyword("RETURNS");
12966 self.write_space();
12967 self.generate_data_type(return_type)?;
12968 }
12969
12970 if let Some(execute_as) = &cp.execute_as {
12972 self.write_space();
12973 self.write_keyword("EXECUTE AS");
12974 self.write_space();
12975 self.write_keyword(execute_as);
12976 }
12977
12978 if let Some(lang) = &cp.language {
12979 self.write_space();
12980 self.write_keyword("LANGUAGE");
12981 self.write_space();
12982 self.write(lang);
12983 }
12984
12985 if let Some(security) = &cp.security {
12986 self.write_space();
12987 self.write_keyword("SECURITY");
12988 self.write_space();
12989 match security {
12990 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12991 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12992 FunctionSecurity::None => self.write_keyword("NONE"),
12993 }
12994 }
12995
12996 if !cp.with_options.is_empty() {
12998 self.write_space();
12999 self.write_keyword("WITH");
13000 self.write_space();
13001 for (i, opt) in cp.with_options.iter().enumerate() {
13002 if i > 0 {
13003 self.write(", ");
13004 }
13005 self.write(opt);
13006 }
13007 }
13008
13009 if let Some(body) = &cp.body {
13010 self.write_space();
13011 match body {
13012 FunctionBody::Block(block) => {
13013 self.write_keyword("AS");
13014 if matches!(
13015 self.config.dialect,
13016 Some(crate::dialects::DialectType::TSQL)
13017 ) {
13018 self.write(" BEGIN ");
13019 self.write(block);
13020 self.write(" END");
13021 } else if matches!(
13022 self.config.dialect,
13023 Some(crate::dialects::DialectType::PostgreSQL)
13024 ) {
13025 self.write(" $$");
13026 self.write(block);
13027 self.write("$$");
13028 } else {
13029 let escaped = self.escape_block_for_single_quote(block);
13031 self.write(" '");
13032 self.write(&escaped);
13033 self.write("'");
13034 }
13035 }
13036 FunctionBody::StringLiteral(s) => {
13037 self.write_keyword("AS");
13038 self.write(" '");
13039 self.write(s);
13040 self.write("'");
13041 }
13042 FunctionBody::Expression(expr) => {
13043 self.write_keyword("AS");
13044 self.write_space();
13045 self.generate_expression(expr)?;
13046 }
13047 FunctionBody::External(name) => {
13048 self.write_keyword("EXTERNAL NAME");
13049 self.write(" '");
13050 self.write(name);
13051 self.write("'");
13052 }
13053 FunctionBody::Return(expr) => {
13054 self.write_keyword("RETURN");
13055 self.write_space();
13056 self.generate_expression(expr)?;
13057 }
13058 FunctionBody::Statements(stmts) => {
13059 self.write_keyword("AS");
13060 self.write(" BEGIN ");
13061 for (i, stmt) in stmts.iter().enumerate() {
13062 if i > 0 {
13063 self.write(" ");
13064 }
13065 self.generate_expression(stmt)?;
13066 self.write(";");
13067 }
13068 self.write(" END");
13069 }
13070 FunctionBody::RawBlock(text) => {
13071 self.write_newline();
13072 self.write(text);
13073 }
13074 FunctionBody::DollarQuoted { content, tag } => {
13075 self.write_keyword("AS");
13076 self.write(" ");
13077 let supports_dollar_quoting = matches!(
13079 self.config.dialect,
13080 Some(crate::dialects::DialectType::PostgreSQL)
13081 | Some(crate::dialects::DialectType::Databricks)
13082 | Some(crate::dialects::DialectType::Redshift)
13083 | Some(crate::dialects::DialectType::DuckDB)
13084 );
13085 if supports_dollar_quoting {
13086 self.write("$");
13088 if let Some(t) = tag {
13089 self.write(t);
13090 }
13091 self.write("$");
13092 self.write(content);
13093 self.write("$");
13094 if let Some(t) = tag {
13095 self.write(t);
13096 }
13097 self.write("$");
13098 } else {
13099 let escaped = self.escape_block_for_single_quote(content);
13101 self.write("'");
13102 self.write(&escaped);
13103 self.write("'");
13104 }
13105 }
13106 }
13107 }
13108
13109 Ok(())
13110 }
13111
13112 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
13113 self.write_keyword("DROP PROCEDURE");
13114
13115 if dp.if_exists {
13116 self.write_space();
13117 self.write_keyword("IF EXISTS");
13118 }
13119
13120 self.write_space();
13121 self.generate_table(&dp.name)?;
13122
13123 if let Some(params) = &dp.parameters {
13124 self.write(" (");
13125 for (i, dt) in params.iter().enumerate() {
13126 if i > 0 {
13127 self.write(", ");
13128 }
13129 self.generate_data_type(dt)?;
13130 }
13131 self.write(")");
13132 }
13133
13134 if dp.cascade {
13135 self.write_space();
13136 self.write_keyword("CASCADE");
13137 }
13138
13139 Ok(())
13140 }
13141
13142 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
13143 self.write_keyword("CREATE");
13144
13145 if cs.or_replace {
13146 self.write_space();
13147 self.write_keyword("OR REPLACE");
13148 }
13149
13150 if cs.temporary {
13151 self.write_space();
13152 self.write_keyword("TEMPORARY");
13153 }
13154
13155 self.write_space();
13156 self.write_keyword("SEQUENCE");
13157
13158 if cs.if_not_exists {
13159 self.write_space();
13160 self.write_keyword("IF NOT EXISTS");
13161 }
13162
13163 self.write_space();
13164 self.generate_table(&cs.name)?;
13165
13166 if let Some(as_type) = &cs.as_type {
13168 self.write_space();
13169 self.write_keyword("AS");
13170 self.write_space();
13171 self.generate_data_type(as_type)?;
13172 }
13173
13174 if let Some(comment) = &cs.comment {
13176 self.write_space();
13177 self.write_keyword("COMMENT");
13178 self.write("=");
13179 self.generate_string_literal(comment)?;
13180 }
13181
13182 if !cs.property_order.is_empty() {
13184 for prop in &cs.property_order {
13185 match prop {
13186 SeqPropKind::Start => {
13187 if let Some(start) = cs.start {
13188 self.write_space();
13189 self.write_keyword("START WITH");
13190 self.write(&format!(" {}", start));
13191 }
13192 }
13193 SeqPropKind::Increment => {
13194 if let Some(inc) = cs.increment {
13195 self.write_space();
13196 self.write_keyword("INCREMENT BY");
13197 self.write(&format!(" {}", inc));
13198 }
13199 }
13200 SeqPropKind::Minvalue => {
13201 if let Some(min) = &cs.minvalue {
13202 self.write_space();
13203 match min {
13204 SequenceBound::Value(v) => {
13205 self.write_keyword("MINVALUE");
13206 self.write(&format!(" {}", v));
13207 }
13208 SequenceBound::None => {
13209 self.write_keyword("NO MINVALUE");
13210 }
13211 }
13212 }
13213 }
13214 SeqPropKind::Maxvalue => {
13215 if let Some(max) = &cs.maxvalue {
13216 self.write_space();
13217 match max {
13218 SequenceBound::Value(v) => {
13219 self.write_keyword("MAXVALUE");
13220 self.write(&format!(" {}", v));
13221 }
13222 SequenceBound::None => {
13223 self.write_keyword("NO MAXVALUE");
13224 }
13225 }
13226 }
13227 }
13228 SeqPropKind::Cache => {
13229 if let Some(cache) = cs.cache {
13230 self.write_space();
13231 self.write_keyword("CACHE");
13232 self.write(&format!(" {}", cache));
13233 }
13234 }
13235 SeqPropKind::NoCache => {
13236 self.write_space();
13237 self.write_keyword("NO CACHE");
13238 }
13239 SeqPropKind::NoCacheWord => {
13240 self.write_space();
13241 self.write_keyword("NOCACHE");
13242 }
13243 SeqPropKind::Cycle => {
13244 self.write_space();
13245 self.write_keyword("CYCLE");
13246 }
13247 SeqPropKind::NoCycle => {
13248 self.write_space();
13249 self.write_keyword("NO CYCLE");
13250 }
13251 SeqPropKind::NoCycleWord => {
13252 self.write_space();
13253 self.write_keyword("NOCYCLE");
13254 }
13255 SeqPropKind::OwnedBy => {
13256 if !cs.owned_by_none {
13258 if let Some(owned) = &cs.owned_by {
13259 self.write_space();
13260 self.write_keyword("OWNED BY");
13261 self.write_space();
13262 self.generate_table(owned)?;
13263 }
13264 }
13265 }
13266 SeqPropKind::Order => {
13267 self.write_space();
13268 self.write_keyword("ORDER");
13269 }
13270 SeqPropKind::NoOrder => {
13271 self.write_space();
13272 self.write_keyword("NOORDER");
13273 }
13274 SeqPropKind::Comment => {
13275 }
13277 SeqPropKind::Sharing => {
13278 if let Some(val) = &cs.sharing {
13279 self.write_space();
13280 self.write(&format!("SHARING={}", val));
13281 }
13282 }
13283 SeqPropKind::Keep => {
13284 self.write_space();
13285 self.write_keyword("KEEP");
13286 }
13287 SeqPropKind::NoKeep => {
13288 self.write_space();
13289 self.write_keyword("NOKEEP");
13290 }
13291 SeqPropKind::Scale => {
13292 self.write_space();
13293 self.write_keyword("SCALE");
13294 if let Some(modifier) = &cs.scale_modifier {
13295 if !modifier.is_empty() {
13296 self.write_space();
13297 self.write_keyword(modifier);
13298 }
13299 }
13300 }
13301 SeqPropKind::NoScale => {
13302 self.write_space();
13303 self.write_keyword("NOSCALE");
13304 }
13305 SeqPropKind::Shard => {
13306 self.write_space();
13307 self.write_keyword("SHARD");
13308 if let Some(modifier) = &cs.shard_modifier {
13309 if !modifier.is_empty() {
13310 self.write_space();
13311 self.write_keyword(modifier);
13312 }
13313 }
13314 }
13315 SeqPropKind::NoShard => {
13316 self.write_space();
13317 self.write_keyword("NOSHARD");
13318 }
13319 SeqPropKind::Session => {
13320 self.write_space();
13321 self.write_keyword("SESSION");
13322 }
13323 SeqPropKind::Global => {
13324 self.write_space();
13325 self.write_keyword("GLOBAL");
13326 }
13327 SeqPropKind::NoMinvalueWord => {
13328 self.write_space();
13329 self.write_keyword("NOMINVALUE");
13330 }
13331 SeqPropKind::NoMaxvalueWord => {
13332 self.write_space();
13333 self.write_keyword("NOMAXVALUE");
13334 }
13335 }
13336 }
13337 } else {
13338 if let Some(inc) = cs.increment {
13340 self.write_space();
13341 self.write_keyword("INCREMENT BY");
13342 self.write(&format!(" {}", inc));
13343 }
13344
13345 if let Some(min) = &cs.minvalue {
13346 self.write_space();
13347 match min {
13348 SequenceBound::Value(v) => {
13349 self.write_keyword("MINVALUE");
13350 self.write(&format!(" {}", v));
13351 }
13352 SequenceBound::None => {
13353 self.write_keyword("NO MINVALUE");
13354 }
13355 }
13356 }
13357
13358 if let Some(max) = &cs.maxvalue {
13359 self.write_space();
13360 match max {
13361 SequenceBound::Value(v) => {
13362 self.write_keyword("MAXVALUE");
13363 self.write(&format!(" {}", v));
13364 }
13365 SequenceBound::None => {
13366 self.write_keyword("NO MAXVALUE");
13367 }
13368 }
13369 }
13370
13371 if let Some(start) = cs.start {
13372 self.write_space();
13373 self.write_keyword("START WITH");
13374 self.write(&format!(" {}", start));
13375 }
13376
13377 if let Some(cache) = cs.cache {
13378 self.write_space();
13379 self.write_keyword("CACHE");
13380 self.write(&format!(" {}", cache));
13381 }
13382
13383 if cs.cycle {
13384 self.write_space();
13385 self.write_keyword("CYCLE");
13386 }
13387
13388 if let Some(owned) = &cs.owned_by {
13389 self.write_space();
13390 self.write_keyword("OWNED BY");
13391 self.write_space();
13392 self.generate_table(owned)?;
13393 }
13394 }
13395
13396 Ok(())
13397 }
13398
13399 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
13400 self.write_keyword("DROP SEQUENCE");
13401
13402 if ds.if_exists {
13403 self.write_space();
13404 self.write_keyword("IF EXISTS");
13405 }
13406
13407 self.write_space();
13408 self.generate_table(&ds.name)?;
13409
13410 if ds.cascade {
13411 self.write_space();
13412 self.write_keyword("CASCADE");
13413 }
13414
13415 Ok(())
13416 }
13417
13418 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
13419 self.write_keyword("ALTER SEQUENCE");
13420
13421 if als.if_exists {
13422 self.write_space();
13423 self.write_keyword("IF EXISTS");
13424 }
13425
13426 self.write_space();
13427 self.generate_table(&als.name)?;
13428
13429 if let Some(inc) = als.increment {
13430 self.write_space();
13431 self.write_keyword("INCREMENT BY");
13432 self.write(&format!(" {}", inc));
13433 }
13434
13435 if let Some(min) = &als.minvalue {
13436 self.write_space();
13437 match min {
13438 SequenceBound::Value(v) => {
13439 self.write_keyword("MINVALUE");
13440 self.write(&format!(" {}", v));
13441 }
13442 SequenceBound::None => {
13443 self.write_keyword("NO MINVALUE");
13444 }
13445 }
13446 }
13447
13448 if let Some(max) = &als.maxvalue {
13449 self.write_space();
13450 match max {
13451 SequenceBound::Value(v) => {
13452 self.write_keyword("MAXVALUE");
13453 self.write(&format!(" {}", v));
13454 }
13455 SequenceBound::None => {
13456 self.write_keyword("NO MAXVALUE");
13457 }
13458 }
13459 }
13460
13461 if let Some(start) = als.start {
13462 self.write_space();
13463 self.write_keyword("START WITH");
13464 self.write(&format!(" {}", start));
13465 }
13466
13467 if let Some(restart) = &als.restart {
13468 self.write_space();
13469 self.write_keyword("RESTART");
13470 if let Some(val) = restart {
13471 self.write_keyword(" WITH");
13472 self.write(&format!(" {}", val));
13473 }
13474 }
13475
13476 if let Some(cache) = als.cache {
13477 self.write_space();
13478 self.write_keyword("CACHE");
13479 self.write(&format!(" {}", cache));
13480 }
13481
13482 if let Some(cycle) = als.cycle {
13483 self.write_space();
13484 if cycle {
13485 self.write_keyword("CYCLE");
13486 } else {
13487 self.write_keyword("NO CYCLE");
13488 }
13489 }
13490
13491 if let Some(owned) = &als.owned_by {
13492 self.write_space();
13493 self.write_keyword("OWNED BY");
13494 self.write_space();
13495 if let Some(table) = owned {
13496 self.generate_table(table)?;
13497 } else {
13498 self.write_keyword("NONE");
13499 }
13500 }
13501
13502 Ok(())
13503 }
13504
13505 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
13506 self.write_keyword("CREATE");
13507
13508 if ct.or_alter {
13509 self.write_space();
13510 self.write_keyword("OR ALTER");
13511 } else if ct.or_replace {
13512 self.write_space();
13513 self.write_keyword("OR REPLACE");
13514 }
13515
13516 if ct.constraint {
13517 self.write_space();
13518 self.write_keyword("CONSTRAINT");
13519 }
13520
13521 self.write_space();
13522 self.write_keyword("TRIGGER");
13523 self.write_space();
13524 self.generate_identifier(&ct.name)?;
13525
13526 self.write_space();
13527 match ct.timing {
13528 TriggerTiming::Before => self.write_keyword("BEFORE"),
13529 TriggerTiming::After => self.write_keyword("AFTER"),
13530 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
13531 }
13532
13533 for (i, event) in ct.events.iter().enumerate() {
13535 if i > 0 {
13536 self.write_keyword(" OR");
13537 }
13538 self.write_space();
13539 match event {
13540 TriggerEvent::Insert => self.write_keyword("INSERT"),
13541 TriggerEvent::Update(cols) => {
13542 self.write_keyword("UPDATE");
13543 if let Some(cols) = cols {
13544 self.write_space();
13545 self.write_keyword("OF");
13546 for (j, col) in cols.iter().enumerate() {
13547 if j > 0 {
13548 self.write(",");
13549 }
13550 self.write_space();
13551 self.generate_identifier(col)?;
13552 }
13553 }
13554 }
13555 TriggerEvent::Delete => self.write_keyword("DELETE"),
13556 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
13557 }
13558 }
13559
13560 self.write_space();
13561 self.write_keyword("ON");
13562 self.write_space();
13563 self.generate_table(&ct.table)?;
13564
13565 if let Some(ref_clause) = &ct.referencing {
13567 self.write_space();
13568 self.write_keyword("REFERENCING");
13569 if let Some(old_table) = &ref_clause.old_table {
13570 self.write_space();
13571 self.write_keyword("OLD TABLE AS");
13572 self.write_space();
13573 self.generate_identifier(old_table)?;
13574 }
13575 if let Some(new_table) = &ref_clause.new_table {
13576 self.write_space();
13577 self.write_keyword("NEW TABLE AS");
13578 self.write_space();
13579 self.generate_identifier(new_table)?;
13580 }
13581 if let Some(old_row) = &ref_clause.old_row {
13582 self.write_space();
13583 self.write_keyword("OLD ROW AS");
13584 self.write_space();
13585 self.generate_identifier(old_row)?;
13586 }
13587 if let Some(new_row) = &ref_clause.new_row {
13588 self.write_space();
13589 self.write_keyword("NEW ROW AS");
13590 self.write_space();
13591 self.generate_identifier(new_row)?;
13592 }
13593 }
13594
13595 if let Some(deferrable) = ct.deferrable {
13597 self.write_space();
13598 if deferrable {
13599 self.write_keyword("DEFERRABLE");
13600 } else {
13601 self.write_keyword("NOT DEFERRABLE");
13602 }
13603 }
13604
13605 if let Some(initially) = ct.initially_deferred {
13606 self.write_space();
13607 self.write_keyword("INITIALLY");
13608 self.write_space();
13609 if initially {
13610 self.write_keyword("DEFERRED");
13611 } else {
13612 self.write_keyword("IMMEDIATE");
13613 }
13614 }
13615
13616 if let Some(for_each) = ct.for_each {
13617 self.write_space();
13618 self.write_keyword("FOR EACH");
13619 self.write_space();
13620 match for_each {
13621 TriggerForEach::Row => self.write_keyword("ROW"),
13622 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
13623 }
13624 }
13625
13626 if let Some(when) = &ct.when {
13628 self.write_space();
13629 self.write_keyword("WHEN");
13630 if ct.when_paren {
13631 self.write(" (");
13632 self.generate_expression(when)?;
13633 self.write(")");
13634 } else {
13635 self.write_space();
13636 self.generate_expression(when)?;
13637 }
13638 }
13639
13640 self.write_space();
13642 match &ct.body {
13643 TriggerBody::Execute { function, args } => {
13644 self.write_keyword("EXECUTE FUNCTION");
13645 self.write_space();
13646 self.generate_table(function)?;
13647 self.write("(");
13648 for (i, arg) in args.iter().enumerate() {
13649 if i > 0 {
13650 self.write(", ");
13651 }
13652 self.generate_expression(arg)?;
13653 }
13654 self.write(")");
13655 }
13656 TriggerBody::Block(block) => {
13657 self.write_keyword("BEGIN");
13658 self.write_space();
13659 self.write(block);
13660 self.write_space();
13661 self.write_keyword("END");
13662 }
13663 }
13664
13665 Ok(())
13666 }
13667
13668 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
13669 self.write_keyword("DROP TRIGGER");
13670
13671 if dt.if_exists {
13672 self.write_space();
13673 self.write_keyword("IF EXISTS");
13674 }
13675
13676 self.write_space();
13677 self.generate_identifier(&dt.name)?;
13678
13679 if let Some(table) = &dt.table {
13680 self.write_space();
13681 self.write_keyword("ON");
13682 self.write_space();
13683 self.generate_table(table)?;
13684 }
13685
13686 if dt.cascade {
13687 self.write_space();
13688 self.write_keyword("CASCADE");
13689 }
13690
13691 Ok(())
13692 }
13693
13694 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
13695 self.write_keyword("CREATE TYPE");
13696
13697 if ct.if_not_exists {
13698 self.write_space();
13699 self.write_keyword("IF NOT EXISTS");
13700 }
13701
13702 self.write_space();
13703 self.generate_table(&ct.name)?;
13704
13705 self.write_space();
13706 self.write_keyword("AS");
13707 self.write_space();
13708
13709 match &ct.definition {
13710 TypeDefinition::Enum(values) => {
13711 self.write_keyword("ENUM");
13712 self.write(" (");
13713 for (i, val) in values.iter().enumerate() {
13714 if i > 0 {
13715 self.write(", ");
13716 }
13717 self.write(&format!("'{}'", val));
13718 }
13719 self.write(")");
13720 }
13721 TypeDefinition::Composite(attrs) => {
13722 self.write("(");
13723 for (i, attr) in attrs.iter().enumerate() {
13724 if i > 0 {
13725 self.write(", ");
13726 }
13727 self.generate_identifier(&attr.name)?;
13728 self.write_space();
13729 self.generate_data_type(&attr.data_type)?;
13730 if let Some(collate) = &attr.collate {
13731 self.write_space();
13732 self.write_keyword("COLLATE");
13733 self.write_space();
13734 self.generate_identifier(collate)?;
13735 }
13736 }
13737 self.write(")");
13738 }
13739 TypeDefinition::Range {
13740 subtype,
13741 subtype_diff,
13742 canonical,
13743 } => {
13744 self.write_keyword("RANGE");
13745 self.write(" (");
13746 self.write_keyword("SUBTYPE");
13747 self.write(" = ");
13748 self.generate_data_type(subtype)?;
13749 if let Some(diff) = subtype_diff {
13750 self.write(", ");
13751 self.write_keyword("SUBTYPE_DIFF");
13752 self.write(" = ");
13753 self.write(diff);
13754 }
13755 if let Some(canon) = canonical {
13756 self.write(", ");
13757 self.write_keyword("CANONICAL");
13758 self.write(" = ");
13759 self.write(canon);
13760 }
13761 self.write(")");
13762 }
13763 TypeDefinition::Base {
13764 input,
13765 output,
13766 internallength,
13767 } => {
13768 self.write("(");
13769 self.write_keyword("INPUT");
13770 self.write(" = ");
13771 self.write(input);
13772 self.write(", ");
13773 self.write_keyword("OUTPUT");
13774 self.write(" = ");
13775 self.write(output);
13776 if let Some(len) = internallength {
13777 self.write(", ");
13778 self.write_keyword("INTERNALLENGTH");
13779 self.write(" = ");
13780 self.write(&len.to_string());
13781 }
13782 self.write(")");
13783 }
13784 TypeDefinition::Domain {
13785 base_type,
13786 default,
13787 constraints,
13788 } => {
13789 self.generate_data_type(base_type)?;
13790 if let Some(def) = default {
13791 self.write_space();
13792 self.write_keyword("DEFAULT");
13793 self.write_space();
13794 self.generate_expression(def)?;
13795 }
13796 for constr in constraints {
13797 self.write_space();
13798 if let Some(name) = &constr.name {
13799 self.write_keyword("CONSTRAINT");
13800 self.write_space();
13801 self.generate_identifier(name)?;
13802 self.write_space();
13803 }
13804 self.write_keyword("CHECK");
13805 self.write(" (");
13806 self.generate_expression(&constr.check)?;
13807 self.write(")");
13808 }
13809 }
13810 }
13811
13812 Ok(())
13813 }
13814
13815 fn generate_create_task(&mut self, task: &crate::expressions::CreateTask) -> Result<()> {
13816 self.write_keyword("CREATE");
13817 if task.or_replace {
13818 self.write_space();
13819 self.write_keyword("OR REPLACE");
13820 }
13821 self.write_space();
13822 self.write_keyword("TASK");
13823 if task.if_not_exists {
13824 self.write_space();
13825 self.write_keyword("IF NOT EXISTS");
13826 }
13827 self.write_space();
13828 self.write(&task.name);
13829 if !task.properties.is_empty() {
13830 if !task.properties.starts_with('\n') && !task.properties.starts_with(' ') {
13832 self.write_space();
13833 }
13834 self.write(&task.properties);
13835 }
13836 self.write_space();
13837 self.write_keyword("AS");
13838 self.write_space();
13839 self.generate_expression(&task.body)?;
13840 Ok(())
13841 }
13842
13843 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
13844 self.write_keyword("DROP TYPE");
13845
13846 if dt.if_exists {
13847 self.write_space();
13848 self.write_keyword("IF EXISTS");
13849 }
13850
13851 self.write_space();
13852 self.generate_table(&dt.name)?;
13853
13854 if dt.cascade {
13855 self.write_space();
13856 self.write_keyword("CASCADE");
13857 }
13858
13859 Ok(())
13860 }
13861
13862 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
13863 let saved_athena_hive_context = self.athena_hive_context;
13865 if matches!(
13866 self.config.dialect,
13867 Some(crate::dialects::DialectType::Athena)
13868 ) {
13869 self.athena_hive_context = true;
13870 }
13871
13872 for comment in &d.leading_comments {
13874 self.write_formatted_comment(comment);
13875 self.write(" ");
13876 }
13877
13878 self.write_keyword("DESCRIBE");
13879
13880 if d.extended {
13881 self.write_space();
13882 self.write_keyword("EXTENDED");
13883 } else if d.formatted {
13884 self.write_space();
13885 self.write_keyword("FORMATTED");
13886 }
13887
13888 if let Some(ref style) = d.style {
13890 self.write_space();
13891 self.write_keyword(style);
13892 }
13893
13894 let should_output_kind = match self.config.dialect {
13896 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
13898 false
13899 }
13900 Some(DialectType::Snowflake) => true,
13902 _ => d.kind.is_some(),
13903 };
13904 if should_output_kind {
13905 if let Some(ref kind) = d.kind {
13906 self.write_space();
13907 self.write_keyword(kind);
13908 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
13909 self.write_space();
13910 self.write_keyword("TABLE");
13911 }
13912 }
13913
13914 self.write_space();
13915 self.generate_expression(&d.target)?;
13916
13917 if !d.params.is_empty() {
13919 self.write("(");
13920 for (i, param) in d.params.iter().enumerate() {
13921 if i > 0 {
13922 self.write(", ");
13923 }
13924 self.write(param);
13925 }
13926 self.write(")");
13927 }
13928
13929 if let Some(ref partition) = d.partition {
13931 self.write_space();
13932 self.generate_expression(partition)?;
13933 }
13934
13935 if d.as_json {
13937 self.write_space();
13938 self.write_keyword("AS JSON");
13939 }
13940
13941 for (name, value) in &d.properties {
13943 self.write_space();
13944 self.write(name);
13945 self.write("=");
13946 self.write(value);
13947 }
13948
13949 self.athena_hive_context = saved_athena_hive_context;
13951
13952 Ok(())
13953 }
13954
13955 fn generate_show(&mut self, s: &Show) -> Result<()> {
13958 self.write_keyword("SHOW");
13959 self.write_space();
13960
13961 let show_terse = s.terse
13964 && !matches!(
13965 s.this.as_str(),
13966 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
13967 );
13968 if show_terse {
13969 self.write_keyword("TERSE");
13970 self.write_space();
13971 }
13972
13973 self.write_keyword(&s.this);
13975
13976 if let Some(ref target_expr) = s.target {
13978 self.write_space();
13979 self.generate_expression(target_expr)?;
13980 }
13981
13982 if s.history {
13984 self.write_space();
13985 self.write_keyword("HISTORY");
13986 }
13987
13988 if let Some(ref for_target) = s.for_target {
13990 self.write_space();
13991 self.write_keyword("FOR");
13992 self.write_space();
13993 self.generate_expression(for_target)?;
13994 }
13995
13996 use crate::dialects::DialectType;
14000 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
14001
14002 if !is_snowflake && s.from.is_some() {
14003 if let Some(ref scope_kind) = s.scope_kind {
14007 self.write_space();
14008 self.write_keyword("IN");
14009 self.write_space();
14010 self.write_keyword(scope_kind);
14011 if let Some(ref scope) = s.scope {
14012 self.write_space();
14013 self.generate_expression(scope)?;
14014 }
14015 } else if let Some(ref scope) = s.scope {
14016 self.write_space();
14017 self.write_keyword("IN");
14018 self.write_space();
14019 self.generate_expression(scope)?;
14020 }
14021
14022 if let Some(ref from) = s.from {
14024 self.write_space();
14025 self.write_keyword("FROM");
14026 self.write_space();
14027 self.generate_expression(from)?;
14028 }
14029
14030 if let Some(ref db) = s.db {
14032 self.write_space();
14033 self.write_keyword("FROM");
14034 self.write_space();
14035 self.generate_expression(db)?;
14036 }
14037
14038 if let Some(ref like) = s.like {
14040 self.write_space();
14041 self.write_keyword("LIKE");
14042 self.write_space();
14043 self.generate_expression(like)?;
14044 }
14045 } else {
14046 if let Some(ref like) = s.like {
14050 self.write_space();
14051 self.write_keyword("LIKE");
14052 self.write_space();
14053 self.generate_expression(like)?;
14054 }
14055
14056 if let Some(ref scope_kind) = s.scope_kind {
14058 self.write_space();
14059 self.write_keyword("IN");
14060 self.write_space();
14061 self.write_keyword(scope_kind);
14062 if let Some(ref scope) = s.scope {
14063 self.write_space();
14064 self.generate_expression(scope)?;
14065 }
14066 } else if let Some(ref scope) = s.scope {
14067 self.write_space();
14068 self.write_keyword("IN");
14069 self.write_space();
14070 self.generate_expression(scope)?;
14071 }
14072 }
14073
14074 if let Some(ref starts_with) = s.starts_with {
14076 self.write_space();
14077 self.write_keyword("STARTS WITH");
14078 self.write_space();
14079 self.generate_expression(starts_with)?;
14080 }
14081
14082 if let Some(ref limit) = s.limit {
14084 self.write_space();
14085 self.generate_limit(limit)?;
14086 }
14087
14088 if is_snowflake {
14090 if let Some(ref from) = s.from {
14091 self.write_space();
14092 self.write_keyword("FROM");
14093 self.write_space();
14094 self.generate_expression(from)?;
14095 }
14096 }
14097
14098 if let Some(ref where_clause) = s.where_clause {
14100 self.write_space();
14101 self.write_keyword("WHERE");
14102 self.write_space();
14103 self.generate_expression(where_clause)?;
14104 }
14105
14106 if let Some(is_mutex) = s.mutex {
14108 self.write_space();
14109 if is_mutex {
14110 self.write_keyword("MUTEX");
14111 } else {
14112 self.write_keyword("STATUS");
14113 }
14114 }
14115
14116 if !s.privileges.is_empty() {
14118 self.write_space();
14119 self.write_keyword("WITH PRIVILEGES");
14120 self.write_space();
14121 for (i, priv_name) in s.privileges.iter().enumerate() {
14122 if i > 0 {
14123 self.write(", ");
14124 }
14125 self.write_keyword(priv_name);
14126 }
14127 }
14128
14129 Ok(())
14130 }
14131
14132 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
14135 use crate::dialects::DialectType;
14136 match lit {
14137 Literal::String(s) => {
14138 self.generate_string_literal(s)?;
14139 }
14140 Literal::Number(n) => {
14141 if matches!(self.config.dialect, Some(DialectType::MySQL))
14142 && n.len() > 2
14143 && (n.starts_with("0x") || n.starts_with("0X"))
14144 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
14145 {
14146 return self.generate_identifier(&Identifier {
14147 name: n.clone(),
14148 quoted: true,
14149 trailing_comments: Vec::new(),
14150 span: None,
14151 });
14152 }
14153 let n = if n.contains('_')
14157 && !matches!(
14158 self.config.dialect,
14159 Some(DialectType::ClickHouse)
14160 | Some(DialectType::DuckDB)
14161 | Some(DialectType::PostgreSQL)
14162 | Some(DialectType::Hive)
14163 | Some(DialectType::Spark)
14164 | Some(DialectType::Databricks)
14165 ) {
14166 std::borrow::Cow::Owned(n.replace('_', ""))
14167 } else {
14168 std::borrow::Cow::Borrowed(n.as_str())
14169 };
14170 if n.starts_with('.') {
14173 self.write("0");
14174 self.write(&n);
14175 } else if n.starts_with("-.") {
14176 self.write("-0");
14178 self.write(&n[1..]);
14179 } else {
14180 self.write(&n);
14181 }
14182 }
14183 Literal::HexString(h) => {
14184 match self.config.dialect {
14186 Some(DialectType::Spark)
14187 | Some(DialectType::Databricks)
14188 | Some(DialectType::Teradata) => self.write("X'"),
14189 _ => self.write("x'"),
14190 }
14191 self.write(h);
14192 self.write("'");
14193 }
14194 Literal::HexNumber(h) => {
14195 match self.config.dialect {
14199 Some(DialectType::BigQuery)
14200 | Some(DialectType::TSQL)
14201 | Some(DialectType::Fabric) => {
14202 self.write("0x");
14203 self.write(h);
14204 }
14205 _ => {
14206 if let Ok(val) = u64::from_str_radix(h, 16) {
14208 self.write(&val.to_string());
14209 } else {
14210 self.write("0x");
14212 self.write(h);
14213 }
14214 }
14215 }
14216 }
14217 Literal::BitString(b) => {
14218 self.write("B'");
14220 self.write(b);
14221 self.write("'");
14222 }
14223 Literal::ByteString(b) => {
14224 self.write("b'");
14226 self.write_escaped_byte_string(b);
14228 self.write("'");
14229 }
14230 Literal::NationalString(s) => {
14231 let keep_n_prefix = matches!(
14234 self.config.dialect,
14235 Some(DialectType::TSQL)
14236 | Some(DialectType::Oracle)
14237 | Some(DialectType::MySQL)
14238 | None
14239 );
14240 if keep_n_prefix {
14241 self.write("N'");
14242 } else {
14243 self.write("'");
14244 }
14245 self.write(s);
14246 self.write("'");
14247 }
14248 Literal::Date(d) => {
14249 self.generate_date_literal(d)?;
14250 }
14251 Literal::Time(t) => {
14252 self.generate_time_literal(t)?;
14253 }
14254 Literal::Timestamp(ts) => {
14255 self.generate_timestamp_literal(ts)?;
14256 }
14257 Literal::Datetime(dt) => {
14258 self.generate_datetime_literal(dt)?;
14259 }
14260 Literal::TripleQuotedString(s, _quote_char) => {
14261 if matches!(
14263 self.config.dialect,
14264 Some(crate::dialects::DialectType::BigQuery)
14265 | Some(crate::dialects::DialectType::DuckDB)
14266 | Some(crate::dialects::DialectType::Snowflake)
14267 | Some(crate::dialects::DialectType::Spark)
14268 | Some(crate::dialects::DialectType::Hive)
14269 | Some(crate::dialects::DialectType::Presto)
14270 | Some(crate::dialects::DialectType::Trino)
14271 | Some(crate::dialects::DialectType::PostgreSQL)
14272 | Some(crate::dialects::DialectType::MySQL)
14273 | Some(crate::dialects::DialectType::Redshift)
14274 | Some(crate::dialects::DialectType::TSQL)
14275 | Some(crate::dialects::DialectType::Oracle)
14276 | Some(crate::dialects::DialectType::ClickHouse)
14277 | Some(crate::dialects::DialectType::Databricks)
14278 | Some(crate::dialects::DialectType::SQLite)
14279 ) {
14280 self.generate_string_literal(s)?;
14281 } else {
14282 let quotes = format!("{0}{0}{0}", _quote_char);
14284 self.write("es);
14285 self.write(s);
14286 self.write("es);
14287 }
14288 }
14289 Literal::EscapeString(s) => {
14290 use crate::dialects::DialectType;
14294 let content = if let Some(c) = s.strip_prefix("e:") {
14295 c
14296 } else if let Some(c) = s.strip_prefix("E:") {
14297 c
14298 } else {
14299 s.as_str()
14300 };
14301
14302 if matches!(
14304 self.config.dialect,
14305 Some(DialectType::MySQL) | Some(DialectType::TiDB)
14306 ) {
14307 self.write(content);
14308 } else {
14309 let prefix = if matches!(
14311 self.config.dialect,
14312 Some(DialectType::SingleStore)
14313 | Some(DialectType::DuckDB)
14314 | Some(DialectType::PostgreSQL)
14315 | Some(DialectType::CockroachDB)
14316 | Some(DialectType::Materialize)
14317 | Some(DialectType::RisingWave)
14318 ) {
14319 "e'"
14320 } else {
14321 "E'"
14322 };
14323
14324 let normalized = content.replace("\\'", "''");
14326 self.write(prefix);
14327 self.write(&normalized);
14328 self.write("'");
14329 }
14330 }
14331 Literal::DollarString(s) => {
14332 use crate::dialects::DialectType;
14335 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
14337 let escape_backslash = matches!(self.config.dialect, Some(DialectType::Snowflake));
14339 let use_backslash_quote =
14343 matches!(self.config.dialect, Some(DialectType::Snowflake));
14344
14345 let mut escaped = String::with_capacity(content.len() + 4);
14346 for ch in content.chars() {
14347 if escape_backslash && ch == '\\' {
14348 escaped.push('\\');
14350 escaped.push('\\');
14351 } else if ch == '\'' {
14352 if use_backslash_quote {
14353 escaped.push('\\');
14354 escaped.push('\'');
14355 } else {
14356 escaped.push('\'');
14357 escaped.push('\'');
14358 }
14359 } else {
14360 escaped.push(ch);
14361 }
14362 }
14363 self.write("'");
14364 self.write(&escaped);
14365 self.write("'");
14366 }
14367 Literal::RawString(s) => {
14368 use crate::dialects::DialectType;
14374
14375 let escape_backslash = matches!(
14377 self.config.dialect,
14378 Some(DialectType::BigQuery)
14379 | Some(DialectType::MySQL)
14380 | Some(DialectType::SingleStore)
14381 | Some(DialectType::TiDB)
14382 | Some(DialectType::Hive)
14383 | Some(DialectType::Spark)
14384 | Some(DialectType::Databricks)
14385 | Some(DialectType::Drill)
14386 | Some(DialectType::Snowflake)
14387 | Some(DialectType::Redshift)
14388 | Some(DialectType::ClickHouse)
14389 );
14390
14391 let backslash_escapes_quote = matches!(
14394 self.config.dialect,
14395 Some(DialectType::BigQuery)
14396 | Some(DialectType::Hive)
14397 | Some(DialectType::Spark)
14398 | Some(DialectType::Databricks)
14399 | Some(DialectType::Drill)
14400 | Some(DialectType::Snowflake)
14401 | Some(DialectType::Redshift)
14402 );
14403
14404 let supports_escape_sequences = escape_backslash;
14407
14408 let mut escaped = String::with_capacity(s.len() + 4);
14409 for ch in s.chars() {
14410 if escape_backslash && ch == '\\' {
14411 escaped.push('\\');
14413 escaped.push('\\');
14414 } else if ch == '\'' {
14415 if backslash_escapes_quote {
14416 escaped.push('\\');
14418 escaped.push('\'');
14419 } else {
14420 escaped.push('\'');
14422 escaped.push('\'');
14423 }
14424 } else if supports_escape_sequences {
14425 match ch {
14428 '\n' => {
14429 escaped.push('\\');
14430 escaped.push('n');
14431 }
14432 '\r' => {
14433 escaped.push('\\');
14434 escaped.push('r');
14435 }
14436 '\t' => {
14437 escaped.push('\\');
14438 escaped.push('t');
14439 }
14440 '\x07' => {
14441 escaped.push('\\');
14442 escaped.push('a');
14443 }
14444 '\x08' => {
14445 escaped.push('\\');
14446 escaped.push('b');
14447 }
14448 '\x0C' => {
14449 escaped.push('\\');
14450 escaped.push('f');
14451 }
14452 '\x0B' => {
14453 escaped.push('\\');
14454 escaped.push('v');
14455 }
14456 _ => escaped.push(ch),
14457 }
14458 } else {
14459 escaped.push(ch);
14460 }
14461 }
14462 self.write("'");
14463 self.write(&escaped);
14464 self.write("'");
14465 }
14466 }
14467 Ok(())
14468 }
14469
14470 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
14472 use crate::dialects::DialectType;
14473
14474 match self.config.dialect {
14475 Some(DialectType::TSQL) => {
14477 self.write("CAST('");
14478 self.write(d);
14479 self.write("' AS DATE)");
14480 }
14481 Some(DialectType::BigQuery) => {
14484 self.write("CAST('");
14485 self.write(d);
14486 self.write("' AS DATE)");
14487 }
14488 Some(DialectType::Exasol) => {
14491 self.write("CAST('");
14492 self.write(d);
14493 self.write("' AS DATE)");
14494 }
14495 Some(DialectType::Snowflake) => {
14498 self.write("CAST('");
14499 self.write(d);
14500 self.write("' AS DATE)");
14501 }
14502 Some(DialectType::PostgreSQL)
14504 | Some(DialectType::MySQL)
14505 | Some(DialectType::SingleStore)
14506 | Some(DialectType::TiDB)
14507 | Some(DialectType::Redshift) => {
14508 self.write("CAST('");
14509 self.write(d);
14510 self.write("' AS DATE)");
14511 }
14512 Some(DialectType::DuckDB)
14514 | Some(DialectType::Presto)
14515 | Some(DialectType::Trino)
14516 | Some(DialectType::Athena)
14517 | Some(DialectType::Spark)
14518 | Some(DialectType::Databricks)
14519 | Some(DialectType::Hive) => {
14520 self.write("CAST('");
14521 self.write(d);
14522 self.write("' AS DATE)");
14523 }
14524 Some(DialectType::Oracle) => {
14526 self.write("TO_DATE('");
14527 self.write(d);
14528 self.write("', 'YYYY-MM-DD')");
14529 }
14530 _ => {
14532 self.write_keyword("DATE");
14533 self.write(" '");
14534 self.write(d);
14535 self.write("'");
14536 }
14537 }
14538 Ok(())
14539 }
14540
14541 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
14543 use crate::dialects::DialectType;
14544
14545 match self.config.dialect {
14546 Some(DialectType::TSQL) => {
14548 self.write("CAST('");
14549 self.write(t);
14550 self.write("' AS TIME)");
14551 }
14552 _ => {
14554 self.write_keyword("TIME");
14555 self.write(" '");
14556 self.write(t);
14557 self.write("'");
14558 }
14559 }
14560 Ok(())
14561 }
14562
14563 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
14565 use crate::expressions::Literal;
14566
14567 match expr {
14568 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
14569 let Literal::Date(d) = lit.as_ref() else {
14570 unreachable!()
14571 };
14572 self.write("CAST('");
14574 self.write(d);
14575 self.write("' AS DATE)");
14576 }
14577 _ => {
14578 self.generate_expression(expr)?;
14580 }
14581 }
14582 Ok(())
14583 }
14584
14585 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
14587 use crate::dialects::DialectType;
14588
14589 match self.config.dialect {
14590 Some(DialectType::TSQL) => {
14592 self.write("CAST('");
14593 self.write(ts);
14594 self.write("' AS DATETIME2)");
14595 }
14596 Some(DialectType::BigQuery) => {
14599 self.write("CAST('");
14600 self.write(ts);
14601 self.write("' AS TIMESTAMP)");
14602 }
14603 Some(DialectType::Snowflake) => {
14606 self.write("CAST('");
14607 self.write(ts);
14608 self.write("' AS TIMESTAMP)");
14609 }
14610 Some(DialectType::Dremio) => {
14613 self.write("CAST('");
14614 self.write(ts);
14615 self.write("' AS TIMESTAMP)");
14616 }
14617 Some(DialectType::Exasol) => {
14620 self.write("CAST('");
14621 self.write(ts);
14622 self.write("' AS TIMESTAMP)");
14623 }
14624 Some(DialectType::Oracle) => {
14627 self.write("TO_TIMESTAMP('");
14628 self.write(ts);
14629 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
14630 }
14631 Some(DialectType::Presto) | Some(DialectType::Trino) => {
14633 if Self::timestamp_has_timezone(ts) {
14634 self.write("CAST('");
14635 self.write(ts);
14636 self.write("' AS TIMESTAMP WITH TIME ZONE)");
14637 } else {
14638 self.write("CAST('");
14639 self.write(ts);
14640 self.write("' AS TIMESTAMP)");
14641 }
14642 }
14643 Some(DialectType::ClickHouse) => {
14645 self.write("CAST('");
14646 self.write(ts);
14647 self.write("' AS Nullable(DateTime))");
14648 }
14649 Some(DialectType::Spark) => {
14651 self.write("CAST('");
14652 self.write(ts);
14653 self.write("' AS TIMESTAMP)");
14654 }
14655 Some(DialectType::Redshift) => {
14658 if ts == "epoch" {
14659 self.write_keyword("TIMESTAMP");
14660 self.write(" '");
14661 self.write(ts);
14662 self.write("'");
14663 } else {
14664 self.write("CAST('");
14665 self.write(ts);
14666 self.write("' AS TIMESTAMP)");
14667 }
14668 }
14669 Some(DialectType::PostgreSQL)
14671 | Some(DialectType::Hive)
14672 | Some(DialectType::SQLite)
14673 | Some(DialectType::DuckDB)
14674 | Some(DialectType::Athena)
14675 | Some(DialectType::Drill)
14676 | Some(DialectType::Teradata) => {
14677 self.write("CAST('");
14678 self.write(ts);
14679 self.write("' AS TIMESTAMP)");
14680 }
14681 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
14683 self.write("CAST('");
14684 self.write(ts);
14685 self.write("' AS DATETIME)");
14686 }
14687 Some(DialectType::Databricks) => {
14689 self.write("CAST('");
14690 self.write(ts);
14691 self.write("' AS TIMESTAMP_NTZ)");
14692 }
14693 _ => {
14695 self.write_keyword("TIMESTAMP");
14696 self.write(" '");
14697 self.write(ts);
14698 self.write("'");
14699 }
14700 }
14701 Ok(())
14702 }
14703
14704 fn timestamp_has_timezone(ts: &str) -> bool {
14707 let ts_lower = ts.to_ascii_lowercase();
14711
14712 let continent_prefixes = [
14714 "africa/",
14715 "america/",
14716 "antarctica/",
14717 "arctic/",
14718 "asia/",
14719 "atlantic/",
14720 "australia/",
14721 "europe/",
14722 "indian/",
14723 "pacific/",
14724 "etc/",
14725 "brazil/",
14726 "canada/",
14727 "chile/",
14728 "mexico/",
14729 "us/",
14730 ];
14731
14732 for prefix in &continent_prefixes {
14733 if ts_lower.contains(prefix) {
14734 return true;
14735 }
14736 }
14737
14738 let tz_abbrevs = [
14741 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
14742 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
14743 " sgt", " aest", " aedt", " acst", " acdt", " awst",
14744 ];
14745
14746 for abbrev in &tz_abbrevs {
14747 if ts_lower.ends_with(abbrev) {
14748 return true;
14749 }
14750 }
14751
14752 let trimmed = ts.trim();
14756 if let Some(last_space) = trimmed.rfind(' ') {
14757 let suffix = &trimmed[last_space + 1..];
14758 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
14759 let rest = &suffix[1..];
14761 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
14762 return true;
14763 }
14764 }
14765 }
14766
14767 false
14768 }
14769
14770 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
14772 use crate::dialects::DialectType;
14773
14774 match self.config.dialect {
14775 Some(DialectType::BigQuery) => {
14778 self.write("CAST('");
14779 self.write(dt);
14780 self.write("' AS DATETIME)");
14781 }
14782 Some(DialectType::DuckDB) => {
14784 self.write("CAST('");
14785 self.write(dt);
14786 self.write("' AS TIMESTAMP)");
14787 }
14788 _ => {
14791 self.write_keyword("DATETIME");
14792 self.write(" '");
14793 self.write(dt);
14794 self.write("'");
14795 }
14796 }
14797 Ok(())
14798 }
14799
14800 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
14802 use crate::dialects::DialectType;
14803
14804 match self.config.dialect {
14805 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
14809 self.write("'");
14811 for c in s.chars() {
14812 match c {
14813 '\'' => self.write("\\'"),
14814 '\\' => self.write("\\\\"),
14815 '\n' => self.write("\\n"),
14816 '\r' => self.write("\\r"),
14817 '\t' => self.write("\\t"),
14818 '\0' => self.write("\\0"),
14819 _ => self.output.push(c),
14820 }
14821 }
14822 self.write("'");
14823 }
14824 Some(DialectType::Drill) => {
14825 self.write("'");
14828 for c in s.chars() {
14829 match c {
14830 '\'' => self.write("''"),
14831 '\\' => self.write("\\\\"),
14832 '\n' => self.write("\\n"),
14833 '\r' => self.write("\\r"),
14834 '\t' => self.write("\\t"),
14835 '\0' => self.write("\\0"),
14836 _ => self.output.push(c),
14837 }
14838 }
14839 self.write("'");
14840 }
14841 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
14842 self.write("'");
14843 for c in s.chars() {
14844 match c {
14845 '\'' => self.write("''"),
14847 '\\' => self.write("\\\\"),
14848 '\n' => self.write("\\n"),
14849 '\r' => self.write("\\r"),
14850 '\t' => self.write("\\t"),
14851 '\0' => self.output.push('\0'),
14853 _ => self.output.push(c),
14854 }
14855 }
14856 self.write("'");
14857 }
14858 Some(DialectType::BigQuery) => {
14860 self.write("'");
14861 for c in s.chars() {
14862 match c {
14863 '\'' => self.write("\\'"),
14864 '\\' => self.write("\\\\"),
14865 '\n' => self.write("\\n"),
14866 '\r' => self.write("\\r"),
14867 '\t' => self.write("\\t"),
14868 '\0' => self.write("\\0"),
14869 '\x07' => self.write("\\a"),
14870 '\x08' => self.write("\\b"),
14871 '\x0C' => self.write("\\f"),
14872 '\x0B' => self.write("\\v"),
14873 _ => self.output.push(c),
14874 }
14875 }
14876 self.write("'");
14877 }
14878 Some(DialectType::Athena) => {
14882 if self.athena_hive_context {
14883 self.write("'");
14885 for c in s.chars() {
14886 match c {
14887 '\'' => self.write("\\'"),
14888 '\\' => self.write("\\\\"),
14889 '\n' => self.write("\\n"),
14890 '\r' => self.write("\\r"),
14891 '\t' => self.write("\\t"),
14892 '\0' => self.write("\\0"),
14893 _ => self.output.push(c),
14894 }
14895 }
14896 self.write("'");
14897 } else {
14898 self.write("'");
14900 for c in s.chars() {
14901 match c {
14902 '\'' => self.write("''"),
14903 _ => self.output.push(c),
14905 }
14906 }
14907 self.write("'");
14908 }
14909 }
14910 Some(DialectType::Snowflake) => {
14915 self.write("'");
14916 for c in s.chars() {
14917 match c {
14918 '\'' => self.write("\\'"),
14919 '\n' => self.write("\\n"),
14922 '\r' => self.write("\\r"),
14923 '\t' => self.write("\\t"),
14924 _ => self.output.push(c),
14925 }
14926 }
14927 self.write("'");
14928 }
14929 Some(DialectType::PostgreSQL) => {
14931 self.write("'");
14932 for c in s.chars() {
14933 match c {
14934 '\'' => self.write("''"),
14935 _ => self.output.push(c),
14936 }
14937 }
14938 self.write("'");
14939 }
14940 Some(DialectType::Redshift) => {
14942 self.write("'");
14943 for c in s.chars() {
14944 match c {
14945 '\'' => self.write("\\'"),
14946 _ => self.output.push(c),
14947 }
14948 }
14949 self.write("'");
14950 }
14951 Some(DialectType::Oracle) => {
14953 self.write("'");
14954 for ch in s.chars() {
14955 if ch == '\'' {
14956 self.output.push_str("''");
14957 } else {
14958 self.output.push(ch);
14959 }
14960 }
14961 self.write("'");
14962 }
14963 Some(DialectType::ClickHouse) => {
14966 self.write("'");
14967 for c in s.chars() {
14968 match c {
14969 '\'' => self.write("''"),
14970 '\\' => self.write("\\\\"),
14971 '\n' => self.write("\\n"),
14972 '\r' => self.write("\\r"),
14973 '\t' => self.write("\\t"),
14974 '\0' => self.write("\\0"),
14975 '\x07' => self.write("\\a"),
14976 '\x08' => self.write("\\b"),
14977 '\x0C' => self.write("\\f"),
14978 '\x0B' => self.write("\\v"),
14979 c if c.is_control() || (c as u32) < 0x20 => {
14981 let byte = c as u32;
14982 if byte < 256 {
14983 self.write(&format!("\\x{:02X}", byte));
14984 } else {
14985 self.output.push(c);
14986 }
14987 }
14988 _ => self.output.push(c),
14989 }
14990 }
14991 self.write("'");
14992 }
14993 _ => {
14996 self.write("'");
14997 for ch in s.chars() {
14998 if ch == '\'' {
14999 self.output.push_str("''");
15000 } else {
15001 self.output.push(ch);
15002 }
15003 }
15004 self.write("'");
15005 }
15006 }
15007 Ok(())
15008 }
15009
15010 fn write_escaped_byte_string(&mut self, s: &str) {
15013 for c in s.chars() {
15014 match c {
15015 '\'' => self.write("\\'"),
15017 '\\' => self.write("\\\\"),
15019 _ if !c.is_control() => self.output.push(c),
15021 _ => {
15023 let byte = c as u32;
15024 if byte < 256 {
15025 self.write(&format!("\\x{:02x}", byte));
15026 } else {
15027 for b in c.to_string().as_bytes() {
15029 self.write(&format!("\\x{:02x}", b));
15030 }
15031 }
15032 }
15033 }
15034 }
15035 }
15036
15037 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
15038 use crate::dialects::DialectType;
15039
15040 match self.config.dialect {
15042 Some(DialectType::TSQL) => {
15045 self.write(if b.value { "1" } else { "0" });
15046 }
15047 Some(DialectType::Oracle) => {
15049 self.write(if b.value { "1" } else { "0" });
15050 }
15051 Some(DialectType::MySQL) => {
15053 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15054 }
15055 _ => {
15057 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15058 }
15059 }
15060 Ok(())
15061 }
15062
15063 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
15066 let name = &id.name;
15067 let quote_style = &self.config.identifier_quote_style;
15068
15069 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
15073
15074 let output_name = if self.config.normalize_identifiers && !id.quoted {
15076 name.to_ascii_lowercase()
15077 } else {
15078 name.to_string()
15079 };
15080
15081 if needs_quoting {
15082 let escaped_name = if quote_style.start == quote_style.end {
15084 output_name.replace(
15085 quote_style.end,
15086 &format!("{}{}", quote_style.end, quote_style.end),
15087 )
15088 } else {
15089 output_name.replace(
15090 quote_style.end,
15091 &format!("{}{}", quote_style.end, quote_style.end),
15092 )
15093 };
15094 self.write(&format!(
15095 "{}{}{}",
15096 quote_style.start, escaped_name, quote_style.end
15097 ));
15098 } else {
15099 self.write(&output_name);
15100 }
15101
15102 for comment in &id.trailing_comments {
15104 self.write(" ");
15105 self.write_formatted_comment(comment);
15106 }
15107 Ok(())
15108 }
15109
15110 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
15111 use crate::dialects::DialectType;
15112
15113 let name = &id.name;
15114
15115 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
15117 && self.athena_hive_context
15118 {
15119 &IdentifierQuoteStyle::BACKTICK
15120 } else {
15121 &self.config.identifier_quote_style
15122 };
15123
15124 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
15131 let needs_digit_quoting = starts_with_digit
15132 && !self.config.identifiers_can_start_with_digit
15133 && self.config.dialect.is_some();
15134 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
15135 && name.len() > 2
15136 && (name.starts_with("0x") || name.starts_with("0X"))
15137 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
15138 let needs_quoting = id.quoted
15139 || self.is_reserved_keyword(name)
15140 || self.config.always_quote_identifiers
15141 || needs_digit_quoting
15142 || mysql_invalid_hex_identifier;
15143
15144 let (base_name, suffix) = if needs_quoting {
15147 if let Some(paren_pos) = name.find('(') {
15149 let base = &name[..paren_pos];
15150 let rest = &name[paren_pos..];
15151 if rest.starts_with('(')
15153 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
15154 {
15155 let close_paren = rest.find(')').unwrap_or(rest.len());
15157 let inside = &rest[1..close_paren];
15158 if inside.chars().all(|c| c.is_ascii_digit()) {
15159 (base.to_string(), rest.to_string())
15160 } else {
15161 (name.to_string(), String::new())
15162 }
15163 } else {
15164 (name.to_string(), String::new())
15165 }
15166 } else if name.ends_with(" ASC") {
15167 let base = &name[..name.len() - 4];
15168 (base.to_string(), " ASC".to_string())
15169 } else if name.ends_with(" DESC") {
15170 let base = &name[..name.len() - 5];
15171 (base.to_string(), " DESC".to_string())
15172 } else {
15173 (name.to_string(), String::new())
15174 }
15175 } else {
15176 (name.to_string(), String::new())
15177 };
15178
15179 let output_name = if self.config.normalize_identifiers && !id.quoted {
15183 base_name.to_ascii_lowercase()
15184 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
15185 && !id.quoted
15186 && self.is_reserved_keyword(name)
15187 {
15188 base_name.to_ascii_uppercase()
15191 } else {
15192 base_name
15193 };
15194
15195 if needs_quoting {
15196 let escaped_name = if quote_style.start == quote_style.end {
15198 output_name.replace(
15200 quote_style.end,
15201 &format!("{}{}", quote_style.end, quote_style.end),
15202 )
15203 } else {
15204 output_name.replace(
15206 quote_style.end,
15207 &format!("{}{}", quote_style.end, quote_style.end),
15208 )
15209 };
15210 self.write(&format!(
15211 "{}{}{}{}",
15212 quote_style.start, escaped_name, quote_style.end, suffix
15213 ));
15214 } else {
15215 self.write(&output_name);
15216 }
15217
15218 for comment in &id.trailing_comments {
15220 self.write(" ");
15221 self.write_formatted_comment(comment);
15222 }
15223 Ok(())
15224 }
15225
15226 fn generate_column(&mut self, col: &Column) -> Result<()> {
15227 use crate::dialects::DialectType;
15228
15229 if let Some(table) = &col.table {
15230 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
15234 && !table.quoted
15235 && table.name.eq_ignore_ascii_case("LOCAL");
15236
15237 if is_exasol_local_prefix {
15238 self.write("LOCAL");
15240 } else {
15241 self.generate_identifier(table)?;
15242 }
15243 self.write(".");
15244 }
15245 self.generate_identifier(&col.name)?;
15246 if col.join_mark && self.config.supports_column_join_marks {
15249 self.write(" (+)");
15250 }
15251 for comment in &col.trailing_comments {
15253 self.write_space();
15254 self.write_formatted_comment(comment);
15255 }
15256 Ok(())
15257 }
15258
15259 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
15262 use crate::dialects::DialectType;
15263 use crate::expressions::PseudocolumnType;
15264
15265 if pc.kind == PseudocolumnType::Sysdate
15267 && !matches!(
15268 self.config.dialect,
15269 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
15270 )
15271 {
15272 self.write_keyword("CURRENT_TIMESTAMP");
15273 if matches!(
15275 self.config.dialect,
15276 Some(DialectType::MySQL)
15277 | Some(DialectType::ClickHouse)
15278 | Some(DialectType::Spark)
15279 | Some(DialectType::Databricks)
15280 | Some(DialectType::Hive)
15281 ) {
15282 self.write("()");
15283 }
15284 } else {
15285 self.write(pc.kind.as_str());
15286 }
15287 Ok(())
15288 }
15289
15290 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
15292 use crate::dialects::DialectType;
15293
15294 let supports_connect_by = matches!(
15297 self.config.dialect,
15298 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
15299 );
15300
15301 if !supports_connect_by && self.config.dialect.is_some() {
15302 if self.config.pretty {
15304 self.write_newline();
15305 } else {
15306 self.write_space();
15307 }
15308 self.write_unsupported_comment(
15309 "CONNECT BY requires manual conversion to recursive CTE",
15310 )?;
15311 }
15312
15313 if let Some(start) = &connect.start {
15315 if self.config.pretty {
15316 self.write_newline();
15317 } else {
15318 self.write_space();
15319 }
15320 self.write_keyword("START WITH");
15321 self.write_space();
15322 self.generate_expression(start)?;
15323 }
15324
15325 if self.config.pretty {
15327 self.write_newline();
15328 } else {
15329 self.write_space();
15330 }
15331 self.write_keyword("CONNECT BY");
15332 if connect.nocycle {
15333 self.write_space();
15334 self.write_keyword("NOCYCLE");
15335 }
15336 self.write_space();
15337 self.generate_expression(&connect.connect)?;
15338
15339 Ok(())
15340 }
15341
15342 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
15344 self.generate_connect(connect)
15345 }
15346
15347 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
15349 self.write_keyword("PRIOR");
15350 self.write_space();
15351 self.generate_expression(&prior.this)?;
15352 Ok(())
15353 }
15354
15355 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
15358 self.write_keyword("CONNECT_BY_ROOT");
15359 self.write_space();
15360 self.generate_expression(&cbr.this)?;
15361 Ok(())
15362 }
15363
15364 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
15366 use crate::dialects::DialectType;
15367
15368 let supports_match_recognize = matches!(
15370 self.config.dialect,
15371 Some(DialectType::Oracle)
15372 | Some(DialectType::Snowflake)
15373 | Some(DialectType::Presto)
15374 | Some(DialectType::Trino)
15375 );
15376
15377 if let Some(source) = &mr.this {
15379 self.generate_expression(source)?;
15380 }
15381
15382 if !supports_match_recognize {
15383 self.write_unsupported_comment("MATCH_RECOGNIZE not supported in this dialect")?;
15384 return Ok(());
15385 }
15386
15387 if self.config.pretty {
15389 self.write_newline();
15390 } else {
15391 self.write_space();
15392 }
15393
15394 self.write_keyword("MATCH_RECOGNIZE");
15395 self.write(" (");
15396
15397 if self.config.pretty {
15398 self.indent_level += 1;
15399 }
15400
15401 let mut needs_separator = false;
15402
15403 if let Some(partition_by) = &mr.partition_by {
15405 if !partition_by.is_empty() {
15406 if self.config.pretty {
15407 self.write_newline();
15408 self.write_indent();
15409 }
15410 self.write_keyword("PARTITION BY");
15411 self.write_space();
15412 for (i, expr) in partition_by.iter().enumerate() {
15413 if i > 0 {
15414 self.write(", ");
15415 }
15416 self.generate_expression(expr)?;
15417 }
15418 needs_separator = true;
15419 }
15420 }
15421
15422 if let Some(order_by) = &mr.order_by {
15424 if !order_by.is_empty() {
15425 if needs_separator {
15426 if self.config.pretty {
15427 self.write_newline();
15428 self.write_indent();
15429 } else {
15430 self.write_space();
15431 }
15432 } else if self.config.pretty {
15433 self.write_newline();
15434 self.write_indent();
15435 }
15436 self.write_keyword("ORDER BY");
15437 if self.config.pretty {
15439 self.indent_level += 1;
15440 for (i, ordered) in order_by.iter().enumerate() {
15441 if i > 0 {
15442 self.write(",");
15443 }
15444 self.write_newline();
15445 self.write_indent();
15446 self.generate_ordered(ordered)?;
15447 }
15448 self.indent_level -= 1;
15449 } else {
15450 self.write_space();
15451 for (i, ordered) in order_by.iter().enumerate() {
15452 if i > 0 {
15453 self.write(", ");
15454 }
15455 self.generate_ordered(ordered)?;
15456 }
15457 }
15458 needs_separator = true;
15459 }
15460 }
15461
15462 if let Some(measures) = &mr.measures {
15464 if !measures.is_empty() {
15465 if needs_separator {
15466 if self.config.pretty {
15467 self.write_newline();
15468 self.write_indent();
15469 } else {
15470 self.write_space();
15471 }
15472 } else if self.config.pretty {
15473 self.write_newline();
15474 self.write_indent();
15475 }
15476 self.write_keyword("MEASURES");
15477 if self.config.pretty {
15479 self.indent_level += 1;
15480 for (i, measure) in measures.iter().enumerate() {
15481 if i > 0 {
15482 self.write(",");
15483 }
15484 self.write_newline();
15485 self.write_indent();
15486 if let Some(semantics) = &measure.window_frame {
15488 match semantics {
15489 MatchRecognizeSemantics::Running => {
15490 self.write_keyword("RUNNING");
15491 self.write_space();
15492 }
15493 MatchRecognizeSemantics::Final => {
15494 self.write_keyword("FINAL");
15495 self.write_space();
15496 }
15497 }
15498 }
15499 self.generate_expression(&measure.this)?;
15500 }
15501 self.indent_level -= 1;
15502 } else {
15503 self.write_space();
15504 for (i, measure) in measures.iter().enumerate() {
15505 if i > 0 {
15506 self.write(", ");
15507 }
15508 if let Some(semantics) = &measure.window_frame {
15510 match semantics {
15511 MatchRecognizeSemantics::Running => {
15512 self.write_keyword("RUNNING");
15513 self.write_space();
15514 }
15515 MatchRecognizeSemantics::Final => {
15516 self.write_keyword("FINAL");
15517 self.write_space();
15518 }
15519 }
15520 }
15521 self.generate_expression(&measure.this)?;
15522 }
15523 }
15524 needs_separator = true;
15525 }
15526 }
15527
15528 if let Some(rows) = &mr.rows {
15530 if needs_separator {
15531 if self.config.pretty {
15532 self.write_newline();
15533 self.write_indent();
15534 } else {
15535 self.write_space();
15536 }
15537 } else if self.config.pretty {
15538 self.write_newline();
15539 self.write_indent();
15540 }
15541 match rows {
15542 MatchRecognizeRows::OneRowPerMatch => {
15543 self.write_keyword("ONE ROW PER MATCH");
15544 }
15545 MatchRecognizeRows::AllRowsPerMatch => {
15546 self.write_keyword("ALL ROWS PER MATCH");
15547 }
15548 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
15549 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
15550 }
15551 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
15552 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
15553 }
15554 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
15555 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
15556 }
15557 }
15558 needs_separator = true;
15559 }
15560
15561 if let Some(after) = &mr.after {
15563 if needs_separator {
15564 if self.config.pretty {
15565 self.write_newline();
15566 self.write_indent();
15567 } else {
15568 self.write_space();
15569 }
15570 } else if self.config.pretty {
15571 self.write_newline();
15572 self.write_indent();
15573 }
15574 match after {
15575 MatchRecognizeAfter::PastLastRow => {
15576 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
15577 }
15578 MatchRecognizeAfter::ToNextRow => {
15579 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
15580 }
15581 MatchRecognizeAfter::ToFirst(ident) => {
15582 self.write_keyword("AFTER MATCH SKIP TO FIRST");
15583 self.write_space();
15584 self.generate_identifier(ident)?;
15585 }
15586 MatchRecognizeAfter::ToLast(ident) => {
15587 self.write_keyword("AFTER MATCH SKIP TO LAST");
15588 self.write_space();
15589 self.generate_identifier(ident)?;
15590 }
15591 }
15592 needs_separator = true;
15593 }
15594
15595 if let Some(pattern) = &mr.pattern {
15597 if needs_separator {
15598 if self.config.pretty {
15599 self.write_newline();
15600 self.write_indent();
15601 } else {
15602 self.write_space();
15603 }
15604 } else if self.config.pretty {
15605 self.write_newline();
15606 self.write_indent();
15607 }
15608 self.write_keyword("PATTERN");
15609 self.write_space();
15610 self.write("(");
15611 self.write(pattern);
15612 self.write(")");
15613 needs_separator = true;
15614 }
15615
15616 if let Some(define) = &mr.define {
15618 if !define.is_empty() {
15619 if needs_separator {
15620 if self.config.pretty {
15621 self.write_newline();
15622 self.write_indent();
15623 } else {
15624 self.write_space();
15625 }
15626 } else if self.config.pretty {
15627 self.write_newline();
15628 self.write_indent();
15629 }
15630 self.write_keyword("DEFINE");
15631 if self.config.pretty {
15633 self.indent_level += 1;
15634 for (i, (name, expr)) in define.iter().enumerate() {
15635 if i > 0 {
15636 self.write(",");
15637 }
15638 self.write_newline();
15639 self.write_indent();
15640 self.generate_identifier(name)?;
15641 self.write(" AS ");
15642 self.generate_expression(expr)?;
15643 }
15644 self.indent_level -= 1;
15645 } else {
15646 self.write_space();
15647 for (i, (name, expr)) in define.iter().enumerate() {
15648 if i > 0 {
15649 self.write(", ");
15650 }
15651 self.generate_identifier(name)?;
15652 self.write(" AS ");
15653 self.generate_expression(expr)?;
15654 }
15655 }
15656 }
15657 }
15658
15659 if self.config.pretty {
15660 self.indent_level -= 1;
15661 self.write_newline();
15662 }
15663 self.write(")");
15664
15665 if let Some(alias) = &mr.alias {
15667 self.write(" ");
15668 if mr.alias_explicit_as {
15669 self.write_keyword("AS");
15670 self.write(" ");
15671 }
15672 self.generate_identifier(alias)?;
15673 }
15674
15675 Ok(())
15676 }
15677
15678 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
15680 use crate::dialects::DialectType;
15681
15682 let supports_hints = matches!(
15684 self.config.dialect,
15685 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
15687 Some(DialectType::Spark) | Some(DialectType::Hive) |
15688 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
15689 );
15690
15691 if !supports_hints || hint.expressions.is_empty() {
15692 return Ok(());
15693 }
15694
15695 let mut hint_strings: Vec<String> = Vec::new();
15698 for expr in &hint.expressions {
15699 match expr {
15700 HintExpression::Raw(text) => {
15701 let parsed = self.parse_raw_hint_text(text);
15703 hint_strings.extend(parsed);
15704 }
15705 _ => {
15706 hint_strings.push(self.hint_expression_to_string(expr)?);
15707 }
15708 }
15709 }
15710
15711 let use_multiline = self.config.pretty && hint_strings.len() > 1;
15715
15716 if use_multiline {
15717 self.write(" /*+ ");
15719 for (i, hint_str) in hint_strings.iter().enumerate() {
15720 if i > 0 {
15721 self.write_newline();
15722 self.write(" "); }
15724 self.write(hint_str);
15725 }
15726 self.write(" */");
15727 } else {
15728 self.write(" /*+ ");
15730 let sep = match self.config.dialect {
15731 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
15732 _ => " ",
15733 };
15734 for (i, hint_str) in hint_strings.iter().enumerate() {
15735 if i > 0 {
15736 self.write(sep);
15737 }
15738 self.write(hint_str);
15739 }
15740 self.write(" */");
15741 }
15742
15743 Ok(())
15744 }
15745
15746 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
15750 let mut results = Vec::new();
15751 let mut chars = text.chars().peekable();
15752 let mut current = String::new();
15753 let mut paren_depth = 0;
15754 let mut has_unparseable_content = false;
15755 let mut position_after_last_function = 0;
15756 let mut char_position = 0;
15757
15758 while let Some(c) = chars.next() {
15759 char_position += c.len_utf8();
15760 match c {
15761 '(' => {
15762 paren_depth += 1;
15763 current.push(c);
15764 }
15765 ')' => {
15766 paren_depth -= 1;
15767 current.push(c);
15768 if paren_depth == 0 {
15770 let trimmed = current.trim().to_string();
15771 if !trimmed.is_empty() {
15772 let formatted = self.format_hint_function(&trimmed);
15774 results.push(formatted);
15775 }
15776 current.clear();
15777 position_after_last_function = char_position;
15778 }
15779 }
15780 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
15781 }
15783 _ if paren_depth == 0 => {
15784 current.push(c);
15786 }
15787 _ => {
15788 current.push(c);
15789 }
15790 }
15791 }
15792
15793 let remaining_text = text[position_after_last_function..].trim();
15795 if !remaining_text.is_empty() {
15796 let words: Vec<&str> = remaining_text.split_whitespace().collect();
15800 let looks_like_hint_functions = words.iter().all(|word| {
15801 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
15803 });
15804
15805 if !looks_like_hint_functions && words.len() > 1 {
15806 has_unparseable_content = true;
15807 }
15808 }
15809
15810 if has_unparseable_content {
15812 return vec![text.trim().to_string()];
15813 }
15814
15815 if results.is_empty() {
15817 results.push(text.trim().to_string());
15818 }
15819
15820 results
15821 }
15822
15823 fn format_hint_function(&self, hint: &str) -> String {
15826 if !self.config.pretty {
15827 return hint.to_string();
15828 }
15829
15830 if let Some(paren_pos) = hint.find('(') {
15832 if hint.ends_with(')') {
15833 let name = &hint[..paren_pos];
15834 let args_str = &hint[paren_pos + 1..hint.len() - 1];
15835
15836 let args: Vec<&str> = args_str.split_whitespace().collect();
15838
15839 let total_args_width: usize =
15841 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() {
15845 let mut result = format!("{}(\n", name);
15846 for arg in &args {
15847 result.push_str(" "); result.push_str(arg);
15849 result.push('\n');
15850 }
15851 result.push_str(" )"); return result;
15853 }
15854 }
15855 }
15856
15857 hint.to_string()
15858 }
15859
15860 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
15862 match expr {
15863 HintExpression::Function { name, args } => {
15864 let arg_strings: Vec<String> = args
15866 .iter()
15867 .map(|arg| {
15868 let mut gen = Generator::with_arc_config(self.config.clone());
15869 gen.generate_expression(arg)?;
15870 Ok(gen.output)
15871 })
15872 .collect::<Result<Vec<_>>>()?;
15873
15874 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
15876 + arg_strings.len().saturating_sub(1); let args_multiline =
15881 self.config.pretty && total_args_width > self.config.max_text_width;
15882
15883 if args_multiline && !arg_strings.is_empty() {
15884 let mut result = format!("{}(\n", name);
15886 for arg_str in &arg_strings {
15887 result.push_str(" "); result.push_str(arg_str);
15889 result.push('\n');
15890 }
15891 result.push_str(" )"); Ok(result)
15893 } else {
15894 let args_str = arg_strings.join(" ");
15896 Ok(format!("{}({})", name, args_str))
15897 }
15898 }
15899 HintExpression::Identifier(name) => Ok(name.clone()),
15900 HintExpression::Raw(text) => {
15901 if self.config.pretty {
15903 Ok(self.format_hint_function(text))
15904 } else {
15905 Ok(text.clone())
15906 }
15907 }
15908 }
15909 }
15910
15911 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
15912 if table.only {
15914 self.write_keyword("ONLY");
15915 self.write_space();
15916 }
15917
15918 if let Some(ref identifier_func) = table.identifier_func {
15920 self.generate_expression(identifier_func)?;
15921 if !table.name.name.is_empty() {
15923 if let Some(catalog) = &table.catalog {
15924 self.write(".");
15925 self.generate_identifier(catalog)?;
15926 }
15927 if let Some(schema) = &table.schema {
15928 self.write(".");
15929 self.generate_identifier(schema)?;
15930 }
15931 self.write(".");
15932 self.generate_identifier(&table.name)?;
15933 }
15934 } else {
15935 if let Some(catalog) = &table.catalog {
15936 self.generate_identifier(catalog)?;
15937 self.write(".");
15938 }
15939 if let Some(schema) = &table.schema {
15940 self.generate_identifier(schema)?;
15941 self.write(".");
15942 }
15943 self.generate_identifier(&table.name)?;
15944 }
15945
15946 if let Some(changes) = &table.changes {
15948 self.write(" ");
15949 self.generate_changes(changes)?;
15950 }
15951
15952 if !table.partitions.is_empty() {
15954 self.write_space();
15955 self.write_keyword("PARTITION");
15956 self.write("(");
15957 for (i, partition) in table.partitions.iter().enumerate() {
15958 if i > 0 {
15959 self.write(", ");
15960 }
15961 self.generate_identifier(partition)?;
15962 }
15963 self.write(")");
15964 }
15965
15966 if table.changes.is_none() {
15969 if let Some(when) = &table.when {
15970 self.write_space();
15971 self.generate_historical_data(when)?;
15972 }
15973 }
15974
15975 let system_time_post_alias = matches!(self.config.dialect, Some(DialectType::BigQuery));
15977 if !system_time_post_alias {
15978 if let Some(ref system_time) = table.system_time {
15979 self.write_space();
15980 self.write(system_time);
15981 }
15982 }
15983
15984 if let Some(ref version) = table.version {
15986 self.write_space();
15987 self.generate_version(version)?;
15988 }
15989
15990 let alias_post_tablesample = self.config.alias_post_tablesample;
15994
15995 if alias_post_tablesample {
15996 self.generate_table_sample_clause(table)?;
15998 }
15999
16000 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
16003 && table.hints.iter().any(|h| {
16004 if let Expression::Identifier(id) = h {
16005 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
16006 } else {
16007 false
16008 }
16009 });
16010 if !table.hints.is_empty() && !is_sqlite_hint {
16011 for hint in &table.hints {
16012 self.write_space();
16013 self.generate_expression(hint)?;
16014 }
16015 }
16016
16017 if let Some(alias) = &table.alias {
16018 self.write_space();
16019 let always_use_as = self.config.dialect.is_none()
16022 || matches!(
16023 self.config.dialect,
16024 Some(DialectType::Generic)
16025 | Some(DialectType::PostgreSQL)
16026 | Some(DialectType::Redshift)
16027 | Some(DialectType::Snowflake)
16028 | Some(DialectType::BigQuery)
16029 | Some(DialectType::DuckDB)
16030 | Some(DialectType::Presto)
16031 | Some(DialectType::Trino)
16032 | Some(DialectType::TSQL)
16033 | Some(DialectType::Fabric)
16034 | Some(DialectType::MySQL)
16035 | Some(DialectType::Spark)
16036 | Some(DialectType::Hive)
16037 | Some(DialectType::SQLite)
16038 | Some(DialectType::Drill)
16039 );
16040 let is_stage_ref = table.name.name.starts_with('@');
16041 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
16043 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
16044 self.write_keyword("AS");
16045 self.write_space();
16046 }
16047 self.generate_identifier(alias)?;
16048
16049 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
16052 self.write("(");
16053 for (i, col_alias) in table.column_aliases.iter().enumerate() {
16054 if i > 0 {
16055 self.write(", ");
16056 }
16057 self.generate_identifier(col_alias)?;
16058 }
16059 self.write(")");
16060 }
16061 }
16062
16063 if system_time_post_alias {
16065 if let Some(ref system_time) = table.system_time {
16066 self.write_space();
16067 self.write(system_time);
16068 }
16069 }
16070
16071 if !alias_post_tablesample {
16073 self.generate_table_sample_clause(table)?;
16074 }
16075
16076 if is_sqlite_hint {
16078 for hint in &table.hints {
16079 self.write_space();
16080 self.generate_expression(hint)?;
16081 }
16082 }
16083
16084 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
16086 self.write_space();
16087 self.write_keyword("FINAL");
16088 }
16089
16090 for comment in &table.trailing_comments {
16092 self.write_space();
16093 self.write_formatted_comment(comment);
16094 }
16095 Ok(())
16099 }
16100
16101 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
16103 if let Some(ref ts) = table.table_sample {
16104 self.write_space();
16105 if ts.is_using_sample {
16106 self.write_keyword("USING SAMPLE");
16107 } else {
16108 self.write_keyword(self.config.tablesample_keywords);
16110 }
16111 self.generate_sample_body(ts)?;
16112 if let Some(ref seed) = ts.seed {
16114 self.write_space();
16115 self.write_keyword(self.config.tablesample_seed_keyword);
16116 self.write(" (");
16117 self.generate_expression(seed)?;
16118 self.write(")");
16119 }
16120 }
16121 Ok(())
16122 }
16123
16124 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
16125 if sr.quoted {
16129 self.write("'");
16130 }
16131
16132 self.write(&sr.name);
16133 if let Some(path) = &sr.path {
16134 self.write(path);
16135 }
16136
16137 if sr.quoted {
16138 self.write("'");
16139 }
16140
16141 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
16143 if has_options {
16144 self.write(" (");
16145 let mut first = true;
16146
16147 if let Some(file_format) = &sr.file_format {
16148 if !first {
16149 self.write(", ");
16150 }
16151 self.write_keyword("FILE_FORMAT");
16152 self.write(" => ");
16153 self.generate_expression(file_format)?;
16154 first = false;
16155 }
16156
16157 if let Some(pattern) = &sr.pattern {
16158 if !first {
16159 self.write(", ");
16160 }
16161 self.write_keyword("PATTERN");
16162 self.write(" => '");
16163 self.write(pattern);
16164 self.write("'");
16165 }
16166
16167 self.write(")");
16168 }
16169 Ok(())
16170 }
16171
16172 fn generate_star(&mut self, star: &Star) -> Result<()> {
16173 use crate::dialects::DialectType;
16174
16175 if let Some(table) = &star.table {
16176 self.generate_identifier(table)?;
16177 self.write(".");
16178 }
16179 self.write("*");
16180
16181 if let Some(except) = &star.except {
16183 if !except.is_empty() {
16184 self.write_space();
16185 match self.config.dialect {
16187 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
16188 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
16189 self.write_keyword("EXCLUDE")
16190 }
16191 _ => self.write_keyword("EXCEPT"), }
16193 self.write(" (");
16194 for (i, col) in except.iter().enumerate() {
16195 if i > 0 {
16196 self.write(", ");
16197 }
16198 self.generate_identifier(col)?;
16199 }
16200 self.write(")");
16201 }
16202 }
16203
16204 if let Some(replace) = &star.replace {
16206 if !replace.is_empty() {
16207 self.write_space();
16208 self.write_keyword("REPLACE");
16209 self.write(" (");
16210 for (i, alias) in replace.iter().enumerate() {
16211 if i > 0 {
16212 self.write(", ");
16213 }
16214 self.generate_expression(&alias.this)?;
16215 self.write_space();
16216 self.write_keyword("AS");
16217 self.write_space();
16218 self.generate_identifier(&alias.alias)?;
16219 }
16220 self.write(")");
16221 }
16222 }
16223
16224 if let Some(rename) = &star.rename {
16226 if !rename.is_empty() {
16227 self.write_space();
16228 self.write_keyword("RENAME");
16229 self.write(" (");
16230 for (i, (old_name, new_name)) in rename.iter().enumerate() {
16231 if i > 0 {
16232 self.write(", ");
16233 }
16234 self.generate_identifier(old_name)?;
16235 self.write_space();
16236 self.write_keyword("AS");
16237 self.write_space();
16238 self.generate_identifier(new_name)?;
16239 }
16240 self.write(")");
16241 }
16242 }
16243
16244 for comment in &star.trailing_comments {
16246 self.write_space();
16247 self.write_formatted_comment(comment);
16248 }
16249
16250 Ok(())
16251 }
16252
16253 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
16255 self.write("{");
16256 match expr {
16257 Expression::Star(star) => {
16258 self.generate_star(star)?;
16260 }
16261 Expression::ILike(ilike) => {
16262 self.generate_expression(&ilike.left)?;
16264 self.write_space();
16265 self.write_keyword("ILIKE");
16266 self.write_space();
16267 self.generate_expression(&ilike.right)?;
16268 }
16269 _ => {
16270 self.generate_expression(expr)?;
16271 }
16272 }
16273 self.write("}");
16274 Ok(())
16275 }
16276
16277 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
16278 match &alias.this {
16282 Expression::Column(col) => {
16283 if let Some(table) = &col.table {
16285 self.generate_identifier(table)?;
16286 self.write(".");
16287 }
16288 self.generate_identifier(&col.name)?;
16289 }
16290 _ => {
16291 self.generate_expression(&alias.this)?;
16292 }
16293 }
16294
16295 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
16299 for comment in &alias.pre_alias_comments {
16300 self.write_space();
16301 self.write_formatted_comment(comment);
16302 }
16303 }
16304
16305 use crate::dialects::DialectType;
16306
16307 let is_table_source = matches!(
16313 &alias.this,
16314 Expression::JSONTable(_)
16315 | Expression::XMLTable(_)
16316 | Expression::TableFromRows(_)
16317 | Expression::Unnest(_)
16318 | Expression::MatchRecognize(_)
16319 | Expression::Select(_)
16320 | Expression::Subquery(_)
16321 | Expression::Paren(_)
16322 );
16323 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
16324 let skip_as = is_table_source && dialect_skips_table_alias_as;
16325
16326 self.write_space();
16327 if !skip_as {
16328 self.write_keyword("AS");
16329 self.write_space();
16330 }
16331
16332 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
16334
16335 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
16337 self.write("(");
16339 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16340 if i > 0 {
16341 self.write(", ");
16342 }
16343 self.generate_alias_identifier(col_alias)?;
16344 }
16345 self.write(")");
16346 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
16347 self.generate_alias_identifier(&alias.alias)?;
16349 self.write("(");
16350 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16351 if i > 0 {
16352 self.write(", ");
16353 }
16354 self.generate_alias_identifier(col_alias)?;
16355 }
16356 self.write(")");
16357 } else {
16358 self.generate_alias_identifier(&alias.alias)?;
16360 }
16361
16362 for comment in &alias.trailing_comments {
16364 self.write_space();
16365 self.write_formatted_comment(comment);
16366 }
16367
16368 if alias.trailing_comments.is_empty() {
16373 for comment in &alias.pre_alias_comments {
16374 self.write_space();
16375 self.write_formatted_comment(comment);
16376 }
16377 }
16378
16379 Ok(())
16380 }
16381
16382 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
16383 use crate::dialects::DialectType;
16384
16385 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
16387 self.generate_expression(&cast.this)?;
16388 self.write(" :> ");
16389 self.generate_data_type(&cast.to)?;
16390 return Ok(());
16391 }
16392
16393 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
16395 let is_unknown_type = matches!(cast.to, DataType::Unknown)
16396 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
16397 if is_unknown_type {
16398 if let Some(format) = &cast.format {
16399 self.write_keyword("CAST");
16400 self.write("(");
16401 self.generate_expression(&cast.this)?;
16402 self.write_space();
16403 self.write_keyword("AS");
16404 self.write_space();
16405 self.write_keyword("FORMAT");
16406 self.write_space();
16407 self.generate_expression(format)?;
16408 self.write(")");
16409 return Ok(());
16410 }
16411 }
16412 }
16413
16414 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
16417 if let Some(format) = &cast.format {
16418 let is_date = matches!(cast.to, DataType::Date);
16420 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
16421
16422 if is_date || is_timestamp {
16423 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
16424 self.write_keyword(func_name);
16425 self.write("(");
16426 self.generate_expression(&cast.this)?;
16427 self.write(", ");
16428
16429 if let Expression::Literal(lit) = format.as_ref() {
16432 if let Literal::String(fmt_str) = lit.as_ref() {
16433 let normalized = self.normalize_oracle_format(fmt_str);
16434 self.write("'");
16435 self.write(&normalized);
16436 self.write("'");
16437 }
16438 } else {
16439 self.generate_expression(format)?;
16440 }
16441
16442 self.write(")");
16443 return Ok(());
16444 }
16445 }
16446 }
16447
16448 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
16451 if let Expression::Array(arr) = &cast.this {
16452 self.generate_data_type(&cast.to)?;
16453 self.write("[");
16455 for (i, expr) in arr.expressions.iter().enumerate() {
16456 if i > 0 {
16457 self.write(", ");
16458 }
16459 self.generate_expression(expr)?;
16460 }
16461 self.write("]");
16462 return Ok(());
16463 }
16464 if matches!(&cast.this, Expression::ArrayFunc(_)) {
16465 self.generate_data_type(&cast.to)?;
16466 self.generate_expression(&cast.this)?;
16467 return Ok(());
16468 }
16469 }
16470
16471 if matches!(
16474 self.config.dialect,
16475 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
16476 ) {
16477 if let Expression::Struct(ref s) = cast.this {
16478 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
16479 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
16480 self.write_keyword("CAST");
16481 self.write("(");
16482 self.generate_struct_as_row(s)?;
16483 self.write_space();
16484 self.write_keyword("AS");
16485 self.write_space();
16486 self.generate_data_type(&cast.to)?;
16487 self.write(")");
16488 return Ok(());
16489 }
16490 }
16491 }
16492
16493 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
16496
16497 if use_double_colon {
16498 self.generate_expression(&cast.this)?;
16500 self.write("::");
16501 self.generate_data_type(&cast.to)?;
16502 } else {
16503 self.write_keyword("CAST");
16505 self.write("(");
16506 self.generate_expression(&cast.this)?;
16507 self.write_space();
16508 self.write_keyword("AS");
16509 self.write_space();
16510 if matches!(
16513 self.config.dialect,
16514 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
16515 ) {
16516 match &cast.to {
16517 DataType::Custom { ref name } => {
16518 if name.eq_ignore_ascii_case("LONGTEXT")
16519 || name.eq_ignore_ascii_case("MEDIUMTEXT")
16520 || name.eq_ignore_ascii_case("TINYTEXT")
16521 || name.eq_ignore_ascii_case("LONGBLOB")
16522 || name.eq_ignore_ascii_case("MEDIUMBLOB")
16523 || name.eq_ignore_ascii_case("TINYBLOB")
16524 {
16525 self.write_keyword("CHAR");
16526 } else {
16527 self.generate_data_type(&cast.to)?;
16528 }
16529 }
16530 DataType::VarChar { length, .. } => {
16531 self.write_keyword("CHAR");
16533 if let Some(n) = length {
16534 self.write(&format!("({})", n));
16535 }
16536 }
16537 DataType::Text => {
16538 self.write_keyword("CHAR");
16540 }
16541 DataType::Timestamp {
16542 precision,
16543 timezone: false,
16544 } => {
16545 self.write_keyword("DATETIME");
16547 if let Some(p) = precision {
16548 self.write(&format!("({})", p));
16549 }
16550 }
16551 _ => {
16552 self.generate_data_type(&cast.to)?;
16553 }
16554 }
16555 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
16556 match &cast.to {
16558 DataType::String { length } => {
16559 self.write_keyword("VARCHAR");
16560 if let Some(n) = length {
16561 self.write(&format!("({})", n));
16562 }
16563 }
16564 _ => {
16565 self.generate_data_type(&cast.to)?;
16566 }
16567 }
16568 } else {
16569 self.generate_data_type(&cast.to)?;
16570 }
16571
16572 if let Some(default) = &cast.default {
16574 self.write_space();
16575 self.write_keyword("DEFAULT");
16576 self.write_space();
16577 self.generate_expression(default)?;
16578 self.write_space();
16579 self.write_keyword("ON");
16580 self.write_space();
16581 self.write_keyword("CONVERSION");
16582 self.write_space();
16583 self.write_keyword("ERROR");
16584 }
16585
16586 if let Some(format) = &cast.format {
16589 if matches!(
16591 self.config.dialect,
16592 Some(crate::dialects::DialectType::Oracle)
16593 ) {
16594 self.write(", ");
16595 } else {
16596 self.write_space();
16597 self.write_keyword("FORMAT");
16598 self.write_space();
16599 }
16600 self.generate_expression(format)?;
16601 }
16602
16603 self.write(")");
16604 for comment in &cast.trailing_comments {
16606 self.write_space();
16607 self.write_formatted_comment(comment);
16608 }
16609 }
16610 Ok(())
16611 }
16612
16613 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
16616 self.write_keyword("ROW");
16617 self.write("(");
16618 for (i, (_, expr)) in s.fields.iter().enumerate() {
16619 if i > 0 {
16620 self.write(", ");
16621 }
16622 if let Expression::Struct(ref inner_s) = expr {
16624 self.generate_struct_as_row(inner_s)?;
16625 } else {
16626 self.generate_expression(expr)?;
16627 }
16628 }
16629 self.write(")");
16630 Ok(())
16631 }
16632
16633 fn normalize_oracle_format(&self, format: &str) -> String {
16636 let mut result = String::new();
16639 let chars: Vec<char> = format.chars().collect();
16640 let mut i = 0;
16641
16642 while i < chars.len() {
16643 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
16644 if i + 2 < chars.len() {
16646 let next = chars[i + 2];
16647 if next == '1' || next == '2' {
16648 result.push('H');
16650 result.push('H');
16651 i += 2;
16652 continue;
16653 }
16654 }
16655 result.push_str("HH12");
16657 i += 2;
16658 } else {
16659 result.push(chars[i]);
16660 i += 1;
16661 }
16662 }
16663
16664 result
16665 }
16666
16667 fn dialect_prefers_double_colon(&self) -> bool {
16671 false
16674 }
16675
16676 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16678 use crate::dialects::DialectType;
16679
16680 let use_percent_operator = matches!(
16682 self.config.dialect,
16683 Some(DialectType::Snowflake)
16684 | Some(DialectType::MySQL)
16685 | Some(DialectType::Presto)
16686 | Some(DialectType::Trino)
16687 | Some(DialectType::PostgreSQL)
16688 | Some(DialectType::DuckDB)
16689 | Some(DialectType::Hive)
16690 | Some(DialectType::Spark)
16691 | Some(DialectType::Databricks)
16692 | Some(DialectType::Athena)
16693 );
16694
16695 if use_percent_operator {
16696 let needs_paren = |e: &Expression| matches!(e, Expression::Add(_) | Expression::Sub(_));
16699 if needs_paren(&f.this) {
16700 self.write("(");
16701 self.generate_expression(&f.this)?;
16702 self.write(")");
16703 } else {
16704 self.generate_expression(&f.this)?;
16705 }
16706 self.write(" % ");
16707 if needs_paren(&f.expression) {
16708 self.write("(");
16709 self.generate_expression(&f.expression)?;
16710 self.write(")");
16711 } else {
16712 self.generate_expression(&f.expression)?;
16713 }
16714 Ok(())
16715 } else {
16716 self.generate_binary_func("MOD", &f.this, &f.expression)
16717 }
16718 }
16719
16720 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16722 use crate::dialects::DialectType;
16723
16724 let func_name = match self.config.dialect {
16726 Some(DialectType::Snowflake) => "COALESCE",
16727 _ => "IFNULL",
16728 };
16729
16730 self.generate_binary_func(func_name, &f.this, &f.expression)
16731 }
16732
16733 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16735 if let Some(ref original_name) = f.original_name {
16737 return self.generate_binary_func(original_name, &f.this, &f.expression);
16738 }
16739
16740 use crate::dialects::DialectType;
16742 let func_name = match self.config.dialect {
16743 Some(DialectType::Snowflake)
16744 | Some(DialectType::ClickHouse)
16745 | Some(DialectType::PostgreSQL)
16746 | Some(DialectType::Presto)
16747 | Some(DialectType::Trino)
16748 | Some(DialectType::Athena)
16749 | Some(DialectType::DuckDB)
16750 | Some(DialectType::BigQuery)
16751 | Some(DialectType::Spark)
16752 | Some(DialectType::Databricks)
16753 | Some(DialectType::Hive) => "COALESCE",
16754 Some(DialectType::MySQL)
16755 | Some(DialectType::Doris)
16756 | Some(DialectType::StarRocks)
16757 | Some(DialectType::SingleStore)
16758 | Some(DialectType::TiDB) => "IFNULL",
16759 _ => "NVL",
16760 };
16761
16762 self.generate_binary_func(func_name, &f.this, &f.expression)
16763 }
16764
16765 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
16767 use crate::dialects::DialectType;
16768
16769 let func_name = match self.config.dialect {
16771 Some(DialectType::Snowflake) => "STDDEV",
16772 _ => "STDDEV_SAMP",
16773 };
16774
16775 self.generate_agg_func(func_name, f)
16776 }
16777
16778 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
16779 self.generate_expression(&coll.this)?;
16780 self.write_space();
16781 self.write_keyword("COLLATE");
16782 self.write_space();
16783 if coll.quoted {
16784 self.write("'");
16786 self.write(&coll.collation);
16787 self.write("'");
16788 } else if coll.double_quoted {
16789 self.write("\"");
16791 self.write(&coll.collation);
16792 self.write("\"");
16793 } else {
16794 self.write(&coll.collation);
16796 }
16797 Ok(())
16798 }
16799
16800 fn generate_case(&mut self, case: &Case) -> Result<()> {
16801 let multiline_case = if self.config.pretty {
16803 let mut statements: Vec<String> = Vec::new();
16805 let operand_str = if let Some(operand) = &case.operand {
16806 let s = self.generate_to_string(operand)?;
16807 statements.push(format!("CASE {}", s));
16808 s
16809 } else {
16810 statements.push("CASE".to_string());
16811 String::new()
16812 };
16813 let _ = operand_str;
16814 for (condition, result) in &case.whens {
16815 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
16816 statements.push(format!("THEN {}", self.generate_to_string(result)?));
16817 }
16818 if let Some(else_) = &case.else_ {
16819 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
16820 }
16821 statements.push("END".to_string());
16822 self.too_wide(&statements)
16823 } else {
16824 false
16825 };
16826
16827 self.write_keyword("CASE");
16828 if let Some(operand) = &case.operand {
16829 self.write_space();
16830 self.generate_expression(operand)?;
16831 }
16832 if multiline_case {
16833 self.indent_level += 1;
16834 }
16835 for (condition, result) in &case.whens {
16836 if multiline_case {
16837 self.write_newline();
16838 self.write_indent();
16839 } else {
16840 self.write_space();
16841 }
16842 self.write_keyword("WHEN");
16843 self.write_space();
16844 self.generate_expression(condition)?;
16845 if multiline_case {
16846 self.write_newline();
16847 self.write_indent();
16848 } else {
16849 self.write_space();
16850 }
16851 self.write_keyword("THEN");
16852 self.write_space();
16853 self.generate_expression(result)?;
16854 }
16855 if let Some(else_) = &case.else_ {
16856 if multiline_case {
16857 self.write_newline();
16858 self.write_indent();
16859 } else {
16860 self.write_space();
16861 }
16862 self.write_keyword("ELSE");
16863 self.write_space();
16864 self.generate_expression(else_)?;
16865 }
16866 if multiline_case {
16867 self.indent_level -= 1;
16868 self.write_newline();
16869 self.write_indent();
16870 } else {
16871 self.write_space();
16872 }
16873 self.write_keyword("END");
16874 for comment in &case.comments {
16876 self.write(" ");
16877 self.write_formatted_comment(comment);
16878 }
16879 Ok(())
16880 }
16881
16882 fn generate_function(&mut self, func: &Function) -> Result<()> {
16883 let normalized_name = self.normalize_func_name(&func.name);
16885
16886 if matches!(self.config.dialect, Some(DialectType::DuckDB))
16888 && func.name.eq_ignore_ascii_case("ARRAY_CONSTRUCT_COMPACT")
16889 {
16890 self.write("LIST_FILTER(");
16891 self.write("[");
16892 for (i, arg) in func.args.iter().enumerate() {
16893 if i > 0 {
16894 self.write(", ");
16895 }
16896 self.generate_expression(arg)?;
16897 }
16898 self.write("], _u -> NOT _u IS NULL)");
16899 return Ok(());
16900 }
16901
16902 if func.name.eq_ignore_ascii_case("STRUCT")
16904 && !matches!(
16905 self.config.dialect,
16906 Some(DialectType::BigQuery)
16907 | Some(DialectType::Spark)
16908 | Some(DialectType::Databricks)
16909 | Some(DialectType::Hive)
16910 | None
16911 )
16912 {
16913 return self.generate_struct_function_cross_dialect(func);
16914 }
16915
16916 if func.name.eq_ignore_ascii_case("__SS_JSON_PATH_QMARK__") && func.args.len() == 2 {
16919 self.generate_expression(&func.args[0])?;
16920 self.write("::?");
16921 if let Expression::Literal(lit) = &func.args[1] {
16923 if let crate::expressions::Literal::String(key) = lit.as_ref() {
16924 self.write(key);
16925 }
16926 } else {
16927 self.generate_expression(&func.args[1])?;
16928 }
16929 return Ok(());
16930 }
16931
16932 if func.name.eq_ignore_ascii_case("__PG_BITWISE_XOR__") && func.args.len() == 2 {
16934 self.generate_expression(&func.args[0])?;
16935 self.write(" # ");
16936 self.generate_expression(&func.args[1])?;
16937 return Ok(());
16938 }
16939
16940 if matches!(
16942 self.config.dialect,
16943 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
16944 ) && func.name.eq_ignore_ascii_case("TRY")
16945 && func.args.len() == 1
16946 {
16947 self.generate_expression(&func.args[0])?;
16948 return Ok(());
16949 }
16950
16951 if self.config.dialect == Some(DialectType::ClickHouse)
16953 && func.name.eq_ignore_ascii_case("TOSTARTOFDAY")
16954 && func.args.len() == 1
16955 {
16956 self.write("dateTrunc('DAY', ");
16957 self.generate_expression(&func.args[0])?;
16958 self.write(")");
16959 return Ok(());
16960 }
16961
16962 if self.config.dialect == Some(DialectType::Redshift)
16964 && func.name.eq_ignore_ascii_case("CONCAT")
16965 && func.args.len() >= 2
16966 {
16967 for (i, arg) in func.args.iter().enumerate() {
16968 if i > 0 {
16969 self.write(" || ");
16970 }
16971 self.generate_expression(arg)?;
16972 }
16973 return Ok(());
16974 }
16975
16976 if self.config.dialect == Some(DialectType::Redshift)
16978 && func.name.eq_ignore_ascii_case("CONCAT_WS")
16979 && func.args.len() >= 2
16980 {
16981 let sep = &func.args[0];
16982 for (i, arg) in func.args.iter().skip(1).enumerate() {
16983 if i > 0 {
16984 self.write(" || ");
16985 self.generate_expression(sep)?;
16986 self.write(" || ");
16987 }
16988 self.generate_expression(arg)?;
16989 }
16990 return Ok(());
16991 }
16992
16993 if self.config.dialect == Some(DialectType::Redshift)
16996 && (func.name.eq_ignore_ascii_case("DATEDIFF")
16997 || func.name.eq_ignore_ascii_case("DATE_DIFF"))
16998 && func.args.len() == 3
16999 {
17000 self.write_keyword("DATEDIFF");
17001 self.write("(");
17002 self.write_redshift_date_part(&func.args[0]);
17004 self.write(", ");
17005 self.generate_expression(&func.args[1])?;
17006 self.write(", ");
17007 self.generate_expression(&func.args[2])?;
17008 self.write(")");
17009 return Ok(());
17010 }
17011
17012 if self.config.dialect == Some(DialectType::Redshift)
17015 && (func.name.eq_ignore_ascii_case("DATEADD")
17016 || func.name.eq_ignore_ascii_case("DATE_ADD"))
17017 && func.args.len() == 3
17018 {
17019 self.write_keyword("DATEADD");
17020 self.write("(");
17021 self.write_redshift_date_part(&func.args[0]);
17023 self.write(", ");
17024 self.generate_expression(&func.args[1])?;
17025 self.write(", ");
17026 self.generate_expression(&func.args[2])?;
17027 self.write(")");
17028 return Ok(());
17029 }
17030
17031 if func.name.eq_ignore_ascii_case("UUID_STRING")
17033 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
17034 {
17035 let func_name = match self.config.dialect {
17036 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
17037 Some(DialectType::BigQuery) => "GENERATE_UUID",
17038 _ => "UUID",
17039 };
17040 self.write_keyword(func_name);
17041 self.write("()");
17042 return Ok(());
17043 }
17044
17045 if matches!(self.config.dialect, Some(DialectType::Snowflake))
17049 && func.name.eq_ignore_ascii_case("GENERATOR")
17050 {
17051 let has_positional_args =
17052 !func.args.is_empty() && !matches!(&func.args[0], Expression::NamedArgument(_));
17053 if has_positional_args {
17054 let param_names = ["ROWCOUNT", "TIMELIMIT"];
17055 self.write_keyword("GENERATOR");
17056 self.write("(");
17057 for (i, arg) in func.args.iter().enumerate() {
17058 if i > 0 {
17059 self.write(", ");
17060 }
17061 if i < param_names.len() {
17062 self.write_keyword(param_names[i]);
17063 self.write(" => ");
17064 self.generate_expression(arg)?;
17065 } else {
17066 self.generate_expression(arg)?;
17067 }
17068 }
17069 self.write(")");
17070 return Ok(());
17071 }
17072 }
17073
17074 if self.config.dialect == Some(DialectType::Redshift)
17077 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
17078 && func.args.len() == 2
17079 {
17080 self.write_keyword("DATE_TRUNC");
17081 self.write("(");
17082 self.write_redshift_date_part_quoted(&func.args[0]);
17084 self.write(", ");
17085 self.generate_expression(&func.args[1])?;
17086 self.write(")");
17087 return Ok(());
17088 }
17089
17090 if matches!(
17092 self.config.dialect,
17093 Some(DialectType::TSQL) | Some(DialectType::Fabric)
17094 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17095 || func.name.eq_ignore_ascii_case("DATEPART"))
17096 && func.args.len() == 2
17097 {
17098 self.write_keyword("DATEPART");
17099 self.write("(");
17100 self.generate_expression(&func.args[0])?;
17101 self.write(", ");
17102 self.generate_expression(&func.args[1])?;
17103 self.write(")");
17104 return Ok(());
17105 }
17106
17107 if matches!(
17109 self.config.dialect,
17110 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
17111 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17112 || func.name.eq_ignore_ascii_case("DATEPART"))
17113 && func.args.len() == 2
17114 {
17115 self.write_keyword("EXTRACT");
17116 self.write("(");
17117 match &func.args[0] {
17119 Expression::Literal(lit)
17120 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
17121 {
17122 let crate::expressions::Literal::String(s) = lit.as_ref() else {
17123 unreachable!()
17124 };
17125 self.write(&s.to_ascii_lowercase());
17126 }
17127 _ => self.generate_expression(&func.args[0])?,
17128 }
17129 self.write_space();
17130 self.write_keyword("FROM");
17131 self.write_space();
17132 self.generate_expression(&func.args[1])?;
17133 self.write(")");
17134 return Ok(());
17135 }
17136
17137 if self.config.dialect == Some(DialectType::Dremio)
17140 && (func.name.eq_ignore_ascii_case("DATE_PART")
17141 || func.name.eq_ignore_ascii_case("DATEPART"))
17142 && func.args.len() == 2
17143 {
17144 self.write_keyword("EXTRACT");
17145 self.write("(");
17146 self.generate_expression(&func.args[0])?;
17147 self.write_space();
17148 self.write_keyword("FROM");
17149 self.write_space();
17150 self.generate_dremio_date_expression(&func.args[1])?;
17152 self.write(")");
17153 return Ok(());
17154 }
17155
17156 if self.config.dialect == Some(DialectType::Dremio)
17158 && func.name.eq_ignore_ascii_case("CURRENT_DATE_UTC")
17159 && func.args.is_empty()
17160 {
17161 self.write_keyword("CURRENT_DATE_UTC");
17162 return Ok(());
17163 }
17164
17165 if self.config.dialect == Some(DialectType::Dremio)
17169 && func.name.eq_ignore_ascii_case("DATETYPE")
17170 && func.args.len() == 3
17171 {
17172 fn get_int_literal(expr: &Expression) -> Option<i64> {
17174 if let Expression::Literal(lit) = expr {
17175 if let crate::expressions::Literal::Number(s) = lit.as_ref() {
17176 s.parse::<i64>().ok()
17177 } else {
17178 None
17179 }
17180 } else {
17181 None
17182 }
17183 }
17184
17185 if let (Some(year), Some(month), Some(day)) = (
17187 get_int_literal(&func.args[0]),
17188 get_int_literal(&func.args[1]),
17189 get_int_literal(&func.args[2]),
17190 ) {
17191 self.write_keyword("DATE");
17193 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
17194 return Ok(());
17195 }
17196
17197 self.write_keyword("CAST");
17199 self.write("(");
17200 self.write_keyword("CONCAT");
17201 self.write("(");
17202 self.generate_expression(&func.args[0])?;
17203 self.write(", '-', ");
17204 self.generate_expression(&func.args[1])?;
17205 self.write(", '-', ");
17206 self.generate_expression(&func.args[2])?;
17207 self.write(")");
17208 self.write_space();
17209 self.write_keyword("AS");
17210 self.write_space();
17211 self.write_keyword("DATE");
17212 self.write(")");
17213 return Ok(());
17214 }
17215
17216 let is_presto_like = matches!(
17219 self.config.dialect,
17220 Some(DialectType::Presto) | Some(DialectType::Trino)
17221 );
17222 if is_presto_like && func.name.eq_ignore_ascii_case("DATE_ADD") && func.args.len() == 3 {
17223 self.write_keyword("DATE_ADD");
17224 self.write("(");
17225 self.generate_expression(&func.args[0])?;
17227 self.write(", ");
17228 let interval = &func.args[1];
17230 let needs_cast = !self.returns_integer_type(interval);
17231 if needs_cast {
17232 self.write_keyword("CAST");
17233 self.write("(");
17234 }
17235 self.generate_expression(interval)?;
17236 if needs_cast {
17237 self.write_space();
17238 self.write_keyword("AS");
17239 self.write_space();
17240 self.write_keyword("BIGINT");
17241 self.write(")");
17242 }
17243 self.write(", ");
17244 self.generate_expression(&func.args[2])?;
17246 self.write(")");
17247 return Ok(());
17248 }
17249
17250 let use_brackets = func.use_bracket_syntax;
17252
17253 let has_ordinality = func.name.len() >= 16
17258 && func.name[func.name.len() - 16..].eq_ignore_ascii_case(" WITH ORDINALITY");
17259 let output_name = if has_ordinality {
17260 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
17261 self.normalize_func_name(base_name)
17262 } else {
17263 normalized_name.clone()
17264 };
17265
17266 if func.name.contains('.') && !has_ordinality {
17269 if func.quoted {
17272 self.write("`");
17273 self.write(&func.name);
17274 self.write("`");
17275 } else {
17276 self.write(&func.name);
17277 }
17278 } else {
17279 self.write(&output_name);
17280 }
17281
17282 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
17285 let needs_parens = if func.name.eq_ignore_ascii_case("CURRENT_USER")
17286 || func.name.eq_ignore_ascii_case("SESSION_USER")
17287 || func.name.eq_ignore_ascii_case("SYSTEM_USER")
17288 {
17289 matches!(
17290 self.config.dialect,
17291 Some(DialectType::Snowflake)
17292 | Some(DialectType::Spark)
17293 | Some(DialectType::Databricks)
17294 | Some(DialectType::Hive)
17295 )
17296 } else {
17297 false
17298 };
17299 !needs_parens
17300 };
17301 if force_parens {
17302 for comment in &func.trailing_comments {
17304 self.write_space();
17305 self.write_formatted_comment(comment);
17306 }
17307 return Ok(());
17308 }
17309
17310 if func.name.eq_ignore_ascii_case("CUBE")
17312 || func.name.eq_ignore_ascii_case("ROLLUP")
17313 || func.name.eq_ignore_ascii_case("GROUPING SETS")
17314 {
17315 self.write(" (");
17316 } else if use_brackets {
17317 self.write("[");
17318 } else {
17319 self.write("(");
17320 }
17321 if func.distinct {
17322 self.write_keyword("DISTINCT");
17323 self.write_space();
17324 }
17325
17326 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
17328 && (func.name.eq_ignore_ascii_case("TABLE")
17329 || func.name.eq_ignore_ascii_case("FLATTEN"));
17330 let is_grouping_func = func.name.eq_ignore_ascii_case("GROUPING SETS")
17332 || func.name.eq_ignore_ascii_case("CUBE")
17333 || func.name.eq_ignore_ascii_case("ROLLUP");
17334 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
17335 if is_grouping_func {
17336 true
17337 } else {
17338 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
17340 for arg in &func.args {
17341 let mut temp_gen = Generator::with_arc_config(self.config.clone());
17342 Arc::make_mut(&mut temp_gen.config).pretty = false; temp_gen.generate_expression(arg)?;
17344 expr_strings.push(temp_gen.output);
17345 }
17346 self.too_wide(&expr_strings)
17347 }
17348 } else {
17349 false
17350 };
17351
17352 if should_split {
17353 self.write_newline();
17355 self.indent_level += 1;
17356 for (i, arg) in func.args.iter().enumerate() {
17357 self.write_indent();
17358 self.generate_expression(arg)?;
17359 if i + 1 < func.args.len() {
17360 self.write(",");
17361 }
17362 self.write_newline();
17363 }
17364 self.indent_level -= 1;
17365 self.write_indent();
17366 } else {
17367 for (i, arg) in func.args.iter().enumerate() {
17369 if i > 0 {
17370 self.write(", ");
17371 }
17372 self.generate_expression(arg)?;
17373 }
17374 }
17375
17376 if use_brackets {
17377 self.write("]");
17378 } else {
17379 self.write(")");
17380 }
17381 if has_ordinality {
17383 self.write_space();
17384 self.write_keyword("WITH ORDINALITY");
17385 }
17386 for comment in &func.trailing_comments {
17388 self.write_space();
17389 self.write_formatted_comment(comment);
17390 }
17391 Ok(())
17392 }
17393
17394 fn generate_function_emits(&mut self, fe: &FunctionEmits) -> Result<()> {
17395 self.generate_expression(&fe.this)?;
17396 self.write_keyword(" EMITS ");
17397 self.generate_expression(&fe.emits)?;
17398 Ok(())
17399 }
17400
17401 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
17402 let mut normalized_name = self.normalize_func_name(&func.name);
17404
17405 if func.name.eq_ignore_ascii_case("MAX_BY") || func.name.eq_ignore_ascii_case("MIN_BY") {
17407 let is_max = func.name.eq_ignore_ascii_case("MAX_BY");
17408 match self.config.dialect {
17409 Some(DialectType::ClickHouse) => {
17410 normalized_name = if is_max {
17411 Cow::Borrowed("argMax")
17412 } else {
17413 Cow::Borrowed("argMin")
17414 };
17415 }
17416 Some(DialectType::DuckDB) => {
17417 normalized_name = if is_max {
17418 Cow::Borrowed("ARG_MAX")
17419 } else {
17420 Cow::Borrowed("ARG_MIN")
17421 };
17422 }
17423 _ => {}
17424 }
17425 }
17426 self.write(normalized_name.as_ref());
17427 self.write("(");
17428 if func.distinct {
17429 self.write_keyword("DISTINCT");
17430 self.write_space();
17431 }
17432
17433 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
17437 let needs_multi_arg_transform =
17438 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
17439
17440 if needs_multi_arg_transform {
17441 self.write_keyword("CASE");
17443 for arg in &func.args {
17444 self.write_space();
17445 self.write_keyword("WHEN");
17446 self.write_space();
17447 self.generate_expression(arg)?;
17448 self.write_space();
17449 self.write_keyword("IS NULL THEN NULL");
17450 }
17451 self.write_space();
17452 self.write_keyword("ELSE");
17453 self.write(" (");
17454 for (i, arg) in func.args.iter().enumerate() {
17455 if i > 0 {
17456 self.write(", ");
17457 }
17458 self.generate_expression(arg)?;
17459 }
17460 self.write(")");
17461 self.write_space();
17462 self.write_keyword("END");
17463 } else {
17464 for (i, arg) in func.args.iter().enumerate() {
17465 if i > 0 {
17466 self.write(", ");
17467 }
17468 self.generate_expression(arg)?;
17469 }
17470 }
17471
17472 if self.config.ignore_nulls_in_func
17474 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
17475 {
17476 if let Some(ignore) = func.ignore_nulls {
17477 self.write_space();
17478 if ignore {
17479 self.write_keyword("IGNORE NULLS");
17480 } else {
17481 self.write_keyword("RESPECT NULLS");
17482 }
17483 }
17484 }
17485
17486 if !func.order_by.is_empty() {
17488 self.write_space();
17489 self.write_keyword("ORDER BY");
17490 self.write_space();
17491 for (i, ord) in func.order_by.iter().enumerate() {
17492 if i > 0 {
17493 self.write(", ");
17494 }
17495 self.generate_ordered(ord)?;
17496 }
17497 }
17498
17499 if let Some(limit) = &func.limit {
17501 self.write_space();
17502 self.write_keyword("LIMIT");
17503 self.write_space();
17504 if let Expression::Tuple(t) = limit.as_ref() {
17506 if t.expressions.len() == 2 {
17507 self.generate_expression(&t.expressions[0])?;
17508 self.write(", ");
17509 self.generate_expression(&t.expressions[1])?;
17510 } else {
17511 self.generate_expression(limit)?;
17512 }
17513 } else {
17514 self.generate_expression(limit)?;
17515 }
17516 }
17517
17518 self.write(")");
17519
17520 if !self.config.ignore_nulls_in_func
17522 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
17523 {
17524 if let Some(ignore) = func.ignore_nulls {
17525 self.write_space();
17526 if ignore {
17527 self.write_keyword("IGNORE NULLS");
17528 } else {
17529 self.write_keyword("RESPECT NULLS");
17530 }
17531 }
17532 }
17533
17534 if let Some(filter) = &func.filter {
17535 self.write_space();
17536 self.write_keyword("FILTER");
17537 self.write("(");
17538 self.write_keyword("WHERE");
17539 self.write_space();
17540 self.generate_expression(filter)?;
17541 self.write(")");
17542 }
17543
17544 Ok(())
17545 }
17546
17547 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
17548 self.generate_expression(&wf.this)?;
17549
17550 if let Some(keep) = &wf.keep {
17552 self.write_space();
17553 self.write_keyword("KEEP");
17554 self.write(" (");
17555 self.write_keyword("DENSE_RANK");
17556 self.write_space();
17557 if keep.first {
17558 self.write_keyword("FIRST");
17559 } else {
17560 self.write_keyword("LAST");
17561 }
17562 self.write_space();
17563 self.write_keyword("ORDER BY");
17564 self.write_space();
17565 for (i, ord) in keep.order_by.iter().enumerate() {
17566 if i > 0 {
17567 self.write(", ");
17568 }
17569 self.generate_ordered(ord)?;
17570 }
17571 self.write(")");
17572 }
17573
17574 let has_over = !wf.over.partition_by.is_empty()
17576 || !wf.over.order_by.is_empty()
17577 || wf.over.frame.is_some()
17578 || wf.over.window_name.is_some();
17579
17580 if has_over {
17582 self.write_space();
17583 self.write_keyword("OVER");
17584
17585 let has_specs = !wf.over.partition_by.is_empty()
17587 || !wf.over.order_by.is_empty()
17588 || wf.over.frame.is_some();
17589
17590 if wf.over.window_name.is_some() && !has_specs {
17591 self.write_space();
17593 self.write(&wf.over.window_name.as_ref().unwrap().name);
17594 } else {
17595 self.write(" (");
17597 self.generate_over(&wf.over)?;
17598 self.write(")");
17599 }
17600 } else if wf.keep.is_none() {
17601 self.write_space();
17603 self.write_keyword("OVER");
17604 self.write(" ()");
17605 }
17606
17607 Ok(())
17608 }
17609
17610 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
17612 self.generate_expression(&wg.this)?;
17613 self.write_space();
17614 self.write_keyword("WITHIN GROUP");
17615 self.write(" (");
17616 self.write_keyword("ORDER BY");
17617 self.write_space();
17618 for (i, ord) in wg.order_by.iter().enumerate() {
17619 if i > 0 {
17620 self.write(", ");
17621 }
17622 self.generate_ordered(ord)?;
17623 }
17624 self.write(")");
17625 Ok(())
17626 }
17627
17628 fn generate_over(&mut self, over: &Over) -> Result<()> {
17630 let mut has_content = false;
17631
17632 if let Some(name) = &over.window_name {
17634 self.write(&name.name);
17635 has_content = true;
17636 }
17637
17638 if !over.partition_by.is_empty() {
17640 if has_content {
17641 self.write_space();
17642 }
17643 self.write_keyword("PARTITION BY");
17644 self.write_space();
17645 for (i, expr) in over.partition_by.iter().enumerate() {
17646 if i > 0 {
17647 self.write(", ");
17648 }
17649 self.generate_expression(expr)?;
17650 }
17651 has_content = true;
17652 }
17653
17654 if !over.order_by.is_empty() {
17656 if has_content {
17657 self.write_space();
17658 }
17659 self.write_keyword("ORDER BY");
17660 self.write_space();
17661 for (i, ordered) in over.order_by.iter().enumerate() {
17662 if i > 0 {
17663 self.write(", ");
17664 }
17665 self.generate_ordered(ordered)?;
17666 }
17667 has_content = true;
17668 }
17669
17670 if let Some(frame) = &over.frame {
17672 if has_content {
17673 self.write_space();
17674 }
17675 self.generate_window_frame(frame)?;
17676 }
17677
17678 Ok(())
17679 }
17680
17681 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
17682 let lowercase_frame = self.config.lowercase_window_frame_keywords;
17684
17685 if !lowercase_frame {
17687 if let Some(kind_text) = &frame.kind_text {
17688 self.write(kind_text);
17689 } else {
17690 match frame.kind {
17691 WindowFrameKind::Rows => self.write_keyword("ROWS"),
17692 WindowFrameKind::Range => self.write_keyword("RANGE"),
17693 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
17694 }
17695 }
17696 } else {
17697 match frame.kind {
17698 WindowFrameKind::Rows => self.write("rows"),
17699 WindowFrameKind::Range => self.write("range"),
17700 WindowFrameKind::Groups => self.write("groups"),
17701 }
17702 }
17703
17704 self.write_space();
17707 let should_normalize = self.config.normalize_window_frame_between
17708 && frame.end.is_none()
17709 && matches!(
17710 frame.start,
17711 WindowFrameBound::Preceding(_)
17712 | WindowFrameBound::Following(_)
17713 | WindowFrameBound::UnboundedPreceding
17714 | WindowFrameBound::UnboundedFollowing
17715 );
17716
17717 if let Some(end) = &frame.end {
17718 self.write_keyword("BETWEEN");
17720 self.write_space();
17721 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
17722 self.write_space();
17723 self.write_keyword("AND");
17724 self.write_space();
17725 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
17726 } else if should_normalize {
17727 self.write_keyword("BETWEEN");
17729 self.write_space();
17730 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
17731 self.write_space();
17732 self.write_keyword("AND");
17733 self.write_space();
17734 self.write_keyword("CURRENT ROW");
17735 } else {
17736 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
17738 }
17739
17740 if let Some(exclude) = &frame.exclude {
17742 self.write_space();
17743 self.write_keyword("EXCLUDE");
17744 self.write_space();
17745 match exclude {
17746 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
17747 WindowFrameExclude::Group => self.write_keyword("GROUP"),
17748 WindowFrameExclude::Ties => self.write_keyword("TIES"),
17749 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
17750 }
17751 }
17752
17753 Ok(())
17754 }
17755
17756 fn generate_window_frame_bound(
17757 &mut self,
17758 bound: &WindowFrameBound,
17759 side_text: Option<&str>,
17760 ) -> Result<()> {
17761 let lowercase_frame = self.config.lowercase_window_frame_keywords;
17763
17764 match bound {
17765 WindowFrameBound::CurrentRow => {
17766 self.write_keyword("CURRENT ROW");
17767 }
17768 WindowFrameBound::UnboundedPreceding => {
17769 self.write_keyword("UNBOUNDED");
17770 self.write_space();
17771 if lowercase_frame {
17772 self.write("preceding");
17773 } else if let Some(text) = side_text {
17774 self.write(text);
17775 } else {
17776 self.write_keyword("PRECEDING");
17777 }
17778 }
17779 WindowFrameBound::UnboundedFollowing => {
17780 self.write_keyword("UNBOUNDED");
17781 self.write_space();
17782 if lowercase_frame {
17783 self.write("following");
17784 } else if let Some(text) = side_text {
17785 self.write(text);
17786 } else {
17787 self.write_keyword("FOLLOWING");
17788 }
17789 }
17790 WindowFrameBound::Preceding(expr) => {
17791 self.generate_expression(expr)?;
17792 self.write_space();
17793 if lowercase_frame {
17794 self.write("preceding");
17795 } else if let Some(text) = side_text {
17796 self.write(text);
17797 } else {
17798 self.write_keyword("PRECEDING");
17799 }
17800 }
17801 WindowFrameBound::Following(expr) => {
17802 self.generate_expression(expr)?;
17803 self.write_space();
17804 if lowercase_frame {
17805 self.write("following");
17806 } else if let Some(text) = side_text {
17807 self.write(text);
17808 } else {
17809 self.write_keyword("FOLLOWING");
17810 }
17811 }
17812 WindowFrameBound::BarePreceding => {
17813 if lowercase_frame {
17814 self.write("preceding");
17815 } else if let Some(text) = side_text {
17816 self.write(text);
17817 } else {
17818 self.write_keyword("PRECEDING");
17819 }
17820 }
17821 WindowFrameBound::BareFollowing => {
17822 if lowercase_frame {
17823 self.write("following");
17824 } else if let Some(text) = side_text {
17825 self.write(text);
17826 } else {
17827 self.write_keyword("FOLLOWING");
17828 }
17829 }
17830 WindowFrameBound::Value(expr) => {
17831 self.generate_expression(expr)?;
17833 }
17834 }
17835 Ok(())
17836 }
17837
17838 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
17839 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
17842 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
17843 && !matches!(&interval.this, Some(Expression::Literal(_)));
17844
17845 if self.config.single_string_interval {
17848 if let (
17849 Some(Expression::Literal(lit)),
17850 Some(IntervalUnitSpec::Simple {
17851 ref unit,
17852 ref use_plural,
17853 }),
17854 ) = (&interval.this, &interval.unit)
17855 {
17856 if let Literal::String(ref val) = lit.as_ref() {
17857 self.write_keyword("INTERVAL");
17858 self.write_space();
17859 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
17860 let unit_str = self.interval_unit_str(unit, effective_plural);
17861 self.write("'");
17862 self.write(val);
17863 self.write(" ");
17864 self.write(&unit_str);
17865 self.write("'");
17866 return Ok(());
17867 }
17868 }
17869 }
17870
17871 if !skip_interval_keyword {
17872 self.write_keyword("INTERVAL");
17873 }
17874
17875 if let Some(ref value) = interval.this {
17877 if !skip_interval_keyword {
17878 self.write_space();
17879 }
17880 let needs_parens = interval.unit.is_some()
17884 && matches!(
17885 value,
17886 Expression::Add(_)
17887 | Expression::Sub(_)
17888 | Expression::Mul(_)
17889 | Expression::Div(_)
17890 | Expression::Mod(_)
17891 | Expression::BitwiseAnd(_)
17892 | Expression::BitwiseOr(_)
17893 | Expression::BitwiseXor(_)
17894 );
17895 if needs_parens {
17896 self.write("(");
17897 }
17898 self.generate_expression(value)?;
17899 if needs_parens {
17900 self.write(")");
17901 }
17902 }
17903
17904 if let Some(ref unit_spec) = interval.unit {
17906 self.write_space();
17907 self.write_interval_unit_spec(unit_spec)?;
17908 }
17909
17910 Ok(())
17911 }
17912
17913 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
17915 match (unit, use_plural) {
17916 (IntervalUnit::Year, false) => "YEAR",
17917 (IntervalUnit::Year, true) => "YEARS",
17918 (IntervalUnit::Quarter, false) => "QUARTER",
17919 (IntervalUnit::Quarter, true) => "QUARTERS",
17920 (IntervalUnit::Month, false) => "MONTH",
17921 (IntervalUnit::Month, true) => "MONTHS",
17922 (IntervalUnit::Week, false) => "WEEK",
17923 (IntervalUnit::Week, true) => "WEEKS",
17924 (IntervalUnit::Day, false) => "DAY",
17925 (IntervalUnit::Day, true) => "DAYS",
17926 (IntervalUnit::Hour, false) => "HOUR",
17927 (IntervalUnit::Hour, true) => "HOURS",
17928 (IntervalUnit::Minute, false) => "MINUTE",
17929 (IntervalUnit::Minute, true) => "MINUTES",
17930 (IntervalUnit::Second, false) => "SECOND",
17931 (IntervalUnit::Second, true) => "SECONDS",
17932 (IntervalUnit::Millisecond, false) => "MILLISECOND",
17933 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
17934 (IntervalUnit::Microsecond, false) => "MICROSECOND",
17935 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
17936 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
17937 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
17938 }
17939 }
17940
17941 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
17942 match unit_spec {
17943 IntervalUnitSpec::Simple { unit, use_plural } => {
17944 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
17946 self.write_simple_interval_unit(unit, effective_plural);
17947 }
17948 IntervalUnitSpec::Span(span) => {
17949 self.write_simple_interval_unit(&span.this, false);
17950 self.write_space();
17951 self.write_keyword("TO");
17952 self.write_space();
17953 self.write_simple_interval_unit(&span.expression, false);
17954 }
17955 IntervalUnitSpec::ExprSpan(span) => {
17956 self.generate_expression(&span.this)?;
17958 self.write_space();
17959 self.write_keyword("TO");
17960 self.write_space();
17961 self.generate_expression(&span.expression)?;
17962 }
17963 IntervalUnitSpec::Expr(expr) => {
17964 self.generate_expression(expr)?;
17965 }
17966 }
17967 Ok(())
17968 }
17969
17970 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
17971 match (unit, use_plural) {
17973 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
17974 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
17975 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
17976 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
17977 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
17978 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
17979 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
17980 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
17981 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
17982 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
17983 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
17984 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
17985 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
17986 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
17987 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
17988 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
17989 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
17990 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
17991 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
17992 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
17993 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
17994 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
17995 }
17996 }
17997
17998 fn write_redshift_date_part(&mut self, expr: &Expression) {
18001 let part_str = self.extract_date_part_string(expr);
18002 if let Some(part) = part_str {
18003 let normalized = self.normalize_date_part(&part);
18004 self.write_keyword(&normalized);
18005 } else {
18006 let _ = self.generate_expression(expr);
18008 }
18009 }
18010
18011 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
18014 let part_str = self.extract_date_part_string(expr);
18015 if let Some(part) = part_str {
18016 let normalized = self.normalize_date_part(&part);
18017 self.write("'");
18018 self.write(&normalized);
18019 self.write("'");
18020 } else {
18021 let _ = self.generate_expression(expr);
18023 }
18024 }
18025
18026 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
18028 match expr {
18029 Expression::Literal(lit)
18030 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
18031 {
18032 let crate::expressions::Literal::String(s) = lit.as_ref() else {
18033 unreachable!()
18034 };
18035 Some(s.clone())
18036 }
18037 Expression::Identifier(id) => Some(id.name.clone()),
18038 Expression::Var(v) => Some(v.this.clone()),
18039 Expression::Column(col) if col.table.is_none() => {
18040 Some(col.name.name.clone())
18042 }
18043 _ => None,
18044 }
18045 }
18046
18047 fn normalize_date_part(&self, part: &str) -> String {
18050 let mut buf = [0u8; 64];
18051 let lower: &str = if part.len() <= 64 {
18052 for (i, b) in part.bytes().enumerate() {
18053 buf[i] = b.to_ascii_lowercase();
18054 }
18055 std::str::from_utf8(&buf[..part.len()]).unwrap_or(part)
18056 } else {
18057 return part.to_ascii_uppercase();
18058 };
18059 match lower {
18060 "day" | "days" | "d" => "DAY".to_string(),
18061 "month" | "months" | "mon" | "mm" => "MONTH".to_string(),
18062 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
18063 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
18064 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
18065 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
18066 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
18067 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
18068 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
18069 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
18070 _ => part.to_ascii_uppercase(),
18071 }
18072 }
18073
18074 fn write_datetime_field(&mut self, field: &DateTimeField) {
18075 match field {
18076 DateTimeField::Year => self.write_keyword("YEAR"),
18077 DateTimeField::Month => self.write_keyword("MONTH"),
18078 DateTimeField::Day => self.write_keyword("DAY"),
18079 DateTimeField::Hour => self.write_keyword("HOUR"),
18080 DateTimeField::Minute => self.write_keyword("MINUTE"),
18081 DateTimeField::Second => self.write_keyword("SECOND"),
18082 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
18083 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
18084 DateTimeField::DayOfWeek => {
18085 let name = match self.config.dialect {
18086 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
18087 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "WEEKDAY",
18088 _ => "DOW",
18089 };
18090 self.write_keyword(name);
18091 }
18092 DateTimeField::DayOfYear => {
18093 let name = match self.config.dialect {
18094 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
18095 _ => "DOY",
18096 };
18097 self.write_keyword(name);
18098 }
18099 DateTimeField::Week => self.write_keyword("WEEK"),
18100 DateTimeField::WeekWithModifier(modifier) => {
18101 self.write_keyword("WEEK");
18102 self.write("(");
18103 self.write(modifier);
18104 self.write(")");
18105 }
18106 DateTimeField::Quarter => self.write_keyword("QUARTER"),
18107 DateTimeField::Epoch => self.write_keyword("EPOCH"),
18108 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
18109 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
18110 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
18111 DateTimeField::Date => self.write_keyword("DATE"),
18112 DateTimeField::Time => self.write_keyword("TIME"),
18113 DateTimeField::Custom(name) => self.write(name),
18114 }
18115 }
18116
18117 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
18119 match field {
18120 DateTimeField::Year => self.write("year"),
18121 DateTimeField::Month => self.write("month"),
18122 DateTimeField::Day => self.write("day"),
18123 DateTimeField::Hour => self.write("hour"),
18124 DateTimeField::Minute => self.write("minute"),
18125 DateTimeField::Second => self.write("second"),
18126 DateTimeField::Millisecond => self.write("millisecond"),
18127 DateTimeField::Microsecond => self.write("microsecond"),
18128 DateTimeField::DayOfWeek => self.write("dow"),
18129 DateTimeField::DayOfYear => self.write("doy"),
18130 DateTimeField::Week => self.write("week"),
18131 DateTimeField::WeekWithModifier(modifier) => {
18132 self.write("week(");
18133 self.write(modifier);
18134 self.write(")");
18135 }
18136 DateTimeField::Quarter => self.write("quarter"),
18137 DateTimeField::Epoch => self.write("epoch"),
18138 DateTimeField::Timezone => self.write("timezone"),
18139 DateTimeField::TimezoneHour => self.write("timezone_hour"),
18140 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
18141 DateTimeField::Date => self.write("date"),
18142 DateTimeField::Time => self.write("time"),
18143 DateTimeField::Custom(name) => self.write(name),
18144 }
18145 }
18146
18147 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
18150 self.write_keyword(name);
18151 self.write("(");
18152 self.generate_expression(arg)?;
18153 self.write(")");
18154 Ok(())
18155 }
18156
18157 fn generate_unary_func(
18159 &mut self,
18160 default_name: &str,
18161 f: &crate::expressions::UnaryFunc,
18162 ) -> Result<()> {
18163 let name = f.original_name.as_deref().unwrap_or(default_name);
18164 self.write_keyword(name);
18165 self.write("(");
18166 self.generate_expression(&f.this)?;
18167 self.write(")");
18168 Ok(())
18169 }
18170
18171 fn generate_sqrt_cbrt(
18173 &mut self,
18174 f: &crate::expressions::UnaryFunc,
18175 func_name: &str,
18176 _op: &str,
18177 ) -> Result<()> {
18178 self.write_keyword(func_name);
18181 self.write("(");
18182 self.generate_expression(&f.this)?;
18183 self.write(")");
18184 Ok(())
18185 }
18186
18187 fn generate_binary_func(
18188 &mut self,
18189 name: &str,
18190 arg1: &Expression,
18191 arg2: &Expression,
18192 ) -> Result<()> {
18193 self.write_keyword(name);
18194 self.write("(");
18195 self.generate_expression(arg1)?;
18196 self.write(", ");
18197 self.generate_expression(arg2)?;
18198 self.write(")");
18199 Ok(())
18200 }
18201
18202 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
18206 let func_name = f.name.as_deref().unwrap_or("CHAR");
18208 self.write_keyword(func_name);
18209 self.write("(");
18210 for (i, arg) in f.args.iter().enumerate() {
18211 if i > 0 {
18212 self.write(", ");
18213 }
18214 self.generate_expression(arg)?;
18215 }
18216 if let Some(ref charset) = f.charset {
18217 self.write(" ");
18218 self.write_keyword("USING");
18219 self.write(" ");
18220 self.write(charset);
18221 }
18222 self.write(")");
18223 Ok(())
18224 }
18225
18226 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
18227 use crate::dialects::DialectType;
18228
18229 match self.config.dialect {
18230 Some(DialectType::Teradata) => {
18231 self.generate_expression(&f.this)?;
18233 self.write(" ** ");
18234 self.generate_expression(&f.expression)?;
18235 Ok(())
18236 }
18237 _ => {
18238 self.generate_binary_func("POWER", &f.this, &f.expression)
18240 }
18241 }
18242 }
18243
18244 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
18245 self.write_func_name(name);
18246 self.write("(");
18247 for (i, arg) in args.iter().enumerate() {
18248 if i > 0 {
18249 self.write(", ");
18250 }
18251 self.generate_expression(arg)?;
18252 }
18253 self.write(")");
18254 Ok(())
18255 }
18256
18257 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
18260 self.write_keyword("CONCAT_WS");
18261 self.write("(");
18262 self.generate_expression(&f.separator)?;
18263 for expr in &f.expressions {
18264 self.write(", ");
18265 self.generate_expression(expr)?;
18266 }
18267 self.write(")");
18268 Ok(())
18269 }
18270
18271 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
18272 if let Expression::Concat(op) = expr {
18273 Self::collect_concat_operands(&op.left, out);
18274 Self::collect_concat_operands(&op.right, out);
18275 } else {
18276 out.push(expr);
18277 }
18278 }
18279
18280 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
18281 let mut operands = Vec::new();
18282 Self::collect_concat_operands(&op.left, &mut operands);
18283 Self::collect_concat_operands(&op.right, &mut operands);
18284
18285 self.write_keyword("CONCAT");
18286 self.write("(");
18287 for (i, operand) in operands.iter().enumerate() {
18288 if i > 0 {
18289 self.write(", ");
18290 }
18291 self.generate_expression(operand)?;
18292 }
18293 self.write(")");
18294 Ok(())
18295 }
18296
18297 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
18298 if let Expression::DPipe(dpipe) = expr {
18299 Self::collect_dpipe_operands(&dpipe.this, out);
18300 Self::collect_dpipe_operands(&dpipe.expression, out);
18301 } else {
18302 out.push(expr);
18303 }
18304 }
18305
18306 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
18307 let mut operands = Vec::new();
18308 Self::collect_dpipe_operands(&e.this, &mut operands);
18309 Self::collect_dpipe_operands(&e.expression, &mut operands);
18310
18311 self.write_keyword("CONCAT");
18312 self.write("(");
18313 for (i, operand) in operands.iter().enumerate() {
18314 if i > 0 {
18315 self.write(", ");
18316 }
18317 self.generate_expression(operand)?;
18318 }
18319 self.write(")");
18320 Ok(())
18321 }
18322
18323 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
18324 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
18326 if is_oracle {
18327 self.write_keyword("SUBSTR");
18328 } else {
18329 self.write_keyword("SUBSTRING");
18330 }
18331 self.write("(");
18332 self.generate_expression(&f.this)?;
18333 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
18335 let use_comma_syntax = matches!(
18337 self.config.dialect,
18338 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
18339 );
18340 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
18341 self.write_space();
18343 self.write_keyword("FROM");
18344 self.write_space();
18345 self.generate_expression(&f.start)?;
18346 if let Some(length) = &f.length {
18347 self.write_space();
18348 self.write_keyword("FOR");
18349 self.write_space();
18350 self.generate_expression(length)?;
18351 }
18352 } else {
18353 self.write(", ");
18355 self.generate_expression(&f.start)?;
18356 if let Some(length) = &f.length {
18357 self.write(", ");
18358 self.generate_expression(length)?;
18359 }
18360 }
18361 self.write(")");
18362 Ok(())
18363 }
18364
18365 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
18366 self.write_keyword("OVERLAY");
18367 self.write("(");
18368 self.generate_expression(&f.this)?;
18369 self.write_space();
18370 self.write_keyword("PLACING");
18371 self.write_space();
18372 self.generate_expression(&f.replacement)?;
18373 self.write_space();
18374 self.write_keyword("FROM");
18375 self.write_space();
18376 self.generate_expression(&f.from)?;
18377 if let Some(length) = &f.length {
18378 self.write_space();
18379 self.write_keyword("FOR");
18380 self.write_space();
18381 self.generate_expression(length)?;
18382 }
18383 self.write(")");
18384 Ok(())
18385 }
18386
18387 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
18388 if f.position_explicit && f.characters.is_none() {
18391 match f.position {
18392 TrimPosition::Leading => {
18393 self.write_keyword("LTRIM");
18394 self.write("(");
18395 self.generate_expression(&f.this)?;
18396 self.write(")");
18397 return Ok(());
18398 }
18399 TrimPosition::Trailing => {
18400 self.write_keyword("RTRIM");
18401 self.write("(");
18402 self.generate_expression(&f.this)?;
18403 self.write(")");
18404 return Ok(());
18405 }
18406 TrimPosition::Both => {
18407 }
18410 }
18411 }
18412
18413 self.write_keyword("TRIM");
18414 self.write("(");
18415 let force_standard = f.characters.is_some()
18418 && !f.sql_standard_syntax
18419 && matches!(
18420 self.config.dialect,
18421 Some(DialectType::Hive)
18422 | Some(DialectType::Spark)
18423 | Some(DialectType::Databricks)
18424 | Some(DialectType::ClickHouse)
18425 );
18426 let use_standard = (f.sql_standard_syntax || force_standard)
18427 && !(f.position_explicit
18428 && f.characters.is_none()
18429 && matches!(f.position, TrimPosition::Both));
18430 if use_standard {
18431 if f.position_explicit {
18434 match f.position {
18435 TrimPosition::Both => self.write_keyword("BOTH"),
18436 TrimPosition::Leading => self.write_keyword("LEADING"),
18437 TrimPosition::Trailing => self.write_keyword("TRAILING"),
18438 }
18439 self.write_space();
18440 }
18441 if let Some(chars) = &f.characters {
18442 self.generate_expression(chars)?;
18443 self.write_space();
18444 }
18445 self.write_keyword("FROM");
18446 self.write_space();
18447 self.generate_expression(&f.this)?;
18448 } else {
18449 self.generate_expression(&f.this)?;
18451 if let Some(chars) = &f.characters {
18452 self.write(", ");
18453 self.generate_expression(chars)?;
18454 }
18455 }
18456 self.write(")");
18457 Ok(())
18458 }
18459
18460 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
18461 self.write_keyword("REPLACE");
18462 self.write("(");
18463 self.generate_expression(&f.this)?;
18464 self.write(", ");
18465 self.generate_expression(&f.old)?;
18466 self.write(", ");
18467 self.generate_expression(&f.new)?;
18468 self.write(")");
18469 Ok(())
18470 }
18471
18472 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
18473 self.write_keyword(name);
18474 self.write("(");
18475 self.generate_expression(&f.this)?;
18476 self.write(", ");
18477 self.generate_expression(&f.length)?;
18478 self.write(")");
18479 Ok(())
18480 }
18481
18482 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
18483 self.write_keyword("REPEAT");
18484 self.write("(");
18485 self.generate_expression(&f.this)?;
18486 self.write(", ");
18487 self.generate_expression(&f.times)?;
18488 self.write(")");
18489 Ok(())
18490 }
18491
18492 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
18493 self.write_keyword(name);
18494 self.write("(");
18495 self.generate_expression(&f.this)?;
18496 self.write(", ");
18497 self.generate_expression(&f.length)?;
18498 if let Some(fill) = &f.fill {
18499 self.write(", ");
18500 self.generate_expression(fill)?;
18501 }
18502 self.write(")");
18503 Ok(())
18504 }
18505
18506 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
18507 self.write_keyword("SPLIT");
18508 self.write("(");
18509 self.generate_expression(&f.this)?;
18510 self.write(", ");
18511 self.generate_expression(&f.delimiter)?;
18512 self.write(")");
18513 Ok(())
18514 }
18515
18516 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
18517 use crate::dialects::DialectType;
18518 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
18520 self.generate_expression(&f.this)?;
18521 self.write(" ~ ");
18522 self.generate_expression(&f.pattern)?;
18523 } else if matches!(self.config.dialect, Some(DialectType::Exasol)) && f.flags.is_none() {
18524 self.generate_expression(&f.this)?;
18526 self.write_keyword(" REGEXP_LIKE ");
18527 self.generate_expression(&f.pattern)?;
18528 } else if matches!(
18529 self.config.dialect,
18530 Some(DialectType::SingleStore)
18531 | Some(DialectType::Spark)
18532 | Some(DialectType::Hive)
18533 | Some(DialectType::Databricks)
18534 ) && f.flags.is_none()
18535 {
18536 self.generate_expression(&f.this)?;
18538 self.write_keyword(" RLIKE ");
18539 self.generate_expression(&f.pattern)?;
18540 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
18541 self.write_keyword("REGEXP");
18543 self.write("(");
18544 self.generate_expression(&f.this)?;
18545 self.write(", ");
18546 self.generate_expression(&f.pattern)?;
18547 if let Some(flags) = &f.flags {
18548 self.write(", ");
18549 self.generate_expression(flags)?;
18550 }
18551 self.write(")");
18552 } else {
18553 self.write_keyword("REGEXP_LIKE");
18554 self.write("(");
18555 self.generate_expression(&f.this)?;
18556 self.write(", ");
18557 self.generate_expression(&f.pattern)?;
18558 if let Some(flags) = &f.flags {
18559 self.write(", ");
18560 self.generate_expression(flags)?;
18561 }
18562 self.write(")");
18563 }
18564 Ok(())
18565 }
18566
18567 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
18568 self.write_keyword("REGEXP_REPLACE");
18569 self.write("(");
18570 self.generate_expression(&f.this)?;
18571 self.write(", ");
18572 self.generate_expression(&f.pattern)?;
18573 self.write(", ");
18574 self.generate_expression(&f.replacement)?;
18575 if let Some(flags) = &f.flags {
18576 self.write(", ");
18577 self.generate_expression(flags)?;
18578 }
18579 self.write(")");
18580 Ok(())
18581 }
18582
18583 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
18584 self.write_keyword("REGEXP_EXTRACT");
18585 self.write("(");
18586 self.generate_expression(&f.this)?;
18587 self.write(", ");
18588 self.generate_expression(&f.pattern)?;
18589 if let Some(group) = &f.group {
18590 self.write(", ");
18591 self.generate_expression(group)?;
18592 }
18593 self.write(")");
18594 Ok(())
18595 }
18596
18597 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
18600 self.write_keyword("ROUND");
18601 self.write("(");
18602 self.generate_expression(&f.this)?;
18603 if let Some(decimals) = &f.decimals {
18604 self.write(", ");
18605 self.generate_expression(decimals)?;
18606 }
18607 self.write(")");
18608 Ok(())
18609 }
18610
18611 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
18612 self.write_keyword("FLOOR");
18613 self.write("(");
18614 self.generate_expression(&f.this)?;
18615 if let Some(to) = &f.to {
18617 self.write(" ");
18618 self.write_keyword("TO");
18619 self.write(" ");
18620 self.generate_expression(to)?;
18621 } else if let Some(scale) = &f.scale {
18622 self.write(", ");
18623 self.generate_expression(scale)?;
18624 }
18625 self.write(")");
18626 Ok(())
18627 }
18628
18629 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
18630 self.write_keyword("CEIL");
18631 self.write("(");
18632 self.generate_expression(&f.this)?;
18633 if let Some(to) = &f.to {
18635 self.write(" ");
18636 self.write_keyword("TO");
18637 self.write(" ");
18638 self.generate_expression(to)?;
18639 } else if let Some(decimals) = &f.decimals {
18640 self.write(", ");
18641 self.generate_expression(decimals)?;
18642 }
18643 self.write(")");
18644 Ok(())
18645 }
18646
18647 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
18648 use crate::expressions::Literal;
18649
18650 if let Some(base) = &f.base {
18651 if self.is_log_base_none() {
18654 if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "2"))
18655 {
18656 self.write_func_name("LOG2");
18657 self.write("(");
18658 self.generate_expression(&f.this)?;
18659 self.write(")");
18660 return Ok(());
18661 } else if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "10"))
18662 {
18663 self.write_func_name("LOG10");
18664 self.write("(");
18665 self.generate_expression(&f.this)?;
18666 self.write(")");
18667 return Ok(());
18668 }
18669 }
18671
18672 self.write_func_name("LOG");
18673 self.write("(");
18674 if self.is_log_value_first() {
18675 self.generate_expression(&f.this)?;
18677 self.write(", ");
18678 self.generate_expression(base)?;
18679 } else {
18680 self.generate_expression(base)?;
18682 self.write(", ");
18683 self.generate_expression(&f.this)?;
18684 }
18685 self.write(")");
18686 } else {
18687 self.write_func_name("LOG");
18689 self.write("(");
18690 self.generate_expression(&f.this)?;
18691 self.write(")");
18692 }
18693 Ok(())
18694 }
18695
18696 fn is_log_value_first(&self) -> bool {
18699 use crate::dialects::DialectType;
18700 matches!(
18701 self.config.dialect,
18702 Some(DialectType::BigQuery)
18703 | Some(DialectType::TSQL)
18704 | Some(DialectType::Tableau)
18705 | Some(DialectType::Fabric)
18706 )
18707 }
18708
18709 fn is_log_base_none(&self) -> bool {
18712 use crate::dialects::DialectType;
18713 matches!(
18714 self.config.dialect,
18715 Some(DialectType::Presto)
18716 | Some(DialectType::Trino)
18717 | Some(DialectType::ClickHouse)
18718 | Some(DialectType::Athena)
18719 )
18720 }
18721
18722 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
18725 self.write_keyword("CURRENT_TIME");
18726 if let Some(precision) = f.precision {
18727 self.write(&format!("({})", precision));
18728 } else if matches!(
18729 self.config.dialect,
18730 Some(crate::dialects::DialectType::MySQL)
18731 | Some(crate::dialects::DialectType::SingleStore)
18732 | Some(crate::dialects::DialectType::TiDB)
18733 ) {
18734 self.write("()");
18735 }
18736 Ok(())
18737 }
18738
18739 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
18740 use crate::dialects::DialectType;
18741
18742 if f.sysdate {
18744 match self.config.dialect {
18745 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
18746 self.write_keyword("SYSDATE");
18747 return Ok(());
18748 }
18749 Some(DialectType::Snowflake) => {
18750 self.write_keyword("SYSDATE");
18752 self.write("()");
18753 return Ok(());
18754 }
18755 _ => {
18756 }
18758 }
18759 }
18760
18761 self.write_keyword("CURRENT_TIMESTAMP");
18762 if let Some(precision) = f.precision {
18764 self.write(&format!("({})", precision));
18765 } else if matches!(
18766 self.config.dialect,
18767 Some(crate::dialects::DialectType::MySQL)
18768 | Some(crate::dialects::DialectType::SingleStore)
18769 | Some(crate::dialects::DialectType::TiDB)
18770 | Some(crate::dialects::DialectType::Spark)
18771 | Some(crate::dialects::DialectType::Hive)
18772 | Some(crate::dialects::DialectType::Databricks)
18773 | Some(crate::dialects::DialectType::ClickHouse)
18774 | Some(crate::dialects::DialectType::BigQuery)
18775 | Some(crate::dialects::DialectType::Snowflake)
18776 | Some(crate::dialects::DialectType::Exasol)
18777 ) {
18778 self.write("()");
18779 }
18780 Ok(())
18781 }
18782
18783 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
18784 if self.config.dialect == Some(DialectType::Exasol) {
18786 self.write_keyword("CONVERT_TZ");
18787 self.write("(");
18788 self.generate_expression(&f.this)?;
18789 self.write(", 'UTC', ");
18790 self.generate_expression(&f.zone)?;
18791 self.write(")");
18792 return Ok(());
18793 }
18794
18795 self.generate_expression(&f.this)?;
18796 self.write_space();
18797 self.write_keyword("AT TIME ZONE");
18798 self.write_space();
18799 self.generate_expression(&f.zone)?;
18800 Ok(())
18801 }
18802
18803 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
18804 use crate::dialects::DialectType;
18805
18806 let is_presto_like = matches!(
18809 self.config.dialect,
18810 Some(DialectType::Presto) | Some(DialectType::Trino)
18811 );
18812
18813 if is_presto_like {
18814 self.write_keyword(name);
18815 self.write("(");
18816 self.write("'");
18818 self.write_simple_interval_unit(&f.unit, false);
18819 self.write("'");
18820 self.write(", ");
18821 let needs_cast = !self.returns_integer_type(&f.interval);
18823 if needs_cast {
18824 self.write_keyword("CAST");
18825 self.write("(");
18826 }
18827 self.generate_expression(&f.interval)?;
18828 if needs_cast {
18829 self.write_space();
18830 self.write_keyword("AS");
18831 self.write_space();
18832 self.write_keyword("BIGINT");
18833 self.write(")");
18834 }
18835 self.write(", ");
18836 self.generate_expression(&f.this)?;
18837 self.write(")");
18838 } else {
18839 self.write_keyword(name);
18840 self.write("(");
18841 self.generate_expression(&f.this)?;
18842 self.write(", ");
18843 self.write_keyword("INTERVAL");
18844 self.write_space();
18845 self.generate_expression(&f.interval)?;
18846 self.write_space();
18847 self.write_simple_interval_unit(&f.unit, false); self.write(")");
18849 }
18850 Ok(())
18851 }
18852
18853 fn returns_integer_type(&self, expr: &Expression) -> bool {
18856 use crate::expressions::{DataType, Literal};
18857 match expr {
18858 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
18860 let Literal::Number(n) = lit.as_ref() else {
18861 unreachable!()
18862 };
18863 !n.contains('.')
18864 }
18865
18866 Expression::Floor(f) => self.returns_integer_type(&f.this),
18868
18869 Expression::Round(f) => {
18871 f.decimals.is_none() && self.returns_integer_type(&f.this)
18873 }
18874
18875 Expression::Sign(f) => self.returns_integer_type(&f.this),
18877
18878 Expression::Abs(f) => self.returns_integer_type(&f.this),
18880
18881 Expression::Mul(op) => {
18883 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
18884 }
18885 Expression::Add(op) => {
18886 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
18887 }
18888 Expression::Sub(op) => {
18889 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
18890 }
18891 Expression::Mod(op) => self.returns_integer_type(&op.left),
18892
18893 Expression::Cast(c) => matches!(
18895 &c.to,
18896 DataType::BigInt { .. }
18897 | DataType::Int { .. }
18898 | DataType::SmallInt { .. }
18899 | DataType::TinyInt { .. }
18900 ),
18901
18902 Expression::Neg(op) => self.returns_integer_type(&op.this),
18904
18905 Expression::Paren(p) => self.returns_integer_type(&p.this),
18907
18908 _ => false,
18911 }
18912 }
18913
18914 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
18915 self.write_keyword("DATEDIFF");
18916 self.write("(");
18917 if let Some(unit) = &f.unit {
18918 self.write_simple_interval_unit(unit, false); self.write(", ");
18920 }
18921 self.generate_expression(&f.this)?;
18922 self.write(", ");
18923 self.generate_expression(&f.expression)?;
18924 self.write(")");
18925 Ok(())
18926 }
18927
18928 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
18929 self.write_keyword("DATE_TRUNC");
18930 self.write("('");
18931 self.write_datetime_field(&f.unit);
18932 self.write("', ");
18933 self.generate_expression(&f.this)?;
18934 self.write(")");
18935 Ok(())
18936 }
18937
18938 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
18939 use crate::dialects::DialectType;
18940 use crate::expressions::DateTimeField;
18941
18942 self.write_keyword("LAST_DAY");
18943 self.write("(");
18944 self.generate_expression(&f.this)?;
18945 if let Some(unit) = &f.unit {
18946 self.write(", ");
18947 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
18950 if let DateTimeField::WeekWithModifier(_) = unit {
18951 self.write_keyword("WEEK");
18952 } else {
18953 self.write_datetime_field(unit);
18954 }
18955 } else {
18956 self.write_datetime_field(unit);
18957 }
18958 }
18959 self.write(")");
18960 Ok(())
18961 }
18962
18963 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
18964 if matches!(
18966 self.config.dialect,
18967 Some(DialectType::TSQL) | Some(DialectType::Fabric)
18968 ) {
18969 self.write_keyword("DATEPART");
18970 self.write("(");
18971 self.write_datetime_field(&f.field);
18972 self.write(", ");
18973 self.generate_expression(&f.this)?;
18974 self.write(")");
18975 return Ok(());
18976 }
18977 self.write_keyword("EXTRACT");
18978 self.write("(");
18979 if matches!(
18981 self.config.dialect,
18982 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
18983 ) {
18984 self.write_datetime_field_lower(&f.field);
18985 } else {
18986 self.write_datetime_field(&f.field);
18987 }
18988 self.write_space();
18989 self.write_keyword("FROM");
18990 self.write_space();
18991 self.generate_expression(&f.this)?;
18992 self.write(")");
18993 Ok(())
18994 }
18995
18996 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
18997 self.write_keyword("TO_DATE");
18998 self.write("(");
18999 self.generate_expression(&f.this)?;
19000 if let Some(format) = &f.format {
19001 self.write(", ");
19002 self.generate_expression(format)?;
19003 }
19004 self.write(")");
19005 Ok(())
19006 }
19007
19008 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
19009 self.write_keyword("TO_TIMESTAMP");
19010 self.write("(");
19011 self.generate_expression(&f.this)?;
19012 if let Some(format) = &f.format {
19013 self.write(", ");
19014 self.generate_expression(format)?;
19015 }
19016 self.write(")");
19017 Ok(())
19018 }
19019
19020 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
19023 use crate::dialects::DialectType;
19024
19025 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
19027 self.write_keyword("CASE WHEN");
19028 self.write_space();
19029 self.generate_expression(&f.condition)?;
19030 self.write_space();
19031 self.write_keyword("THEN");
19032 self.write_space();
19033 self.generate_expression(&f.true_value)?;
19034 if let Some(false_val) = &f.false_value {
19035 self.write_space();
19036 self.write_keyword("ELSE");
19037 self.write_space();
19038 self.generate_expression(false_val)?;
19039 }
19040 self.write_space();
19041 self.write_keyword("END");
19042 return Ok(());
19043 }
19044
19045 if self.config.dialect == Some(DialectType::Exasol) {
19047 self.write_keyword("IF");
19048 self.write_space();
19049 self.generate_expression(&f.condition)?;
19050 self.write_space();
19051 self.write_keyword("THEN");
19052 self.write_space();
19053 self.generate_expression(&f.true_value)?;
19054 if let Some(false_val) = &f.false_value {
19055 self.write_space();
19056 self.write_keyword("ELSE");
19057 self.write_space();
19058 self.generate_expression(false_val)?;
19059 }
19060 self.write_space();
19061 self.write_keyword("ENDIF");
19062 return Ok(());
19063 }
19064
19065 let func_name = match self.config.dialect {
19067 Some(DialectType::Snowflake) => "IFF",
19068 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
19069 Some(DialectType::Drill) => "`IF`",
19070 _ => "IF",
19071 };
19072 self.write(func_name);
19073 self.write("(");
19074 self.generate_expression(&f.condition)?;
19075 self.write(", ");
19076 self.generate_expression(&f.true_value)?;
19077 if let Some(false_val) = &f.false_value {
19078 self.write(", ");
19079 self.generate_expression(false_val)?;
19080 }
19081 self.write(")");
19082 Ok(())
19083 }
19084
19085 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
19086 self.write_keyword("NVL2");
19087 self.write("(");
19088 self.generate_expression(&f.this)?;
19089 self.write(", ");
19090 self.generate_expression(&f.true_value)?;
19091 self.write(", ");
19092 self.generate_expression(&f.false_value)?;
19093 self.write(")");
19094 Ok(())
19095 }
19096
19097 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
19100 let count_name = match self.config.normalize_functions {
19102 NormalizeFunctions::Upper => "COUNT".to_string(),
19103 NormalizeFunctions::Lower => "count".to_string(),
19104 NormalizeFunctions::None => f
19105 .original_name
19106 .clone()
19107 .unwrap_or_else(|| "COUNT".to_string()),
19108 };
19109 self.write(&count_name);
19110 self.write("(");
19111 if f.distinct {
19112 self.write_keyword("DISTINCT");
19113 self.write_space();
19114 }
19115 if f.star {
19116 self.write("*");
19117 } else if let Some(ref expr) = f.this {
19118 if let Expression::Tuple(tuple) = expr {
19120 let needs_transform =
19124 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
19125
19126 if needs_transform {
19127 self.write_keyword("CASE");
19129 for e in &tuple.expressions {
19130 self.write_space();
19131 self.write_keyword("WHEN");
19132 self.write_space();
19133 self.generate_expression(e)?;
19134 self.write_space();
19135 self.write_keyword("IS NULL THEN NULL");
19136 }
19137 self.write_space();
19138 self.write_keyword("ELSE");
19139 self.write(" (");
19140 for (i, e) in tuple.expressions.iter().enumerate() {
19141 if i > 0 {
19142 self.write(", ");
19143 }
19144 self.generate_expression(e)?;
19145 }
19146 self.write(")");
19147 self.write_space();
19148 self.write_keyword("END");
19149 } else {
19150 for (i, e) in tuple.expressions.iter().enumerate() {
19151 if i > 0 {
19152 self.write(", ");
19153 }
19154 self.generate_expression(e)?;
19155 }
19156 }
19157 } else {
19158 self.generate_expression(expr)?;
19159 }
19160 }
19161 if let Some(ignore) = f.ignore_nulls {
19163 self.write_space();
19164 if ignore {
19165 self.write_keyword("IGNORE NULLS");
19166 } else {
19167 self.write_keyword("RESPECT NULLS");
19168 }
19169 }
19170 self.write(")");
19171 if let Some(ref filter) = f.filter {
19172 self.write_space();
19173 self.write_keyword("FILTER");
19174 self.write("(");
19175 self.write_keyword("WHERE");
19176 self.write_space();
19177 self.generate_expression(filter)?;
19178 self.write(")");
19179 }
19180 Ok(())
19181 }
19182
19183 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
19184 let func_name: Cow<'_, str> = match self.config.normalize_functions {
19186 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
19187 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
19188 NormalizeFunctions::None => {
19189 if let Some(ref original) = f.name {
19192 Cow::Owned(original.clone())
19193 } else {
19194 Cow::Owned(name.to_ascii_lowercase())
19195 }
19196 }
19197 };
19198 self.write(func_name.as_ref());
19199 self.write("(");
19200 if f.distinct {
19201 self.write_keyword("DISTINCT");
19202 self.write_space();
19203 }
19204 if !matches!(f.this, Expression::Null(_)) {
19206 self.generate_expression(&f.this)?;
19207 }
19208 if self.config.ignore_nulls_in_func
19211 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19212 {
19213 match f.ignore_nulls {
19214 Some(true) => {
19215 self.write_space();
19216 self.write_keyword("IGNORE NULLS");
19217 }
19218 Some(false) => {
19219 self.write_space();
19220 self.write_keyword("RESPECT NULLS");
19221 }
19222 None => {}
19223 }
19224 }
19225 if let Some((ref expr, is_max)) = f.having_max {
19228 self.write_space();
19229 self.write_keyword("HAVING");
19230 self.write_space();
19231 if is_max {
19232 self.write_keyword("MAX");
19233 } else {
19234 self.write_keyword("MIN");
19235 }
19236 self.write_space();
19237 self.generate_expression(expr)?;
19238 }
19239 if !f.order_by.is_empty() {
19241 self.write_space();
19242 self.write_keyword("ORDER BY");
19243 self.write_space();
19244 for (i, ord) in f.order_by.iter().enumerate() {
19245 if i > 0 {
19246 self.write(", ");
19247 }
19248 self.generate_ordered(ord)?;
19249 }
19250 }
19251 if let Some(ref limit) = f.limit {
19253 self.write_space();
19254 self.write_keyword("LIMIT");
19255 self.write_space();
19256 if let Expression::Tuple(t) = limit.as_ref() {
19258 if t.expressions.len() == 2 {
19259 self.generate_expression(&t.expressions[0])?;
19260 self.write(", ");
19261 self.generate_expression(&t.expressions[1])?;
19262 } else {
19263 self.generate_expression(limit)?;
19264 }
19265 } else {
19266 self.generate_expression(limit)?;
19267 }
19268 }
19269 self.write(")");
19270 if !self.config.ignore_nulls_in_func
19273 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19274 {
19275 match f.ignore_nulls {
19276 Some(true) => {
19277 self.write_space();
19278 self.write_keyword("IGNORE NULLS");
19279 }
19280 Some(false) => {
19281 self.write_space();
19282 self.write_keyword("RESPECT NULLS");
19283 }
19284 None => {}
19285 }
19286 }
19287 if let Some(ref filter) = f.filter {
19288 self.write_space();
19289 self.write_keyword("FILTER");
19290 self.write("(");
19291 self.write_keyword("WHERE");
19292 self.write_space();
19293 self.generate_expression(filter)?;
19294 self.write(")");
19295 }
19296 Ok(())
19297 }
19298
19299 fn generate_agg_func_with_ignore_nulls_bool(&mut self, name: &str, f: &AggFunc) -> Result<()> {
19302 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
19304 let func_name: Cow<'_, str> = match self.config.normalize_functions {
19306 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
19307 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
19308 NormalizeFunctions::None => {
19309 if let Some(ref original) = f.name {
19310 Cow::Owned(original.clone())
19311 } else {
19312 Cow::Owned(name.to_ascii_lowercase())
19313 }
19314 }
19315 };
19316 self.write(func_name.as_ref());
19317 self.write("(");
19318 if f.distinct {
19319 self.write_keyword("DISTINCT");
19320 self.write_space();
19321 }
19322 if !matches!(f.this, Expression::Null(_)) {
19323 self.generate_expression(&f.this)?;
19324 }
19325 self.write(", ");
19326 self.write_keyword("TRUE");
19327 self.write(")");
19328 return Ok(());
19329 }
19330 self.generate_agg_func(name, f)
19331 }
19332
19333 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
19334 self.write_keyword("GROUP_CONCAT");
19335 self.write("(");
19336 if f.distinct {
19337 self.write_keyword("DISTINCT");
19338 self.write_space();
19339 }
19340 self.generate_expression(&f.this)?;
19341 if let Some(ref order_by) = f.order_by {
19342 self.write_space();
19343 self.write_keyword("ORDER BY");
19344 self.write_space();
19345 for (i, ord) in order_by.iter().enumerate() {
19346 if i > 0 {
19347 self.write(", ");
19348 }
19349 self.generate_ordered(ord)?;
19350 }
19351 }
19352 if let Some(ref sep) = f.separator {
19353 if matches!(
19356 self.config.dialect,
19357 Some(crate::dialects::DialectType::SQLite)
19358 ) {
19359 self.write(", ");
19360 self.generate_expression(sep)?;
19361 } else {
19362 self.write_space();
19363 self.write_keyword("SEPARATOR");
19364 self.write_space();
19365 self.generate_expression(sep)?;
19366 }
19367 }
19368 if let Some(ref limit) = f.limit {
19369 self.write_space();
19370 self.write_keyword("LIMIT");
19371 self.write_space();
19372 self.generate_expression(limit)?;
19373 }
19374 self.write(")");
19375 if let Some(ref filter) = f.filter {
19376 self.write_space();
19377 self.write_keyword("FILTER");
19378 self.write("(");
19379 self.write_keyword("WHERE");
19380 self.write_space();
19381 self.generate_expression(filter)?;
19382 self.write(")");
19383 }
19384 Ok(())
19385 }
19386
19387 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
19388 let is_tsql = matches!(
19389 self.config.dialect,
19390 Some(crate::dialects::DialectType::TSQL)
19391 );
19392 self.write_keyword("STRING_AGG");
19393 self.write("(");
19394 if f.distinct {
19395 self.write_keyword("DISTINCT");
19396 self.write_space();
19397 }
19398 self.generate_expression(&f.this)?;
19399 if let Some(ref separator) = f.separator {
19400 self.write(", ");
19401 self.generate_expression(separator)?;
19402 }
19403 if !is_tsql {
19405 if let Some(ref order_by) = f.order_by {
19406 self.write_space();
19407 self.write_keyword("ORDER BY");
19408 self.write_space();
19409 for (i, ord) in order_by.iter().enumerate() {
19410 if i > 0 {
19411 self.write(", ");
19412 }
19413 self.generate_ordered(ord)?;
19414 }
19415 }
19416 }
19417 if let Some(ref limit) = f.limit {
19418 self.write_space();
19419 self.write_keyword("LIMIT");
19420 self.write_space();
19421 self.generate_expression(limit)?;
19422 }
19423 self.write(")");
19424 if is_tsql {
19426 if let Some(ref order_by) = f.order_by {
19427 self.write_space();
19428 self.write_keyword("WITHIN GROUP");
19429 self.write(" (");
19430 self.write_keyword("ORDER BY");
19431 self.write_space();
19432 for (i, ord) in order_by.iter().enumerate() {
19433 if i > 0 {
19434 self.write(", ");
19435 }
19436 self.generate_ordered(ord)?;
19437 }
19438 self.write(")");
19439 }
19440 }
19441 if let Some(ref filter) = f.filter {
19442 self.write_space();
19443 self.write_keyword("FILTER");
19444 self.write("(");
19445 self.write_keyword("WHERE");
19446 self.write_space();
19447 self.generate_expression(filter)?;
19448 self.write(")");
19449 }
19450 Ok(())
19451 }
19452
19453 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
19454 use crate::dialects::DialectType;
19455 self.write_keyword("LISTAGG");
19456 self.write("(");
19457 if f.distinct {
19458 self.write_keyword("DISTINCT");
19459 self.write_space();
19460 }
19461 self.generate_expression(&f.this)?;
19462 if let Some(ref sep) = f.separator {
19463 self.write(", ");
19464 self.generate_expression(sep)?;
19465 } else if matches!(
19466 self.config.dialect,
19467 Some(DialectType::Trino) | Some(DialectType::Presto)
19468 ) {
19469 self.write(", ','");
19471 }
19472 if let Some(ref overflow) = f.on_overflow {
19473 self.write_space();
19474 self.write_keyword("ON OVERFLOW");
19475 self.write_space();
19476 match overflow {
19477 ListAggOverflow::Error => self.write_keyword("ERROR"),
19478 ListAggOverflow::Truncate { filler, with_count } => {
19479 self.write_keyword("TRUNCATE");
19480 if let Some(ref fill) = filler {
19481 self.write_space();
19482 self.generate_expression(fill)?;
19483 }
19484 if *with_count {
19485 self.write_space();
19486 self.write_keyword("WITH COUNT");
19487 } else {
19488 self.write_space();
19489 self.write_keyword("WITHOUT COUNT");
19490 }
19491 }
19492 }
19493 }
19494 self.write(")");
19495 if let Some(ref order_by) = f.order_by {
19496 self.write_space();
19497 self.write_keyword("WITHIN GROUP");
19498 self.write(" (");
19499 self.write_keyword("ORDER BY");
19500 self.write_space();
19501 for (i, ord) in order_by.iter().enumerate() {
19502 if i > 0 {
19503 self.write(", ");
19504 }
19505 self.generate_ordered(ord)?;
19506 }
19507 self.write(")");
19508 }
19509 if let Some(ref filter) = f.filter {
19510 self.write_space();
19511 self.write_keyword("FILTER");
19512 self.write("(");
19513 self.write_keyword("WHERE");
19514 self.write_space();
19515 self.generate_expression(filter)?;
19516 self.write(")");
19517 }
19518 Ok(())
19519 }
19520
19521 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
19522 self.write_keyword("SUM_IF");
19523 self.write("(");
19524 self.generate_expression(&f.this)?;
19525 self.write(", ");
19526 self.generate_expression(&f.condition)?;
19527 self.write(")");
19528 if let Some(ref filter) = f.filter {
19529 self.write_space();
19530 self.write_keyword("FILTER");
19531 self.write("(");
19532 self.write_keyword("WHERE");
19533 self.write_space();
19534 self.generate_expression(filter)?;
19535 self.write(")");
19536 }
19537 Ok(())
19538 }
19539
19540 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
19541 self.write_keyword("APPROX_PERCENTILE");
19542 self.write("(");
19543 self.generate_expression(&f.this)?;
19544 self.write(", ");
19545 self.generate_expression(&f.percentile)?;
19546 if let Some(ref acc) = f.accuracy {
19547 self.write(", ");
19548 self.generate_expression(acc)?;
19549 }
19550 self.write(")");
19551 if let Some(ref filter) = f.filter {
19552 self.write_space();
19553 self.write_keyword("FILTER");
19554 self.write("(");
19555 self.write_keyword("WHERE");
19556 self.write_space();
19557 self.generate_expression(filter)?;
19558 self.write(")");
19559 }
19560 Ok(())
19561 }
19562
19563 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
19564 self.write_keyword(name);
19565 self.write("(");
19566 self.generate_expression(&f.percentile)?;
19567 self.write(")");
19568 if let Some(ref order_by) = f.order_by {
19569 self.write_space();
19570 self.write_keyword("WITHIN GROUP");
19571 self.write(" (");
19572 self.write_keyword("ORDER BY");
19573 self.write_space();
19574 self.generate_expression(&f.this)?;
19575 for ord in order_by.iter() {
19576 if ord.desc {
19577 self.write_space();
19578 self.write_keyword("DESC");
19579 }
19580 }
19581 self.write(")");
19582 }
19583 if let Some(ref filter) = f.filter {
19584 self.write_space();
19585 self.write_keyword("FILTER");
19586 self.write("(");
19587 self.write_keyword("WHERE");
19588 self.write_space();
19589 self.generate_expression(filter)?;
19590 self.write(")");
19591 }
19592 Ok(())
19593 }
19594
19595 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
19598 self.write_keyword("NTILE");
19599 self.write("(");
19600 if let Some(num_buckets) = &f.num_buckets {
19601 self.generate_expression(num_buckets)?;
19602 }
19603 if let Some(order_by) = &f.order_by {
19604 self.write_keyword(" ORDER BY ");
19605 for (i, ob) in order_by.iter().enumerate() {
19606 if i > 0 {
19607 self.write(", ");
19608 }
19609 self.generate_ordered(ob)?;
19610 }
19611 }
19612 self.write(")");
19613 Ok(())
19614 }
19615
19616 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
19617 self.write_keyword(name);
19618 self.write("(");
19619 self.generate_expression(&f.this)?;
19620 if let Some(ref offset) = f.offset {
19621 self.write(", ");
19622 self.generate_expression(offset)?;
19623 if let Some(ref default) = f.default {
19624 self.write(", ");
19625 self.generate_expression(default)?;
19626 }
19627 }
19628 if self.config.ignore_nulls_in_func {
19630 match f.ignore_nulls {
19631 Some(true) => {
19632 self.write_space();
19633 self.write_keyword("IGNORE NULLS");
19634 }
19635 Some(false) => {
19636 self.write_space();
19637 self.write_keyword("RESPECT NULLS");
19638 }
19639 None => {}
19640 }
19641 }
19642 self.write(")");
19643 if !self.config.ignore_nulls_in_func {
19645 match f.ignore_nulls {
19646 Some(true) => {
19647 self.write_space();
19648 self.write_keyword("IGNORE NULLS");
19649 }
19650 Some(false) => {
19651 self.write_space();
19652 self.write_keyword("RESPECT NULLS");
19653 }
19654 None => {}
19655 }
19656 }
19657 Ok(())
19658 }
19659
19660 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
19661 self.write_keyword(name);
19662 self.write("(");
19663 self.generate_expression(&f.this)?;
19664 if !f.order_by.is_empty() {
19666 self.write_space();
19667 self.write_keyword("ORDER BY");
19668 self.write_space();
19669 for (i, ordered) in f.order_by.iter().enumerate() {
19670 if i > 0 {
19671 self.write(", ");
19672 }
19673 self.generate_ordered(ordered)?;
19674 }
19675 }
19676 if self.config.ignore_nulls_in_func {
19678 match f.ignore_nulls {
19679 Some(true) => {
19680 self.write_space();
19681 self.write_keyword("IGNORE NULLS");
19682 }
19683 Some(false) => {
19684 self.write_space();
19685 self.write_keyword("RESPECT NULLS");
19686 }
19687 None => {}
19688 }
19689 }
19690 self.write(")");
19691 if !self.config.ignore_nulls_in_func {
19693 match f.ignore_nulls {
19694 Some(true) => {
19695 self.write_space();
19696 self.write_keyword("IGNORE NULLS");
19697 }
19698 Some(false) => {
19699 self.write_space();
19700 self.write_keyword("RESPECT NULLS");
19701 }
19702 None => {}
19703 }
19704 }
19705 Ok(())
19706 }
19707
19708 fn generate_value_func_with_ignore_nulls_bool(
19711 &mut self,
19712 name: &str,
19713 f: &ValueFunc,
19714 ) -> Result<()> {
19715 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
19716 self.write_keyword(name);
19717 self.write("(");
19718 self.generate_expression(&f.this)?;
19719 self.write(", ");
19720 self.write_keyword("TRUE");
19721 self.write(")");
19722 return Ok(());
19723 }
19724 self.generate_value_func(name, f)
19725 }
19726
19727 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
19728 self.write_keyword("NTH_VALUE");
19729 self.write("(");
19730 self.generate_expression(&f.this)?;
19731 self.write(", ");
19732 self.generate_expression(&f.offset)?;
19733 if self.config.ignore_nulls_in_func {
19735 match f.ignore_nulls {
19736 Some(true) => {
19737 self.write_space();
19738 self.write_keyword("IGNORE NULLS");
19739 }
19740 Some(false) => {
19741 self.write_space();
19742 self.write_keyword("RESPECT NULLS");
19743 }
19744 None => {}
19745 }
19746 }
19747 self.write(")");
19748 if matches!(
19750 self.config.dialect,
19751 Some(crate::dialects::DialectType::Snowflake)
19752 ) {
19753 match f.from_first {
19754 Some(true) => {
19755 self.write_space();
19756 self.write_keyword("FROM FIRST");
19757 }
19758 Some(false) => {
19759 self.write_space();
19760 self.write_keyword("FROM LAST");
19761 }
19762 None => {}
19763 }
19764 }
19765 if !self.config.ignore_nulls_in_func {
19767 match f.ignore_nulls {
19768 Some(true) => {
19769 self.write_space();
19770 self.write_keyword("IGNORE NULLS");
19771 }
19772 Some(false) => {
19773 self.write_space();
19774 self.write_keyword("RESPECT NULLS");
19775 }
19776 None => {}
19777 }
19778 }
19779 Ok(())
19780 }
19781
19782 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
19785 if matches!(
19788 self.config.dialect,
19789 Some(crate::dialects::DialectType::ClickHouse)
19790 ) {
19791 self.write_keyword("POSITION");
19792 self.write("(");
19793 self.generate_expression(&f.string)?;
19794 self.write(", ");
19795 self.generate_expression(&f.substring)?;
19796 if let Some(ref start) = f.start {
19797 self.write(", ");
19798 self.generate_expression(start)?;
19799 }
19800 self.write(")");
19801 return Ok(());
19802 }
19803
19804 self.write_keyword("POSITION");
19805 self.write("(");
19806 self.generate_expression(&f.substring)?;
19807 self.write_space();
19808 self.write_keyword("IN");
19809 self.write_space();
19810 self.generate_expression(&f.string)?;
19811 if let Some(ref start) = f.start {
19812 self.write(", ");
19813 self.generate_expression(start)?;
19814 }
19815 self.write(")");
19816 Ok(())
19817 }
19818
19819 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
19822 if f.lower.is_some() || f.upper.is_some() {
19824 self.write_keyword("RANDOM");
19825 self.write("(");
19826 if let Some(ref lower) = f.lower {
19827 self.generate_expression(lower)?;
19828 }
19829 if let Some(ref upper) = f.upper {
19830 self.write(", ");
19831 self.generate_expression(upper)?;
19832 }
19833 self.write(")");
19834 return Ok(());
19835 }
19836 let func_name = match self.config.dialect {
19838 Some(crate::dialects::DialectType::Snowflake)
19839 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
19840 _ => "RAND",
19841 };
19842 self.write_keyword(func_name);
19843 self.write("(");
19844 if !matches!(
19846 self.config.dialect,
19847 Some(crate::dialects::DialectType::DuckDB)
19848 ) {
19849 if let Some(ref seed) = f.seed {
19850 self.generate_expression(seed)?;
19851 }
19852 }
19853 self.write(")");
19854 Ok(())
19855 }
19856
19857 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
19858 self.write_keyword("TRUNCATE");
19859 self.write("(");
19860 self.generate_expression(&f.this)?;
19861 if let Some(ref decimals) = f.decimals {
19862 self.write(", ");
19863 self.generate_expression(decimals)?;
19864 }
19865 self.write(")");
19866 Ok(())
19867 }
19868
19869 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
19872 self.write_keyword("DECODE");
19873 self.write("(");
19874 self.generate_expression(&f.this)?;
19875 for (search, result) in &f.search_results {
19876 self.write(", ");
19877 self.generate_expression(search)?;
19878 self.write(", ");
19879 self.generate_expression(result)?;
19880 }
19881 if let Some(ref default) = f.default {
19882 self.write(", ");
19883 self.generate_expression(default)?;
19884 }
19885 self.write(")");
19886 Ok(())
19887 }
19888
19889 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
19892 self.write_keyword(name);
19893 self.write("(");
19894 self.generate_expression(&f.this)?;
19895 self.write(", ");
19896 self.generate_expression(&f.format)?;
19897 self.write(")");
19898 Ok(())
19899 }
19900
19901 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
19902 self.write_keyword("FROM_UNIXTIME");
19903 self.write("(");
19904 self.generate_expression(&f.this)?;
19905 if let Some(ref format) = f.format {
19906 self.write(", ");
19907 self.generate_expression(format)?;
19908 }
19909 self.write(")");
19910 Ok(())
19911 }
19912
19913 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
19914 self.write_keyword("UNIX_TIMESTAMP");
19915 self.write("(");
19916 if let Some(ref expr) = f.this {
19917 self.generate_expression(expr)?;
19918 if let Some(ref format) = f.format {
19919 self.write(", ");
19920 self.generate_expression(format)?;
19921 }
19922 } else if matches!(
19923 self.config.dialect,
19924 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
19925 ) {
19926 self.write_keyword("CURRENT_TIMESTAMP");
19928 self.write("()");
19929 }
19930 self.write(")");
19931 Ok(())
19932 }
19933
19934 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
19935 self.write_keyword("MAKE_DATE");
19936 self.write("(");
19937 self.generate_expression(&f.year)?;
19938 self.write(", ");
19939 self.generate_expression(&f.month)?;
19940 self.write(", ");
19941 self.generate_expression(&f.day)?;
19942 self.write(")");
19943 Ok(())
19944 }
19945
19946 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
19947 self.write_keyword("MAKE_TIMESTAMP");
19948 self.write("(");
19949 self.generate_expression(&f.year)?;
19950 self.write(", ");
19951 self.generate_expression(&f.month)?;
19952 self.write(", ");
19953 self.generate_expression(&f.day)?;
19954 self.write(", ");
19955 self.generate_expression(&f.hour)?;
19956 self.write(", ");
19957 self.generate_expression(&f.minute)?;
19958 self.write(", ");
19959 self.generate_expression(&f.second)?;
19960 if let Some(ref tz) = f.timezone {
19961 self.write(", ");
19962 self.generate_expression(tz)?;
19963 }
19964 self.write(")");
19965 Ok(())
19966 }
19967
19968 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
19970 match expr {
19971 Expression::Struct(s) => {
19972 if s.fields.iter().all(|(name, _)| name.is_some()) {
19973 Some(
19974 s.fields
19975 .iter()
19976 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
19977 .collect(),
19978 )
19979 } else {
19980 None
19981 }
19982 }
19983 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
19984 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
19986 Some(
19987 f.args
19988 .iter()
19989 .filter_map(|a| {
19990 if let Expression::Alias(alias) = a {
19991 Some(alias.alias.name.clone())
19992 } else {
19993 None
19994 }
19995 })
19996 .collect(),
19997 )
19998 } else {
19999 None
20000 }
20001 }
20002 _ => None,
20003 }
20004 }
20005
20006 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
20008 match expr {
20009 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
20010 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20011 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
20012 }
20013 _ => false,
20014 }
20015 }
20016
20017 fn struct_field_count(expr: &Expression) -> usize {
20019 match expr {
20020 Expression::Struct(s) => s.fields.len(),
20021 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => f.args.len(),
20022 _ => 0,
20023 }
20024 }
20025
20026 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
20028 match expr {
20029 Expression::Struct(s) => {
20030 let mut new_fields = Vec::with_capacity(s.fields.len());
20031 for (i, (name, value)) in s.fields.iter().enumerate() {
20032 if name.is_none() && i < field_names.len() {
20033 new_fields.push((Some(field_names[i].clone()), value.clone()));
20034 } else {
20035 new_fields.push((name.clone(), value.clone()));
20036 }
20037 }
20038 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
20039 }
20040 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20041 let mut new_args = Vec::with_capacity(f.args.len());
20042 for (i, arg) in f.args.iter().enumerate() {
20043 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
20044 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
20046 this: arg.clone(),
20047 alias: crate::expressions::Identifier::new(field_names[i].clone()),
20048 column_aliases: Vec::new(),
20049 pre_alias_comments: Vec::new(),
20050 trailing_comments: Vec::new(),
20051 inferred_type: None,
20052 })));
20053 } else {
20054 new_args.push(arg.clone());
20055 }
20056 }
20057 Expression::Function(Box::new(crate::expressions::Function {
20058 name: f.name.clone(),
20059 args: new_args,
20060 distinct: f.distinct,
20061 trailing_comments: f.trailing_comments.clone(),
20062 use_bracket_syntax: f.use_bracket_syntax,
20063 no_parens: f.no_parens,
20064 quoted: f.quoted,
20065 span: None,
20066 inferred_type: None,
20067 }))
20068 }
20069 _ => expr.clone(),
20070 }
20071 }
20072
20073 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
20077 let first = match expressions.first() {
20078 Some(e) => e,
20079 None => return expressions.to_vec(),
20080 };
20081
20082 let field_names = match Self::extract_struct_field_names(first) {
20083 Some(names) if !names.is_empty() => names,
20084 _ => return expressions.to_vec(),
20085 };
20086
20087 let mut result = Vec::with_capacity(expressions.len());
20088 for (idx, expr) in expressions.iter().enumerate() {
20089 if idx == 0 {
20090 result.push(expr.clone());
20091 continue;
20092 }
20093 if Self::struct_field_count(expr) == field_names.len()
20095 && Self::struct_has_unnamed_fields(expr)
20096 {
20097 result.push(Self::apply_struct_field_names(expr, &field_names));
20098 } else {
20099 result.push(expr.clone());
20100 }
20101 }
20102 result
20103 }
20104
20105 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
20108 let needs_inheritance = matches!(
20111 self.config.dialect,
20112 Some(DialectType::DuckDB)
20113 | Some(DialectType::Spark)
20114 | Some(DialectType::Databricks)
20115 | Some(DialectType::Hive)
20116 | Some(DialectType::Snowflake)
20117 | Some(DialectType::Presto)
20118 | Some(DialectType::Trino)
20119 );
20120 let propagated: Vec<Expression>;
20121 let expressions = if needs_inheritance && f.expressions.len() > 1 {
20122 propagated = Self::inherit_struct_field_names(&f.expressions);
20123 &propagated
20124 } else {
20125 &f.expressions
20126 };
20127
20128 let should_split = if self.config.pretty && !expressions.is_empty() {
20130 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
20131 for expr in expressions {
20132 let mut temp_gen = Generator::with_arc_config(self.config.clone());
20133 Arc::make_mut(&mut temp_gen.config).pretty = false;
20134 temp_gen.generate_expression(expr)?;
20135 expr_strings.push(temp_gen.output);
20136 }
20137 self.too_wide(&expr_strings)
20138 } else {
20139 false
20140 };
20141
20142 if f.bracket_notation {
20143 let (open, close) = match self.config.dialect {
20147 None
20148 | Some(DialectType::Generic)
20149 | Some(DialectType::Spark)
20150 | Some(DialectType::Databricks)
20151 | Some(DialectType::Hive) => {
20152 self.write_keyword("ARRAY");
20153 ("(", ")")
20154 }
20155 Some(DialectType::Presto)
20156 | Some(DialectType::Trino)
20157 | Some(DialectType::PostgreSQL)
20158 | Some(DialectType::Redshift)
20159 | Some(DialectType::Materialize)
20160 | Some(DialectType::RisingWave)
20161 | Some(DialectType::CockroachDB) => {
20162 self.write_keyword("ARRAY");
20163 ("[", "]")
20164 }
20165 _ => ("[", "]"),
20166 };
20167 self.write(open);
20168 if should_split {
20169 self.write_newline();
20170 self.indent_level += 1;
20171 for (i, expr) in expressions.iter().enumerate() {
20172 self.write_indent();
20173 self.generate_expression(expr)?;
20174 if i + 1 < expressions.len() {
20175 self.write(",");
20176 }
20177 self.write_newline();
20178 }
20179 self.indent_level -= 1;
20180 self.write_indent();
20181 } else {
20182 for (i, expr) in expressions.iter().enumerate() {
20183 if i > 0 {
20184 self.write(", ");
20185 }
20186 self.generate_expression(expr)?;
20187 }
20188 }
20189 self.write(close);
20190 } else {
20191 if f.use_list_keyword {
20193 self.write_keyword("LIST");
20194 } else {
20195 self.write_keyword("ARRAY");
20196 }
20197 let has_subquery = expressions
20200 .iter()
20201 .any(|e| matches!(e, Expression::Select(_)));
20202 let (open, close) = if matches!(
20203 self.config.dialect,
20204 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
20205 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
20206 && has_subquery)
20207 {
20208 ("(", ")")
20209 } else {
20210 ("[", "]")
20211 };
20212 self.write(open);
20213 if should_split {
20214 self.write_newline();
20215 self.indent_level += 1;
20216 for (i, expr) in expressions.iter().enumerate() {
20217 self.write_indent();
20218 self.generate_expression(expr)?;
20219 if i + 1 < expressions.len() {
20220 self.write(",");
20221 }
20222 self.write_newline();
20223 }
20224 self.indent_level -= 1;
20225 self.write_indent();
20226 } else {
20227 for (i, expr) in expressions.iter().enumerate() {
20228 if i > 0 {
20229 self.write(", ");
20230 }
20231 self.generate_expression(expr)?;
20232 }
20233 }
20234 self.write(close);
20235 }
20236 Ok(())
20237 }
20238
20239 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
20240 self.write_keyword("ARRAY_SORT");
20241 self.write("(");
20242 self.generate_expression(&f.this)?;
20243 if let Some(ref comp) = f.comparator {
20244 self.write(", ");
20245 self.generate_expression(comp)?;
20246 }
20247 self.write(")");
20248 Ok(())
20249 }
20250
20251 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
20252 self.write_keyword(name);
20253 self.write("(");
20254 self.generate_expression(&f.this)?;
20255 self.write(", ");
20256 self.generate_expression(&f.separator)?;
20257 if let Some(ref null_rep) = f.null_replacement {
20258 self.write(", ");
20259 self.generate_expression(null_rep)?;
20260 }
20261 self.write(")");
20262 Ok(())
20263 }
20264
20265 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
20266 self.write_keyword("UNNEST");
20267 self.write("(");
20268 self.generate_expression(&f.this)?;
20269 for extra in &f.expressions {
20270 self.write(", ");
20271 self.generate_expression(extra)?;
20272 }
20273 self.write(")");
20274 if f.with_ordinality {
20275 self.write_space();
20276 if self.config.unnest_with_ordinality {
20277 self.write_keyword("WITH ORDINALITY");
20279 } else if f.offset_alias.is_some() {
20280 if let Some(ref alias) = f.alias {
20283 self.write_keyword("AS");
20284 self.write_space();
20285 self.generate_identifier(alias)?;
20286 self.write_space();
20287 }
20288 self.write_keyword("WITH OFFSET");
20289 if let Some(ref offset_alias) = f.offset_alias {
20290 self.write_space();
20291 self.write_keyword("AS");
20292 self.write_space();
20293 self.generate_identifier(offset_alias)?;
20294 }
20295 } else {
20296 self.write_keyword("WITH OFFSET");
20298 if f.alias.is_none() {
20299 self.write(" AS offset");
20300 }
20301 }
20302 }
20303 if let Some(ref alias) = f.alias {
20304 let should_add_alias = if !f.with_ordinality {
20306 true
20307 } else if self.config.unnest_with_ordinality {
20308 true
20310 } else if f.offset_alias.is_some() {
20311 false
20313 } else {
20314 true
20316 };
20317 if should_add_alias {
20318 self.write_space();
20319 self.write_keyword("AS");
20320 self.write_space();
20321 self.generate_identifier(alias)?;
20322 }
20323 }
20324 Ok(())
20325 }
20326
20327 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
20328 self.write_keyword("FILTER");
20329 self.write("(");
20330 self.generate_expression(&f.this)?;
20331 self.write(", ");
20332 self.generate_expression(&f.filter)?;
20333 self.write(")");
20334 Ok(())
20335 }
20336
20337 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
20338 self.write_keyword("TRANSFORM");
20339 self.write("(");
20340 self.generate_expression(&f.this)?;
20341 self.write(", ");
20342 self.generate_expression(&f.transform)?;
20343 self.write(")");
20344 Ok(())
20345 }
20346
20347 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
20348 self.write_keyword(name);
20349 self.write("(");
20350 self.generate_expression(&f.start)?;
20351 self.write(", ");
20352 self.generate_expression(&f.stop)?;
20353 if let Some(ref step) = f.step {
20354 self.write(", ");
20355 self.generate_expression(step)?;
20356 }
20357 self.write(")");
20358 Ok(())
20359 }
20360
20361 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
20364 self.write_keyword("STRUCT");
20365 self.write("(");
20366 for (i, (name, expr)) in f.fields.iter().enumerate() {
20367 if i > 0 {
20368 self.write(", ");
20369 }
20370 if let Some(ref id) = name {
20371 self.generate_identifier(id)?;
20372 self.write(" ");
20373 self.write_keyword("AS");
20374 self.write(" ");
20375 }
20376 self.generate_expression(expr)?;
20377 }
20378 self.write(")");
20379 Ok(())
20380 }
20381
20382 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
20384 let mut names: Vec<Option<String>> = Vec::new();
20387 let mut values: Vec<&Expression> = Vec::new();
20388 let mut all_named = true;
20389
20390 for arg in &func.args {
20391 match arg {
20392 Expression::Alias(a) => {
20393 names.push(Some(a.alias.name.clone()));
20394 values.push(&a.this);
20395 }
20396 _ => {
20397 names.push(None);
20398 values.push(arg);
20399 all_named = false;
20400 }
20401 }
20402 }
20403
20404 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
20405 self.write("{");
20407 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20408 if i > 0 {
20409 self.write(", ");
20410 }
20411 if let Some(n) = name {
20412 self.write("'");
20413 self.write(n);
20414 self.write("'");
20415 } else {
20416 self.write("'_");
20417 self.write(&i.to_string());
20418 self.write("'");
20419 }
20420 self.write(": ");
20421 self.generate_expression(value)?;
20422 }
20423 self.write("}");
20424 return Ok(());
20425 }
20426
20427 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
20428 self.write_keyword("OBJECT_CONSTRUCT");
20430 self.write("(");
20431 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20432 if i > 0 {
20433 self.write(", ");
20434 }
20435 if let Some(n) = name {
20436 self.write("'");
20437 self.write(n);
20438 self.write("'");
20439 } else {
20440 self.write("'_");
20441 self.write(&i.to_string());
20442 self.write("'");
20443 }
20444 self.write(", ");
20445 self.generate_expression(value)?;
20446 }
20447 self.write(")");
20448 return Ok(());
20449 }
20450
20451 if matches!(
20452 self.config.dialect,
20453 Some(DialectType::Presto) | Some(DialectType::Trino)
20454 ) {
20455 if all_named && !names.is_empty() {
20456 self.write_keyword("CAST");
20459 self.write("(");
20460 self.write_keyword("ROW");
20461 self.write("(");
20462 for (i, value) in values.iter().enumerate() {
20463 if i > 0 {
20464 self.write(", ");
20465 }
20466 self.generate_expression(value)?;
20467 }
20468 self.write(")");
20469 self.write(" ");
20470 self.write_keyword("AS");
20471 self.write(" ");
20472 self.write_keyword("ROW");
20473 self.write("(");
20474 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20475 if i > 0 {
20476 self.write(", ");
20477 }
20478 if let Some(n) = name {
20479 self.write(n);
20480 }
20481 self.write(" ");
20482 let type_str = Self::infer_sql_type_for_presto(value);
20483 self.write_keyword(&type_str);
20484 }
20485 self.write(")");
20486 self.write(")");
20487 } else {
20488 self.write_keyword("ROW");
20490 self.write("(");
20491 for (i, value) in values.iter().enumerate() {
20492 if i > 0 {
20493 self.write(", ");
20494 }
20495 self.generate_expression(value)?;
20496 }
20497 self.write(")");
20498 }
20499 return Ok(());
20500 }
20501
20502 self.write_keyword("ROW");
20504 self.write("(");
20505 for (i, value) in values.iter().enumerate() {
20506 if i > 0 {
20507 self.write(", ");
20508 }
20509 self.generate_expression(value)?;
20510 }
20511 self.write(")");
20512 Ok(())
20513 }
20514
20515 fn infer_sql_type_for_presto(expr: &Expression) -> String {
20517 match expr {
20518 Expression::Literal(lit)
20519 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
20520 {
20521 "VARCHAR".to_string()
20522 }
20523 Expression::Literal(lit)
20524 if matches!(lit.as_ref(), crate::expressions::Literal::Number(_)) =>
20525 {
20526 let crate::expressions::Literal::Number(n) = lit.as_ref() else {
20527 unreachable!()
20528 };
20529 if n.contains('.') {
20530 "DOUBLE".to_string()
20531 } else {
20532 "INTEGER".to_string()
20533 }
20534 }
20535 Expression::Boolean(_) => "BOOLEAN".to_string(),
20536 Expression::Literal(lit)
20537 if matches!(lit.as_ref(), crate::expressions::Literal::Date(_)) =>
20538 {
20539 "DATE".to_string()
20540 }
20541 Expression::Literal(lit)
20542 if matches!(lit.as_ref(), crate::expressions::Literal::Timestamp(_)) =>
20543 {
20544 "TIMESTAMP".to_string()
20545 }
20546 Expression::Literal(lit)
20547 if matches!(lit.as_ref(), crate::expressions::Literal::Datetime(_)) =>
20548 {
20549 "TIMESTAMP".to_string()
20550 }
20551 Expression::Array(_) | Expression::ArrayFunc(_) => {
20552 "ARRAY(VARCHAR)".to_string()
20554 }
20555 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
20557 Expression::Function(f) => {
20558 if f.name.eq_ignore_ascii_case("STRUCT") {
20559 "ROW".to_string()
20560 } else if f.name.eq_ignore_ascii_case("CURRENT_DATE") {
20561 "DATE".to_string()
20562 } else if f.name.eq_ignore_ascii_case("CURRENT_TIMESTAMP")
20563 || f.name.eq_ignore_ascii_case("NOW")
20564 {
20565 "TIMESTAMP".to_string()
20566 } else {
20567 "VARCHAR".to_string()
20568 }
20569 }
20570 _ => "VARCHAR".to_string(),
20571 }
20572 }
20573
20574 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
20575 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
20577 self.write_keyword("STRUCT_EXTRACT");
20578 self.write("(");
20579 self.generate_expression(&f.this)?;
20580 self.write(", ");
20581 self.write("'");
20583 self.write(&f.field.name);
20584 self.write("'");
20585 self.write(")");
20586 return Ok(());
20587 }
20588 self.generate_expression(&f.this)?;
20589 self.write(".");
20590 self.generate_identifier(&f.field)
20591 }
20592
20593 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
20594 self.write_keyword("NAMED_STRUCT");
20595 self.write("(");
20596 for (i, (name, value)) in f.pairs.iter().enumerate() {
20597 if i > 0 {
20598 self.write(", ");
20599 }
20600 self.generate_expression(name)?;
20601 self.write(", ");
20602 self.generate_expression(value)?;
20603 }
20604 self.write(")");
20605 Ok(())
20606 }
20607
20608 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
20611 if f.curly_brace_syntax {
20612 if f.with_map_keyword {
20614 self.write_keyword("MAP");
20615 self.write(" ");
20616 }
20617 self.write("{");
20618 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
20619 if i > 0 {
20620 self.write(", ");
20621 }
20622 self.generate_expression(key)?;
20623 self.write(": ");
20624 self.generate_expression(val)?;
20625 }
20626 self.write("}");
20627 } else {
20628 self.write_keyword("MAP");
20630 self.write("(");
20631 self.write_keyword("ARRAY");
20632 self.write("[");
20633 for (i, key) in f.keys.iter().enumerate() {
20634 if i > 0 {
20635 self.write(", ");
20636 }
20637 self.generate_expression(key)?;
20638 }
20639 self.write("], ");
20640 self.write_keyword("ARRAY");
20641 self.write("[");
20642 for (i, val) in f.values.iter().enumerate() {
20643 if i > 0 {
20644 self.write(", ");
20645 }
20646 self.generate_expression(val)?;
20647 }
20648 self.write("])");
20649 }
20650 Ok(())
20651 }
20652
20653 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
20654 self.write_keyword(name);
20655 self.write("(");
20656 self.generate_expression(&f.this)?;
20657 self.write(", ");
20658 self.generate_expression(&f.transform)?;
20659 self.write(")");
20660 Ok(())
20661 }
20662
20663 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
20666 use crate::dialects::DialectType;
20667
20668 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
20670
20671 if use_arrow {
20672 self.generate_expression(&f.this)?;
20674 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
20675 self.write(" ->> ");
20676 } else {
20677 self.write(" -> ");
20678 }
20679 self.generate_expression(&f.path)?;
20680 return Ok(());
20681 }
20682
20683 if f.hash_arrow_syntax
20685 && matches!(
20686 self.config.dialect,
20687 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
20688 )
20689 {
20690 self.generate_expression(&f.this)?;
20691 self.write(" #>> ");
20692 self.generate_expression(&f.path)?;
20693 return Ok(());
20694 }
20695
20696 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
20699 match name {
20700 "JSON_EXTRACT_SCALAR"
20701 | "JSON_EXTRACT_PATH_TEXT"
20702 | "JSON_EXTRACT"
20703 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
20704 _ => name,
20705 }
20706 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
20707 match name {
20708 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
20709 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
20710 _ => name,
20711 }
20712 } else {
20713 name
20714 };
20715
20716 self.write_keyword(func_name);
20717 self.write("(");
20718 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
20720 if let Expression::Cast(ref cast) = f.this {
20721 if matches!(cast.to, crate::expressions::DataType::Json) {
20722 self.generate_expression(&cast.this)?;
20723 } else {
20724 self.generate_expression(&f.this)?;
20725 }
20726 } else {
20727 self.generate_expression(&f.this)?;
20728 }
20729 } else {
20730 self.generate_expression(&f.this)?;
20731 }
20732 if matches!(
20735 self.config.dialect,
20736 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
20737 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
20738 {
20739 if let Expression::Literal(ref lit) = f.path {
20740 if let Literal::String(ref s) = lit.as_ref() {
20741 let parts = Self::decompose_json_path(s);
20742 for part in &parts {
20743 self.write(", '");
20744 self.write(part);
20745 self.write("'");
20746 }
20747 }
20748 } else {
20749 self.write(", ");
20750 self.generate_expression(&f.path)?;
20751 }
20752 } else {
20753 self.write(", ");
20754 self.generate_expression(&f.path)?;
20755 }
20756
20757 if let Some(ref wrapper) = f.wrapper_option {
20760 self.write_space();
20761 self.write_keyword(wrapper);
20762 }
20763 if let Some(ref quotes) = f.quotes_option {
20764 self.write_space();
20765 self.write_keyword(quotes);
20766 if f.on_scalar_string {
20767 self.write_space();
20768 self.write_keyword("ON SCALAR STRING");
20769 }
20770 }
20771 if let Some(ref on_err) = f.on_error {
20772 self.write_space();
20773 self.write_keyword(on_err);
20774 }
20775 if let Some(ref ret_type) = f.returning {
20776 self.write_space();
20777 self.write_keyword("RETURNING");
20778 self.write_space();
20779 self.generate_data_type(ret_type)?;
20780 }
20781
20782 self.write(")");
20783 Ok(())
20784 }
20785
20786 fn dialect_supports_json_arrow(&self) -> bool {
20788 use crate::dialects::DialectType;
20789 match self.config.dialect {
20790 Some(DialectType::PostgreSQL) => true,
20792 Some(DialectType::MySQL) => true,
20793 Some(DialectType::DuckDB) => true,
20794 Some(DialectType::CockroachDB) => true,
20795 Some(DialectType::StarRocks) => true,
20796 Some(DialectType::SQLite) => true,
20797 _ => false,
20799 }
20800 }
20801
20802 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
20803 use crate::dialects::DialectType;
20804
20805 if matches!(
20807 self.config.dialect,
20808 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
20809 ) && name == "JSON_EXTRACT_PATH"
20810 {
20811 self.generate_expression(&f.this)?;
20812 self.write(" #> ");
20813 if f.paths.len() == 1 {
20814 self.generate_expression(&f.paths[0])?;
20815 } else {
20816 self.write_keyword("ARRAY");
20818 self.write("[");
20819 for (i, path) in f.paths.iter().enumerate() {
20820 if i > 0 {
20821 self.write(", ");
20822 }
20823 self.generate_expression(path)?;
20824 }
20825 self.write("]");
20826 }
20827 return Ok(());
20828 }
20829
20830 self.write_keyword(name);
20831 self.write("(");
20832 self.generate_expression(&f.this)?;
20833 for path in &f.paths {
20834 self.write(", ");
20835 self.generate_expression(path)?;
20836 }
20837 self.write(")");
20838 Ok(())
20839 }
20840
20841 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
20842 use crate::dialects::DialectType;
20843
20844 self.write_keyword("JSON_OBJECT");
20845 self.write("(");
20846 if f.star {
20847 self.write("*");
20848 } else {
20849 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
20853 || matches!(
20854 self.config.dialect,
20855 Some(DialectType::BigQuery)
20856 | Some(DialectType::MySQL)
20857 | Some(DialectType::SQLite)
20858 );
20859
20860 for (i, (key, value)) in f.pairs.iter().enumerate() {
20861 if i > 0 {
20862 self.write(", ");
20863 }
20864 self.generate_expression(key)?;
20865 if use_comma_syntax {
20866 self.write(", ");
20867 } else {
20868 self.write(": ");
20869 }
20870 self.generate_expression(value)?;
20871 }
20872 }
20873 if let Some(null_handling) = f.null_handling {
20874 self.write_space();
20875 match null_handling {
20876 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
20877 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
20878 }
20879 }
20880 if f.with_unique_keys {
20881 self.write_space();
20882 self.write_keyword("WITH UNIQUE KEYS");
20883 }
20884 if let Some(ref ret_type) = f.returning_type {
20885 self.write_space();
20886 self.write_keyword("RETURNING");
20887 self.write_space();
20888 self.generate_data_type(ret_type)?;
20889 if f.format_json {
20890 self.write_space();
20891 self.write_keyword("FORMAT JSON");
20892 }
20893 if let Some(ref enc) = f.encoding {
20894 self.write_space();
20895 self.write_keyword("ENCODING");
20896 self.write_space();
20897 self.write(enc);
20898 }
20899 }
20900 self.write(")");
20901 Ok(())
20902 }
20903
20904 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
20905 self.write_keyword(name);
20906 self.write("(");
20907 self.generate_expression(&f.this)?;
20908 for (path, value) in &f.path_values {
20909 self.write(", ");
20910 self.generate_expression(path)?;
20911 self.write(", ");
20912 self.generate_expression(value)?;
20913 }
20914 self.write(")");
20915 Ok(())
20916 }
20917
20918 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
20919 self.write_keyword("JSON_ARRAYAGG");
20920 self.write("(");
20921 self.generate_expression(&f.this)?;
20922 if let Some(ref order_by) = f.order_by {
20923 self.write_space();
20924 self.write_keyword("ORDER BY");
20925 self.write_space();
20926 for (i, ord) in order_by.iter().enumerate() {
20927 if i > 0 {
20928 self.write(", ");
20929 }
20930 self.generate_ordered(ord)?;
20931 }
20932 }
20933 if let Some(null_handling) = f.null_handling {
20934 self.write_space();
20935 match null_handling {
20936 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
20937 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
20938 }
20939 }
20940 self.write(")");
20941 if let Some(ref filter) = f.filter {
20942 self.write_space();
20943 self.write_keyword("FILTER");
20944 self.write("(");
20945 self.write_keyword("WHERE");
20946 self.write_space();
20947 self.generate_expression(filter)?;
20948 self.write(")");
20949 }
20950 Ok(())
20951 }
20952
20953 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
20954 self.write_keyword("JSON_OBJECTAGG");
20955 self.write("(");
20956 self.generate_expression(&f.key)?;
20957 self.write(": ");
20958 self.generate_expression(&f.value)?;
20959 if let Some(null_handling) = f.null_handling {
20960 self.write_space();
20961 match null_handling {
20962 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
20963 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
20964 }
20965 }
20966 self.write(")");
20967 if let Some(ref filter) = f.filter {
20968 self.write_space();
20969 self.write_keyword("FILTER");
20970 self.write("(");
20971 self.write_keyword("WHERE");
20972 self.write_space();
20973 self.generate_expression(filter)?;
20974 self.write(")");
20975 }
20976 Ok(())
20977 }
20978
20979 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
20982 use crate::dialects::DialectType;
20983
20984 if self.config.dialect == Some(DialectType::Redshift) {
20986 self.write_keyword("CAST");
20987 self.write("(");
20988 self.generate_expression(&f.this)?;
20989 self.write_space();
20990 self.write_keyword("AS");
20991 self.write_space();
20992 self.generate_data_type(&f.to)?;
20993 self.write(")");
20994 return Ok(());
20995 }
20996
20997 self.write_keyword("CONVERT");
20998 self.write("(");
20999 self.generate_data_type(&f.to)?;
21000 self.write(", ");
21001 self.generate_expression(&f.this)?;
21002 if let Some(ref style) = f.style {
21003 self.write(", ");
21004 self.generate_expression(style)?;
21005 }
21006 self.write(")");
21007 Ok(())
21008 }
21009
21010 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
21013 if f.colon {
21014 self.write_keyword("LAMBDA");
21016 self.write_space();
21017 for (i, param) in f.parameters.iter().enumerate() {
21018 if i > 0 {
21019 self.write(", ");
21020 }
21021 self.generate_identifier(param)?;
21022 }
21023 self.write(" : ");
21024 } else {
21025 if f.parameters.len() == 1 {
21027 self.generate_identifier(&f.parameters[0])?;
21028 } else {
21029 self.write("(");
21030 for (i, param) in f.parameters.iter().enumerate() {
21031 if i > 0 {
21032 self.write(", ");
21033 }
21034 self.generate_identifier(param)?;
21035 }
21036 self.write(")");
21037 }
21038 self.write(" -> ");
21039 }
21040 self.generate_expression(&f.body)
21041 }
21042
21043 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
21044 self.generate_identifier(&f.name)?;
21045 match f.separator {
21046 NamedArgSeparator::DArrow => self.write(" => "),
21047 NamedArgSeparator::ColonEq => self.write(" := "),
21048 NamedArgSeparator::Eq => self.write(" = "),
21049 }
21050 self.generate_expression(&f.value)
21051 }
21052
21053 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
21054 self.write_keyword(&f.prefix);
21055 self.write(" ");
21056 self.generate_expression(&f.this)
21057 }
21058
21059 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
21060 match f.style {
21061 ParameterStyle::Question => self.write("?"),
21062 ParameterStyle::Dollar => {
21063 self.write("$");
21064 if let Some(idx) = f.index {
21065 self.write(&idx.to_string());
21066 } else if let Some(ref name) = f.name {
21067 self.write(name);
21069 }
21070 }
21071 ParameterStyle::DollarBrace => {
21072 self.write("${");
21074 if let Some(ref name) = f.name {
21075 self.write(name);
21076 }
21077 if let Some(ref expr) = f.expression {
21078 self.write(":");
21079 self.write(expr);
21080 }
21081 self.write("}");
21082 }
21083 ParameterStyle::Colon => {
21084 self.write(":");
21085 if let Some(idx) = f.index {
21086 self.write(&idx.to_string());
21087 } else if let Some(ref name) = f.name {
21088 self.write(name);
21089 }
21090 }
21091 ParameterStyle::At => {
21092 self.write("@");
21093 if let Some(ref name) = f.name {
21094 if f.string_quoted {
21095 self.write("'");
21096 self.write(name);
21097 self.write("'");
21098 } else if f.quoted {
21099 self.write("\"");
21100 self.write(name);
21101 self.write("\"");
21102 } else {
21103 self.write(name);
21104 }
21105 }
21106 }
21107 ParameterStyle::DoubleAt => {
21108 self.write("@@");
21109 if let Some(ref name) = f.name {
21110 self.write(name);
21111 }
21112 }
21113 ParameterStyle::DoubleDollar => {
21114 self.write("$$");
21115 if let Some(ref name) = f.name {
21116 self.write(name);
21117 }
21118 }
21119 ParameterStyle::Percent => {
21120 if let Some(ref name) = f.name {
21121 self.write("%(");
21123 self.write(name);
21124 self.write(")s");
21125 } else {
21126 self.write("%s");
21128 }
21129 }
21130 ParameterStyle::Brace => {
21131 self.write("{");
21134 if let Some(ref name) = f.name {
21135 self.write(name);
21136 }
21137 if let Some(ref expr) = f.expression {
21138 self.write(": ");
21139 self.write(expr);
21140 }
21141 self.write("}");
21142 }
21143 }
21144 Ok(())
21145 }
21146
21147 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
21148 self.write("?");
21149 if let Some(idx) = f.index {
21150 self.write(&idx.to_string());
21151 }
21152 Ok(())
21153 }
21154
21155 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
21156 if f.is_block {
21157 self.write("/*");
21158 self.write(&f.text);
21159 self.write("*/");
21160 } else {
21161 self.write("--");
21162 self.write(&f.text);
21163 }
21164 Ok(())
21165 }
21166
21167 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
21170 self.generate_expression(&f.this)?;
21171 if f.not {
21172 self.write_space();
21173 self.write_keyword("NOT");
21174 }
21175 self.write_space();
21176 self.write_keyword("SIMILAR TO");
21177 self.write_space();
21178 self.generate_expression(&f.pattern)?;
21179 if let Some(ref escape) = f.escape {
21180 self.write_space();
21181 self.write_keyword("ESCAPE");
21182 self.write_space();
21183 self.generate_expression(escape)?;
21184 }
21185 Ok(())
21186 }
21187
21188 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
21189 self.generate_expression(&f.this)?;
21190 self.write_space();
21191 if let Some(op) = &f.op {
21193 match op {
21194 QuantifiedOp::Eq => self.write("="),
21195 QuantifiedOp::Neq => self.write("<>"),
21196 QuantifiedOp::Lt => self.write("<"),
21197 QuantifiedOp::Lte => self.write("<="),
21198 QuantifiedOp::Gt => self.write(">"),
21199 QuantifiedOp::Gte => self.write(">="),
21200 }
21201 self.write_space();
21202 }
21203 self.write_keyword(name);
21204
21205 if matches!(&f.subquery, Expression::Subquery(_)) {
21207 self.write_space();
21208 self.generate_expression(&f.subquery)?;
21209 } else {
21210 self.write("(");
21211
21212 let is_statement = matches!(
21213 &f.subquery,
21214 Expression::Select(_)
21215 | Expression::Union(_)
21216 | Expression::Intersect(_)
21217 | Expression::Except(_)
21218 );
21219
21220 if self.config.pretty && is_statement {
21221 self.write_newline();
21222 self.indent_level += 1;
21223 self.write_indent();
21224 }
21225 self.generate_expression(&f.subquery)?;
21226 if self.config.pretty && is_statement {
21227 self.write_newline();
21228 self.indent_level -= 1;
21229 self.write_indent();
21230 }
21231 self.write(")");
21232 }
21233 Ok(())
21234 }
21235
21236 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
21237 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
21239 self.generate_expression(this)?;
21240 self.write_space();
21241 self.write_keyword("OVERLAPS");
21242 self.write_space();
21243 self.generate_expression(expr)?;
21244 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
21245 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
21246 {
21247 self.write("(");
21249 self.generate_expression(ls)?;
21250 self.write(", ");
21251 self.generate_expression(le)?;
21252 self.write(")");
21253 self.write_space();
21254 self.write_keyword("OVERLAPS");
21255 self.write_space();
21256 self.write("(");
21257 self.generate_expression(rs)?;
21258 self.write(", ");
21259 self.generate_expression(re)?;
21260 self.write(")");
21261 }
21262 Ok(())
21263 }
21264
21265 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
21268 use crate::dialects::DialectType;
21269
21270 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
21272 self.generate_expression(&cast.this)?;
21273 self.write(" !:> ");
21274 self.generate_data_type(&cast.to)?;
21275 return Ok(());
21276 }
21277
21278 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
21280 self.write_keyword("TRYCAST");
21281 self.write("(");
21282 self.generate_expression(&cast.this)?;
21283 self.write_space();
21284 self.write_keyword("AS");
21285 self.write_space();
21286 self.generate_data_type(&cast.to)?;
21287 self.write(")");
21288 return Ok(());
21289 }
21290
21291 let keyword = if matches!(
21293 self.config.dialect,
21294 Some(DialectType::Hive)
21295 | Some(DialectType::MySQL)
21296 | Some(DialectType::SQLite)
21297 | Some(DialectType::Oracle)
21298 | Some(DialectType::ClickHouse)
21299 | Some(DialectType::Redshift)
21300 | Some(DialectType::PostgreSQL)
21301 | Some(DialectType::StarRocks)
21302 | Some(DialectType::Doris)
21303 ) {
21304 "CAST"
21305 } else {
21306 "TRY_CAST"
21307 };
21308
21309 self.write_keyword(keyword);
21310 self.write("(");
21311 self.generate_expression(&cast.this)?;
21312 self.write_space();
21313 self.write_keyword("AS");
21314 self.write_space();
21315 self.generate_data_type(&cast.to)?;
21316
21317 if let Some(format) = &cast.format {
21319 self.write_space();
21320 self.write_keyword("FORMAT");
21321 self.write_space();
21322 self.generate_expression(format)?;
21323 }
21324
21325 self.write(")");
21326 Ok(())
21327 }
21328
21329 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
21330 self.write_keyword("SAFE_CAST");
21331 self.write("(");
21332 self.generate_expression(&cast.this)?;
21333 self.write_space();
21334 self.write_keyword("AS");
21335 self.write_space();
21336 self.generate_data_type(&cast.to)?;
21337
21338 if let Some(format) = &cast.format {
21340 self.write_space();
21341 self.write_keyword("FORMAT");
21342 self.write_space();
21343 self.generate_expression(format)?;
21344 }
21345
21346 self.write(")");
21347 Ok(())
21348 }
21349
21350 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
21353 let needs_parens = matches!(&s.this, Expression::JsonExtract(ref f) if f.arrow_syntax);
21357 if needs_parens {
21358 self.write("(");
21359 }
21360 self.generate_expression(&s.this)?;
21361 if needs_parens {
21362 self.write(")");
21363 }
21364 self.write("[");
21365 self.generate_expression(&s.index)?;
21366 self.write("]");
21367 Ok(())
21368 }
21369
21370 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
21371 self.generate_expression(&d.this)?;
21372 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
21375 && matches!(
21376 &d.this,
21377 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
21378 );
21379 if use_colon {
21380 self.write(":");
21381 } else {
21382 self.write(".");
21383 }
21384 self.generate_identifier(&d.field)
21385 }
21386
21387 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
21388 self.generate_expression(&m.this)?;
21389 self.write(".");
21390 if m.method.quoted {
21393 let q = self.config.identifier_quote;
21394 self.write(&format!("{}{}{}", q, m.method.name, q));
21395 } else {
21396 self.write(&m.method.name);
21397 }
21398 self.write("(");
21399 for (i, arg) in m.args.iter().enumerate() {
21400 if i > 0 {
21401 self.write(", ");
21402 }
21403 self.generate_expression(arg)?;
21404 }
21405 self.write(")");
21406 Ok(())
21407 }
21408
21409 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
21410 let needs_parens = matches!(
21413 &s.this,
21414 Expression::JsonExtract(f) if f.arrow_syntax
21415 ) || matches!(
21416 &s.this,
21417 Expression::JsonExtractScalar(f) if f.arrow_syntax
21418 );
21419
21420 if needs_parens {
21421 self.write("(");
21422 }
21423 self.generate_expression(&s.this)?;
21424 if needs_parens {
21425 self.write(")");
21426 }
21427 self.write("[");
21428 if let Some(start) = &s.start {
21429 self.generate_expression(start)?;
21430 }
21431 self.write(":");
21432 if let Some(end) = &s.end {
21433 self.generate_expression(end)?;
21434 }
21435 self.write("]");
21436 Ok(())
21437 }
21438
21439 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
21440 match &op.left {
21444 Expression::Column(col) => {
21445 if let Some(table) = &col.table {
21448 self.generate_identifier(table)?;
21449 self.write(".");
21450 }
21451 self.generate_identifier(&col.name)?;
21452 if col.join_mark && self.config.supports_column_join_marks {
21454 self.write(" (+)");
21455 }
21456 if op.left_comments.is_empty() {
21458 for comment in &col.trailing_comments {
21459 self.write_space();
21460 self.write_formatted_comment(comment);
21461 }
21462 }
21463 }
21464 Expression::Add(inner_op)
21465 | Expression::Sub(inner_op)
21466 | Expression::Mul(inner_op)
21467 | Expression::Div(inner_op)
21468 | Expression::Concat(inner_op) => {
21469 self.generate_binary_op_no_trailing(inner_op, match &op.left {
21471 Expression::Add(_) => "+",
21472 Expression::Sub(_) => "-",
21473 Expression::Mul(_) => "*",
21474 Expression::Div(_) => "/",
21475 Expression::Concat(_) => "||",
21476 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
21477 })?;
21478 }
21479 _ => {
21480 self.generate_expression(&op.left)?;
21481 }
21482 }
21483 for comment in &op.left_comments {
21485 self.write_space();
21486 self.write_formatted_comment(comment);
21487 }
21488 if self.config.pretty
21489 && matches!(self.config.dialect, Some(DialectType::Snowflake))
21490 && (operator == "AND" || operator == "OR")
21491 {
21492 self.write_newline();
21493 self.write_indent();
21494 self.write_keyword(operator);
21495 } else {
21496 self.write_space();
21497 if operator.chars().all(|c| c.is_alphabetic()) {
21498 self.write_keyword(operator);
21499 } else {
21500 self.write(operator);
21501 }
21502 }
21503 for comment in &op.operator_comments {
21505 self.write_space();
21506 self.write_formatted_comment(comment);
21507 }
21508 self.write_space();
21509 self.generate_expression(&op.right)?;
21510 for comment in &op.trailing_comments {
21512 self.write_space();
21513 self.write_formatted_comment(comment);
21514 }
21515 Ok(())
21516 }
21517
21518 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
21519 let keyword = connector.keyword();
21520 let Some(terms) = self.flatten_connector_terms(op, connector) else {
21521 return self.generate_binary_op(op, keyword);
21522 };
21523
21524 self.generate_expression(terms[0])?;
21525 for term in terms.iter().skip(1) {
21526 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
21527 self.write_newline();
21528 self.write_indent();
21529 self.write_keyword(keyword);
21530 } else {
21531 self.write_space();
21532 self.write_keyword(keyword);
21533 }
21534 self.write_space();
21535 self.generate_expression(term)?;
21536 }
21537
21538 Ok(())
21539 }
21540
21541 fn flatten_connector_terms<'a>(
21542 &self,
21543 root: &'a BinaryOp,
21544 connector: ConnectorOperator,
21545 ) -> Option<Vec<&'a Expression>> {
21546 if !root.left_comments.is_empty()
21547 || !root.operator_comments.is_empty()
21548 || !root.trailing_comments.is_empty()
21549 {
21550 return None;
21551 }
21552
21553 let mut terms = Vec::new();
21554 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
21555
21556 while let Some(expr) = stack.pop() {
21557 match (connector, expr) {
21558 (ConnectorOperator::And, Expression::And(inner))
21559 if inner.left_comments.is_empty()
21560 && inner.operator_comments.is_empty()
21561 && inner.trailing_comments.is_empty() =>
21562 {
21563 stack.push(&inner.right);
21564 stack.push(&inner.left);
21565 }
21566 (ConnectorOperator::Or, Expression::Or(inner))
21567 if inner.left_comments.is_empty()
21568 && inner.operator_comments.is_empty()
21569 && inner.trailing_comments.is_empty() =>
21570 {
21571 stack.push(&inner.right);
21572 stack.push(&inner.left);
21573 }
21574 _ => terms.push(expr),
21575 }
21576 }
21577
21578 if terms.len() > 1 {
21579 Some(terms)
21580 } else {
21581 None
21582 }
21583 }
21584
21585 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
21587 self.generate_expression(&op.left)?;
21588 self.write_space();
21589 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
21591 self.write("`ILIKE`");
21592 } else {
21593 self.write_keyword(operator);
21594 }
21595 if let Some(quantifier) = &op.quantifier {
21596 self.write_space();
21597 self.write_keyword(quantifier);
21598 let is_any =
21603 quantifier.eq_ignore_ascii_case("ANY") || quantifier.eq_ignore_ascii_case("SOME");
21604 if !(is_any && matches!(&op.right, Expression::Paren(_))) {
21605 self.write_space();
21606 }
21607 } else {
21608 self.write_space();
21609 }
21610 self.generate_expression(&op.right)?;
21611 if let Some(escape) = &op.escape {
21612 self.write_space();
21613 self.write_keyword("ESCAPE");
21614 self.write_space();
21615 self.generate_expression(escape)?;
21616 }
21617 Ok(())
21618 }
21619
21620 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
21623 use crate::dialects::DialectType;
21624 self.generate_expression(&op.left)?;
21625 self.write_space();
21626 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
21627 self.write("<=>");
21628 } else {
21629 self.write_keyword("IS NOT DISTINCT FROM");
21630 }
21631 self.write_space();
21632 self.generate_expression(&op.right)?;
21633 Ok(())
21634 }
21635
21636 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
21638 self.generate_expression(&op.left)?;
21639 self.write_space();
21640 self.write_keyword("IS DISTINCT FROM");
21641 self.write_space();
21642 self.generate_expression(&op.right)?;
21643 Ok(())
21644 }
21645
21646 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
21648 match &op.left {
21650 Expression::Column(col) => {
21651 if let Some(table) = &col.table {
21652 self.generate_identifier(table)?;
21653 self.write(".");
21654 }
21655 self.generate_identifier(&col.name)?;
21656 if col.join_mark && self.config.supports_column_join_marks {
21658 self.write(" (+)");
21659 }
21660 }
21661 Expression::Add(inner_op)
21662 | Expression::Sub(inner_op)
21663 | Expression::Mul(inner_op)
21664 | Expression::Div(inner_op)
21665 | Expression::Concat(inner_op) => {
21666 self.generate_binary_op_no_trailing(inner_op, match &op.left {
21667 Expression::Add(_) => "+",
21668 Expression::Sub(_) => "-",
21669 Expression::Mul(_) => "*",
21670 Expression::Div(_) => "/",
21671 Expression::Concat(_) => "||",
21672 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
21673 })?;
21674 }
21675 _ => {
21676 self.generate_expression(&op.left)?;
21677 }
21678 }
21679 for comment in &op.left_comments {
21681 self.write_space();
21682 self.write_formatted_comment(comment);
21683 }
21684 self.write_space();
21685 if operator.chars().all(|c| c.is_alphabetic()) {
21686 self.write_keyword(operator);
21687 } else {
21688 self.write(operator);
21689 }
21690 for comment in &op.operator_comments {
21692 self.write_space();
21693 self.write_formatted_comment(comment);
21694 }
21695 self.write_space();
21696 match &op.right {
21699 Expression::Column(col) => {
21700 if let Some(table) = &col.table {
21701 self.generate_identifier(table)?;
21702 self.write(".");
21703 }
21704 self.generate_identifier(&col.name)?;
21705 if col.join_mark && self.config.supports_column_join_marks {
21707 self.write(" (+)");
21708 }
21709 }
21710 _ => {
21711 self.generate_expression(&op.right)?;
21712 }
21713 }
21714 Ok(())
21716 }
21717
21718 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
21719 if operator.chars().all(|c| c.is_alphabetic()) {
21720 self.write_keyword(operator);
21721 self.write_space();
21722 } else {
21723 self.write(operator);
21724 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
21726 self.write_space();
21727 }
21728 }
21729 self.generate_expression(&op.this)
21730 }
21731
21732 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
21733 let is_generic =
21737 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
21738 let use_prefix_not =
21739 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
21740 if use_prefix_not {
21741 self.write_keyword("NOT");
21742 self.write_space();
21743 }
21744 self.generate_expression(&in_expr.this)?;
21745 if in_expr.global {
21746 self.write_space();
21747 self.write_keyword("GLOBAL");
21748 }
21749 if in_expr.not && !use_prefix_not {
21750 self.write_space();
21751 self.write_keyword("NOT");
21752 }
21753 self.write_space();
21754 self.write_keyword("IN");
21755
21756 if let Some(unnest_expr) = &in_expr.unnest {
21758 self.write_space();
21759 self.write_keyword("UNNEST");
21760 self.write("(");
21761 self.generate_expression(unnest_expr)?;
21762 self.write(")");
21763 return Ok(());
21764 }
21765
21766 if let Some(query) = &in_expr.query {
21767 let is_bare = in_expr.expressions.is_empty()
21770 && !matches!(
21771 query,
21772 Expression::Select(_)
21773 | Expression::Union(_)
21774 | Expression::Intersect(_)
21775 | Expression::Except(_)
21776 | Expression::Subquery(_)
21777 );
21778 if is_bare {
21779 self.write_space();
21781 self.generate_expression(query)?;
21782 } else {
21783 self.write(" (");
21785 let is_statement = matches!(
21786 query,
21787 Expression::Select(_)
21788 | Expression::Union(_)
21789 | Expression::Intersect(_)
21790 | Expression::Except(_)
21791 | Expression::Subquery(_)
21792 );
21793 if self.config.pretty && is_statement {
21794 self.write_newline();
21795 self.indent_level += 1;
21796 self.write_indent();
21797 }
21798 self.generate_expression(query)?;
21799 if self.config.pretty && is_statement {
21800 self.write_newline();
21801 self.indent_level -= 1;
21802 self.write_indent();
21803 }
21804 self.write(")");
21805 }
21806 } else {
21807 let is_duckdb = matches!(
21811 self.config.dialect,
21812 Some(crate::dialects::DialectType::DuckDB)
21813 );
21814 let is_clickhouse = matches!(
21815 self.config.dialect,
21816 Some(crate::dialects::DialectType::ClickHouse)
21817 );
21818 let single_expr = in_expr.expressions.len() == 1;
21819 if is_clickhouse && single_expr {
21820 if let Expression::Array(arr) = &in_expr.expressions[0] {
21821 self.write(" (");
21823 for (i, expr) in arr.expressions.iter().enumerate() {
21824 if i > 0 {
21825 self.write(", ");
21826 }
21827 self.generate_expression(expr)?;
21828 }
21829 self.write(")");
21830 } else {
21831 self.write_space();
21832 self.generate_expression(&in_expr.expressions[0])?;
21833 }
21834 } else {
21835 let is_bare_ref = single_expr
21836 && matches!(
21837 &in_expr.expressions[0],
21838 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
21839 );
21840 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
21841 self.write_space();
21844 self.generate_expression(&in_expr.expressions[0])?;
21845 } else {
21846 self.write(" (");
21848 for (i, expr) in in_expr.expressions.iter().enumerate() {
21849 if i > 0 {
21850 self.write(", ");
21851 }
21852 self.generate_expression(expr)?;
21853 }
21854 self.write(")");
21855 }
21856 }
21857 }
21858
21859 Ok(())
21860 }
21861
21862 fn generate_between(&mut self, between: &Between) -> Result<()> {
21863 let use_prefix_not = between.not
21865 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
21866 if use_prefix_not {
21867 self.write_keyword("NOT");
21868 self.write_space();
21869 }
21870 self.generate_expression(&between.this)?;
21871 if between.not && !use_prefix_not {
21872 self.write_space();
21873 self.write_keyword("NOT");
21874 }
21875 self.write_space();
21876 self.write_keyword("BETWEEN");
21877 if let Some(sym) = between.symmetric {
21879 if sym {
21880 self.write(" SYMMETRIC");
21881 } else {
21882 self.write(" ASYMMETRIC");
21883 }
21884 }
21885 self.write_space();
21886 self.generate_expression(&between.low)?;
21887 self.write_space();
21888 self.write_keyword("AND");
21889 self.write_space();
21890 self.generate_expression(&between.high)
21891 }
21892
21893 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
21894 let use_prefix_not = is_null.not
21896 && (self.config.dialect.is_none()
21897 || self.config.dialect == Some(DialectType::Generic)
21898 || is_null.postfix_form);
21899 if use_prefix_not {
21900 self.write_keyword("NOT");
21902 self.write_space();
21903 self.generate_expression(&is_null.this)?;
21904 self.write_space();
21905 self.write_keyword("IS");
21906 self.write_space();
21907 self.write_keyword("NULL");
21908 } else {
21909 self.generate_expression(&is_null.this)?;
21910 self.write_space();
21911 self.write_keyword("IS");
21912 if is_null.not {
21913 self.write_space();
21914 self.write_keyword("NOT");
21915 }
21916 self.write_space();
21917 self.write_keyword("NULL");
21918 }
21919 Ok(())
21920 }
21921
21922 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
21923 self.generate_expression(&is_true.this)?;
21924 self.write_space();
21925 self.write_keyword("IS");
21926 if is_true.not {
21927 self.write_space();
21928 self.write_keyword("NOT");
21929 }
21930 self.write_space();
21931 self.write_keyword("TRUE");
21932 Ok(())
21933 }
21934
21935 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
21936 self.generate_expression(&is_false.this)?;
21937 self.write_space();
21938 self.write_keyword("IS");
21939 if is_false.not {
21940 self.write_space();
21941 self.write_keyword("NOT");
21942 }
21943 self.write_space();
21944 self.write_keyword("FALSE");
21945 Ok(())
21946 }
21947
21948 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
21949 self.generate_expression(&is_json.this)?;
21950 self.write_space();
21951 self.write_keyword("IS");
21952 if is_json.negated {
21953 self.write_space();
21954 self.write_keyword("NOT");
21955 }
21956 self.write_space();
21957 self.write_keyword("JSON");
21958
21959 if let Some(ref json_type) = is_json.json_type {
21961 self.write_space();
21962 self.write_keyword(json_type);
21963 }
21964
21965 match &is_json.unique_keys {
21967 Some(JsonUniqueKeys::With) => {
21968 self.write_space();
21969 self.write_keyword("WITH UNIQUE KEYS");
21970 }
21971 Some(JsonUniqueKeys::Without) => {
21972 self.write_space();
21973 self.write_keyword("WITHOUT UNIQUE KEYS");
21974 }
21975 Some(JsonUniqueKeys::Shorthand) => {
21976 self.write_space();
21977 self.write_keyword("UNIQUE KEYS");
21978 }
21979 None => {}
21980 }
21981
21982 Ok(())
21983 }
21984
21985 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
21986 self.generate_expression(&is_expr.left)?;
21987 self.write_space();
21988 self.write_keyword("IS");
21989 self.write_space();
21990 self.generate_expression(&is_expr.right)
21991 }
21992
21993 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
21994 if exists.not {
21995 self.write_keyword("NOT");
21996 self.write_space();
21997 }
21998 self.write_keyword("EXISTS");
21999 self.write("(");
22000 let is_statement = matches!(
22001 &exists.this,
22002 Expression::Select(_)
22003 | Expression::Union(_)
22004 | Expression::Intersect(_)
22005 | Expression::Except(_)
22006 );
22007 if self.config.pretty && is_statement {
22008 self.write_newline();
22009 self.indent_level += 1;
22010 self.write_indent();
22011 self.generate_expression(&exists.this)?;
22012 self.write_newline();
22013 self.indent_level -= 1;
22014 self.write_indent();
22015 self.write(")");
22016 } else {
22017 self.generate_expression(&exists.this)?;
22018 self.write(")");
22019 }
22020 Ok(())
22021 }
22022
22023 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
22024 self.generate_expression(&op.left)?;
22025 self.write_space();
22026 self.write_keyword("MEMBER OF");
22027 self.write("(");
22028 self.generate_expression(&op.right)?;
22029 self.write(")");
22030 Ok(())
22031 }
22032
22033 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
22034 if subquery.lateral {
22035 self.write_keyword("LATERAL");
22036 self.write_space();
22037 }
22038
22039 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
22043 matches!(
22044 &p.this,
22045 Expression::Select(_)
22046 | Expression::Union(_)
22047 | Expression::Intersect(_)
22048 | Expression::Except(_)
22049 | Expression::Subquery(_)
22050 )
22051 } else {
22052 false
22053 };
22054
22055 let is_statement = matches!(
22057 &subquery.this,
22058 Expression::Select(_)
22059 | Expression::Union(_)
22060 | Expression::Intersect(_)
22061 | Expression::Except(_)
22062 | Expression::Merge(_)
22063 );
22064
22065 if !skip_outer_parens {
22066 self.write("(");
22067 if self.config.pretty && is_statement {
22068 self.write_newline();
22069 self.indent_level += 1;
22070 self.write_indent();
22071 }
22072 }
22073 self.generate_expression(&subquery.this)?;
22074
22075 if subquery.modifiers_inside {
22077 if let Some(order_by) = &subquery.order_by {
22079 self.write_space();
22080 self.write_keyword("ORDER BY");
22081 self.write_space();
22082 for (i, ord) in order_by.expressions.iter().enumerate() {
22083 if i > 0 {
22084 self.write(", ");
22085 }
22086 self.generate_ordered(ord)?;
22087 }
22088 }
22089
22090 if let Some(limit) = &subquery.limit {
22091 self.write_space();
22092 self.write_keyword("LIMIT");
22093 self.write_space();
22094 self.generate_expression(&limit.this)?;
22095 if limit.percent {
22096 self.write_space();
22097 self.write_keyword("PERCENT");
22098 }
22099 }
22100
22101 if let Some(offset) = &subquery.offset {
22102 self.write_space();
22103 self.write_keyword("OFFSET");
22104 self.write_space();
22105 self.generate_expression(&offset.this)?;
22106 }
22107 }
22108
22109 if !skip_outer_parens {
22110 if self.config.pretty && is_statement {
22111 self.write_newline();
22112 self.indent_level -= 1;
22113 self.write_indent();
22114 }
22115 self.write(")");
22116 }
22117
22118 if !subquery.modifiers_inside {
22120 if let Some(order_by) = &subquery.order_by {
22121 self.write_space();
22122 self.write_keyword("ORDER BY");
22123 self.write_space();
22124 for (i, ord) in order_by.expressions.iter().enumerate() {
22125 if i > 0 {
22126 self.write(", ");
22127 }
22128 self.generate_ordered(ord)?;
22129 }
22130 }
22131
22132 if let Some(limit) = &subquery.limit {
22133 self.write_space();
22134 self.write_keyword("LIMIT");
22135 self.write_space();
22136 self.generate_expression(&limit.this)?;
22137 if limit.percent {
22138 self.write_space();
22139 self.write_keyword("PERCENT");
22140 }
22141 }
22142
22143 if let Some(offset) = &subquery.offset {
22144 self.write_space();
22145 self.write_keyword("OFFSET");
22146 self.write_space();
22147 self.generate_expression(&offset.this)?;
22148 }
22149
22150 if let Some(distribute_by) = &subquery.distribute_by {
22152 self.write_space();
22153 self.write_keyword("DISTRIBUTE BY");
22154 self.write_space();
22155 for (i, expr) in distribute_by.expressions.iter().enumerate() {
22156 if i > 0 {
22157 self.write(", ");
22158 }
22159 self.generate_expression(expr)?;
22160 }
22161 }
22162
22163 if let Some(sort_by) = &subquery.sort_by {
22165 self.write_space();
22166 self.write_keyword("SORT BY");
22167 self.write_space();
22168 for (i, ord) in sort_by.expressions.iter().enumerate() {
22169 if i > 0 {
22170 self.write(", ");
22171 }
22172 self.generate_ordered(ord)?;
22173 }
22174 }
22175
22176 if let Some(cluster_by) = &subquery.cluster_by {
22178 self.write_space();
22179 self.write_keyword("CLUSTER BY");
22180 self.write_space();
22181 for (i, ord) in cluster_by.expressions.iter().enumerate() {
22182 if i > 0 {
22183 self.write(", ");
22184 }
22185 self.generate_ordered(ord)?;
22186 }
22187 }
22188 }
22189
22190 if let Some(alias) = &subquery.alias {
22191 self.write_space();
22192 let skip_as = matches!(
22194 self.config.dialect,
22195 Some(crate::dialects::DialectType::Oracle)
22196 );
22197 if !skip_as {
22198 self.write_keyword("AS");
22199 self.write_space();
22200 }
22201 self.generate_identifier(alias)?;
22202 if !subquery.column_aliases.is_empty() {
22203 self.write("(");
22204 for (i, col) in subquery.column_aliases.iter().enumerate() {
22205 if i > 0 {
22206 self.write(", ");
22207 }
22208 self.generate_identifier(col)?;
22209 }
22210 self.write(")");
22211 }
22212 }
22213 for comment in &subquery.trailing_comments {
22215 self.write(" ");
22216 self.write_formatted_comment(comment);
22217 }
22218 Ok(())
22219 }
22220
22221 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
22222 if let Some(ref with) = pivot.with {
22224 self.generate_with(with)?;
22225 self.write_space();
22226 }
22227
22228 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
22229
22230 let is_redshift_unpivot = pivot.unpivot
22234 && pivot.expressions.is_empty()
22235 && pivot.fields.is_empty()
22236 && pivot.using.is_empty()
22237 && pivot.into.is_none()
22238 && !matches!(&pivot.this, Expression::Null(_));
22239
22240 if is_redshift_unpivot {
22241 self.write_keyword("UNPIVOT");
22243 self.write_space();
22244 self.generate_expression(&pivot.this)?;
22245 if let Some(alias) = &pivot.alias {
22247 self.write_space();
22248 self.write_keyword("AS");
22249 self.write_space();
22250 self.write(&alias.name);
22252 }
22253 return Ok(());
22254 }
22255
22256 let is_simplified = !pivot.using.is_empty()
22258 || pivot.into.is_some()
22259 || (pivot.fields.is_empty()
22260 && !pivot.expressions.is_empty()
22261 && !matches!(&pivot.this, Expression::Null(_)));
22262
22263 if is_simplified {
22264 self.write_keyword(direction);
22268 self.write_space();
22269 self.generate_expression(&pivot.this)?;
22270
22271 if !pivot.expressions.is_empty() {
22272 self.write_space();
22273 self.write_keyword("ON");
22274 self.write_space();
22275 for (i, expr) in pivot.expressions.iter().enumerate() {
22276 if i > 0 {
22277 self.write(", ");
22278 }
22279 self.generate_expression(expr)?;
22280 }
22281 }
22282
22283 if let Some(into) = &pivot.into {
22285 self.write_space();
22286 self.write_keyword("INTO");
22287 self.write_space();
22288 self.generate_expression(into)?;
22289 }
22290
22291 if !pivot.using.is_empty() {
22293 self.write_space();
22294 self.write_keyword("USING");
22295 self.write_space();
22296 for (i, expr) in pivot.using.iter().enumerate() {
22297 if i > 0 {
22298 self.write(", ");
22299 }
22300 self.generate_expression(expr)?;
22301 }
22302 }
22303
22304 if let Some(group) = &pivot.group {
22306 self.write_space();
22307 self.generate_expression(group)?;
22308 }
22309 } else {
22310 if !matches!(&pivot.this, Expression::Null(_)) {
22315 self.generate_expression(&pivot.this)?;
22316 self.write_space();
22317 }
22318 self.write_keyword(direction);
22319 self.write("(");
22320
22321 for (i, expr) in pivot.expressions.iter().enumerate() {
22323 if i > 0 {
22324 self.write(", ");
22325 }
22326 self.generate_expression(expr)?;
22327 }
22328
22329 if !pivot.fields.is_empty() {
22331 if !pivot.expressions.is_empty() {
22332 self.write_space();
22333 }
22334 self.write_keyword("FOR");
22335 self.write_space();
22336 for (i, field) in pivot.fields.iter().enumerate() {
22337 if i > 0 {
22338 self.write_space();
22339 }
22340 self.generate_expression(field)?;
22342 }
22343 }
22344
22345 if let Some(default_val) = &pivot.default_on_null {
22347 self.write_space();
22348 self.write_keyword("DEFAULT ON NULL");
22349 self.write(" (");
22350 self.generate_expression(default_val)?;
22351 self.write(")");
22352 }
22353
22354 if let Some(group) = &pivot.group {
22356 self.write_space();
22357 self.generate_expression(group)?;
22358 }
22359
22360 self.write(")");
22361 }
22362
22363 if let Some(alias) = &pivot.alias {
22365 self.write_space();
22366 self.write_keyword("AS");
22367 self.write_space();
22368 self.generate_identifier(alias)?;
22369 }
22370
22371 Ok(())
22372 }
22373
22374 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
22375 self.generate_expression(&unpivot.this)?;
22376 self.write_space();
22377 self.write_keyword("UNPIVOT");
22378 if let Some(include) = unpivot.include_nulls {
22380 self.write_space();
22381 if include {
22382 self.write_keyword("INCLUDE NULLS");
22383 } else {
22384 self.write_keyword("EXCLUDE NULLS");
22385 }
22386 self.write_space();
22387 }
22388 self.write("(");
22389 if unpivot.value_column_parenthesized {
22390 self.write("(");
22391 }
22392 self.generate_identifier(&unpivot.value_column)?;
22393 for extra_col in &unpivot.extra_value_columns {
22395 self.write(", ");
22396 self.generate_identifier(extra_col)?;
22397 }
22398 if unpivot.value_column_parenthesized {
22399 self.write(")");
22400 }
22401 self.write_space();
22402 self.write_keyword("FOR");
22403 self.write_space();
22404 self.generate_identifier(&unpivot.name_column)?;
22405 self.write_space();
22406 self.write_keyword("IN");
22407 self.write(" (");
22408 for (i, col) in unpivot.columns.iter().enumerate() {
22409 if i > 0 {
22410 self.write(", ");
22411 }
22412 self.generate_expression(col)?;
22413 }
22414 self.write("))");
22415 if let Some(alias) = &unpivot.alias {
22416 self.write_space();
22417 self.write_keyword("AS");
22418 self.write_space();
22419 self.generate_identifier(alias)?;
22420 }
22421 Ok(())
22422 }
22423
22424 fn generate_values(&mut self, values: &Values) -> Result<()> {
22425 self.write_keyword("VALUES");
22426 for (i, row) in values.expressions.iter().enumerate() {
22427 if i > 0 {
22428 self.write(",");
22429 }
22430 self.write(" (");
22431 for (j, expr) in row.expressions.iter().enumerate() {
22432 if j > 0 {
22433 self.write(", ");
22434 }
22435 self.generate_expression(expr)?;
22436 }
22437 self.write(")");
22438 }
22439 if let Some(alias) = &values.alias {
22440 self.write_space();
22441 self.write_keyword("AS");
22442 self.write_space();
22443 self.generate_identifier(alias)?;
22444 if !values.column_aliases.is_empty() {
22445 self.write("(");
22446 for (i, col) in values.column_aliases.iter().enumerate() {
22447 if i > 0 {
22448 self.write(", ");
22449 }
22450 self.generate_identifier(col)?;
22451 }
22452 self.write(")");
22453 }
22454 }
22455 Ok(())
22456 }
22457
22458 fn generate_array(&mut self, arr: &Array) -> Result<()> {
22459 let needs_inheritance = matches!(
22461 self.config.dialect,
22462 Some(DialectType::DuckDB)
22463 | Some(DialectType::Spark)
22464 | Some(DialectType::Databricks)
22465 | Some(DialectType::Hive)
22466 | Some(DialectType::Snowflake)
22467 | Some(DialectType::Presto)
22468 | Some(DialectType::Trino)
22469 );
22470 let propagated: Vec<Expression>;
22471 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
22472 propagated = Self::inherit_struct_field_names(&arr.expressions);
22473 &propagated
22474 } else {
22475 &arr.expressions
22476 };
22477
22478 let use_parens =
22481 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
22482 if !self.config.array_bracket_only {
22483 self.write_keyword("ARRAY");
22484 }
22485 if use_parens {
22486 self.write("(");
22487 } else {
22488 self.write("[");
22489 }
22490 for (i, expr) in expressions.iter().enumerate() {
22491 if i > 0 {
22492 self.write(", ");
22493 }
22494 self.generate_expression(expr)?;
22495 }
22496 if use_parens {
22497 self.write(")");
22498 } else {
22499 self.write("]");
22500 }
22501 Ok(())
22502 }
22503
22504 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
22505 if tuple.expressions.len() == 2 {
22508 if let Expression::TableAlias(_) = &tuple.expressions[1] {
22509 self.generate_expression(&tuple.expressions[0])?;
22511 self.write_space();
22512 self.write_keyword("AS");
22513 self.write_space();
22514 self.generate_expression(&tuple.expressions[1])?;
22515 return Ok(());
22516 }
22517 }
22518
22519 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
22522 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
22523 for expr in &tuple.expressions {
22524 expr_strings.push(self.generate_to_string(expr)?);
22525 }
22526 self.too_wide(&expr_strings)
22527 } else {
22528 false
22529 };
22530
22531 if expand_tuple {
22532 self.write("(");
22533 self.write_newline();
22534 self.indent_level += 1;
22535 for (i, expr) in tuple.expressions.iter().enumerate() {
22536 if i > 0 {
22537 self.write(",");
22538 self.write_newline();
22539 }
22540 self.write_indent();
22541 self.generate_expression(expr)?;
22542 }
22543 self.indent_level -= 1;
22544 self.write_newline();
22545 self.write_indent();
22546 self.write(")");
22547 } else {
22548 self.write("(");
22549 for (i, expr) in tuple.expressions.iter().enumerate() {
22550 if i > 0 {
22551 self.write(", ");
22552 }
22553 self.generate_expression(expr)?;
22554 }
22555 self.write(")");
22556 }
22557 Ok(())
22558 }
22559
22560 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
22561 self.generate_expression(&pipe.this)?;
22562 self.write(" |> ");
22563 self.generate_expression(&pipe.expression)?;
22564 Ok(())
22565 }
22566
22567 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
22568 self.generate_expression(&ordered.this)?;
22569 if ordered.desc {
22570 self.write_space();
22571 self.write_keyword("DESC");
22572 } else if ordered.explicit_asc {
22573 self.write_space();
22574 self.write_keyword("ASC");
22575 }
22576 if let Some(nulls_first) = ordered.nulls_first {
22577 let is_asc = !ordered.desc;
22591 let is_nulls_are_large = matches!(
22592 self.config.dialect,
22593 Some(DialectType::Oracle)
22594 | Some(DialectType::PostgreSQL)
22595 | Some(DialectType::Redshift)
22596 | Some(DialectType::Snowflake)
22597 );
22598 let is_nulls_are_last = matches!(
22599 self.config.dialect,
22600 Some(DialectType::Dremio)
22601 | Some(DialectType::DuckDB)
22602 | Some(DialectType::Presto)
22603 | Some(DialectType::Trino)
22604 | Some(DialectType::Athena)
22605 | Some(DialectType::ClickHouse)
22606 | Some(DialectType::Drill)
22607 | Some(DialectType::Exasol)
22608 );
22609
22610 let is_default_nulls = if is_nulls_are_large {
22612 (is_asc && !nulls_first) || (!is_asc && nulls_first)
22614 } else if is_nulls_are_last {
22615 !nulls_first
22617 } else {
22618 false
22619 };
22620
22621 if !is_default_nulls {
22622 self.write_space();
22623 self.write_keyword("NULLS");
22624 self.write_space();
22625 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
22626 }
22627 }
22628 if let Some(ref with_fill) = ordered.with_fill {
22630 self.write_space();
22631 self.generate_with_fill(with_fill)?;
22632 }
22633 Ok(())
22634 }
22635
22636 fn write_clickhouse_type(&mut self, type_str: &str) {
22638 if self.clickhouse_nullable_depth < 0 {
22639 self.write(type_str);
22641 } else {
22642 self.write(&format!("Nullable({})", type_str));
22643 }
22644 }
22645
22646 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
22647 use crate::dialects::DialectType;
22648
22649 match dt {
22650 DataType::Boolean => {
22651 match self.config.dialect {
22653 Some(DialectType::TSQL) => self.write_keyword("BIT"),
22654 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
22656 self.write_keyword("NUMBER(1)")
22658 }
22659 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
22661 }
22662 }
22663 DataType::TinyInt { length } => {
22664 match self.config.dialect {
22668 Some(DialectType::PostgreSQL)
22669 | Some(DialectType::Redshift)
22670 | Some(DialectType::Oracle)
22671 | Some(DialectType::Exasol) => {
22672 self.write_keyword("SMALLINT");
22673 }
22674 Some(DialectType::Teradata) => {
22675 self.write_keyword("BYTEINT");
22677 }
22678 Some(DialectType::Dremio) => {
22679 self.write_keyword("INT");
22681 }
22682 Some(DialectType::ClickHouse) => {
22683 self.write_clickhouse_type("Int8");
22684 }
22685 _ => {
22686 self.write_keyword("TINYINT");
22687 }
22688 }
22689 if let Some(n) = length {
22690 if !matches!(
22691 self.config.dialect,
22692 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
22693 ) {
22694 self.write(&format!("({})", n));
22695 }
22696 }
22697 }
22698 DataType::SmallInt { length } => {
22699 match self.config.dialect {
22701 Some(DialectType::Dremio) => {
22702 self.write_keyword("INT");
22703 }
22704 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
22705 self.write_keyword("INTEGER");
22706 }
22707 Some(DialectType::BigQuery) => {
22708 self.write_keyword("INT64");
22709 }
22710 Some(DialectType::ClickHouse) => {
22711 self.write_clickhouse_type("Int16");
22712 }
22713 _ => {
22714 self.write_keyword("SMALLINT");
22715 if let Some(n) = length {
22716 self.write(&format!("({})", n));
22717 }
22718 }
22719 }
22720 }
22721 DataType::Int {
22722 length,
22723 integer_spelling: _,
22724 } => {
22725 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
22727 self.write_keyword("INT64");
22728 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22729 self.write_clickhouse_type("Int32");
22730 } else {
22731 let use_integer = match self.config.dialect {
22733 Some(DialectType::TSQL)
22734 | Some(DialectType::Fabric)
22735 | Some(DialectType::Presto)
22736 | Some(DialectType::Trino)
22737 | Some(DialectType::SQLite)
22738 | Some(DialectType::Redshift) => true,
22739 _ => false,
22740 };
22741 if use_integer {
22742 self.write_keyword("INTEGER");
22743 } else {
22744 self.write_keyword("INT");
22745 }
22746 if let Some(n) = length {
22747 self.write(&format!("({})", n));
22748 }
22749 }
22750 }
22751 DataType::BigInt { length } => {
22752 match self.config.dialect {
22754 Some(DialectType::Oracle) => {
22755 self.write_keyword("INT");
22757 }
22758 Some(DialectType::ClickHouse) => {
22759 self.write_clickhouse_type("Int64");
22760 }
22761 _ => {
22762 self.write_keyword("BIGINT");
22763 if let Some(n) = length {
22764 self.write(&format!("({})", n));
22765 }
22766 }
22767 }
22768 }
22769 DataType::Float {
22770 precision,
22771 scale,
22772 real_spelling,
22773 } => {
22774 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22778 self.write_clickhouse_type("Float32");
22779 } else if *real_spelling
22780 && !matches!(
22781 self.config.dialect,
22782 Some(DialectType::Spark)
22783 | Some(DialectType::Databricks)
22784 | Some(DialectType::Hive)
22785 | Some(DialectType::Snowflake)
22786 | Some(DialectType::MySQL)
22787 | Some(DialectType::BigQuery)
22788 )
22789 {
22790 self.write_keyword("REAL")
22791 } else {
22792 match self.config.dialect {
22793 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
22794 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
22795 _ => self.write_keyword("FLOAT"),
22796 }
22797 }
22798 if !matches!(
22801 self.config.dialect,
22802 Some(DialectType::Spark)
22803 | Some(DialectType::Databricks)
22804 | Some(DialectType::Hive)
22805 | Some(DialectType::Presto)
22806 | Some(DialectType::Trino)
22807 ) {
22808 if let Some(p) = precision {
22809 self.write(&format!("({}", p));
22810 if let Some(s) = scale {
22811 self.write(&format!(", {})", s));
22812 } else {
22813 self.write(")");
22814 }
22815 }
22816 }
22817 }
22818 DataType::Double { precision, scale } => {
22819 match self.config.dialect {
22821 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22822 self.write_keyword("FLOAT")
22823 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
22825 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
22826 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
22827 Some(DialectType::SQLite) => self.write_keyword("REAL"),
22828 Some(DialectType::PostgreSQL)
22829 | Some(DialectType::Redshift)
22830 | Some(DialectType::Teradata)
22831 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
22832 _ => self.write_keyword("DOUBLE"),
22833 }
22834 if let Some(p) = precision {
22836 self.write(&format!("({}", p));
22837 if let Some(s) = scale {
22838 self.write(&format!(", {})", s));
22839 } else {
22840 self.write(")");
22841 }
22842 }
22843 }
22844 DataType::Decimal { precision, scale } => {
22845 match self.config.dialect {
22847 Some(DialectType::ClickHouse) => {
22848 self.write("Decimal");
22849 if let Some(p) = precision {
22850 self.write(&format!("({}", p));
22851 if let Some(s) = scale {
22852 self.write(&format!(", {}", s));
22853 }
22854 self.write(")");
22855 }
22856 }
22857 Some(DialectType::Oracle) => {
22858 self.write_keyword("NUMBER");
22860 if let Some(p) = precision {
22861 self.write(&format!("({}", p));
22862 if let Some(s) = scale {
22863 self.write(&format!(", {}", s));
22864 }
22865 self.write(")");
22866 }
22867 }
22868 Some(DialectType::BigQuery) => {
22869 self.write_keyword("NUMERIC");
22871 if let Some(p) = precision {
22872 self.write(&format!("({}", p));
22873 if let Some(s) = scale {
22874 self.write(&format!(", {}", s));
22875 }
22876 self.write(")");
22877 }
22878 }
22879 _ => {
22880 self.write_keyword("DECIMAL");
22881 if let Some(p) = precision {
22882 self.write(&format!("({}", p));
22883 if let Some(s) = scale {
22884 self.write(&format!(", {}", s));
22885 }
22886 self.write(")");
22887 }
22888 }
22889 }
22890 }
22891 DataType::Char { length } => {
22892 match self.config.dialect {
22894 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
22895 self.write_keyword("TEXT");
22897 }
22898 Some(DialectType::Hive)
22899 | Some(DialectType::Spark)
22900 | Some(DialectType::Databricks) => {
22901 if length.is_some()
22904 && !matches!(self.config.dialect, Some(DialectType::Hive))
22905 {
22906 self.write_keyword("CHAR");
22907 if let Some(n) = length {
22908 self.write(&format!("({})", n));
22909 }
22910 } else {
22911 self.write_keyword("STRING");
22912 }
22913 }
22914 Some(DialectType::Dremio) => {
22915 self.write_keyword("VARCHAR");
22917 if let Some(n) = length {
22918 self.write(&format!("({})", n));
22919 }
22920 }
22921 _ => {
22922 self.write_keyword("CHAR");
22923 if let Some(n) = length {
22924 self.write(&format!("({})", n));
22925 }
22926 }
22927 }
22928 }
22929 DataType::VarChar {
22930 length,
22931 parenthesized_length,
22932 } => {
22933 match self.config.dialect {
22935 Some(DialectType::Oracle) => {
22936 self.write_keyword("VARCHAR2");
22937 if let Some(n) = length {
22938 self.write(&format!("({})", n));
22939 }
22940 }
22941 Some(DialectType::DuckDB) => {
22942 self.write_keyword("TEXT");
22944 if let Some(n) = length {
22945 self.write(&format!("({})", n));
22946 }
22947 }
22948 Some(DialectType::SQLite) => {
22949 self.write_keyword("TEXT");
22951 if let Some(n) = length {
22952 self.write(&format!("({})", n));
22953 }
22954 }
22955 Some(DialectType::MySQL) if length.is_none() => {
22956 self.write_keyword("TEXT");
22958 }
22959 Some(DialectType::Hive)
22960 | Some(DialectType::Spark)
22961 | Some(DialectType::Databricks)
22962 if length.is_none() =>
22963 {
22964 self.write_keyword("STRING");
22966 }
22967 _ => {
22968 self.write_keyword("VARCHAR");
22969 if let Some(n) = length {
22970 if *parenthesized_length {
22972 self.write(&format!("(({}))", n));
22973 } else {
22974 self.write(&format!("({})", n));
22975 }
22976 }
22977 }
22978 }
22979 }
22980 DataType::Text => {
22981 match self.config.dialect {
22983 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
22984 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22985 self.write_keyword("VARCHAR(MAX)")
22986 }
22987 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
22988 Some(DialectType::Snowflake)
22989 | Some(DialectType::Dremio)
22990 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
22991 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
22992 Some(DialectType::Presto)
22993 | Some(DialectType::Trino)
22994 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
22995 Some(DialectType::Spark)
22996 | Some(DialectType::Databricks)
22997 | Some(DialectType::Hive) => self.write_keyword("STRING"),
22998 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
22999 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
23000 self.write_keyword("STRING")
23001 }
23002 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
23003 _ => self.write_keyword("TEXT"),
23004 }
23005 }
23006 DataType::TextWithLength { length } => {
23007 match self.config.dialect {
23009 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
23010 Some(DialectType::Hive)
23011 | Some(DialectType::Spark)
23012 | Some(DialectType::Databricks) => {
23013 self.write(&format!("VARCHAR({})", length));
23014 }
23015 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
23016 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
23017 Some(DialectType::Snowflake)
23018 | Some(DialectType::Presto)
23019 | Some(DialectType::Trino)
23020 | Some(DialectType::Athena)
23021 | Some(DialectType::Drill)
23022 | Some(DialectType::Dremio) => {
23023 self.write(&format!("VARCHAR({})", length));
23024 }
23025 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23026 self.write(&format!("VARCHAR({})", length))
23027 }
23028 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
23029 self.write(&format!("STRING({})", length))
23030 }
23031 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
23032 _ => self.write(&format!("TEXT({})", length)),
23033 }
23034 }
23035 DataType::String { length } => {
23036 match self.config.dialect {
23038 Some(DialectType::ClickHouse) => {
23039 self.write("String");
23041 if let Some(n) = length {
23042 self.write(&format!("({})", n));
23043 }
23044 }
23045 Some(DialectType::BigQuery)
23046 | Some(DialectType::Hive)
23047 | Some(DialectType::Spark)
23048 | Some(DialectType::Databricks)
23049 | Some(DialectType::StarRocks)
23050 | Some(DialectType::Doris) => {
23051 self.write_keyword("STRING");
23052 if let Some(n) = length {
23053 self.write(&format!("({})", n));
23054 }
23055 }
23056 Some(DialectType::PostgreSQL) => {
23057 if let Some(n) = length {
23059 self.write_keyword("VARCHAR");
23060 self.write(&format!("({})", n));
23061 } else {
23062 self.write_keyword("TEXT");
23063 }
23064 }
23065 Some(DialectType::Redshift) => {
23066 if let Some(n) = length {
23068 self.write_keyword("VARCHAR");
23069 self.write(&format!("({})", n));
23070 } else {
23071 self.write_keyword("VARCHAR(MAX)");
23072 }
23073 }
23074 Some(DialectType::MySQL) => {
23075 if let Some(n) = length {
23077 self.write_keyword("VARCHAR");
23078 self.write(&format!("({})", n));
23079 } else {
23080 self.write_keyword("TEXT");
23081 }
23082 }
23083 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23084 if let Some(n) = length {
23086 self.write_keyword("VARCHAR");
23087 self.write(&format!("({})", n));
23088 } else {
23089 self.write_keyword("VARCHAR(MAX)");
23090 }
23091 }
23092 Some(DialectType::Oracle) => {
23093 self.write_keyword("CLOB");
23095 }
23096 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
23097 self.write_keyword("TEXT");
23099 if let Some(n) = length {
23100 self.write(&format!("({})", n));
23101 }
23102 }
23103 Some(DialectType::Presto)
23104 | Some(DialectType::Trino)
23105 | Some(DialectType::Drill)
23106 | Some(DialectType::Dremio) => {
23107 self.write_keyword("VARCHAR");
23109 if let Some(n) = length {
23110 self.write(&format!("({})", n));
23111 }
23112 }
23113 Some(DialectType::Snowflake) => {
23114 self.write_keyword("STRING");
23117 if let Some(n) = length {
23118 self.write(&format!("({})", n));
23119 }
23120 }
23121 _ => {
23122 self.write_keyword("STRING");
23124 if let Some(n) = length {
23125 self.write(&format!("({})", n));
23126 }
23127 }
23128 }
23129 }
23130 DataType::Binary { length } => {
23131 match self.config.dialect {
23133 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
23134 self.write_keyword("BYTEA");
23135 if let Some(n) = length {
23136 self.write(&format!("({})", n));
23137 }
23138 }
23139 Some(DialectType::Redshift) => {
23140 self.write_keyword("VARBYTE");
23141 if let Some(n) = length {
23142 self.write(&format!("({})", n));
23143 }
23144 }
23145 Some(DialectType::DuckDB)
23146 | Some(DialectType::SQLite)
23147 | Some(DialectType::Oracle) => {
23148 self.write_keyword("BLOB");
23150 if let Some(n) = length {
23151 self.write(&format!("({})", n));
23152 }
23153 }
23154 Some(DialectType::Presto)
23155 | Some(DialectType::Trino)
23156 | Some(DialectType::Athena)
23157 | Some(DialectType::Drill)
23158 | Some(DialectType::Dremio) => {
23159 self.write_keyword("VARBINARY");
23161 if let Some(n) = length {
23162 self.write(&format!("({})", n));
23163 }
23164 }
23165 Some(DialectType::ClickHouse) => {
23166 if self.clickhouse_nullable_depth < 0 {
23168 self.write("BINARY");
23169 } else {
23170 self.write("Nullable(BINARY");
23171 }
23172 if let Some(n) = length {
23173 self.write(&format!("({})", n));
23174 }
23175 if self.clickhouse_nullable_depth >= 0 {
23176 self.write(")");
23177 }
23178 }
23179 _ => {
23180 self.write_keyword("BINARY");
23181 if let Some(n) = length {
23182 self.write(&format!("({})", n));
23183 }
23184 }
23185 }
23186 }
23187 DataType::VarBinary { length } => {
23188 match self.config.dialect {
23190 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
23191 self.write_keyword("BYTEA");
23192 if let Some(n) = length {
23193 self.write(&format!("({})", n));
23194 }
23195 }
23196 Some(DialectType::Redshift) => {
23197 self.write_keyword("VARBYTE");
23198 if let Some(n) = length {
23199 self.write(&format!("({})", n));
23200 }
23201 }
23202 Some(DialectType::DuckDB)
23203 | Some(DialectType::SQLite)
23204 | Some(DialectType::Oracle) => {
23205 self.write_keyword("BLOB");
23207 if let Some(n) = length {
23208 self.write(&format!("({})", n));
23209 }
23210 }
23211 Some(DialectType::Exasol) => {
23212 self.write_keyword("VARCHAR");
23214 }
23215 Some(DialectType::Spark)
23216 | Some(DialectType::Hive)
23217 | Some(DialectType::Databricks) => {
23218 self.write_keyword("BINARY");
23220 if let Some(n) = length {
23221 self.write(&format!("({})", n));
23222 }
23223 }
23224 Some(DialectType::ClickHouse) => {
23225 self.write_clickhouse_type("String");
23227 }
23228 _ => {
23229 self.write_keyword("VARBINARY");
23230 if let Some(n) = length {
23231 self.write(&format!("({})", n));
23232 }
23233 }
23234 }
23235 }
23236 DataType::Blob => {
23237 match self.config.dialect {
23239 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
23240 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
23241 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23242 self.write_keyword("VARBINARY")
23243 }
23244 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
23245 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
23246 Some(DialectType::Presto)
23247 | Some(DialectType::Trino)
23248 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
23249 Some(DialectType::DuckDB) => {
23250 self.write_keyword("VARBINARY");
23253 }
23254 Some(DialectType::Spark)
23255 | Some(DialectType::Databricks)
23256 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
23257 Some(DialectType::ClickHouse) => {
23258 self.write("Nullable(String)");
23262 }
23263 _ => self.write_keyword("BLOB"),
23264 }
23265 }
23266 DataType::Bit { length } => {
23267 match self.config.dialect {
23269 Some(DialectType::Dremio)
23270 | Some(DialectType::Spark)
23271 | Some(DialectType::Databricks)
23272 | Some(DialectType::Hive)
23273 | Some(DialectType::Snowflake)
23274 | Some(DialectType::BigQuery)
23275 | Some(DialectType::Presto)
23276 | Some(DialectType::Trino)
23277 | Some(DialectType::ClickHouse)
23278 | Some(DialectType::Redshift) => {
23279 self.write_keyword("BOOLEAN");
23281 }
23282 _ => {
23283 self.write_keyword("BIT");
23284 if let Some(n) = length {
23285 self.write(&format!("({})", n));
23286 }
23287 }
23288 }
23289 }
23290 DataType::VarBit { length } => {
23291 self.write_keyword("VARBIT");
23292 if let Some(n) = length {
23293 self.write(&format!("({})", n));
23294 }
23295 }
23296 DataType::Date => self.write_keyword("DATE"),
23297 DataType::Time {
23298 precision,
23299 timezone,
23300 } => {
23301 if *timezone {
23302 match self.config.dialect {
23304 Some(DialectType::DuckDB) => {
23305 self.write_keyword("TIMETZ");
23307 }
23308 Some(DialectType::PostgreSQL) => {
23309 self.write_keyword("TIMETZ");
23311 if let Some(p) = precision {
23312 self.write(&format!("({})", p));
23313 }
23314 }
23315 _ => {
23316 self.write_keyword("TIME");
23318 if let Some(p) = precision {
23319 self.write(&format!("({})", p));
23320 }
23321 self.write_keyword(" WITH TIME ZONE");
23322 }
23323 }
23324 } else {
23325 if matches!(
23327 self.config.dialect,
23328 Some(DialectType::Spark)
23329 | Some(DialectType::Databricks)
23330 | Some(DialectType::Hive)
23331 ) {
23332 self.write_keyword("TIMESTAMP");
23333 } else {
23334 self.write_keyword("TIME");
23335 if let Some(p) = precision {
23336 self.write(&format!("({})", p));
23337 }
23338 }
23339 }
23340 }
23341 DataType::Timestamp {
23342 precision,
23343 timezone,
23344 } => {
23345 match self.config.dialect {
23347 Some(DialectType::ClickHouse) => {
23348 self.write("DateTime");
23349 if let Some(p) = precision {
23350 self.write(&format!("({})", p));
23351 }
23352 }
23353 Some(DialectType::TSQL) => {
23354 if *timezone {
23355 self.write_keyword("DATETIMEOFFSET");
23356 } else {
23357 self.write_keyword("DATETIME2");
23358 }
23359 if let Some(p) = precision {
23360 self.write(&format!("({})", p));
23361 }
23362 }
23363 Some(DialectType::MySQL) => {
23364 self.write_keyword("TIMESTAMP");
23366 if let Some(p) = precision {
23367 self.write(&format!("({})", p));
23368 }
23369 }
23370 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
23371 self.write_keyword("DATETIME");
23373 if let Some(p) = precision {
23374 self.write(&format!("({})", p));
23375 }
23376 }
23377 Some(DialectType::BigQuery) => {
23378 if *timezone {
23380 self.write_keyword("TIMESTAMP");
23381 } else {
23382 self.write_keyword("DATETIME");
23383 }
23384 }
23385 Some(DialectType::DuckDB) => {
23386 if *timezone {
23388 self.write_keyword("TIMESTAMPTZ");
23389 } else {
23390 self.write_keyword("TIMESTAMP");
23391 if let Some(p) = precision {
23392 self.write(&format!("({})", p));
23393 }
23394 }
23395 }
23396 _ => {
23397 if *timezone && !self.config.tz_to_with_time_zone {
23398 self.write_keyword("TIMESTAMPTZ");
23400 if let Some(p) = precision {
23401 self.write(&format!("({})", p));
23402 }
23403 } else {
23404 self.write_keyword("TIMESTAMP");
23405 if let Some(p) = precision {
23406 self.write(&format!("({})", p));
23407 }
23408 if *timezone {
23409 self.write_space();
23410 self.write_keyword("WITH TIME ZONE");
23411 }
23412 }
23413 }
23414 }
23415 }
23416 DataType::Interval { unit, to } => {
23417 self.write_keyword("INTERVAL");
23418 if let Some(u) = unit {
23419 self.write_space();
23420 self.write_keyword(u);
23421 }
23422 if let Some(t) = to {
23424 self.write_space();
23425 self.write_keyword("TO");
23426 self.write_space();
23427 self.write_keyword(t);
23428 }
23429 }
23430 DataType::Json => {
23431 match self.config.dialect {
23433 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
23436 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
23437 _ => self.write_keyword("JSON"),
23438 }
23439 }
23440 DataType::JsonB => {
23441 match self.config.dialect {
23443 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
23444 Some(DialectType::Doris) => self.write_keyword("JSONB"),
23445 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
23446 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
23447 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
23450 }
23451 DataType::Uuid => {
23452 match self.config.dialect {
23454 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
23455 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
23456 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
23457 Some(DialectType::BigQuery)
23458 | Some(DialectType::Spark)
23459 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
23460 _ => self.write_keyword("UUID"),
23461 }
23462 }
23463 DataType::Array {
23464 element_type,
23465 dimension,
23466 } => {
23467 match self.config.dialect {
23469 Some(DialectType::PostgreSQL)
23470 | Some(DialectType::Redshift)
23471 | Some(DialectType::DuckDB) => {
23472 self.generate_data_type(element_type)?;
23474 if let Some(dim) = dimension {
23475 self.write(&format!("[{}]", dim));
23476 } else {
23477 self.write("[]");
23478 }
23479 }
23480 Some(DialectType::BigQuery) => {
23481 self.write_keyword("ARRAY<");
23482 self.generate_data_type(element_type)?;
23483 self.write(">");
23484 }
23485 Some(DialectType::Snowflake)
23486 | Some(DialectType::Presto)
23487 | Some(DialectType::Trino)
23488 | Some(DialectType::ClickHouse) => {
23489 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23491 self.write("Array(");
23492 } else {
23493 self.write_keyword("ARRAY(");
23494 }
23495 self.generate_data_type(element_type)?;
23496 self.write(")");
23497 }
23498 Some(DialectType::TSQL)
23499 | Some(DialectType::MySQL)
23500 | Some(DialectType::Oracle) => {
23501 match self.config.dialect {
23504 Some(DialectType::MySQL) => self.write_keyword("JSON"),
23505 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
23506 _ => self.write_keyword("JSON"),
23507 }
23508 }
23509 _ => {
23510 self.write_keyword("ARRAY<");
23512 self.generate_data_type(element_type)?;
23513 self.write(">");
23514 }
23515 }
23516 }
23517 DataType::List { element_type } => {
23518 self.generate_data_type(element_type)?;
23520 self.write_keyword(" LIST");
23521 }
23522 DataType::Map {
23523 key_type,
23524 value_type,
23525 } => {
23526 match self.config.dialect {
23528 Some(DialectType::Materialize) => {
23529 self.write_keyword("MAP[");
23531 self.generate_data_type(key_type)?;
23532 self.write(" => ");
23533 self.generate_data_type(value_type)?;
23534 self.write("]");
23535 }
23536 Some(DialectType::Snowflake)
23537 | Some(DialectType::RisingWave)
23538 | Some(DialectType::DuckDB)
23539 | Some(DialectType::Presto)
23540 | Some(DialectType::Trino)
23541 | Some(DialectType::Athena) => {
23542 self.write_keyword("MAP(");
23543 self.generate_data_type(key_type)?;
23544 self.write(", ");
23545 self.generate_data_type(value_type)?;
23546 self.write(")");
23547 }
23548 Some(DialectType::ClickHouse) => {
23549 self.write("Map(");
23552 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
23554 self.clickhouse_nullable_depth = 0;
23555 self.write(", ");
23556 self.generate_data_type(value_type)?;
23557 self.write(")");
23558 }
23559 _ => {
23560 self.write_keyword("MAP<");
23561 self.generate_data_type(key_type)?;
23562 self.write(", ");
23563 self.generate_data_type(value_type)?;
23564 self.write(">");
23565 }
23566 }
23567 }
23568 DataType::Vector {
23569 element_type,
23570 dimension,
23571 } => {
23572 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
23573 self.write_keyword("VECTOR(");
23575 if let Some(dim) = dimension {
23576 self.write(&dim.to_string());
23577 }
23578 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
23580 DataType::TinyInt { .. } => Some("I8"),
23581 DataType::SmallInt { .. } => Some("I16"),
23582 DataType::Int { .. } => Some("I32"),
23583 DataType::BigInt { .. } => Some("I64"),
23584 DataType::Float { .. } => Some("F32"),
23585 DataType::Double { .. } => Some("F64"),
23586 _ => None,
23587 });
23588 if let Some(alias) = type_alias {
23589 if dimension.is_some() {
23590 self.write(", ");
23591 }
23592 self.write(alias);
23593 }
23594 self.write(")");
23595 } else {
23596 self.write_keyword("VECTOR(");
23598 if let Some(ref et) = element_type {
23599 self.generate_data_type(et)?;
23600 if dimension.is_some() {
23601 self.write(", ");
23602 }
23603 }
23604 if let Some(dim) = dimension {
23605 self.write(&dim.to_string());
23606 }
23607 self.write(")");
23608 }
23609 }
23610 DataType::Object { fields, modifier } => {
23611 self.write_keyword("OBJECT(");
23612 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
23613 if i > 0 {
23614 self.write(", ");
23615 }
23616 self.write(name);
23617 self.write(" ");
23618 self.generate_data_type(dt)?;
23619 if *not_null {
23620 self.write_keyword(" NOT NULL");
23621 }
23622 }
23623 self.write(")");
23624 if let Some(mod_str) = modifier {
23625 self.write(" ");
23626 self.write_keyword(mod_str);
23627 }
23628 }
23629 DataType::Struct { fields, nested } => {
23630 match self.config.dialect {
23632 Some(DialectType::Snowflake) => {
23633 self.write_keyword("OBJECT(");
23635 for (i, field) in fields.iter().enumerate() {
23636 if i > 0 {
23637 self.write(", ");
23638 }
23639 if !field.name.is_empty() {
23640 self.write(&field.name);
23641 self.write(" ");
23642 }
23643 self.generate_data_type(&field.data_type)?;
23644 }
23645 self.write(")");
23646 }
23647 Some(DialectType::Presto) | Some(DialectType::Trino) => {
23648 self.write_keyword("ROW(");
23650 for (i, field) in fields.iter().enumerate() {
23651 if i > 0 {
23652 self.write(", ");
23653 }
23654 if !field.name.is_empty() {
23655 self.write(&field.name);
23656 self.write(" ");
23657 }
23658 self.generate_data_type(&field.data_type)?;
23659 }
23660 self.write(")");
23661 }
23662 Some(DialectType::DuckDB) => {
23663 self.write_keyword("STRUCT(");
23665 for (i, field) in fields.iter().enumerate() {
23666 if i > 0 {
23667 self.write(", ");
23668 }
23669 if !field.name.is_empty() {
23670 self.write(&field.name);
23671 self.write(" ");
23672 }
23673 self.generate_data_type(&field.data_type)?;
23674 }
23675 self.write(")");
23676 }
23677 Some(DialectType::ClickHouse) => {
23678 self.write("Tuple(");
23680 for (i, field) in fields.iter().enumerate() {
23681 if i > 0 {
23682 self.write(", ");
23683 }
23684 if !field.name.is_empty() {
23685 self.write(&field.name);
23686 self.write(" ");
23687 }
23688 self.generate_data_type(&field.data_type)?;
23689 }
23690 self.write(")");
23691 }
23692 Some(DialectType::SingleStore) => {
23693 self.write_keyword("RECORD(");
23695 for (i, field) in fields.iter().enumerate() {
23696 if i > 0 {
23697 self.write(", ");
23698 }
23699 if !field.name.is_empty() {
23700 self.write(&field.name);
23701 self.write(" ");
23702 }
23703 self.generate_data_type(&field.data_type)?;
23704 }
23705 self.write(")");
23706 }
23707 _ => {
23708 let force_angle_brackets = matches!(
23710 self.config.dialect,
23711 Some(DialectType::Hive)
23712 | Some(DialectType::Spark)
23713 | Some(DialectType::Databricks)
23714 );
23715 if *nested && !force_angle_brackets {
23716 self.write_keyword("STRUCT(");
23717 for (i, field) in fields.iter().enumerate() {
23718 if i > 0 {
23719 self.write(", ");
23720 }
23721 if !field.name.is_empty() {
23722 self.write(&field.name);
23723 self.write(" ");
23724 }
23725 self.generate_data_type(&field.data_type)?;
23726 }
23727 self.write(")");
23728 } else {
23729 self.write_keyword("STRUCT<");
23730 for (i, field) in fields.iter().enumerate() {
23731 if i > 0 {
23732 self.write(", ");
23733 }
23734 if !field.name.is_empty() {
23735 self.write(&field.name);
23737 self.write(self.config.struct_field_sep);
23738 }
23739 self.generate_data_type(&field.data_type)?;
23741 if let Some(comment) = &field.comment {
23743 self.write(" COMMENT '");
23744 self.write(comment);
23745 self.write("'");
23746 }
23747 if !field.options.is_empty() {
23749 self.write(" ");
23750 self.generate_options_clause(&field.options)?;
23751 }
23752 }
23753 self.write(">");
23754 }
23755 }
23756 }
23757 }
23758 DataType::Enum {
23759 values,
23760 assignments,
23761 } => {
23762 if self.config.dialect == Some(DialectType::ClickHouse) {
23765 self.write("Enum(");
23766 } else {
23767 self.write_keyword("ENUM(");
23768 }
23769 for (i, val) in values.iter().enumerate() {
23770 if i > 0 {
23771 self.write(", ");
23772 }
23773 self.write("'");
23774 self.write(val);
23775 self.write("'");
23776 if let Some(Some(assignment)) = assignments.get(i) {
23777 self.write(" = ");
23778 self.write(assignment);
23779 }
23780 }
23781 self.write(")");
23782 }
23783 DataType::Set { values } => {
23784 self.write_keyword("SET(");
23786 for (i, val) in values.iter().enumerate() {
23787 if i > 0 {
23788 self.write(", ");
23789 }
23790 self.write("'");
23791 self.write(val);
23792 self.write("'");
23793 }
23794 self.write(")");
23795 }
23796 DataType::Union { fields } => {
23797 self.write_keyword("UNION(");
23799 for (i, (name, dt)) in fields.iter().enumerate() {
23800 if i > 0 {
23801 self.write(", ");
23802 }
23803 if !name.is_empty() {
23804 self.write(name);
23805 self.write(" ");
23806 }
23807 self.generate_data_type(dt)?;
23808 }
23809 self.write(")");
23810 }
23811 DataType::Nullable { inner } => {
23812 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23814 self.write("Nullable(");
23815 let saved_depth = self.clickhouse_nullable_depth;
23817 self.clickhouse_nullable_depth = -1;
23818 self.generate_data_type(inner)?;
23819 self.clickhouse_nullable_depth = saved_depth;
23820 self.write(")");
23821 } else {
23822 match inner.as_ref() {
23824 DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
23825 self.generate_data_type(&DataType::Timestamp {
23826 precision: None,
23827 timezone: false,
23828 })?;
23829 }
23830 _ => {
23831 self.generate_data_type(inner)?;
23832 }
23833 }
23834 }
23835 }
23836 DataType::Custom { name } => {
23837 let name_upper = name.to_ascii_uppercase();
23839 match self.config.dialect {
23840 Some(DialectType::ClickHouse) => {
23841 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
23842 (name_upper[..idx].to_string(), &name[idx..])
23843 } else {
23844 (name_upper.clone(), "")
23845 };
23846 let mapped = match base_upper.as_str() {
23847 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
23848 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
23849 "DATETIME64" => "DateTime64",
23850 "DATE32" => "Date32",
23851 "INT" => "Int32",
23852 "MEDIUMINT" => "Int32",
23853 "INT8" => "Int8",
23854 "INT16" => "Int16",
23855 "INT32" => "Int32",
23856 "INT64" => "Int64",
23857 "INT128" => "Int128",
23858 "INT256" => "Int256",
23859 "UINT8" => "UInt8",
23860 "UINT16" => "UInt16",
23861 "UINT32" => "UInt32",
23862 "UINT64" => "UInt64",
23863 "UINT128" => "UInt128",
23864 "UINT256" => "UInt256",
23865 "FLOAT32" => "Float32",
23866 "FLOAT64" => "Float64",
23867 "DECIMAL32" => "Decimal32",
23868 "DECIMAL64" => "Decimal64",
23869 "DECIMAL128" => "Decimal128",
23870 "DECIMAL256" => "Decimal256",
23871 "ENUM" => "Enum",
23872 "ENUM8" => "Enum8",
23873 "ENUM16" => "Enum16",
23874 "FIXEDSTRING" => "FixedString",
23875 "NESTED" => "Nested",
23876 "LOWCARDINALITY" => "LowCardinality",
23877 "NULLABLE" => "Nullable",
23878 "IPV4" => "IPv4",
23879 "IPV6" => "IPv6",
23880 "POINT" => "Point",
23881 "RING" => "Ring",
23882 "LINESTRING" => "LineString",
23883 "MULTILINESTRING" => "MultiLineString",
23884 "POLYGON" => "Polygon",
23885 "MULTIPOLYGON" => "MultiPolygon",
23886 "AGGREGATEFUNCTION" => "AggregateFunction",
23887 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
23888 "DYNAMIC" => "Dynamic",
23889 _ => "",
23890 };
23891 if mapped.is_empty() {
23892 self.write(name);
23893 } else {
23894 self.write(mapped);
23895 self.write(suffix);
23896 }
23897 }
23898 Some(DialectType::MySQL)
23899 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
23900 {
23901 self.write_keyword("TIMESTAMP");
23903 }
23904 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
23905 self.write_keyword("SQL_VARIANT");
23906 }
23907 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
23908 self.write_keyword("DECIMAL(38, 5)");
23909 }
23910 Some(DialectType::Exasol) => {
23911 match name_upper.as_str() {
23913 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
23915 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
23917 "MEDIUMINT" => self.write_keyword("INT"),
23919 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
23921 self.write_keyword("DECIMAL")
23922 }
23923 "DATETIME" => self.write_keyword("TIMESTAMP"),
23925 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
23926 _ => self.write(name),
23927 }
23928 }
23929 Some(DialectType::Dremio) => {
23930 match name_upper.as_str() {
23932 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
23933 "ARRAY" => self.write_keyword("LIST"),
23934 "NCHAR" => self.write_keyword("VARCHAR"),
23935 _ => self.write(name),
23936 }
23937 }
23938 _ => {
23940 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
23942 (name_upper[..idx].to_string(), Some(&name[idx..]))
23943 } else {
23944 (name_upper.clone(), None)
23945 };
23946
23947 match base_upper.as_str() {
23948 "INT64"
23949 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
23950 {
23951 self.write_keyword("BIGINT");
23952 }
23953 "FLOAT64"
23954 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
23955 {
23956 self.write_keyword("DOUBLE");
23957 }
23958 "BOOL"
23959 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
23960 {
23961 self.write_keyword("BOOLEAN");
23962 }
23963 "BYTES"
23964 if matches!(
23965 self.config.dialect,
23966 Some(DialectType::Spark)
23967 | Some(DialectType::Hive)
23968 | Some(DialectType::Databricks)
23969 ) =>
23970 {
23971 self.write_keyword("BINARY");
23972 }
23973 "BYTES"
23974 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
23975 {
23976 self.write_keyword("VARBINARY");
23977 }
23978 "DATETIME2" | "SMALLDATETIME"
23980 if !matches!(
23981 self.config.dialect,
23982 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23983 ) =>
23984 {
23985 if matches!(
23987 self.config.dialect,
23988 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
23989 ) {
23990 self.write_keyword("TIMESTAMP");
23991 if let Some(args) = _args_str {
23992 self.write(args);
23993 }
23994 } else {
23995 self.write_keyword("TIMESTAMP");
23996 }
23997 }
23998 "DATETIMEOFFSET"
24000 if !matches!(
24001 self.config.dialect,
24002 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24003 ) =>
24004 {
24005 if matches!(
24006 self.config.dialect,
24007 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
24008 ) {
24009 self.write_keyword("TIMESTAMPTZ");
24010 if let Some(args) = _args_str {
24011 self.write(args);
24012 }
24013 } else {
24014 self.write_keyword("TIMESTAMPTZ");
24015 }
24016 }
24017 "UNIQUEIDENTIFIER"
24019 if !matches!(
24020 self.config.dialect,
24021 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24022 ) =>
24023 {
24024 match self.config.dialect {
24025 Some(DialectType::Spark)
24026 | Some(DialectType::Databricks)
24027 | Some(DialectType::Hive) => self.write_keyword("STRING"),
24028 _ => self.write_keyword("UUID"),
24029 }
24030 }
24031 "BIT"
24033 if !matches!(
24034 self.config.dialect,
24035 Some(DialectType::TSQL)
24036 | Some(DialectType::Fabric)
24037 | Some(DialectType::PostgreSQL)
24038 | Some(DialectType::MySQL)
24039 | Some(DialectType::DuckDB)
24040 ) =>
24041 {
24042 self.write_keyword("BOOLEAN");
24043 }
24044 "NVARCHAR"
24046 if !matches!(
24047 self.config.dialect,
24048 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24049 ) =>
24050 {
24051 match self.config.dialect {
24052 Some(DialectType::Oracle) => {
24053 self.write_keyword("NVARCHAR2");
24055 if let Some(args) = _args_str {
24056 self.write(args);
24057 }
24058 }
24059 Some(DialectType::BigQuery) => {
24060 self.write_keyword("STRING");
24062 }
24063 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
24064 self.write_keyword("TEXT");
24065 if let Some(args) = _args_str {
24066 self.write(args);
24067 }
24068 }
24069 Some(DialectType::Hive) => {
24070 self.write_keyword("STRING");
24072 }
24073 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
24074 if _args_str.is_some() {
24075 self.write_keyword("VARCHAR");
24076 self.write(_args_str.unwrap());
24077 } else {
24078 self.write_keyword("STRING");
24079 }
24080 }
24081 _ => {
24082 self.write_keyword("VARCHAR");
24083 if let Some(args) = _args_str {
24084 self.write(args);
24085 }
24086 }
24087 }
24088 }
24089 "NCHAR"
24091 if !matches!(
24092 self.config.dialect,
24093 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24094 ) =>
24095 {
24096 match self.config.dialect {
24097 Some(DialectType::Oracle) => {
24098 self.write_keyword("NCHAR");
24100 if let Some(args) = _args_str {
24101 self.write(args);
24102 }
24103 }
24104 Some(DialectType::BigQuery) => {
24105 self.write_keyword("STRING");
24107 }
24108 Some(DialectType::Hive) => {
24109 self.write_keyword("STRING");
24111 }
24112 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
24113 self.write_keyword("TEXT");
24114 if let Some(args) = _args_str {
24115 self.write(args);
24116 }
24117 }
24118 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
24119 if _args_str.is_some() {
24120 self.write_keyword("CHAR");
24121 self.write(_args_str.unwrap());
24122 } else {
24123 self.write_keyword("STRING");
24124 }
24125 }
24126 _ => {
24127 self.write_keyword("CHAR");
24128 if let Some(args) = _args_str {
24129 self.write(args);
24130 }
24131 }
24132 }
24133 }
24134 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
24137 Some(DialectType::MySQL)
24138 | Some(DialectType::SingleStore)
24139 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
24140 Some(DialectType::Spark)
24141 | Some(DialectType::Databricks)
24142 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
24143 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
24144 Some(DialectType::Presto)
24145 | Some(DialectType::Trino)
24146 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
24147 Some(DialectType::Snowflake)
24148 | Some(DialectType::Redshift)
24149 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
24150 _ => self.write_keyword("TEXT"),
24151 },
24152 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
24155 Some(DialectType::MySQL)
24156 | Some(DialectType::SingleStore)
24157 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
24158 Some(DialectType::Spark)
24159 | Some(DialectType::Databricks)
24160 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
24161 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
24162 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
24163 Some(DialectType::Presto)
24164 | Some(DialectType::Trino)
24165 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
24166 Some(DialectType::Snowflake)
24167 | Some(DialectType::Redshift)
24168 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
24169 _ => self.write_keyword("BLOB"),
24170 },
24171 "LONGVARCHAR" => match self.config.dialect {
24173 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
24174 _ => self.write_keyword("VARCHAR"),
24175 },
24176 "DATETIME" => {
24178 match self.config.dialect {
24179 Some(DialectType::MySQL)
24180 | Some(DialectType::Doris)
24181 | Some(DialectType::StarRocks)
24182 | Some(DialectType::TSQL)
24183 | Some(DialectType::Fabric)
24184 | Some(DialectType::BigQuery)
24185 | Some(DialectType::SQLite)
24186 | Some(DialectType::Snowflake) => {
24187 self.write_keyword("DATETIME");
24188 if let Some(args) = _args_str {
24189 self.write(args);
24190 }
24191 }
24192 Some(_) => {
24193 self.write_keyword("TIMESTAMP");
24195 if let Some(args) = _args_str {
24196 self.write(args);
24197 }
24198 }
24199 None => {
24200 self.write(name);
24202 }
24203 }
24204 }
24205 "VARCHAR2"
24207 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
24208 {
24209 match self.config.dialect {
24210 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24211 self.write_keyword("TEXT");
24212 }
24213 Some(DialectType::Hive)
24214 | Some(DialectType::Spark)
24215 | Some(DialectType::Databricks)
24216 | Some(DialectType::BigQuery)
24217 | Some(DialectType::ClickHouse)
24218 | Some(DialectType::StarRocks)
24219 | Some(DialectType::Doris) => {
24220 self.write_keyword("STRING");
24221 }
24222 _ => {
24223 self.write_keyword("VARCHAR");
24224 if let Some(args) = _args_str {
24225 self.write(args);
24226 }
24227 }
24228 }
24229 }
24230 "NVARCHAR2"
24231 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
24232 {
24233 match self.config.dialect {
24234 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24235 self.write_keyword("TEXT");
24236 }
24237 Some(DialectType::Hive)
24238 | Some(DialectType::Spark)
24239 | Some(DialectType::Databricks)
24240 | Some(DialectType::BigQuery)
24241 | Some(DialectType::ClickHouse)
24242 | Some(DialectType::StarRocks)
24243 | Some(DialectType::Doris) => {
24244 self.write_keyword("STRING");
24245 }
24246 _ => {
24247 self.write_keyword("VARCHAR");
24248 if let Some(args) = _args_str {
24249 self.write(args);
24250 }
24251 }
24252 }
24253 }
24254 _ => self.write(name),
24255 }
24256 }
24257 }
24258 }
24259 DataType::Geometry { subtype, srid } => {
24260 match self.config.dialect {
24262 Some(DialectType::MySQL) => {
24263 if let Some(sub) = subtype {
24265 self.write_keyword(sub);
24266 if let Some(s) = srid {
24267 self.write(" SRID ");
24268 self.write(&s.to_string());
24269 }
24270 } else {
24271 self.write_keyword("GEOMETRY");
24272 }
24273 }
24274 Some(DialectType::BigQuery) => {
24275 self.write_keyword("GEOGRAPHY");
24277 }
24278 Some(DialectType::Teradata) => {
24279 self.write_keyword("ST_GEOMETRY");
24281 if subtype.is_some() || srid.is_some() {
24282 self.write("(");
24283 if let Some(sub) = subtype {
24284 self.write_keyword(sub);
24285 }
24286 if let Some(s) = srid {
24287 if subtype.is_some() {
24288 self.write(", ");
24289 }
24290 self.write(&s.to_string());
24291 }
24292 self.write(")");
24293 }
24294 }
24295 _ => {
24296 self.write_keyword("GEOMETRY");
24298 if subtype.is_some() || srid.is_some() {
24299 self.write("(");
24300 if let Some(sub) = subtype {
24301 self.write_keyword(sub);
24302 }
24303 if let Some(s) = srid {
24304 if subtype.is_some() {
24305 self.write(", ");
24306 }
24307 self.write(&s.to_string());
24308 }
24309 self.write(")");
24310 }
24311 }
24312 }
24313 }
24314 DataType::Geography { subtype, srid } => {
24315 match self.config.dialect {
24317 Some(DialectType::MySQL) => {
24318 if let Some(sub) = subtype {
24320 self.write_keyword(sub);
24321 } else {
24322 self.write_keyword("GEOMETRY");
24323 }
24324 let effective_srid = srid.unwrap_or(4326);
24326 self.write(" SRID ");
24327 self.write(&effective_srid.to_string());
24328 }
24329 Some(DialectType::BigQuery) => {
24330 self.write_keyword("GEOGRAPHY");
24332 }
24333 Some(DialectType::Snowflake) => {
24334 self.write_keyword("GEOGRAPHY");
24336 }
24337 _ => {
24338 self.write_keyword("GEOGRAPHY");
24340 if subtype.is_some() || srid.is_some() {
24341 self.write("(");
24342 if let Some(sub) = subtype {
24343 self.write_keyword(sub);
24344 }
24345 if let Some(s) = srid {
24346 if subtype.is_some() {
24347 self.write(", ");
24348 }
24349 self.write(&s.to_string());
24350 }
24351 self.write(")");
24352 }
24353 }
24354 }
24355 }
24356 DataType::CharacterSet { name } => {
24357 self.write_keyword("CHAR CHARACTER SET ");
24359 self.write(name);
24360 }
24361 _ => self.write("UNKNOWN"),
24362 }
24363 Ok(())
24364 }
24365
24366 #[inline]
24369 fn write(&mut self, s: &str) {
24370 self.output.push_str(s);
24371 }
24372
24373 #[inline]
24374 fn write_space(&mut self) {
24375 self.output.push(' ');
24376 }
24377
24378 #[inline]
24379 fn write_keyword(&mut self, keyword: &str) {
24380 if self.config.uppercase_keywords {
24381 self.output.push_str(keyword);
24382 } else {
24383 for b in keyword.bytes() {
24384 self.output.push(b.to_ascii_lowercase() as char);
24385 }
24386 }
24387 }
24388
24389 fn write_func_name(&mut self, name: &str) {
24391 let normalized = self.normalize_func_name(name);
24392 self.output.push_str(normalized.as_ref());
24393 }
24394
24395 fn convert_strptime_to_exasol_format(format: &str) -> String {
24399 let mut result = String::new();
24400 let chars: Vec<char> = format.chars().collect();
24401 let mut i = 0;
24402 while i < chars.len() {
24403 if chars[i] == '%' && i + 1 < chars.len() {
24404 let spec = chars[i + 1];
24405 let exasol_spec = match spec {
24406 'Y' => "YYYY",
24407 'y' => "YY",
24408 'm' => "MM",
24409 'd' => "DD",
24410 'H' => "HH",
24411 'M' => "MI",
24412 'S' => "SS",
24413 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
24425 result.push('%');
24427 result.push(spec);
24428 i += 2;
24429 continue;
24430 }
24431 };
24432 result.push_str(exasol_spec);
24433 i += 2;
24434 } else {
24435 result.push(chars[i]);
24436 i += 1;
24437 }
24438 }
24439 result
24440 }
24441
24442 fn convert_strptime_to_postgres_format(format: &str) -> String {
24446 let mut result = String::new();
24447 let chars: Vec<char> = format.chars().collect();
24448 let mut i = 0;
24449 while i < chars.len() {
24450 if chars[i] == '%' && i + 1 < chars.len() {
24451 if chars[i + 1] == '-' && i + 2 < chars.len() {
24453 let spec = chars[i + 2];
24454 let pg_spec = match spec {
24455 'd' => "FMDD",
24456 'm' => "FMMM",
24457 'H' => "FMHH24",
24458 'M' => "FMMI",
24459 'S' => "FMSS",
24460 _ => {
24461 result.push('%');
24462 result.push('-');
24463 result.push(spec);
24464 i += 3;
24465 continue;
24466 }
24467 };
24468 result.push_str(pg_spec);
24469 i += 3;
24470 continue;
24471 }
24472 let spec = chars[i + 1];
24473 let pg_spec = match spec {
24474 'Y' => "YYYY",
24475 'y' => "YY",
24476 'm' => "MM",
24477 'd' => "DD",
24478 'H' => "HH24",
24479 'I' => "HH12",
24480 'M' => "MI",
24481 'S' => "SS",
24482 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
24493 result.push('%');
24495 result.push(spec);
24496 i += 2;
24497 continue;
24498 }
24499 };
24500 result.push_str(pg_spec);
24501 i += 2;
24502 } else {
24503 result.push(chars[i]);
24504 i += 1;
24505 }
24506 }
24507 result
24508 }
24509
24510 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
24512 if self.config.limit_only_literals {
24513 if let Some(value) = Self::try_evaluate_constant(expr) {
24514 self.write(&value.to_string());
24515 return Ok(());
24516 }
24517 }
24518 self.generate_expression(expr)
24519 }
24520
24521 fn write_formatted_comment(&mut self, comment: &str) {
24525 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
24528 &comment[2..comment.len() - 2]
24531 } else if comment.starts_with("--") {
24532 &comment[2..]
24535 } else {
24536 comment
24538 };
24539 if content.trim().is_empty() {
24541 return;
24542 }
24543 let sanitized = content.replace("*/", "* /").replace("/*", "/ *");
24546 let content = &sanitized;
24547 self.output.push_str("/*");
24549 if !content.starts_with(' ') {
24550 self.output.push(' ');
24551 }
24552 self.output.push_str(content);
24553 if !content.ends_with(' ') {
24554 self.output.push(' ');
24555 }
24556 self.output.push_str("*/");
24557 }
24558
24559 fn escape_block_for_single_quote(&self, block: &str) -> String {
24562 let escape_backslash = matches!(
24563 self.config.dialect,
24564 Some(crate::dialects::DialectType::Snowflake)
24565 );
24566 let mut escaped = String::with_capacity(block.len() + 4);
24567 for ch in block.chars() {
24568 if ch == '\'' {
24569 escaped.push('\\');
24570 escaped.push('\'');
24571 } else if escape_backslash && ch == '\\' {
24572 escaped.push('\\');
24573 escaped.push('\\');
24574 } else {
24575 escaped.push(ch);
24576 }
24577 }
24578 escaped
24579 }
24580
24581 fn write_newline(&mut self) {
24582 self.output.push('\n');
24583 }
24584
24585 fn write_indent(&mut self) {
24586 for _ in 0..self.indent_level {
24587 self.output.push_str(self.config.indent);
24588 }
24589 }
24590
24591 fn too_wide(&self, args: &[String]) -> bool {
24597 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
24598 }
24599
24600 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
24603 let config = GeneratorConfig {
24604 pretty: false,
24605 dialect: self.config.dialect,
24606 ..Default::default()
24607 };
24608 let mut gen = Generator::with_config(config);
24609 gen.generate_expression(expr)?;
24610 Ok(gen.output)
24611 }
24612
24613 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
24616 if self.config.pretty {
24617 self.write_newline();
24618 self.write_indent();
24619 self.write_keyword(keyword);
24620 self.write_newline();
24621 self.indent_level += 1;
24622 self.write_indent();
24623 self.generate_expression(condition)?;
24624 self.indent_level -= 1;
24625 } else {
24626 self.write_space();
24627 self.write_keyword(keyword);
24628 self.write_space();
24629 self.generate_expression(condition)?;
24630 }
24631 Ok(())
24632 }
24633
24634 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
24637 if exprs.is_empty() {
24638 return Ok(());
24639 }
24640
24641 if self.config.pretty {
24642 self.write_newline();
24643 self.write_indent();
24644 self.write_keyword(keyword);
24645 self.write_newline();
24646 self.indent_level += 1;
24647 for (i, expr) in exprs.iter().enumerate() {
24648 if i > 0 {
24649 self.write(",");
24650 self.write_newline();
24651 }
24652 self.write_indent();
24653 self.generate_expression(expr)?;
24654 }
24655 self.indent_level -= 1;
24656 } else {
24657 self.write_space();
24658 self.write_keyword(keyword);
24659 self.write_space();
24660 for (i, expr) in exprs.iter().enumerate() {
24661 if i > 0 {
24662 self.write(", ");
24663 }
24664 self.generate_expression(expr)?;
24665 }
24666 }
24667 Ok(())
24668 }
24669
24670 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
24672 if orderings.is_empty() {
24673 return Ok(());
24674 }
24675
24676 if self.config.pretty {
24677 self.write_newline();
24678 self.write_indent();
24679 self.write_keyword(keyword);
24680 self.write_newline();
24681 self.indent_level += 1;
24682 for (i, ordered) in orderings.iter().enumerate() {
24683 if i > 0 {
24684 self.write(",");
24685 self.write_newline();
24686 }
24687 self.write_indent();
24688 self.generate_ordered(ordered)?;
24689 }
24690 self.indent_level -= 1;
24691 } else {
24692 self.write_space();
24693 self.write_keyword(keyword);
24694 self.write_space();
24695 for (i, ordered) in orderings.iter().enumerate() {
24696 if i > 0 {
24697 self.write(", ");
24698 }
24699 self.generate_ordered(ordered)?;
24700 }
24701 }
24702 Ok(())
24703 }
24704
24705 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
24707 if windows.is_empty() {
24708 return Ok(());
24709 }
24710
24711 if self.config.pretty {
24712 self.write_newline();
24713 self.write_indent();
24714 self.write_keyword("WINDOW");
24715 self.write_newline();
24716 self.indent_level += 1;
24717 for (i, named_window) in windows.iter().enumerate() {
24718 if i > 0 {
24719 self.write(",");
24720 self.write_newline();
24721 }
24722 self.write_indent();
24723 self.generate_identifier(&named_window.name)?;
24724 self.write_space();
24725 self.write_keyword("AS");
24726 self.write(" (");
24727 self.generate_over(&named_window.spec)?;
24728 self.write(")");
24729 }
24730 self.indent_level -= 1;
24731 } else {
24732 self.write_space();
24733 self.write_keyword("WINDOW");
24734 self.write_space();
24735 for (i, named_window) in windows.iter().enumerate() {
24736 if i > 0 {
24737 self.write(", ");
24738 }
24739 self.generate_identifier(&named_window.name)?;
24740 self.write_space();
24741 self.write_keyword("AS");
24742 self.write(" (");
24743 self.generate_over(&named_window.spec)?;
24744 self.write(")");
24745 }
24746 }
24747 Ok(())
24748 }
24749
24750 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
24752 self.write_keyword("AI_AGG");
24754 self.write("(");
24755 self.generate_expression(&e.this)?;
24756 self.write(", ");
24757 self.generate_expression(&e.expression)?;
24758 self.write(")");
24759 Ok(())
24760 }
24761
24762 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
24763 self.write_keyword("AI_CLASSIFY");
24765 self.write("(");
24766 self.generate_expression(&e.this)?;
24767 if let Some(categories) = &e.categories {
24768 self.write(", ");
24769 self.generate_expression(categories)?;
24770 }
24771 if let Some(config) = &e.config {
24772 self.write(", ");
24773 self.generate_expression(config)?;
24774 }
24775 self.write(")");
24776 Ok(())
24777 }
24778
24779 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
24780 self.write_keyword("ADD");
24782 self.write_space();
24783 if e.exists {
24784 self.write_keyword("IF NOT EXISTS");
24785 self.write_space();
24786 }
24787 self.generate_expression(&e.this)?;
24788 if let Some(location) = &e.location {
24789 self.write_space();
24790 self.generate_expression(location)?;
24791 }
24792 Ok(())
24793 }
24794
24795 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
24796 self.write_keyword("ALGORITHM");
24798 self.write("=");
24799 self.generate_expression(&e.this)?;
24800 Ok(())
24801 }
24802
24803 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
24804 self.generate_expression(&e.this)?;
24806 self.write_space();
24807 self.write_keyword("AS");
24808 self.write(" (");
24809 for (i, expr) in e.expressions.iter().enumerate() {
24810 if i > 0 {
24811 self.write(", ");
24812 }
24813 self.generate_expression(expr)?;
24814 }
24815 self.write(")");
24816 Ok(())
24817 }
24818
24819 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
24820 self.write_keyword("ALLOWED_VALUES");
24822 self.write_space();
24823 for (i, expr) in e.expressions.iter().enumerate() {
24824 if i > 0 {
24825 self.write(", ");
24826 }
24827 self.generate_expression(expr)?;
24828 }
24829 Ok(())
24830 }
24831
24832 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
24833 self.write_keyword("ALTER COLUMN");
24835 self.write_space();
24836 self.generate_expression(&e.this)?;
24837
24838 if let Some(dtype) = &e.dtype {
24839 self.write_space();
24840 self.write_keyword("SET DATA TYPE");
24841 self.write_space();
24842 self.generate_expression(dtype)?;
24843 if let Some(collate) = &e.collate {
24844 self.write_space();
24845 self.write_keyword("COLLATE");
24846 self.write_space();
24847 self.generate_expression(collate)?;
24848 }
24849 if let Some(using) = &e.using {
24850 self.write_space();
24851 self.write_keyword("USING");
24852 self.write_space();
24853 self.generate_expression(using)?;
24854 }
24855 } else if let Some(default) = &e.default {
24856 self.write_space();
24857 self.write_keyword("SET DEFAULT");
24858 self.write_space();
24859 self.generate_expression(default)?;
24860 } else if let Some(comment) = &e.comment {
24861 self.write_space();
24862 self.write_keyword("COMMENT");
24863 self.write_space();
24864 self.generate_expression(comment)?;
24865 } else if let Some(drop) = &e.drop {
24866 self.write_space();
24867 self.write_keyword("DROP");
24868 self.write_space();
24869 self.generate_expression(drop)?;
24870 } else if let Some(visible) = &e.visible {
24871 self.write_space();
24872 self.generate_expression(visible)?;
24873 } else if let Some(rename_to) = &e.rename_to {
24874 self.write_space();
24875 self.write_keyword("RENAME TO");
24876 self.write_space();
24877 self.generate_expression(rename_to)?;
24878 } else if let Some(allow_null) = &e.allow_null {
24879 self.write_space();
24880 self.generate_expression(allow_null)?;
24881 }
24882 Ok(())
24883 }
24884
24885 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
24886 self.write_keyword("ALTER SESSION");
24888 self.write_space();
24889 if e.unset.is_some() {
24890 self.write_keyword("UNSET");
24891 } else {
24892 self.write_keyword("SET");
24893 }
24894 self.write_space();
24895 for (i, expr) in e.expressions.iter().enumerate() {
24896 if i > 0 {
24897 self.write(", ");
24898 }
24899 self.generate_expression(expr)?;
24900 }
24901 Ok(())
24902 }
24903
24904 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
24905 self.write_keyword("SET");
24907
24908 if let Some(opt) = &e.option {
24910 self.write_space();
24911 self.generate_expression(opt)?;
24912 }
24913
24914 if !e.expressions.is_empty() {
24917 let is_properties = e
24919 .expressions
24920 .iter()
24921 .any(|expr| matches!(expr, Expression::Eq(_)));
24922 if is_properties && e.option.is_none() {
24923 self.write_space();
24924 self.write_keyword("PROPERTIES");
24925 }
24926 self.write_space();
24927 for (i, expr) in e.expressions.iter().enumerate() {
24928 if i > 0 {
24929 self.write(", ");
24930 }
24931 self.generate_expression(expr)?;
24932 }
24933 }
24934
24935 if let Some(file_format) = &e.file_format {
24937 self.write(" ");
24938 self.write_keyword("STAGE_FILE_FORMAT");
24939 self.write(" = (");
24940 self.generate_space_separated_properties(file_format)?;
24941 self.write(")");
24942 }
24943
24944 if let Some(copy_options) = &e.copy_options {
24946 self.write(" ");
24947 self.write_keyword("STAGE_COPY_OPTIONS");
24948 self.write(" = (");
24949 self.generate_space_separated_properties(copy_options)?;
24950 self.write(")");
24951 }
24952
24953 if let Some(tag) = &e.tag {
24955 self.write(" ");
24956 self.write_keyword("TAG");
24957 self.write(" ");
24958 self.generate_expression(tag)?;
24959 }
24960
24961 Ok(())
24962 }
24963
24964 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
24966 match expr {
24967 Expression::Tuple(t) => {
24968 for (i, prop) in t.expressions.iter().enumerate() {
24969 if i > 0 {
24970 self.write(" ");
24971 }
24972 self.generate_expression(prop)?;
24973 }
24974 }
24975 _ => {
24976 self.generate_expression(expr)?;
24977 }
24978 }
24979 Ok(())
24980 }
24981
24982 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
24983 self.write_keyword("ALTER");
24985 if e.compound.is_some() {
24986 self.write_space();
24987 self.write_keyword("COMPOUND");
24988 }
24989 self.write_space();
24990 self.write_keyword("SORTKEY");
24991 self.write_space();
24992 if let Some(this) = &e.this {
24993 self.generate_expression(this)?;
24994 } else if !e.expressions.is_empty() {
24995 self.write("(");
24996 for (i, expr) in e.expressions.iter().enumerate() {
24997 if i > 0 {
24998 self.write(", ");
24999 }
25000 self.generate_expression(expr)?;
25001 }
25002 self.write(")");
25003 }
25004 Ok(())
25005 }
25006
25007 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
25008 self.write_keyword("ANALYZE");
25010 if !e.options.is_empty() {
25011 self.write_space();
25012 for (i, opt) in e.options.iter().enumerate() {
25013 if i > 0 {
25014 self.write_space();
25015 }
25016 if let Expression::Identifier(id) = opt {
25018 self.write_keyword(&id.name);
25019 } else {
25020 self.generate_expression(opt)?;
25021 }
25022 }
25023 }
25024 if let Some(kind) = &e.kind {
25025 self.write_space();
25026 self.write_keyword(kind);
25027 }
25028 if let Some(this) = &e.this {
25029 self.write_space();
25030 self.generate_expression(this)?;
25031 }
25032 if !e.columns.is_empty() {
25034 self.write("(");
25035 for (i, col) in e.columns.iter().enumerate() {
25036 if i > 0 {
25037 self.write(", ");
25038 }
25039 self.write(col);
25040 }
25041 self.write(")");
25042 }
25043 if let Some(partition) = &e.partition {
25044 self.write_space();
25045 self.generate_expression(partition)?;
25046 }
25047 if let Some(mode) = &e.mode {
25048 self.write_space();
25049 self.generate_expression(mode)?;
25050 }
25051 if let Some(expression) = &e.expression {
25052 self.write_space();
25053 self.generate_expression(expression)?;
25054 }
25055 if !e.properties.is_empty() {
25056 self.write_space();
25057 self.write_keyword(self.config.with_properties_prefix);
25058 self.write(" (");
25059 for (i, prop) in e.properties.iter().enumerate() {
25060 if i > 0 {
25061 self.write(", ");
25062 }
25063 self.generate_expression(prop)?;
25064 }
25065 self.write(")");
25066 }
25067 Ok(())
25068 }
25069
25070 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
25071 self.write_keyword("DELETE");
25073 if let Some(kind) = &e.kind {
25074 self.write_space();
25075 self.write_keyword(kind);
25076 }
25077 self.write_space();
25078 self.write_keyword("STATISTICS");
25079 Ok(())
25080 }
25081
25082 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
25083 if let Expression::Identifier(id) = e.this.as_ref() {
25086 self.write_keyword(&id.name);
25087 } else {
25088 self.generate_expression(&e.this)?;
25089 }
25090 self.write_space();
25091 self.write_keyword("HISTOGRAM ON");
25092 self.write_space();
25093 for (i, expr) in e.expressions.iter().enumerate() {
25094 if i > 0 {
25095 self.write(", ");
25096 }
25097 self.generate_expression(expr)?;
25098 }
25099 if let Some(expression) = &e.expression {
25100 self.write_space();
25101 self.generate_expression(expression)?;
25102 }
25103 if let Some(update_options) = &e.update_options {
25104 self.write_space();
25105 self.generate_expression(update_options)?;
25106 self.write_space();
25107 self.write_keyword("UPDATE");
25108 }
25109 Ok(())
25110 }
25111
25112 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
25113 self.write_keyword("LIST CHAINED ROWS");
25115 if let Some(expression) = &e.expression {
25116 self.write_space();
25117 self.write_keyword("INTO");
25118 self.write_space();
25119 self.generate_expression(expression)?;
25120 }
25121 Ok(())
25122 }
25123
25124 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
25125 self.write_keyword("SAMPLE");
25127 self.write_space();
25128 if let Some(sample) = &e.sample {
25129 self.generate_expression(sample)?;
25130 self.write_space();
25131 }
25132 self.write_keyword(&e.kind);
25133 Ok(())
25134 }
25135
25136 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
25137 self.write_keyword(&e.kind);
25139 if let Some(option) = &e.option {
25140 self.write_space();
25141 self.generate_expression(option)?;
25142 }
25143 self.write_space();
25144 self.write_keyword("STATISTICS");
25145 if let Some(this) = &e.this {
25146 self.write_space();
25147 self.generate_expression(this)?;
25148 }
25149 if !e.expressions.is_empty() {
25150 self.write_space();
25151 for (i, expr) in e.expressions.iter().enumerate() {
25152 if i > 0 {
25153 self.write(", ");
25154 }
25155 self.generate_expression(expr)?;
25156 }
25157 }
25158 Ok(())
25159 }
25160
25161 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
25162 self.write_keyword("VALIDATE");
25164 self.write_space();
25165 self.write_keyword(&e.kind);
25166 if let Some(this) = &e.this {
25167 self.write_space();
25168 if let Expression::Identifier(id) = this.as_ref() {
25170 self.write_keyword(&id.name);
25171 } else {
25172 self.generate_expression(this)?;
25173 }
25174 }
25175 if let Some(expression) = &e.expression {
25176 self.write_space();
25177 self.write_keyword("INTO");
25178 self.write_space();
25179 self.generate_expression(expression)?;
25180 }
25181 Ok(())
25182 }
25183
25184 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
25185 self.write_keyword("WITH");
25187 self.write_space();
25188 for (i, expr) in e.expressions.iter().enumerate() {
25189 if i > 0 {
25190 self.write(", ");
25191 }
25192 self.generate_expression(expr)?;
25193 }
25194 Ok(())
25195 }
25196
25197 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
25198 self.generate_expression(&e.this)?;
25201 self.write("(");
25202 for (i, arg) in e.expressions.iter().enumerate() {
25203 if i > 0 {
25204 self.write(", ");
25205 }
25206 self.generate_expression(arg)?;
25207 }
25208 self.write(")");
25209 Ok(())
25210 }
25211
25212 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
25213 self.generate_expression(&e.this)?;
25215 self.write("(");
25216 for (i, arg) in e.expressions.iter().enumerate() {
25217 if i > 0 {
25218 self.write(", ");
25219 }
25220 self.generate_expression(arg)?;
25221 }
25222 self.write(")");
25223 Ok(())
25224 }
25225
25226 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
25227 self.generate_expression(&e.this)?;
25229 self.write_space();
25230 self.write_keyword("APPLY");
25231 self.write("(");
25232 self.generate_expression(&e.expression)?;
25233 self.write(")");
25234 Ok(())
25235 }
25236
25237 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
25238 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
25240 self.write("(");
25241 self.generate_expression(&e.this)?;
25242 if let Some(percentile) = &e.percentile {
25243 self.write(", ");
25244 self.generate_expression(percentile)?;
25245 }
25246 self.write(")");
25247 Ok(())
25248 }
25249
25250 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
25251 self.write_keyword("APPROX_QUANTILE");
25253 self.write("(");
25254 self.generate_expression(&e.this)?;
25255 if let Some(quantile) = &e.quantile {
25256 self.write(", ");
25257 self.generate_expression(quantile)?;
25258 }
25259 if let Some(accuracy) = &e.accuracy {
25260 self.write(", ");
25261 self.generate_expression(accuracy)?;
25262 }
25263 if let Some(weight) = &e.weight {
25264 self.write(", ");
25265 self.generate_expression(weight)?;
25266 }
25267 self.write(")");
25268 Ok(())
25269 }
25270
25271 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
25272 self.write_keyword("APPROX_QUANTILES");
25274 self.write("(");
25275 self.generate_expression(&e.this)?;
25276 if let Some(expression) = &e.expression {
25277 self.write(", ");
25278 self.generate_expression(expression)?;
25279 }
25280 self.write(")");
25281 Ok(())
25282 }
25283
25284 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
25285 self.write_keyword("APPROX_TOP_K");
25287 self.write("(");
25288 self.generate_expression(&e.this)?;
25289 if let Some(expression) = &e.expression {
25290 self.write(", ");
25291 self.generate_expression(expression)?;
25292 }
25293 if let Some(counters) = &e.counters {
25294 self.write(", ");
25295 self.generate_expression(counters)?;
25296 }
25297 self.write(")");
25298 Ok(())
25299 }
25300
25301 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
25302 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
25304 self.write("(");
25305 self.generate_expression(&e.this)?;
25306 if let Some(expression) = &e.expression {
25307 self.write(", ");
25308 self.generate_expression(expression)?;
25309 }
25310 self.write(")");
25311 Ok(())
25312 }
25313
25314 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
25315 self.write_keyword("APPROX_TOP_K_COMBINE");
25317 self.write("(");
25318 self.generate_expression(&e.this)?;
25319 if let Some(expression) = &e.expression {
25320 self.write(", ");
25321 self.generate_expression(expression)?;
25322 }
25323 self.write(")");
25324 Ok(())
25325 }
25326
25327 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
25328 self.write_keyword("APPROX_TOP_K_ESTIMATE");
25330 self.write("(");
25331 self.generate_expression(&e.this)?;
25332 if let Some(expression) = &e.expression {
25333 self.write(", ");
25334 self.generate_expression(expression)?;
25335 }
25336 self.write(")");
25337 Ok(())
25338 }
25339
25340 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
25341 self.write_keyword("APPROX_TOP_SUM");
25343 self.write("(");
25344 self.generate_expression(&e.this)?;
25345 self.write(", ");
25346 self.generate_expression(&e.expression)?;
25347 if let Some(count) = &e.count {
25348 self.write(", ");
25349 self.generate_expression(count)?;
25350 }
25351 self.write(")");
25352 Ok(())
25353 }
25354
25355 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
25356 self.write_keyword("ARG_MAX");
25358 self.write("(");
25359 self.generate_expression(&e.this)?;
25360 self.write(", ");
25361 self.generate_expression(&e.expression)?;
25362 if let Some(count) = &e.count {
25363 self.write(", ");
25364 self.generate_expression(count)?;
25365 }
25366 self.write(")");
25367 Ok(())
25368 }
25369
25370 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
25371 self.write_keyword("ARG_MIN");
25373 self.write("(");
25374 self.generate_expression(&e.this)?;
25375 self.write(", ");
25376 self.generate_expression(&e.expression)?;
25377 if let Some(count) = &e.count {
25378 self.write(", ");
25379 self.generate_expression(count)?;
25380 }
25381 self.write(")");
25382 Ok(())
25383 }
25384
25385 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
25386 self.write_keyword("ARRAY_ALL");
25388 self.write("(");
25389 self.generate_expression(&e.this)?;
25390 self.write(", ");
25391 self.generate_expression(&e.expression)?;
25392 self.write(")");
25393 Ok(())
25394 }
25395
25396 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
25397 self.write_keyword("ARRAY_ANY");
25399 self.write("(");
25400 self.generate_expression(&e.this)?;
25401 self.write(", ");
25402 self.generate_expression(&e.expression)?;
25403 self.write(")");
25404 Ok(())
25405 }
25406
25407 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
25408 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
25410 self.write("(");
25411 for (i, expr) in e.expressions.iter().enumerate() {
25412 if i > 0 {
25413 self.write(", ");
25414 }
25415 self.generate_expression(expr)?;
25416 }
25417 self.write(")");
25418 Ok(())
25419 }
25420
25421 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
25422 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
25424 self.write("arraySum");
25425 } else {
25426 self.write_keyword("ARRAY_SUM");
25427 }
25428 self.write("(");
25429 self.generate_expression(&e.this)?;
25430 if let Some(expression) = &e.expression {
25431 self.write(", ");
25432 self.generate_expression(expression)?;
25433 }
25434 self.write(")");
25435 Ok(())
25436 }
25437
25438 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
25439 self.generate_expression(&e.this)?;
25441 self.write_space();
25442 self.write_keyword("AT");
25443 self.write_space();
25444 self.generate_expression(&e.expression)?;
25445 Ok(())
25446 }
25447
25448 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
25449 self.write_keyword("ATTACH");
25451 if e.exists {
25452 self.write_space();
25453 self.write_keyword("IF NOT EXISTS");
25454 }
25455 self.write_space();
25456 self.generate_expression(&e.this)?;
25457 if !e.expressions.is_empty() {
25458 self.write(" (");
25459 for (i, expr) in e.expressions.iter().enumerate() {
25460 if i > 0 {
25461 self.write(", ");
25462 }
25463 self.generate_expression(expr)?;
25464 }
25465 self.write(")");
25466 }
25467 Ok(())
25468 }
25469
25470 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
25471 self.generate_expression(&e.this)?;
25474 if let Some(expression) = &e.expression {
25475 self.write_space();
25476 self.generate_expression(expression)?;
25477 }
25478 Ok(())
25479 }
25480
25481 fn generate_auto_increment_keyword(
25485 &mut self,
25486 col: &crate::expressions::ColumnDef,
25487 ) -> Result<()> {
25488 use crate::dialects::DialectType;
25489 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
25490 self.write_keyword("IDENTITY");
25491 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25492 self.write("(");
25493 if let Some(ref start) = col.auto_increment_start {
25494 self.generate_expression(start)?;
25495 } else {
25496 self.write("0");
25497 }
25498 self.write(", ");
25499 if let Some(ref inc) = col.auto_increment_increment {
25500 self.generate_expression(inc)?;
25501 } else {
25502 self.write("1");
25503 }
25504 self.write(")");
25505 }
25506 } else if matches!(
25507 self.config.dialect,
25508 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
25509 ) {
25510 self.write_keyword("AUTOINCREMENT");
25511 if let Some(ref start) = col.auto_increment_start {
25512 self.write_space();
25513 self.write_keyword("START");
25514 self.write_space();
25515 self.generate_expression(start)?;
25516 }
25517 if let Some(ref inc) = col.auto_increment_increment {
25518 self.write_space();
25519 self.write_keyword("INCREMENT");
25520 self.write_space();
25521 self.generate_expression(inc)?;
25522 }
25523 if let Some(order) = col.auto_increment_order {
25524 self.write_space();
25525 if order {
25526 self.write_keyword("ORDER");
25527 } else {
25528 self.write_keyword("NOORDER");
25529 }
25530 }
25531 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
25532 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
25533 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25534 self.write(" (");
25535 let mut first = true;
25536 if let Some(ref start) = col.auto_increment_start {
25537 self.write_keyword("START WITH");
25538 self.write_space();
25539 self.generate_expression(start)?;
25540 first = false;
25541 }
25542 if let Some(ref inc) = col.auto_increment_increment {
25543 if !first {
25544 self.write_space();
25545 }
25546 self.write_keyword("INCREMENT BY");
25547 self.write_space();
25548 self.generate_expression(inc)?;
25549 }
25550 self.write(")");
25551 }
25552 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
25553 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25556 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
25557 } else {
25558 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
25559 }
25560 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25561 self.write(" (");
25562 let mut first = true;
25563 if let Some(ref start) = col.auto_increment_start {
25564 self.write_keyword("START WITH");
25565 self.write_space();
25566 self.generate_expression(start)?;
25567 first = false;
25568 }
25569 if let Some(ref inc) = col.auto_increment_increment {
25570 if !first {
25571 self.write_space();
25572 }
25573 self.write_keyword("INCREMENT BY");
25574 self.write_space();
25575 self.generate_expression(inc)?;
25576 }
25577 self.write(")");
25578 }
25579 } else if matches!(
25580 self.config.dialect,
25581 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25582 ) {
25583 self.write_keyword("IDENTITY");
25584 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25585 self.write("(");
25586 if let Some(ref start) = col.auto_increment_start {
25587 self.generate_expression(start)?;
25588 } else {
25589 self.write("0");
25590 }
25591 self.write(", ");
25592 if let Some(ref inc) = col.auto_increment_increment {
25593 self.generate_expression(inc)?;
25594 } else {
25595 self.write("1");
25596 }
25597 self.write(")");
25598 }
25599 } else {
25600 self.write_keyword("AUTO_INCREMENT");
25601 if let Some(ref start) = col.auto_increment_start {
25602 self.write_space();
25603 self.write_keyword("START");
25604 self.write_space();
25605 self.generate_expression(start)?;
25606 }
25607 if let Some(ref inc) = col.auto_increment_increment {
25608 self.write_space();
25609 self.write_keyword("INCREMENT");
25610 self.write_space();
25611 self.generate_expression(inc)?;
25612 }
25613 if let Some(order) = col.auto_increment_order {
25614 self.write_space();
25615 if order {
25616 self.write_keyword("ORDER");
25617 } else {
25618 self.write_keyword("NOORDER");
25619 }
25620 }
25621 }
25622 Ok(())
25623 }
25624
25625 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
25626 self.write_keyword("AUTO_INCREMENT");
25628 self.write("=");
25629 self.generate_expression(&e.this)?;
25630 Ok(())
25631 }
25632
25633 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
25634 self.write_keyword("AUTO_REFRESH");
25636 self.write("=");
25637 self.generate_expression(&e.this)?;
25638 Ok(())
25639 }
25640
25641 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
25642 self.write_keyword("BACKUP");
25644 self.write_space();
25645 self.generate_expression(&e.this)?;
25646 Ok(())
25647 }
25648
25649 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
25650 self.write_keyword("BASE64_DECODE_BINARY");
25652 self.write("(");
25653 self.generate_expression(&e.this)?;
25654 if let Some(alphabet) = &e.alphabet {
25655 self.write(", ");
25656 self.generate_expression(alphabet)?;
25657 }
25658 self.write(")");
25659 Ok(())
25660 }
25661
25662 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
25663 self.write_keyword("BASE64_DECODE_STRING");
25665 self.write("(");
25666 self.generate_expression(&e.this)?;
25667 if let Some(alphabet) = &e.alphabet {
25668 self.write(", ");
25669 self.generate_expression(alphabet)?;
25670 }
25671 self.write(")");
25672 Ok(())
25673 }
25674
25675 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
25676 self.write_keyword("BASE64_ENCODE");
25678 self.write("(");
25679 self.generate_expression(&e.this)?;
25680 if let Some(max_line_length) = &e.max_line_length {
25681 self.write(", ");
25682 self.generate_expression(max_line_length)?;
25683 }
25684 if let Some(alphabet) = &e.alphabet {
25685 self.write(", ");
25686 self.generate_expression(alphabet)?;
25687 }
25688 self.write(")");
25689 Ok(())
25690 }
25691
25692 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
25693 self.write_keyword("BLOCKCOMPRESSION");
25695 self.write("=");
25696 if let Some(autotemp) = &e.autotemp {
25697 self.write_keyword("AUTOTEMP");
25698 self.write("(");
25699 self.generate_expression(autotemp)?;
25700 self.write(")");
25701 }
25702 if let Some(always) = &e.always {
25703 self.generate_expression(always)?;
25704 }
25705 if let Some(default) = &e.default {
25706 self.generate_expression(default)?;
25707 }
25708 if let Some(manual) = &e.manual {
25709 self.generate_expression(manual)?;
25710 }
25711 if let Some(never) = &e.never {
25712 self.generate_expression(never)?;
25713 }
25714 Ok(())
25715 }
25716
25717 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
25718 self.write("((");
25720 self.generate_expression(&e.this)?;
25721 self.write(") ");
25722 self.write_keyword("AND");
25723 self.write(" (");
25724 self.generate_expression(&e.expression)?;
25725 self.write("))");
25726 Ok(())
25727 }
25728
25729 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
25730 self.write("((");
25732 self.generate_expression(&e.this)?;
25733 self.write(") ");
25734 self.write_keyword("OR");
25735 self.write(" (");
25736 self.generate_expression(&e.expression)?;
25737 self.write("))");
25738 Ok(())
25739 }
25740
25741 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
25742 self.write_keyword("BUILD");
25744 self.write_space();
25745 self.generate_expression(&e.this)?;
25746 Ok(())
25747 }
25748
25749 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
25750 self.generate_expression(&e.this)?;
25752 Ok(())
25753 }
25754
25755 fn generate_case_specific_column_constraint(
25756 &mut self,
25757 e: &CaseSpecificColumnConstraint,
25758 ) -> Result<()> {
25759 if e.not_.is_some() {
25761 self.write_keyword("NOT");
25762 self.write_space();
25763 }
25764 self.write_keyword("CASESPECIFIC");
25765 Ok(())
25766 }
25767
25768 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
25769 self.write_keyword("CAST");
25771 self.write("(");
25772 self.generate_expression(&e.this)?;
25773 if self.config.dialect == Some(DialectType::ClickHouse) {
25774 self.write(", ");
25776 } else {
25777 self.write_space();
25778 self.write_keyword("AS");
25779 self.write_space();
25780 }
25781 if let Some(to) = &e.to {
25782 self.generate_expression(to)?;
25783 }
25784 self.write(")");
25785 Ok(())
25786 }
25787
25788 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
25789 self.write_keyword("CHANGES");
25792 self.write(" (");
25793 if let Some(information) = &e.information {
25794 self.write_keyword("INFORMATION");
25795 self.write(" => ");
25796 self.generate_expression(information)?;
25797 }
25798 self.write(")");
25799 if let Some(at_before) = &e.at_before {
25801 self.write(" ");
25802 self.generate_expression(at_before)?;
25803 }
25804 if let Some(end) = &e.end {
25805 self.write(" ");
25806 self.generate_expression(end)?;
25807 }
25808 Ok(())
25809 }
25810
25811 fn generate_character_set_column_constraint(
25812 &mut self,
25813 e: &CharacterSetColumnConstraint,
25814 ) -> Result<()> {
25815 self.write_keyword("CHARACTER SET");
25817 self.write_space();
25818 self.generate_expression(&e.this)?;
25819 Ok(())
25820 }
25821
25822 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
25823 if e.default.is_some() {
25825 self.write_keyword("DEFAULT");
25826 self.write_space();
25827 }
25828 self.write_keyword("CHARACTER SET");
25829 self.write("=");
25830 self.generate_expression(&e.this)?;
25831 Ok(())
25832 }
25833
25834 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
25835 self.write_keyword("CHECK");
25837 self.write(" (");
25838 self.generate_expression(&e.this)?;
25839 self.write(")");
25840 if e.enforced.is_some() {
25841 self.write_space();
25842 self.write_keyword("ENFORCED");
25843 }
25844 Ok(())
25845 }
25846
25847 fn generate_assume_column_constraint(&mut self, e: &AssumeColumnConstraint) -> Result<()> {
25848 self.write_keyword("ASSUME");
25850 self.write(" (");
25851 self.generate_expression(&e.this)?;
25852 self.write(")");
25853 Ok(())
25854 }
25855
25856 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
25857 self.write_keyword("CHECK_JSON");
25859 self.write("(");
25860 self.generate_expression(&e.this)?;
25861 self.write(")");
25862 Ok(())
25863 }
25864
25865 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
25866 self.write_keyword("CHECK_XML");
25868 self.write("(");
25869 self.generate_expression(&e.this)?;
25870 self.write(")");
25871 Ok(())
25872 }
25873
25874 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
25875 self.write_keyword("CHECKSUM");
25877 self.write("=");
25878 if e.on.is_some() {
25879 self.write_keyword("ON");
25880 } else if e.default.is_some() {
25881 self.write_keyword("DEFAULT");
25882 } else {
25883 self.write_keyword("OFF");
25884 }
25885 Ok(())
25886 }
25887
25888 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
25889 if e.shallow.is_some() {
25891 self.write_keyword("SHALLOW");
25892 self.write_space();
25893 }
25894 if e.copy.is_some() {
25895 self.write_keyword("COPY");
25896 } else {
25897 self.write_keyword("CLONE");
25898 }
25899 self.write_space();
25900 self.generate_expression(&e.this)?;
25901 Ok(())
25902 }
25903
25904 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
25905 self.write_keyword("CLUSTER BY");
25907 self.write(" (");
25908 for (i, ord) in e.expressions.iter().enumerate() {
25909 if i > 0 {
25910 self.write(", ");
25911 }
25912 self.generate_ordered(ord)?;
25913 }
25914 self.write(")");
25915 Ok(())
25916 }
25917
25918 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
25919 self.write_keyword("CLUSTER BY");
25921 self.write_space();
25922 for (i, col) in e.columns.iter().enumerate() {
25923 if i > 0 {
25924 self.write(", ");
25925 }
25926 self.generate_identifier(col)?;
25927 }
25928 Ok(())
25929 }
25930
25931 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
25932 self.write_keyword("CLUSTERED BY");
25934 self.write(" (");
25935 for (i, expr) in e.expressions.iter().enumerate() {
25936 if i > 0 {
25937 self.write(", ");
25938 }
25939 self.generate_expression(expr)?;
25940 }
25941 self.write(")");
25942 if let Some(sorted_by) = &e.sorted_by {
25943 self.write_space();
25944 self.write_keyword("SORTED BY");
25945 self.write(" (");
25946 if let Expression::Tuple(t) = sorted_by.as_ref() {
25948 for (i, expr) in t.expressions.iter().enumerate() {
25949 if i > 0 {
25950 self.write(", ");
25951 }
25952 self.generate_expression(expr)?;
25953 }
25954 } else {
25955 self.generate_expression(sorted_by)?;
25956 }
25957 self.write(")");
25958 }
25959 if let Some(buckets) = &e.buckets {
25960 self.write_space();
25961 self.write_keyword("INTO");
25962 self.write_space();
25963 self.generate_expression(buckets)?;
25964 self.write_space();
25965 self.write_keyword("BUCKETS");
25966 }
25967 Ok(())
25968 }
25969
25970 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
25971 if e.default.is_some() {
25975 self.write_keyword("DEFAULT");
25976 self.write_space();
25977 }
25978 self.write_keyword("COLLATE");
25979 match self.config.dialect {
25981 Some(DialectType::BigQuery) => self.write_space(),
25982 _ => self.write("="),
25983 }
25984 self.generate_expression(&e.this)?;
25985 Ok(())
25986 }
25987
25988 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
25989 match e {
25991 ColumnConstraint::NotNull => {
25992 self.write_keyword("NOT NULL");
25993 }
25994 ColumnConstraint::Null => {
25995 self.write_keyword("NULL");
25996 }
25997 ColumnConstraint::Unique => {
25998 self.write_keyword("UNIQUE");
25999 }
26000 ColumnConstraint::PrimaryKey => {
26001 self.write_keyword("PRIMARY KEY");
26002 }
26003 ColumnConstraint::Default(expr) => {
26004 self.write_keyword("DEFAULT");
26005 self.write_space();
26006 self.generate_expression(expr)?;
26007 }
26008 ColumnConstraint::Check(expr) => {
26009 self.write_keyword("CHECK");
26010 self.write(" (");
26011 self.generate_expression(expr)?;
26012 self.write(")");
26013 }
26014 ColumnConstraint::References(fk_ref) => {
26015 if fk_ref.has_foreign_key_keywords {
26016 self.write_keyword("FOREIGN KEY");
26017 self.write_space();
26018 }
26019 self.write_keyword("REFERENCES");
26020 self.write_space();
26021 self.generate_table(&fk_ref.table)?;
26022 if !fk_ref.columns.is_empty() {
26023 self.write(" (");
26024 for (i, col) in fk_ref.columns.iter().enumerate() {
26025 if i > 0 {
26026 self.write(", ");
26027 }
26028 self.generate_identifier(col)?;
26029 }
26030 self.write(")");
26031 }
26032 }
26033 ColumnConstraint::GeneratedAsIdentity(gen) => {
26034 self.write_keyword("GENERATED");
26035 self.write_space();
26036 if gen.always {
26037 self.write_keyword("ALWAYS");
26038 } else {
26039 self.write_keyword("BY DEFAULT");
26040 if gen.on_null {
26041 self.write_space();
26042 self.write_keyword("ON NULL");
26043 }
26044 }
26045 self.write_space();
26046 self.write_keyword("AS IDENTITY");
26047 }
26048 ColumnConstraint::Collate(collation) => {
26049 self.write_keyword("COLLATE");
26050 self.write_space();
26051 self.generate_identifier(collation)?;
26052 }
26053 ColumnConstraint::Comment(comment) => {
26054 self.write_keyword("COMMENT");
26055 self.write(" '");
26056 self.write(comment);
26057 self.write("'");
26058 }
26059 ColumnConstraint::ComputedColumn(cc) => {
26060 self.generate_computed_column_inline(cc)?;
26061 }
26062 ColumnConstraint::GeneratedAsRow(gar) => {
26063 self.generate_generated_as_row_inline(gar)?;
26064 }
26065 ColumnConstraint::Tags(tags) => {
26066 self.write_keyword("TAG");
26067 self.write(" (");
26068 for (i, expr) in tags.expressions.iter().enumerate() {
26069 if i > 0 {
26070 self.write(", ");
26071 }
26072 self.generate_expression(expr)?;
26073 }
26074 self.write(")");
26075 }
26076 ColumnConstraint::Path(path_expr) => {
26077 self.write_keyword("PATH");
26078 self.write_space();
26079 self.generate_expression(path_expr)?;
26080 }
26081 }
26082 Ok(())
26083 }
26084
26085 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
26086 match e {
26088 ColumnPosition::First => {
26089 self.write_keyword("FIRST");
26090 }
26091 ColumnPosition::After(ident) => {
26092 self.write_keyword("AFTER");
26093 self.write_space();
26094 self.generate_identifier(ident)?;
26095 }
26096 }
26097 Ok(())
26098 }
26099
26100 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
26101 self.generate_expression(&e.this)?;
26103 self.write("(");
26104 self.generate_expression(&e.expression)?;
26105 self.write(")");
26106 Ok(())
26107 }
26108
26109 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
26110 if let Some(ref unpack) = e.unpack {
26113 if let Expression::Boolean(b) = unpack.as_ref() {
26114 if b.value {
26115 self.write("*");
26116 }
26117 }
26118 }
26119 self.write_keyword("COLUMNS");
26120 self.write("(");
26121 self.generate_expression(&e.this)?;
26122 self.write(")");
26123 Ok(())
26124 }
26125
26126 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
26127 self.generate_expression(&e.this)?;
26129 self.write("(");
26130 for (i, expr) in e.expressions.iter().enumerate() {
26131 if i > 0 {
26132 self.write(", ");
26133 }
26134 self.generate_expression(expr)?;
26135 }
26136 self.write(")");
26137 Ok(())
26138 }
26139
26140 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
26141 self.generate_expression(&e.this)?;
26143 self.write("(");
26144 for (i, param) in e.params.iter().enumerate() {
26145 if i > 0 {
26146 self.write(", ");
26147 }
26148 self.generate_expression(param)?;
26149 }
26150 self.write(")(");
26151 for (i, expr) in e.expressions.iter().enumerate() {
26152 if i > 0 {
26153 self.write(", ");
26154 }
26155 self.generate_expression(expr)?;
26156 }
26157 self.write(")");
26158 Ok(())
26159 }
26160
26161 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
26162 self.write_keyword("COMMIT");
26164
26165 if e.this.is_none()
26167 && matches!(
26168 self.config.dialect,
26169 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26170 )
26171 {
26172 self.write_space();
26173 self.write_keyword("TRANSACTION");
26174 }
26175
26176 if let Some(this) = &e.this {
26178 let is_transaction_marker = matches!(
26180 this.as_ref(),
26181 Expression::Identifier(id) if id.name == "TRANSACTION"
26182 );
26183
26184 self.write_space();
26185 self.write_keyword("TRANSACTION");
26186
26187 if !is_transaction_marker {
26189 self.write_space();
26190 self.generate_expression(this)?;
26191 }
26192 }
26193
26194 if let Some(durability) = &e.durability {
26196 self.write_space();
26197 self.write_keyword("WITH");
26198 self.write(" (");
26199 self.write_keyword("DELAYED_DURABILITY");
26200 self.write(" = ");
26201 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
26202 self.write_keyword("ON");
26203 } else {
26204 self.write_keyword("OFF");
26205 }
26206 self.write(")");
26207 }
26208
26209 if let Some(chain) = &e.chain {
26211 self.write_space();
26212 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
26213 self.write_keyword("AND NO CHAIN");
26214 } else {
26215 self.write_keyword("AND CHAIN");
26216 }
26217 }
26218 Ok(())
26219 }
26220
26221 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
26222 self.write("[");
26224 self.generate_expression(&e.this)?;
26225 self.write_space();
26226 self.write_keyword("FOR");
26227 self.write_space();
26228 self.generate_expression(&e.expression)?;
26229 if let Some(pos) = &e.position {
26231 self.write(", ");
26232 self.generate_expression(pos)?;
26233 }
26234 if let Some(iterator) = &e.iterator {
26235 self.write_space();
26236 self.write_keyword("IN");
26237 self.write_space();
26238 self.generate_expression(iterator)?;
26239 }
26240 if let Some(condition) = &e.condition {
26241 self.write_space();
26242 self.write_keyword("IF");
26243 self.write_space();
26244 self.generate_expression(condition)?;
26245 }
26246 self.write("]");
26247 Ok(())
26248 }
26249
26250 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
26251 self.write_keyword("COMPRESS");
26253 self.write("(");
26254 self.generate_expression(&e.this)?;
26255 if let Some(method) = &e.method {
26256 self.write(", '");
26257 self.write(method);
26258 self.write("'");
26259 }
26260 self.write(")");
26261 Ok(())
26262 }
26263
26264 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
26265 self.write_keyword("COMPRESS");
26267 if let Some(this) = &e.this {
26268 self.write_space();
26269 self.generate_expression(this)?;
26270 }
26271 Ok(())
26272 }
26273
26274 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
26275 self.write_keyword("AS");
26277 self.write_space();
26278 self.generate_expression(&e.this)?;
26279 if e.not_null.is_some() {
26280 self.write_space();
26281 self.write_keyword("PERSISTED NOT NULL");
26282 } else if e.persisted.is_some() {
26283 self.write_space();
26284 self.write_keyword("PERSISTED");
26285 }
26286 Ok(())
26287 }
26288
26289 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
26293 let computed_expr = if matches!(
26294 self.config.dialect,
26295 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26296 ) {
26297 match &*cc.expression {
26298 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
26299 {
26300 let wrapped = Expression::Cast(Box::new(Cast {
26301 this: y.this.clone(),
26302 to: DataType::Date,
26303 trailing_comments: Vec::new(),
26304 double_colon_syntax: false,
26305 format: None,
26306 default: None,
26307 inferred_type: None,
26308 }));
26309 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
26310 }
26311 Expression::Function(f)
26312 if f.name.eq_ignore_ascii_case("YEAR")
26313 && f.args.len() == 1
26314 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
26315 {
26316 let wrapped = Expression::Cast(Box::new(Cast {
26317 this: f.args[0].clone(),
26318 to: DataType::Date,
26319 trailing_comments: Vec::new(),
26320 double_colon_syntax: false,
26321 format: None,
26322 default: None,
26323 inferred_type: None,
26324 }));
26325 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
26326 }
26327 _ => *cc.expression.clone(),
26328 }
26329 } else {
26330 *cc.expression.clone()
26331 };
26332
26333 match cc.persistence_kind.as_deref() {
26334 Some("STORED") | Some("VIRTUAL") => {
26335 self.write_keyword("GENERATED ALWAYS AS");
26337 self.write(" (");
26338 self.generate_expression(&computed_expr)?;
26339 self.write(")");
26340 self.write_space();
26341 if cc.persisted {
26342 self.write_keyword("STORED");
26343 } else {
26344 self.write_keyword("VIRTUAL");
26345 }
26346 }
26347 Some("PERSISTED") => {
26348 self.write_keyword("AS");
26350 self.write(" (");
26351 self.generate_expression(&computed_expr)?;
26352 self.write(")");
26353 self.write_space();
26354 self.write_keyword("PERSISTED");
26355 if let Some(ref dt) = cc.data_type {
26357 self.write_space();
26358 self.generate_data_type(dt)?;
26359 }
26360 if cc.not_null {
26361 self.write_space();
26362 self.write_keyword("NOT NULL");
26363 }
26364 }
26365 _ => {
26366 if matches!(
26369 self.config.dialect,
26370 Some(DialectType::Spark)
26371 | Some(DialectType::Databricks)
26372 | Some(DialectType::Hive)
26373 ) {
26374 self.write_keyword("GENERATED ALWAYS AS");
26375 self.write(" (");
26376 self.generate_expression(&computed_expr)?;
26377 self.write(")");
26378 } else if matches!(
26379 self.config.dialect,
26380 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26381 ) {
26382 self.write_keyword("AS");
26383 let omit_parens = matches!(computed_expr, Expression::Year(_))
26384 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
26385 if omit_parens {
26386 self.write_space();
26387 self.generate_expression(&computed_expr)?;
26388 } else {
26389 self.write(" (");
26390 self.generate_expression(&computed_expr)?;
26391 self.write(")");
26392 }
26393 } else {
26394 self.write_keyword("AS");
26395 self.write(" (");
26396 self.generate_expression(&computed_expr)?;
26397 self.write(")");
26398 }
26399 }
26400 }
26401 Ok(())
26402 }
26403
26404 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
26407 self.write_keyword("GENERATED ALWAYS AS ROW ");
26408 if gar.start {
26409 self.write_keyword("START");
26410 } else {
26411 self.write_keyword("END");
26412 }
26413 if gar.hidden {
26414 self.write_space();
26415 self.write_keyword("HIDDEN");
26416 }
26417 Ok(())
26418 }
26419
26420 fn generate_system_versioning_content(
26422 &mut self,
26423 e: &WithSystemVersioningProperty,
26424 ) -> Result<()> {
26425 let mut parts = Vec::new();
26426
26427 if let Some(this) = &e.this {
26428 let mut s = String::from("HISTORY_TABLE=");
26429 let mut gen = Generator::with_arc_config(self.config.clone());
26430 gen.generate_expression(this)?;
26431 s.push_str(&gen.output);
26432 parts.push(s);
26433 }
26434
26435 if let Some(data_consistency) = &e.data_consistency {
26436 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
26437 let mut gen = Generator::with_arc_config(self.config.clone());
26438 gen.generate_expression(data_consistency)?;
26439 s.push_str(&gen.output);
26440 parts.push(s);
26441 }
26442
26443 if let Some(retention_period) = &e.retention_period {
26444 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
26445 let mut gen = Generator::with_arc_config(self.config.clone());
26446 gen.generate_expression(retention_period)?;
26447 s.push_str(&gen.output);
26448 parts.push(s);
26449 }
26450
26451 self.write_keyword("SYSTEM_VERSIONING");
26452 self.write("=");
26453
26454 if !parts.is_empty() {
26455 self.write_keyword("ON");
26456 self.write("(");
26457 self.write(&parts.join(", "));
26458 self.write(")");
26459 } else if e.on.is_some() {
26460 self.write_keyword("ON");
26461 } else {
26462 self.write_keyword("OFF");
26463 }
26464
26465 Ok(())
26466 }
26467
26468 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
26469 if e.else_.is_some() {
26472 self.write_keyword("ELSE");
26473 self.write_space();
26474 } else if let Some(expression) = &e.expression {
26475 self.write_keyword("WHEN");
26476 self.write_space();
26477 self.generate_expression(expression)?;
26478 self.write_space();
26479 self.write_keyword("THEN");
26480 self.write_space();
26481 }
26482
26483 if let Expression::Insert(insert) = e.this.as_ref() {
26486 self.write_keyword("INTO");
26487 self.write_space();
26488 self.generate_table(&insert.table)?;
26489
26490 if !insert.columns.is_empty() {
26492 self.write(" (");
26493 for (i, col) in insert.columns.iter().enumerate() {
26494 if i > 0 {
26495 self.write(", ");
26496 }
26497 self.generate_identifier(col)?;
26498 }
26499 self.write(")");
26500 }
26501
26502 if !insert.values.is_empty() {
26504 self.write_space();
26505 self.write_keyword("VALUES");
26506 for (row_idx, row) in insert.values.iter().enumerate() {
26507 if row_idx > 0 {
26508 self.write(", ");
26509 }
26510 self.write(" (");
26511 for (i, val) in row.iter().enumerate() {
26512 if i > 0 {
26513 self.write(", ");
26514 }
26515 self.generate_expression(val)?;
26516 }
26517 self.write(")");
26518 }
26519 }
26520 } else {
26521 self.generate_expression(&e.this)?;
26523 }
26524 Ok(())
26525 }
26526
26527 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
26528 self.write_keyword("CONSTRAINT");
26530 self.write_space();
26531 self.generate_expression(&e.this)?;
26532 if !e.expressions.is_empty() {
26533 self.write_space();
26534 for (i, expr) in e.expressions.iter().enumerate() {
26535 if i > 0 {
26536 self.write_space();
26537 }
26538 self.generate_expression(expr)?;
26539 }
26540 }
26541 Ok(())
26542 }
26543
26544 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
26545 self.write_keyword("CONVERT_TIMEZONE");
26547 self.write("(");
26548 let mut first = true;
26549 if let Some(source_tz) = &e.source_tz {
26550 self.generate_expression(source_tz)?;
26551 first = false;
26552 }
26553 if let Some(target_tz) = &e.target_tz {
26554 if !first {
26555 self.write(", ");
26556 }
26557 self.generate_expression(target_tz)?;
26558 first = false;
26559 }
26560 if let Some(timestamp) = &e.timestamp {
26561 if !first {
26562 self.write(", ");
26563 }
26564 self.generate_expression(timestamp)?;
26565 }
26566 self.write(")");
26567 Ok(())
26568 }
26569
26570 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
26571 self.write_keyword("CONVERT");
26573 self.write("(");
26574 self.generate_expression(&e.this)?;
26575 if let Some(dest) = &e.dest {
26576 self.write_space();
26577 self.write_keyword("USING");
26578 self.write_space();
26579 self.generate_expression(dest)?;
26580 }
26581 self.write(")");
26582 Ok(())
26583 }
26584
26585 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
26586 self.write_keyword("COPY");
26587 if e.is_into {
26588 self.write_space();
26589 self.write_keyword("INTO");
26590 }
26591 self.write_space();
26592
26593 if let Expression::Literal(lit) = &e.this {
26595 if let Literal::String(s) = lit.as_ref() {
26596 if s.starts_with('@') {
26597 self.write(s);
26598 } else {
26599 self.generate_expression(&e.this)?;
26600 }
26601 }
26602 } else {
26603 self.generate_expression(&e.this)?;
26604 }
26605
26606 if e.kind {
26608 if self.config.pretty {
26610 self.write_newline();
26611 } else {
26612 self.write_space();
26613 }
26614 self.write_keyword("FROM");
26615 self.write_space();
26616 } else if !e.files.is_empty() {
26617 if self.config.pretty {
26619 self.write_newline();
26620 } else {
26621 self.write_space();
26622 }
26623 self.write_keyword("TO");
26624 self.write_space();
26625 }
26626
26627 for (i, file) in e.files.iter().enumerate() {
26629 if i > 0 {
26630 self.write_space();
26631 }
26632 if let Expression::Literal(lit) = file {
26634 if let Literal::String(s) = lit.as_ref() {
26635 if s.starts_with('@') {
26636 self.write(s);
26637 } else {
26638 self.generate_expression(file)?;
26639 }
26640 }
26641 } else if let Expression::Identifier(id) = file {
26642 if id.quoted {
26644 self.write("`");
26645 self.write(&id.name);
26646 self.write("`");
26647 } else {
26648 self.generate_expression(file)?;
26649 }
26650 } else {
26651 self.generate_expression(file)?;
26652 }
26653 }
26654
26655 if !e.with_wrapped {
26657 if let Some(ref creds) = e.credentials {
26658 if let Some(ref storage) = creds.storage {
26659 if self.config.pretty {
26660 self.write_newline();
26661 } else {
26662 self.write_space();
26663 }
26664 self.write_keyword("STORAGE_INTEGRATION");
26665 self.write(" = ");
26666 self.write(storage);
26667 }
26668 if creds.credentials.is_empty() {
26669 if self.config.pretty {
26671 self.write_newline();
26672 } else {
26673 self.write_space();
26674 }
26675 self.write_keyword("CREDENTIALS");
26676 self.write(" = ()");
26677 } else {
26678 if self.config.pretty {
26679 self.write_newline();
26680 } else {
26681 self.write_space();
26682 }
26683 self.write_keyword("CREDENTIALS");
26684 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
26687 self.write(" '");
26689 self.write(&creds.credentials[0].1);
26690 self.write("'");
26691 } else {
26692 self.write(" = (");
26694 for (i, (k, v)) in creds.credentials.iter().enumerate() {
26695 if i > 0 {
26696 self.write_space();
26697 }
26698 self.write(k);
26699 self.write("='");
26700 self.write(v);
26701 self.write("'");
26702 }
26703 self.write(")");
26704 }
26705 }
26706 if let Some(ref encryption) = creds.encryption {
26707 self.write_space();
26708 self.write_keyword("ENCRYPTION");
26709 self.write(" = ");
26710 self.write(encryption);
26711 }
26712 }
26713 }
26714
26715 if !e.params.is_empty() {
26717 if e.with_wrapped {
26718 self.write_space();
26720 self.write_keyword("WITH");
26721 self.write(" (");
26722 for (i, param) in e.params.iter().enumerate() {
26723 if i > 0 {
26724 self.write(", ");
26725 }
26726 self.generate_copy_param_with_format(param)?;
26727 }
26728 self.write(")");
26729 } else {
26730 for param in &e.params {
26734 if self.config.pretty {
26735 self.write_newline();
26736 } else {
26737 self.write_space();
26738 }
26739 self.write(¶m.name);
26741 if let Some(ref value) = param.value {
26742 if param.eq {
26744 self.write(" = ");
26745 } else {
26746 self.write(" ");
26747 }
26748 if !param.values.is_empty() {
26749 self.write("(");
26750 for (i, v) in param.values.iter().enumerate() {
26751 if i > 0 {
26752 self.write_space();
26753 }
26754 self.generate_copy_nested_param(v)?;
26755 }
26756 self.write(")");
26757 } else {
26758 self.generate_copy_param_value(value)?;
26760 }
26761 } else if !param.values.is_empty() {
26762 if param.eq {
26764 self.write(" = (");
26765 } else {
26766 self.write(" (");
26767 }
26768 let is_key_value_pairs = param
26773 .values
26774 .first()
26775 .map_or(false, |v| matches!(v, Expression::Eq(_)));
26776 let sep = if is_key_value_pairs && param.eq {
26777 " "
26778 } else {
26779 ", "
26780 };
26781 for (i, v) in param.values.iter().enumerate() {
26782 if i > 0 {
26783 self.write(sep);
26784 }
26785 self.generate_copy_nested_param(v)?;
26786 }
26787 self.write(")");
26788 }
26789 }
26790 }
26791 }
26792
26793 Ok(())
26794 }
26795
26796 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
26799 self.write_keyword(¶m.name);
26800 if !param.values.is_empty() {
26801 self.write(" = (");
26803 for (i, v) in param.values.iter().enumerate() {
26804 if i > 0 {
26805 self.write(", ");
26806 }
26807 self.generate_copy_nested_param(v)?;
26808 }
26809 self.write(")");
26810 } else if let Some(ref value) = param.value {
26811 if param.eq {
26812 self.write(" = ");
26813 } else {
26814 self.write(" ");
26815 }
26816 self.generate_expression(value)?;
26817 }
26818 Ok(())
26819 }
26820
26821 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
26823 match expr {
26824 Expression::Eq(eq) => {
26825 match &eq.left {
26827 Expression::Column(c) => self.write(&c.name.name),
26828 _ => self.generate_expression(&eq.left)?,
26829 }
26830 self.write("=");
26831 match &eq.right {
26833 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
26834 let Literal::String(s) = lit.as_ref() else {
26835 unreachable!()
26836 };
26837 self.write("'");
26838 self.write(s);
26839 self.write("'");
26840 }
26841 Expression::Tuple(t) => {
26842 self.write("(");
26844 if self.config.pretty {
26845 self.write_newline();
26846 self.indent_level += 1;
26847 for (i, item) in t.expressions.iter().enumerate() {
26848 if i > 0 {
26849 self.write(", ");
26850 }
26851 self.write_indent();
26852 self.generate_expression(item)?;
26853 }
26854 self.write_newline();
26855 self.indent_level -= 1;
26856 } else {
26857 for (i, item) in t.expressions.iter().enumerate() {
26858 if i > 0 {
26859 self.write(", ");
26860 }
26861 self.generate_expression(item)?;
26862 }
26863 }
26864 self.write(")");
26865 }
26866 _ => self.generate_expression(&eq.right)?,
26867 }
26868 Ok(())
26869 }
26870 Expression::Column(c) => {
26871 self.write(&c.name.name);
26873 Ok(())
26874 }
26875 _ => self.generate_expression(expr),
26876 }
26877 }
26878
26879 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
26882 match expr {
26883 Expression::Column(c) => {
26884 if c.name.quoted {
26886 self.write("\"");
26887 self.write(&c.name.name);
26888 self.write("\"");
26889 } else {
26890 self.write(&c.name.name);
26891 }
26892 Ok(())
26893 }
26894 Expression::Identifier(id) => {
26895 if id.quoted {
26897 self.write("\"");
26898 self.write(&id.name);
26899 self.write("\"");
26900 } else {
26901 self.write(&id.name);
26902 }
26903 Ok(())
26904 }
26905 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
26906 let Literal::String(s) = lit.as_ref() else {
26907 unreachable!()
26908 };
26909 self.write("'");
26911 self.write(s);
26912 self.write("'");
26913 Ok(())
26914 }
26915 _ => self.generate_expression(expr),
26916 }
26917 }
26918
26919 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
26920 self.write_keyword(&e.name);
26921 if let Some(ref value) = e.value {
26922 if e.eq {
26923 self.write(" = ");
26924 } else {
26925 self.write(" ");
26926 }
26927 self.generate_expression(value)?;
26928 }
26929 if !e.values.is_empty() {
26930 if e.eq {
26931 self.write(" = ");
26932 } else {
26933 self.write(" ");
26934 }
26935 self.write("(");
26936 for (i, v) in e.values.iter().enumerate() {
26937 if i > 0 {
26938 self.write(", ");
26939 }
26940 self.generate_expression(v)?;
26941 }
26942 self.write(")");
26943 }
26944 Ok(())
26945 }
26946
26947 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
26948 self.write_keyword("CORR");
26950 self.write("(");
26951 self.generate_expression(&e.this)?;
26952 self.write(", ");
26953 self.generate_expression(&e.expression)?;
26954 self.write(")");
26955 Ok(())
26956 }
26957
26958 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
26959 self.write_keyword("COSINE_DISTANCE");
26961 self.write("(");
26962 self.generate_expression(&e.this)?;
26963 self.write(", ");
26964 self.generate_expression(&e.expression)?;
26965 self.write(")");
26966 Ok(())
26967 }
26968
26969 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
26970 self.write_keyword("COVAR_POP");
26972 self.write("(");
26973 self.generate_expression(&e.this)?;
26974 self.write(", ");
26975 self.generate_expression(&e.expression)?;
26976 self.write(")");
26977 Ok(())
26978 }
26979
26980 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
26981 self.write_keyword("COVAR_SAMP");
26983 self.write("(");
26984 self.generate_expression(&e.this)?;
26985 self.write(", ");
26986 self.generate_expression(&e.expression)?;
26987 self.write(")");
26988 Ok(())
26989 }
26990
26991 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
26992 self.write_keyword("CREDENTIALS");
26994 self.write(" (");
26995 for (i, (key, value)) in e.credentials.iter().enumerate() {
26996 if i > 0 {
26997 self.write(", ");
26998 }
26999 self.write(key);
27000 self.write("='");
27001 self.write(value);
27002 self.write("'");
27003 }
27004 self.write(")");
27005 Ok(())
27006 }
27007
27008 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
27009 self.write_keyword("CREDENTIALS");
27011 self.write("=(");
27012 for (i, expr) in e.expressions.iter().enumerate() {
27013 if i > 0 {
27014 self.write(", ");
27015 }
27016 self.generate_expression(expr)?;
27017 }
27018 self.write(")");
27019 Ok(())
27020 }
27021
27022 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
27023 use crate::dialects::DialectType;
27024
27025 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
27028 self.generate_expression(&e.this)?;
27029 self.write_space();
27030 self.write_keyword("AS");
27031 self.write_space();
27032 self.generate_identifier(&e.alias)?;
27033 return Ok(());
27034 }
27035 self.write(&e.alias.name);
27036
27037 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
27039
27040 if !e.columns.is_empty() && !skip_cte_columns {
27041 self.write("(");
27042 for (i, col) in e.columns.iter().enumerate() {
27043 if i > 0 {
27044 self.write(", ");
27045 }
27046 self.write(&col.name);
27047 }
27048 self.write(")");
27049 }
27050 if !e.key_expressions.is_empty() {
27052 self.write_space();
27053 self.write_keyword("USING KEY");
27054 self.write(" (");
27055 for (i, key) in e.key_expressions.iter().enumerate() {
27056 if i > 0 {
27057 self.write(", ");
27058 }
27059 self.write(&key.name);
27060 }
27061 self.write(")");
27062 }
27063 self.write_space();
27064 self.write_keyword("AS");
27065 self.write_space();
27066 if let Some(materialized) = e.materialized {
27067 if materialized {
27068 self.write_keyword("MATERIALIZED");
27069 } else {
27070 self.write_keyword("NOT MATERIALIZED");
27071 }
27072 self.write_space();
27073 }
27074 self.write("(");
27075 self.generate_expression(&e.this)?;
27076 self.write(")");
27077 Ok(())
27078 }
27079
27080 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
27081 if e.expressions.is_empty() {
27083 self.write_keyword("WITH CUBE");
27084 } else {
27085 self.write_keyword("CUBE");
27086 self.write("(");
27087 for (i, expr) in e.expressions.iter().enumerate() {
27088 if i > 0 {
27089 self.write(", ");
27090 }
27091 self.generate_expression(expr)?;
27092 }
27093 self.write(")");
27094 }
27095 Ok(())
27096 }
27097
27098 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
27099 self.write_keyword("CURRENT_DATETIME");
27101 if let Some(this) = &e.this {
27102 self.write("(");
27103 self.generate_expression(this)?;
27104 self.write(")");
27105 }
27106 Ok(())
27107 }
27108
27109 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
27110 self.write_keyword("CURRENT_SCHEMA");
27112 Ok(())
27113 }
27114
27115 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
27116 self.write_keyword("CURRENT_SCHEMAS");
27118 self.write("(");
27119 if !matches!(
27121 self.config.dialect,
27122 Some(crate::dialects::DialectType::Snowflake)
27123 ) {
27124 if let Some(this) = &e.this {
27125 self.generate_expression(this)?;
27126 }
27127 }
27128 self.write(")");
27129 Ok(())
27130 }
27131
27132 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
27133 self.write_keyword("CURRENT_USER");
27135 let needs_parens = e.this.is_some()
27137 || matches!(
27138 self.config.dialect,
27139 Some(DialectType::Snowflake)
27140 | Some(DialectType::Spark)
27141 | Some(DialectType::Hive)
27142 | Some(DialectType::DuckDB)
27143 | Some(DialectType::BigQuery)
27144 | Some(DialectType::MySQL)
27145 | Some(DialectType::Databricks)
27146 );
27147 if needs_parens {
27148 self.write("()");
27149 }
27150 Ok(())
27151 }
27152
27153 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
27154 if self.config.dialect == Some(DialectType::Solr) {
27156 self.generate_expression(&e.this)?;
27157 self.write(" ");
27158 self.write_keyword("OR");
27159 self.write(" ");
27160 self.generate_expression(&e.expression)?;
27161 } else if self.config.dialect == Some(DialectType::MySQL) {
27162 self.generate_mysql_concat_from_dpipe(e)?;
27163 } else {
27164 self.generate_expression(&e.this)?;
27166 self.write(" || ");
27167 self.generate_expression(&e.expression)?;
27168 }
27169 Ok(())
27170 }
27171
27172 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
27173 self.write_keyword("DATABLOCKSIZE");
27175 self.write("=");
27176 if let Some(size) = e.size {
27177 self.write(&size.to_string());
27178 if let Some(units) = &e.units {
27179 self.write_space();
27180 self.generate_expression(units)?;
27181 }
27182 } else if e.minimum.is_some() {
27183 self.write_keyword("MINIMUM");
27184 } else if e.maximum.is_some() {
27185 self.write_keyword("MAXIMUM");
27186 } else if e.default.is_some() {
27187 self.write_keyword("DEFAULT");
27188 }
27189 Ok(())
27190 }
27191
27192 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
27193 self.write_keyword("DATA_DELETION");
27195 self.write("=");
27196
27197 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
27198 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
27199
27200 if is_on {
27201 self.write_keyword("ON");
27202 if has_options {
27203 self.write("(");
27204 let mut first = true;
27205 if let Some(filter_column) = &e.filter_column {
27206 self.write_keyword("FILTER_COLUMN");
27207 self.write("=");
27208 self.generate_expression(filter_column)?;
27209 first = false;
27210 }
27211 if let Some(retention_period) = &e.retention_period {
27212 if !first {
27213 self.write(", ");
27214 }
27215 self.write_keyword("RETENTION_PERIOD");
27216 self.write("=");
27217 self.generate_expression(retention_period)?;
27218 }
27219 self.write(")");
27220 }
27221 } else {
27222 self.write_keyword("OFF");
27223 }
27224 Ok(())
27225 }
27226
27227 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
27231 use crate::dialects::DialectType;
27232 use crate::expressions::Literal;
27233
27234 match self.config.dialect {
27235 Some(DialectType::Exasol) => {
27237 self.write_keyword("TO_DATE");
27238 self.write("(");
27239 match &e.this {
27241 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27242 let Literal::String(s) = lit.as_ref() else {
27243 unreachable!()
27244 };
27245 self.write("'");
27246 self.write(s);
27247 self.write("'");
27248 }
27249 _ => {
27250 self.generate_expression(&e.this)?;
27251 }
27252 }
27253 self.write(")");
27254 }
27255 _ => {
27257 self.write_keyword("DATE");
27258 self.write("(");
27259 self.generate_expression(&e.this)?;
27260 self.write(")");
27261 }
27262 }
27263 Ok(())
27264 }
27265
27266 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
27267 self.write_keyword("DATE_BIN");
27269 self.write("(");
27270 self.generate_expression(&e.this)?;
27271 self.write(", ");
27272 self.generate_expression(&e.expression)?;
27273 if let Some(origin) = &e.origin {
27274 self.write(", ");
27275 self.generate_expression(origin)?;
27276 }
27277 self.write(")");
27278 Ok(())
27279 }
27280
27281 fn generate_date_format_column_constraint(
27282 &mut self,
27283 e: &DateFormatColumnConstraint,
27284 ) -> Result<()> {
27285 self.write_keyword("FORMAT");
27287 self.write_space();
27288 self.generate_expression(&e.this)?;
27289 Ok(())
27290 }
27291
27292 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
27293 self.write_keyword("DATE_FROM_PARTS");
27295 self.write("(");
27296 let mut first = true;
27297 if let Some(year) = &e.year {
27298 self.generate_expression(year)?;
27299 first = false;
27300 }
27301 if let Some(month) = &e.month {
27302 if !first {
27303 self.write(", ");
27304 }
27305 self.generate_expression(month)?;
27306 first = false;
27307 }
27308 if let Some(day) = &e.day {
27309 if !first {
27310 self.write(", ");
27311 }
27312 self.generate_expression(day)?;
27313 }
27314 self.write(")");
27315 Ok(())
27316 }
27317
27318 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
27319 self.write_keyword("DATETIME");
27321 self.write("(");
27322 self.generate_expression(&e.this)?;
27323 if let Some(expr) = &e.expression {
27324 self.write(", ");
27325 self.generate_expression(expr)?;
27326 }
27327 self.write(")");
27328 Ok(())
27329 }
27330
27331 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
27332 self.write_keyword("DATETIME_ADD");
27334 self.write("(");
27335 self.generate_expression(&e.this)?;
27336 self.write(", ");
27337 self.generate_expression(&e.expression)?;
27338 if let Some(unit) = &e.unit {
27339 self.write(", ");
27340 self.write_keyword(unit);
27341 }
27342 self.write(")");
27343 Ok(())
27344 }
27345
27346 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
27347 self.write_keyword("DATETIME_DIFF");
27349 self.write("(");
27350 self.generate_expression(&e.this)?;
27351 self.write(", ");
27352 self.generate_expression(&e.expression)?;
27353 if let Some(unit) = &e.unit {
27354 self.write(", ");
27355 self.write_keyword(unit);
27356 }
27357 self.write(")");
27358 Ok(())
27359 }
27360
27361 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
27362 self.write_keyword("DATETIME_SUB");
27364 self.write("(");
27365 self.generate_expression(&e.this)?;
27366 self.write(", ");
27367 self.generate_expression(&e.expression)?;
27368 if let Some(unit) = &e.unit {
27369 self.write(", ");
27370 self.write_keyword(unit);
27371 }
27372 self.write(")");
27373 Ok(())
27374 }
27375
27376 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
27377 self.write_keyword("DATETIME_TRUNC");
27379 self.write("(");
27380 self.generate_expression(&e.this)?;
27381 self.write(", ");
27382 self.write_keyword(&e.unit);
27383 if let Some(zone) = &e.zone {
27384 self.write(", ");
27385 self.generate_expression(zone)?;
27386 }
27387 self.write(")");
27388 Ok(())
27389 }
27390
27391 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
27392 self.write_keyword("DAYNAME");
27394 self.write("(");
27395 self.generate_expression(&e.this)?;
27396 self.write(")");
27397 Ok(())
27398 }
27399
27400 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
27401 self.write_keyword("DECLARE");
27403 self.write_space();
27404 if e.replace {
27405 self.write_keyword("OR");
27406 self.write_space();
27407 self.write_keyword("REPLACE");
27408 self.write_space();
27409 }
27410 for (i, expr) in e.expressions.iter().enumerate() {
27411 if i > 0 {
27412 self.write(", ");
27413 }
27414 self.generate_expression(expr)?;
27415 }
27416 Ok(())
27417 }
27418
27419 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
27420 use crate::dialects::DialectType;
27421
27422 self.generate_expression(&e.this)?;
27424 for name in &e.additional_names {
27426 self.write(", ");
27427 self.generate_expression(name)?;
27428 }
27429 if let Some(kind) = &e.kind {
27430 self.write_space();
27431 match self.config.dialect {
27435 Some(DialectType::BigQuery) => {
27436 self.write(kind);
27437 }
27438 Some(DialectType::TSQL) => {
27439 let is_complex_table = kind.starts_with("TABLE")
27443 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
27444 if is_complex_table {
27445 self.write(kind);
27446 } else if kind == "INT" {
27447 self.write("INTEGER");
27448 } else if kind.starts_with("TABLE") {
27449 let normalized = kind
27451 .replace(" INT ", " INTEGER ")
27452 .replace(" INT,", " INTEGER,")
27453 .replace(" INT)", " INTEGER)")
27454 .replace("(INT ", "(INTEGER ");
27455 self.write(&normalized);
27456 } else {
27457 self.write(kind);
27458 }
27459 }
27460 _ => {
27461 if e.has_as {
27462 self.write_keyword("AS");
27463 self.write_space();
27464 }
27465 self.write(kind);
27466 }
27467 }
27468 }
27469 if let Some(default) = &e.default {
27470 match self.config.dialect {
27472 Some(DialectType::BigQuery) => {
27473 self.write_space();
27474 self.write_keyword("DEFAULT");
27475 self.write_space();
27476 }
27477 _ => {
27478 self.write(" = ");
27479 }
27480 }
27481 self.generate_expression(default)?;
27482 }
27483 Ok(())
27484 }
27485
27486 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
27487 self.write_keyword("DECODE");
27489 self.write("(");
27490 for (i, expr) in e.expressions.iter().enumerate() {
27491 if i > 0 {
27492 self.write(", ");
27493 }
27494 self.generate_expression(expr)?;
27495 }
27496 self.write(")");
27497 Ok(())
27498 }
27499
27500 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
27501 self.write_keyword("DECOMPRESS");
27503 self.write("(");
27504 self.generate_expression(&e.this)?;
27505 self.write(", '");
27506 self.write(&e.method);
27507 self.write("')");
27508 Ok(())
27509 }
27510
27511 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
27512 self.write_keyword("DECOMPRESS");
27514 self.write("(");
27515 self.generate_expression(&e.this)?;
27516 self.write(", '");
27517 self.write(&e.method);
27518 self.write("')");
27519 Ok(())
27520 }
27521
27522 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
27523 self.write_keyword("DECRYPT");
27525 self.write("(");
27526 self.generate_expression(&e.this)?;
27527 if let Some(passphrase) = &e.passphrase {
27528 self.write(", ");
27529 self.generate_expression(passphrase)?;
27530 }
27531 if let Some(aad) = &e.aad {
27532 self.write(", ");
27533 self.generate_expression(aad)?;
27534 }
27535 if let Some(method) = &e.encryption_method {
27536 self.write(", ");
27537 self.generate_expression(method)?;
27538 }
27539 self.write(")");
27540 Ok(())
27541 }
27542
27543 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
27544 self.write_keyword("DECRYPT_RAW");
27546 self.write("(");
27547 self.generate_expression(&e.this)?;
27548 if let Some(key) = &e.key {
27549 self.write(", ");
27550 self.generate_expression(key)?;
27551 }
27552 if let Some(iv) = &e.iv {
27553 self.write(", ");
27554 self.generate_expression(iv)?;
27555 }
27556 if let Some(aad) = &e.aad {
27557 self.write(", ");
27558 self.generate_expression(aad)?;
27559 }
27560 if let Some(method) = &e.encryption_method {
27561 self.write(", ");
27562 self.generate_expression(method)?;
27563 }
27564 self.write(")");
27565 Ok(())
27566 }
27567
27568 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
27569 self.write_keyword("DEFINER");
27571 self.write(" = ");
27572 self.generate_expression(&e.this)?;
27573 Ok(())
27574 }
27575
27576 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
27577 self.write_keyword("DETACH");
27579 if e.exists {
27580 self.write_keyword(" DATABASE IF EXISTS");
27581 }
27582 self.write_space();
27583 self.generate_expression(&e.this)?;
27584 Ok(())
27585 }
27586
27587 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
27588 let property_name = match e.this.as_ref() {
27589 Expression::Identifier(id) => id.name.as_str(),
27590 Expression::Var(v) => v.this.as_str(),
27591 _ => "DICTIONARY",
27592 };
27593 self.write_keyword(property_name);
27594 self.write("(");
27595 self.write(&e.kind);
27596 if let Some(settings) = &e.settings {
27597 self.write("(");
27598 if let Expression::Tuple(t) = settings.as_ref() {
27599 if self.config.pretty && !t.expressions.is_empty() {
27600 self.write_newline();
27601 self.indent_level += 1;
27602 for (i, pair) in t.expressions.iter().enumerate() {
27603 if i > 0 {
27604 self.write(",");
27605 self.write_newline();
27606 }
27607 self.write_indent();
27608 if let Expression::Tuple(pair_tuple) = pair {
27609 if let Some(k) = pair_tuple.expressions.first() {
27610 self.generate_expression(k)?;
27611 }
27612 if let Some(v) = pair_tuple.expressions.get(1) {
27613 self.write(" ");
27614 self.generate_expression(v)?;
27615 }
27616 } else {
27617 self.generate_expression(pair)?;
27618 }
27619 }
27620 self.indent_level -= 1;
27621 self.write_newline();
27622 self.write_indent();
27623 } else {
27624 for (i, pair) in t.expressions.iter().enumerate() {
27625 if i > 0 {
27626 self.write(" ");
27628 }
27629 if let Expression::Tuple(pair_tuple) = pair {
27630 if let Some(k) = pair_tuple.expressions.first() {
27631 self.generate_expression(k)?;
27632 }
27633 if let Some(v) = pair_tuple.expressions.get(1) {
27634 self.write(" ");
27635 self.generate_expression(v)?;
27636 }
27637 } else {
27638 self.generate_expression(pair)?;
27639 }
27640 }
27641 }
27642 } else {
27643 self.generate_expression(settings)?;
27644 }
27645 self.write(")");
27646 } else {
27647 self.write("()");
27649 }
27650 self.write(")");
27651 Ok(())
27652 }
27653
27654 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
27655 let property_name = match e.this.as_ref() {
27656 Expression::Identifier(id) => id.name.as_str(),
27657 Expression::Var(v) => v.this.as_str(),
27658 _ => "RANGE",
27659 };
27660 self.write_keyword(property_name);
27661 self.write("(");
27662 if let Some(min) = &e.min {
27663 self.write_keyword("MIN");
27664 self.write_space();
27665 self.generate_expression(min)?;
27666 }
27667 if let Some(max) = &e.max {
27668 self.write_space();
27669 self.write_keyword("MAX");
27670 self.write_space();
27671 self.generate_expression(max)?;
27672 }
27673 self.write(")");
27674 Ok(())
27675 }
27676
27677 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
27678 if e.local.is_some() {
27680 self.write_keyword("LOCAL ");
27681 }
27682 self.write_keyword("DIRECTORY");
27683 self.write_space();
27684 self.generate_expression(&e.this)?;
27685 if let Some(row_format) = &e.row_format {
27686 self.write_space();
27687 self.generate_expression(row_format)?;
27688 }
27689 Ok(())
27690 }
27691
27692 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
27693 self.write_keyword("DISTKEY");
27695 self.write("(");
27696 self.generate_expression(&e.this)?;
27697 self.write(")");
27698 Ok(())
27699 }
27700
27701 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
27702 self.write_keyword("DISTSTYLE");
27704 self.write_space();
27705 self.generate_expression(&e.this)?;
27706 Ok(())
27707 }
27708
27709 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
27710 self.write_keyword("DISTRIBUTE BY");
27712 self.write_space();
27713 for (i, expr) in e.expressions.iter().enumerate() {
27714 if i > 0 {
27715 self.write(", ");
27716 }
27717 self.generate_expression(expr)?;
27718 }
27719 Ok(())
27720 }
27721
27722 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
27723 self.write_keyword("DISTRIBUTED BY");
27725 self.write_space();
27726 self.write(&e.kind);
27727 if !e.expressions.is_empty() {
27728 self.write(" (");
27729 for (i, expr) in e.expressions.iter().enumerate() {
27730 if i > 0 {
27731 self.write(", ");
27732 }
27733 self.generate_expression(expr)?;
27734 }
27735 self.write(")");
27736 }
27737 if let Some(buckets) = &e.buckets {
27738 self.write_space();
27739 self.write_keyword("BUCKETS");
27740 self.write_space();
27741 self.generate_expression(buckets)?;
27742 }
27743 if let Some(order) = &e.order {
27744 self.write_space();
27745 self.generate_expression(order)?;
27746 }
27747 Ok(())
27748 }
27749
27750 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
27751 self.write_keyword("DOT_PRODUCT");
27753 self.write("(");
27754 self.generate_expression(&e.this)?;
27755 self.write(", ");
27756 self.generate_expression(&e.expression)?;
27757 self.write(")");
27758 Ok(())
27759 }
27760
27761 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
27762 self.write_keyword("DROP");
27764 if e.exists {
27765 self.write_keyword(" IF EXISTS ");
27766 } else {
27767 self.write_space();
27768 }
27769 for (i, expr) in e.expressions.iter().enumerate() {
27770 if i > 0 {
27771 self.write(", ");
27772 }
27773 self.generate_expression(expr)?;
27774 }
27775 Ok(())
27776 }
27777
27778 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
27779 self.write_keyword("DUPLICATE KEY");
27781 self.write(" (");
27782 for (i, expr) in e.expressions.iter().enumerate() {
27783 if i > 0 {
27784 self.write(", ");
27785 }
27786 self.generate_expression(expr)?;
27787 }
27788 self.write(")");
27789 Ok(())
27790 }
27791
27792 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
27793 self.write_keyword("ELT");
27795 self.write("(");
27796 self.generate_expression(&e.this)?;
27797 for expr in &e.expressions {
27798 self.write(", ");
27799 self.generate_expression(expr)?;
27800 }
27801 self.write(")");
27802 Ok(())
27803 }
27804
27805 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
27806 self.write_keyword("ENCODE");
27808 self.write("(");
27809 self.generate_expression(&e.this)?;
27810 if let Some(charset) = &e.charset {
27811 self.write(", ");
27812 self.generate_expression(charset)?;
27813 }
27814 self.write(")");
27815 Ok(())
27816 }
27817
27818 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
27819 if e.key.is_some() {
27821 self.write_keyword("KEY ");
27822 }
27823 self.write_keyword("ENCODE");
27824 self.write_space();
27825 self.generate_expression(&e.this)?;
27826 if !e.properties.is_empty() {
27827 self.write(" (");
27828 for (i, prop) in e.properties.iter().enumerate() {
27829 if i > 0 {
27830 self.write(", ");
27831 }
27832 self.generate_expression(prop)?;
27833 }
27834 self.write(")");
27835 }
27836 Ok(())
27837 }
27838
27839 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
27840 self.write_keyword("ENCRYPT");
27842 self.write("(");
27843 self.generate_expression(&e.this)?;
27844 if let Some(passphrase) = &e.passphrase {
27845 self.write(", ");
27846 self.generate_expression(passphrase)?;
27847 }
27848 if let Some(aad) = &e.aad {
27849 self.write(", ");
27850 self.generate_expression(aad)?;
27851 }
27852 if let Some(method) = &e.encryption_method {
27853 self.write(", ");
27854 self.generate_expression(method)?;
27855 }
27856 self.write(")");
27857 Ok(())
27858 }
27859
27860 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
27861 self.write_keyword("ENCRYPT_RAW");
27863 self.write("(");
27864 self.generate_expression(&e.this)?;
27865 if let Some(key) = &e.key {
27866 self.write(", ");
27867 self.generate_expression(key)?;
27868 }
27869 if let Some(iv) = &e.iv {
27870 self.write(", ");
27871 self.generate_expression(iv)?;
27872 }
27873 if let Some(aad) = &e.aad {
27874 self.write(", ");
27875 self.generate_expression(aad)?;
27876 }
27877 if let Some(method) = &e.encryption_method {
27878 self.write(", ");
27879 self.generate_expression(method)?;
27880 }
27881 self.write(")");
27882 Ok(())
27883 }
27884
27885 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
27886 self.write_keyword("ENGINE");
27888 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
27889 self.write("=");
27890 } else {
27891 self.write(" = ");
27892 }
27893 self.generate_expression(&e.this)?;
27894 Ok(())
27895 }
27896
27897 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
27898 self.write_keyword("ENVIRONMENT");
27900 self.write(" (");
27901 for (i, expr) in e.expressions.iter().enumerate() {
27902 if i > 0 {
27903 self.write(", ");
27904 }
27905 self.generate_expression(expr)?;
27906 }
27907 self.write(")");
27908 Ok(())
27909 }
27910
27911 fn generate_ephemeral_column_constraint(
27912 &mut self,
27913 e: &EphemeralColumnConstraint,
27914 ) -> Result<()> {
27915 self.write_keyword("EPHEMERAL");
27917 if let Some(this) = &e.this {
27918 self.write_space();
27919 self.generate_expression(this)?;
27920 }
27921 Ok(())
27922 }
27923
27924 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
27925 self.write_keyword("EQUAL_NULL");
27927 self.write("(");
27928 self.generate_expression(&e.this)?;
27929 self.write(", ");
27930 self.generate_expression(&e.expression)?;
27931 self.write(")");
27932 Ok(())
27933 }
27934
27935 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
27936 use crate::dialects::DialectType;
27937
27938 match self.config.dialect {
27940 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
27941 self.generate_expression(&e.this)?;
27942 self.write(" <-> ");
27943 self.generate_expression(&e.expression)?;
27944 }
27945 _ => {
27946 self.write_keyword("EUCLIDEAN_DISTANCE");
27948 self.write("(");
27949 self.generate_expression(&e.this)?;
27950 self.write(", ");
27951 self.generate_expression(&e.expression)?;
27952 self.write(")");
27953 }
27954 }
27955 Ok(())
27956 }
27957
27958 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
27959 self.write_keyword("EXECUTE AS");
27961 self.write_space();
27962 self.generate_expression(&e.this)?;
27963 Ok(())
27964 }
27965
27966 fn generate_export(&mut self, e: &Export) -> Result<()> {
27967 self.write_keyword("EXPORT DATA");
27969 if let Some(connection) = &e.connection {
27970 self.write_space();
27971 self.write_keyword("WITH CONNECTION");
27972 self.write_space();
27973 self.generate_expression(connection)?;
27974 }
27975 if !e.options.is_empty() {
27976 self.write_space();
27977 self.generate_options_clause(&e.options)?;
27978 }
27979 self.write_space();
27980 self.write_keyword("AS");
27981 self.write_space();
27982 self.generate_expression(&e.this)?;
27983 Ok(())
27984 }
27985
27986 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
27987 self.write_keyword("EXTERNAL");
27989 if let Some(this) = &e.this {
27990 self.write_space();
27991 self.generate_expression(this)?;
27992 }
27993 Ok(())
27994 }
27995
27996 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
27997 if e.no.is_some() {
27999 self.write_keyword("NO ");
28000 }
28001 self.write_keyword("FALLBACK");
28002 if e.protection.is_some() {
28003 self.write_keyword(" PROTECTION");
28004 }
28005 Ok(())
28006 }
28007
28008 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
28009 self.write_keyword("FARM_FINGERPRINT");
28011 self.write("(");
28012 for (i, expr) in e.expressions.iter().enumerate() {
28013 if i > 0 {
28014 self.write(", ");
28015 }
28016 self.generate_expression(expr)?;
28017 }
28018 self.write(")");
28019 Ok(())
28020 }
28021
28022 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
28023 self.write_keyword("FEATURES_AT_TIME");
28025 self.write("(");
28026 self.generate_expression(&e.this)?;
28027 if let Some(time) = &e.time {
28028 self.write(", ");
28029 self.generate_expression(time)?;
28030 }
28031 if let Some(num_rows) = &e.num_rows {
28032 self.write(", ");
28033 self.generate_expression(num_rows)?;
28034 }
28035 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
28036 self.write(", ");
28037 self.generate_expression(ignore_nulls)?;
28038 }
28039 self.write(")");
28040 Ok(())
28041 }
28042
28043 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
28044 let use_limit = !e.percent
28046 && !e.with_ties
28047 && e.count.is_some()
28048 && matches!(
28049 self.config.dialect,
28050 Some(DialectType::Spark)
28051 | Some(DialectType::Hive)
28052 | Some(DialectType::DuckDB)
28053 | Some(DialectType::SQLite)
28054 | Some(DialectType::MySQL)
28055 | Some(DialectType::BigQuery)
28056 | Some(DialectType::Databricks)
28057 | Some(DialectType::StarRocks)
28058 | Some(DialectType::Doris)
28059 | Some(DialectType::Athena)
28060 | Some(DialectType::ClickHouse)
28061 );
28062
28063 if use_limit {
28064 self.write_keyword("LIMIT");
28065 self.write_space();
28066 self.generate_expression(e.count.as_ref().unwrap())?;
28067 return Ok(());
28068 }
28069
28070 self.write_keyword("FETCH");
28072 if !e.direction.is_empty() {
28073 self.write_space();
28074 self.write_keyword(&e.direction);
28075 }
28076 if let Some(count) = &e.count {
28077 self.write_space();
28078 self.generate_expression(count)?;
28079 }
28080 if e.percent {
28082 self.write_keyword(" PERCENT");
28083 }
28084 if e.rows {
28085 self.write_keyword(" ROWS");
28086 }
28087 if e.with_ties {
28088 self.write_keyword(" WITH TIES");
28089 } else if e.rows {
28090 self.write_keyword(" ONLY");
28091 } else {
28092 self.write_keyword(" ROWS ONLY");
28093 }
28094 Ok(())
28095 }
28096
28097 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
28098 if e.hive_format.is_some() {
28102 self.write_keyword("STORED AS");
28104 self.write_space();
28105 if let Some(this) = &e.this {
28106 if let Expression::Identifier(id) = this.as_ref() {
28108 self.write_keyword(&id.name.to_ascii_uppercase());
28109 } else {
28110 self.generate_expression(this)?;
28111 }
28112 }
28113 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
28114 self.write_keyword("STORED AS");
28116 self.write_space();
28117 if let Some(this) = &e.this {
28118 if let Expression::Identifier(id) = this.as_ref() {
28119 self.write_keyword(&id.name.to_ascii_uppercase());
28120 } else {
28121 self.generate_expression(this)?;
28122 }
28123 }
28124 } else if matches!(
28125 self.config.dialect,
28126 Some(DialectType::Spark) | Some(DialectType::Databricks)
28127 ) {
28128 self.write_keyword("USING");
28130 self.write_space();
28131 if let Some(this) = &e.this {
28132 self.generate_expression(this)?;
28133 }
28134 } else {
28135 self.write_keyword("FILE_FORMAT");
28137 self.write(" = ");
28138 if let Some(this) = &e.this {
28139 self.generate_expression(this)?;
28140 } else if !e.expressions.is_empty() {
28141 self.write("(");
28142 for (i, expr) in e.expressions.iter().enumerate() {
28143 if i > 0 {
28144 self.write(", ");
28145 }
28146 self.generate_expression(expr)?;
28147 }
28148 self.write(")");
28149 }
28150 }
28151 Ok(())
28152 }
28153
28154 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
28155 self.generate_expression(&e.this)?;
28157 self.write_space();
28158 self.write_keyword("FILTER");
28159 self.write("(");
28160 self.write_keyword("WHERE");
28161 self.write_space();
28162 self.generate_expression(&e.expression)?;
28163 self.write(")");
28164 Ok(())
28165 }
28166
28167 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
28168 self.write_keyword("FLOAT64");
28170 self.write("(");
28171 self.generate_expression(&e.this)?;
28172 if let Some(expr) = &e.expression {
28173 self.write(", ");
28174 self.generate_expression(expr)?;
28175 }
28176 self.write(")");
28177 Ok(())
28178 }
28179
28180 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
28181 self.write_keyword("FOR");
28183 self.write_space();
28184 self.generate_expression(&e.this)?;
28185 self.write_space();
28186 self.write_keyword("DO");
28187 self.write_space();
28188 self.generate_expression(&e.expression)?;
28189 Ok(())
28190 }
28191
28192 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
28193 self.write_keyword("FOREIGN KEY");
28195 if !e.expressions.is_empty() {
28196 self.write(" (");
28197 for (i, expr) in e.expressions.iter().enumerate() {
28198 if i > 0 {
28199 self.write(", ");
28200 }
28201 self.generate_expression(expr)?;
28202 }
28203 self.write(")");
28204 }
28205 if let Some(reference) = &e.reference {
28206 self.write_space();
28207 self.generate_expression(reference)?;
28208 }
28209 if let Some(delete) = &e.delete {
28210 self.write_space();
28211 self.write_keyword("ON DELETE");
28212 self.write_space();
28213 self.generate_expression(delete)?;
28214 }
28215 if let Some(update) = &e.update {
28216 self.write_space();
28217 self.write_keyword("ON UPDATE");
28218 self.write_space();
28219 self.generate_expression(update)?;
28220 }
28221 if !e.options.is_empty() {
28222 self.write_space();
28223 for (i, opt) in e.options.iter().enumerate() {
28224 if i > 0 {
28225 self.write_space();
28226 }
28227 self.generate_expression(opt)?;
28228 }
28229 }
28230 Ok(())
28231 }
28232
28233 fn generate_format(&mut self, e: &Format) -> Result<()> {
28234 self.write_keyword("FORMAT");
28236 self.write("(");
28237 self.generate_expression(&e.this)?;
28238 for expr in &e.expressions {
28239 self.write(", ");
28240 self.generate_expression(expr)?;
28241 }
28242 self.write(")");
28243 Ok(())
28244 }
28245
28246 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
28247 self.generate_expression(&e.this)?;
28249 self.write(" (");
28250 self.write_keyword("FORMAT");
28251 self.write(" '");
28252 self.write(&e.format);
28253 self.write("')");
28254 Ok(())
28255 }
28256
28257 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
28258 self.write_keyword("FREESPACE");
28260 self.write("=");
28261 self.generate_expression(&e.this)?;
28262 if e.percent.is_some() {
28263 self.write_keyword(" PERCENT");
28264 }
28265 Ok(())
28266 }
28267
28268 fn generate_from(&mut self, e: &From) -> Result<()> {
28269 self.write_keyword("FROM");
28271 self.write_space();
28272
28273 use crate::dialects::DialectType;
28277 let has_tablesample = e
28278 .expressions
28279 .iter()
28280 .any(|expr| matches!(expr, Expression::TableSample(_)));
28281 let is_cross_join_dialect = matches!(
28282 self.config.dialect,
28283 Some(DialectType::BigQuery)
28284 | Some(DialectType::Hive)
28285 | Some(DialectType::Spark)
28286 | Some(DialectType::Databricks)
28287 | Some(DialectType::SQLite)
28288 | Some(DialectType::ClickHouse)
28289 );
28290 let source_is_same_as_target2 = self.config.source_dialect.is_some()
28291 && self.config.source_dialect == self.config.dialect;
28292 let source_is_cross_join_dialect2 = matches!(
28293 self.config.source_dialect,
28294 Some(DialectType::BigQuery)
28295 | Some(DialectType::Hive)
28296 | Some(DialectType::Spark)
28297 | Some(DialectType::Databricks)
28298 | Some(DialectType::SQLite)
28299 | Some(DialectType::ClickHouse)
28300 );
28301 let use_cross_join = !has_tablesample
28302 && is_cross_join_dialect
28303 && (source_is_same_as_target2
28304 || source_is_cross_join_dialect2
28305 || self.config.source_dialect.is_none());
28306
28307 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
28309
28310 for (i, expr) in e.expressions.iter().enumerate() {
28311 if i > 0 {
28312 if use_cross_join {
28313 self.write(" CROSS JOIN ");
28314 } else {
28315 self.write(", ");
28316 }
28317 }
28318 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
28319 self.write("(");
28320 self.generate_expression(expr)?;
28321 self.write(")");
28322 } else {
28323 self.generate_expression(expr)?;
28324 }
28325 let leading = Self::extract_table_leading_comments(expr);
28328 for comment in &leading {
28329 self.write_space();
28330 self.write_formatted_comment(comment);
28331 }
28332 }
28333 Ok(())
28334 }
28335
28336 fn extract_table_leading_comments(expr: &Expression) -> Vec<String> {
28338 match expr {
28339 Expression::Table(t) => t.leading_comments.clone(),
28340 Expression::Pivot(p) => {
28341 if let Expression::Table(t) = &p.this {
28342 t.leading_comments.clone()
28343 } else {
28344 Vec::new()
28345 }
28346 }
28347 _ => Vec::new(),
28348 }
28349 }
28350
28351 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
28352 self.write_keyword("FROM_BASE");
28354 self.write("(");
28355 self.generate_expression(&e.this)?;
28356 self.write(", ");
28357 self.generate_expression(&e.expression)?;
28358 self.write(")");
28359 Ok(())
28360 }
28361
28362 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
28363 self.generate_expression(&e.this)?;
28365 if let Some(zone) = &e.zone {
28366 self.write_space();
28367 self.write_keyword("AT TIME ZONE");
28368 self.write_space();
28369 self.generate_expression(zone)?;
28370 self.write_space();
28371 self.write_keyword("AT TIME ZONE");
28372 self.write(" 'UTC'");
28373 }
28374 Ok(())
28375 }
28376
28377 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
28378 self.write_keyword("GAP_FILL");
28380 self.write("(");
28381 self.generate_expression(&e.this)?;
28382 if let Some(ts_column) = &e.ts_column {
28383 self.write(", ");
28384 self.generate_expression(ts_column)?;
28385 }
28386 if let Some(bucket_width) = &e.bucket_width {
28387 self.write(", ");
28388 self.generate_expression(bucket_width)?;
28389 }
28390 if let Some(partitioning_columns) = &e.partitioning_columns {
28391 self.write(", ");
28392 self.generate_expression(partitioning_columns)?;
28393 }
28394 if let Some(value_columns) = &e.value_columns {
28395 self.write(", ");
28396 self.generate_expression(value_columns)?;
28397 }
28398 self.write(")");
28399 Ok(())
28400 }
28401
28402 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
28403 self.write_keyword("GENERATE_DATE_ARRAY");
28405 self.write("(");
28406 let mut first = true;
28407 if let Some(start) = &e.start {
28408 self.generate_expression(start)?;
28409 first = false;
28410 }
28411 if let Some(end) = &e.end {
28412 if !first {
28413 self.write(", ");
28414 }
28415 self.generate_expression(end)?;
28416 first = false;
28417 }
28418 if let Some(step) = &e.step {
28419 if !first {
28420 self.write(", ");
28421 }
28422 self.generate_expression(step)?;
28423 }
28424 self.write(")");
28425 Ok(())
28426 }
28427
28428 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
28429 self.write_keyword("ML.GENERATE_EMBEDDING");
28431 self.write("(");
28432 self.generate_expression(&e.this)?;
28433 self.write(", ");
28434 self.generate_expression(&e.expression)?;
28435 if let Some(params) = &e.params_struct {
28436 self.write(", ");
28437 self.generate_expression(params)?;
28438 }
28439 self.write(")");
28440 Ok(())
28441 }
28442
28443 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
28444 let fn_name = match self.config.dialect {
28446 Some(DialectType::Presto)
28447 | Some(DialectType::Trino)
28448 | Some(DialectType::Athena)
28449 | Some(DialectType::Spark)
28450 | Some(DialectType::Databricks)
28451 | Some(DialectType::Hive) => "SEQUENCE",
28452 _ => "GENERATE_SERIES",
28453 };
28454 self.write_keyword(fn_name);
28455 self.write("(");
28456 let mut first = true;
28457 if let Some(start) = &e.start {
28458 self.generate_expression(start)?;
28459 first = false;
28460 }
28461 if let Some(end) = &e.end {
28462 if !first {
28463 self.write(", ");
28464 }
28465 self.generate_expression(end)?;
28466 first = false;
28467 }
28468 if let Some(step) = &e.step {
28469 if !first {
28470 self.write(", ");
28471 }
28472 if matches!(
28475 self.config.dialect,
28476 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
28477 ) {
28478 if let Some(converted) = self.convert_week_interval_to_day(step) {
28479 self.generate_expression(&converted)?;
28480 } else {
28481 self.generate_expression(step)?;
28482 }
28483 } else {
28484 self.generate_expression(step)?;
28485 }
28486 }
28487 self.write(")");
28488 Ok(())
28489 }
28490
28491 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
28494 use crate::expressions::*;
28495 if let Expression::Interval(ref iv) = expr {
28496 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
28498 unit: IntervalUnit::Week,
28499 ..
28500 }) = &iv.unit
28501 {
28502 let count = match &iv.this {
28504 Some(Expression::Literal(lit)) => match lit.as_ref() {
28505 Literal::String(s) | Literal::Number(s) => s.clone(),
28506 _ => return None,
28507 },
28508 _ => return None,
28509 };
28510 (true, count)
28511 } else if iv.unit.is_none() {
28512 if let Some(Expression::Literal(lit)) = &iv.this {
28514 if let Literal::String(s) = lit.as_ref() {
28515 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
28516 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
28517 (true, parts[0].to_string())
28518 } else {
28519 (false, String::new())
28520 }
28521 } else {
28522 (false, String::new())
28523 }
28524 } else {
28525 (false, String::new())
28526 }
28527 } else {
28528 (false, String::new())
28529 };
28530
28531 if is_week {
28532 let count_expr = Expression::Literal(Box::new(Literal::Number(count_str)));
28534 let day_interval = Expression::Interval(Box::new(Interval {
28535 this: Some(Expression::Literal(Box::new(Literal::String(
28536 "7".to_string(),
28537 )))),
28538 unit: Some(IntervalUnitSpec::Simple {
28539 unit: IntervalUnit::Day,
28540 use_plural: false,
28541 }),
28542 }));
28543 let mul = Expression::Mul(Box::new(BinaryOp {
28544 left: count_expr,
28545 right: day_interval,
28546 left_comments: vec![],
28547 operator_comments: vec![],
28548 trailing_comments: vec![],
28549 inferred_type: None,
28550 }));
28551 return Some(Expression::Paren(Box::new(Paren {
28552 this: mul,
28553 trailing_comments: vec![],
28554 })));
28555 }
28556 }
28557 None
28558 }
28559
28560 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
28561 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
28563 self.write("(");
28564 let mut first = true;
28565 if let Some(start) = &e.start {
28566 self.generate_expression(start)?;
28567 first = false;
28568 }
28569 if let Some(end) = &e.end {
28570 if !first {
28571 self.write(", ");
28572 }
28573 self.generate_expression(end)?;
28574 first = false;
28575 }
28576 if let Some(step) = &e.step {
28577 if !first {
28578 self.write(", ");
28579 }
28580 self.generate_expression(step)?;
28581 }
28582 self.write(")");
28583 Ok(())
28584 }
28585
28586 fn generate_generated_as_identity_column_constraint(
28587 &mut self,
28588 e: &GeneratedAsIdentityColumnConstraint,
28589 ) -> Result<()> {
28590 use crate::dialects::DialectType;
28591
28592 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
28594 self.write_keyword("AUTOINCREMENT");
28595 if let Some(start) = &e.start {
28596 self.write_keyword(" START ");
28597 self.generate_expression(start)?;
28598 }
28599 if let Some(increment) = &e.increment {
28600 self.write_keyword(" INCREMENT ");
28601 self.generate_expression(increment)?;
28602 }
28603 return Ok(());
28604 }
28605
28606 self.write_keyword("GENERATED");
28608 if let Some(this) = &e.this {
28609 if let Expression::Boolean(b) = this.as_ref() {
28611 if b.value {
28612 self.write_keyword(" ALWAYS");
28613 } else {
28614 self.write_keyword(" BY DEFAULT");
28615 if e.on_null.is_some() {
28616 self.write_keyword(" ON NULL");
28617 }
28618 }
28619 } else {
28620 self.write_keyword(" ALWAYS");
28621 }
28622 }
28623 self.write_keyword(" AS IDENTITY");
28624 let has_options = e.start.is_some()
28626 || e.increment.is_some()
28627 || e.minvalue.is_some()
28628 || e.maxvalue.is_some();
28629 if has_options {
28630 self.write(" (");
28631 let mut first = true;
28632 if let Some(start) = &e.start {
28633 self.write_keyword("START WITH ");
28634 self.generate_expression(start)?;
28635 first = false;
28636 }
28637 if let Some(increment) = &e.increment {
28638 if !first {
28639 self.write(" ");
28640 }
28641 self.write_keyword("INCREMENT BY ");
28642 self.generate_expression(increment)?;
28643 first = false;
28644 }
28645 if let Some(minvalue) = &e.minvalue {
28646 if !first {
28647 self.write(" ");
28648 }
28649 self.write_keyword("MINVALUE ");
28650 self.generate_expression(minvalue)?;
28651 first = false;
28652 }
28653 if let Some(maxvalue) = &e.maxvalue {
28654 if !first {
28655 self.write(" ");
28656 }
28657 self.write_keyword("MAXVALUE ");
28658 self.generate_expression(maxvalue)?;
28659 }
28660 self.write(")");
28661 }
28662 Ok(())
28663 }
28664
28665 fn generate_generated_as_row_column_constraint(
28666 &mut self,
28667 e: &GeneratedAsRowColumnConstraint,
28668 ) -> Result<()> {
28669 self.write_keyword("GENERATED ALWAYS AS ROW ");
28671 if e.start.is_some() {
28672 self.write_keyword("START");
28673 } else {
28674 self.write_keyword("END");
28675 }
28676 if e.hidden.is_some() {
28677 self.write_keyword(" HIDDEN");
28678 }
28679 Ok(())
28680 }
28681
28682 fn generate_get(&mut self, e: &Get) -> Result<()> {
28683 self.write_keyword("GET");
28685 self.write_space();
28686 self.generate_expression(&e.this)?;
28687 if let Some(target) = &e.target {
28688 self.write_space();
28689 self.generate_expression(target)?;
28690 }
28691 for prop in &e.properties {
28692 self.write_space();
28693 self.generate_expression(prop)?;
28694 }
28695 Ok(())
28696 }
28697
28698 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
28699 self.generate_expression(&e.this)?;
28701 self.write("[");
28702 self.generate_expression(&e.expression)?;
28703 self.write("]");
28704 Ok(())
28705 }
28706
28707 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
28708 self.write_keyword("GETBIT");
28710 self.write("(");
28711 self.generate_expression(&e.this)?;
28712 self.write(", ");
28713 self.generate_expression(&e.expression)?;
28714 self.write(")");
28715 Ok(())
28716 }
28717
28718 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
28719 if e.is_role {
28721 self.write_keyword("ROLE");
28722 self.write_space();
28723 } else if e.is_group {
28724 self.write_keyword("GROUP");
28725 self.write_space();
28726 } else if e.is_share {
28727 self.write_keyword("SHARE");
28728 self.write_space();
28729 }
28730 self.write(&e.name.name);
28731 Ok(())
28732 }
28733
28734 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
28735 self.generate_expression(&e.this)?;
28737 if !e.expressions.is_empty() {
28738 self.write("(");
28739 for (i, expr) in e.expressions.iter().enumerate() {
28740 if i > 0 {
28741 self.write(", ");
28742 }
28743 self.generate_expression(expr)?;
28744 }
28745 self.write(")");
28746 }
28747 Ok(())
28748 }
28749
28750 fn generate_group(&mut self, e: &Group) -> Result<()> {
28751 self.write_keyword("GROUP BY");
28753 match e.all {
28755 Some(true) => {
28756 self.write_space();
28757 self.write_keyword("ALL");
28758 }
28759 Some(false) => {
28760 self.write_space();
28761 self.write_keyword("DISTINCT");
28762 }
28763 None => {}
28764 }
28765 if !e.expressions.is_empty() {
28766 self.write_space();
28767 for (i, expr) in e.expressions.iter().enumerate() {
28768 if i > 0 {
28769 self.write(", ");
28770 }
28771 self.generate_expression(expr)?;
28772 }
28773 }
28774 if let Some(cube) = &e.cube {
28776 if !e.expressions.is_empty() {
28777 self.write(", ");
28778 } else {
28779 self.write_space();
28780 }
28781 self.generate_expression(cube)?;
28782 }
28783 if let Some(rollup) = &e.rollup {
28784 if !e.expressions.is_empty() || e.cube.is_some() {
28785 self.write(", ");
28786 } else {
28787 self.write_space();
28788 }
28789 self.generate_expression(rollup)?;
28790 }
28791 if let Some(grouping_sets) = &e.grouping_sets {
28792 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
28793 self.write(", ");
28794 } else {
28795 self.write_space();
28796 }
28797 self.generate_expression(grouping_sets)?;
28798 }
28799 if let Some(totals) = &e.totals {
28800 self.write_space();
28801 self.write_keyword("WITH TOTALS");
28802 self.generate_expression(totals)?;
28803 }
28804 Ok(())
28805 }
28806
28807 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
28808 self.write_keyword("GROUP BY");
28810 match e.all {
28812 Some(true) => {
28813 self.write_space();
28814 self.write_keyword("ALL");
28815 }
28816 Some(false) => {
28817 self.write_space();
28818 self.write_keyword("DISTINCT");
28819 }
28820 None => {}
28821 }
28822
28823 let mut trailing_cube = false;
28826 let mut trailing_rollup = false;
28827 let mut regular_expressions: Vec<&Expression> = Vec::new();
28828
28829 for expr in &e.expressions {
28830 match expr {
28831 Expression::Cube(c) if c.expressions.is_empty() => {
28832 trailing_cube = true;
28833 }
28834 Expression::Rollup(r) if r.expressions.is_empty() => {
28835 trailing_rollup = true;
28836 }
28837 _ => {
28838 regular_expressions.push(expr);
28839 }
28840 }
28841 }
28842
28843 if self.config.pretty {
28845 self.write_newline();
28846 self.indent_level += 1;
28847 for (i, expr) in regular_expressions.iter().enumerate() {
28848 if i > 0 {
28849 self.write(",");
28850 self.write_newline();
28851 }
28852 self.write_indent();
28853 self.generate_expression(expr)?;
28854 }
28855 self.indent_level -= 1;
28856 } else {
28857 self.write_space();
28858 for (i, expr) in regular_expressions.iter().enumerate() {
28859 if i > 0 {
28860 self.write(", ");
28861 }
28862 self.generate_expression(expr)?;
28863 }
28864 }
28865
28866 if trailing_cube {
28868 self.write_space();
28869 self.write_keyword("WITH CUBE");
28870 } else if trailing_rollup {
28871 self.write_space();
28872 self.write_keyword("WITH ROLLUP");
28873 }
28874
28875 if e.totals {
28877 self.write_space();
28878 self.write_keyword("WITH TOTALS");
28879 }
28880
28881 Ok(())
28882 }
28883
28884 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
28885 self.write_keyword("GROUPING");
28887 self.write("(");
28888 for (i, expr) in e.expressions.iter().enumerate() {
28889 if i > 0 {
28890 self.write(", ");
28891 }
28892 self.generate_expression(expr)?;
28893 }
28894 self.write(")");
28895 Ok(())
28896 }
28897
28898 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
28899 self.write_keyword("GROUPING_ID");
28901 self.write("(");
28902 for (i, expr) in e.expressions.iter().enumerate() {
28903 if i > 0 {
28904 self.write(", ");
28905 }
28906 self.generate_expression(expr)?;
28907 }
28908 self.write(")");
28909 Ok(())
28910 }
28911
28912 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
28913 self.write_keyword("GROUPING SETS");
28915 self.write(" (");
28916 for (i, expr) in e.expressions.iter().enumerate() {
28917 if i > 0 {
28918 self.write(", ");
28919 }
28920 self.generate_expression(expr)?;
28921 }
28922 self.write(")");
28923 Ok(())
28924 }
28925
28926 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
28927 self.write_keyword("HASH_AGG");
28929 self.write("(");
28930 self.generate_expression(&e.this)?;
28931 for expr in &e.expressions {
28932 self.write(", ");
28933 self.generate_expression(expr)?;
28934 }
28935 self.write(")");
28936 Ok(())
28937 }
28938
28939 fn generate_having(&mut self, e: &Having) -> Result<()> {
28940 self.write_keyword("HAVING");
28942 self.write_space();
28943 self.generate_expression(&e.this)?;
28944 Ok(())
28945 }
28946
28947 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
28948 self.generate_expression(&e.this)?;
28950 self.write_space();
28951 self.write_keyword("HAVING");
28952 self.write_space();
28953 if e.max.is_some() {
28954 self.write_keyword("MAX");
28955 } else {
28956 self.write_keyword("MIN");
28957 }
28958 self.write_space();
28959 self.generate_expression(&e.expression)?;
28960 Ok(())
28961 }
28962
28963 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
28964 use crate::dialects::DialectType;
28965 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
28967 if let Expression::Literal(ref lit) = *e.this {
28969 if let Literal::String(ref s) = lit.as_ref() {
28970 return self.generate_string_literal(s);
28971 }
28972 }
28973 }
28974 if matches!(
28976 self.config.dialect,
28977 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
28978 ) {
28979 self.write("$");
28980 if let Some(tag) = &e.tag {
28981 self.generate_expression(tag)?;
28982 }
28983 self.write("$");
28984 self.generate_expression(&e.this)?;
28985 self.write("$");
28986 if let Some(tag) = &e.tag {
28987 self.generate_expression(tag)?;
28988 }
28989 self.write("$");
28990 return Ok(());
28991 }
28992 self.write("$");
28994 if let Some(tag) = &e.tag {
28995 self.generate_expression(tag)?;
28996 }
28997 self.write("$");
28998 self.generate_expression(&e.this)?;
28999 self.write("$");
29000 if let Some(tag) = &e.tag {
29001 self.generate_expression(tag)?;
29002 }
29003 self.write("$");
29004 Ok(())
29005 }
29006
29007 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
29008 self.write_keyword("HEX_ENCODE");
29010 self.write("(");
29011 self.generate_expression(&e.this)?;
29012 self.write(")");
29013 Ok(())
29014 }
29015
29016 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
29017 match e.this.as_ref() {
29020 Expression::Identifier(id) => self.write(&id.name),
29021 other => self.generate_expression(other)?,
29022 }
29023 self.write(" (");
29024 self.write(&e.kind);
29025 self.write(" => ");
29026 self.generate_expression(&e.expression)?;
29027 self.write(")");
29028 Ok(())
29029 }
29030
29031 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
29032 self.write_keyword("HLL");
29034 self.write("(");
29035 self.generate_expression(&e.this)?;
29036 for expr in &e.expressions {
29037 self.write(", ");
29038 self.generate_expression(expr)?;
29039 }
29040 self.write(")");
29041 Ok(())
29042 }
29043
29044 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
29045 if e.input_.is_some() && e.output.is_some() {
29047 self.write_keyword("IN OUT");
29048 } else if e.input_.is_some() {
29049 self.write_keyword("IN");
29050 } else if e.output.is_some() {
29051 self.write_keyword("OUT");
29052 }
29053 Ok(())
29054 }
29055
29056 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
29057 self.write_keyword("INCLUDE");
29059 self.write_space();
29060 self.generate_expression(&e.this)?;
29061 if let Some(column_def) = &e.column_def {
29062 self.write_space();
29063 self.generate_expression(column_def)?;
29064 }
29065 if let Some(alias) = &e.alias {
29066 self.write_space();
29067 self.write_keyword("AS");
29068 self.write_space();
29069 self.write(alias);
29070 }
29071 Ok(())
29072 }
29073
29074 fn generate_index(&mut self, e: &Index) -> Result<()> {
29075 if e.unique {
29077 self.write_keyword("UNIQUE");
29078 self.write_space();
29079 }
29080 if e.primary.is_some() {
29081 self.write_keyword("PRIMARY");
29082 self.write_space();
29083 }
29084 if e.amp.is_some() {
29085 self.write_keyword("AMP");
29086 self.write_space();
29087 }
29088 if e.table.is_none() {
29089 self.write_keyword("INDEX");
29090 self.write_space();
29091 }
29092 if let Some(name) = &e.this {
29093 self.generate_expression(name)?;
29094 self.write_space();
29095 }
29096 if let Some(table) = &e.table {
29097 self.write_keyword("ON");
29098 self.write_space();
29099 self.generate_expression(table)?;
29100 }
29101 if !e.params.is_empty() {
29102 self.write("(");
29103 for (i, param) in e.params.iter().enumerate() {
29104 if i > 0 {
29105 self.write(", ");
29106 }
29107 self.generate_expression(param)?;
29108 }
29109 self.write(")");
29110 }
29111 Ok(())
29112 }
29113
29114 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
29115 if let Some(kind) = &e.kind {
29117 self.write(kind);
29118 self.write_space();
29119 }
29120 self.write_keyword("INDEX");
29121 if let Some(this) = &e.this {
29122 self.write_space();
29123 self.generate_expression(this)?;
29124 }
29125 if let Some(index_type) = &e.index_type {
29126 self.write_space();
29127 self.write_keyword("USING");
29128 self.write_space();
29129 self.generate_expression(index_type)?;
29130 }
29131 if !e.expressions.is_empty() {
29132 self.write(" (");
29133 for (i, expr) in e.expressions.iter().enumerate() {
29134 if i > 0 {
29135 self.write(", ");
29136 }
29137 self.generate_expression(expr)?;
29138 }
29139 self.write(")");
29140 }
29141 for opt in &e.options {
29142 self.write_space();
29143 self.generate_expression(opt)?;
29144 }
29145 Ok(())
29146 }
29147
29148 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
29149 if let Some(key_block_size) = &e.key_block_size {
29151 self.write_keyword("KEY_BLOCK_SIZE");
29152 self.write(" = ");
29153 self.generate_expression(key_block_size)?;
29154 } else if let Some(using) = &e.using {
29155 self.write_keyword("USING");
29156 self.write_space();
29157 self.generate_expression(using)?;
29158 } else if let Some(parser) = &e.parser {
29159 self.write_keyword("WITH PARSER");
29160 self.write_space();
29161 self.generate_expression(parser)?;
29162 } else if let Some(comment) = &e.comment {
29163 self.write_keyword("COMMENT");
29164 self.write_space();
29165 self.generate_expression(comment)?;
29166 } else if let Some(visible) = &e.visible {
29167 self.generate_expression(visible)?;
29168 } else if let Some(engine_attr) = &e.engine_attr {
29169 self.write_keyword("ENGINE_ATTRIBUTE");
29170 self.write(" = ");
29171 self.generate_expression(engine_attr)?;
29172 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
29173 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
29174 self.write(" = ");
29175 self.generate_expression(secondary_engine_attr)?;
29176 }
29177 Ok(())
29178 }
29179
29180 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
29181 if let Some(using) = &e.using {
29183 self.write_keyword("USING");
29184 self.write_space();
29185 self.generate_expression(using)?;
29186 }
29187 if !e.columns.is_empty() {
29188 self.write("(");
29189 for (i, col) in e.columns.iter().enumerate() {
29190 if i > 0 {
29191 self.write(", ");
29192 }
29193 self.generate_expression(col)?;
29194 }
29195 self.write(")");
29196 }
29197 if let Some(partition_by) = &e.partition_by {
29198 self.write_space();
29199 self.write_keyword("PARTITION BY");
29200 self.write_space();
29201 self.generate_expression(partition_by)?;
29202 }
29203 if let Some(where_) = &e.where_ {
29204 self.write_space();
29205 self.generate_expression(where_)?;
29206 }
29207 if let Some(include) = &e.include {
29208 self.write_space();
29209 self.write_keyword("INCLUDE");
29210 self.write(" (");
29211 self.generate_expression(include)?;
29212 self.write(")");
29213 }
29214 if let Some(with_storage) = &e.with_storage {
29215 self.write_space();
29216 self.write_keyword("WITH");
29217 self.write(" (");
29218 self.generate_expression(with_storage)?;
29219 self.write(")");
29220 }
29221 if let Some(tablespace) = &e.tablespace {
29222 self.write_space();
29223 self.write_keyword("USING INDEX TABLESPACE");
29224 self.write_space();
29225 self.generate_expression(tablespace)?;
29226 }
29227 Ok(())
29228 }
29229
29230 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
29231 if let Expression::Identifier(id) = &*e.this {
29235 self.write_keyword(&id.name);
29236 } else {
29237 self.generate_expression(&e.this)?;
29238 }
29239 self.write_space();
29240 self.write_keyword("INDEX");
29241 if let Some(target) = &e.target {
29242 self.write_space();
29243 self.write_keyword("FOR");
29244 self.write_space();
29245 if let Expression::Identifier(id) = &**target {
29246 self.write_keyword(&id.name);
29247 } else {
29248 self.generate_expression(target)?;
29249 }
29250 }
29251 self.write(" (");
29253 for (i, expr) in e.expressions.iter().enumerate() {
29254 if i > 0 {
29255 self.write(", ");
29256 }
29257 self.generate_expression(expr)?;
29258 }
29259 self.write(")");
29260 Ok(())
29261 }
29262
29263 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
29264 self.write_keyword("INHERITS");
29266 self.write(" (");
29267 for (i, expr) in e.expressions.iter().enumerate() {
29268 if i > 0 {
29269 self.write(", ");
29270 }
29271 self.generate_expression(expr)?;
29272 }
29273 self.write(")");
29274 Ok(())
29275 }
29276
29277 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
29278 self.write_keyword("INPUT");
29280 self.write("(");
29281 self.generate_expression(&e.this)?;
29282 self.write(")");
29283 Ok(())
29284 }
29285
29286 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
29287 if let Some(input_format) = &e.input_format {
29289 self.write_keyword("INPUTFORMAT");
29290 self.write_space();
29291 self.generate_expression(input_format)?;
29292 }
29293 if let Some(output_format) = &e.output_format {
29294 if e.input_format.is_some() {
29295 self.write(" ");
29296 }
29297 self.write_keyword("OUTPUTFORMAT");
29298 self.write_space();
29299 self.generate_expression(output_format)?;
29300 }
29301 Ok(())
29302 }
29303
29304 fn generate_install(&mut self, e: &Install) -> Result<()> {
29305 if e.force.is_some() {
29307 self.write_keyword("FORCE");
29308 self.write_space();
29309 }
29310 self.write_keyword("INSTALL");
29311 self.write_space();
29312 self.generate_expression(&e.this)?;
29313 if let Some(from) = &e.from_ {
29314 self.write_space();
29315 self.write_keyword("FROM");
29316 self.write_space();
29317 self.generate_expression(from)?;
29318 }
29319 Ok(())
29320 }
29321
29322 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
29323 self.write_keyword("INTERVAL");
29325 self.write_space();
29326 self.generate_expression(&e.expression)?;
29328 if let Some(unit) = &e.unit {
29329 self.write_space();
29330 self.write(unit);
29331 }
29332 Ok(())
29333 }
29334
29335 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
29336 self.write(&format!("{:?}", e.this).to_ascii_uppercase());
29338 self.write_space();
29339 self.write_keyword("TO");
29340 self.write_space();
29341 self.write(&format!("{:?}", e.expression).to_ascii_uppercase());
29342 Ok(())
29343 }
29344
29345 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
29346 self.write_keyword("INTO");
29348 if e.temporary {
29349 self.write_keyword(" TEMPORARY");
29350 }
29351 if e.unlogged.is_some() {
29352 self.write_keyword(" UNLOGGED");
29353 }
29354 if let Some(this) = &e.this {
29355 self.write_space();
29356 self.generate_expression(this)?;
29357 }
29358 if !e.expressions.is_empty() {
29359 self.write(" (");
29360 for (i, expr) in e.expressions.iter().enumerate() {
29361 if i > 0 {
29362 self.write(", ");
29363 }
29364 self.generate_expression(expr)?;
29365 }
29366 self.write(")");
29367 }
29368 Ok(())
29369 }
29370
29371 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
29372 self.generate_expression(&e.this)?;
29374 self.write_space();
29375 self.generate_expression(&e.expression)?;
29376 Ok(())
29377 }
29378
29379 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
29380 self.write_keyword("WITH");
29382 if e.no.is_some() {
29383 self.write_keyword(" NO");
29384 }
29385 if e.concurrent.is_some() {
29386 self.write_keyword(" CONCURRENT");
29387 }
29388 self.write_keyword(" ISOLATED LOADING");
29389 if let Some(target) = &e.target {
29390 self.write_space();
29391 self.generate_expression(target)?;
29392 }
29393 Ok(())
29394 }
29395
29396 fn generate_json(&mut self, e: &JSON) -> Result<()> {
29397 self.write_keyword("JSON");
29399 if let Some(this) = &e.this {
29400 self.write_space();
29401 self.generate_expression(this)?;
29402 }
29403 if let Some(with_) = &e.with_ {
29404 if let Expression::Boolean(b) = with_.as_ref() {
29406 if b.value {
29407 self.write_keyword(" WITH");
29408 } else {
29409 self.write_keyword(" WITHOUT");
29410 }
29411 }
29412 }
29413 if e.unique {
29414 self.write_keyword(" UNIQUE KEYS");
29415 }
29416 Ok(())
29417 }
29418
29419 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
29420 self.write_keyword("JSON_ARRAY");
29422 self.write("(");
29423 for (i, expr) in e.expressions.iter().enumerate() {
29424 if i > 0 {
29425 self.write(", ");
29426 }
29427 self.generate_expression(expr)?;
29428 }
29429 if let Some(null_handling) = &e.null_handling {
29430 self.write_space();
29431 self.generate_expression(null_handling)?;
29432 }
29433 if let Some(return_type) = &e.return_type {
29434 self.write_space();
29435 self.write_keyword("RETURNING");
29436 self.write_space();
29437 self.generate_expression(return_type)?;
29438 }
29439 if e.strict.is_some() {
29440 self.write_space();
29441 self.write_keyword("STRICT");
29442 }
29443 self.write(")");
29444 Ok(())
29445 }
29446
29447 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
29448 self.write_keyword("JSON_ARRAYAGG");
29450 self.write("(");
29451 self.generate_expression(&e.this)?;
29452 if let Some(order) = &e.order {
29453 self.write_space();
29454 if let Expression::OrderBy(ob) = order.as_ref() {
29456 self.write_keyword("ORDER BY");
29457 self.write_space();
29458 for (i, ord) in ob.expressions.iter().enumerate() {
29459 if i > 0 {
29460 self.write(", ");
29461 }
29462 self.generate_ordered(ord)?;
29463 }
29464 } else {
29465 self.generate_expression(order)?;
29467 }
29468 }
29469 if let Some(null_handling) = &e.null_handling {
29470 self.write_space();
29471 self.generate_expression(null_handling)?;
29472 }
29473 if let Some(return_type) = &e.return_type {
29474 self.write_space();
29475 self.write_keyword("RETURNING");
29476 self.write_space();
29477 self.generate_expression(return_type)?;
29478 }
29479 if e.strict.is_some() {
29480 self.write_space();
29481 self.write_keyword("STRICT");
29482 }
29483 self.write(")");
29484 Ok(())
29485 }
29486
29487 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
29488 self.write_keyword("JSON_OBJECTAGG");
29490 self.write("(");
29491 for (i, expr) in e.expressions.iter().enumerate() {
29492 if i > 0 {
29493 self.write(", ");
29494 }
29495 self.generate_expression(expr)?;
29496 }
29497 if let Some(null_handling) = &e.null_handling {
29498 self.write_space();
29499 self.generate_expression(null_handling)?;
29500 }
29501 if let Some(unique_keys) = &e.unique_keys {
29502 self.write_space();
29503 if let Expression::Boolean(b) = unique_keys.as_ref() {
29504 if b.value {
29505 self.write_keyword("WITH UNIQUE KEYS");
29506 } else {
29507 self.write_keyword("WITHOUT UNIQUE KEYS");
29508 }
29509 }
29510 }
29511 if let Some(return_type) = &e.return_type {
29512 self.write_space();
29513 self.write_keyword("RETURNING");
29514 self.write_space();
29515 self.generate_expression(return_type)?;
29516 }
29517 self.write(")");
29518 Ok(())
29519 }
29520
29521 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
29522 self.write_keyword("JSON_ARRAY_APPEND");
29524 self.write("(");
29525 self.generate_expression(&e.this)?;
29526 for expr in &e.expressions {
29527 self.write(", ");
29528 self.generate_expression(expr)?;
29529 }
29530 self.write(")");
29531 Ok(())
29532 }
29533
29534 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
29535 self.write_keyword("JSON_ARRAY_CONTAINS");
29537 self.write("(");
29538 self.generate_expression(&e.this)?;
29539 self.write(", ");
29540 self.generate_expression(&e.expression)?;
29541 self.write(")");
29542 Ok(())
29543 }
29544
29545 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
29546 self.write_keyword("JSON_ARRAY_INSERT");
29548 self.write("(");
29549 self.generate_expression(&e.this)?;
29550 for expr in &e.expressions {
29551 self.write(", ");
29552 self.generate_expression(expr)?;
29553 }
29554 self.write(")");
29555 Ok(())
29556 }
29557
29558 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
29559 self.write_keyword("JSONB_EXISTS");
29561 self.write("(");
29562 self.generate_expression(&e.this)?;
29563 if let Some(path) = &e.path {
29564 self.write(", ");
29565 self.generate_expression(path)?;
29566 }
29567 self.write(")");
29568 Ok(())
29569 }
29570
29571 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
29572 self.write_keyword("JSONB_EXTRACT_SCALAR");
29574 self.write("(");
29575 self.generate_expression(&e.this)?;
29576 self.write(", ");
29577 self.generate_expression(&e.expression)?;
29578 self.write(")");
29579 Ok(())
29580 }
29581
29582 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
29583 self.write_keyword("JSONB_OBJECT_AGG");
29585 self.write("(");
29586 self.generate_expression(&e.this)?;
29587 self.write(", ");
29588 self.generate_expression(&e.expression)?;
29589 self.write(")");
29590 Ok(())
29591 }
29592
29593 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
29594 if let Some(nested_schema) = &e.nested_schema {
29596 self.write_keyword("NESTED");
29597 if let Some(path) = &e.path {
29598 self.write_space();
29599 self.write_keyword("PATH");
29600 self.write_space();
29601 self.generate_expression(path)?;
29602 }
29603 self.write_space();
29604 self.generate_expression(nested_schema)?;
29605 } else {
29606 if let Some(this) = &e.this {
29607 self.generate_expression(this)?;
29608 }
29609 if let Some(kind) = &e.kind {
29610 self.write_space();
29611 self.write(kind);
29612 }
29613 if let Some(path) = &e.path {
29614 self.write_space();
29615 self.write_keyword("PATH");
29616 self.write_space();
29617 self.generate_expression(path)?;
29618 }
29619 if e.ordinality.is_some() {
29620 self.write_keyword(" FOR ORDINALITY");
29621 }
29622 }
29623 Ok(())
29624 }
29625
29626 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
29627 self.write_keyword("JSON_EXISTS");
29629 self.write("(");
29630 self.generate_expression(&e.this)?;
29631 if let Some(path) = &e.path {
29632 self.write(", ");
29633 self.generate_expression(path)?;
29634 }
29635 if let Some(passing) = &e.passing {
29636 self.write_space();
29637 self.write_keyword("PASSING");
29638 self.write_space();
29639 self.generate_expression(passing)?;
29640 }
29641 if let Some(on_condition) = &e.on_condition {
29642 self.write_space();
29643 self.generate_expression(on_condition)?;
29644 }
29645 self.write(")");
29646 Ok(())
29647 }
29648
29649 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
29650 self.generate_expression(&e.this)?;
29651 self.write(".:");
29652 if Self::data_type_has_nested_expressions(&e.to) {
29656 let saved = std::mem::take(&mut self.output);
29658 self.generate_data_type(&e.to)?;
29659 let type_sql = std::mem::replace(&mut self.output, saved);
29660 self.write("\"");
29661 self.write(&type_sql);
29662 self.write("\"");
29663 } else {
29664 self.generate_data_type(&e.to)?;
29665 }
29666 Ok(())
29667 }
29668
29669 fn data_type_has_nested_expressions(dt: &DataType) -> bool {
29672 matches!(
29673 dt,
29674 DataType::Array { .. } | DataType::Map { .. } | DataType::Struct { .. }
29675 )
29676 }
29677
29678 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
29679 self.write_keyword("JSON_EXTRACT_ARRAY");
29681 self.write("(");
29682 self.generate_expression(&e.this)?;
29683 if let Some(expr) = &e.expression {
29684 self.write(", ");
29685 self.generate_expression(expr)?;
29686 }
29687 self.write(")");
29688 Ok(())
29689 }
29690
29691 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
29692 if let Some(option) = &e.option {
29694 self.generate_expression(option)?;
29695 self.write_space();
29696 }
29697 self.write_keyword("QUOTES");
29698 if e.scalar.is_some() {
29699 self.write_keyword(" SCALAR_ONLY");
29700 }
29701 Ok(())
29702 }
29703
29704 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
29705 self.write_keyword("JSON_EXTRACT_SCALAR");
29707 self.write("(");
29708 self.generate_expression(&e.this)?;
29709 self.write(", ");
29710 self.generate_expression(&e.expression)?;
29711 self.write(")");
29712 Ok(())
29713 }
29714
29715 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
29716 if e.variant_extract.is_some() {
29720 use crate::dialects::DialectType;
29721 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
29722 self.generate_expression(&e.this)?;
29726 self.write(":");
29727 match e.expression.as_ref() {
29728 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
29729 let Literal::String(s) = lit.as_ref() else {
29730 unreachable!()
29731 };
29732 self.write_databricks_json_path(s);
29733 }
29734 _ => {
29735 self.generate_expression(&e.expression)?;
29737 }
29738 }
29739 } else {
29740 self.write_keyword("GET_PATH");
29742 self.write("(");
29743 self.generate_expression(&e.this)?;
29744 self.write(", ");
29745 self.generate_expression(&e.expression)?;
29746 self.write(")");
29747 }
29748 } else {
29749 self.write_keyword("JSON_EXTRACT");
29750 self.write("(");
29751 self.generate_expression(&e.this)?;
29752 self.write(", ");
29753 self.generate_expression(&e.expression)?;
29754 for expr in &e.expressions {
29755 self.write(", ");
29756 self.generate_expression(expr)?;
29757 }
29758 self.write(")");
29759 }
29760 Ok(())
29761 }
29762
29763 fn write_databricks_json_path(&mut self, path: &str) {
29767 if path.starts_with("[\"") || path.starts_with("['") {
29770 self.write(path);
29771 return;
29772 }
29773 let mut first = true;
29777 for segment in path.split('.') {
29778 if !first {
29779 self.write(".");
29780 }
29781 first = false;
29782 if let Some(bracket_pos) = segment.find('[') {
29784 let key = &segment[..bracket_pos];
29785 let subscript = &segment[bracket_pos..];
29786 if key.is_empty() {
29787 self.write(segment);
29789 } else if Self::is_safe_json_path_key(key) {
29790 self.write(key);
29791 self.write(subscript);
29792 } else {
29793 self.write("[\"");
29794 self.write(key);
29795 self.write("\"]");
29796 self.write(subscript);
29797 }
29798 } else if Self::is_safe_json_path_key(segment) {
29799 self.write(segment);
29800 } else {
29801 self.write("[\"");
29802 self.write(segment);
29803 self.write("\"]");
29804 }
29805 }
29806 }
29807
29808 fn is_safe_json_path_key(key: &str) -> bool {
29811 if key.is_empty() {
29812 return false;
29813 }
29814 let mut chars = key.chars();
29815 let first = chars.next().unwrap();
29816 if first != '_' && !first.is_ascii_alphabetic() {
29817 return false;
29818 }
29819 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
29820 }
29821
29822 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
29823 if let Some(this) = &e.this {
29826 self.generate_expression(this)?;
29827 self.write_space();
29828 }
29829 self.write_keyword("FORMAT JSON");
29830 Ok(())
29831 }
29832
29833 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
29834 self.generate_expression(&e.this)?;
29836 self.write(": ");
29837 self.generate_expression(&e.expression)?;
29838 Ok(())
29839 }
29840
29841 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
29842 self.write_keyword("JSON_KEYS");
29844 self.write("(");
29845 self.generate_expression(&e.this)?;
29846 if let Some(expr) = &e.expression {
29847 self.write(", ");
29848 self.generate_expression(expr)?;
29849 }
29850 for expr in &e.expressions {
29851 self.write(", ");
29852 self.generate_expression(expr)?;
29853 }
29854 self.write(")");
29855 Ok(())
29856 }
29857
29858 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
29859 self.write_keyword("JSON_KEYS");
29861 self.write("(");
29862 self.generate_expression(&e.this)?;
29863 if let Some(expr) = &e.expression {
29864 self.write(", ");
29865 self.generate_expression(expr)?;
29866 }
29867 self.write(")");
29868 Ok(())
29869 }
29870
29871 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
29872 let mut path_str = String::new();
29875 for expr in &e.expressions {
29876 match expr {
29877 Expression::JSONPathRoot(_) => {
29878 path_str.push('$');
29879 }
29880 Expression::JSONPathKey(k) => {
29881 if let Expression::Literal(lit) = k.this.as_ref() {
29883 if let crate::expressions::Literal::String(s) = lit.as_ref() {
29884 path_str.push('.');
29885 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
29887 if needs_quoting {
29888 path_str.push('"');
29889 path_str.push_str(s);
29890 path_str.push('"');
29891 } else {
29892 path_str.push_str(s);
29893 }
29894 }
29895 }
29896 }
29897 Expression::JSONPathSubscript(s) => {
29898 if let Expression::Literal(lit) = s.this.as_ref() {
29900 if let crate::expressions::Literal::Number(n) = lit.as_ref() {
29901 path_str.push('[');
29902 path_str.push_str(n);
29903 path_str.push(']');
29904 }
29905 }
29906 }
29907 _ => {
29908 let mut temp_gen = Self::with_arc_config(self.config.clone());
29910 temp_gen.generate_expression(expr)?;
29911 path_str.push_str(&temp_gen.output);
29912 }
29913 }
29914 }
29915 self.write("'");
29917 self.write(&path_str);
29918 self.write("'");
29919 Ok(())
29920 }
29921
29922 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
29923 self.write("?(");
29925 self.generate_expression(&e.this)?;
29926 self.write(")");
29927 Ok(())
29928 }
29929
29930 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
29931 self.write(".");
29933 self.generate_expression(&e.this)?;
29934 Ok(())
29935 }
29936
29937 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
29938 self.write("..");
29940 if let Some(this) = &e.this {
29941 self.generate_expression(this)?;
29942 }
29943 Ok(())
29944 }
29945
29946 fn generate_json_path_root(&mut self) -> Result<()> {
29947 self.write("$");
29949 Ok(())
29950 }
29951
29952 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
29953 self.write("(");
29955 self.generate_expression(&e.this)?;
29956 self.write(")");
29957 Ok(())
29958 }
29959
29960 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
29961 self.generate_expression(&e.this)?;
29963 Ok(())
29964 }
29965
29966 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
29967 self.write("[");
29969 if let Some(start) = &e.start {
29970 self.generate_expression(start)?;
29971 }
29972 self.write(":");
29973 if let Some(end) = &e.end {
29974 self.generate_expression(end)?;
29975 }
29976 if let Some(step) = &e.step {
29977 self.write(":");
29978 self.generate_expression(step)?;
29979 }
29980 self.write("]");
29981 Ok(())
29982 }
29983
29984 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
29985 self.write("[");
29987 self.generate_expression(&e.this)?;
29988 self.write("]");
29989 Ok(())
29990 }
29991
29992 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
29993 self.write("[");
29995 for (i, expr) in e.expressions.iter().enumerate() {
29996 if i > 0 {
29997 self.write(", ");
29998 }
29999 self.generate_expression(expr)?;
30000 }
30001 self.write("]");
30002 Ok(())
30003 }
30004
30005 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
30006 self.write_keyword("JSON_REMOVE");
30008 self.write("(");
30009 self.generate_expression(&e.this)?;
30010 for expr in &e.expressions {
30011 self.write(", ");
30012 self.generate_expression(expr)?;
30013 }
30014 self.write(")");
30015 Ok(())
30016 }
30017
30018 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
30019 self.write_keyword("COLUMNS");
30022 self.write("(");
30023
30024 if self.config.pretty && !e.expressions.is_empty() {
30025 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
30027 for expr in &e.expressions {
30028 let mut temp_gen = Generator::with_arc_config(self.config.clone());
30029 temp_gen.generate_expression(expr)?;
30030 expr_strings.push(temp_gen.output);
30031 }
30032
30033 if self.too_wide(&expr_strings) {
30035 self.write_newline();
30037 self.indent_level += 1;
30038 for (i, expr_str) in expr_strings.iter().enumerate() {
30039 if i > 0 {
30040 self.write(",");
30041 self.write_newline();
30042 }
30043 self.write_indent();
30044 self.write(expr_str);
30045 }
30046 self.write_newline();
30047 self.indent_level -= 1;
30048 self.write_indent();
30049 } else {
30050 for (i, expr_str) in expr_strings.iter().enumerate() {
30052 if i > 0 {
30053 self.write(", ");
30054 }
30055 self.write(expr_str);
30056 }
30057 }
30058 } else {
30059 for (i, expr) in e.expressions.iter().enumerate() {
30061 if i > 0 {
30062 self.write(", ");
30063 }
30064 self.generate_expression(expr)?;
30065 }
30066 }
30067 self.write(")");
30068 Ok(())
30069 }
30070
30071 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
30072 self.write_keyword("JSON_SET");
30074 self.write("(");
30075 self.generate_expression(&e.this)?;
30076 for expr in &e.expressions {
30077 self.write(", ");
30078 self.generate_expression(expr)?;
30079 }
30080 self.write(")");
30081 Ok(())
30082 }
30083
30084 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
30085 self.write_keyword("JSON_STRIP_NULLS");
30087 self.write("(");
30088 self.generate_expression(&e.this)?;
30089 if let Some(expr) = &e.expression {
30090 self.write(", ");
30091 self.generate_expression(expr)?;
30092 }
30093 self.write(")");
30094 Ok(())
30095 }
30096
30097 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
30098 self.write_keyword("JSON_TABLE");
30100 self.write("(");
30101 self.generate_expression(&e.this)?;
30102 if let Some(path) = &e.path {
30103 self.write(", ");
30104 self.generate_expression(path)?;
30105 }
30106 if let Some(error_handling) = &e.error_handling {
30107 self.write_space();
30108 self.generate_expression(error_handling)?;
30109 }
30110 if let Some(empty_handling) = &e.empty_handling {
30111 self.write_space();
30112 self.generate_expression(empty_handling)?;
30113 }
30114 if let Some(schema) = &e.schema {
30115 self.write_space();
30116 self.generate_expression(schema)?;
30117 }
30118 self.write(")");
30119 Ok(())
30120 }
30121
30122 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
30123 self.write_keyword("JSON_TYPE");
30125 self.write("(");
30126 self.generate_expression(&e.this)?;
30127 self.write(")");
30128 Ok(())
30129 }
30130
30131 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
30132 self.write_keyword("JSON_VALUE");
30134 self.write("(");
30135 self.generate_expression(&e.this)?;
30136 if let Some(path) = &e.path {
30137 self.write(", ");
30138 self.generate_expression(path)?;
30139 }
30140 if let Some(returning) = &e.returning {
30141 self.write_space();
30142 self.write_keyword("RETURNING");
30143 self.write_space();
30144 self.generate_expression(returning)?;
30145 }
30146 if let Some(on_condition) = &e.on_condition {
30147 self.write_space();
30148 self.generate_expression(on_condition)?;
30149 }
30150 self.write(")");
30151 Ok(())
30152 }
30153
30154 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
30155 self.write_keyword("JSON_VALUE_ARRAY");
30157 self.write("(");
30158 self.generate_expression(&e.this)?;
30159 self.write(")");
30160 Ok(())
30161 }
30162
30163 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
30164 self.write_keyword("JAROWINKLER_SIMILARITY");
30166 self.write("(");
30167 self.generate_expression(&e.this)?;
30168 self.write(", ");
30169 self.generate_expression(&e.expression)?;
30170 self.write(")");
30171 Ok(())
30172 }
30173
30174 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
30175 self.generate_expression(&e.this)?;
30177 self.write("(");
30178 for (i, expr) in e.expressions.iter().enumerate() {
30179 if i > 0 {
30180 self.write(", ");
30181 }
30182 self.generate_expression(expr)?;
30183 }
30184 self.write(")");
30185 Ok(())
30186 }
30187
30188 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
30189 if e.no.is_some() {
30191 self.write_keyword("NO ");
30192 }
30193 if let Some(local) = &e.local {
30194 self.generate_expression(local)?;
30195 self.write_space();
30196 }
30197 if e.dual.is_some() {
30198 self.write_keyword("DUAL ");
30199 }
30200 if e.before.is_some() {
30201 self.write_keyword("BEFORE ");
30202 }
30203 if e.after.is_some() {
30204 self.write_keyword("AFTER ");
30205 }
30206 self.write_keyword("JOURNAL");
30207 Ok(())
30208 }
30209
30210 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
30211 self.write_keyword("LANGUAGE");
30213 self.write_space();
30214 self.generate_expression(&e.this)?;
30215 Ok(())
30216 }
30217
30218 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
30219 if e.view.is_some() {
30221 self.write_keyword("LATERAL VIEW");
30223 if e.outer.is_some() {
30224 self.write_space();
30225 self.write_keyword("OUTER");
30226 }
30227 self.write_space();
30228 self.generate_expression(&e.this)?;
30229 if let Some(alias) = &e.alias {
30230 self.write_space();
30231 self.write(alias);
30232 }
30233 } else {
30234 self.write_keyword("LATERAL");
30236 self.write_space();
30237 self.generate_expression(&e.this)?;
30238 if e.ordinality.is_some() {
30239 self.write_space();
30240 self.write_keyword("WITH ORDINALITY");
30241 }
30242 if let Some(alias) = &e.alias {
30243 self.write_space();
30244 self.write_keyword("AS");
30245 self.write_space();
30246 self.write(alias);
30247 if !e.column_aliases.is_empty() {
30248 self.write("(");
30249 for (i, col) in e.column_aliases.iter().enumerate() {
30250 if i > 0 {
30251 self.write(", ");
30252 }
30253 self.write(col);
30254 }
30255 self.write(")");
30256 }
30257 }
30258 }
30259 Ok(())
30260 }
30261
30262 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
30263 self.write_keyword("LIKE");
30265 self.write_space();
30266 self.generate_expression(&e.this)?;
30267 for expr in &e.expressions {
30268 self.write_space();
30269 self.generate_expression(expr)?;
30270 }
30271 Ok(())
30272 }
30273
30274 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
30275 self.write_keyword("LIMIT");
30276 self.write_space();
30277 self.write_limit_expr(&e.this)?;
30278 if e.percent {
30279 self.write_space();
30280 self.write_keyword("PERCENT");
30281 }
30282 for comment in &e.comments {
30284 self.write(" ");
30285 self.write_formatted_comment(comment);
30286 }
30287 Ok(())
30288 }
30289
30290 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
30291 if e.percent.is_some() {
30293 self.write_keyword(" PERCENT");
30294 }
30295 if e.rows.is_some() {
30296 self.write_keyword(" ROWS");
30297 }
30298 if e.with_ties.is_some() {
30299 self.write_keyword(" WITH TIES");
30300 } else if e.rows.is_some() {
30301 self.write_keyword(" ONLY");
30302 }
30303 Ok(())
30304 }
30305
30306 fn generate_list(&mut self, e: &List) -> Result<()> {
30307 use crate::dialects::DialectType;
30308 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
30309
30310 if e.expressions.len() == 1 {
30312 if let Expression::Select(_) = &e.expressions[0] {
30313 self.write_keyword("LIST");
30314 self.write("(");
30315 self.generate_expression(&e.expressions[0])?;
30316 self.write(")");
30317 return Ok(());
30318 }
30319 }
30320
30321 if is_materialize {
30323 self.write_keyword("LIST");
30324 self.write("[");
30325 for (i, expr) in e.expressions.iter().enumerate() {
30326 if i > 0 {
30327 self.write(", ");
30328 }
30329 self.generate_expression(expr)?;
30330 }
30331 self.write("]");
30332 } else {
30333 self.write_keyword("LIST");
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 }
30344 Ok(())
30345 }
30346
30347 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
30348 if let Expression::Select(_) = &*e.this {
30350 self.write_keyword("MAP");
30351 self.write("(");
30352 self.generate_expression(&e.this)?;
30353 self.write(")");
30354 return Ok(());
30355 }
30356
30357 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
30358
30359 self.write_keyword("MAP");
30361 if is_duckdb {
30362 self.write(" {");
30363 } else {
30364 self.write("[");
30365 }
30366 if let Expression::Struct(s) = &*e.this {
30367 for (i, (_, expr)) in s.fields.iter().enumerate() {
30368 if i > 0 {
30369 self.write(", ");
30370 }
30371 if let Expression::PropertyEQ(op) = expr {
30372 self.generate_expression(&op.left)?;
30373 if is_duckdb {
30374 self.write(": ");
30375 } else {
30376 self.write(" => ");
30377 }
30378 self.generate_expression(&op.right)?;
30379 } else {
30380 self.generate_expression(expr)?;
30381 }
30382 }
30383 }
30384 if is_duckdb {
30385 self.write("}");
30386 } else {
30387 self.write("]");
30388 }
30389 Ok(())
30390 }
30391
30392 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
30393 self.write_keyword("LOCALTIME");
30395 if let Some(precision) = &e.this {
30396 self.write("(");
30397 self.generate_expression(precision)?;
30398 self.write(")");
30399 }
30400 Ok(())
30401 }
30402
30403 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
30404 self.write_keyword("LOCALTIMESTAMP");
30406 if let Some(precision) = &e.this {
30407 self.write("(");
30408 self.generate_expression(precision)?;
30409 self.write(")");
30410 }
30411 Ok(())
30412 }
30413
30414 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
30415 self.write_keyword("LOCATION");
30417 self.write_space();
30418 self.generate_expression(&e.this)?;
30419 Ok(())
30420 }
30421
30422 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
30423 if e.update.is_some() {
30425 if e.key.is_some() {
30426 self.write_keyword("FOR NO KEY UPDATE");
30427 } else {
30428 self.write_keyword("FOR UPDATE");
30429 }
30430 } else {
30431 if e.key.is_some() {
30432 self.write_keyword("FOR KEY SHARE");
30433 } else {
30434 self.write_keyword("FOR SHARE");
30435 }
30436 }
30437 if !e.expressions.is_empty() {
30438 self.write_keyword(" OF ");
30439 for (i, expr) in e.expressions.iter().enumerate() {
30440 if i > 0 {
30441 self.write(", ");
30442 }
30443 self.generate_expression(expr)?;
30444 }
30445 }
30446 if let Some(wait) = &e.wait {
30451 match wait.as_ref() {
30452 Expression::Boolean(b) => {
30453 if b.value {
30454 self.write_keyword(" NOWAIT");
30455 } else {
30456 self.write_keyword(" SKIP LOCKED");
30457 }
30458 }
30459 _ => {
30460 self.write_keyword(" WAIT ");
30462 self.generate_expression(wait)?;
30463 }
30464 }
30465 }
30466 Ok(())
30467 }
30468
30469 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
30470 self.write_keyword("LOCK");
30472 self.write_space();
30473 self.generate_expression(&e.this)?;
30474 Ok(())
30475 }
30476
30477 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
30478 self.write_keyword("LOCKING");
30480 self.write_space();
30481 self.write(&e.kind);
30482 if let Some(this) = &e.this {
30483 self.write_space();
30484 self.generate_expression(this)?;
30485 }
30486 if let Some(for_or_in) = &e.for_or_in {
30487 self.write_space();
30488 self.generate_expression(for_or_in)?;
30489 }
30490 if let Some(lock_type) = &e.lock_type {
30491 self.write_space();
30492 self.generate_expression(lock_type)?;
30493 }
30494 if e.override_.is_some() {
30495 self.write_keyword(" OVERRIDE");
30496 }
30497 Ok(())
30498 }
30499
30500 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
30501 self.generate_expression(&e.this)?;
30503 self.write_space();
30504 self.generate_expression(&e.expression)?;
30505 Ok(())
30506 }
30507
30508 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
30509 if e.no.is_some() {
30511 self.write_keyword("NO ");
30512 }
30513 self.write_keyword("LOG");
30514 Ok(())
30515 }
30516
30517 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
30518 self.write_keyword("MD5");
30520 self.write("(");
30521 self.generate_expression(&e.this)?;
30522 for expr in &e.expressions {
30523 self.write(", ");
30524 self.generate_expression(expr)?;
30525 }
30526 self.write(")");
30527 Ok(())
30528 }
30529
30530 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
30531 self.write_keyword("ML.FORECAST");
30533 self.write("(");
30534 self.generate_expression(&e.this)?;
30535 if let Some(expression) = &e.expression {
30536 self.write(", ");
30537 self.generate_expression(expression)?;
30538 }
30539 if let Some(params) = &e.params_struct {
30540 self.write(", ");
30541 self.generate_expression(params)?;
30542 }
30543 self.write(")");
30544 Ok(())
30545 }
30546
30547 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
30548 self.write_keyword("ML.TRANSLATE");
30550 self.write("(");
30551 self.generate_expression(&e.this)?;
30552 self.write(", ");
30553 self.generate_expression(&e.expression)?;
30554 if let Some(params) = &e.params_struct {
30555 self.write(", ");
30556 self.generate_expression(params)?;
30557 }
30558 self.write(")");
30559 Ok(())
30560 }
30561
30562 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
30563 self.write_keyword("MAKE_INTERVAL");
30565 self.write("(");
30566 let mut first = true;
30567 if let Some(year) = &e.year {
30568 self.write("years => ");
30569 self.generate_expression(year)?;
30570 first = false;
30571 }
30572 if let Some(month) = &e.month {
30573 if !first {
30574 self.write(", ");
30575 }
30576 self.write("months => ");
30577 self.generate_expression(month)?;
30578 first = false;
30579 }
30580 if let Some(week) = &e.week {
30581 if !first {
30582 self.write(", ");
30583 }
30584 self.write("weeks => ");
30585 self.generate_expression(week)?;
30586 first = false;
30587 }
30588 if let Some(day) = &e.day {
30589 if !first {
30590 self.write(", ");
30591 }
30592 self.write("days => ");
30593 self.generate_expression(day)?;
30594 first = false;
30595 }
30596 if let Some(hour) = &e.hour {
30597 if !first {
30598 self.write(", ");
30599 }
30600 self.write("hours => ");
30601 self.generate_expression(hour)?;
30602 first = false;
30603 }
30604 if let Some(minute) = &e.minute {
30605 if !first {
30606 self.write(", ");
30607 }
30608 self.write("mins => ");
30609 self.generate_expression(minute)?;
30610 first = false;
30611 }
30612 if let Some(second) = &e.second {
30613 if !first {
30614 self.write(", ");
30615 }
30616 self.write("secs => ");
30617 self.generate_expression(second)?;
30618 }
30619 self.write(")");
30620 Ok(())
30621 }
30622
30623 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
30624 self.write_keyword("MANHATTAN_DISTANCE");
30626 self.write("(");
30627 self.generate_expression(&e.this)?;
30628 self.write(", ");
30629 self.generate_expression(&e.expression)?;
30630 self.write(")");
30631 Ok(())
30632 }
30633
30634 fn generate_map(&mut self, e: &Map) -> Result<()> {
30635 self.write_keyword("MAP");
30637 self.write("(");
30638 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
30639 if i > 0 {
30640 self.write(", ");
30641 }
30642 self.generate_expression(key)?;
30643 self.write(", ");
30644 self.generate_expression(value)?;
30645 }
30646 self.write(")");
30647 Ok(())
30648 }
30649
30650 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
30651 self.write_keyword("MAP_CAT");
30653 self.write("(");
30654 self.generate_expression(&e.this)?;
30655 self.write(", ");
30656 self.generate_expression(&e.expression)?;
30657 self.write(")");
30658 Ok(())
30659 }
30660
30661 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
30662 self.write_keyword("MAP_DELETE");
30664 self.write("(");
30665 self.generate_expression(&e.this)?;
30666 for expr in &e.expressions {
30667 self.write(", ");
30668 self.generate_expression(expr)?;
30669 }
30670 self.write(")");
30671 Ok(())
30672 }
30673
30674 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
30675 self.write_keyword("MAP_INSERT");
30677 self.write("(");
30678 self.generate_expression(&e.this)?;
30679 if let Some(key) = &e.key {
30680 self.write(", ");
30681 self.generate_expression(key)?;
30682 }
30683 if let Some(value) = &e.value {
30684 self.write(", ");
30685 self.generate_expression(value)?;
30686 }
30687 if let Some(update_flag) = &e.update_flag {
30688 self.write(", ");
30689 self.generate_expression(update_flag)?;
30690 }
30691 self.write(")");
30692 Ok(())
30693 }
30694
30695 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
30696 self.write_keyword("MAP_PICK");
30698 self.write("(");
30699 self.generate_expression(&e.this)?;
30700 for expr in &e.expressions {
30701 self.write(", ");
30702 self.generate_expression(expr)?;
30703 }
30704 self.write(")");
30705 Ok(())
30706 }
30707
30708 fn generate_masking_policy_column_constraint(
30709 &mut self,
30710 e: &MaskingPolicyColumnConstraint,
30711 ) -> Result<()> {
30712 self.write_keyword("MASKING POLICY");
30714 self.write_space();
30715 self.generate_expression(&e.this)?;
30716 if !e.expressions.is_empty() {
30717 self.write_keyword(" USING");
30718 self.write(" (");
30719 for (i, expr) in e.expressions.iter().enumerate() {
30720 if i > 0 {
30721 self.write(", ");
30722 }
30723 self.generate_expression(expr)?;
30724 }
30725 self.write(")");
30726 }
30727 Ok(())
30728 }
30729
30730 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
30731 if matches!(
30732 self.config.dialect,
30733 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
30734 ) {
30735 if e.expressions.len() > 1 {
30736 self.write("(");
30737 }
30738 for (i, expr) in e.expressions.iter().enumerate() {
30739 if i > 0 {
30740 self.write_keyword(" OR ");
30741 }
30742 self.generate_expression(expr)?;
30743 self.write_space();
30744 self.write("@@");
30745 self.write_space();
30746 self.generate_expression(&e.this)?;
30747 }
30748 if e.expressions.len() > 1 {
30749 self.write(")");
30750 }
30751 return Ok(());
30752 }
30753
30754 self.write_keyword("MATCH");
30756 self.write("(");
30757 for (i, expr) in e.expressions.iter().enumerate() {
30758 if i > 0 {
30759 self.write(", ");
30760 }
30761 self.generate_expression(expr)?;
30762 }
30763 self.write(")");
30764 self.write_keyword(" AGAINST");
30765 self.write("(");
30766 self.generate_expression(&e.this)?;
30767 if let Some(modifier) = &e.modifier {
30768 self.write_space();
30769 self.generate_expression(modifier)?;
30770 }
30771 self.write(")");
30772 Ok(())
30773 }
30774
30775 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
30776 if let Some(window_frame) = &e.window_frame {
30778 self.write(&format!("{:?}", window_frame).to_ascii_uppercase());
30779 self.write_space();
30780 }
30781 self.generate_expression(&e.this)?;
30782 Ok(())
30783 }
30784
30785 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
30786 self.write_keyword("MATERIALIZED");
30788 if let Some(this) = &e.this {
30789 self.write_space();
30790 self.generate_expression(this)?;
30791 }
30792 Ok(())
30793 }
30794
30795 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
30796 if let Some(with_) = &e.with_ {
30799 self.generate_expression(with_)?;
30800 self.write_space();
30801 }
30802 self.write_keyword("MERGE INTO");
30803 self.write_space();
30804 self.generate_expression(&e.this)?;
30805
30806 if self.config.pretty {
30808 self.write_newline();
30809 self.write_indent();
30810 } else {
30811 self.write_space();
30812 }
30813 self.write_keyword("USING");
30814 self.write_space();
30815 self.generate_expression(&e.using)?;
30816
30817 if let Some(on) = &e.on {
30819 if self.config.pretty {
30820 self.write_newline();
30821 self.write_indent();
30822 } else {
30823 self.write_space();
30824 }
30825 self.write_keyword("ON");
30826 self.write_space();
30827 self.generate_expression(on)?;
30828 }
30829 if let Some(using_cond) = &e.using_cond {
30831 self.write_space();
30832 self.write_keyword("USING");
30833 self.write_space();
30834 self.write("(");
30835 if let Expression::Tuple(tuple) = using_cond.as_ref() {
30837 for (i, col) in tuple.expressions.iter().enumerate() {
30838 if i > 0 {
30839 self.write(", ");
30840 }
30841 self.generate_expression(col)?;
30842 }
30843 } else {
30844 self.generate_expression(using_cond)?;
30845 }
30846 self.write(")");
30847 }
30848 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
30850 if matches!(
30851 self.config.dialect,
30852 Some(crate::DialectType::PostgreSQL)
30853 | Some(crate::DialectType::Redshift)
30854 | Some(crate::DialectType::Trino)
30855 | Some(crate::DialectType::Presto)
30856 | Some(crate::DialectType::Athena)
30857 ) {
30858 let mut names = Vec::new();
30859 match e.this.as_ref() {
30860 Expression::Alias(a) => {
30861 if let Expression::Table(t) = &a.this {
30863 names.push(t.name.name.clone());
30864 } else if let Expression::Identifier(id) = &a.this {
30865 names.push(id.name.clone());
30866 }
30867 names.push(a.alias.name.clone());
30868 }
30869 Expression::Table(t) => {
30870 names.push(t.name.name.clone());
30871 }
30872 Expression::Identifier(id) => {
30873 names.push(id.name.clone());
30874 }
30875 _ => {}
30876 }
30877 self.merge_strip_qualifiers = names;
30878 }
30879
30880 if let Some(whens) = &e.whens {
30882 if self.config.pretty {
30883 self.write_newline();
30884 self.write_indent();
30885 } else {
30886 self.write_space();
30887 }
30888 self.generate_expression(whens)?;
30889 }
30890
30891 self.merge_strip_qualifiers = saved_merge_strip;
30893
30894 if let Some(returning) = &e.returning {
30896 if self.config.pretty {
30897 self.write_newline();
30898 self.write_indent();
30899 } else {
30900 self.write_space();
30901 }
30902 self.generate_expression(returning)?;
30903 }
30904 Ok(())
30905 }
30906
30907 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
30908 if e.no.is_some() {
30910 self.write_keyword("NO MERGEBLOCKRATIO");
30911 } else if e.default.is_some() {
30912 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
30913 } else {
30914 self.write_keyword("MERGEBLOCKRATIO");
30915 self.write("=");
30916 if let Some(this) = &e.this {
30917 self.generate_expression(this)?;
30918 }
30919 if e.percent.is_some() {
30920 self.write_keyword(" PERCENT");
30921 }
30922 }
30923 Ok(())
30924 }
30925
30926 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
30927 self.write_keyword("TTL");
30929 let pretty_clickhouse = self.config.pretty
30930 && matches!(
30931 self.config.dialect,
30932 Some(crate::dialects::DialectType::ClickHouse)
30933 );
30934
30935 if pretty_clickhouse {
30936 self.write_newline();
30937 self.indent_level += 1;
30938 for (i, expr) in e.expressions.iter().enumerate() {
30939 if i > 0 {
30940 self.write(",");
30941 self.write_newline();
30942 }
30943 self.write_indent();
30944 self.generate_expression(expr)?;
30945 }
30946 self.indent_level -= 1;
30947 } else {
30948 self.write_space();
30949 for (i, expr) in e.expressions.iter().enumerate() {
30950 if i > 0 {
30951 self.write(", ");
30952 }
30953 self.generate_expression(expr)?;
30954 }
30955 }
30956
30957 if let Some(where_) = &e.where_ {
30958 if pretty_clickhouse {
30959 self.write_newline();
30960 if let Expression::Where(w) = where_.as_ref() {
30961 self.write_indent();
30962 self.write_keyword("WHERE");
30963 self.write_newline();
30964 self.indent_level += 1;
30965 self.write_indent();
30966 self.generate_expression(&w.this)?;
30967 self.indent_level -= 1;
30968 } else {
30969 self.write_indent();
30970 self.generate_expression(where_)?;
30971 }
30972 } else {
30973 self.write_space();
30974 self.generate_expression(where_)?;
30975 }
30976 }
30977 if let Some(group) = &e.group {
30978 if pretty_clickhouse {
30979 self.write_newline();
30980 if let Expression::Group(g) = group.as_ref() {
30981 self.write_indent();
30982 self.write_keyword("GROUP BY");
30983 self.write_newline();
30984 self.indent_level += 1;
30985 for (i, expr) in g.expressions.iter().enumerate() {
30986 if i > 0 {
30987 self.write(",");
30988 self.write_newline();
30989 }
30990 self.write_indent();
30991 self.generate_expression(expr)?;
30992 }
30993 self.indent_level -= 1;
30994 } else {
30995 self.write_indent();
30996 self.generate_expression(group)?;
30997 }
30998 } else {
30999 self.write_space();
31000 self.generate_expression(group)?;
31001 }
31002 }
31003 if let Some(aggregates) = &e.aggregates {
31004 if pretty_clickhouse {
31005 self.write_newline();
31006 self.write_indent();
31007 self.write_keyword("SET");
31008 self.write_newline();
31009 self.indent_level += 1;
31010 if let Expression::Tuple(t) = aggregates.as_ref() {
31011 for (i, agg) in t.expressions.iter().enumerate() {
31012 if i > 0 {
31013 self.write(",");
31014 self.write_newline();
31015 }
31016 self.write_indent();
31017 self.generate_expression(agg)?;
31018 }
31019 } else {
31020 self.write_indent();
31021 self.generate_expression(aggregates)?;
31022 }
31023 self.indent_level -= 1;
31024 } else {
31025 self.write_space();
31026 self.write_keyword("SET");
31027 self.write_space();
31028 self.generate_expression(aggregates)?;
31029 }
31030 }
31031 Ok(())
31032 }
31033
31034 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
31035 self.generate_expression(&e.this)?;
31037 if e.delete.is_some() {
31038 self.write_keyword(" DELETE");
31039 }
31040 if let Some(recompress) = &e.recompress {
31041 self.write_keyword(" RECOMPRESS ");
31042 self.generate_expression(recompress)?;
31043 }
31044 if let Some(to_disk) = &e.to_disk {
31045 self.write_keyword(" TO DISK ");
31046 self.generate_expression(to_disk)?;
31047 }
31048 if let Some(to_volume) = &e.to_volume {
31049 self.write_keyword(" TO VOLUME ");
31050 self.generate_expression(to_volume)?;
31051 }
31052 Ok(())
31053 }
31054
31055 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
31056 self.write_keyword("MINHASH");
31058 self.write("(");
31059 self.generate_expression(&e.this)?;
31060 for expr in &e.expressions {
31061 self.write(", ");
31062 self.generate_expression(expr)?;
31063 }
31064 self.write(")");
31065 Ok(())
31066 }
31067
31068 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
31069 self.generate_expression(&e.this)?;
31071 self.write("!");
31072 self.generate_expression(&e.expression)?;
31073 Ok(())
31074 }
31075
31076 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
31077 self.write_keyword("MONTHNAME");
31079 self.write("(");
31080 self.generate_expression(&e.this)?;
31081 self.write(")");
31082 Ok(())
31083 }
31084
31085 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
31086 for comment in &e.leading_comments {
31088 self.write_formatted_comment(comment);
31089 if self.config.pretty {
31090 self.write_newline();
31091 self.write_indent();
31092 } else {
31093 self.write_space();
31094 }
31095 }
31096 self.write_keyword("INSERT");
31098 self.write_space();
31099 self.write(&e.kind);
31100 if self.config.pretty {
31101 self.indent_level += 1;
31102 for expr in &e.expressions {
31103 self.write_newline();
31104 self.write_indent();
31105 self.generate_expression(expr)?;
31106 }
31107 self.indent_level -= 1;
31108 } else {
31109 for expr in &e.expressions {
31110 self.write_space();
31111 self.generate_expression(expr)?;
31112 }
31113 }
31114 if let Some(source) = &e.source {
31115 if self.config.pretty {
31116 self.write_newline();
31117 self.write_indent();
31118 } else {
31119 self.write_space();
31120 }
31121 self.generate_expression(source)?;
31122 }
31123 Ok(())
31124 }
31125
31126 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
31127 self.write_keyword("NEXT VALUE FOR");
31129 self.write_space();
31130 self.generate_expression(&e.this)?;
31131 if let Some(order) = &e.order {
31132 self.write_space();
31133 self.write_keyword("OVER");
31134 self.write(" (");
31135 self.generate_expression(order)?;
31136 self.write(")");
31137 }
31138 Ok(())
31139 }
31140
31141 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
31142 self.write_keyword("NORMAL");
31144 self.write("(");
31145 self.generate_expression(&e.this)?;
31146 if let Some(stddev) = &e.stddev {
31147 self.write(", ");
31148 self.generate_expression(stddev)?;
31149 }
31150 if let Some(gen) = &e.gen {
31151 self.write(", ");
31152 self.generate_expression(gen)?;
31153 }
31154 self.write(")");
31155 Ok(())
31156 }
31157
31158 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
31159 if e.is_casefold.is_some() {
31161 self.write_keyword("NORMALIZE_AND_CASEFOLD");
31162 } else {
31163 self.write_keyword("NORMALIZE");
31164 }
31165 self.write("(");
31166 self.generate_expression(&e.this)?;
31167 if let Some(form) = &e.form {
31168 self.write(", ");
31169 self.generate_expression(form)?;
31170 }
31171 self.write(")");
31172 Ok(())
31173 }
31174
31175 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
31176 if e.allow_null.is_none() {
31178 self.write_keyword("NOT ");
31179 }
31180 self.write_keyword("NULL");
31181 Ok(())
31182 }
31183
31184 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
31185 self.write_keyword("NULLIF");
31187 self.write("(");
31188 self.generate_expression(&e.this)?;
31189 self.write(", ");
31190 self.generate_expression(&e.expression)?;
31191 self.write(")");
31192 Ok(())
31193 }
31194
31195 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
31196 self.write_keyword("FORMAT");
31198 self.write("(");
31199 self.generate_expression(&e.this)?;
31200 self.write(", '");
31201 self.write(&e.format);
31202 self.write("'");
31203 if let Some(culture) = &e.culture {
31204 self.write(", ");
31205 self.generate_expression(culture)?;
31206 }
31207 self.write(")");
31208 Ok(())
31209 }
31210
31211 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
31212 self.write_keyword("OBJECT_AGG");
31214 self.write("(");
31215 self.generate_expression(&e.this)?;
31216 self.write(", ");
31217 self.generate_expression(&e.expression)?;
31218 self.write(")");
31219 Ok(())
31220 }
31221
31222 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
31223 self.generate_expression(&e.this)?;
31225 Ok(())
31226 }
31227
31228 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
31229 self.write_keyword("OBJECT_INSERT");
31231 self.write("(");
31232 self.generate_expression(&e.this)?;
31233 if let Some(key) = &e.key {
31234 self.write(", ");
31235 self.generate_expression(key)?;
31236 }
31237 if let Some(value) = &e.value {
31238 self.write(", ");
31239 self.generate_expression(value)?;
31240 }
31241 if let Some(update_flag) = &e.update_flag {
31242 self.write(", ");
31243 self.generate_expression(update_flag)?;
31244 }
31245 self.write(")");
31246 Ok(())
31247 }
31248
31249 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
31250 self.write_keyword("OFFSET");
31252 self.write_space();
31253 self.generate_expression(&e.this)?;
31254 if e.rows == Some(true)
31256 && matches!(
31257 self.config.dialect,
31258 Some(crate::dialects::DialectType::TSQL)
31259 | Some(crate::dialects::DialectType::Oracle)
31260 )
31261 {
31262 self.write_space();
31263 self.write_keyword("ROWS");
31264 }
31265 Ok(())
31266 }
31267
31268 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
31269 self.write_keyword("QUALIFY");
31271 self.write_space();
31272 self.generate_expression(&e.this)?;
31273 Ok(())
31274 }
31275
31276 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
31277 self.write_keyword("ON CLUSTER");
31279 self.write_space();
31280 self.generate_expression(&e.this)?;
31281 Ok(())
31282 }
31283
31284 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
31285 self.write_keyword("ON COMMIT");
31287 if e.delete.is_some() {
31288 self.write_keyword(" DELETE ROWS");
31289 } else {
31290 self.write_keyword(" PRESERVE ROWS");
31291 }
31292 Ok(())
31293 }
31294
31295 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
31296 if let Some(empty) = &e.empty {
31298 self.generate_expression(empty)?;
31299 self.write_keyword(" ON EMPTY");
31300 }
31301 if let Some(error) = &e.error {
31302 if e.empty.is_some() {
31303 self.write_space();
31304 }
31305 self.generate_expression(error)?;
31306 self.write_keyword(" ON ERROR");
31307 }
31308 if let Some(null) = &e.null {
31309 if e.empty.is_some() || e.error.is_some() {
31310 self.write_space();
31311 }
31312 self.generate_expression(null)?;
31313 self.write_keyword(" ON NULL");
31314 }
31315 Ok(())
31316 }
31317
31318 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
31319 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
31321 return Ok(());
31322 }
31323 if e.duplicate.is_some() {
31325 self.write_keyword("ON DUPLICATE KEY UPDATE");
31327 for (i, expr) in e.expressions.iter().enumerate() {
31328 if i > 0 {
31329 self.write(",");
31330 }
31331 self.write_space();
31332 self.generate_expression(expr)?;
31333 }
31334 return Ok(());
31335 } else {
31336 self.write_keyword("ON CONFLICT");
31337 }
31338 if let Some(constraint) = &e.constraint {
31339 self.write_keyword(" ON CONSTRAINT ");
31340 self.generate_expression(constraint)?;
31341 }
31342 if let Some(conflict_keys) = &e.conflict_keys {
31343 if let Expression::Tuple(t) = conflict_keys.as_ref() {
31345 self.write("(");
31346 for (i, expr) in t.expressions.iter().enumerate() {
31347 if i > 0 {
31348 self.write(", ");
31349 }
31350 self.generate_expression(expr)?;
31351 }
31352 self.write(")");
31353 } else {
31354 self.write("(");
31355 self.generate_expression(conflict_keys)?;
31356 self.write(")");
31357 }
31358 }
31359 if let Some(index_predicate) = &e.index_predicate {
31360 self.write_keyword(" WHERE ");
31361 self.generate_expression(index_predicate)?;
31362 }
31363 if let Some(action) = &e.action {
31364 if let Expression::Identifier(id) = action.as_ref() {
31366 if id.name.eq_ignore_ascii_case("NOTHING") {
31367 self.write_keyword(" DO NOTHING");
31368 } else {
31369 self.write_keyword(" DO ");
31370 self.generate_expression(action)?;
31371 }
31372 } else if let Expression::Tuple(t) = action.as_ref() {
31373 self.write_keyword(" DO UPDATE SET ");
31375 for (i, expr) in t.expressions.iter().enumerate() {
31376 if i > 0 {
31377 self.write(", ");
31378 }
31379 self.generate_expression(expr)?;
31380 }
31381 } else {
31382 self.write_keyword(" DO ");
31383 self.generate_expression(action)?;
31384 }
31385 }
31386 if let Some(where_) = &e.where_ {
31388 self.write_keyword(" WHERE ");
31389 self.generate_expression(where_)?;
31390 }
31391 Ok(())
31392 }
31393
31394 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
31395 self.write_keyword("ON");
31397 self.write_space();
31398 self.generate_expression(&e.this)?;
31399 Ok(())
31400 }
31401
31402 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
31403 self.generate_expression(&e.this)?;
31405 self.write_space();
31406 self.generate_expression(&e.expression)?;
31407 Ok(())
31408 }
31409
31410 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
31411 self.write_keyword("OPENJSON");
31413 self.write("(");
31414 self.generate_expression(&e.this)?;
31415 if let Some(path) = &e.path {
31416 self.write(", ");
31417 self.generate_expression(path)?;
31418 }
31419 self.write(")");
31420 if !e.expressions.is_empty() {
31421 self.write_keyword(" WITH");
31422 if self.config.pretty {
31423 self.write(" (\n");
31424 self.indent_level += 2;
31425 for (i, expr) in e.expressions.iter().enumerate() {
31426 if i > 0 {
31427 self.write(",\n");
31428 }
31429 self.write_indent();
31430 self.generate_expression(expr)?;
31431 }
31432 self.write("\n");
31433 self.indent_level -= 2;
31434 self.write(")");
31435 } else {
31436 self.write(" (");
31437 for (i, expr) in e.expressions.iter().enumerate() {
31438 if i > 0 {
31439 self.write(", ");
31440 }
31441 self.generate_expression(expr)?;
31442 }
31443 self.write(")");
31444 }
31445 }
31446 Ok(())
31447 }
31448
31449 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
31450 self.generate_expression(&e.this)?;
31452 self.write_space();
31453 if let Some(ref dt) = e.data_type {
31455 self.generate_data_type(dt)?;
31456 } else if !e.kind.is_empty() {
31457 self.write(&e.kind);
31458 }
31459 if let Some(path) = &e.path {
31460 self.write_space();
31461 self.generate_expression(path)?;
31462 }
31463 if e.as_json.is_some() {
31464 self.write_keyword(" AS JSON");
31465 }
31466 Ok(())
31467 }
31468
31469 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
31470 self.generate_expression(&e.this)?;
31472 self.write_space();
31473 if let Some(op) = &e.operator {
31474 self.write_keyword("OPERATOR");
31475 self.write("(");
31476 self.generate_expression(op)?;
31477 self.write(")");
31478 }
31479 for comment in &e.comments {
31481 self.write_space();
31482 self.write_formatted_comment(comment);
31483 }
31484 self.write_space();
31485 self.generate_expression(&e.expression)?;
31486 Ok(())
31487 }
31488
31489 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
31490 self.write_keyword("ORDER BY");
31492 let pretty_clickhouse_single_paren = self.config.pretty
31493 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
31494 && e.expressions.len() == 1
31495 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
31496 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
31497 && e.expressions.len() == 1
31498 && matches!(e.expressions[0].this, Expression::Tuple(_))
31499 && !e.expressions[0].desc
31500 && e.expressions[0].nulls_first.is_none();
31501
31502 if pretty_clickhouse_single_paren {
31503 self.write_space();
31504 if let Expression::Paren(p) = &e.expressions[0].this {
31505 self.write("(");
31506 self.write_newline();
31507 self.indent_level += 1;
31508 self.write_indent();
31509 self.generate_expression(&p.this)?;
31510 self.indent_level -= 1;
31511 self.write_newline();
31512 self.write(")");
31513 }
31514 return Ok(());
31515 }
31516
31517 if clickhouse_single_tuple {
31518 self.write_space();
31519 if let Expression::Tuple(t) = &e.expressions[0].this {
31520 self.write("(");
31521 for (i, expr) in t.expressions.iter().enumerate() {
31522 if i > 0 {
31523 self.write(", ");
31524 }
31525 self.generate_expression(expr)?;
31526 }
31527 self.write(")");
31528 }
31529 return Ok(());
31530 }
31531
31532 self.write_space();
31533 for (i, ordered) in e.expressions.iter().enumerate() {
31534 if i > 0 {
31535 self.write(", ");
31536 }
31537 self.generate_expression(&ordered.this)?;
31538 if ordered.desc {
31539 self.write_space();
31540 self.write_keyword("DESC");
31541 } else if ordered.explicit_asc {
31542 self.write_space();
31543 self.write_keyword("ASC");
31544 }
31545 if let Some(nulls_first) = ordered.nulls_first {
31546 let skip_nulls_last =
31548 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
31549 if !skip_nulls_last {
31550 self.write_space();
31551 self.write_keyword("NULLS");
31552 self.write_space();
31553 if nulls_first {
31554 self.write_keyword("FIRST");
31555 } else {
31556 self.write_keyword("LAST");
31557 }
31558 }
31559 }
31560 }
31561 Ok(())
31562 }
31563
31564 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
31565 self.write_keyword("OUTPUT");
31567 self.write("(");
31568 if self.config.pretty {
31569 self.indent_level += 1;
31570 self.write_newline();
31571 self.write_indent();
31572 self.generate_expression(&e.this)?;
31573 self.indent_level -= 1;
31574 self.write_newline();
31575 } else {
31576 self.generate_expression(&e.this)?;
31577 }
31578 self.write(")");
31579 Ok(())
31580 }
31581
31582 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
31583 self.write_keyword("TRUNCATE");
31585 if let Some(this) = &e.this {
31586 self.write_space();
31587 self.generate_expression(this)?;
31588 }
31589 if e.with_count.is_some() {
31590 self.write_keyword(" WITH COUNT");
31591 } else {
31592 self.write_keyword(" WITHOUT COUNT");
31593 }
31594 Ok(())
31595 }
31596
31597 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
31598 self.generate_expression(&e.this)?;
31600 self.write("(");
31601 for (i, expr) in e.expressions.iter().enumerate() {
31602 if i > 0 {
31603 self.write(", ");
31604 }
31605 self.generate_expression(expr)?;
31606 }
31607 self.write(")(");
31608 for (i, param) in e.params.iter().enumerate() {
31609 if i > 0 {
31610 self.write(", ");
31611 }
31612 self.generate_expression(param)?;
31613 }
31614 self.write(")");
31615 Ok(())
31616 }
31617
31618 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
31619 self.write_keyword("PARSE_DATETIME");
31621 self.write("(");
31622 if let Some(format) = &e.format {
31623 self.write("'");
31624 self.write(format);
31625 self.write("', ");
31626 }
31627 self.generate_expression(&e.this)?;
31628 if let Some(zone) = &e.zone {
31629 self.write(", ");
31630 self.generate_expression(zone)?;
31631 }
31632 self.write(")");
31633 Ok(())
31634 }
31635
31636 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
31637 self.write_keyword("PARSE_IP");
31639 self.write("(");
31640 self.generate_expression(&e.this)?;
31641 if let Some(type_) = &e.type_ {
31642 self.write(", ");
31643 self.generate_expression(type_)?;
31644 }
31645 if let Some(permissive) = &e.permissive {
31646 self.write(", ");
31647 self.generate_expression(permissive)?;
31648 }
31649 self.write(")");
31650 Ok(())
31651 }
31652
31653 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
31654 self.write_keyword("PARSE_JSON");
31656 self.write("(");
31657 self.generate_expression(&e.this)?;
31658 if let Some(expression) = &e.expression {
31659 self.write(", ");
31660 self.generate_expression(expression)?;
31661 }
31662 self.write(")");
31663 Ok(())
31664 }
31665
31666 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
31667 self.write_keyword("PARSE_TIME");
31669 self.write("(");
31670 self.write(&format!("'{}'", e.format));
31671 self.write(", ");
31672 self.generate_expression(&e.this)?;
31673 self.write(")");
31674 Ok(())
31675 }
31676
31677 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
31678 self.write_keyword("PARSE_URL");
31680 self.write("(");
31681 self.generate_expression(&e.this)?;
31682 if let Some(part) = &e.part_to_extract {
31683 self.write(", ");
31684 self.generate_expression(part)?;
31685 }
31686 if let Some(key) = &e.key {
31687 self.write(", ");
31688 self.generate_expression(key)?;
31689 }
31690 if let Some(permissive) = &e.permissive {
31691 self.write(", ");
31692 self.generate_expression(permissive)?;
31693 }
31694 self.write(")");
31695 Ok(())
31696 }
31697
31698 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
31699 if e.subpartition {
31701 self.write_keyword("SUBPARTITION");
31702 } else {
31703 self.write_keyword("PARTITION");
31704 }
31705 self.write("(");
31706 for (i, expr) in e.expressions.iter().enumerate() {
31707 if i > 0 {
31708 self.write(", ");
31709 }
31710 self.generate_expression(expr)?;
31711 }
31712 self.write(")");
31713 Ok(())
31714 }
31715
31716 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
31717 if let Some(this) = &e.this {
31719 if let Some(expression) = &e.expression {
31720 self.write_keyword("WITH");
31722 self.write(" (");
31723 self.write_keyword("MODULUS");
31724 self.write_space();
31725 self.generate_expression(this)?;
31726 self.write(", ");
31727 self.write_keyword("REMAINDER");
31728 self.write_space();
31729 self.generate_expression(expression)?;
31730 self.write(")");
31731 } else {
31732 self.write_keyword("IN");
31734 self.write(" (");
31735 self.generate_partition_bound_values(this)?;
31736 self.write(")");
31737 }
31738 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
31739 self.write_keyword("FROM");
31741 self.write(" (");
31742 self.generate_partition_bound_values(from)?;
31743 self.write(") ");
31744 self.write_keyword("TO");
31745 self.write(" (");
31746 self.generate_partition_bound_values(to)?;
31747 self.write(")");
31748 }
31749 Ok(())
31750 }
31751
31752 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
31755 if let Expression::Tuple(t) = expr {
31756 for (i, e) in t.expressions.iter().enumerate() {
31757 if i > 0 {
31758 self.write(", ");
31759 }
31760 self.generate_expression(e)?;
31761 }
31762 Ok(())
31763 } else {
31764 self.generate_expression(expr)
31765 }
31766 }
31767
31768 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
31769 self.write_keyword("PARTITION BY LIST");
31771 if let Some(partition_exprs) = &e.partition_expressions {
31772 self.write(" (");
31773 self.generate_doris_partition_expressions(partition_exprs)?;
31775 self.write(")");
31776 }
31777 if let Some(create_exprs) = &e.create_expressions {
31778 self.write(" (");
31779 self.generate_doris_partition_definitions(create_exprs)?;
31781 self.write(")");
31782 }
31783 Ok(())
31784 }
31785
31786 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
31787 self.write_keyword("PARTITION BY RANGE");
31789 if let Some(partition_exprs) = &e.partition_expressions {
31790 self.write(" (");
31791 self.generate_doris_partition_expressions(partition_exprs)?;
31793 self.write(")");
31794 }
31795 if let Some(create_exprs) = &e.create_expressions {
31796 self.write(" (");
31797 self.generate_doris_partition_definitions(create_exprs)?;
31799 self.write(")");
31800 }
31801 Ok(())
31802 }
31803
31804 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
31806 if let Expression::Tuple(t) = expr {
31807 for (i, e) in t.expressions.iter().enumerate() {
31808 if i > 0 {
31809 self.write(", ");
31810 }
31811 self.generate_expression(e)?;
31812 }
31813 } else {
31814 self.generate_expression(expr)?;
31815 }
31816 Ok(())
31817 }
31818
31819 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
31821 match expr {
31822 Expression::Tuple(t) => {
31823 for (i, part) in t.expressions.iter().enumerate() {
31825 if i > 0 {
31826 self.write(", ");
31827 }
31828 if let Expression::Partition(p) = part {
31830 for (j, inner) in p.expressions.iter().enumerate() {
31831 if j > 0 {
31832 self.write(", ");
31833 }
31834 self.generate_expression(inner)?;
31835 }
31836 } else {
31837 self.generate_expression(part)?;
31838 }
31839 }
31840 }
31841 Expression::PartitionByRangePropertyDynamic(_) => {
31842 self.generate_expression(expr)?;
31844 }
31845 _ => {
31846 self.generate_expression(expr)?;
31847 }
31848 }
31849 Ok(())
31850 }
31851
31852 fn generate_partition_by_range_property_dynamic(
31853 &mut self,
31854 e: &PartitionByRangePropertyDynamic,
31855 ) -> Result<()> {
31856 if e.use_start_end {
31857 if let Some(start) = &e.start {
31859 self.write_keyword("START");
31860 self.write(" (");
31861 self.generate_expression(start)?;
31862 self.write(")");
31863 }
31864 if let Some(end) = &e.end {
31865 self.write_space();
31866 self.write_keyword("END");
31867 self.write(" (");
31868 self.generate_expression(end)?;
31869 self.write(")");
31870 }
31871 if let Some(every) = &e.every {
31872 self.write_space();
31873 self.write_keyword("EVERY");
31874 self.write(" (");
31875 self.generate_doris_interval(every)?;
31877 self.write(")");
31878 }
31879 } else {
31880 if let Some(start) = &e.start {
31882 self.write_keyword("FROM");
31883 self.write(" (");
31884 self.generate_expression(start)?;
31885 self.write(")");
31886 }
31887 if let Some(end) = &e.end {
31888 self.write_space();
31889 self.write_keyword("TO");
31890 self.write(" (");
31891 self.generate_expression(end)?;
31892 self.write(")");
31893 }
31894 if let Some(every) = &e.every {
31895 self.write_space();
31896 self.generate_doris_interval(every)?;
31898 }
31899 }
31900 Ok(())
31901 }
31902
31903 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
31905 if let Expression::Interval(interval) = expr {
31906 self.write_keyword("INTERVAL");
31907 if let Some(ref value) = interval.this {
31908 self.write_space();
31909 match value {
31913 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()) => {
31914 if let Literal::String(s) = lit.as_ref() {
31915 self.write(s);
31916 }
31917 }
31918 _ => {
31919 self.generate_expression(value)?;
31920 }
31921 }
31922 }
31923 if let Some(ref unit_spec) = interval.unit {
31924 self.write_space();
31925 self.write_interval_unit_spec(unit_spec)?;
31926 }
31927 Ok(())
31928 } else {
31929 self.generate_expression(expr)
31930 }
31931 }
31932
31933 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
31934 self.write_keyword("TRUNCATE");
31936 self.write("(");
31937 self.generate_expression(&e.expression)?;
31938 self.write(", ");
31939 self.generate_expression(&e.this)?;
31940 self.write(")");
31941 Ok(())
31942 }
31943
31944 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
31945 self.write_keyword("PARTITION");
31947 self.write_space();
31948 self.generate_expression(&e.this)?;
31949 self.write_space();
31950 self.write_keyword("VALUES IN");
31951 self.write(" (");
31952 for (i, expr) in e.expressions.iter().enumerate() {
31953 if i > 0 {
31954 self.write(", ");
31955 }
31956 self.generate_expression(expr)?;
31957 }
31958 self.write(")");
31959 Ok(())
31960 }
31961
31962 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
31963 if e.expressions.is_empty() && e.expression.is_some() {
31966 self.generate_expression(&e.this)?;
31968 self.write_space();
31969 self.write_keyword("TO");
31970 self.write_space();
31971 self.generate_expression(e.expression.as_ref().unwrap())?;
31972 return Ok(());
31973 }
31974
31975 self.write_keyword("PARTITION");
31977 self.write_space();
31978 self.generate_expression(&e.this)?;
31979 self.write_space();
31980
31981 if e.expressions.len() == 1 {
31983 self.write_keyword("VALUES LESS THAN");
31985 self.write(" (");
31986 self.generate_expression(&e.expressions[0])?;
31987 self.write(")");
31988 } else if !e.expressions.is_empty() {
31989 self.write_keyword("VALUES");
31991 self.write(" [");
31992 for (i, expr) in e.expressions.iter().enumerate() {
31993 if i > 0 {
31994 self.write(", ");
31995 }
31996 if let Expression::Tuple(t) = expr {
31998 self.write("(");
31999 for (j, inner) in t.expressions.iter().enumerate() {
32000 if j > 0 {
32001 self.write(", ");
32002 }
32003 self.generate_expression(inner)?;
32004 }
32005 self.write(")");
32006 } else {
32007 self.write("(");
32008 self.generate_expression(expr)?;
32009 self.write(")");
32010 }
32011 }
32012 self.write(")");
32013 }
32014 Ok(())
32015 }
32016
32017 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
32018 self.write_keyword("BUCKET");
32020 self.write("(");
32021 self.generate_expression(&e.this)?;
32022 self.write(", ");
32023 self.generate_expression(&e.expression)?;
32024 self.write(")");
32025 Ok(())
32026 }
32027
32028 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
32029 self.write_keyword("PARTITION BY");
32031 self.write_space();
32032 for (i, expr) in e.expressions.iter().enumerate() {
32033 if i > 0 {
32034 self.write(", ");
32035 }
32036 self.generate_expression(expr)?;
32037 }
32038 Ok(())
32039 }
32040
32041 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
32042 if matches!(
32044 self.config.dialect,
32045 Some(crate::dialects::DialectType::Teradata)
32046 | Some(crate::dialects::DialectType::ClickHouse)
32047 ) {
32048 self.write_keyword("PARTITION BY");
32049 } else {
32050 self.write_keyword("PARTITIONED BY");
32051 }
32052 self.write_space();
32053 if self.config.pretty {
32055 if let Expression::Tuple(ref tuple) = *e.this {
32056 self.write("(");
32057 self.write_newline();
32058 self.indent_level += 1;
32059 for (i, expr) in tuple.expressions.iter().enumerate() {
32060 if i > 0 {
32061 self.write(",");
32062 self.write_newline();
32063 }
32064 self.write_indent();
32065 self.generate_expression(expr)?;
32066 }
32067 self.indent_level -= 1;
32068 self.write_newline();
32069 self.write(")");
32070 } else {
32071 self.generate_expression(&e.this)?;
32072 }
32073 } else {
32074 self.generate_expression(&e.this)?;
32075 }
32076 Ok(())
32077 }
32078
32079 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
32080 self.write_keyword("PARTITION OF");
32082 self.write_space();
32083 self.generate_expression(&e.this)?;
32084 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
32086 self.write_space();
32087 self.write_keyword("FOR VALUES");
32088 self.write_space();
32089 self.generate_expression(&e.expression)?;
32090 } else {
32091 self.write_space();
32092 self.write_keyword("DEFAULT");
32093 }
32094 Ok(())
32095 }
32096
32097 fn generate_period_for_system_time_constraint(
32098 &mut self,
32099 e: &PeriodForSystemTimeConstraint,
32100 ) -> Result<()> {
32101 self.write_keyword("PERIOD FOR SYSTEM_TIME");
32103 self.write(" (");
32104 self.generate_expression(&e.this)?;
32105 self.write(", ");
32106 self.generate_expression(&e.expression)?;
32107 self.write(")");
32108 Ok(())
32109 }
32110
32111 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
32112 self.generate_expression(&e.this)?;
32115 self.write_space();
32116 self.write_keyword("AS");
32117 self.write_space();
32118 if self.config.unpivot_aliases_are_identifiers {
32120 match &e.alias {
32121 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
32122 let Literal::String(s) = lit.as_ref() else {
32123 unreachable!()
32124 };
32125 self.generate_identifier(&Identifier::new(s.clone()))?;
32127 }
32128 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
32129 let Literal::Number(n) = lit.as_ref() else {
32130 unreachable!()
32131 };
32132 let mut id = Identifier::new(n.clone());
32134 id.quoted = true;
32135 self.generate_identifier(&id)?;
32136 }
32137 other => {
32138 self.generate_expression(other)?;
32139 }
32140 }
32141 } else {
32142 self.generate_expression(&e.alias)?;
32143 }
32144 Ok(())
32145 }
32146
32147 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
32148 self.write_keyword("ANY");
32150 if let Some(this) = &e.this {
32151 self.write_space();
32152 self.generate_expression(this)?;
32153 }
32154 Ok(())
32155 }
32156
32157 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
32158 self.write_keyword("ML.PREDICT");
32160 self.write("(");
32161 self.write_keyword("MODEL");
32162 self.write_space();
32163 self.generate_expression(&e.this)?;
32164 self.write(", ");
32165 self.generate_expression(&e.expression)?;
32166 if let Some(params) = &e.params_struct {
32167 self.write(", ");
32168 self.generate_expression(params)?;
32169 }
32170 self.write(")");
32171 Ok(())
32172 }
32173
32174 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
32175 self.write_keyword("PREVIOUS_DAY");
32177 self.write("(");
32178 self.generate_expression(&e.this)?;
32179 self.write(", ");
32180 self.generate_expression(&e.expression)?;
32181 self.write(")");
32182 Ok(())
32183 }
32184
32185 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
32186 self.write_keyword("PRIMARY KEY");
32188 if let Some(name) = &e.this {
32189 self.write_space();
32190 self.generate_expression(name)?;
32191 }
32192 if !e.expressions.is_empty() {
32193 self.write(" (");
32194 for (i, expr) in e.expressions.iter().enumerate() {
32195 if i > 0 {
32196 self.write(", ");
32197 }
32198 self.generate_expression(expr)?;
32199 }
32200 self.write(")");
32201 }
32202 if let Some(include) = &e.include {
32203 self.write_space();
32204 self.generate_expression(include)?;
32205 }
32206 if !e.options.is_empty() {
32207 self.write_space();
32208 for (i, opt) in e.options.iter().enumerate() {
32209 if i > 0 {
32210 self.write_space();
32211 }
32212 self.generate_expression(opt)?;
32213 }
32214 }
32215 Ok(())
32216 }
32217
32218 fn generate_primary_key_column_constraint(
32219 &mut self,
32220 _e: &PrimaryKeyColumnConstraint,
32221 ) -> Result<()> {
32222 self.write_keyword("PRIMARY KEY");
32224 Ok(())
32225 }
32226
32227 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
32228 self.write_keyword("PATH");
32230 self.write_space();
32231 self.generate_expression(&e.this)?;
32232 Ok(())
32233 }
32234
32235 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
32236 self.write_keyword("PROJECTION");
32238 self.write_space();
32239 self.generate_expression(&e.this)?;
32240 self.write(" (");
32241 self.generate_expression(&e.expression)?;
32242 self.write(")");
32243 Ok(())
32244 }
32245
32246 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
32247 for (i, prop) in e.expressions.iter().enumerate() {
32249 if i > 0 {
32250 self.write(", ");
32251 }
32252 self.generate_expression(prop)?;
32253 }
32254 Ok(())
32255 }
32256
32257 fn generate_property(&mut self, e: &Property) -> Result<()> {
32258 self.generate_expression(&e.this)?;
32260 if let Some(value) = &e.value {
32261 self.write("=");
32262 self.generate_expression(value)?;
32263 }
32264 Ok(())
32265 }
32266
32267 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
32268 self.write_keyword("OPTIONS");
32269 if e.entries.is_empty() {
32270 self.write(" ()");
32271 return Ok(());
32272 }
32273
32274 if self.config.pretty {
32275 self.write(" (");
32276 self.write_newline();
32277 self.indent_level += 1;
32278 for (i, entry) in e.entries.iter().enumerate() {
32279 if i > 0 {
32280 self.write(",");
32281 self.write_newline();
32282 }
32283 self.write_indent();
32284 self.generate_identifier(&entry.key)?;
32285 self.write("=");
32286 self.generate_expression(&entry.value)?;
32287 }
32288 self.indent_level -= 1;
32289 self.write_newline();
32290 self.write(")");
32291 } else {
32292 self.write(" (");
32293 for (i, entry) in e.entries.iter().enumerate() {
32294 if i > 0 {
32295 self.write(", ");
32296 }
32297 self.generate_identifier(&entry.key)?;
32298 self.write("=");
32299 self.generate_expression(&entry.value)?;
32300 }
32301 self.write(")");
32302 }
32303 Ok(())
32304 }
32305
32306 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
32308 self.write_keyword("OPTIONS");
32309 self.write(" (");
32310 for (i, opt) in options.iter().enumerate() {
32311 if i > 0 {
32312 self.write(", ");
32313 }
32314 self.generate_option_expression(opt)?;
32315 }
32316 self.write(")");
32317 Ok(())
32318 }
32319
32320 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
32322 self.write_keyword("PROPERTIES");
32323 self.write(" (");
32324 for (i, prop) in properties.iter().enumerate() {
32325 if i > 0 {
32326 self.write(", ");
32327 }
32328 self.generate_option_expression(prop)?;
32329 }
32330 self.write(")");
32331 Ok(())
32332 }
32333
32334 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
32336 self.write_keyword("ENVIRONMENT");
32337 self.write(" (");
32338 for (i, env_item) in environment.iter().enumerate() {
32339 if i > 0 {
32340 self.write(", ");
32341 }
32342 self.generate_environment_expression(env_item)?;
32343 }
32344 self.write(")");
32345 Ok(())
32346 }
32347
32348 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
32350 match expr {
32351 Expression::Eq(eq) => {
32352 self.generate_expression(&eq.left)?;
32354 self.write(" = ");
32355 self.generate_expression(&eq.right)?;
32356 Ok(())
32357 }
32358 _ => self.generate_expression(expr),
32359 }
32360 }
32361
32362 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
32364 self.write_keyword("TBLPROPERTIES");
32365 if self.config.pretty {
32366 self.write(" (");
32367 self.write_newline();
32368 self.indent_level += 1;
32369 for (i, opt) in options.iter().enumerate() {
32370 if i > 0 {
32371 self.write(",");
32372 self.write_newline();
32373 }
32374 self.write_indent();
32375 self.generate_option_expression(opt)?;
32376 }
32377 self.indent_level -= 1;
32378 self.write_newline();
32379 self.write(")");
32380 } else {
32381 self.write(" (");
32382 for (i, opt) in options.iter().enumerate() {
32383 if i > 0 {
32384 self.write(", ");
32385 }
32386 self.generate_option_expression(opt)?;
32387 }
32388 self.write(")");
32389 }
32390 Ok(())
32391 }
32392
32393 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
32395 match expr {
32396 Expression::Eq(eq) => {
32397 self.generate_expression(&eq.left)?;
32399 self.write("=");
32400 self.generate_expression(&eq.right)?;
32401 Ok(())
32402 }
32403 _ => self.generate_expression(expr),
32404 }
32405 }
32406
32407 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
32408 self.generate_expression(&e.this)?;
32410 Ok(())
32411 }
32412
32413 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
32414 self.write_keyword("PUT");
32416 self.write_space();
32417
32418 if e.source_quoted {
32420 self.write("'");
32421 self.write(&e.source);
32422 self.write("'");
32423 } else {
32424 self.write(&e.source);
32425 }
32426
32427 self.write_space();
32428
32429 if let Expression::Literal(lit) = &e.target {
32431 if let Literal::String(s) = lit.as_ref() {
32432 self.write(s);
32433 }
32434 } else {
32435 self.generate_expression(&e.target)?;
32436 }
32437
32438 for param in &e.params {
32440 self.write_space();
32441 self.write(¶m.name);
32442 if let Some(ref value) = param.value {
32443 self.write("=");
32444 self.generate_expression(value)?;
32445 }
32446 }
32447
32448 Ok(())
32449 }
32450
32451 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
32452 self.write_keyword("QUANTILE");
32454 self.write("(");
32455 self.generate_expression(&e.this)?;
32456 if let Some(quantile) = &e.quantile {
32457 self.write(", ");
32458 self.generate_expression(quantile)?;
32459 }
32460 self.write(")");
32461 Ok(())
32462 }
32463
32464 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
32465 if matches!(
32467 self.config.dialect,
32468 Some(crate::dialects::DialectType::Teradata)
32469 ) {
32470 self.write_keyword("SET");
32471 self.write_space();
32472 }
32473 self.write_keyword("QUERY_BAND");
32474 self.write(" = ");
32475 self.generate_expression(&e.this)?;
32476 if e.update.is_some() {
32477 self.write_space();
32478 self.write_keyword("UPDATE");
32479 }
32480 if let Some(scope) = &e.scope {
32481 self.write_space();
32482 self.write_keyword("FOR");
32483 self.write_space();
32484 self.generate_expression(scope)?;
32485 }
32486 Ok(())
32487 }
32488
32489 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
32490 self.generate_expression(&e.this)?;
32492 if let Some(expression) = &e.expression {
32493 self.write(" = ");
32494 self.generate_expression(expression)?;
32495 }
32496 Ok(())
32497 }
32498
32499 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
32500 self.write_keyword("TRANSFORM");
32502 self.write("(");
32503 for (i, expr) in e.expressions.iter().enumerate() {
32504 if i > 0 {
32505 self.write(", ");
32506 }
32507 self.generate_expression(expr)?;
32508 }
32509 self.write(")");
32510 if let Some(row_format_before) = &e.row_format_before {
32511 self.write_space();
32512 self.generate_expression(row_format_before)?;
32513 }
32514 if let Some(record_writer) = &e.record_writer {
32515 self.write_space();
32516 self.write_keyword("RECORDWRITER");
32517 self.write_space();
32518 self.generate_expression(record_writer)?;
32519 }
32520 if let Some(command_script) = &e.command_script {
32521 self.write_space();
32522 self.write_keyword("USING");
32523 self.write_space();
32524 self.generate_expression(command_script)?;
32525 }
32526 if let Some(schema) = &e.schema {
32527 self.write_space();
32528 self.write_keyword("AS");
32529 self.write_space();
32530 self.generate_expression(schema)?;
32531 }
32532 if let Some(row_format_after) = &e.row_format_after {
32533 self.write_space();
32534 self.generate_expression(row_format_after)?;
32535 }
32536 if let Some(record_reader) = &e.record_reader {
32537 self.write_space();
32538 self.write_keyword("RECORDREADER");
32539 self.write_space();
32540 self.generate_expression(record_reader)?;
32541 }
32542 Ok(())
32543 }
32544
32545 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
32546 self.write_keyword("RANDN");
32548 self.write("(");
32549 if let Some(this) = &e.this {
32550 self.generate_expression(this)?;
32551 }
32552 self.write(")");
32553 Ok(())
32554 }
32555
32556 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
32557 self.write_keyword("RANDSTR");
32559 self.write("(");
32560 self.generate_expression(&e.this)?;
32561 if let Some(generator) = &e.generator {
32562 self.write(", ");
32563 self.generate_expression(generator)?;
32564 }
32565 self.write(")");
32566 Ok(())
32567 }
32568
32569 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
32570 self.write_keyword("RANGE_BUCKET");
32572 self.write("(");
32573 self.generate_expression(&e.this)?;
32574 self.write(", ");
32575 self.generate_expression(&e.expression)?;
32576 self.write(")");
32577 Ok(())
32578 }
32579
32580 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
32581 self.write_keyword("RANGE_N");
32583 self.write("(");
32584 self.generate_expression(&e.this)?;
32585 self.write_space();
32586 self.write_keyword("BETWEEN");
32587 self.write_space();
32588 for (i, expr) in e.expressions.iter().enumerate() {
32589 if i > 0 {
32590 self.write(", ");
32591 }
32592 self.generate_expression(expr)?;
32593 }
32594 if let Some(each) = &e.each {
32595 self.write_space();
32596 self.write_keyword("EACH");
32597 self.write_space();
32598 self.generate_expression(each)?;
32599 }
32600 self.write(")");
32601 Ok(())
32602 }
32603
32604 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
32605 self.write_keyword("READ_CSV");
32607 self.write("(");
32608 self.generate_expression(&e.this)?;
32609 for expr in &e.expressions {
32610 self.write(", ");
32611 self.generate_expression(expr)?;
32612 }
32613 self.write(")");
32614 Ok(())
32615 }
32616
32617 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
32618 self.write_keyword("READ_PARQUET");
32620 self.write("(");
32621 for (i, expr) in e.expressions.iter().enumerate() {
32622 if i > 0 {
32623 self.write(", ");
32624 }
32625 self.generate_expression(expr)?;
32626 }
32627 self.write(")");
32628 Ok(())
32629 }
32630
32631 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
32632 if e.kind == "CYCLE" {
32635 self.write_keyword("CYCLE");
32636 } else {
32637 self.write_keyword("SEARCH");
32638 self.write_space();
32639 self.write(&e.kind);
32640 self.write_space();
32641 self.write_keyword("FIRST BY");
32642 }
32643 self.write_space();
32644 self.generate_expression(&e.this)?;
32645 self.write_space();
32646 self.write_keyword("SET");
32647 self.write_space();
32648 self.generate_expression(&e.expression)?;
32649 if let Some(using) = &e.using {
32650 self.write_space();
32651 self.write_keyword("USING");
32652 self.write_space();
32653 self.generate_expression(using)?;
32654 }
32655 Ok(())
32656 }
32657
32658 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
32659 self.write_keyword("REDUCE");
32661 self.write("(");
32662 self.generate_expression(&e.this)?;
32663 if let Some(initial) = &e.initial {
32664 self.write(", ");
32665 self.generate_expression(initial)?;
32666 }
32667 if let Some(merge) = &e.merge {
32668 self.write(", ");
32669 self.generate_expression(merge)?;
32670 }
32671 if let Some(finish) = &e.finish {
32672 self.write(", ");
32673 self.generate_expression(finish)?;
32674 }
32675 self.write(")");
32676 Ok(())
32677 }
32678
32679 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
32680 self.write_keyword("REFERENCES");
32682 self.write_space();
32683 self.generate_expression(&e.this)?;
32684 if !e.expressions.is_empty() {
32685 self.write(" (");
32686 for (i, expr) in e.expressions.iter().enumerate() {
32687 if i > 0 {
32688 self.write(", ");
32689 }
32690 self.generate_expression(expr)?;
32691 }
32692 self.write(")");
32693 }
32694 for opt in &e.options {
32695 self.write_space();
32696 self.generate_expression(opt)?;
32697 }
32698 Ok(())
32699 }
32700
32701 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
32702 self.write_keyword("REFRESH");
32704 if !e.kind.is_empty() {
32705 self.write_space();
32706 self.write_keyword(&e.kind);
32707 }
32708 self.write_space();
32709 self.generate_expression(&e.this)?;
32710 Ok(())
32711 }
32712
32713 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
32714 self.write_keyword("REFRESH");
32716 self.write_space();
32717 self.write_keyword(&e.method);
32718
32719 if let Some(ref kind) = e.kind {
32720 self.write_space();
32721 self.write_keyword("ON");
32722 self.write_space();
32723 self.write_keyword(kind);
32724
32725 if let Some(ref every) = e.every {
32727 self.write_space();
32728 self.write_keyword("EVERY");
32729 self.write_space();
32730 self.generate_expression(every)?;
32731 if let Some(ref unit) = e.unit {
32732 self.write_space();
32733 self.write_keyword(unit);
32734 }
32735 }
32736
32737 if let Some(ref starts) = e.starts {
32739 self.write_space();
32740 self.write_keyword("STARTS");
32741 self.write_space();
32742 self.generate_expression(starts)?;
32743 }
32744 }
32745 Ok(())
32746 }
32747
32748 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
32749 self.write_keyword("REGEXP_COUNT");
32751 self.write("(");
32752 self.generate_expression(&e.this)?;
32753 self.write(", ");
32754 self.generate_expression(&e.expression)?;
32755 if let Some(position) = &e.position {
32756 self.write(", ");
32757 self.generate_expression(position)?;
32758 }
32759 if let Some(parameters) = &e.parameters {
32760 self.write(", ");
32761 self.generate_expression(parameters)?;
32762 }
32763 self.write(")");
32764 Ok(())
32765 }
32766
32767 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
32768 self.write_keyword("REGEXP_EXTRACT_ALL");
32770 self.write("(");
32771 self.generate_expression(&e.this)?;
32772 self.write(", ");
32773 self.generate_expression(&e.expression)?;
32774 if let Some(group) = &e.group {
32775 self.write(", ");
32776 self.generate_expression(group)?;
32777 }
32778 self.write(")");
32779 Ok(())
32780 }
32781
32782 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
32783 self.write_keyword("REGEXP_FULL_MATCH");
32785 self.write("(");
32786 self.generate_expression(&e.this)?;
32787 self.write(", ");
32788 self.generate_expression(&e.expression)?;
32789 self.write(")");
32790 Ok(())
32791 }
32792
32793 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
32794 use crate::dialects::DialectType;
32795 if matches!(
32797 self.config.dialect,
32798 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
32799 ) && e.flag.is_none()
32800 {
32801 self.generate_expression(&e.this)?;
32802 self.write(" ~* ");
32803 self.generate_expression(&e.expression)?;
32804 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
32805 self.write_keyword("REGEXP_LIKE");
32807 self.write("(");
32808 self.generate_expression(&e.this)?;
32809 self.write(", ");
32810 self.generate_expression(&e.expression)?;
32811 self.write(", ");
32812 if let Some(flag) = &e.flag {
32813 self.generate_expression(flag)?;
32814 } else {
32815 self.write("'i'");
32816 }
32817 self.write(")");
32818 } else {
32819 self.generate_expression(&e.this)?;
32821 self.write_space();
32822 self.write_keyword("REGEXP_ILIKE");
32823 self.write_space();
32824 self.generate_expression(&e.expression)?;
32825 if let Some(flag) = &e.flag {
32826 self.write(", ");
32827 self.generate_expression(flag)?;
32828 }
32829 }
32830 Ok(())
32831 }
32832
32833 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
32834 self.write_keyword("REGEXP_INSTR");
32836 self.write("(");
32837 self.generate_expression(&e.this)?;
32838 self.write(", ");
32839 self.generate_expression(&e.expression)?;
32840 if let Some(position) = &e.position {
32841 self.write(", ");
32842 self.generate_expression(position)?;
32843 }
32844 if let Some(occurrence) = &e.occurrence {
32845 self.write(", ");
32846 self.generate_expression(occurrence)?;
32847 }
32848 if let Some(option) = &e.option {
32849 self.write(", ");
32850 self.generate_expression(option)?;
32851 }
32852 if let Some(parameters) = &e.parameters {
32853 self.write(", ");
32854 self.generate_expression(parameters)?;
32855 }
32856 if let Some(group) = &e.group {
32857 self.write(", ");
32858 self.generate_expression(group)?;
32859 }
32860 self.write(")");
32861 Ok(())
32862 }
32863
32864 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
32865 self.write_keyword("REGEXP_SPLIT");
32867 self.write("(");
32868 self.generate_expression(&e.this)?;
32869 self.write(", ");
32870 self.generate_expression(&e.expression)?;
32871 if let Some(limit) = &e.limit {
32872 self.write(", ");
32873 self.generate_expression(limit)?;
32874 }
32875 self.write(")");
32876 Ok(())
32877 }
32878
32879 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
32880 self.write_keyword("REGR_AVGX");
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_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
32891 self.write_keyword("REGR_AVGY");
32893 self.write("(");
32894 self.generate_expression(&e.this)?;
32895 self.write(", ");
32896 self.generate_expression(&e.expression)?;
32897 self.write(")");
32898 Ok(())
32899 }
32900
32901 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
32902 self.write_keyword("REGR_COUNT");
32904 self.write("(");
32905 self.generate_expression(&e.this)?;
32906 self.write(", ");
32907 self.generate_expression(&e.expression)?;
32908 self.write(")");
32909 Ok(())
32910 }
32911
32912 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
32913 self.write_keyword("REGR_INTERCEPT");
32915 self.write("(");
32916 self.generate_expression(&e.this)?;
32917 self.write(", ");
32918 self.generate_expression(&e.expression)?;
32919 self.write(")");
32920 Ok(())
32921 }
32922
32923 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
32924 self.write_keyword("REGR_R2");
32926 self.write("(");
32927 self.generate_expression(&e.this)?;
32928 self.write(", ");
32929 self.generate_expression(&e.expression)?;
32930 self.write(")");
32931 Ok(())
32932 }
32933
32934 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
32935 self.write_keyword("REGR_SLOPE");
32937 self.write("(");
32938 self.generate_expression(&e.this)?;
32939 self.write(", ");
32940 self.generate_expression(&e.expression)?;
32941 self.write(")");
32942 Ok(())
32943 }
32944
32945 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
32946 self.write_keyword("REGR_SXX");
32948 self.write("(");
32949 self.generate_expression(&e.this)?;
32950 self.write(", ");
32951 self.generate_expression(&e.expression)?;
32952 self.write(")");
32953 Ok(())
32954 }
32955
32956 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
32957 self.write_keyword("REGR_SXY");
32959 self.write("(");
32960 self.generate_expression(&e.this)?;
32961 self.write(", ");
32962 self.generate_expression(&e.expression)?;
32963 self.write(")");
32964 Ok(())
32965 }
32966
32967 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
32968 self.write_keyword("REGR_SYY");
32970 self.write("(");
32971 self.generate_expression(&e.this)?;
32972 self.write(", ");
32973 self.generate_expression(&e.expression)?;
32974 self.write(")");
32975 Ok(())
32976 }
32977
32978 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
32979 self.write_keyword("REGR_VALX");
32981 self.write("(");
32982 self.generate_expression(&e.this)?;
32983 self.write(", ");
32984 self.generate_expression(&e.expression)?;
32985 self.write(")");
32986 Ok(())
32987 }
32988
32989 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
32990 self.write_keyword("REGR_VALY");
32992 self.write("(");
32993 self.generate_expression(&e.this)?;
32994 self.write(", ");
32995 self.generate_expression(&e.expression)?;
32996 self.write(")");
32997 Ok(())
32998 }
32999
33000 fn generate_remote_with_connection_model_property(
33001 &mut self,
33002 e: &RemoteWithConnectionModelProperty,
33003 ) -> Result<()> {
33004 self.write_keyword("REMOTE WITH CONNECTION");
33006 self.write_space();
33007 self.generate_expression(&e.this)?;
33008 Ok(())
33009 }
33010
33011 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
33012 self.write_keyword("RENAME COLUMN");
33014 if e.exists {
33015 self.write_space();
33016 self.write_keyword("IF EXISTS");
33017 }
33018 self.write_space();
33019 self.generate_expression(&e.this)?;
33020 if let Some(to) = &e.to {
33021 self.write_space();
33022 self.write_keyword("TO");
33023 self.write_space();
33024 self.generate_expression(to)?;
33025 }
33026 Ok(())
33027 }
33028
33029 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
33030 self.write_keyword("REPLACE PARTITION");
33032 self.write_space();
33033 self.generate_expression(&e.expression)?;
33034 if let Some(source) = &e.source {
33035 self.write_space();
33036 self.write_keyword("FROM");
33037 self.write_space();
33038 self.generate_expression(source)?;
33039 }
33040 Ok(())
33041 }
33042
33043 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
33044 let keyword = match self.config.dialect {
33047 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
33048 _ => "RETURNING",
33049 };
33050 self.write_keyword(keyword);
33051 self.write_space();
33052 for (i, expr) in e.expressions.iter().enumerate() {
33053 if i > 0 {
33054 self.write(", ");
33055 }
33056 self.generate_expression(expr)?;
33057 }
33058 if let Some(into) = &e.into {
33059 self.write_space();
33060 self.write_keyword("INTO");
33061 self.write_space();
33062 self.generate_expression(into)?;
33063 }
33064 Ok(())
33065 }
33066
33067 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
33068 self.write_space();
33070 self.write_keyword("OUTPUT");
33071 self.write_space();
33072 for (i, expr) in output.columns.iter().enumerate() {
33073 if i > 0 {
33074 self.write(", ");
33075 }
33076 self.generate_expression(expr)?;
33077 }
33078 if let Some(into_table) = &output.into_table {
33079 self.write_space();
33080 self.write_keyword("INTO");
33081 self.write_space();
33082 self.generate_expression(into_table)?;
33083 }
33084 Ok(())
33085 }
33086
33087 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
33088 self.write_keyword("RETURNS");
33090 if e.is_table.is_some() {
33091 self.write_space();
33092 self.write_keyword("TABLE");
33093 }
33094 if let Some(table) = &e.table {
33095 self.write_space();
33096 self.generate_expression(table)?;
33097 } else if let Some(this) = &e.this {
33098 self.write_space();
33099 self.generate_expression(this)?;
33100 }
33101 if e.null.is_some() {
33102 self.write_space();
33103 self.write_keyword("NULL ON NULL INPUT");
33104 }
33105 Ok(())
33106 }
33107
33108 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
33109 self.write_keyword("ROLLBACK");
33111
33112 if e.this.is_none()
33114 && matches!(
33115 self.config.dialect,
33116 Some(DialectType::TSQL) | Some(DialectType::Fabric)
33117 )
33118 {
33119 self.write_space();
33120 self.write_keyword("TRANSACTION");
33121 }
33122
33123 if let Some(this) = &e.this {
33125 let is_transaction_marker = matches!(
33127 this.as_ref(),
33128 Expression::Identifier(id) if id.name == "TRANSACTION"
33129 );
33130
33131 self.write_space();
33132 self.write_keyword("TRANSACTION");
33133
33134 if !is_transaction_marker {
33136 self.write_space();
33137 self.generate_expression(this)?;
33138 }
33139 }
33140
33141 if let Some(savepoint) = &e.savepoint {
33143 self.write_space();
33144 self.write_keyword("TO");
33145 self.write_space();
33146 self.generate_expression(savepoint)?;
33147 }
33148 Ok(())
33149 }
33150
33151 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
33152 if e.expressions.is_empty() {
33154 self.write_keyword("WITH ROLLUP");
33155 } else {
33156 self.write_keyword("ROLLUP");
33157 self.write("(");
33158 for (i, expr) in e.expressions.iter().enumerate() {
33159 if i > 0 {
33160 self.write(", ");
33161 }
33162 self.generate_expression(expr)?;
33163 }
33164 self.write(")");
33165 }
33166 Ok(())
33167 }
33168
33169 fn generate_row_format_delimited_property(
33170 &mut self,
33171 e: &RowFormatDelimitedProperty,
33172 ) -> Result<()> {
33173 self.write_keyword("ROW FORMAT DELIMITED");
33175 if let Some(fields) = &e.fields {
33176 self.write_space();
33177 self.write_keyword("FIELDS TERMINATED BY");
33178 self.write_space();
33179 self.generate_expression(fields)?;
33180 }
33181 if let Some(escaped) = &e.escaped {
33182 self.write_space();
33183 self.write_keyword("ESCAPED BY");
33184 self.write_space();
33185 self.generate_expression(escaped)?;
33186 }
33187 if let Some(items) = &e.collection_items {
33188 self.write_space();
33189 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
33190 self.write_space();
33191 self.generate_expression(items)?;
33192 }
33193 if let Some(keys) = &e.map_keys {
33194 self.write_space();
33195 self.write_keyword("MAP KEYS TERMINATED BY");
33196 self.write_space();
33197 self.generate_expression(keys)?;
33198 }
33199 if let Some(lines) = &e.lines {
33200 self.write_space();
33201 self.write_keyword("LINES TERMINATED BY");
33202 self.write_space();
33203 self.generate_expression(lines)?;
33204 }
33205 if let Some(null) = &e.null {
33206 self.write_space();
33207 self.write_keyword("NULL DEFINED AS");
33208 self.write_space();
33209 self.generate_expression(null)?;
33210 }
33211 if let Some(serde) = &e.serde {
33212 self.write_space();
33213 self.generate_expression(serde)?;
33214 }
33215 Ok(())
33216 }
33217
33218 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
33219 self.write_keyword("ROW FORMAT");
33221 self.write_space();
33222 self.generate_expression(&e.this)?;
33223 Ok(())
33224 }
33225
33226 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
33227 self.write_keyword("ROW FORMAT SERDE");
33229 self.write_space();
33230 self.generate_expression(&e.this)?;
33231 if let Some(props) = &e.serde_properties {
33232 self.write_space();
33233 self.generate_expression(props)?;
33235 }
33236 Ok(())
33237 }
33238
33239 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
33240 self.write_keyword("SHA2");
33242 self.write("(");
33243 self.generate_expression(&e.this)?;
33244 if let Some(length) = e.length {
33245 self.write(", ");
33246 self.write(&length.to_string());
33247 }
33248 self.write(")");
33249 Ok(())
33250 }
33251
33252 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
33253 self.write_keyword("SHA2_DIGEST");
33255 self.write("(");
33256 self.generate_expression(&e.this)?;
33257 if let Some(length) = e.length {
33258 self.write(", ");
33259 self.write(&length.to_string());
33260 }
33261 self.write(")");
33262 Ok(())
33263 }
33264
33265 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
33266 let name = if matches!(
33267 self.config.dialect,
33268 Some(crate::dialects::DialectType::Spark)
33269 | Some(crate::dialects::DialectType::Databricks)
33270 ) {
33271 "TRY_ADD"
33272 } else {
33273 "SAFE_ADD"
33274 };
33275 self.write_keyword(name);
33276 self.write("(");
33277 self.generate_expression(&e.this)?;
33278 self.write(", ");
33279 self.generate_expression(&e.expression)?;
33280 self.write(")");
33281 Ok(())
33282 }
33283
33284 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
33285 self.write_keyword("SAFE_DIVIDE");
33287 self.write("(");
33288 self.generate_expression(&e.this)?;
33289 self.write(", ");
33290 self.generate_expression(&e.expression)?;
33291 self.write(")");
33292 Ok(())
33293 }
33294
33295 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
33296 let name = if matches!(
33297 self.config.dialect,
33298 Some(crate::dialects::DialectType::Spark)
33299 | Some(crate::dialects::DialectType::Databricks)
33300 ) {
33301 "TRY_MULTIPLY"
33302 } else {
33303 "SAFE_MULTIPLY"
33304 };
33305 self.write_keyword(name);
33306 self.write("(");
33307 self.generate_expression(&e.this)?;
33308 self.write(", ");
33309 self.generate_expression(&e.expression)?;
33310 self.write(")");
33311 Ok(())
33312 }
33313
33314 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
33315 let name = if matches!(
33316 self.config.dialect,
33317 Some(crate::dialects::DialectType::Spark)
33318 | Some(crate::dialects::DialectType::Databricks)
33319 ) {
33320 "TRY_SUBTRACT"
33321 } else {
33322 "SAFE_SUBTRACT"
33323 };
33324 self.write_keyword(name);
33325 self.write("(");
33326 self.generate_expression(&e.this)?;
33327 self.write(", ");
33328 self.generate_expression(&e.expression)?;
33329 self.write(")");
33330 Ok(())
33331 }
33332
33333 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
33336 if matches!(sample.method, SampleMethod::Bucket) {
33338 self.write(" (");
33339 self.write_keyword("BUCKET");
33340 self.write_space();
33341 if let Some(ref num) = sample.bucket_numerator {
33342 self.generate_expression(num)?;
33343 }
33344 self.write_space();
33345 self.write_keyword("OUT OF");
33346 self.write_space();
33347 if let Some(ref denom) = sample.bucket_denominator {
33348 self.generate_expression(denom)?;
33349 }
33350 if let Some(ref field) = sample.bucket_field {
33351 self.write_space();
33352 self.write_keyword("ON");
33353 self.write_space();
33354 self.generate_expression(field)?;
33355 }
33356 self.write(")");
33357 return Ok(());
33358 }
33359
33360 let is_snowflake = matches!(
33362 self.config.dialect,
33363 Some(crate::dialects::DialectType::Snowflake)
33364 );
33365 let is_postgres = matches!(
33366 self.config.dialect,
33367 Some(crate::dialects::DialectType::PostgreSQL)
33368 | Some(crate::dialects::DialectType::Redshift)
33369 );
33370 let is_databricks = matches!(
33372 self.config.dialect,
33373 Some(crate::dialects::DialectType::Databricks)
33374 );
33375 let is_spark = matches!(
33376 self.config.dialect,
33377 Some(crate::dialects::DialectType::Spark)
33378 );
33379 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
33380 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
33382 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
33383 self.write_space();
33384 if !sample.explicit_method && (is_snowflake || force_method) {
33385 self.write_keyword("BERNOULLI");
33387 } else {
33388 match sample.method {
33389 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
33390 SampleMethod::System => self.write_keyword("SYSTEM"),
33391 SampleMethod::Block => self.write_keyword("BLOCK"),
33392 SampleMethod::Row => self.write_keyword("ROW"),
33393 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
33394 SampleMethod::Percent => self.write_keyword("SYSTEM"),
33395 SampleMethod::Bucket => {} }
33397 }
33398 }
33399
33400 let emit_size_no_parens = !self.config.tablesample_requires_parens;
33402 if emit_size_no_parens {
33403 self.write_space();
33404 match &sample.size {
33405 Expression::Tuple(tuple) => {
33406 for (i, expr) in tuple.expressions.iter().enumerate() {
33407 if i > 0 {
33408 self.write(", ");
33409 }
33410 self.generate_expression(expr)?;
33411 }
33412 }
33413 expr => self.generate_expression(expr)?,
33414 }
33415 } else {
33416 self.write(" (");
33417 self.generate_expression(&sample.size)?;
33418 }
33419
33420 let is_rows_method = matches!(
33422 sample.method,
33423 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
33424 );
33425 let is_percent = matches!(
33426 sample.method,
33427 SampleMethod::Percent
33428 | SampleMethod::System
33429 | SampleMethod::Bernoulli
33430 | SampleMethod::Block
33431 );
33432
33433 let is_presto = matches!(
33437 self.config.dialect,
33438 Some(crate::dialects::DialectType::Presto)
33439 | Some(crate::dialects::DialectType::Trino)
33440 | Some(crate::dialects::DialectType::Athena)
33441 );
33442 let should_output_unit = if is_databricks || is_spark {
33443 is_percent || is_rows_method || sample.unit_after_size
33445 } else if is_snowflake || is_postgres || is_presto {
33446 sample.unit_after_size
33447 } else {
33448 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
33449 };
33450
33451 if should_output_unit {
33452 self.write_space();
33453 if sample.is_percent {
33454 self.write_keyword("PERCENT");
33455 } else if is_rows_method && !sample.unit_after_size {
33456 self.write_keyword("ROWS");
33457 } else if sample.unit_after_size {
33458 match sample.method {
33459 SampleMethod::Percent
33460 | SampleMethod::System
33461 | SampleMethod::Bernoulli
33462 | SampleMethod::Block => {
33463 self.write_keyword("PERCENT");
33464 }
33465 SampleMethod::Row | SampleMethod::Reservoir => {
33466 self.write_keyword("ROWS");
33467 }
33468 _ => self.write_keyword("ROWS"),
33469 }
33470 } else {
33471 self.write_keyword("PERCENT");
33472 }
33473 }
33474
33475 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
33476 if let Some(ref offset) = sample.offset {
33477 self.write_space();
33478 self.write_keyword("OFFSET");
33479 self.write_space();
33480 self.generate_expression(offset)?;
33481 }
33482 }
33483 if !emit_size_no_parens {
33484 self.write(")");
33485 }
33486
33487 Ok(())
33488 }
33489
33490 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
33491 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
33493 self.write_keyword("SAMPLE BY");
33494 } else {
33495 self.write_keyword("SAMPLE");
33496 }
33497 self.write_space();
33498 self.generate_expression(&e.this)?;
33499 Ok(())
33500 }
33501
33502 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
33503 if let Some(this) = &e.this {
33505 self.generate_expression(this)?;
33506 }
33507 if !e.expressions.is_empty() {
33508 if e.this.is_some() {
33510 self.write_space();
33511 }
33512 self.write("(");
33513 for (i, expr) in e.expressions.iter().enumerate() {
33514 if i > 0 {
33515 self.write(", ");
33516 }
33517 self.generate_expression(expr)?;
33518 }
33519 self.write(")");
33520 }
33521 Ok(())
33522 }
33523
33524 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
33525 self.write_keyword("COMMENT");
33527 self.write_space();
33528 self.generate_expression(&e.this)?;
33529 Ok(())
33530 }
33531
33532 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
33533 if let Some(this) = &e.this {
33535 self.generate_expression(this)?;
33536 self.write("::");
33537 }
33538 self.generate_expression(&e.expression)?;
33539 Ok(())
33540 }
33541
33542 fn generate_search(&mut self, e: &Search) -> Result<()> {
33543 self.write_keyword("SEARCH");
33545 self.write("(");
33546 self.generate_expression(&e.this)?;
33547 self.write(", ");
33548 self.generate_expression(&e.expression)?;
33549 if let Some(json_scope) = &e.json_scope {
33550 self.write(", ");
33551 self.generate_expression(json_scope)?;
33552 }
33553 if let Some(analyzer) = &e.analyzer {
33554 self.write(", ");
33555 self.generate_expression(analyzer)?;
33556 }
33557 if let Some(analyzer_options) = &e.analyzer_options {
33558 self.write(", ");
33559 self.generate_expression(analyzer_options)?;
33560 }
33561 if let Some(search_mode) = &e.search_mode {
33562 self.write(", ");
33563 self.generate_expression(search_mode)?;
33564 }
33565 self.write(")");
33566 Ok(())
33567 }
33568
33569 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
33570 self.write_keyword("SEARCH_IP");
33572 self.write("(");
33573 self.generate_expression(&e.this)?;
33574 self.write(", ");
33575 self.generate_expression(&e.expression)?;
33576 self.write(")");
33577 Ok(())
33578 }
33579
33580 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
33581 self.write_keyword("SECURITY");
33583 self.write_space();
33584 self.generate_expression(&e.this)?;
33585 Ok(())
33586 }
33587
33588 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
33589 self.write("SEMANTIC_VIEW(");
33591
33592 if self.config.pretty {
33593 self.write_newline();
33595 self.indent_level += 1;
33596 self.write_indent();
33597 self.generate_expression(&e.this)?;
33598
33599 if let Some(metrics) = &e.metrics {
33600 self.write_newline();
33601 self.write_indent();
33602 self.write_keyword("METRICS");
33603 self.write_space();
33604 self.generate_semantic_view_tuple(metrics)?;
33605 }
33606 if let Some(dimensions) = &e.dimensions {
33607 self.write_newline();
33608 self.write_indent();
33609 self.write_keyword("DIMENSIONS");
33610 self.write_space();
33611 self.generate_semantic_view_tuple(dimensions)?;
33612 }
33613 if let Some(facts) = &e.facts {
33614 self.write_newline();
33615 self.write_indent();
33616 self.write_keyword("FACTS");
33617 self.write_space();
33618 self.generate_semantic_view_tuple(facts)?;
33619 }
33620 if let Some(where_) = &e.where_ {
33621 self.write_newline();
33622 self.write_indent();
33623 self.write_keyword("WHERE");
33624 self.write_space();
33625 self.generate_expression(where_)?;
33626 }
33627 self.write_newline();
33628 self.indent_level -= 1;
33629 self.write_indent();
33630 } else {
33631 self.generate_expression(&e.this)?;
33633 if let Some(metrics) = &e.metrics {
33634 self.write_space();
33635 self.write_keyword("METRICS");
33636 self.write_space();
33637 self.generate_semantic_view_tuple(metrics)?;
33638 }
33639 if let Some(dimensions) = &e.dimensions {
33640 self.write_space();
33641 self.write_keyword("DIMENSIONS");
33642 self.write_space();
33643 self.generate_semantic_view_tuple(dimensions)?;
33644 }
33645 if let Some(facts) = &e.facts {
33646 self.write_space();
33647 self.write_keyword("FACTS");
33648 self.write_space();
33649 self.generate_semantic_view_tuple(facts)?;
33650 }
33651 if let Some(where_) = &e.where_ {
33652 self.write_space();
33653 self.write_keyword("WHERE");
33654 self.write_space();
33655 self.generate_expression(where_)?;
33656 }
33657 }
33658 self.write(")");
33659 Ok(())
33660 }
33661
33662 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
33664 if let Expression::Tuple(t) = expr {
33665 for (i, e) in t.expressions.iter().enumerate() {
33666 if i > 0 {
33667 self.write(", ");
33668 }
33669 self.generate_expression(e)?;
33670 }
33671 } else {
33672 self.generate_expression(expr)?;
33673 }
33674 Ok(())
33675 }
33676
33677 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
33678 if let Some(start) = &e.start {
33680 self.write_keyword("START WITH");
33681 self.write_space();
33682 self.generate_expression(start)?;
33683 }
33684 if let Some(increment) = &e.increment {
33685 self.write_space();
33686 self.write_keyword("INCREMENT BY");
33687 self.write_space();
33688 self.generate_expression(increment)?;
33689 }
33690 if let Some(minvalue) = &e.minvalue {
33691 self.write_space();
33692 self.write_keyword("MINVALUE");
33693 self.write_space();
33694 self.generate_expression(minvalue)?;
33695 }
33696 if let Some(maxvalue) = &e.maxvalue {
33697 self.write_space();
33698 self.write_keyword("MAXVALUE");
33699 self.write_space();
33700 self.generate_expression(maxvalue)?;
33701 }
33702 if let Some(cache) = &e.cache {
33703 self.write_space();
33704 self.write_keyword("CACHE");
33705 self.write_space();
33706 self.generate_expression(cache)?;
33707 }
33708 if let Some(owned) = &e.owned {
33709 self.write_space();
33710 self.write_keyword("OWNED BY");
33711 self.write_space();
33712 self.generate_expression(owned)?;
33713 }
33714 for opt in &e.options {
33715 self.write_space();
33716 self.generate_expression(opt)?;
33717 }
33718 Ok(())
33719 }
33720
33721 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
33722 if e.with_.is_some() {
33724 self.write_keyword("WITH");
33725 self.write_space();
33726 }
33727 self.write_keyword("SERDEPROPERTIES");
33728 self.write(" (");
33729 for (i, expr) in e.expressions.iter().enumerate() {
33730 if i > 0 {
33731 self.write(", ");
33732 }
33733 match expr {
33735 Expression::Eq(eq) => {
33736 self.generate_expression(&eq.left)?;
33737 self.write("=");
33738 self.generate_expression(&eq.right)?;
33739 }
33740 _ => self.generate_expression(expr)?,
33741 }
33742 }
33743 self.write(")");
33744 Ok(())
33745 }
33746
33747 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
33748 self.write("@@");
33750 if let Some(kind) = &e.kind {
33751 self.write(kind);
33752 self.write(".");
33753 }
33754 self.generate_expression(&e.this)?;
33755 Ok(())
33756 }
33757
33758 fn generate_set(&mut self, e: &Set) -> Result<()> {
33759 if e.unset.is_some() {
33761 self.write_keyword("UNSET");
33762 } else {
33763 self.write_keyword("SET");
33764 }
33765 if e.tag.is_some() {
33766 self.write_space();
33767 self.write_keyword("TAG");
33768 }
33769 if !e.expressions.is_empty() {
33770 self.write_space();
33771 for (i, expr) in e.expressions.iter().enumerate() {
33772 if i > 0 {
33773 self.write(", ");
33774 }
33775 self.generate_expression(expr)?;
33776 }
33777 }
33778 Ok(())
33779 }
33780
33781 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
33782 self.write_keyword("SET");
33784 self.write_space();
33785 self.generate_expression(&e.this)?;
33786 Ok(())
33787 }
33788
33789 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
33790 if let Some(kind) = &e.kind {
33792 self.write_keyword(kind);
33793 self.write_space();
33794 }
33795 self.generate_expression(&e.name)?;
33796 self.write(" = ");
33797 self.generate_expression(&e.value)?;
33798 Ok(())
33799 }
33800
33801 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
33802 if let Some(with_) = &e.with_ {
33804 self.generate_expression(with_)?;
33805 self.write_space();
33806 }
33807 self.generate_expression(&e.this)?;
33808 self.write_space();
33809 if let Some(kind) = &e.kind {
33811 self.write_keyword(kind);
33812 }
33813 if e.distinct {
33814 self.write_space();
33815 self.write_keyword("DISTINCT");
33816 } else {
33817 self.write_space();
33818 self.write_keyword("ALL");
33819 }
33820 if e.by_name.is_some() {
33821 self.write_space();
33822 self.write_keyword("BY NAME");
33823 }
33824 self.write_space();
33825 self.generate_expression(&e.expression)?;
33826 Ok(())
33827 }
33828
33829 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
33830 if e.multi.is_some() {
33832 self.write_keyword("MULTISET");
33833 } else {
33834 self.write_keyword("SET");
33835 }
33836 Ok(())
33837 }
33838
33839 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
33840 self.write_keyword("SETTINGS");
33842 if self.config.pretty && e.expressions.len() > 1 {
33843 self.indent_level += 1;
33845 for (i, expr) in e.expressions.iter().enumerate() {
33846 if i > 0 {
33847 self.write(",");
33848 }
33849 self.write_newline();
33850 self.write_indent();
33851 self.generate_expression(expr)?;
33852 }
33853 self.indent_level -= 1;
33854 } else {
33855 self.write_space();
33856 for (i, expr) in e.expressions.iter().enumerate() {
33857 if i > 0 {
33858 self.write(", ");
33859 }
33860 self.generate_expression(expr)?;
33861 }
33862 }
33863 Ok(())
33864 }
33865
33866 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
33867 self.write_keyword("SHARING");
33869 if let Some(this) = &e.this {
33870 self.write(" = ");
33871 self.generate_expression(this)?;
33872 }
33873 Ok(())
33874 }
33875
33876 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
33877 if let Some(begin) = &e.this {
33879 self.generate_expression(begin)?;
33880 }
33881 self.write(":");
33882 if let Some(end) = &e.expression {
33883 self.generate_expression(end)?;
33884 }
33885 if let Some(step) = &e.step {
33886 self.write(":");
33887 self.generate_expression(step)?;
33888 }
33889 Ok(())
33890 }
33891
33892 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
33893 self.write_keyword("SORT_ARRAY");
33895 self.write("(");
33896 self.generate_expression(&e.this)?;
33897 if let Some(asc) = &e.asc {
33898 self.write(", ");
33899 self.generate_expression(asc)?;
33900 }
33901 self.write(")");
33902 Ok(())
33903 }
33904
33905 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
33906 self.write_keyword("SORT BY");
33908 self.write_space();
33909 for (i, expr) in e.expressions.iter().enumerate() {
33910 if i > 0 {
33911 self.write(", ");
33912 }
33913 self.generate_ordered(expr)?;
33914 }
33915 Ok(())
33916 }
33917
33918 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
33919 if e.compound.is_some() {
33921 self.write_keyword("COMPOUND");
33922 self.write_space();
33923 }
33924 self.write_keyword("SORTKEY");
33925 self.write("(");
33926 if let Expression::Tuple(t) = e.this.as_ref() {
33928 for (i, expr) in t.expressions.iter().enumerate() {
33929 if i > 0 {
33930 self.write(", ");
33931 }
33932 self.generate_expression(expr)?;
33933 }
33934 } else {
33935 self.generate_expression(&e.this)?;
33936 }
33937 self.write(")");
33938 Ok(())
33939 }
33940
33941 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
33942 self.write_keyword("SPLIT_PART");
33944 self.write("(");
33945 self.generate_expression(&e.this)?;
33946 if let Some(delimiter) = &e.delimiter {
33947 self.write(", ");
33948 self.generate_expression(delimiter)?;
33949 }
33950 if let Some(part_index) = &e.part_index {
33951 self.write(", ");
33952 self.generate_expression(part_index)?;
33953 }
33954 self.write(")");
33955 Ok(())
33956 }
33957
33958 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
33959 self.generate_expression(&e.this)?;
33961 Ok(())
33962 }
33963
33964 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
33965 self.write_keyword("SQL SECURITY");
33967 self.write_space();
33968 self.generate_expression(&e.this)?;
33969 Ok(())
33970 }
33971
33972 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
33973 self.write_keyword("ST_DISTANCE");
33975 self.write("(");
33976 self.generate_expression(&e.this)?;
33977 self.write(", ");
33978 self.generate_expression(&e.expression)?;
33979 if let Some(use_spheroid) = &e.use_spheroid {
33980 self.write(", ");
33981 self.generate_expression(use_spheroid)?;
33982 }
33983 self.write(")");
33984 Ok(())
33985 }
33986
33987 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
33988 self.write_keyword("ST_POINT");
33990 self.write("(");
33991 self.generate_expression(&e.this)?;
33992 self.write(", ");
33993 self.generate_expression(&e.expression)?;
33994 self.write(")");
33995 Ok(())
33996 }
33997
33998 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
33999 self.generate_expression(&e.this)?;
34001 Ok(())
34002 }
34003
34004 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
34005 self.write_keyword("STANDARD_HASH");
34007 self.write("(");
34008 self.generate_expression(&e.this)?;
34009 if let Some(expression) = &e.expression {
34010 self.write(", ");
34011 self.generate_expression(expression)?;
34012 }
34013 self.write(")");
34014 Ok(())
34015 }
34016
34017 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
34018 self.write_keyword("STORED BY");
34020 self.write_space();
34021 self.generate_expression(&e.this)?;
34022 Ok(())
34023 }
34024
34025 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
34026 use crate::dialects::DialectType;
34029 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
34030 self.write_keyword("CHARINDEX");
34032 self.write("(");
34033 if let Some(substr) = &e.substr {
34034 self.generate_expression(substr)?;
34035 self.write(", ");
34036 }
34037 self.generate_expression(&e.this)?;
34038 if let Some(position) = &e.position {
34039 self.write(", ");
34040 self.generate_expression(position)?;
34041 }
34042 self.write(")");
34043 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34044 self.write_keyword("POSITION");
34045 self.write("(");
34046 self.generate_expression(&e.this)?;
34047 if let Some(substr) = &e.substr {
34048 self.write(", ");
34049 self.generate_expression(substr)?;
34050 }
34051 if let Some(position) = &e.position {
34052 self.write(", ");
34053 self.generate_expression(position)?;
34054 }
34055 if let Some(occurrence) = &e.occurrence {
34056 self.write(", ");
34057 self.generate_expression(occurrence)?;
34058 }
34059 self.write(")");
34060 } else if matches!(
34061 self.config.dialect,
34062 Some(DialectType::SQLite)
34063 | Some(DialectType::Oracle)
34064 | Some(DialectType::BigQuery)
34065 | Some(DialectType::Teradata)
34066 ) {
34067 self.write_keyword("INSTR");
34068 self.write("(");
34069 self.generate_expression(&e.this)?;
34070 if let Some(substr) = &e.substr {
34071 self.write(", ");
34072 self.generate_expression(substr)?;
34073 }
34074 if let Some(position) = &e.position {
34075 self.write(", ");
34076 self.generate_expression(position)?;
34077 } else if e.occurrence.is_some() {
34078 self.write(", 1");
34081 }
34082 if let Some(occurrence) = &e.occurrence {
34083 self.write(", ");
34084 self.generate_expression(occurrence)?;
34085 }
34086 self.write(")");
34087 } else if matches!(
34088 self.config.dialect,
34089 Some(DialectType::MySQL)
34090 | Some(DialectType::SingleStore)
34091 | Some(DialectType::Doris)
34092 | Some(DialectType::StarRocks)
34093 | Some(DialectType::Hive)
34094 | Some(DialectType::Spark)
34095 | Some(DialectType::Databricks)
34096 ) {
34097 self.write_keyword("LOCATE");
34099 self.write("(");
34100 if let Some(substr) = &e.substr {
34101 self.generate_expression(substr)?;
34102 self.write(", ");
34103 }
34104 self.generate_expression(&e.this)?;
34105 if let Some(position) = &e.position {
34106 self.write(", ");
34107 self.generate_expression(position)?;
34108 }
34109 self.write(")");
34110 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
34111 self.write_keyword("CHARINDEX");
34113 self.write("(");
34114 if let Some(substr) = &e.substr {
34115 self.generate_expression(substr)?;
34116 self.write(", ");
34117 }
34118 self.generate_expression(&e.this)?;
34119 if let Some(position) = &e.position {
34120 self.write(", ");
34121 self.generate_expression(position)?;
34122 }
34123 self.write(")");
34124 } else if matches!(
34125 self.config.dialect,
34126 Some(DialectType::PostgreSQL)
34127 | Some(DialectType::Materialize)
34128 | Some(DialectType::RisingWave)
34129 | Some(DialectType::Redshift)
34130 ) {
34131 self.write_keyword("POSITION");
34133 self.write("(");
34134 if let Some(substr) = &e.substr {
34135 self.generate_expression(substr)?;
34136 self.write(" IN ");
34137 }
34138 self.generate_expression(&e.this)?;
34139 self.write(")");
34140 } else {
34141 self.write_keyword("STRPOS");
34142 self.write("(");
34143 self.generate_expression(&e.this)?;
34144 if let Some(substr) = &e.substr {
34145 self.write(", ");
34146 self.generate_expression(substr)?;
34147 }
34148 if let Some(position) = &e.position {
34149 self.write(", ");
34150 self.generate_expression(position)?;
34151 }
34152 if let Some(occurrence) = &e.occurrence {
34153 self.write(", ");
34154 self.generate_expression(occurrence)?;
34155 }
34156 self.write(")");
34157 }
34158 Ok(())
34159 }
34160
34161 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
34162 match self.config.dialect {
34163 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
34164 self.write_keyword("TO_DATE");
34166 self.write("(");
34167 self.generate_expression(&e.this)?;
34168 if let Some(format) = &e.format {
34169 self.write(", '");
34170 self.write(&Self::strftime_to_java_format(format));
34171 self.write("'");
34172 }
34173 self.write(")");
34174 }
34175 Some(DialectType::DuckDB) => {
34176 self.write_keyword("CAST");
34178 self.write("(");
34179 self.write_keyword("STRPTIME");
34180 self.write("(");
34181 self.generate_expression(&e.this)?;
34182 if let Some(format) = &e.format {
34183 self.write(", '");
34184 self.write(format);
34185 self.write("'");
34186 }
34187 self.write(")");
34188 self.write_keyword(" AS ");
34189 self.write_keyword("DATE");
34190 self.write(")");
34191 }
34192 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
34193 self.write_keyword("TO_DATE");
34195 self.write("(");
34196 self.generate_expression(&e.this)?;
34197 if let Some(format) = &e.format {
34198 self.write(", '");
34199 self.write(&Self::strftime_to_postgres_format(format));
34200 self.write("'");
34201 }
34202 self.write(")");
34203 }
34204 Some(DialectType::BigQuery) => {
34205 self.write_keyword("PARSE_DATE");
34207 self.write("(");
34208 if let Some(format) = &e.format {
34209 self.write("'");
34210 self.write(format);
34211 self.write("'");
34212 self.write(", ");
34213 }
34214 self.generate_expression(&e.this)?;
34215 self.write(")");
34216 }
34217 Some(DialectType::Teradata) => {
34218 self.write_keyword("CAST");
34220 self.write("(");
34221 self.generate_expression(&e.this)?;
34222 self.write_keyword(" AS ");
34223 self.write_keyword("DATE");
34224 if let Some(format) = &e.format {
34225 self.write_keyword(" FORMAT ");
34226 self.write("'");
34227 self.write(&Self::strftime_to_teradata_format(format));
34228 self.write("'");
34229 }
34230 self.write(")");
34231 }
34232 _ => {
34233 self.write_keyword("STR_TO_DATE");
34235 self.write("(");
34236 self.generate_expression(&e.this)?;
34237 if let Some(format) = &e.format {
34238 self.write(", '");
34239 self.write(format);
34240 self.write("'");
34241 }
34242 self.write(")");
34243 }
34244 }
34245 Ok(())
34246 }
34247
34248 fn strftime_to_teradata_format(fmt: &str) -> String {
34250 let mut result = String::with_capacity(fmt.len() * 2);
34251 let bytes = fmt.as_bytes();
34252 let len = bytes.len();
34253 let mut i = 0;
34254 while i < len {
34255 if bytes[i] == b'%' && i + 1 < len {
34256 let replacement = match bytes[i + 1] {
34257 b'Y' => "YYYY",
34258 b'y' => "YY",
34259 b'm' => "MM",
34260 b'B' => "MMMM",
34261 b'b' => "MMM",
34262 b'd' => "DD",
34263 b'j' => "DDD",
34264 b'H' => "HH",
34265 b'M' => "MI",
34266 b'S' => "SS",
34267 b'f' => "SSSSSS",
34268 b'A' => "EEEE",
34269 b'a' => "EEE",
34270 _ => {
34271 result.push('%');
34272 i += 1;
34273 continue;
34274 }
34275 };
34276 result.push_str(replacement);
34277 i += 2;
34278 } else {
34279 result.push(bytes[i] as char);
34280 i += 1;
34281 }
34282 }
34283 result
34284 }
34285
34286 pub fn strftime_to_java_format_static(fmt: &str) -> String {
34289 Self::strftime_to_java_format(fmt)
34290 }
34291
34292 fn strftime_to_java_format(fmt: &str) -> String {
34294 let mut result = String::with_capacity(fmt.len() * 2);
34295 let bytes = fmt.as_bytes();
34296 let len = bytes.len();
34297 let mut i = 0;
34298 while i < len {
34299 if bytes[i] == b'%' && i + 1 < len {
34300 if bytes[i + 1] == b'-' && i + 2 < len {
34302 let replacement = match bytes[i + 2] {
34303 b'd' => "d",
34304 b'm' => "M",
34305 b'H' => "H",
34306 b'M' => "m",
34307 b'S' => "s",
34308 _ => {
34309 result.push('%');
34310 i += 1;
34311 continue;
34312 }
34313 };
34314 result.push_str(replacement);
34315 i += 3;
34316 } else {
34317 let replacement = match bytes[i + 1] {
34318 b'Y' => "yyyy",
34319 b'y' => "yy",
34320 b'm' => "MM",
34321 b'B' => "MMMM",
34322 b'b' => "MMM",
34323 b'd' => "dd",
34324 b'j' => "DDD",
34325 b'H' => "HH",
34326 b'M' => "mm",
34327 b'S' => "ss",
34328 b'f' => "SSSSSS",
34329 b'A' => "EEEE",
34330 b'a' => "EEE",
34331 _ => {
34332 result.push('%');
34333 i += 1;
34334 continue;
34335 }
34336 };
34337 result.push_str(replacement);
34338 i += 2;
34339 }
34340 } else {
34341 result.push(bytes[i] as char);
34342 i += 1;
34343 }
34344 }
34345 result
34346 }
34347
34348 fn strftime_to_tsql_format(fmt: &str) -> String {
34351 let mut result = String::with_capacity(fmt.len() * 2);
34352 let bytes = fmt.as_bytes();
34353 let len = bytes.len();
34354 let mut i = 0;
34355 while i < len {
34356 if bytes[i] == b'%' && i + 1 < len {
34357 if bytes[i + 1] == b'-' && i + 2 < len {
34359 let replacement = match bytes[i + 2] {
34360 b'd' => "d",
34361 b'm' => "M",
34362 b'H' => "H",
34363 b'M' => "m",
34364 b'S' => "s",
34365 _ => {
34366 result.push('%');
34367 i += 1;
34368 continue;
34369 }
34370 };
34371 result.push_str(replacement);
34372 i += 3;
34373 } else {
34374 let replacement = match bytes[i + 1] {
34375 b'Y' => "yyyy",
34376 b'y' => "yy",
34377 b'm' => "MM",
34378 b'B' => "MMMM",
34379 b'b' => "MMM",
34380 b'd' => "dd",
34381 b'j' => "DDD",
34382 b'H' => "HH",
34383 b'M' => "mm",
34384 b'S' => "ss",
34385 b'f' => "ffffff",
34386 b'A' => "dddd",
34387 b'a' => "ddd",
34388 _ => {
34389 result.push('%');
34390 i += 1;
34391 continue;
34392 }
34393 };
34394 result.push_str(replacement);
34395 i += 2;
34396 }
34397 } else {
34398 result.push(bytes[i] as char);
34399 i += 1;
34400 }
34401 }
34402 result
34403 }
34404
34405 fn decompose_json_path(path: &str) -> Vec<String> {
34408 let mut parts = Vec::new();
34409 let path = if path.starts_with("$.") {
34411 &path[2..]
34412 } else if path.starts_with('$') {
34413 &path[1..]
34414 } else {
34415 path
34416 };
34417 if path.is_empty() {
34418 return parts;
34419 }
34420 let mut current = String::new();
34421 let chars: Vec<char> = path.chars().collect();
34422 let mut i = 0;
34423 while i < chars.len() {
34424 match chars[i] {
34425 '.' => {
34426 if !current.is_empty() {
34427 parts.push(current.clone());
34428 current.clear();
34429 }
34430 i += 1;
34431 }
34432 '[' => {
34433 if !current.is_empty() {
34434 parts.push(current.clone());
34435 current.clear();
34436 }
34437 i += 1;
34438 let mut bracket_content = String::new();
34440 while i < chars.len() && chars[i] != ']' {
34441 if chars[i] == '"' || chars[i] == '\'' {
34443 let quote = chars[i];
34444 i += 1;
34445 while i < chars.len() && chars[i] != quote {
34446 bracket_content.push(chars[i]);
34447 i += 1;
34448 }
34449 if i < chars.len() {
34450 i += 1;
34451 } } else {
34453 bracket_content.push(chars[i]);
34454 i += 1;
34455 }
34456 }
34457 if i < chars.len() {
34458 i += 1;
34459 } if bracket_content != "*" {
34462 parts.push(bracket_content);
34463 }
34464 }
34465 _ => {
34466 current.push(chars[i]);
34467 i += 1;
34468 }
34469 }
34470 }
34471 if !current.is_empty() {
34472 parts.push(current);
34473 }
34474 parts
34475 }
34476
34477 fn strftime_to_postgres_format(fmt: &str) -> String {
34479 let mut result = String::with_capacity(fmt.len() * 2);
34480 let bytes = fmt.as_bytes();
34481 let len = bytes.len();
34482 let mut i = 0;
34483 while i < len {
34484 if bytes[i] == b'%' && i + 1 < len {
34485 if bytes[i + 1] == b'-' && i + 2 < len {
34487 let replacement = match bytes[i + 2] {
34488 b'd' => "FMDD",
34489 b'm' => "FMMM",
34490 b'H' => "FMHH24",
34491 b'M' => "FMMI",
34492 b'S' => "FMSS",
34493 _ => {
34494 result.push('%');
34495 i += 1;
34496 continue;
34497 }
34498 };
34499 result.push_str(replacement);
34500 i += 3;
34501 } else {
34502 let replacement = match bytes[i + 1] {
34503 b'Y' => "YYYY",
34504 b'y' => "YY",
34505 b'm' => "MM",
34506 b'B' => "Month",
34507 b'b' => "Mon",
34508 b'd' => "DD",
34509 b'j' => "DDD",
34510 b'H' => "HH24",
34511 b'M' => "MI",
34512 b'S' => "SS",
34513 b'f' => "US",
34514 b'A' => "Day",
34515 b'a' => "Dy",
34516 _ => {
34517 result.push('%');
34518 i += 1;
34519 continue;
34520 }
34521 };
34522 result.push_str(replacement);
34523 i += 2;
34524 }
34525 } else {
34526 result.push(bytes[i] as char);
34527 i += 1;
34528 }
34529 }
34530 result
34531 }
34532
34533 fn strftime_to_snowflake_format(fmt: &str) -> String {
34535 let mut result = String::with_capacity(fmt.len() * 2);
34536 let bytes = fmt.as_bytes();
34537 let len = bytes.len();
34538 let mut i = 0;
34539 while i < len {
34540 if bytes[i] == b'%' && i + 1 < len {
34541 if bytes[i + 1] == b'-' && i + 2 < len {
34543 let replacement = match bytes[i + 2] {
34544 b'd' => "dd",
34545 b'm' => "mm",
34546 _ => {
34547 result.push('%');
34548 i += 1;
34549 continue;
34550 }
34551 };
34552 result.push_str(replacement);
34553 i += 3;
34554 } else {
34555 let replacement = match bytes[i + 1] {
34556 b'Y' => "yyyy",
34557 b'y' => "yy",
34558 b'm' => "mm",
34559 b'd' => "DD",
34560 b'H' => "hh24",
34561 b'M' => "mi",
34562 b'S' => "ss",
34563 b'f' => "ff",
34564 _ => {
34565 result.push('%');
34566 i += 1;
34567 continue;
34568 }
34569 };
34570 result.push_str(replacement);
34571 i += 2;
34572 }
34573 } else {
34574 result.push(bytes[i] as char);
34575 i += 1;
34576 }
34577 }
34578 result
34579 }
34580
34581 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
34582 self.write_keyword("STR_TO_MAP");
34584 self.write("(");
34585 self.generate_expression(&e.this)?;
34586 let needs_defaults = matches!(
34588 self.config.dialect,
34589 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
34590 );
34591 if let Some(pair_delim) = &e.pair_delim {
34592 self.write(", ");
34593 self.generate_expression(pair_delim)?;
34594 } else if needs_defaults {
34595 self.write(", ','");
34596 }
34597 if let Some(key_value_delim) = &e.key_value_delim {
34598 self.write(", ");
34599 self.generate_expression(key_value_delim)?;
34600 } else if needs_defaults {
34601 self.write(", ':'");
34602 }
34603 self.write(")");
34604 Ok(())
34605 }
34606
34607 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
34608 let is_strftime = e.format.contains('%');
34610 let to_strftime = |f: &str| -> String {
34612 if is_strftime {
34613 f.to_string()
34614 } else {
34615 Self::snowflake_format_to_strftime(f)
34616 }
34617 };
34618 let to_java = |f: &str| -> String {
34620 if is_strftime {
34621 Self::strftime_to_java_format(f)
34622 } else {
34623 Self::snowflake_format_to_spark(f)
34624 }
34625 };
34626 let to_pg = |f: &str| -> String {
34628 if is_strftime {
34629 Self::strftime_to_postgres_format(f)
34630 } else {
34631 Self::convert_strptime_to_postgres_format(f)
34632 }
34633 };
34634
34635 match self.config.dialect {
34636 Some(DialectType::Exasol) => {
34637 self.write_keyword("TO_DATE");
34638 self.write("(");
34639 self.generate_expression(&e.this)?;
34640 self.write(", '");
34641 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
34642 self.write("'");
34643 self.write(")");
34644 }
34645 Some(DialectType::BigQuery) => {
34646 let fmt = to_strftime(&e.format);
34648 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
34650 self.write_keyword("PARSE_TIMESTAMP");
34651 self.write("('");
34652 self.write(&fmt);
34653 self.write("', ");
34654 self.generate_expression(&e.this)?;
34655 self.write(")");
34656 }
34657 Some(DialectType::Hive) => {
34658 let java_fmt = to_java(&e.format);
34661 if java_fmt == "yyyy-MM-dd HH:mm:ss"
34662 || java_fmt == "yyyy-MM-dd"
34663 || e.format == "yyyy-MM-dd HH:mm:ss"
34664 || e.format == "yyyy-MM-dd"
34665 {
34666 self.write_keyword("CAST");
34667 self.write("(");
34668 self.generate_expression(&e.this)?;
34669 self.write(" ");
34670 self.write_keyword("AS TIMESTAMP");
34671 self.write(")");
34672 } else {
34673 self.write_keyword("CAST");
34675 self.write("(");
34676 self.write_keyword("FROM_UNIXTIME");
34677 self.write("(");
34678 self.write_keyword("UNIX_TIMESTAMP");
34679 self.write("(");
34680 self.generate_expression(&e.this)?;
34681 self.write(", '");
34682 self.write(&java_fmt);
34683 self.write("')");
34684 self.write(") ");
34685 self.write_keyword("AS TIMESTAMP");
34686 self.write(")");
34687 }
34688 }
34689 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
34690 let java_fmt = to_java(&e.format);
34692 self.write_keyword("TO_TIMESTAMP");
34693 self.write("(");
34694 self.generate_expression(&e.this)?;
34695 self.write(", '");
34696 self.write(&java_fmt);
34697 self.write("')");
34698 }
34699 Some(DialectType::MySQL) => {
34700 let mut fmt = to_strftime(&e.format);
34702 fmt = fmt.replace("%-d", "%e");
34704 fmt = fmt.replace("%-m", "%c");
34705 fmt = fmt.replace("%H:%M:%S", "%T");
34706 self.write_keyword("STR_TO_DATE");
34707 self.write("(");
34708 self.generate_expression(&e.this)?;
34709 self.write(", '");
34710 self.write(&fmt);
34711 self.write("')");
34712 }
34713 Some(DialectType::Drill) => {
34714 let java_fmt = to_java(&e.format);
34716 let java_fmt = java_fmt.replace('T', "''T''");
34718 self.write_keyword("TO_TIMESTAMP");
34719 self.write("(");
34720 self.generate_expression(&e.this)?;
34721 self.write(", '");
34722 self.write(&java_fmt);
34723 self.write("')");
34724 }
34725 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
34726 let mut fmt = to_strftime(&e.format);
34728 fmt = fmt.replace("%-d", "%e");
34730 fmt = fmt.replace("%-m", "%c");
34731 fmt = fmt.replace("%H:%M:%S", "%T");
34732 self.write_keyword("DATE_PARSE");
34733 self.write("(");
34734 self.generate_expression(&e.this)?;
34735 self.write(", '");
34736 self.write(&fmt);
34737 self.write("')");
34738 }
34739 Some(DialectType::DuckDB) => {
34740 let fmt = to_strftime(&e.format);
34742 self.write_keyword("STRPTIME");
34743 self.write("(");
34744 self.generate_expression(&e.this)?;
34745 self.write(", '");
34746 self.write(&fmt);
34747 self.write("')");
34748 }
34749 Some(DialectType::PostgreSQL)
34750 | Some(DialectType::Redshift)
34751 | Some(DialectType::Materialize) => {
34752 let pg_fmt = to_pg(&e.format);
34754 self.write_keyword("TO_TIMESTAMP");
34755 self.write("(");
34756 self.generate_expression(&e.this)?;
34757 self.write(", '");
34758 self.write(&pg_fmt);
34759 self.write("')");
34760 }
34761 Some(DialectType::Oracle) => {
34762 let pg_fmt = to_pg(&e.format);
34764 self.write_keyword("TO_TIMESTAMP");
34765 self.write("(");
34766 self.generate_expression(&e.this)?;
34767 self.write(", '");
34768 self.write(&pg_fmt);
34769 self.write("')");
34770 }
34771 Some(DialectType::Snowflake) => {
34772 self.write_keyword("TO_TIMESTAMP");
34774 self.write("(");
34775 self.generate_expression(&e.this)?;
34776 self.write(", '");
34777 self.write(&e.format);
34778 self.write("')");
34779 }
34780 _ => {
34781 self.write_keyword("STR_TO_TIME");
34783 self.write("(");
34784 self.generate_expression(&e.this)?;
34785 self.write(", '");
34786 self.write(&e.format);
34787 self.write("'");
34788 self.write(")");
34789 }
34790 }
34791 Ok(())
34792 }
34793
34794 fn snowflake_format_to_strftime(format: &str) -> String {
34796 let mut result = String::new();
34797 let chars: Vec<char> = format.chars().collect();
34798 let mut i = 0;
34799 while i < chars.len() {
34800 let remaining = &format[i..];
34801 if remaining.starts_with("yyyy") {
34802 result.push_str("%Y");
34803 i += 4;
34804 } else if remaining.starts_with("yy") {
34805 result.push_str("%y");
34806 i += 2;
34807 } else if remaining.starts_with("mmmm") {
34808 result.push_str("%B"); i += 4;
34810 } else if remaining.starts_with("mon") {
34811 result.push_str("%b"); i += 3;
34813 } else if remaining.starts_with("mm") {
34814 result.push_str("%m");
34815 i += 2;
34816 } else if remaining.starts_with("DD") {
34817 result.push_str("%d");
34818 i += 2;
34819 } else if remaining.starts_with("dy") {
34820 result.push_str("%a"); i += 2;
34822 } else if remaining.starts_with("hh24") {
34823 result.push_str("%H");
34824 i += 4;
34825 } else if remaining.starts_with("hh12") {
34826 result.push_str("%I");
34827 i += 4;
34828 } else if remaining.starts_with("hh") {
34829 result.push_str("%H");
34830 i += 2;
34831 } else if remaining.starts_with("mi") {
34832 result.push_str("%M");
34833 i += 2;
34834 } else if remaining.starts_with("ss") {
34835 result.push_str("%S");
34836 i += 2;
34837 } else if remaining.starts_with("ff") {
34838 result.push_str("%f");
34840 i += 2;
34841 while i < chars.len() && chars[i].is_ascii_digit() {
34843 i += 1;
34844 }
34845 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
34846 result.push_str("%p");
34847 i += 2;
34848 } else if remaining.starts_with("tz") {
34849 result.push_str("%Z");
34850 i += 2;
34851 } else {
34852 result.push(chars[i]);
34853 i += 1;
34854 }
34855 }
34856 result
34857 }
34858
34859 fn snowflake_format_to_spark(format: &str) -> String {
34861 let mut result = String::new();
34862 let chars: Vec<char> = format.chars().collect();
34863 let mut i = 0;
34864 while i < chars.len() {
34865 let remaining = &format[i..];
34866 if remaining.starts_with("yyyy") {
34867 result.push_str("yyyy");
34868 i += 4;
34869 } else if remaining.starts_with("yy") {
34870 result.push_str("yy");
34871 i += 2;
34872 } else if remaining.starts_with("mmmm") {
34873 result.push_str("MMMM"); i += 4;
34875 } else if remaining.starts_with("mon") {
34876 result.push_str("MMM"); i += 3;
34878 } else if remaining.starts_with("mm") {
34879 result.push_str("MM");
34880 i += 2;
34881 } else if remaining.starts_with("DD") {
34882 result.push_str("dd");
34883 i += 2;
34884 } else if remaining.starts_with("dy") {
34885 result.push_str("EEE"); i += 2;
34887 } else if remaining.starts_with("hh24") {
34888 result.push_str("HH");
34889 i += 4;
34890 } else if remaining.starts_with("hh12") {
34891 result.push_str("hh");
34892 i += 4;
34893 } else if remaining.starts_with("hh") {
34894 result.push_str("HH");
34895 i += 2;
34896 } else if remaining.starts_with("mi") {
34897 result.push_str("mm");
34898 i += 2;
34899 } else if remaining.starts_with("ss") {
34900 result.push_str("ss");
34901 i += 2;
34902 } else if remaining.starts_with("ff") {
34903 result.push_str("SSS"); i += 2;
34905 while i < chars.len() && chars[i].is_ascii_digit() {
34907 i += 1;
34908 }
34909 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
34910 result.push_str("a");
34911 i += 2;
34912 } else if remaining.starts_with("tz") {
34913 result.push_str("z");
34914 i += 2;
34915 } else {
34916 result.push(chars[i]);
34917 i += 1;
34918 }
34919 }
34920 result
34921 }
34922
34923 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
34924 match self.config.dialect {
34925 Some(DialectType::DuckDB) => {
34926 self.write_keyword("EPOCH");
34928 self.write("(");
34929 self.write_keyword("STRPTIME");
34930 self.write("(");
34931 if let Some(this) = &e.this {
34932 self.generate_expression(this)?;
34933 }
34934 if let Some(format) = &e.format {
34935 self.write(", '");
34936 self.write(format);
34937 self.write("'");
34938 }
34939 self.write("))");
34940 }
34941 Some(DialectType::Hive) => {
34942 self.write_keyword("UNIX_TIMESTAMP");
34944 self.write("(");
34945 if let Some(this) = &e.this {
34946 self.generate_expression(this)?;
34947 }
34948 if let Some(format) = &e.format {
34949 let java_fmt = Self::strftime_to_java_format(format);
34950 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
34951 self.write(", '");
34952 self.write(&java_fmt);
34953 self.write("'");
34954 }
34955 }
34956 self.write(")");
34957 }
34958 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
34959 self.write_keyword("UNIX_TIMESTAMP");
34961 self.write("(");
34962 if let Some(this) = &e.this {
34963 self.generate_expression(this)?;
34964 }
34965 if let Some(format) = &e.format {
34966 self.write(", '");
34967 self.write(format);
34968 self.write("'");
34969 }
34970 self.write(")");
34971 }
34972 Some(DialectType::Presto) | Some(DialectType::Trino) => {
34973 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
34976 let java_fmt = Self::strftime_to_java_format(c_fmt);
34977 self.write_keyword("TO_UNIXTIME");
34978 self.write("(");
34979 self.write_keyword("COALESCE");
34980 self.write("(");
34981 self.write_keyword("TRY");
34982 self.write("(");
34983 self.write_keyword("DATE_PARSE");
34984 self.write("(");
34985 self.write_keyword("CAST");
34986 self.write("(");
34987 if let Some(this) = &e.this {
34988 self.generate_expression(this)?;
34989 }
34990 self.write(" ");
34991 self.write_keyword("AS VARCHAR");
34992 self.write("), '");
34993 self.write(c_fmt);
34994 self.write("')), ");
34995 self.write_keyword("PARSE_DATETIME");
34996 self.write("(");
34997 self.write_keyword("DATE_FORMAT");
34998 self.write("(");
34999 self.write_keyword("CAST");
35000 self.write("(");
35001 if let Some(this) = &e.this {
35002 self.generate_expression(this)?;
35003 }
35004 self.write(" ");
35005 self.write_keyword("AS TIMESTAMP");
35006 self.write("), '");
35007 self.write(c_fmt);
35008 self.write("'), '");
35009 self.write(&java_fmt);
35010 self.write("')))");
35011 }
35012 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35013 self.write_keyword("UNIX_TIMESTAMP");
35015 self.write("(");
35016 if let Some(this) = &e.this {
35017 self.generate_expression(this)?;
35018 }
35019 if let Some(format) = &e.format {
35020 let java_fmt = Self::strftime_to_java_format(format);
35021 self.write(", '");
35022 self.write(&java_fmt);
35023 self.write("'");
35024 }
35025 self.write(")");
35026 }
35027 _ => {
35028 self.write_keyword("STR_TO_UNIX");
35030 self.write("(");
35031 if let Some(this) = &e.this {
35032 self.generate_expression(this)?;
35033 }
35034 if let Some(format) = &e.format {
35035 self.write(", '");
35036 self.write(format);
35037 self.write("'");
35038 }
35039 self.write(")");
35040 }
35041 }
35042 Ok(())
35043 }
35044
35045 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
35046 self.write_keyword("STRING_TO_ARRAY");
35048 self.write("(");
35049 self.generate_expression(&e.this)?;
35050 if let Some(expression) = &e.expression {
35051 self.write(", ");
35052 self.generate_expression(expression)?;
35053 }
35054 if let Some(null_val) = &e.null {
35055 self.write(", ");
35056 self.generate_expression(null_val)?;
35057 }
35058 self.write(")");
35059 Ok(())
35060 }
35061
35062 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
35063 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35064 self.write_keyword("OBJECT_CONSTRUCT");
35066 self.write("(");
35067 for (i, (name, expr)) in e.fields.iter().enumerate() {
35068 if i > 0 {
35069 self.write(", ");
35070 }
35071 if let Some(name) = name {
35072 self.write("'");
35073 self.write(name);
35074 self.write("'");
35075 self.write(", ");
35076 } else {
35077 self.write("'_");
35078 self.write(&i.to_string());
35079 self.write("'");
35080 self.write(", ");
35081 }
35082 self.generate_expression(expr)?;
35083 }
35084 self.write(")");
35085 } else if self.config.struct_curly_brace_notation {
35086 self.write("{");
35088 for (i, (name, expr)) in e.fields.iter().enumerate() {
35089 if i > 0 {
35090 self.write(", ");
35091 }
35092 if let Some(name) = name {
35093 self.write("'");
35095 self.write(name);
35096 self.write("'");
35097 self.write(": ");
35098 } else {
35099 self.write("'_");
35101 self.write(&i.to_string());
35102 self.write("'");
35103 self.write(": ");
35104 }
35105 self.generate_expression(expr)?;
35106 }
35107 self.write("}");
35108 } else {
35109 let value_as_name = matches!(
35113 self.config.dialect,
35114 Some(DialectType::BigQuery)
35115 | Some(DialectType::Spark)
35116 | Some(DialectType::Databricks)
35117 | Some(DialectType::Hive)
35118 );
35119 self.write_keyword("STRUCT");
35120 self.write("(");
35121 for (i, (name, expr)) in e.fields.iter().enumerate() {
35122 if i > 0 {
35123 self.write(", ");
35124 }
35125 if let Some(name) = name {
35126 if value_as_name {
35127 self.generate_expression(expr)?;
35129 self.write_space();
35130 self.write_keyword("AS");
35131 self.write_space();
35132 let needs_quoting = name.contains(' ') || name.contains('-');
35134 if needs_quoting {
35135 if matches!(
35136 self.config.dialect,
35137 Some(DialectType::Spark)
35138 | Some(DialectType::Databricks)
35139 | Some(DialectType::Hive)
35140 ) {
35141 self.write("`");
35142 self.write(name);
35143 self.write("`");
35144 } else {
35145 self.write(name);
35146 }
35147 } else {
35148 self.write(name);
35149 }
35150 } else {
35151 self.write(name);
35153 self.write_space();
35154 self.write_keyword("AS");
35155 self.write_space();
35156 self.generate_expression(expr)?;
35157 }
35158 } else {
35159 self.generate_expression(expr)?;
35160 }
35161 }
35162 self.write(")");
35163 }
35164 Ok(())
35165 }
35166
35167 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
35168 self.write_keyword("STUFF");
35170 self.write("(");
35171 self.generate_expression(&e.this)?;
35172 if let Some(start) = &e.start {
35173 self.write(", ");
35174 self.generate_expression(start)?;
35175 }
35176 if let Some(length) = e.length {
35177 self.write(", ");
35178 self.write(&length.to_string());
35179 }
35180 self.write(", ");
35181 self.generate_expression(&e.expression)?;
35182 self.write(")");
35183 Ok(())
35184 }
35185
35186 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
35187 self.write_keyword("SUBSTRING_INDEX");
35189 self.write("(");
35190 self.generate_expression(&e.this)?;
35191 if let Some(delimiter) = &e.delimiter {
35192 self.write(", ");
35193 self.generate_expression(delimiter)?;
35194 }
35195 if let Some(count) = &e.count {
35196 self.write(", ");
35197 self.generate_expression(count)?;
35198 }
35199 self.write(")");
35200 Ok(())
35201 }
35202
35203 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
35204 self.write_keyword("SUMMARIZE");
35206 if e.table.is_some() {
35207 self.write_space();
35208 self.write_keyword("TABLE");
35209 }
35210 self.write_space();
35211 self.generate_expression(&e.this)?;
35212 Ok(())
35213 }
35214
35215 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
35216 self.write_keyword("SYSTIMESTAMP");
35218 Ok(())
35219 }
35220
35221 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
35222 if let Some(this) = &e.this {
35224 self.generate_expression(this)?;
35225 }
35226 if !e.columns.is_empty() {
35227 self.write("(");
35228 for (i, col) in e.columns.iter().enumerate() {
35229 if i > 0 {
35230 self.write(", ");
35231 }
35232 self.generate_expression(col)?;
35233 }
35234 self.write(")");
35235 }
35236 Ok(())
35237 }
35238
35239 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
35240 self.write_keyword("TABLE");
35242 self.write("(");
35243 self.generate_expression(&e.this)?;
35244 self.write(")");
35245 if let Some(alias) = &e.alias {
35246 self.write_space();
35247 self.write_keyword("AS");
35248 self.write_space();
35249 self.write(alias);
35250 }
35251 Ok(())
35252 }
35253
35254 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
35255 self.write_keyword("ROWS FROM");
35257 self.write(" (");
35258 for (i, expr) in e.expressions.iter().enumerate() {
35259 if i > 0 {
35260 self.write(", ");
35261 }
35262 match expr {
35266 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
35267 self.generate_expression(&tuple.expressions[0])?;
35269 self.write_space();
35270 self.write_keyword("AS");
35271 self.write_space();
35272 self.generate_expression(&tuple.expressions[1])?;
35273 }
35274 _ => {
35275 self.generate_expression(expr)?;
35276 }
35277 }
35278 }
35279 self.write(")");
35280 if e.ordinality {
35281 self.write_space();
35282 self.write_keyword("WITH ORDINALITY");
35283 }
35284 if let Some(alias) = &e.alias {
35285 self.write_space();
35286 self.write_keyword("AS");
35287 self.write_space();
35288 self.generate_expression(alias)?;
35289 }
35290 Ok(())
35291 }
35292
35293 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
35294 use crate::dialects::DialectType;
35295
35296 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
35298 if self.config.alias_post_tablesample {
35300 if let Expression::Subquery(ref s) = **this {
35302 if let Some(ref alias) = s.alias {
35303 let mut subquery_no_alias = (**s).clone();
35305 subquery_no_alias.alias = None;
35306 subquery_no_alias.column_aliases = Vec::new();
35307 self.generate_expression(&Expression::Subquery(Box::new(
35308 subquery_no_alias,
35309 )))?;
35310 self.write_space();
35311 self.write_keyword("TABLESAMPLE");
35312 self.generate_sample_body(sample)?;
35313 if let Some(ref seed) = sample.seed {
35314 self.write_space();
35315 let use_seed = sample.use_seed_keyword
35316 && !matches!(
35317 self.config.dialect,
35318 Some(crate::dialects::DialectType::Databricks)
35319 | Some(crate::dialects::DialectType::Spark)
35320 );
35321 if use_seed {
35322 self.write_keyword("SEED");
35323 } else {
35324 self.write_keyword("REPEATABLE");
35325 }
35326 self.write(" (");
35327 self.generate_expression(seed)?;
35328 self.write(")");
35329 }
35330 self.write_space();
35331 self.write_keyword("AS");
35332 self.write_space();
35333 self.generate_identifier(alias)?;
35334 return Ok(());
35335 }
35336 } else if let Expression::Alias(ref a) = **this {
35337 self.generate_expression(&a.this)?;
35339 self.write_space();
35340 self.write_keyword("TABLESAMPLE");
35341 self.generate_sample_body(sample)?;
35342 if let Some(ref seed) = sample.seed {
35343 self.write_space();
35344 let use_seed = sample.use_seed_keyword
35345 && !matches!(
35346 self.config.dialect,
35347 Some(crate::dialects::DialectType::Databricks)
35348 | Some(crate::dialects::DialectType::Spark)
35349 );
35350 if use_seed {
35351 self.write_keyword("SEED");
35352 } else {
35353 self.write_keyword("REPEATABLE");
35354 }
35355 self.write(" (");
35356 self.generate_expression(seed)?;
35357 self.write(")");
35358 }
35359 self.write_space();
35361 self.write_keyword("AS");
35362 self.write_space();
35363 self.generate_identifier(&a.alias)?;
35364 return Ok(());
35365 }
35366 }
35367 self.generate_expression(this)?;
35369 self.write_space();
35370 self.write_keyword("TABLESAMPLE");
35371 self.generate_sample_body(sample)?;
35372 if let Some(ref seed) = sample.seed {
35374 self.write_space();
35375 let use_seed = sample.use_seed_keyword
35377 && !matches!(
35378 self.config.dialect,
35379 Some(crate::dialects::DialectType::Databricks)
35380 | Some(crate::dialects::DialectType::Spark)
35381 );
35382 if use_seed {
35383 self.write_keyword("SEED");
35384 } else {
35385 self.write_keyword("REPEATABLE");
35386 }
35387 self.write(" (");
35388 self.generate_expression(seed)?;
35389 self.write(")");
35390 }
35391 return Ok(());
35392 }
35393
35394 self.write_keyword("TABLESAMPLE");
35396 if let Some(method) = &e.method {
35397 self.write_space();
35398 self.write_keyword(method);
35399 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35400 self.write_space();
35402 self.write_keyword("BERNOULLI");
35403 }
35404 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
35405 self.write_space();
35406 self.write_keyword("BUCKET");
35407 self.write_space();
35408 self.generate_expression(numerator)?;
35409 self.write_space();
35410 self.write_keyword("OUT OF");
35411 self.write_space();
35412 self.generate_expression(denominator)?;
35413 if let Some(field) = &e.bucket_field {
35414 self.write_space();
35415 self.write_keyword("ON");
35416 self.write_space();
35417 self.generate_expression(field)?;
35418 }
35419 } else if !e.expressions.is_empty() {
35420 self.write(" (");
35421 for (i, expr) in e.expressions.iter().enumerate() {
35422 if i > 0 {
35423 self.write(", ");
35424 }
35425 self.generate_expression(expr)?;
35426 }
35427 self.write(")");
35428 } else if let Some(percent) = &e.percent {
35429 self.write(" (");
35430 self.generate_expression(percent)?;
35431 self.write_space();
35432 self.write_keyword("PERCENT");
35433 self.write(")");
35434 }
35435 Ok(())
35436 }
35437
35438 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
35439 if let Some(prefix) = &e.prefix {
35441 self.generate_expression(prefix)?;
35442 }
35443 if let Some(this) = &e.this {
35444 self.generate_expression(this)?;
35445 }
35446 if let Some(postfix) = &e.postfix {
35447 self.generate_expression(postfix)?;
35448 }
35449 Ok(())
35450 }
35451
35452 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
35453 self.write_keyword("TAG");
35455 self.write(" (");
35456 for (i, expr) in e.expressions.iter().enumerate() {
35457 if i > 0 {
35458 self.write(", ");
35459 }
35460 self.generate_expression(expr)?;
35461 }
35462 self.write(")");
35463 Ok(())
35464 }
35465
35466 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
35467 if let Some(this) = &e.this {
35469 self.generate_expression(this)?;
35470 self.write_space();
35471 }
35472 self.write_keyword("TEMPORARY");
35473 Ok(())
35474 }
35475
35476 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
35479 self.write_keyword("TIME");
35481 self.write("(");
35482 self.generate_expression(&e.this)?;
35483 self.write(")");
35484 Ok(())
35485 }
35486
35487 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
35488 self.write_keyword("TIME_ADD");
35490 self.write("(");
35491 self.generate_expression(&e.this)?;
35492 self.write(", ");
35493 self.generate_expression(&e.expression)?;
35494 if let Some(unit) = &e.unit {
35495 self.write(", ");
35496 self.write_keyword(unit);
35497 }
35498 self.write(")");
35499 Ok(())
35500 }
35501
35502 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
35503 self.write_keyword("TIME_DIFF");
35505 self.write("(");
35506 self.generate_expression(&e.this)?;
35507 self.write(", ");
35508 self.generate_expression(&e.expression)?;
35509 if let Some(unit) = &e.unit {
35510 self.write(", ");
35511 self.write_keyword(unit);
35512 }
35513 self.write(")");
35514 Ok(())
35515 }
35516
35517 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
35518 self.write_keyword("TIME_FROM_PARTS");
35520 self.write("(");
35521 let mut first = true;
35522 if let Some(hour) = &e.hour {
35523 self.generate_expression(hour)?;
35524 first = false;
35525 }
35526 if let Some(minute) = &e.min {
35527 if !first {
35528 self.write(", ");
35529 }
35530 self.generate_expression(minute)?;
35531 first = false;
35532 }
35533 if let Some(second) = &e.sec {
35534 if !first {
35535 self.write(", ");
35536 }
35537 self.generate_expression(second)?;
35538 first = false;
35539 }
35540 if let Some(ns) = &e.nano {
35541 if !first {
35542 self.write(", ");
35543 }
35544 self.generate_expression(ns)?;
35545 }
35546 self.write(")");
35547 Ok(())
35548 }
35549
35550 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
35551 self.write_keyword("TIME_SLICE");
35553 self.write("(");
35554 self.generate_expression(&e.this)?;
35555 self.write(", ");
35556 self.generate_expression(&e.expression)?;
35557 self.write(", ");
35558 self.write_keyword(&e.unit);
35559 self.write(")");
35560 Ok(())
35561 }
35562
35563 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
35564 self.write_keyword("TIME_STR_TO_TIME");
35566 self.write("(");
35567 self.generate_expression(&e.this)?;
35568 self.write(")");
35569 Ok(())
35570 }
35571
35572 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
35573 self.write_keyword("TIME_SUB");
35575 self.write("(");
35576 self.generate_expression(&e.this)?;
35577 self.write(", ");
35578 self.generate_expression(&e.expression)?;
35579 if let Some(unit) = &e.unit {
35580 self.write(", ");
35581 self.write_keyword(unit);
35582 }
35583 self.write(")");
35584 Ok(())
35585 }
35586
35587 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
35588 match self.config.dialect {
35589 Some(DialectType::Exasol) => {
35590 self.write_keyword("TO_CHAR");
35592 self.write("(");
35593 self.generate_expression(&e.this)?;
35594 self.write(", '");
35595 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
35596 self.write("'");
35597 self.write(")");
35598 }
35599 Some(DialectType::PostgreSQL)
35600 | Some(DialectType::Redshift)
35601 | Some(DialectType::Materialize) => {
35602 self.write_keyword("TO_CHAR");
35604 self.write("(");
35605 self.generate_expression(&e.this)?;
35606 self.write(", '");
35607 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
35608 self.write("'");
35609 self.write(")");
35610 }
35611 Some(DialectType::Oracle) => {
35612 self.write_keyword("TO_CHAR");
35614 self.write("(");
35615 self.generate_expression(&e.this)?;
35616 self.write(", '");
35617 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
35618 self.write("'");
35619 self.write(")");
35620 }
35621 Some(DialectType::Drill) => {
35622 self.write_keyword("TO_CHAR");
35624 self.write("(");
35625 self.generate_expression(&e.this)?;
35626 self.write(", '");
35627 self.write(&Self::strftime_to_java_format(&e.format));
35628 self.write("'");
35629 self.write(")");
35630 }
35631 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
35632 self.write_keyword("FORMAT");
35634 self.write("(");
35635 self.generate_expression(&e.this)?;
35636 self.write(", '");
35637 self.write(&Self::strftime_to_tsql_format(&e.format));
35638 self.write("'");
35639 self.write(")");
35640 }
35641 Some(DialectType::DuckDB) => {
35642 self.write_keyword("STRFTIME");
35644 self.write("(");
35645 self.generate_expression(&e.this)?;
35646 self.write(", '");
35647 self.write(&e.format);
35648 self.write("'");
35649 self.write(")");
35650 }
35651 Some(DialectType::BigQuery) => {
35652 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
35655 self.write_keyword("FORMAT_DATE");
35656 self.write("('");
35657 self.write(&fmt);
35658 self.write("', ");
35659 self.generate_expression(&e.this)?;
35660 self.write(")");
35661 }
35662 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35663 self.write_keyword("DATE_FORMAT");
35665 self.write("(");
35666 self.generate_expression(&e.this)?;
35667 self.write(", '");
35668 self.write(&Self::strftime_to_java_format(&e.format));
35669 self.write("'");
35670 self.write(")");
35671 }
35672 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
35673 self.write_keyword("DATE_FORMAT");
35675 self.write("(");
35676 self.generate_expression(&e.this)?;
35677 self.write(", '");
35678 self.write(&e.format);
35679 self.write("'");
35680 self.write(")");
35681 }
35682 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35683 self.write_keyword("DATE_FORMAT");
35685 self.write("(");
35686 self.generate_expression(&e.this)?;
35687 self.write(", '");
35688 self.write(&e.format);
35689 self.write("'");
35690 self.write(")");
35691 }
35692 _ => {
35693 self.write_keyword("TIME_TO_STR");
35695 self.write("(");
35696 self.generate_expression(&e.this)?;
35697 self.write(", '");
35698 self.write(&e.format);
35699 self.write("'");
35700 self.write(")");
35701 }
35702 }
35703 Ok(())
35704 }
35705
35706 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
35707 match self.config.dialect {
35708 Some(DialectType::DuckDB) => {
35709 self.write_keyword("EPOCH");
35711 self.write("(");
35712 self.generate_expression(&e.this)?;
35713 self.write(")");
35714 }
35715 Some(DialectType::Hive)
35716 | Some(DialectType::Spark)
35717 | Some(DialectType::Databricks)
35718 | Some(DialectType::Doris)
35719 | Some(DialectType::StarRocks)
35720 | Some(DialectType::Drill) => {
35721 self.write_keyword("UNIX_TIMESTAMP");
35723 self.write("(");
35724 self.generate_expression(&e.this)?;
35725 self.write(")");
35726 }
35727 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35728 self.write_keyword("TO_UNIXTIME");
35730 self.write("(");
35731 self.generate_expression(&e.this)?;
35732 self.write(")");
35733 }
35734 _ => {
35735 self.write_keyword("TIME_TO_UNIX");
35737 self.write("(");
35738 self.generate_expression(&e.this)?;
35739 self.write(")");
35740 }
35741 }
35742 Ok(())
35743 }
35744
35745 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
35746 match self.config.dialect {
35747 Some(DialectType::Hive) => {
35748 self.write_keyword("TO_DATE");
35750 self.write("(");
35751 self.generate_expression(&e.this)?;
35752 self.write(")");
35753 }
35754 _ => {
35755 self.write_keyword("TIME_STR_TO_DATE");
35757 self.write("(");
35758 self.generate_expression(&e.this)?;
35759 self.write(")");
35760 }
35761 }
35762 Ok(())
35763 }
35764
35765 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
35766 self.write_keyword("TIME_TRUNC");
35768 self.write("(");
35769 self.generate_expression(&e.this)?;
35770 self.write(", ");
35771 self.write_keyword(&e.unit);
35772 self.write(")");
35773 Ok(())
35774 }
35775
35776 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
35777 if let Some(unit) = &e.unit {
35779 self.write_keyword(unit);
35780 }
35781 Ok(())
35782 }
35783
35784 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
35788 use crate::dialects::DialectType;
35789 use crate::expressions::Literal;
35790
35791 match self.config.dialect {
35792 Some(DialectType::Exasol) => {
35794 self.write_keyword("TO_TIMESTAMP");
35795 self.write("(");
35796 if let Some(this) = &e.this {
35798 match this.as_ref() {
35799 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
35800 let Literal::String(s) = lit.as_ref() else {
35801 unreachable!()
35802 };
35803 self.write("'");
35804 self.write(s);
35805 self.write("'");
35806 }
35807 _ => {
35808 self.generate_expression(this)?;
35809 }
35810 }
35811 }
35812 self.write(")");
35813 }
35814 _ => {
35816 self.write_keyword("TIMESTAMP");
35817 self.write("(");
35818 if let Some(this) = &e.this {
35819 self.generate_expression(this)?;
35820 }
35821 if let Some(zone) = &e.zone {
35822 self.write(", ");
35823 self.generate_expression(zone)?;
35824 }
35825 self.write(")");
35826 }
35827 }
35828 Ok(())
35829 }
35830
35831 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
35832 self.write_keyword("TIMESTAMP_ADD");
35834 self.write("(");
35835 self.generate_expression(&e.this)?;
35836 self.write(", ");
35837 self.generate_expression(&e.expression)?;
35838 if let Some(unit) = &e.unit {
35839 self.write(", ");
35840 self.write_keyword(unit);
35841 }
35842 self.write(")");
35843 Ok(())
35844 }
35845
35846 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
35847 self.write_keyword("TIMESTAMP_DIFF");
35849 self.write("(");
35850 self.generate_expression(&e.this)?;
35851 self.write(", ");
35852 self.generate_expression(&e.expression)?;
35853 if let Some(unit) = &e.unit {
35854 self.write(", ");
35855 self.write_keyword(unit);
35856 }
35857 self.write(")");
35858 Ok(())
35859 }
35860
35861 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
35862 self.write_keyword("TIMESTAMP_FROM_PARTS");
35864 self.write("(");
35865 if let Some(this) = &e.this {
35866 self.generate_expression(this)?;
35867 }
35868 if let Some(expression) = &e.expression {
35869 self.write(", ");
35870 self.generate_expression(expression)?;
35871 }
35872 if let Some(zone) = &e.zone {
35873 self.write(", ");
35874 self.generate_expression(zone)?;
35875 }
35876 if let Some(milli) = &e.milli {
35877 self.write(", ");
35878 self.generate_expression(milli)?;
35879 }
35880 self.write(")");
35881 Ok(())
35882 }
35883
35884 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
35885 self.write_keyword("TIMESTAMP_SUB");
35887 self.write("(");
35888 self.generate_expression(&e.this)?;
35889 self.write(", ");
35890 self.write_keyword("INTERVAL");
35891 self.write_space();
35892 self.generate_expression(&e.expression)?;
35893 if let Some(unit) = &e.unit {
35894 self.write_space();
35895 self.write_keyword(unit);
35896 }
35897 self.write(")");
35898 Ok(())
35899 }
35900
35901 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
35902 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
35904 self.write("(");
35905 if let Some(zone) = &e.zone {
35906 self.generate_expression(zone)?;
35907 }
35908 self.write(")");
35909 Ok(())
35910 }
35911
35912 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
35913 self.write_keyword("TO_BINARY");
35915 self.write("(");
35916 self.generate_expression(&e.this)?;
35917 if let Some(format) = &e.format {
35918 self.write(", '");
35919 self.write(format);
35920 self.write("'");
35921 }
35922 self.write(")");
35923 Ok(())
35924 }
35925
35926 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
35927 self.write_keyword("TO_BOOLEAN");
35929 self.write("(");
35930 self.generate_expression(&e.this)?;
35931 self.write(")");
35932 Ok(())
35933 }
35934
35935 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
35936 self.write_keyword("TO_CHAR");
35938 self.write("(");
35939 self.generate_expression(&e.this)?;
35940 if let Some(format) = &e.format {
35941 self.write(", '");
35942 self.write(format);
35943 self.write("'");
35944 }
35945 if let Some(nlsparam) = &e.nlsparam {
35946 self.write(", ");
35947 self.generate_expression(nlsparam)?;
35948 }
35949 self.write(")");
35950 Ok(())
35951 }
35952
35953 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
35954 self.write_keyword("TO_DECFLOAT");
35956 self.write("(");
35957 self.generate_expression(&e.this)?;
35958 if let Some(format) = &e.format {
35959 self.write(", '");
35960 self.write(format);
35961 self.write("'");
35962 }
35963 self.write(")");
35964 Ok(())
35965 }
35966
35967 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
35968 self.write_keyword("TO_DOUBLE");
35970 self.write("(");
35971 self.generate_expression(&e.this)?;
35972 if let Some(format) = &e.format {
35973 self.write(", '");
35974 self.write(format);
35975 self.write("'");
35976 }
35977 self.write(")");
35978 Ok(())
35979 }
35980
35981 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
35982 self.write_keyword("TO_FILE");
35984 self.write("(");
35985 self.generate_expression(&e.this)?;
35986 if let Some(path) = &e.path {
35987 self.write(", ");
35988 self.generate_expression(path)?;
35989 }
35990 self.write(")");
35991 Ok(())
35992 }
35993
35994 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
35995 let is_safe = e.safe.is_some();
35998 if is_safe {
35999 self.write_keyword("TRY_TO_NUMBER");
36000 } else {
36001 self.write_keyword("TO_NUMBER");
36002 }
36003 self.write("(");
36004 self.generate_expression(&e.this)?;
36005 if let Some(format) = &e.format {
36006 self.write(", ");
36007 self.generate_expression(format)?;
36008 }
36009 if let Some(nlsparam) = &e.nlsparam {
36010 self.write(", ");
36011 self.generate_expression(nlsparam)?;
36012 }
36013 if let Some(precision) = &e.precision {
36014 self.write(", ");
36015 self.generate_expression(precision)?;
36016 }
36017 if let Some(scale) = &e.scale {
36018 self.write(", ");
36019 self.generate_expression(scale)?;
36020 }
36021 self.write(")");
36022 Ok(())
36023 }
36024
36025 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
36026 self.write_keyword("TO_TABLE");
36028 self.write_space();
36029 self.generate_expression(&e.this)?;
36030 Ok(())
36031 }
36032
36033 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
36034 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
36036 Expression::Identifier(id) => id.name.clone(),
36037 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
36038 let Literal::String(s) = lit.as_ref() else {
36039 unreachable!()
36040 };
36041 s.clone()
36042 }
36043 _ => String::new(),
36044 });
36045
36046 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
36047 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
36048 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
36049 matches!(m.as_ref(), Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)))
36050 });
36051
36052 let use_start_transaction = matches!(
36054 self.config.dialect,
36055 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
36056 );
36057 let strip_transaction = matches!(
36059 self.config.dialect,
36060 Some(DialectType::Snowflake)
36061 | Some(DialectType::PostgreSQL)
36062 | Some(DialectType::Redshift)
36063 | Some(DialectType::MySQL)
36064 | Some(DialectType::Hive)
36065 | Some(DialectType::Spark)
36066 | Some(DialectType::Databricks)
36067 | Some(DialectType::DuckDB)
36068 | Some(DialectType::Oracle)
36069 | Some(DialectType::Doris)
36070 | Some(DialectType::StarRocks)
36071 | Some(DialectType::Materialize)
36072 | Some(DialectType::ClickHouse)
36073 );
36074
36075 if is_start || use_start_transaction {
36076 self.write_keyword("START TRANSACTION");
36078 if let Some(modes) = &e.modes {
36079 self.write_space();
36080 self.generate_expression(modes)?;
36081 }
36082 } else {
36083 self.write_keyword("BEGIN");
36085
36086 let is_kind = e.this.as_ref().map_or(false, |t| {
36088 if let Expression::Identifier(id) = t.as_ref() {
36089 id.name.eq_ignore_ascii_case("DEFERRED")
36090 || id.name.eq_ignore_ascii_case("IMMEDIATE")
36091 || id.name.eq_ignore_ascii_case("EXCLUSIVE")
36092 } else {
36093 false
36094 }
36095 });
36096
36097 if is_kind {
36099 if let Some(this) = &e.this {
36100 self.write_space();
36101 if let Expression::Identifier(id) = this.as_ref() {
36102 self.write_keyword(&id.name);
36103 }
36104 }
36105 }
36106
36107 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
36109 self.write_space();
36110 self.write_keyword("TRANSACTION");
36111 }
36112
36113 if !is_kind {
36115 if let Some(this) = &e.this {
36116 self.write_space();
36117 self.generate_expression(this)?;
36118 }
36119 }
36120
36121 if has_with_mark {
36123 self.write_space();
36124 self.write_keyword("WITH MARK");
36125 if let Some(Expression::Literal(lit)) = e.mark.as_deref() {
36126 if let Literal::String(desc) = lit.as_ref() {
36127 if !desc.is_empty() {
36128 self.write_space();
36129 self.write(&format!("'{}'", desc));
36130 }
36131 }
36132 }
36133 }
36134
36135 if let Some(modes) = &e.modes {
36137 self.write_space();
36138 self.generate_expression(modes)?;
36139 }
36140 }
36141 Ok(())
36142 }
36143
36144 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
36145 self.write_keyword("TRANSFORM");
36147 self.write("(");
36148 self.generate_expression(&e.this)?;
36149 self.write(", ");
36150 self.generate_expression(&e.expression)?;
36151 self.write(")");
36152 Ok(())
36153 }
36154
36155 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
36156 self.write_keyword("TRANSFORM");
36158 self.write("(");
36159 if self.config.pretty && !e.expressions.is_empty() {
36160 self.indent_level += 1;
36161 for (i, expr) in e.expressions.iter().enumerate() {
36162 if i > 0 {
36163 self.write(",");
36164 }
36165 self.write_newline();
36166 self.write_indent();
36167 self.generate_expression(expr)?;
36168 }
36169 self.indent_level -= 1;
36170 self.write_newline();
36171 self.write(")");
36172 } else {
36173 for (i, expr) in e.expressions.iter().enumerate() {
36174 if i > 0 {
36175 self.write(", ");
36176 }
36177 self.generate_expression(expr)?;
36178 }
36179 self.write(")");
36180 }
36181 Ok(())
36182 }
36183
36184 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
36185 use crate::dialects::DialectType;
36186 if let Some(this) = &e.this {
36188 self.generate_expression(this)?;
36189 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
36190 self.write_space();
36191 }
36192 }
36193 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
36194 self.write_keyword("TRANSIENT");
36195 }
36196 Ok(())
36197 }
36198
36199 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
36200 self.write_keyword("TRANSLATE");
36202 self.write("(");
36203 self.generate_expression(&e.this)?;
36204 if let Some(from) = &e.from_ {
36205 self.write(", ");
36206 self.generate_expression(from)?;
36207 }
36208 if let Some(to) = &e.to {
36209 self.write(", ");
36210 self.generate_expression(to)?;
36211 }
36212 self.write(")");
36213 Ok(())
36214 }
36215
36216 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
36217 self.write_keyword("TRANSLATE");
36219 self.write("(");
36220 self.generate_expression(&e.this)?;
36221 self.write_space();
36222 self.write_keyword("USING");
36223 self.write_space();
36224 self.generate_expression(&e.expression)?;
36225 if e.with_error.is_some() {
36226 self.write_space();
36227 self.write_keyword("WITH ERROR");
36228 }
36229 self.write(")");
36230 Ok(())
36231 }
36232
36233 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
36234 self.write_keyword("TRUNCATE TABLE");
36236 self.write_space();
36237 for (i, expr) in e.expressions.iter().enumerate() {
36238 if i > 0 {
36239 self.write(", ");
36240 }
36241 self.generate_expression(expr)?;
36242 }
36243 Ok(())
36244 }
36245
36246 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
36247 self.write_keyword("TRY_BASE64_DECODE_BINARY");
36249 self.write("(");
36250 self.generate_expression(&e.this)?;
36251 if let Some(alphabet) = &e.alphabet {
36252 self.write(", ");
36253 self.generate_expression(alphabet)?;
36254 }
36255 self.write(")");
36256 Ok(())
36257 }
36258
36259 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
36260 self.write_keyword("TRY_BASE64_DECODE_STRING");
36262 self.write("(");
36263 self.generate_expression(&e.this)?;
36264 if let Some(alphabet) = &e.alphabet {
36265 self.write(", ");
36266 self.generate_expression(alphabet)?;
36267 }
36268 self.write(")");
36269 Ok(())
36270 }
36271
36272 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
36273 self.write_keyword("TRY_TO_DECFLOAT");
36275 self.write("(");
36276 self.generate_expression(&e.this)?;
36277 if let Some(format) = &e.format {
36278 self.write(", '");
36279 self.write(format);
36280 self.write("'");
36281 }
36282 self.write(")");
36283 Ok(())
36284 }
36285
36286 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
36287 self.write_keyword("TS_OR_DS_ADD");
36289 self.write("(");
36290 self.generate_expression(&e.this)?;
36291 self.write(", ");
36292 self.generate_expression(&e.expression)?;
36293 if let Some(unit) = &e.unit {
36294 self.write(", ");
36295 self.write_keyword(unit);
36296 }
36297 if let Some(return_type) = &e.return_type {
36298 self.write(", ");
36299 self.generate_expression(return_type)?;
36300 }
36301 self.write(")");
36302 Ok(())
36303 }
36304
36305 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
36306 self.write_keyword("TS_OR_DS_DIFF");
36308 self.write("(");
36309 self.generate_expression(&e.this)?;
36310 self.write(", ");
36311 self.generate_expression(&e.expression)?;
36312 if let Some(unit) = &e.unit {
36313 self.write(", ");
36314 self.write_keyword(unit);
36315 }
36316 self.write(")");
36317 Ok(())
36318 }
36319
36320 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
36321 let default_time_format = "%Y-%m-%d %H:%M:%S";
36322 let default_date_format = "%Y-%m-%d";
36323 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
36324 f != default_time_format && f != default_date_format
36325 });
36326
36327 if has_non_default_format {
36328 let fmt = e.format.as_ref().unwrap();
36330 match self.config.dialect {
36331 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
36332 let str_to_time = crate::expressions::StrToTime {
36335 this: Box::new((*e.this).clone()),
36336 format: fmt.clone(),
36337 zone: None,
36338 safe: None,
36339 target_type: None,
36340 };
36341 self.generate_str_to_time(&str_to_time)?;
36342 }
36343 Some(DialectType::Hive)
36344 | Some(DialectType::Spark)
36345 | Some(DialectType::Databricks) => {
36346 self.write_keyword("TO_DATE");
36348 self.write("(");
36349 self.generate_expression(&e.this)?;
36350 self.write(", '");
36351 self.write(&Self::strftime_to_java_format(fmt));
36352 self.write("')");
36353 }
36354 Some(DialectType::Snowflake) => {
36355 self.write_keyword("TO_DATE");
36357 self.write("(");
36358 self.generate_expression(&e.this)?;
36359 self.write(", '");
36360 self.write(&Self::strftime_to_snowflake_format(fmt));
36361 self.write("')");
36362 }
36363 Some(DialectType::Doris) => {
36364 self.write_keyword("TO_DATE");
36366 self.write("(");
36367 self.generate_expression(&e.this)?;
36368 self.write(")");
36369 }
36370 _ => {
36371 self.write_keyword("CAST");
36373 self.write("(");
36374 let str_to_time = crate::expressions::StrToTime {
36375 this: Box::new((*e.this).clone()),
36376 format: fmt.clone(),
36377 zone: None,
36378 safe: None,
36379 target_type: None,
36380 };
36381 self.generate_str_to_time(&str_to_time)?;
36382 self.write_keyword(" AS ");
36383 self.write_keyword("DATE");
36384 self.write(")");
36385 }
36386 }
36387 } else {
36388 match self.config.dialect {
36390 Some(DialectType::MySQL)
36391 | Some(DialectType::SQLite)
36392 | Some(DialectType::StarRocks) => {
36393 self.write_keyword("DATE");
36395 self.write("(");
36396 self.generate_expression(&e.this)?;
36397 self.write(")");
36398 }
36399 Some(DialectType::Hive)
36400 | Some(DialectType::Spark)
36401 | Some(DialectType::Databricks)
36402 | Some(DialectType::Snowflake)
36403 | Some(DialectType::Doris) => {
36404 self.write_keyword("TO_DATE");
36406 self.write("(");
36407 self.generate_expression(&e.this)?;
36408 self.write(")");
36409 }
36410 Some(DialectType::Presto)
36411 | Some(DialectType::Trino)
36412 | Some(DialectType::Athena) => {
36413 self.write_keyword("CAST");
36415 self.write("(");
36416 self.write_keyword("CAST");
36417 self.write("(");
36418 self.generate_expression(&e.this)?;
36419 self.write_keyword(" AS ");
36420 self.write_keyword("TIMESTAMP");
36421 self.write(")");
36422 self.write_keyword(" AS ");
36423 self.write_keyword("DATE");
36424 self.write(")");
36425 }
36426 Some(DialectType::ClickHouse) => {
36427 self.write_keyword("CAST");
36429 self.write("(");
36430 self.generate_expression(&e.this)?;
36431 self.write_keyword(" AS ");
36432 self.write("Nullable(DATE)");
36433 self.write(")");
36434 }
36435 _ => {
36436 self.write_keyword("CAST");
36438 self.write("(");
36439 self.generate_expression(&e.this)?;
36440 self.write_keyword(" AS ");
36441 self.write_keyword("DATE");
36442 self.write(")");
36443 }
36444 }
36445 }
36446 Ok(())
36447 }
36448
36449 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
36450 self.write_keyword("TS_OR_DS_TO_TIME");
36452 self.write("(");
36453 self.generate_expression(&e.this)?;
36454 if let Some(format) = &e.format {
36455 self.write(", '");
36456 self.write(format);
36457 self.write("'");
36458 }
36459 self.write(")");
36460 Ok(())
36461 }
36462
36463 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
36464 self.write_keyword("UNHEX");
36466 self.write("(");
36467 self.generate_expression(&e.this)?;
36468 if let Some(expression) = &e.expression {
36469 self.write(", ");
36470 self.generate_expression(expression)?;
36471 }
36472 self.write(")");
36473 Ok(())
36474 }
36475
36476 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
36477 self.write("U&");
36479 self.generate_expression(&e.this)?;
36480 if let Some(escape) = &e.escape {
36481 self.write_space();
36482 self.write_keyword("UESCAPE");
36483 self.write_space();
36484 self.generate_expression(escape)?;
36485 }
36486 Ok(())
36487 }
36488
36489 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
36490 self.write_keyword("UNIFORM");
36492 self.write("(");
36493 self.generate_expression(&e.this)?;
36494 self.write(", ");
36495 self.generate_expression(&e.expression)?;
36496 if let Some(gen) = &e.gen {
36497 self.write(", ");
36498 self.generate_expression(gen)?;
36499 }
36500 if let Some(seed) = &e.seed {
36501 self.write(", ");
36502 self.generate_expression(seed)?;
36503 }
36504 self.write(")");
36505 Ok(())
36506 }
36507
36508 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
36509 self.write_keyword("UNIQUE");
36511 if e.nulls.is_some() {
36513 self.write(" NULLS NOT DISTINCT");
36514 }
36515 if let Some(this) = &e.this {
36516 self.write_space();
36517 self.generate_expression(this)?;
36518 }
36519 if let Some(index_type) = &e.index_type {
36520 self.write(" USING ");
36521 self.generate_expression(index_type)?;
36522 }
36523 if let Some(on_conflict) = &e.on_conflict {
36524 self.write_space();
36525 self.generate_expression(on_conflict)?;
36526 }
36527 for opt in &e.options {
36528 self.write_space();
36529 self.generate_expression(opt)?;
36530 }
36531 Ok(())
36532 }
36533
36534 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
36535 self.write_keyword("UNIQUE KEY");
36537 self.write(" (");
36538 for (i, expr) in e.expressions.iter().enumerate() {
36539 if i > 0 {
36540 self.write(", ");
36541 }
36542 self.generate_expression(expr)?;
36543 }
36544 self.write(")");
36545 Ok(())
36546 }
36547
36548 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
36549 self.write_keyword("ROLLUP");
36551 self.write(" (");
36552 for (i, index) in e.expressions.iter().enumerate() {
36553 if i > 0 {
36554 self.write(", ");
36555 }
36556 self.generate_identifier(&index.name)?;
36557 self.write("(");
36558 for (j, col) in index.expressions.iter().enumerate() {
36559 if j > 0 {
36560 self.write(", ");
36561 }
36562 self.generate_identifier(col)?;
36563 }
36564 self.write(")");
36565 }
36566 self.write(")");
36567 Ok(())
36568 }
36569
36570 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
36571 match self.config.dialect {
36572 Some(DialectType::DuckDB) => {
36573 self.write_keyword("STRFTIME");
36575 self.write("(");
36576 self.write_keyword("TO_TIMESTAMP");
36577 self.write("(");
36578 self.generate_expression(&e.this)?;
36579 self.write("), '");
36580 if let Some(format) = &e.format {
36581 self.write(format);
36582 }
36583 self.write("')");
36584 }
36585 Some(DialectType::Hive) => {
36586 self.write_keyword("FROM_UNIXTIME");
36588 self.write("(");
36589 self.generate_expression(&e.this)?;
36590 if let Some(format) = &e.format {
36591 if format != "yyyy-MM-dd HH:mm:ss" {
36592 self.write(", '");
36593 self.write(format);
36594 self.write("'");
36595 }
36596 }
36597 self.write(")");
36598 }
36599 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36600 self.write_keyword("DATE_FORMAT");
36602 self.write("(");
36603 self.write_keyword("FROM_UNIXTIME");
36604 self.write("(");
36605 self.generate_expression(&e.this)?;
36606 self.write("), '");
36607 if let Some(format) = &e.format {
36608 self.write(format);
36609 }
36610 self.write("')");
36611 }
36612 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36613 self.write_keyword("FROM_UNIXTIME");
36615 self.write("(");
36616 self.generate_expression(&e.this)?;
36617 if let Some(format) = &e.format {
36618 self.write(", '");
36619 self.write(format);
36620 self.write("'");
36621 }
36622 self.write(")");
36623 }
36624 _ => {
36625 self.write_keyword("UNIX_TO_STR");
36627 self.write("(");
36628 self.generate_expression(&e.this)?;
36629 if let Some(format) = &e.format {
36630 self.write(", '");
36631 self.write(format);
36632 self.write("'");
36633 }
36634 self.write(")");
36635 }
36636 }
36637 Ok(())
36638 }
36639
36640 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
36641 use crate::dialects::DialectType;
36642 let scale = e.scale.unwrap_or(0); match self.config.dialect {
36645 Some(DialectType::Snowflake) => {
36646 self.write_keyword("TO_TIMESTAMP");
36648 self.write("(");
36649 self.generate_expression(&e.this)?;
36650 if let Some(s) = e.scale {
36651 if s > 0 {
36652 self.write(", ");
36653 self.write(&s.to_string());
36654 }
36655 }
36656 self.write(")");
36657 }
36658 Some(DialectType::BigQuery) => {
36659 match scale {
36662 0 => {
36663 self.write_keyword("TIMESTAMP_SECONDS");
36664 self.write("(");
36665 self.generate_expression(&e.this)?;
36666 self.write(")");
36667 }
36668 3 => {
36669 self.write_keyword("TIMESTAMP_MILLIS");
36670 self.write("(");
36671 self.generate_expression(&e.this)?;
36672 self.write(")");
36673 }
36674 6 => {
36675 self.write_keyword("TIMESTAMP_MICROS");
36676 self.write("(");
36677 self.generate_expression(&e.this)?;
36678 self.write(")");
36679 }
36680 _ => {
36681 self.write_keyword("TIMESTAMP_SECONDS");
36683 self.write("(CAST(");
36684 self.generate_expression(&e.this)?;
36685 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
36686 }
36687 }
36688 }
36689 Some(DialectType::Spark) => {
36690 match scale {
36695 0 => {
36696 self.write_keyword("CAST");
36697 self.write("(");
36698 self.write_keyword("FROM_UNIXTIME");
36699 self.write("(");
36700 self.generate_expression(&e.this)?;
36701 self.write(") ");
36702 self.write_keyword("AS TIMESTAMP");
36703 self.write(")");
36704 }
36705 3 => {
36706 self.write_keyword("TIMESTAMP_MILLIS");
36707 self.write("(");
36708 self.generate_expression(&e.this)?;
36709 self.write(")");
36710 }
36711 6 => {
36712 self.write_keyword("TIMESTAMP_MICROS");
36713 self.write("(");
36714 self.generate_expression(&e.this)?;
36715 self.write(")");
36716 }
36717 _ => {
36718 self.write_keyword("TIMESTAMP_SECONDS");
36719 self.write("(");
36720 self.generate_expression(&e.this)?;
36721 self.write(&format!(" / POWER(10, {}))", scale));
36722 }
36723 }
36724 }
36725 Some(DialectType::Databricks) => {
36726 match scale {
36730 0 => {
36731 self.write_keyword("CAST");
36732 self.write("(");
36733 self.write_keyword("FROM_UNIXTIME");
36734 self.write("(");
36735 self.generate_expression(&e.this)?;
36736 self.write(") ");
36737 self.write_keyword("AS TIMESTAMP");
36738 self.write(")");
36739 }
36740 3 => {
36741 self.write_keyword("TIMESTAMP_MILLIS");
36742 self.write("(");
36743 self.generate_expression(&e.this)?;
36744 self.write(")");
36745 }
36746 6 => {
36747 self.write_keyword("TIMESTAMP_MICROS");
36748 self.write("(");
36749 self.generate_expression(&e.this)?;
36750 self.write(")");
36751 }
36752 _ => {
36753 self.write_keyword("TIMESTAMP_SECONDS");
36754 self.write("(");
36755 self.generate_expression(&e.this)?;
36756 self.write(&format!(" / POWER(10, {}))", scale));
36757 }
36758 }
36759 }
36760 Some(DialectType::Hive) => {
36761 if scale == 0 {
36763 self.write_keyword("FROM_UNIXTIME");
36764 self.write("(");
36765 self.generate_expression(&e.this)?;
36766 self.write(")");
36767 } else {
36768 self.write_keyword("FROM_UNIXTIME");
36769 self.write("(");
36770 self.generate_expression(&e.this)?;
36771 self.write(&format!(" / POWER(10, {})", scale));
36772 self.write(")");
36773 }
36774 }
36775 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36776 if scale == 0 {
36779 self.write_keyword("FROM_UNIXTIME");
36780 self.write("(");
36781 self.generate_expression(&e.this)?;
36782 self.write(")");
36783 } else {
36784 self.write_keyword("FROM_UNIXTIME");
36785 self.write("(CAST(");
36786 self.generate_expression(&e.this)?;
36787 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
36788 }
36789 }
36790 Some(DialectType::DuckDB) => {
36791 match scale {
36795 0 => {
36796 self.write_keyword("TO_TIMESTAMP");
36797 self.write("(");
36798 self.generate_expression(&e.this)?;
36799 self.write(")");
36800 }
36801 3 => {
36802 self.write_keyword("EPOCH_MS");
36803 self.write("(");
36804 self.generate_expression(&e.this)?;
36805 self.write(")");
36806 }
36807 6 => {
36808 self.write_keyword("MAKE_TIMESTAMP");
36809 self.write("(");
36810 self.generate_expression(&e.this)?;
36811 self.write(")");
36812 }
36813 _ => {
36814 self.write_keyword("TO_TIMESTAMP");
36815 self.write("(");
36816 self.generate_expression(&e.this)?;
36817 self.write(&format!(" / POWER(10, {}))", scale));
36818 self.write_keyword(" AT TIME ZONE");
36819 self.write(" 'UTC'");
36820 }
36821 }
36822 }
36823 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
36824 self.write_keyword("FROM_UNIXTIME");
36826 self.write("(");
36827 self.generate_expression(&e.this)?;
36828 self.write(")");
36829 }
36830 Some(DialectType::Oracle) => {
36831 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
36833 self.generate_expression(&e.this)?;
36834 self.write(" / 86400)");
36835 }
36836 Some(DialectType::Redshift) => {
36837 self.write("(TIMESTAMP 'epoch' + ");
36840 if scale == 0 {
36841 self.generate_expression(&e.this)?;
36842 } else {
36843 self.write("(");
36844 self.generate_expression(&e.this)?;
36845 self.write(&format!(" / POWER(10, {}))", scale));
36846 }
36847 self.write(" * INTERVAL '1 SECOND')");
36848 }
36849 Some(DialectType::Exasol) => {
36850 self.write_keyword("FROM_POSIX_TIME");
36852 self.write("(");
36853 self.generate_expression(&e.this)?;
36854 self.write(")");
36855 }
36856 _ => {
36857 self.write_keyword("TO_TIMESTAMP");
36859 self.write("(");
36860 self.generate_expression(&e.this)?;
36861 if let Some(s) = e.scale {
36862 self.write(", ");
36863 self.write(&s.to_string());
36864 }
36865 self.write(")");
36866 }
36867 }
36868 Ok(())
36869 }
36870
36871 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
36872 if !matches!(&*e.this, Expression::Null(_)) {
36874 self.write_keyword("NAME");
36875 self.write_space();
36876 self.generate_expression(&e.this)?;
36877 }
36878 if !e.expressions.is_empty() {
36879 self.write_space();
36880 self.write_keyword("VALUE");
36881 self.write_space();
36882 for (i, expr) in e.expressions.iter().enumerate() {
36883 if i > 0 {
36884 self.write(", ");
36885 }
36886 self.generate_expression(expr)?;
36887 }
36888 }
36889 Ok(())
36890 }
36891
36892 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
36893 if e.wrapped.is_some() {
36895 self.write("(");
36896 }
36897 self.generate_expression(&e.this)?;
36898 if e.wrapped.is_some() {
36899 self.write(")");
36900 }
36901 self.write("(");
36902 for (i, expr) in e.expressions.iter().enumerate() {
36903 if i > 0 {
36904 self.write(", ");
36905 }
36906 self.generate_expression(expr)?;
36907 }
36908 self.write(")");
36909 Ok(())
36910 }
36911
36912 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
36913 self.write_keyword("USING TEMPLATE");
36915 self.write_space();
36916 self.generate_expression(&e.this)?;
36917 Ok(())
36918 }
36919
36920 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
36921 self.write_keyword("UTC_TIME");
36923 Ok(())
36924 }
36925
36926 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
36927 if matches!(
36928 self.config.dialect,
36929 Some(crate::dialects::DialectType::ClickHouse)
36930 ) {
36931 self.write_keyword("CURRENT_TIMESTAMP");
36932 self.write("('UTC')");
36933 } else {
36934 self.write_keyword("UTC_TIMESTAMP");
36935 }
36936 Ok(())
36937 }
36938
36939 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
36940 use crate::dialects::DialectType;
36941 let func_name = match self.config.dialect {
36943 Some(DialectType::Snowflake) => "UUID_STRING",
36944 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
36945 Some(DialectType::BigQuery) => "GENERATE_UUID",
36946 _ => {
36947 if let Some(name) = &e.name {
36948 name.as_str()
36949 } else {
36950 "UUID"
36951 }
36952 }
36953 };
36954 self.write_keyword(func_name);
36955 self.write("(");
36956 if let Some(this) = &e.this {
36957 self.generate_expression(this)?;
36958 }
36959 self.write(")");
36960 Ok(())
36961 }
36962
36963 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
36964 self.write_keyword("MAP");
36966 self.write("(");
36967 let mut first = true;
36968 for (k, v) in e.keys.iter().zip(e.values.iter()) {
36969 if !first {
36970 self.write(", ");
36971 }
36972 self.generate_expression(k)?;
36973 self.write(", ");
36974 self.generate_expression(v)?;
36975 first = false;
36976 }
36977 self.write(")");
36978 Ok(())
36979 }
36980
36981 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
36982 self.write_keyword("VECTOR_SEARCH");
36984 self.write("(");
36985 self.generate_expression(&e.this)?;
36986 if let Some(col) = &e.column_to_search {
36987 self.write(", ");
36988 self.generate_expression(col)?;
36989 }
36990 if let Some(query_table) = &e.query_table {
36991 self.write(", ");
36992 self.generate_expression(query_table)?;
36993 }
36994 if let Some(query_col) = &e.query_column_to_search {
36995 self.write(", ");
36996 self.generate_expression(query_col)?;
36997 }
36998 if let Some(top_k) = &e.top_k {
36999 self.write(", ");
37000 self.generate_expression(top_k)?;
37001 }
37002 if let Some(dist_type) = &e.distance_type {
37003 self.write(", ");
37004 self.generate_expression(dist_type)?;
37005 }
37006 self.write(")");
37007 Ok(())
37008 }
37009
37010 fn generate_version(&mut self, e: &Version) -> Result<()> {
37011 use crate::dialects::DialectType;
37017 let skip_for = matches!(
37018 self.config.dialect,
37019 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
37020 );
37021 if !skip_for {
37022 self.write_keyword("FOR");
37023 self.write_space();
37024 }
37025 match e.this.as_ref() {
37027 Expression::Identifier(ident) => {
37028 self.write_keyword(&ident.name);
37029 }
37030 _ => {
37031 self.generate_expression(&e.this)?;
37032 }
37033 }
37034 self.write_space();
37035 self.write_keyword(&e.kind);
37036 if let Some(expression) = &e.expression {
37037 self.write_space();
37038 self.generate_expression(expression)?;
37039 }
37040 Ok(())
37041 }
37042
37043 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
37044 self.generate_expression(&e.this)?;
37046 Ok(())
37047 }
37048
37049 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
37050 if e.this.is_some() {
37052 self.write_keyword("NOT VOLATILE");
37053 } else {
37054 self.write_keyword("VOLATILE");
37055 }
37056 Ok(())
37057 }
37058
37059 fn generate_watermark_column_constraint(
37060 &mut self,
37061 e: &WatermarkColumnConstraint,
37062 ) -> Result<()> {
37063 self.write_keyword("WATERMARK FOR");
37065 self.write_space();
37066 self.generate_expression(&e.this)?;
37067 self.write_space();
37068 self.write_keyword("AS");
37069 self.write_space();
37070 self.generate_expression(&e.expression)?;
37071 Ok(())
37072 }
37073
37074 fn generate_week(&mut self, e: &Week) -> Result<()> {
37075 self.write_keyword("WEEK");
37077 self.write("(");
37078 self.generate_expression(&e.this)?;
37079 if let Some(mode) = &e.mode {
37080 self.write(", ");
37081 self.generate_expression(mode)?;
37082 }
37083 self.write(")");
37084 Ok(())
37085 }
37086
37087 fn generate_when(&mut self, e: &When) -> Result<()> {
37088 self.write_keyword("WHEN");
37092 self.write_space();
37093
37094 if let Some(matched) = &e.matched {
37096 match matched.as_ref() {
37098 Expression::Boolean(b) if b.value => {
37099 self.write_keyword("MATCHED");
37100 }
37101 _ => {
37102 self.write_keyword("NOT MATCHED");
37103 }
37104 }
37105 } else {
37106 self.write_keyword("NOT MATCHED");
37107 }
37108
37109 if self.config.matched_by_source {
37114 if let Some(source) = &e.source {
37115 if let Expression::Boolean(b) = source.as_ref() {
37116 if b.value {
37117 self.write_space();
37119 self.write_keyword("BY SOURCE");
37120 }
37121 } else {
37123 self.write_space();
37125 self.write_keyword("BY SOURCE");
37126 }
37127 }
37128 }
37129
37130 if let Some(condition) = &e.condition {
37132 self.write_space();
37133 self.write_keyword("AND");
37134 self.write_space();
37135 self.generate_expression(condition)?;
37136 }
37137
37138 self.write_space();
37139 self.write_keyword("THEN");
37140 self.write_space();
37141
37142 self.generate_merge_action(&e.then)?;
37145
37146 Ok(())
37147 }
37148
37149 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
37150 match action {
37151 Expression::Tuple(tuple) => {
37152 let elements = &tuple.expressions;
37153 if elements.is_empty() {
37154 return self.generate_expression(action);
37155 }
37156 match &elements[0] {
37158 Expression::Var(v) if v.this == "INSERT" => {
37159 self.write_keyword("INSERT");
37160 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
37162 self.write(" *");
37163 } else {
37164 let mut values_idx = 1;
37165 if elements.len() > 1 {
37167 if let Expression::Tuple(cols) = &elements[1] {
37168 if elements.len() > 2 {
37170 self.write(" (");
37172 for (i, col) in cols.expressions.iter().enumerate() {
37173 if i > 0 {
37174 self.write(", ");
37175 }
37176 if !self.merge_strip_qualifiers.is_empty() {
37178 let stripped = self.strip_merge_qualifier(col);
37179 self.generate_expression(&stripped)?;
37180 } else {
37181 self.generate_expression(col)?;
37182 }
37183 }
37184 self.write(")");
37185 values_idx = 2;
37186 } else {
37187 values_idx = 1;
37189 }
37190 }
37191 }
37192 if values_idx < elements.len() {
37194 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
37196 if !is_row {
37197 self.write_space();
37198 self.write_keyword("VALUES");
37199 }
37200 self.write(" ");
37201 if let Expression::Tuple(vals) = &elements[values_idx] {
37202 self.write("(");
37203 for (i, val) in vals.expressions.iter().enumerate() {
37204 if i > 0 {
37205 self.write(", ");
37206 }
37207 self.generate_expression(val)?;
37208 }
37209 self.write(")");
37210 } else {
37211 self.generate_expression(&elements[values_idx])?;
37212 }
37213 }
37214 } }
37216 Expression::Var(v) if v.this == "UPDATE" => {
37217 self.write_keyword("UPDATE");
37218 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
37220 self.write(" *");
37221 } else if elements.len() > 1 {
37222 self.write_space();
37223 self.write_keyword("SET");
37224 if self.config.pretty {
37226 self.write_newline();
37227 self.indent_level += 1;
37228 self.write_indent();
37229 } else {
37230 self.write_space();
37231 }
37232 if let Expression::Tuple(assignments) = &elements[1] {
37233 for (i, assignment) in assignments.expressions.iter().enumerate() {
37234 if i > 0 {
37235 if self.config.pretty {
37236 self.write(",");
37237 self.write_newline();
37238 self.write_indent();
37239 } else {
37240 self.write(", ");
37241 }
37242 }
37243 if !self.merge_strip_qualifiers.is_empty() {
37245 self.generate_merge_set_assignment(assignment)?;
37246 } else {
37247 self.generate_expression(assignment)?;
37248 }
37249 }
37250 } else {
37251 self.generate_expression(&elements[1])?;
37252 }
37253 if self.config.pretty {
37254 self.indent_level -= 1;
37255 }
37256 }
37257 }
37258 _ => {
37259 self.generate_expression(action)?;
37261 }
37262 }
37263 }
37264 Expression::Var(v)
37265 if v.this == "INSERT"
37266 || v.this == "UPDATE"
37267 || v.this == "DELETE"
37268 || v.this == "DO NOTHING" =>
37269 {
37270 self.write_keyword(&v.this);
37271 }
37272 _ => {
37273 self.generate_expression(action)?;
37274 }
37275 }
37276 Ok(())
37277 }
37278
37279 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
37281 match assignment {
37282 Expression::Eq(eq) => {
37283 let stripped_left = self.strip_merge_qualifier(&eq.left);
37285 self.generate_expression(&stripped_left)?;
37286 self.write(" = ");
37287 self.generate_expression(&eq.right)?;
37288 Ok(())
37289 }
37290 other => self.generate_expression(other),
37291 }
37292 }
37293
37294 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
37296 match expr {
37297 Expression::Column(col) => {
37298 if let Some(ref table_ident) = col.table {
37299 if self
37300 .merge_strip_qualifiers
37301 .iter()
37302 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
37303 {
37304 let mut col = col.clone();
37306 col.table = None;
37307 return Expression::Column(col);
37308 }
37309 }
37310 expr.clone()
37311 }
37312 Expression::Dot(dot) => {
37313 if let Expression::Identifier(id) = &dot.this {
37315 if self
37316 .merge_strip_qualifiers
37317 .iter()
37318 .any(|n| n.eq_ignore_ascii_case(&id.name))
37319 {
37320 return Expression::Identifier(dot.field.clone());
37321 }
37322 }
37323 expr.clone()
37324 }
37325 _ => expr.clone(),
37326 }
37327 }
37328
37329 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
37330 for (i, expr) in e.expressions.iter().enumerate() {
37332 if i > 0 {
37333 if self.config.pretty {
37335 self.write_newline();
37336 self.write_indent();
37337 } else {
37338 self.write_space();
37339 }
37340 }
37341 self.generate_expression(expr)?;
37342 }
37343 Ok(())
37344 }
37345
37346 fn generate_where(&mut self, e: &Where) -> Result<()> {
37347 self.write_keyword("WHERE");
37349 self.write_space();
37350 self.generate_expression(&e.this)?;
37351 Ok(())
37352 }
37353
37354 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
37355 self.write_keyword("WIDTH_BUCKET");
37357 self.write("(");
37358 self.generate_expression(&e.this)?;
37359 if let Some(min_value) = &e.min_value {
37360 self.write(", ");
37361 self.generate_expression(min_value)?;
37362 }
37363 if let Some(max_value) = &e.max_value {
37364 self.write(", ");
37365 self.generate_expression(max_value)?;
37366 }
37367 if let Some(num_buckets) = &e.num_buckets {
37368 self.write(", ");
37369 self.generate_expression(num_buckets)?;
37370 }
37371 self.write(")");
37372 Ok(())
37373 }
37374
37375 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
37376 self.generate_window_spec(e)
37378 }
37379
37380 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
37381 let mut has_content = false;
37383
37384 if !e.partition_by.is_empty() {
37386 self.write_keyword("PARTITION BY");
37387 self.write_space();
37388 for (i, expr) in e.partition_by.iter().enumerate() {
37389 if i > 0 {
37390 self.write(", ");
37391 }
37392 self.generate_expression(expr)?;
37393 }
37394 has_content = true;
37395 }
37396
37397 if !e.order_by.is_empty() {
37399 if has_content {
37400 self.write_space();
37401 }
37402 self.write_keyword("ORDER BY");
37403 self.write_space();
37404 for (i, ordered) in e.order_by.iter().enumerate() {
37405 if i > 0 {
37406 self.write(", ");
37407 }
37408 self.generate_expression(&ordered.this)?;
37409 if ordered.desc {
37410 self.write_space();
37411 self.write_keyword("DESC");
37412 } else if ordered.explicit_asc {
37413 self.write_space();
37414 self.write_keyword("ASC");
37415 }
37416 if let Some(nulls_first) = ordered.nulls_first {
37417 self.write_space();
37418 self.write_keyword("NULLS");
37419 self.write_space();
37420 if nulls_first {
37421 self.write_keyword("FIRST");
37422 } else {
37423 self.write_keyword("LAST");
37424 }
37425 }
37426 }
37427 has_content = true;
37428 }
37429
37430 if let Some(frame) = &e.frame {
37432 if has_content {
37433 self.write_space();
37434 }
37435 self.generate_window_frame(frame)?;
37436 }
37437
37438 Ok(())
37439 }
37440
37441 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
37442 self.write_keyword("WITH");
37444 self.write_space();
37445 if e.no.is_some() {
37446 self.write_keyword("NO");
37447 self.write_space();
37448 }
37449 self.write_keyword("DATA");
37450
37451 if let Some(statistics) = &e.statistics {
37453 self.write_space();
37454 self.write_keyword("AND");
37455 self.write_space();
37456 match statistics.as_ref() {
37458 Expression::Boolean(b) if !b.value => {
37459 self.write_keyword("NO");
37460 self.write_space();
37461 }
37462 _ => {}
37463 }
37464 self.write_keyword("STATISTICS");
37465 }
37466 Ok(())
37467 }
37468
37469 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
37470 self.write_keyword("WITH FILL");
37472
37473 if let Some(from_) = &e.from_ {
37474 self.write_space();
37475 self.write_keyword("FROM");
37476 self.write_space();
37477 self.generate_expression(from_)?;
37478 }
37479
37480 if let Some(to) = &e.to {
37481 self.write_space();
37482 self.write_keyword("TO");
37483 self.write_space();
37484 self.generate_expression(to)?;
37485 }
37486
37487 if let Some(step) = &e.step {
37488 self.write_space();
37489 self.write_keyword("STEP");
37490 self.write_space();
37491 self.generate_expression(step)?;
37492 }
37493
37494 if let Some(staleness) = &e.staleness {
37495 self.write_space();
37496 self.write_keyword("STALENESS");
37497 self.write_space();
37498 self.generate_expression(staleness)?;
37499 }
37500
37501 if let Some(interpolate) = &e.interpolate {
37502 self.write_space();
37503 self.write_keyword("INTERPOLATE");
37504 self.write(" (");
37505 self.generate_interpolate_item(interpolate)?;
37507 self.write(")");
37508 }
37509
37510 Ok(())
37511 }
37512
37513 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
37515 match expr {
37516 Expression::Alias(alias) => {
37517 self.generate_identifier(&alias.alias)?;
37519 self.write_space();
37520 self.write_keyword("AS");
37521 self.write_space();
37522 self.generate_expression(&alias.this)?;
37523 }
37524 Expression::Tuple(tuple) => {
37525 for (i, item) in tuple.expressions.iter().enumerate() {
37526 if i > 0 {
37527 self.write(", ");
37528 }
37529 self.generate_interpolate_item(item)?;
37530 }
37531 }
37532 other => {
37533 self.generate_expression(other)?;
37534 }
37535 }
37536 Ok(())
37537 }
37538
37539 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
37540 self.write_keyword("WITH JOURNAL TABLE");
37542 self.write("=");
37543 self.generate_expression(&e.this)?;
37544 Ok(())
37545 }
37546
37547 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
37548 self.generate_expression(&e.this)?;
37550 self.write_space();
37551 self.write_keyword("WITH");
37552 self.write_space();
37553 self.write_keyword(&e.op);
37554 Ok(())
37555 }
37556
37557 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
37558 self.write_keyword("WITH");
37560 self.write_space();
37561 for (i, expr) in e.expressions.iter().enumerate() {
37562 if i > 0 {
37563 self.write(", ");
37564 }
37565 self.generate_expression(expr)?;
37566 }
37567 Ok(())
37568 }
37569
37570 fn generate_with_schema_binding_property(
37571 &mut self,
37572 e: &WithSchemaBindingProperty,
37573 ) -> Result<()> {
37574 self.write_keyword("WITH");
37576 self.write_space();
37577 self.generate_expression(&e.this)?;
37578 Ok(())
37579 }
37580
37581 fn generate_with_system_versioning_property(
37582 &mut self,
37583 e: &WithSystemVersioningProperty,
37584 ) -> Result<()> {
37585 let mut parts = Vec::new();
37591
37592 if let Some(this) = &e.this {
37593 let mut s = String::from("HISTORY_TABLE=");
37595 let mut gen = Generator::new();
37596 gen.generate_expression(this)?;
37597 s.push_str(&gen.output);
37598 parts.push(s);
37599 }
37600
37601 if let Some(data_consistency) = &e.data_consistency {
37602 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
37603 let mut gen = Generator::new();
37604 gen.generate_expression(data_consistency)?;
37605 s.push_str(&gen.output);
37606 parts.push(s);
37607 }
37608
37609 if let Some(retention_period) = &e.retention_period {
37610 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
37611 let mut gen = Generator::new();
37612 gen.generate_expression(retention_period)?;
37613 s.push_str(&gen.output);
37614 parts.push(s);
37615 }
37616
37617 self.write_keyword("SYSTEM_VERSIONING");
37618 self.write("=");
37619
37620 if !parts.is_empty() {
37621 self.write_keyword("ON");
37622 self.write("(");
37623 self.write(&parts.join(", "));
37624 self.write(")");
37625 } else if e.on.is_some() {
37626 self.write_keyword("ON");
37627 } else {
37628 self.write_keyword("OFF");
37629 }
37630
37631 if e.with_.is_some() {
37633 let inner = self.output.clone();
37634 self.output.clear();
37635 self.write("WITH(");
37636 self.write(&inner);
37637 self.write(")");
37638 }
37639
37640 Ok(())
37641 }
37642
37643 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
37644 self.write_keyword("WITH");
37646 self.write(" (");
37647 for (i, expr) in e.expressions.iter().enumerate() {
37648 if i > 0 {
37649 self.write(", ");
37650 }
37651 self.generate_expression(expr)?;
37652 }
37653 self.write(")");
37654 Ok(())
37655 }
37656
37657 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
37658 self.write_keyword("XMLELEMENT");
37661 self.write("(");
37662
37663 if e.evalname.is_some() {
37664 self.write_keyword("EVALNAME");
37665 } else {
37666 self.write_keyword("NAME");
37667 }
37668 self.write_space();
37669 self.generate_expression(&e.this)?;
37670
37671 for expr in &e.expressions {
37672 self.write(", ");
37673 self.generate_expression(expr)?;
37674 }
37675 self.write(")");
37676 Ok(())
37677 }
37678
37679 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
37680 self.write_keyword("XMLGET");
37682 self.write("(");
37683 self.generate_expression(&e.this)?;
37684 self.write(", ");
37685 self.generate_expression(&e.expression)?;
37686 if let Some(instance) = &e.instance {
37687 self.write(", ");
37688 self.generate_expression(instance)?;
37689 }
37690 self.write(")");
37691 Ok(())
37692 }
37693
37694 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
37695 self.generate_expression(&e.this)?;
37697 if let Some(expression) = &e.expression {
37698 self.write("(");
37699 self.generate_expression(expression)?;
37700 self.write(")");
37701 }
37702 Ok(())
37703 }
37704
37705 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
37706 self.write_keyword("XMLTABLE");
37708 self.write("(");
37709
37710 if self.config.pretty {
37711 self.indent_level += 1;
37712 self.write_newline();
37713 self.write_indent();
37714 self.generate_expression(&e.this)?;
37715
37716 if let Some(passing) = &e.passing {
37717 self.write_newline();
37718 self.write_indent();
37719 self.write_keyword("PASSING");
37720 if let Expression::Tuple(tuple) = passing.as_ref() {
37721 for expr in &tuple.expressions {
37722 self.write_newline();
37723 self.indent_level += 1;
37724 self.write_indent();
37725 self.generate_expression(expr)?;
37726 self.indent_level -= 1;
37727 }
37728 } else {
37729 self.write_newline();
37730 self.indent_level += 1;
37731 self.write_indent();
37732 self.generate_expression(passing)?;
37733 self.indent_level -= 1;
37734 }
37735 }
37736
37737 if e.by_ref.is_some() {
37738 self.write_newline();
37739 self.write_indent();
37740 self.write_keyword("RETURNING SEQUENCE BY REF");
37741 }
37742
37743 if !e.columns.is_empty() {
37744 self.write_newline();
37745 self.write_indent();
37746 self.write_keyword("COLUMNS");
37747 for (i, col) in e.columns.iter().enumerate() {
37748 self.write_newline();
37749 self.indent_level += 1;
37750 self.write_indent();
37751 self.generate_expression(col)?;
37752 self.indent_level -= 1;
37753 if i < e.columns.len() - 1 {
37754 self.write(",");
37755 }
37756 }
37757 }
37758
37759 self.indent_level -= 1;
37760 self.write_newline();
37761 self.write_indent();
37762 self.write(")");
37763 return Ok(());
37764 }
37765
37766 if let Some(namespaces) = &e.namespaces {
37768 self.write_keyword("XMLNAMESPACES");
37769 self.write("(");
37770 if let Expression::Tuple(tuple) = namespaces.as_ref() {
37772 for (i, expr) in tuple.expressions.iter().enumerate() {
37773 if i > 0 {
37774 self.write(", ");
37775 }
37776 if !matches!(expr, Expression::Alias(_)) {
37779 self.write_keyword("DEFAULT");
37780 self.write_space();
37781 }
37782 self.generate_expression(expr)?;
37783 }
37784 } else {
37785 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
37787 self.write_keyword("DEFAULT");
37788 self.write_space();
37789 }
37790 self.generate_expression(namespaces)?;
37791 }
37792 self.write("), ");
37793 }
37794
37795 self.generate_expression(&e.this)?;
37797
37798 if let Some(passing) = &e.passing {
37800 self.write_space();
37801 self.write_keyword("PASSING");
37802 self.write_space();
37803 if let Expression::Tuple(tuple) = passing.as_ref() {
37805 for (i, expr) in tuple.expressions.iter().enumerate() {
37806 if i > 0 {
37807 self.write(", ");
37808 }
37809 self.generate_expression(expr)?;
37810 }
37811 } else {
37812 self.generate_expression(passing)?;
37813 }
37814 }
37815
37816 if e.by_ref.is_some() {
37818 self.write_space();
37819 self.write_keyword("RETURNING SEQUENCE BY REF");
37820 }
37821
37822 if !e.columns.is_empty() {
37824 self.write_space();
37825 self.write_keyword("COLUMNS");
37826 self.write_space();
37827 for (i, col) in e.columns.iter().enumerate() {
37828 if i > 0 {
37829 self.write(", ");
37830 }
37831 self.generate_expression(col)?;
37832 }
37833 }
37834
37835 self.write(")");
37836 Ok(())
37837 }
37838
37839 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
37840 if let Some(this) = &e.this {
37843 self.generate_expression(this)?;
37844 if let Some(expression) = &e.expression {
37845 self.write_space();
37846 self.write_keyword("XOR");
37847 self.write_space();
37848 self.generate_expression(expression)?;
37849 }
37850 }
37851
37852 for (i, expr) in e.expressions.iter().enumerate() {
37854 if i > 0 || e.this.is_some() {
37855 self.write_space();
37856 self.write_keyword("XOR");
37857 self.write_space();
37858 }
37859 self.generate_expression(expr)?;
37860 }
37861 Ok(())
37862 }
37863
37864 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
37865 self.write_keyword("ZIPF");
37867 self.write("(");
37868 self.generate_expression(&e.this)?;
37869 if let Some(elementcount) = &e.elementcount {
37870 self.write(", ");
37871 self.generate_expression(elementcount)?;
37872 }
37873 if let Some(gen) = &e.gen {
37874 self.write(", ");
37875 self.generate_expression(gen)?;
37876 }
37877 self.write(")");
37878 Ok(())
37879 }
37880}
37881
37882impl Default for Generator {
37883 fn default() -> Self {
37884 Self::new()
37885 }
37886}
37887
37888#[cfg(test)]
37889mod tests {
37890 use super::*;
37891 use crate::parser::Parser;
37892
37893 fn roundtrip(sql: &str) -> String {
37894 let ast = Parser::parse_sql(sql).unwrap();
37895 Generator::sql(&ast[0]).unwrap()
37896 }
37897
37898 #[test]
37899 fn test_simple_select() {
37900 let result = roundtrip("SELECT 1");
37901 assert_eq!(result, "SELECT 1");
37902 }
37903
37904 #[test]
37905 fn test_select_from() {
37906 let result = roundtrip("SELECT a, b FROM t");
37907 assert_eq!(result, "SELECT a, b FROM t");
37908 }
37909
37910 #[test]
37911 fn test_select_where() {
37912 let result = roundtrip("SELECT * FROM t WHERE x = 1");
37913 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
37914 }
37915
37916 #[test]
37917 fn test_select_join() {
37918 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
37919 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
37920 }
37921
37922 #[test]
37923 fn test_insert() {
37924 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
37925 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
37926 }
37927
37928 #[test]
37929 fn test_pretty_print() {
37930 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
37931 let result = Generator::pretty_sql(&ast[0]).unwrap();
37932 assert!(result.contains('\n'));
37933 }
37934
37935 #[test]
37936 fn test_window_function() {
37937 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
37938 assert_eq!(
37939 result,
37940 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
37941 );
37942 }
37943
37944 #[test]
37945 fn test_window_function_with_frame() {
37946 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
37947 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
37948 }
37949
37950 #[test]
37951 fn test_aggregate_with_filter() {
37952 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
37953 assert_eq!(
37954 result,
37955 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
37956 );
37957 }
37958
37959 #[test]
37960 fn test_subscript() {
37961 let result = roundtrip("SELECT arr[0]");
37962 assert_eq!(result, "SELECT arr[0]");
37963 }
37964
37965 #[test]
37967 fn test_create_table() {
37968 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
37969 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
37970 }
37971
37972 #[test]
37973 fn test_create_table_with_constraints() {
37974 let result = roundtrip(
37975 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
37976 );
37977 assert_eq!(
37978 result,
37979 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
37980 );
37981 }
37982
37983 #[test]
37984 fn test_create_table_if_not_exists() {
37985 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
37986 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
37987 }
37988
37989 #[test]
37990 fn test_drop_table() {
37991 let result = roundtrip("DROP TABLE users");
37992 assert_eq!(result, "DROP TABLE users");
37993 }
37994
37995 #[test]
37996 fn test_drop_table_if_exists_cascade() {
37997 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
37998 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
37999 }
38000
38001 #[test]
38002 fn test_alter_table_add_column() {
38003 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
38004 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
38005 }
38006
38007 #[test]
38008 fn test_alter_table_drop_column() {
38009 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
38010 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
38011 }
38012
38013 #[test]
38014 fn test_create_index() {
38015 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
38016 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
38017 }
38018
38019 #[test]
38020 fn test_create_unique_index() {
38021 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
38022 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
38023 }
38024
38025 #[test]
38026 fn test_drop_index() {
38027 let result = roundtrip("DROP INDEX idx_name");
38028 assert_eq!(result, "DROP INDEX idx_name");
38029 }
38030
38031 #[test]
38032 fn test_create_view() {
38033 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
38034 assert_eq!(
38035 result,
38036 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
38037 );
38038 }
38039
38040 #[test]
38041 fn test_drop_view() {
38042 let result = roundtrip("DROP VIEW active_users");
38043 assert_eq!(result, "DROP VIEW active_users");
38044 }
38045
38046 #[test]
38047 fn test_truncate() {
38048 let result = roundtrip("TRUNCATE TABLE users");
38049 assert_eq!(result, "TRUNCATE TABLE users");
38050 }
38051
38052 #[test]
38053 fn test_string_literal_escaping_default() {
38054 let result = roundtrip("SELECT 'hello'");
38056 assert_eq!(result, "SELECT 'hello'");
38057
38058 let result = roundtrip("SELECT 'it''s a test'");
38060 assert_eq!(result, "SELECT 'it''s a test'");
38061 }
38062
38063 #[test]
38064 fn test_not_in_style_prefix_default_generic() {
38065 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
38066 assert_eq!(
38067 result,
38068 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
38069 );
38070 }
38071
38072 #[test]
38073 fn test_not_in_style_infix_generic_override() {
38074 let ast =
38075 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
38076 .unwrap();
38077 let config = GeneratorConfig {
38078 not_in_style: NotInStyle::Infix,
38079 ..Default::default()
38080 };
38081 let mut gen = Generator::with_config(config);
38082 let result = gen.generate(&ast[0]).unwrap();
38083 assert_eq!(
38084 result,
38085 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
38086 );
38087 }
38088
38089 #[test]
38090 fn test_string_literal_escaping_mysql() {
38091 use crate::dialects::DialectType;
38092
38093 let config = GeneratorConfig {
38094 dialect: Some(DialectType::MySQL),
38095 ..Default::default()
38096 };
38097
38098 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38099 let mut gen = Generator::with_config(config.clone());
38100 let result = gen.generate(&ast[0]).unwrap();
38101 assert_eq!(result, "SELECT 'hello'");
38102
38103 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38105 let mut gen = Generator::with_config(config.clone());
38106 let result = gen.generate(&ast[0]).unwrap();
38107 assert_eq!(result, "SELECT 'it''s'");
38108 }
38109
38110 #[test]
38111 fn test_string_literal_escaping_postgres() {
38112 use crate::dialects::DialectType;
38113
38114 let config = GeneratorConfig {
38115 dialect: Some(DialectType::PostgreSQL),
38116 ..Default::default()
38117 };
38118
38119 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38120 let mut gen = Generator::with_config(config.clone());
38121 let result = gen.generate(&ast[0]).unwrap();
38122 assert_eq!(result, "SELECT 'hello'");
38123
38124 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38126 let mut gen = Generator::with_config(config.clone());
38127 let result = gen.generate(&ast[0]).unwrap();
38128 assert_eq!(result, "SELECT 'it''s'");
38129 }
38130
38131 #[test]
38132 fn test_string_literal_escaping_bigquery() {
38133 use crate::dialects::DialectType;
38134
38135 let config = GeneratorConfig {
38136 dialect: Some(DialectType::BigQuery),
38137 ..Default::default()
38138 };
38139
38140 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38141 let mut gen = Generator::with_config(config.clone());
38142 let result = gen.generate(&ast[0]).unwrap();
38143 assert_eq!(result, "SELECT 'hello'");
38144
38145 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38147 let mut gen = Generator::with_config(config.clone());
38148 let result = gen.generate(&ast[0]).unwrap();
38149 assert_eq!(result, "SELECT 'it\\'s'");
38150 }
38151
38152 #[test]
38153 fn test_generate_deep_and_chain_without_stack_growth() {
38154 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
38155 Expression::column("c0"),
38156 Expression::number(0),
38157 )));
38158
38159 for i in 1..2500 {
38160 let predicate = Expression::Eq(Box::new(BinaryOp::new(
38161 Expression::column(format!("c{i}")),
38162 Expression::number(i as i64),
38163 )));
38164 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
38165 }
38166
38167 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
38168 assert!(sql.contains("c2499 = 2499"), "{}", sql);
38169 }
38170
38171 #[test]
38172 fn test_generate_deep_or_chain_without_stack_growth() {
38173 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
38174 Expression::column("c0"),
38175 Expression::number(0),
38176 )));
38177
38178 for i in 1..2500 {
38179 let predicate = Expression::Eq(Box::new(BinaryOp::new(
38180 Expression::column(format!("c{i}")),
38181 Expression::number(i as i64),
38182 )));
38183 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
38184 }
38185
38186 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
38187 assert!(sql.contains("c2499 = 2499"), "{}", sql);
38188 }
38189}