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 !ct.with_partition_columns.is_empty() {
7952 if self.config.pretty {
7953 self.write_newline();
7954 } else {
7955 self.write_space();
7956 }
7957 self.write_keyword("WITH PARTITION COLUMNS");
7958 self.write(" (");
7959 if self.config.pretty {
7960 self.write_newline();
7961 self.indent_level += 1;
7962 for (i, col) in ct.with_partition_columns.iter().enumerate() {
7963 if i > 0 {
7964 self.write(",");
7965 self.write_newline();
7966 }
7967 self.write_indent();
7968 self.generate_column_def(col)?;
7969 }
7970 self.indent_level -= 1;
7971 self.write_newline();
7972 } else {
7973 for (i, col) in ct.with_partition_columns.iter().enumerate() {
7974 if i > 0 {
7975 self.write(", ");
7976 }
7977 self.generate_column_def(col)?;
7978 }
7979 }
7980 self.write(")");
7981 }
7982
7983 if let Some(ref conn) = ct.with_connection {
7985 if self.config.pretty {
7986 self.write_newline();
7987 } else {
7988 self.write_space();
7989 }
7990 self.write_keyword("WITH CONNECTION");
7991 self.write_space();
7992 self.generate_table(conn)?;
7993 }
7994
7995 if !is_clickhouse {
7998 for prop in &ct.properties {
7999 if let Expression::SchemaCommentProperty(_) = prop {
8000 if self.config.pretty {
8001 self.write_newline();
8002 } else {
8003 self.write_space();
8004 }
8005 self.generate_expression(prop)?;
8006 }
8007 }
8008 }
8009
8010 if !ct.with_properties.is_empty() {
8012 let is_snowflake_special_table = matches!(
8014 self.config.dialect,
8015 Some(crate::dialects::DialectType::Snowflake)
8016 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
8017 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
8018 if is_snowflake_special_table {
8019 for (key, value) in &ct.with_properties {
8020 self.write_space();
8021 self.write(key);
8022 self.write("=");
8023 self.write(value);
8024 }
8025 } else if self.config.pretty {
8026 self.write_newline();
8027 self.write_keyword("WITH");
8028 self.write(" (");
8029 self.write_newline();
8030 self.indent_level += 1;
8031 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8032 if i > 0 {
8033 self.write(",");
8034 self.write_newline();
8035 }
8036 self.write_indent();
8037 self.write(key);
8038 self.write("=");
8039 self.write(value);
8040 }
8041 self.indent_level -= 1;
8042 self.write_newline();
8043 self.write(")");
8044 } else {
8045 self.write_space();
8046 self.write_keyword("WITH");
8047 self.write(" (");
8048 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8049 if i > 0 {
8050 self.write(", ");
8051 }
8052 self.write(key);
8053 self.write("=");
8054 self.write(value);
8055 }
8056 self.write(")");
8057 }
8058 }
8059
8060 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
8061 if is_clickhouse && ct.as_select.is_some() {
8062 let mut pre = Vec::new();
8063 let mut post = Vec::new();
8064 for prop in &ct.properties {
8065 if matches!(prop, Expression::SchemaCommentProperty(_)) {
8066 post.push(prop);
8067 } else {
8068 pre.push(prop);
8069 }
8070 }
8071 (pre, post)
8072 } else {
8073 (ct.properties.iter().collect(), Vec::new())
8074 };
8075
8076 for prop in pre_as_properties {
8078 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
8080 continue;
8081 }
8082 if self.config.pretty {
8083 self.write_newline();
8084 } else {
8085 self.write_space();
8086 }
8087 if let Expression::Properties(props) = prop {
8091 let is_hive_dialect = matches!(
8092 self.config.dialect,
8093 Some(crate::dialects::DialectType::Hive)
8094 | Some(crate::dialects::DialectType::Spark)
8095 | Some(crate::dialects::DialectType::Databricks)
8096 | Some(crate::dialects::DialectType::Athena)
8097 );
8098 let is_doris_starrocks = matches!(
8099 self.config.dialect,
8100 Some(crate::dialects::DialectType::Doris)
8101 | Some(crate::dialects::DialectType::StarRocks)
8102 );
8103 if is_hive_dialect {
8104 self.generate_tblproperties_clause(&props.expressions)?;
8105 } else if is_doris_starrocks {
8106 self.generate_properties_clause(&props.expressions)?;
8107 } else {
8108 self.generate_options_clause(&props.expressions)?;
8109 }
8110 } else {
8111 self.generate_expression(prop)?;
8112 }
8113 }
8114
8115 for prop in &ct.post_table_properties {
8117 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
8118 self.write(" WITH(");
8119 self.generate_system_versioning_content(svp)?;
8120 self.write(")");
8121 } else if let Expression::Properties(props) = prop {
8122 let is_doris_starrocks = matches!(
8124 self.config.dialect,
8125 Some(crate::dialects::DialectType::Doris)
8126 | Some(crate::dialects::DialectType::StarRocks)
8127 );
8128 self.write_space();
8129 if is_doris_starrocks {
8130 self.generate_properties_clause(&props.expressions)?;
8131 } else {
8132 self.generate_options_clause(&props.expressions)?;
8133 }
8134 } else {
8135 self.write_space();
8136 self.generate_expression(prop)?;
8137 }
8138 }
8139
8140 if let Some(ref rollup) = ct.rollup {
8143 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
8144 self.write_space();
8145 self.generate_rollup_property(rollup)?;
8146 }
8147 }
8148
8149 let is_mysql_compatible = matches!(
8153 self.config.dialect,
8154 Some(DialectType::MySQL)
8155 | Some(DialectType::SingleStore)
8156 | Some(DialectType::Doris)
8157 | Some(DialectType::StarRocks)
8158 | None
8159 );
8160 let is_hive_compatible = matches!(
8161 self.config.dialect,
8162 Some(DialectType::Hive)
8163 | Some(DialectType::Spark)
8164 | Some(DialectType::Databricks)
8165 | Some(DialectType::Athena)
8166 );
8167 let mysql_pretty_options =
8168 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
8169 for (key, value) in &ct.mysql_table_options {
8170 let should_output = if is_mysql_compatible {
8172 true
8173 } else if is_hive_compatible && key == "COMMENT" {
8174 true } else {
8176 false
8177 };
8178 if should_output {
8179 if mysql_pretty_options {
8180 self.write_newline();
8181 self.write_indent();
8182 } else {
8183 self.write_space();
8184 }
8185 self.write_keyword(key);
8186 if key == "COMMENT" && !self.config.schema_comment_with_eq {
8188 self.write_space();
8189 } else {
8190 self.write("=");
8191 }
8192 self.write(value);
8193 }
8194 }
8195
8196 if ct.temporary
8198 && matches!(
8199 self.config.dialect,
8200 Some(DialectType::Spark) | Some(DialectType::Databricks)
8201 )
8202 && ct.as_select.is_none()
8203 {
8204 self.write_space();
8205 self.write_keyword("USING PARQUET");
8206 }
8207
8208 if !ct.inherits.is_empty() {
8210 self.write_space();
8211 self.write_keyword("INHERITS");
8212 self.write(" (");
8213 for (i, parent) in ct.inherits.iter().enumerate() {
8214 if i > 0 {
8215 self.write(", ");
8216 }
8217 self.generate_table(parent)?;
8218 }
8219 self.write(")");
8220 }
8221
8222 if let Some(ref query) = ct.as_select {
8224 self.write_space();
8225 self.write_keyword("AS");
8226 self.write_space();
8227 if ct.as_select_parenthesized {
8228 self.write("(");
8229 }
8230 self.generate_expression(query)?;
8231 if ct.as_select_parenthesized {
8232 self.write(")");
8233 }
8234
8235 if let Some(with_data) = ct.with_data {
8237 self.write_space();
8238 self.write_keyword("WITH");
8239 if !with_data {
8240 self.write_space();
8241 self.write_keyword("NO");
8242 }
8243 self.write_space();
8244 self.write_keyword("DATA");
8245 }
8246
8247 if let Some(with_statistics) = ct.with_statistics {
8249 self.write_space();
8250 self.write_keyword("AND");
8251 if !with_statistics {
8252 self.write_space();
8253 self.write_keyword("NO");
8254 }
8255 self.write_space();
8256 self.write_keyword("STATISTICS");
8257 }
8258
8259 for index in &ct.teradata_indexes {
8261 self.write_space();
8262 match index.kind {
8263 TeradataIndexKind::NoPrimary => {
8264 self.write_keyword("NO PRIMARY INDEX");
8265 }
8266 TeradataIndexKind::Primary => {
8267 self.write_keyword("PRIMARY INDEX");
8268 }
8269 TeradataIndexKind::PrimaryAmp => {
8270 self.write_keyword("PRIMARY AMP INDEX");
8271 }
8272 TeradataIndexKind::Unique => {
8273 self.write_keyword("UNIQUE INDEX");
8274 }
8275 TeradataIndexKind::UniquePrimary => {
8276 self.write_keyword("UNIQUE PRIMARY INDEX");
8277 }
8278 TeradataIndexKind::Secondary => {
8279 self.write_keyword("INDEX");
8280 }
8281 }
8282 if let Some(ref name) = index.name {
8284 self.write_space();
8285 self.write(name);
8286 }
8287 if !index.columns.is_empty() {
8289 self.write(" (");
8290 for (i, col) in index.columns.iter().enumerate() {
8291 if i > 0 {
8292 self.write(", ");
8293 }
8294 self.write(col);
8295 }
8296 self.write(")");
8297 }
8298 }
8299
8300 if let Some(ref on_commit) = ct.on_commit {
8302 self.write_space();
8303 self.write_keyword("ON COMMIT");
8304 self.write_space();
8305 match on_commit {
8306 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8307 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8308 }
8309 }
8310
8311 if !post_as_properties.is_empty() {
8312 for prop in post_as_properties {
8313 self.write_space();
8314 self.generate_expression(prop)?;
8315 }
8316 }
8317
8318 self.athena_hive_context = saved_athena_hive_context;
8320 return Ok(());
8321 }
8322
8323 if let Some(ref on_commit) = ct.on_commit {
8325 self.write_space();
8326 self.write_keyword("ON COMMIT");
8327 self.write_space();
8328 match on_commit {
8329 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8330 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8331 }
8332 }
8333
8334 self.athena_hive_context = saved_athena_hive_context;
8336
8337 Ok(())
8338 }
8339
8340 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
8343 self.generate_identifier(&col.name)?;
8345 if !matches!(col.data_type, DataType::Unknown) {
8347 self.write_space();
8348 self.generate_data_type(&col.data_type)?;
8349 }
8350 for constraint in &col.constraints {
8352 if let ColumnConstraint::Path(path_expr) = constraint {
8353 self.write_space();
8354 self.write_keyword("PATH");
8355 self.write_space();
8356 self.generate_expression(path_expr)?;
8357 }
8358 }
8359 Ok(())
8360 }
8361
8362 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
8363 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8365 && col
8366 .constraints
8367 .iter()
8368 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8369 let omit_computed_type = !self.config.computed_column_with_type
8371 && col
8372 .constraints
8373 .iter()
8374 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8375
8376 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
8379
8380 let has_no_type = col.no_type
8383 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8384 && col.constraints.is_empty());
8385
8386 self.generate_identifier(&col.name)?;
8387
8388 let serial_expansion = if matches!(
8390 self.config.dialect,
8391 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
8392 ) {
8393 if let DataType::Custom { ref name } = col.data_type {
8394 if name.eq_ignore_ascii_case("SERIAL") {
8395 Some("INT")
8396 } else if name.eq_ignore_ascii_case("BIGSERIAL") {
8397 Some("BIGINT")
8398 } else if name.eq_ignore_ascii_case("SMALLSERIAL") {
8399 Some("SMALLINT")
8400 } else {
8401 None
8402 }
8403 } else {
8404 None
8405 }
8406 } else {
8407 None
8408 };
8409
8410 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
8411 {
8412 self.write_space();
8413 let saved_nullable_depth = self.clickhouse_nullable_depth;
8416 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
8417 self.clickhouse_nullable_depth = -1;
8418 }
8419 if let Some(int_type) = serial_expansion {
8420 self.write_keyword(int_type);
8422 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8423 let unsigned_type = match &col.data_type {
8425 DataType::Int { .. } => Some("UINTEGER"),
8426 DataType::BigInt { .. } => Some("UBIGINT"),
8427 DataType::SmallInt { .. } => Some("USMALLINT"),
8428 DataType::TinyInt { .. } => Some("UTINYINT"),
8429 _ => None,
8430 };
8431 if let Some(utype) = unsigned_type {
8432 self.write_keyword(utype);
8433 } else {
8434 self.generate_data_type(&col.data_type)?;
8435 }
8436 } else {
8437 self.generate_data_type(&col.data_type)?;
8438 }
8439 self.clickhouse_nullable_depth = saved_nullable_depth;
8440 }
8441
8442 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8445 self.write_space();
8446 self.write_keyword("UNSIGNED");
8447 }
8448 if col.zerofill {
8449 self.write_space();
8450 self.write_keyword("ZEROFILL");
8451 }
8452
8453 if let Some(ref charset) = col.character_set {
8457 self.write_space();
8458 self.write_keyword("CHARACTER SET");
8459 self.write_space();
8460 self.write(charset);
8461 }
8462
8463 if col.uppercase {
8464 self.write_space();
8465 self.write_keyword("UPPERCASE");
8466 }
8467
8468 if let Some(casespecific) = col.casespecific {
8469 self.write_space();
8470 if casespecific {
8471 self.write_keyword("CASESPECIFIC");
8472 } else {
8473 self.write_keyword("NOT CASESPECIFIC");
8474 }
8475 }
8476
8477 if let Some(ref format) = col.format {
8478 self.write_space();
8479 self.write_keyword("FORMAT");
8480 self.write(" '");
8481 self.write(format);
8482 self.write("'");
8483 }
8484
8485 if let Some(ref title) = col.title {
8486 self.write_space();
8487 self.write_keyword("TITLE");
8488 self.write(" '");
8489 self.write(title);
8490 self.write("'");
8491 }
8492
8493 if let Some(length) = col.inline_length {
8494 self.write_space();
8495 self.write_keyword("INLINE LENGTH");
8496 self.write(" ");
8497 self.write(&length.to_string());
8498 }
8499
8500 if let Some(ref compress) = col.compress {
8501 self.write_space();
8502 self.write_keyword("COMPRESS");
8503 if !compress.is_empty() {
8504 if compress.len() == 1 {
8506 if let Expression::Literal(lit) = &compress[0] {
8507 if let Literal::String(_) = lit.as_ref() {
8508 self.write_space();
8509 self.generate_expression(&compress[0])?;
8510 }
8511 } else {
8512 self.write(" (");
8513 self.generate_expression(&compress[0])?;
8514 self.write(")");
8515 }
8516 } else {
8517 self.write(" (");
8518 for (i, val) in compress.iter().enumerate() {
8519 if i > 0 {
8520 self.write(", ");
8521 }
8522 self.generate_expression(val)?;
8523 }
8524 self.write(")");
8525 }
8526 }
8527 }
8528
8529 if !col.constraint_order.is_empty() {
8532 let mut references_idx = 0;
8535 let mut check_idx = 0;
8536 let mut generated_idx = 0;
8537 let mut collate_idx = 0;
8538 let mut comment_idx = 0;
8539 let defer_not_null_after_identity = false;
8542 let mut pending_not_null_after_identity = false;
8543
8544 for constraint_type in &col.constraint_order {
8545 match constraint_type {
8546 ConstraintType::PrimaryKey => {
8547 if col.primary_key
8549 && !matches!(self.config.dialect, Some(DialectType::Materialize))
8550 {
8551 if let Some(ref cname) = col.primary_key_constraint_name {
8552 self.write_space();
8553 self.write_keyword("CONSTRAINT");
8554 self.write_space();
8555 self.write(cname);
8556 }
8557 self.write_space();
8558 self.write_keyword("PRIMARY KEY");
8559 if let Some(ref order) = col.primary_key_order {
8560 self.write_space();
8561 match order {
8562 SortOrder::Asc => self.write_keyword("ASC"),
8563 SortOrder::Desc => self.write_keyword("DESC"),
8564 }
8565 }
8566 }
8567 }
8568 ConstraintType::Unique => {
8569 if col.unique {
8570 if let Some(ref cname) = col.unique_constraint_name {
8571 self.write_space();
8572 self.write_keyword("CONSTRAINT");
8573 self.write_space();
8574 self.write(cname);
8575 }
8576 self.write_space();
8577 self.write_keyword("UNIQUE");
8578 if col.unique_nulls_not_distinct {
8580 self.write(" NULLS NOT DISTINCT");
8581 }
8582 }
8583 }
8584 ConstraintType::NotNull => {
8585 if col.nullable == Some(false) {
8586 if defer_not_null_after_identity {
8587 pending_not_null_after_identity = true;
8588 continue;
8589 }
8590 if let Some(ref cname) = col.not_null_constraint_name {
8591 self.write_space();
8592 self.write_keyword("CONSTRAINT");
8593 self.write_space();
8594 self.write(cname);
8595 }
8596 self.write_space();
8597 self.write_keyword("NOT NULL");
8598 }
8599 }
8600 ConstraintType::Null => {
8601 if col.nullable == Some(true) {
8602 self.write_space();
8603 self.write_keyword("NULL");
8604 }
8605 }
8606 ConstraintType::Default => {
8607 if let Some(ref default) = col.default {
8608 self.write_space();
8609 self.write_keyword("DEFAULT");
8610 self.write_space();
8611 self.generate_expression(default)?;
8612 }
8613 }
8614 ConstraintType::AutoIncrement => {
8615 if col.auto_increment {
8616 if matches!(
8618 self.config.dialect,
8619 Some(crate::dialects::DialectType::DuckDB)
8620 ) {
8621 } else if matches!(
8623 self.config.dialect,
8624 Some(crate::dialects::DialectType::Materialize)
8625 ) {
8626 if !matches!(col.nullable, Some(false)) {
8628 self.write_space();
8629 self.write_keyword("NOT NULL");
8630 }
8631 } else if matches!(
8632 self.config.dialect,
8633 Some(crate::dialects::DialectType::PostgreSQL)
8634 ) {
8635 self.write_space();
8637 self.generate_auto_increment_keyword(col)?;
8638 } else {
8639 self.write_space();
8640 self.generate_auto_increment_keyword(col)?;
8641 if pending_not_null_after_identity {
8642 self.write_space();
8643 self.write_keyword("NOT NULL");
8644 pending_not_null_after_identity = false;
8645 }
8646 }
8647 } }
8649 ConstraintType::References => {
8650 while references_idx < col.constraints.len() {
8652 if let ColumnConstraint::References(fk_ref) =
8653 &col.constraints[references_idx]
8654 {
8655 if let Some(ref name) = fk_ref.constraint_name {
8657 self.write_space();
8658 self.write_keyword("CONSTRAINT");
8659 self.write_space();
8660 self.write(name);
8661 }
8662 self.write_space();
8663 if fk_ref.has_foreign_key_keywords {
8664 self.write_keyword("FOREIGN KEY");
8665 self.write_space();
8666 }
8667 self.write_keyword("REFERENCES");
8668 self.write_space();
8669 self.generate_table(&fk_ref.table)?;
8670 if !fk_ref.columns.is_empty() {
8671 self.write(" (");
8672 for (i, c) in fk_ref.columns.iter().enumerate() {
8673 if i > 0 {
8674 self.write(", ");
8675 }
8676 self.generate_identifier(c)?;
8677 }
8678 self.write(")");
8679 }
8680 self.generate_referential_actions(fk_ref)?;
8681 references_idx += 1;
8682 break;
8683 }
8684 references_idx += 1;
8685 }
8686 }
8687 ConstraintType::Check => {
8688 while check_idx < col.constraints.len() {
8690 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
8691 if check_idx == 0 {
8693 if let Some(ref cname) = col.check_constraint_name {
8694 self.write_space();
8695 self.write_keyword("CONSTRAINT");
8696 self.write_space();
8697 self.write(cname);
8698 }
8699 }
8700 self.write_space();
8701 self.write_keyword("CHECK");
8702 self.write(" (");
8703 self.generate_expression(expr)?;
8704 self.write(")");
8705 check_idx += 1;
8706 break;
8707 }
8708 check_idx += 1;
8709 }
8710 }
8711 ConstraintType::GeneratedAsIdentity => {
8712 while generated_idx < col.constraints.len() {
8714 if let ColumnConstraint::GeneratedAsIdentity(gen) =
8715 &col.constraints[generated_idx]
8716 {
8717 self.write_space();
8718 if matches!(
8720 self.config.dialect,
8721 Some(crate::dialects::DialectType::Redshift)
8722 ) {
8723 self.write_keyword("IDENTITY");
8724 self.write("(");
8725 if let Some(ref start) = gen.start {
8726 self.generate_expression(start)?;
8727 } else {
8728 self.write("0");
8729 }
8730 self.write(", ");
8731 if let Some(ref incr) = gen.increment {
8732 self.generate_expression(incr)?;
8733 } else {
8734 self.write("1");
8735 }
8736 self.write(")");
8737 } else {
8738 self.write_keyword("GENERATED");
8739 if gen.always {
8740 self.write_space();
8741 self.write_keyword("ALWAYS");
8742 } else {
8743 self.write_space();
8744 self.write_keyword("BY DEFAULT");
8745 if gen.on_null {
8746 self.write_space();
8747 self.write_keyword("ON NULL");
8748 }
8749 }
8750 self.write_space();
8751 self.write_keyword("AS IDENTITY");
8752
8753 let has_options = gen.start.is_some()
8754 || gen.increment.is_some()
8755 || gen.minvalue.is_some()
8756 || gen.maxvalue.is_some()
8757 || gen.cycle.is_some();
8758 if has_options {
8759 self.write(" (");
8760 let mut first = true;
8761 if let Some(ref start) = gen.start {
8762 if !first {
8763 self.write(" ");
8764 }
8765 first = false;
8766 self.write_keyword("START WITH");
8767 self.write_space();
8768 self.generate_expression(start)?;
8769 }
8770 if let Some(ref incr) = gen.increment {
8771 if !first {
8772 self.write(" ");
8773 }
8774 first = false;
8775 self.write_keyword("INCREMENT BY");
8776 self.write_space();
8777 self.generate_expression(incr)?;
8778 }
8779 if let Some(ref minv) = gen.minvalue {
8780 if !first {
8781 self.write(" ");
8782 }
8783 first = false;
8784 self.write_keyword("MINVALUE");
8785 self.write_space();
8786 self.generate_expression(minv)?;
8787 }
8788 if let Some(ref maxv) = gen.maxvalue {
8789 if !first {
8790 self.write(" ");
8791 }
8792 first = false;
8793 self.write_keyword("MAXVALUE");
8794 self.write_space();
8795 self.generate_expression(maxv)?;
8796 }
8797 if let Some(cycle) = gen.cycle {
8798 if !first {
8799 self.write(" ");
8800 }
8801 if cycle {
8802 self.write_keyword("CYCLE");
8803 } else {
8804 self.write_keyword("NO CYCLE");
8805 }
8806 }
8807 self.write(")");
8808 }
8809 }
8810 generated_idx += 1;
8811 break;
8812 }
8813 generated_idx += 1;
8814 }
8815 }
8816 ConstraintType::Collate => {
8817 while collate_idx < col.constraints.len() {
8819 if let ColumnConstraint::Collate(collation) =
8820 &col.constraints[collate_idx]
8821 {
8822 self.write_space();
8823 self.write_keyword("COLLATE");
8824 self.write_space();
8825 self.generate_identifier(collation)?;
8826 collate_idx += 1;
8827 break;
8828 }
8829 collate_idx += 1;
8830 }
8831 }
8832 ConstraintType::Comment => {
8833 while comment_idx < col.constraints.len() {
8835 if let ColumnConstraint::Comment(comment) =
8836 &col.constraints[comment_idx]
8837 {
8838 self.write_space();
8839 self.write_keyword("COMMENT");
8840 self.write_space();
8841 self.generate_string_literal(comment)?;
8842 comment_idx += 1;
8843 break;
8844 }
8845 comment_idx += 1;
8846 }
8847 }
8848 ConstraintType::Tags => {
8849 for constraint in &col.constraints {
8851 if let ColumnConstraint::Tags(tags) = constraint {
8852 self.write_space();
8853 self.write_keyword("TAG");
8854 self.write(" (");
8855 for (i, expr) in tags.expressions.iter().enumerate() {
8856 if i > 0 {
8857 self.write(", ");
8858 }
8859 self.generate_expression(expr)?;
8860 }
8861 self.write(")");
8862 break;
8863 }
8864 }
8865 }
8866 ConstraintType::ComputedColumn => {
8867 for constraint in &col.constraints {
8869 if let ColumnConstraint::ComputedColumn(cc) = constraint {
8870 self.write_space();
8871 self.generate_computed_column_inline(cc)?;
8872 break;
8873 }
8874 }
8875 }
8876 ConstraintType::GeneratedAsRow => {
8877 for constraint in &col.constraints {
8879 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
8880 self.write_space();
8881 self.generate_generated_as_row_inline(gar)?;
8882 break;
8883 }
8884 }
8885 }
8886 ConstraintType::OnUpdate => {
8887 if let Some(ref expr) = col.on_update {
8888 self.write_space();
8889 self.write_keyword("ON UPDATE");
8890 self.write_space();
8891 self.generate_expression(expr)?;
8892 }
8893 }
8894 ConstraintType::Encode => {
8895 if let Some(ref encoding) = col.encoding {
8896 self.write_space();
8897 self.write_keyword("ENCODE");
8898 self.write_space();
8899 self.write(encoding);
8900 }
8901 }
8902 ConstraintType::Path => {
8903 for constraint in &col.constraints {
8905 if let ColumnConstraint::Path(path_expr) = constraint {
8906 self.write_space();
8907 self.write_keyword("PATH");
8908 self.write_space();
8909 self.generate_expression(path_expr)?;
8910 break;
8911 }
8912 }
8913 }
8914 }
8915 }
8916 if pending_not_null_after_identity {
8917 self.write_space();
8918 self.write_keyword("NOT NULL");
8919 }
8920 } else {
8921 if col.primary_key {
8923 self.write_space();
8924 self.write_keyword("PRIMARY KEY");
8925 if let Some(ref order) = col.primary_key_order {
8926 self.write_space();
8927 match order {
8928 SortOrder::Asc => self.write_keyword("ASC"),
8929 SortOrder::Desc => self.write_keyword("DESC"),
8930 }
8931 }
8932 }
8933
8934 if col.unique {
8935 self.write_space();
8936 self.write_keyword("UNIQUE");
8937 if col.unique_nulls_not_distinct {
8939 self.write(" NULLS NOT DISTINCT");
8940 }
8941 }
8942
8943 match col.nullable {
8944 Some(false) => {
8945 self.write_space();
8946 self.write_keyword("NOT NULL");
8947 }
8948 Some(true) => {
8949 self.write_space();
8950 self.write_keyword("NULL");
8951 }
8952 None => {}
8953 }
8954
8955 if let Some(ref default) = col.default {
8956 self.write_space();
8957 self.write_keyword("DEFAULT");
8958 self.write_space();
8959 self.generate_expression(default)?;
8960 }
8961
8962 if col.auto_increment {
8963 self.write_space();
8964 self.generate_auto_increment_keyword(col)?;
8965 }
8966
8967 for constraint in &col.constraints {
8969 match constraint {
8970 ColumnConstraint::References(fk_ref) => {
8971 self.write_space();
8972 if fk_ref.has_foreign_key_keywords {
8973 self.write_keyword("FOREIGN KEY");
8974 self.write_space();
8975 }
8976 self.write_keyword("REFERENCES");
8977 self.write_space();
8978 self.generate_table(&fk_ref.table)?;
8979 if !fk_ref.columns.is_empty() {
8980 self.write(" (");
8981 for (i, c) in fk_ref.columns.iter().enumerate() {
8982 if i > 0 {
8983 self.write(", ");
8984 }
8985 self.generate_identifier(c)?;
8986 }
8987 self.write(")");
8988 }
8989 self.generate_referential_actions(fk_ref)?;
8990 }
8991 ColumnConstraint::Check(expr) => {
8992 self.write_space();
8993 self.write_keyword("CHECK");
8994 self.write(" (");
8995 self.generate_expression(expr)?;
8996 self.write(")");
8997 }
8998 ColumnConstraint::GeneratedAsIdentity(gen) => {
8999 self.write_space();
9000 if matches!(
9002 self.config.dialect,
9003 Some(crate::dialects::DialectType::Redshift)
9004 ) {
9005 self.write_keyword("IDENTITY");
9006 self.write("(");
9007 if let Some(ref start) = gen.start {
9008 self.generate_expression(start)?;
9009 } else {
9010 self.write("0");
9011 }
9012 self.write(", ");
9013 if let Some(ref incr) = gen.increment {
9014 self.generate_expression(incr)?;
9015 } else {
9016 self.write("1");
9017 }
9018 self.write(")");
9019 } else {
9020 self.write_keyword("GENERATED");
9021 if gen.always {
9022 self.write_space();
9023 self.write_keyword("ALWAYS");
9024 } else {
9025 self.write_space();
9026 self.write_keyword("BY DEFAULT");
9027 if gen.on_null {
9028 self.write_space();
9029 self.write_keyword("ON NULL");
9030 }
9031 }
9032 self.write_space();
9033 self.write_keyword("AS IDENTITY");
9034
9035 let has_options = gen.start.is_some()
9036 || gen.increment.is_some()
9037 || gen.minvalue.is_some()
9038 || gen.maxvalue.is_some()
9039 || gen.cycle.is_some();
9040 if has_options {
9041 self.write(" (");
9042 let mut first = true;
9043 if let Some(ref start) = gen.start {
9044 if !first {
9045 self.write(" ");
9046 }
9047 first = false;
9048 self.write_keyword("START WITH");
9049 self.write_space();
9050 self.generate_expression(start)?;
9051 }
9052 if let Some(ref incr) = gen.increment {
9053 if !first {
9054 self.write(" ");
9055 }
9056 first = false;
9057 self.write_keyword("INCREMENT BY");
9058 self.write_space();
9059 self.generate_expression(incr)?;
9060 }
9061 if let Some(ref minv) = gen.minvalue {
9062 if !first {
9063 self.write(" ");
9064 }
9065 first = false;
9066 self.write_keyword("MINVALUE");
9067 self.write_space();
9068 self.generate_expression(minv)?;
9069 }
9070 if let Some(ref maxv) = gen.maxvalue {
9071 if !first {
9072 self.write(" ");
9073 }
9074 first = false;
9075 self.write_keyword("MAXVALUE");
9076 self.write_space();
9077 self.generate_expression(maxv)?;
9078 }
9079 if let Some(cycle) = gen.cycle {
9080 if !first {
9081 self.write(" ");
9082 }
9083 if cycle {
9084 self.write_keyword("CYCLE");
9085 } else {
9086 self.write_keyword("NO CYCLE");
9087 }
9088 }
9089 self.write(")");
9090 }
9091 }
9092 }
9093 ColumnConstraint::Collate(collation) => {
9094 self.write_space();
9095 self.write_keyword("COLLATE");
9096 self.write_space();
9097 self.generate_identifier(collation)?;
9098 }
9099 ColumnConstraint::Comment(comment) => {
9100 self.write_space();
9101 self.write_keyword("COMMENT");
9102 self.write_space();
9103 self.generate_string_literal(comment)?;
9104 }
9105 ColumnConstraint::Path(path_expr) => {
9106 self.write_space();
9107 self.write_keyword("PATH");
9108 self.write_space();
9109 self.generate_expression(path_expr)?;
9110 }
9111 _ => {} }
9113 }
9114
9115 if let Some(ref encoding) = col.encoding {
9117 self.write_space();
9118 self.write_keyword("ENCODE");
9119 self.write_space();
9120 self.write(encoding);
9121 }
9122 }
9123
9124 if let Some(ref codec) = col.codec {
9126 self.write_space();
9127 self.write_keyword("CODEC");
9128 self.write("(");
9129 self.write(codec);
9130 self.write(")");
9131 }
9132
9133 if let Some(ref ephemeral) = col.ephemeral {
9135 self.write_space();
9136 self.write_keyword("EPHEMERAL");
9137 if let Some(ref expr) = ephemeral {
9138 self.write_space();
9139 self.generate_expression(expr)?;
9140 }
9141 }
9142
9143 if let Some(ref mat_expr) = col.materialized_expr {
9145 self.write_space();
9146 self.write_keyword("MATERIALIZED");
9147 self.write_space();
9148 self.generate_expression(mat_expr)?;
9149 }
9150
9151 if let Some(ref alias_expr) = col.alias_expr {
9153 self.write_space();
9154 self.write_keyword("ALIAS");
9155 self.write_space();
9156 self.generate_expression(alias_expr)?;
9157 }
9158
9159 if let Some(ref ttl_expr) = col.ttl_expr {
9161 self.write_space();
9162 self.write_keyword("TTL");
9163 self.write_space();
9164 self.generate_expression(ttl_expr)?;
9165 }
9166
9167 if col.not_for_replication
9169 && matches!(
9170 self.config.dialect,
9171 Some(crate::dialects::DialectType::TSQL)
9172 | Some(crate::dialects::DialectType::Fabric)
9173 )
9174 {
9175 self.write_space();
9176 self.write_keyword("NOT FOR REPLICATION");
9177 }
9178
9179 if !col.options.is_empty() {
9181 self.write_space();
9182 self.generate_options_clause(&col.options)?;
9183 }
9184
9185 if !col.primary_key
9188 && self
9189 .sqlite_inline_pk_columns
9190 .contains(&col.name.name.to_ascii_lowercase())
9191 {
9192 self.write_space();
9193 self.write_keyword("PRIMARY KEY");
9194 }
9195
9196 if serial_expansion.is_some() {
9199 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
9200 self.write_space();
9201 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
9202 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
9203 self.write_space();
9204 self.write_keyword("NOT NULL");
9205 }
9206 }
9207
9208 Ok(())
9209 }
9210
9211 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
9212 match constraint {
9213 TableConstraint::PrimaryKey {
9214 name,
9215 columns,
9216 include_columns,
9217 modifiers,
9218 has_constraint_keyword,
9219 } => {
9220 if let Some(ref n) = name {
9221 if *has_constraint_keyword {
9222 self.write_keyword("CONSTRAINT");
9223 self.write_space();
9224 self.generate_identifier(n)?;
9225 self.write_space();
9226 }
9227 }
9228 self.write_keyword("PRIMARY KEY");
9229 if let Some(ref clustered) = modifiers.clustered {
9231 self.write_space();
9232 self.write_keyword(clustered);
9233 }
9234 if let Some(ref n) = name {
9236 if !*has_constraint_keyword {
9237 self.write_space();
9238 self.generate_identifier(n)?;
9239 }
9240 }
9241 self.write(" (");
9242 for (i, col) in columns.iter().enumerate() {
9243 if i > 0 {
9244 self.write(", ");
9245 }
9246 self.generate_identifier(col)?;
9247 }
9248 self.write(")");
9249 if !include_columns.is_empty() {
9250 self.write_space();
9251 self.write_keyword("INCLUDE");
9252 self.write(" (");
9253 for (i, col) in include_columns.iter().enumerate() {
9254 if i > 0 {
9255 self.write(", ");
9256 }
9257 self.generate_identifier(col)?;
9258 }
9259 self.write(")");
9260 }
9261 self.generate_constraint_modifiers(modifiers);
9262 }
9263 TableConstraint::Unique {
9264 name,
9265 columns,
9266 columns_parenthesized,
9267 modifiers,
9268 has_constraint_keyword,
9269 nulls_not_distinct,
9270 } => {
9271 if let Some(ref n) = name {
9272 if *has_constraint_keyword {
9273 self.write_keyword("CONSTRAINT");
9274 self.write_space();
9275 self.generate_identifier(n)?;
9276 self.write_space();
9277 }
9278 }
9279 self.write_keyword("UNIQUE");
9280 if let Some(ref clustered) = modifiers.clustered {
9282 self.write_space();
9283 self.write_keyword(clustered);
9284 }
9285 if *nulls_not_distinct {
9287 self.write(" NULLS NOT DISTINCT");
9288 }
9289 if let Some(ref n) = name {
9291 if !*has_constraint_keyword {
9292 self.write_space();
9293 self.generate_identifier(n)?;
9294 }
9295 }
9296 if *columns_parenthesized {
9297 self.write(" (");
9298 for (i, col) in columns.iter().enumerate() {
9299 if i > 0 {
9300 self.write(", ");
9301 }
9302 self.generate_identifier(col)?;
9303 }
9304 self.write(")");
9305 } else {
9306 for col in columns.iter() {
9308 self.write_space();
9309 self.generate_identifier(col)?;
9310 }
9311 }
9312 self.generate_constraint_modifiers(modifiers);
9313 }
9314 TableConstraint::ForeignKey {
9315 name,
9316 columns,
9317 references,
9318 on_delete,
9319 on_update,
9320 modifiers,
9321 } => {
9322 if let Some(ref n) = name {
9323 self.write_keyword("CONSTRAINT");
9324 self.write_space();
9325 self.generate_identifier(n)?;
9326 self.write_space();
9327 }
9328 self.write_keyword("FOREIGN KEY");
9329 self.write(" (");
9330 for (i, col) in columns.iter().enumerate() {
9331 if i > 0 {
9332 self.write(", ");
9333 }
9334 self.generate_identifier(col)?;
9335 }
9336 self.write(")");
9337 if let Some(ref refs) = references {
9338 self.write(" ");
9339 self.write_keyword("REFERENCES");
9340 self.write_space();
9341 self.generate_table(&refs.table)?;
9342 if !refs.columns.is_empty() {
9343 if self.config.pretty {
9344 self.write(" (");
9345 self.write_newline();
9346 self.indent_level += 1;
9347 for (i, col) in refs.columns.iter().enumerate() {
9348 if i > 0 {
9349 self.write(",");
9350 self.write_newline();
9351 }
9352 self.write_indent();
9353 self.generate_identifier(col)?;
9354 }
9355 self.indent_level -= 1;
9356 self.write_newline();
9357 self.write_indent();
9358 self.write(")");
9359 } else {
9360 self.write(" (");
9361 for (i, col) in refs.columns.iter().enumerate() {
9362 if i > 0 {
9363 self.write(", ");
9364 }
9365 self.generate_identifier(col)?;
9366 }
9367 self.write(")");
9368 }
9369 }
9370 self.generate_referential_actions(refs)?;
9371 } else {
9372 if let Some(ref action) = on_delete {
9374 self.write_space();
9375 self.write_keyword("ON DELETE");
9376 self.write_space();
9377 self.generate_referential_action(action);
9378 }
9379 if let Some(ref action) = on_update {
9380 self.write_space();
9381 self.write_keyword("ON UPDATE");
9382 self.write_space();
9383 self.generate_referential_action(action);
9384 }
9385 }
9386 self.generate_constraint_modifiers(modifiers);
9387 }
9388 TableConstraint::Check {
9389 name,
9390 expression,
9391 modifiers,
9392 } => {
9393 if let Some(ref n) = name {
9394 self.write_keyword("CONSTRAINT");
9395 self.write_space();
9396 self.generate_identifier(n)?;
9397 self.write_space();
9398 }
9399 self.write_keyword("CHECK");
9400 self.write(" (");
9401 self.generate_expression(expression)?;
9402 self.write(")");
9403 self.generate_constraint_modifiers(modifiers);
9404 }
9405 TableConstraint::Assume { name, expression } => {
9406 if let Some(ref n) = name {
9407 self.write_keyword("CONSTRAINT");
9408 self.write_space();
9409 self.generate_identifier(n)?;
9410 self.write_space();
9411 }
9412 self.write_keyword("ASSUME");
9413 self.write(" (");
9414 self.generate_expression(expression)?;
9415 self.write(")");
9416 }
9417 TableConstraint::Default {
9418 name,
9419 expression,
9420 column,
9421 } => {
9422 if let Some(ref n) = name {
9423 self.write_keyword("CONSTRAINT");
9424 self.write_space();
9425 self.generate_identifier(n)?;
9426 self.write_space();
9427 }
9428 self.write_keyword("DEFAULT");
9429 self.write_space();
9430 self.generate_expression(expression)?;
9431 self.write_space();
9432 self.write_keyword("FOR");
9433 self.write_space();
9434 self.generate_identifier(column)?;
9435 }
9436 TableConstraint::Index {
9437 name,
9438 columns,
9439 kind,
9440 modifiers,
9441 use_key_keyword,
9442 expression,
9443 index_type,
9444 granularity,
9445 } => {
9446 if expression.is_some() {
9448 self.write_keyword("INDEX");
9449 if let Some(ref n) = name {
9450 self.write_space();
9451 self.generate_identifier(n)?;
9452 }
9453 if let Some(ref expr) = expression {
9454 self.write_space();
9455 self.generate_expression(expr)?;
9456 }
9457 if let Some(ref idx_type) = index_type {
9458 self.write_space();
9459 self.write_keyword("TYPE");
9460 self.write_space();
9461 self.generate_expression(idx_type)?;
9462 }
9463 if let Some(ref gran) = granularity {
9464 self.write_space();
9465 self.write_keyword("GRANULARITY");
9466 self.write_space();
9467 self.generate_expression(gran)?;
9468 }
9469 } else {
9470 use crate::dialects::DialectType;
9474 let index_keyword = if *use_key_keyword
9475 && !matches!(self.config.dialect, Some(DialectType::MySQL))
9476 {
9477 "KEY"
9478 } else {
9479 "INDEX"
9480 };
9481
9482 if let Some(ref k) = kind {
9484 self.write_keyword(k);
9485 if k != "UNIQUE" {
9487 self.write_space();
9488 self.write_keyword(index_keyword);
9489 }
9490 } else {
9491 self.write_keyword(index_keyword);
9492 }
9493
9494 if modifiers.using_before_columns && name.is_none() {
9496 if let Some(ref using) = modifiers.using {
9497 self.write_space();
9498 self.write_keyword("USING");
9499 self.write_space();
9500 self.write_keyword(using);
9501 }
9502 }
9503
9504 if let Some(ref n) = name {
9506 self.write_space();
9507 self.generate_identifier(n)?;
9508 }
9509
9510 if modifiers.using_before_columns && name.is_some() {
9512 if let Some(ref using) = modifiers.using {
9513 self.write_space();
9514 self.write_keyword("USING");
9515 self.write_space();
9516 self.write_keyword(using);
9517 }
9518 }
9519
9520 self.write(" (");
9522 for (i, col) in columns.iter().enumerate() {
9523 if i > 0 {
9524 self.write(", ");
9525 }
9526 self.generate_identifier(col)?;
9527 }
9528 self.write(")");
9529
9530 if !modifiers.using_before_columns {
9532 if let Some(ref using) = modifiers.using {
9533 self.write_space();
9534 self.write_keyword("USING");
9535 self.write_space();
9536 self.write_keyword(using);
9537 }
9538 }
9539
9540 self.generate_constraint_modifiers_without_using(modifiers);
9542 }
9543 }
9544 TableConstraint::Projection { name, expression } => {
9545 self.write_keyword("PROJECTION");
9547 self.write_space();
9548 self.generate_identifier(name)?;
9549 self.write(" (");
9550 self.generate_expression(expression)?;
9551 self.write(")");
9552 }
9553 TableConstraint::Like { source, options } => {
9554 self.write_keyword("LIKE");
9555 self.write_space();
9556 self.generate_table(source)?;
9557 for (action, prop) in options {
9558 self.write_space();
9559 match action {
9560 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
9561 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
9562 }
9563 self.write_space();
9564 self.write_keyword(prop);
9565 }
9566 }
9567 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
9568 self.write_keyword("PERIOD FOR SYSTEM_TIME");
9569 self.write(" (");
9570 self.generate_identifier(start_col)?;
9571 self.write(", ");
9572 self.generate_identifier(end_col)?;
9573 self.write(")");
9574 }
9575 TableConstraint::Exclude {
9576 name,
9577 using,
9578 elements,
9579 include_columns,
9580 where_clause,
9581 with_params,
9582 using_index_tablespace,
9583 modifiers: _,
9584 } => {
9585 if let Some(ref n) = name {
9586 self.write_keyword("CONSTRAINT");
9587 self.write_space();
9588 self.generate_identifier(n)?;
9589 self.write_space();
9590 }
9591 self.write_keyword("EXCLUDE");
9592 if let Some(ref method) = using {
9593 self.write_space();
9594 self.write_keyword("USING");
9595 self.write_space();
9596 self.write(method);
9597 self.write("(");
9598 } else {
9599 self.write(" (");
9600 }
9601 for (i, elem) in elements.iter().enumerate() {
9602 if i > 0 {
9603 self.write(", ");
9604 }
9605 self.write(&elem.expression);
9606 self.write_space();
9607 self.write_keyword("WITH");
9608 self.write_space();
9609 self.write(&elem.operator);
9610 }
9611 self.write(")");
9612 if !include_columns.is_empty() {
9613 self.write_space();
9614 self.write_keyword("INCLUDE");
9615 self.write(" (");
9616 for (i, col) in include_columns.iter().enumerate() {
9617 if i > 0 {
9618 self.write(", ");
9619 }
9620 self.generate_identifier(col)?;
9621 }
9622 self.write(")");
9623 }
9624 if !with_params.is_empty() {
9625 self.write_space();
9626 self.write_keyword("WITH");
9627 self.write(" (");
9628 for (i, (key, val)) in with_params.iter().enumerate() {
9629 if i > 0 {
9630 self.write(", ");
9631 }
9632 self.write(key);
9633 self.write("=");
9634 self.write(val);
9635 }
9636 self.write(")");
9637 }
9638 if let Some(ref tablespace) = using_index_tablespace {
9639 self.write_space();
9640 self.write_keyword("USING INDEX TABLESPACE");
9641 self.write_space();
9642 self.write(tablespace);
9643 }
9644 if let Some(ref where_expr) = where_clause {
9645 self.write_space();
9646 self.write_keyword("WHERE");
9647 self.write(" (");
9648 self.generate_expression(where_expr)?;
9649 self.write(")");
9650 }
9651 }
9652 TableConstraint::Tags(tags) => {
9653 self.write_keyword("TAG");
9654 self.write(" (");
9655 for (i, expr) in tags.expressions.iter().enumerate() {
9656 if i > 0 {
9657 self.write(", ");
9658 }
9659 self.generate_expression(expr)?;
9660 }
9661 self.write(")");
9662 }
9663 TableConstraint::InitiallyDeferred { deferred } => {
9664 self.write_keyword("INITIALLY");
9665 self.write_space();
9666 if *deferred {
9667 self.write_keyword("DEFERRED");
9668 } else {
9669 self.write_keyword("IMMEDIATE");
9670 }
9671 }
9672 }
9673 Ok(())
9674 }
9675
9676 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9677 if let Some(using) = &modifiers.using {
9679 self.write_space();
9680 self.write_keyword("USING");
9681 self.write_space();
9682 self.write_keyword(using);
9683 }
9684 if let Some(enforced) = modifiers.enforced {
9686 self.write_space();
9687 if enforced {
9688 self.write_keyword("ENFORCED");
9689 } else {
9690 self.write_keyword("NOT ENFORCED");
9691 }
9692 }
9693 if let Some(deferrable) = modifiers.deferrable {
9695 self.write_space();
9696 if deferrable {
9697 self.write_keyword("DEFERRABLE");
9698 } else {
9699 self.write_keyword("NOT DEFERRABLE");
9700 }
9701 }
9702 if let Some(initially_deferred) = modifiers.initially_deferred {
9704 self.write_space();
9705 if initially_deferred {
9706 self.write_keyword("INITIALLY DEFERRED");
9707 } else {
9708 self.write_keyword("INITIALLY IMMEDIATE");
9709 }
9710 }
9711 if modifiers.norely {
9713 self.write_space();
9714 self.write_keyword("NORELY");
9715 }
9716 if modifiers.rely {
9718 self.write_space();
9719 self.write_keyword("RELY");
9720 }
9721 if modifiers.not_valid {
9723 self.write_space();
9724 self.write_keyword("NOT VALID");
9725 }
9726 if let Some(on_conflict) = &modifiers.on_conflict {
9728 self.write_space();
9729 self.write_keyword("ON CONFLICT");
9730 self.write_space();
9731 self.write_keyword(on_conflict);
9732 }
9733 if !modifiers.with_options.is_empty() {
9735 self.write_space();
9736 self.write_keyword("WITH");
9737 self.write(" (");
9738 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
9739 if i > 0 {
9740 self.write(", ");
9741 }
9742 self.write(key);
9743 self.write("=");
9744 self.write(value);
9745 }
9746 self.write(")");
9747 }
9748 if let Some(ref fg) = modifiers.on_filegroup {
9750 self.write_space();
9751 self.write_keyword("ON");
9752 self.write_space();
9753 let _ = self.generate_identifier(fg);
9754 }
9755 }
9756
9757 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
9759 if let Some(enforced) = modifiers.enforced {
9761 self.write_space();
9762 if enforced {
9763 self.write_keyword("ENFORCED");
9764 } else {
9765 self.write_keyword("NOT ENFORCED");
9766 }
9767 }
9768 if let Some(deferrable) = modifiers.deferrable {
9770 self.write_space();
9771 if deferrable {
9772 self.write_keyword("DEFERRABLE");
9773 } else {
9774 self.write_keyword("NOT DEFERRABLE");
9775 }
9776 }
9777 if let Some(initially_deferred) = modifiers.initially_deferred {
9779 self.write_space();
9780 if initially_deferred {
9781 self.write_keyword("INITIALLY DEFERRED");
9782 } else {
9783 self.write_keyword("INITIALLY IMMEDIATE");
9784 }
9785 }
9786 if modifiers.norely {
9788 self.write_space();
9789 self.write_keyword("NORELY");
9790 }
9791 if modifiers.rely {
9793 self.write_space();
9794 self.write_keyword("RELY");
9795 }
9796 if modifiers.not_valid {
9798 self.write_space();
9799 self.write_keyword("NOT VALID");
9800 }
9801 if let Some(on_conflict) = &modifiers.on_conflict {
9803 self.write_space();
9804 self.write_keyword("ON CONFLICT");
9805 self.write_space();
9806 self.write_keyword(on_conflict);
9807 }
9808 self.generate_index_specific_modifiers(modifiers);
9810 }
9811
9812 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9814 if let Some(ref comment) = modifiers.comment {
9815 self.write_space();
9816 self.write_keyword("COMMENT");
9817 self.write(" '");
9818 self.write(comment);
9819 self.write("'");
9820 }
9821 if let Some(visible) = modifiers.visible {
9822 self.write_space();
9823 if visible {
9824 self.write_keyword("VISIBLE");
9825 } else {
9826 self.write_keyword("INVISIBLE");
9827 }
9828 }
9829 if let Some(ref attr) = modifiers.engine_attribute {
9830 self.write_space();
9831 self.write_keyword("ENGINE_ATTRIBUTE");
9832 self.write(" = '");
9833 self.write(attr);
9834 self.write("'");
9835 }
9836 if let Some(ref parser) = modifiers.with_parser {
9837 self.write_space();
9838 self.write_keyword("WITH PARSER");
9839 self.write_space();
9840 self.write(parser);
9841 }
9842 }
9843
9844 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
9845 if !fk_ref.match_after_actions {
9847 if let Some(ref match_type) = fk_ref.match_type {
9848 self.write_space();
9849 self.write_keyword("MATCH");
9850 self.write_space();
9851 match match_type {
9852 MatchType::Full => self.write_keyword("FULL"),
9853 MatchType::Partial => self.write_keyword("PARTIAL"),
9854 MatchType::Simple => self.write_keyword("SIMPLE"),
9855 }
9856 }
9857 }
9858
9859 if fk_ref.on_update_first {
9861 if let Some(ref action) = fk_ref.on_update {
9862 self.write_space();
9863 self.write_keyword("ON UPDATE");
9864 self.write_space();
9865 self.generate_referential_action(action);
9866 }
9867 if let Some(ref action) = fk_ref.on_delete {
9868 self.write_space();
9869 self.write_keyword("ON DELETE");
9870 self.write_space();
9871 self.generate_referential_action(action);
9872 }
9873 } else {
9874 if let Some(ref action) = fk_ref.on_delete {
9875 self.write_space();
9876 self.write_keyword("ON DELETE");
9877 self.write_space();
9878 self.generate_referential_action(action);
9879 }
9880 if let Some(ref action) = fk_ref.on_update {
9881 self.write_space();
9882 self.write_keyword("ON UPDATE");
9883 self.write_space();
9884 self.generate_referential_action(action);
9885 }
9886 }
9887
9888 if fk_ref.match_after_actions {
9890 if let Some(ref match_type) = fk_ref.match_type {
9891 self.write_space();
9892 self.write_keyword("MATCH");
9893 self.write_space();
9894 match match_type {
9895 MatchType::Full => self.write_keyword("FULL"),
9896 MatchType::Partial => self.write_keyword("PARTIAL"),
9897 MatchType::Simple => self.write_keyword("SIMPLE"),
9898 }
9899 }
9900 }
9901
9902 if let Some(deferrable) = fk_ref.deferrable {
9904 self.write_space();
9905 if deferrable {
9906 self.write_keyword("DEFERRABLE");
9907 } else {
9908 self.write_keyword("NOT DEFERRABLE");
9909 }
9910 }
9911
9912 Ok(())
9913 }
9914
9915 fn generate_referential_action(&mut self, action: &ReferentialAction) {
9916 match action {
9917 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
9918 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
9919 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
9920 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
9921 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
9922 }
9923 }
9924
9925 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
9926 if let Some(ref object_id_args) = dt.object_id_args {
9928 if matches!(
9929 self.config.dialect,
9930 Some(crate::dialects::DialectType::TSQL)
9931 | Some(crate::dialects::DialectType::Fabric)
9932 ) {
9933 self.write_keyword("IF NOT OBJECT_ID");
9934 self.write("(");
9935 self.write(object_id_args);
9936 self.write(")");
9937 self.write_space();
9938 self.write_keyword("IS NULL BEGIN DROP TABLE");
9939 self.write_space();
9940 for (i, table) in dt.names.iter().enumerate() {
9941 if i > 0 {
9942 self.write(", ");
9943 }
9944 self.generate_table(table)?;
9945 }
9946 self.write("; ");
9947 self.write_keyword("END");
9948 return Ok(());
9949 }
9950 }
9951
9952 let saved_athena_hive_context = self.athena_hive_context;
9954 if matches!(
9955 self.config.dialect,
9956 Some(crate::dialects::DialectType::Athena)
9957 ) {
9958 self.athena_hive_context = true;
9959 }
9960
9961 for comment in &dt.leading_comments {
9963 self.write_formatted_comment(comment);
9964 self.write_space();
9965 }
9966 if dt.iceberg {
9967 self.write_keyword("DROP ICEBERG TABLE");
9968 } else {
9969 self.write_keyword("DROP TABLE");
9970 }
9971
9972 if dt.if_exists {
9973 self.write_space();
9974 self.write_keyword("IF EXISTS");
9975 }
9976
9977 self.write_space();
9978 for (i, table) in dt.names.iter().enumerate() {
9979 if i > 0 {
9980 self.write(", ");
9981 }
9982 self.generate_table(table)?;
9983 }
9984
9985 if dt.cascade_constraints {
9986 self.write_space();
9987 self.write_keyword("CASCADE CONSTRAINTS");
9988 } else if dt.cascade {
9989 self.write_space();
9990 self.write_keyword("CASCADE");
9991 }
9992
9993 if dt.restrict {
9994 self.write_space();
9995 self.write_keyword("RESTRICT");
9996 }
9997
9998 if dt.purge {
9999 self.write_space();
10000 self.write_keyword("PURGE");
10001 }
10002
10003 if dt.sync {
10004 self.write_space();
10005 self.write_keyword("SYNC");
10006 }
10007
10008 self.athena_hive_context = saved_athena_hive_context;
10010
10011 Ok(())
10012 }
10013
10014 fn generate_undrop(&mut self, u: &Undrop) -> Result<()> {
10015 self.write_keyword("UNDROP");
10016 self.write_space();
10017 self.write_keyword(&u.kind);
10018 if u.if_exists {
10019 self.write_space();
10020 self.write_keyword("IF EXISTS");
10021 }
10022 self.write_space();
10023 self.generate_table(&u.name)?;
10024 Ok(())
10025 }
10026
10027 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
10028 let saved_athena_hive_context = self.athena_hive_context;
10030 if matches!(
10031 self.config.dialect,
10032 Some(crate::dialects::DialectType::Athena)
10033 ) {
10034 self.athena_hive_context = true;
10035 }
10036
10037 self.write_keyword("ALTER");
10038 if let Some(ref modifier) = at.table_modifier {
10040 if !matches!(
10041 self.config.dialect,
10042 Some(crate::dialects::DialectType::DuckDB)
10043 ) {
10044 self.write_space();
10045 self.write_keyword(modifier);
10046 }
10047 }
10048 self.write(" ");
10049 self.write_keyword("TABLE");
10050 if at.if_exists {
10051 self.write_space();
10052 self.write_keyword("IF EXISTS");
10053 }
10054 self.write_space();
10055 self.generate_table(&at.name)?;
10056
10057 if let Some(ref on_cluster) = at.on_cluster {
10059 self.write_space();
10060 self.generate_on_cluster(on_cluster)?;
10061 }
10062
10063 if let Some(ref partition) = at.partition {
10065 self.write_space();
10066 self.write_keyword("PARTITION");
10067 self.write("(");
10068 for (i, (key, value)) in partition.iter().enumerate() {
10069 if i > 0 {
10070 self.write(", ");
10071 }
10072 self.generate_identifier(key)?;
10073 self.write(" = ");
10074 self.generate_expression(value)?;
10075 }
10076 self.write(")");
10077 }
10078
10079 if let Some(ref with_check) = at.with_check {
10081 self.write_space();
10082 self.write_keyword(with_check);
10083 }
10084
10085 if self.config.pretty {
10086 self.write_newline();
10088 self.indent_level += 1;
10089 for (i, action) in at.actions.iter().enumerate() {
10090 let is_continuation = i > 0
10092 && matches!(
10093 (&at.actions[i - 1], action),
10094 (
10095 AlterTableAction::AddColumn { .. },
10096 AlterTableAction::AddColumn { .. }
10097 ) | (
10098 AlterTableAction::AddConstraint(_),
10099 AlterTableAction::AddConstraint(_)
10100 )
10101 );
10102 if i > 0 {
10103 self.write(",");
10104 self.write_newline();
10105 }
10106 self.write_indent();
10107 self.generate_alter_action_with_continuation(action, is_continuation)?;
10108 }
10109 self.indent_level -= 1;
10110 } else {
10111 for (i, action) in at.actions.iter().enumerate() {
10112 let is_continuation = i > 0
10114 && matches!(
10115 (&at.actions[i - 1], action),
10116 (
10117 AlterTableAction::AddColumn { .. },
10118 AlterTableAction::AddColumn { .. }
10119 ) | (
10120 AlterTableAction::AddConstraint(_),
10121 AlterTableAction::AddConstraint(_)
10122 )
10123 );
10124 if i > 0 {
10125 self.write(",");
10126 }
10127 self.write_space();
10128 self.generate_alter_action_with_continuation(action, is_continuation)?;
10129 }
10130 }
10131
10132 if let Some(ref algorithm) = at.algorithm {
10134 self.write(", ");
10135 self.write_keyword("ALGORITHM");
10136 self.write("=");
10137 self.write_keyword(algorithm);
10138 }
10139 if let Some(ref lock) = at.lock {
10140 self.write(", ");
10141 self.write_keyword("LOCK");
10142 self.write("=");
10143 self.write_keyword(lock);
10144 }
10145
10146 self.athena_hive_context = saved_athena_hive_context;
10148
10149 Ok(())
10150 }
10151
10152 fn generate_alter_action_with_continuation(
10153 &mut self,
10154 action: &AlterTableAction,
10155 is_continuation: bool,
10156 ) -> Result<()> {
10157 match action {
10158 AlterTableAction::AddColumn {
10159 column,
10160 if_not_exists,
10161 position,
10162 } => {
10163 use crate::dialects::DialectType;
10164 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
10168 let is_tsql_like = matches!(
10169 self.config.dialect,
10170 Some(DialectType::TSQL) | Some(DialectType::Fabric)
10171 );
10172 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
10174
10175 if is_continuation && (is_snowflake || is_tsql_like) {
10176 } else if is_snowflake {
10178 self.write_keyword("ADD");
10179 self.write_space();
10180 } else if is_athena {
10181 self.write_keyword("ADD COLUMNS");
10183 self.write(" (");
10184 } else if self.config.alter_table_include_column_keyword {
10185 self.write_keyword("ADD COLUMN");
10186 self.write_space();
10187 } else {
10188 self.write_keyword("ADD");
10190 self.write_space();
10191 }
10192
10193 if *if_not_exists {
10194 self.write_keyword("IF NOT EXISTS");
10195 self.write_space();
10196 }
10197 self.generate_column_def(column)?;
10198
10199 if is_athena {
10201 self.write(")");
10202 }
10203
10204 if let Some(pos) = position {
10206 self.write_space();
10207 match pos {
10208 ColumnPosition::First => self.write_keyword("FIRST"),
10209 ColumnPosition::After(col_name) => {
10210 self.write_keyword("AFTER");
10211 self.write_space();
10212 self.generate_identifier(col_name)?;
10213 }
10214 }
10215 }
10216 }
10217 AlterTableAction::DropColumn {
10218 name,
10219 if_exists,
10220 cascade,
10221 } => {
10222 self.write_keyword("DROP COLUMN");
10223 if *if_exists {
10224 self.write_space();
10225 self.write_keyword("IF EXISTS");
10226 }
10227 self.write_space();
10228 self.generate_identifier(name)?;
10229 if *cascade {
10230 self.write_space();
10231 self.write_keyword("CASCADE");
10232 }
10233 }
10234 AlterTableAction::DropColumns { names } => {
10235 self.write_keyword("DROP COLUMNS");
10236 self.write(" (");
10237 for (i, name) in names.iter().enumerate() {
10238 if i > 0 {
10239 self.write(", ");
10240 }
10241 self.generate_identifier(name)?;
10242 }
10243 self.write(")");
10244 }
10245 AlterTableAction::RenameColumn {
10246 old_name,
10247 new_name,
10248 if_exists,
10249 } => {
10250 self.write_keyword("RENAME COLUMN");
10251 if *if_exists {
10252 self.write_space();
10253 self.write_keyword("IF EXISTS");
10254 }
10255 self.write_space();
10256 self.generate_identifier(old_name)?;
10257 self.write_space();
10258 self.write_keyword("TO");
10259 self.write_space();
10260 self.generate_identifier(new_name)?;
10261 }
10262 AlterTableAction::AlterColumn {
10263 name,
10264 action,
10265 use_modify_keyword,
10266 } => {
10267 use crate::dialects::DialectType;
10268 let use_modify = *use_modify_keyword
10271 || (matches!(self.config.dialect, Some(DialectType::MySQL))
10272 && matches!(action, AlterColumnAction::SetDataType { .. }));
10273 if use_modify {
10274 self.write_keyword("MODIFY COLUMN");
10275 self.write_space();
10276 self.generate_identifier(name)?;
10277 if let AlterColumnAction::SetDataType {
10279 data_type,
10280 using: _,
10281 collate,
10282 } = action
10283 {
10284 self.write_space();
10285 self.generate_data_type(data_type)?;
10286 if let Some(collate_name) = collate {
10288 self.write_space();
10289 self.write_keyword("COLLATE");
10290 self.write_space();
10291 self.write(&format!("'{}'", collate_name));
10293 }
10294 } else {
10295 self.write_space();
10296 self.generate_alter_column_action(action)?;
10297 }
10298 } else if matches!(self.config.dialect, Some(DialectType::Hive))
10299 && matches!(action, AlterColumnAction::SetDataType { .. })
10300 {
10301 self.write_keyword("CHANGE COLUMN");
10303 self.write_space();
10304 self.generate_identifier(name)?;
10305 self.write_space();
10306 self.generate_identifier(name)?;
10307 if let AlterColumnAction::SetDataType { data_type, .. } = action {
10308 self.write_space();
10309 self.generate_data_type(data_type)?;
10310 }
10311 } else {
10312 self.write_keyword("ALTER COLUMN");
10313 self.write_space();
10314 self.generate_identifier(name)?;
10315 self.write_space();
10316 self.generate_alter_column_action(action)?;
10317 }
10318 }
10319 AlterTableAction::RenameTable(new_name) => {
10320 let mysql_like = matches!(
10322 self.config.dialect,
10323 Some(DialectType::MySQL)
10324 | Some(DialectType::Doris)
10325 | Some(DialectType::StarRocks)
10326 | Some(DialectType::SingleStore)
10327 );
10328 if mysql_like {
10329 self.write_keyword("RENAME");
10330 } else {
10331 self.write_keyword("RENAME TO");
10332 }
10333 self.write_space();
10334 let rename_table_with_db = !matches!(
10336 self.config.dialect,
10337 Some(DialectType::Doris)
10338 | Some(DialectType::DuckDB)
10339 | Some(DialectType::BigQuery)
10340 | Some(DialectType::PostgreSQL)
10341 );
10342 if !rename_table_with_db {
10343 let mut stripped = new_name.clone();
10344 stripped.schema = None;
10345 stripped.catalog = None;
10346 self.generate_table(&stripped)?;
10347 } else {
10348 self.generate_table(new_name)?;
10349 }
10350 }
10351 AlterTableAction::AddConstraint(constraint) => {
10352 if !is_continuation {
10355 self.write_keyword("ADD");
10356 self.write_space();
10357 }
10358 self.generate_table_constraint(constraint)?;
10359 }
10360 AlterTableAction::DropConstraint { name, if_exists } => {
10361 self.write_keyword("DROP CONSTRAINT");
10362 if *if_exists {
10363 self.write_space();
10364 self.write_keyword("IF EXISTS");
10365 }
10366 self.write_space();
10367 self.generate_identifier(name)?;
10368 }
10369 AlterTableAction::DropForeignKey { name } => {
10370 self.write_keyword("DROP FOREIGN KEY");
10371 self.write_space();
10372 self.generate_identifier(name)?;
10373 }
10374 AlterTableAction::DropPartition {
10375 partitions,
10376 if_exists,
10377 } => {
10378 self.write_keyword("DROP");
10379 if *if_exists {
10380 self.write_space();
10381 self.write_keyword("IF EXISTS");
10382 }
10383 for (i, partition) in partitions.iter().enumerate() {
10384 if i > 0 {
10385 self.write(",");
10386 }
10387 self.write_space();
10388 self.write_keyword("PARTITION");
10389 if partition.len() == 1 && partition[0].0.name == "__expr__" {
10391 self.write_space();
10393 self.generate_expression(&partition[0].1)?;
10394 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
10395 self.write_space();
10397 self.write_keyword("ALL");
10398 } else if partition.len() == 1 && partition[0].0.name == "ID" {
10399 self.write_space();
10401 self.write_keyword("ID");
10402 self.write_space();
10403 self.generate_expression(&partition[0].1)?;
10404 } else {
10405 self.write("(");
10407 for (j, (key, value)) in partition.iter().enumerate() {
10408 if j > 0 {
10409 self.write(", ");
10410 }
10411 self.generate_identifier(key)?;
10412 self.write(" = ");
10413 self.generate_expression(value)?;
10414 }
10415 self.write(")");
10416 }
10417 }
10418 }
10419 AlterTableAction::Delete { where_clause } => {
10420 self.write_keyword("DELETE");
10421 self.write_space();
10422 self.write_keyword("WHERE");
10423 self.write_space();
10424 self.generate_expression(where_clause)?;
10425 }
10426 AlterTableAction::SwapWith(target) => {
10427 self.write_keyword("SWAP WITH");
10428 self.write_space();
10429 self.generate_table(target)?;
10430 }
10431 AlterTableAction::SetProperty { properties } => {
10432 use crate::dialects::DialectType;
10433 self.write_keyword("SET");
10434 let is_trino_presto = matches!(
10436 self.config.dialect,
10437 Some(DialectType::Trino) | Some(DialectType::Presto)
10438 );
10439 if is_trino_presto {
10440 self.write_space();
10441 self.write_keyword("PROPERTIES");
10442 }
10443 let eq = if is_trino_presto { " = " } else { "=" };
10444 for (i, (key, value)) in properties.iter().enumerate() {
10445 if i > 0 {
10446 self.write(",");
10447 }
10448 self.write_space();
10449 if key.contains(' ') {
10451 self.generate_string_literal(key)?;
10452 } else {
10453 self.write(key);
10454 }
10455 self.write(eq);
10456 self.generate_expression(value)?;
10457 }
10458 }
10459 AlterTableAction::UnsetProperty { properties } => {
10460 self.write_keyword("UNSET");
10461 for (i, name) in properties.iter().enumerate() {
10462 if i > 0 {
10463 self.write(",");
10464 }
10465 self.write_space();
10466 self.write(name);
10467 }
10468 }
10469 AlterTableAction::ClusterBy { expressions } => {
10470 self.write_keyword("CLUSTER BY");
10471 self.write(" (");
10472 for (i, expr) in expressions.iter().enumerate() {
10473 if i > 0 {
10474 self.write(", ");
10475 }
10476 self.generate_expression(expr)?;
10477 }
10478 self.write(")");
10479 }
10480 AlterTableAction::SetTag { expressions } => {
10481 self.write_keyword("SET TAG");
10482 for (i, (key, value)) in expressions.iter().enumerate() {
10483 if i > 0 {
10484 self.write(",");
10485 }
10486 self.write_space();
10487 self.write(key);
10488 self.write(" = ");
10489 self.generate_expression(value)?;
10490 }
10491 }
10492 AlterTableAction::UnsetTag { names } => {
10493 self.write_keyword("UNSET TAG");
10494 for (i, name) in names.iter().enumerate() {
10495 if i > 0 {
10496 self.write(",");
10497 }
10498 self.write_space();
10499 self.write(name);
10500 }
10501 }
10502 AlterTableAction::SetOptions { expressions } => {
10503 self.write_keyword("SET");
10504 self.write(" (");
10505 for (i, expr) in expressions.iter().enumerate() {
10506 if i > 0 {
10507 self.write(", ");
10508 }
10509 self.generate_expression(expr)?;
10510 }
10511 self.write(")");
10512 }
10513 AlterTableAction::AlterIndex { name, visible } => {
10514 self.write_keyword("ALTER INDEX");
10515 self.write_space();
10516 self.generate_identifier(name)?;
10517 self.write_space();
10518 if *visible {
10519 self.write_keyword("VISIBLE");
10520 } else {
10521 self.write_keyword("INVISIBLE");
10522 }
10523 }
10524 AlterTableAction::SetAttribute { attribute } => {
10525 self.write_keyword("SET");
10526 self.write_space();
10527 self.write_keyword(attribute);
10528 }
10529 AlterTableAction::SetStageFileFormat { options } => {
10530 self.write_keyword("SET");
10531 self.write_space();
10532 self.write_keyword("STAGE_FILE_FORMAT");
10533 self.write(" = (");
10534 if let Some(opts) = options {
10535 self.generate_space_separated_properties(opts)?;
10536 }
10537 self.write(")");
10538 }
10539 AlterTableAction::SetStageCopyOptions { options } => {
10540 self.write_keyword("SET");
10541 self.write_space();
10542 self.write_keyword("STAGE_COPY_OPTIONS");
10543 self.write(" = (");
10544 if let Some(opts) = options {
10545 self.generate_space_separated_properties(opts)?;
10546 }
10547 self.write(")");
10548 }
10549 AlterTableAction::AddColumns { columns, cascade } => {
10550 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
10553 if is_oracle {
10554 self.write_keyword("ADD");
10555 } else {
10556 self.write_keyword("ADD COLUMNS");
10557 }
10558 self.write(" (");
10559 for (i, col) in columns.iter().enumerate() {
10560 if i > 0 {
10561 self.write(", ");
10562 }
10563 self.generate_column_def(col)?;
10564 }
10565 self.write(")");
10566 if *cascade {
10567 self.write_space();
10568 self.write_keyword("CASCADE");
10569 }
10570 }
10571 AlterTableAction::ChangeColumn {
10572 old_name,
10573 new_name,
10574 data_type,
10575 comment,
10576 cascade,
10577 } => {
10578 use crate::dialects::DialectType;
10579 let is_spark = matches!(
10580 self.config.dialect,
10581 Some(DialectType::Spark) | Some(DialectType::Databricks)
10582 );
10583 let is_rename = old_name.name != new_name.name;
10584
10585 if is_spark {
10586 if is_rename {
10587 self.write_keyword("RENAME COLUMN");
10589 self.write_space();
10590 self.generate_identifier(old_name)?;
10591 self.write_space();
10592 self.write_keyword("TO");
10593 self.write_space();
10594 self.generate_identifier(new_name)?;
10595 } else if comment.is_some() {
10596 self.write_keyword("ALTER COLUMN");
10598 self.write_space();
10599 self.generate_identifier(old_name)?;
10600 self.write_space();
10601 self.write_keyword("COMMENT");
10602 self.write_space();
10603 self.write("'");
10604 self.write(comment.as_ref().unwrap());
10605 self.write("'");
10606 } else if data_type.is_some() {
10607 self.write_keyword("ALTER COLUMN");
10609 self.write_space();
10610 self.generate_identifier(old_name)?;
10611 self.write_space();
10612 self.write_keyword("TYPE");
10613 self.write_space();
10614 self.generate_data_type(data_type.as_ref().unwrap())?;
10615 } else {
10616 self.write_keyword("CHANGE COLUMN");
10618 self.write_space();
10619 self.generate_identifier(old_name)?;
10620 self.write_space();
10621 self.generate_identifier(new_name)?;
10622 }
10623 } else {
10624 if data_type.is_some() {
10626 self.write_keyword("CHANGE COLUMN");
10627 } else {
10628 self.write_keyword("CHANGE");
10629 }
10630 self.write_space();
10631 self.generate_identifier(old_name)?;
10632 self.write_space();
10633 self.generate_identifier(new_name)?;
10634 if let Some(ref dt) = data_type {
10635 self.write_space();
10636 self.generate_data_type(dt)?;
10637 }
10638 if let Some(ref c) = comment {
10639 self.write_space();
10640 self.write_keyword("COMMENT");
10641 self.write_space();
10642 self.write("'");
10643 self.write(c);
10644 self.write("'");
10645 }
10646 if *cascade {
10647 self.write_space();
10648 self.write_keyword("CASCADE");
10649 }
10650 }
10651 }
10652 AlterTableAction::AddPartition {
10653 partition,
10654 if_not_exists,
10655 location,
10656 } => {
10657 self.write_keyword("ADD");
10658 self.write_space();
10659 if *if_not_exists {
10660 self.write_keyword("IF NOT EXISTS");
10661 self.write_space();
10662 }
10663 self.generate_expression(partition)?;
10664 if let Some(ref loc) = location {
10665 self.write_space();
10666 self.write_keyword("LOCATION");
10667 self.write_space();
10668 self.generate_expression(loc)?;
10669 }
10670 }
10671 AlterTableAction::AlterSortKey {
10672 this,
10673 expressions,
10674 compound,
10675 } => {
10676 self.write_keyword("ALTER");
10678 if *compound {
10679 self.write_space();
10680 self.write_keyword("COMPOUND");
10681 }
10682 self.write_space();
10683 self.write_keyword("SORTKEY");
10684 self.write_space();
10685 if let Some(style) = this {
10686 self.write_keyword(style);
10687 } else if !expressions.is_empty() {
10688 self.write("(");
10689 for (i, expr) in expressions.iter().enumerate() {
10690 if i > 0 {
10691 self.write(", ");
10692 }
10693 self.generate_expression(expr)?;
10694 }
10695 self.write(")");
10696 }
10697 }
10698 AlterTableAction::AlterDistStyle { style, distkey } => {
10699 self.write_keyword("ALTER");
10701 self.write_space();
10702 self.write_keyword("DISTSTYLE");
10703 self.write_space();
10704 self.write_keyword(style);
10705 if let Some(col) = distkey {
10706 self.write_space();
10707 self.write_keyword("DISTKEY");
10708 self.write_space();
10709 self.generate_identifier(col)?;
10710 }
10711 }
10712 AlterTableAction::SetTableProperties { properties } => {
10713 self.write_keyword("SET TABLE PROPERTIES");
10715 self.write(" (");
10716 for (i, (key, value)) in properties.iter().enumerate() {
10717 if i > 0 {
10718 self.write(", ");
10719 }
10720 self.generate_expression(key)?;
10721 self.write(" = ");
10722 self.generate_expression(value)?;
10723 }
10724 self.write(")");
10725 }
10726 AlterTableAction::SetLocation { location } => {
10727 self.write_keyword("SET LOCATION");
10729 self.write_space();
10730 self.write("'");
10731 self.write(location);
10732 self.write("'");
10733 }
10734 AlterTableAction::SetFileFormat { format } => {
10735 self.write_keyword("SET FILE FORMAT");
10737 self.write_space();
10738 self.write_keyword(format);
10739 }
10740 AlterTableAction::ReplacePartition { partition, source } => {
10741 self.write_keyword("REPLACE PARTITION");
10743 self.write_space();
10744 self.generate_expression(partition)?;
10745 if let Some(src) = source {
10746 self.write_space();
10747 self.write_keyword("FROM");
10748 self.write_space();
10749 self.generate_expression(src)?;
10750 }
10751 }
10752 AlterTableAction::Raw { sql } => {
10753 self.write(sql);
10754 }
10755 }
10756 Ok(())
10757 }
10758
10759 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
10760 match action {
10761 AlterColumnAction::SetDataType {
10762 data_type,
10763 using,
10764 collate,
10765 } => {
10766 use crate::dialects::DialectType;
10767 let is_no_prefix = matches!(
10772 self.config.dialect,
10773 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
10774 );
10775 let is_type_only = matches!(
10776 self.config.dialect,
10777 Some(DialectType::Redshift)
10778 | Some(DialectType::Spark)
10779 | Some(DialectType::Databricks)
10780 );
10781 if is_type_only {
10782 self.write_keyword("TYPE");
10783 self.write_space();
10784 } else if !is_no_prefix {
10785 self.write_keyword("SET DATA TYPE");
10786 self.write_space();
10787 }
10788 self.generate_data_type(data_type)?;
10789 if let Some(ref collation) = collate {
10790 self.write_space();
10791 self.write_keyword("COLLATE");
10792 self.write_space();
10793 self.write(collation);
10794 }
10795 if let Some(ref using_expr) = using {
10796 self.write_space();
10797 self.write_keyword("USING");
10798 self.write_space();
10799 self.generate_expression(using_expr)?;
10800 }
10801 }
10802 AlterColumnAction::SetDefault(expr) => {
10803 self.write_keyword("SET DEFAULT");
10804 self.write_space();
10805 self.generate_expression(expr)?;
10806 }
10807 AlterColumnAction::DropDefault => {
10808 self.write_keyword("DROP DEFAULT");
10809 }
10810 AlterColumnAction::SetNotNull => {
10811 self.write_keyword("SET NOT NULL");
10812 }
10813 AlterColumnAction::DropNotNull => {
10814 self.write_keyword("DROP NOT NULL");
10815 }
10816 AlterColumnAction::Comment(comment) => {
10817 self.write_keyword("COMMENT");
10818 self.write_space();
10819 self.generate_string_literal(comment)?;
10820 }
10821 AlterColumnAction::SetVisible => {
10822 self.write_keyword("SET VISIBLE");
10823 }
10824 AlterColumnAction::SetInvisible => {
10825 self.write_keyword("SET INVISIBLE");
10826 }
10827 }
10828 Ok(())
10829 }
10830
10831 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
10832 self.write_keyword("CREATE");
10833
10834 if ci.unique {
10835 self.write_space();
10836 self.write_keyword("UNIQUE");
10837 }
10838
10839 if let Some(ref clustered) = ci.clustered {
10841 self.write_space();
10842 self.write_keyword(clustered);
10843 }
10844
10845 self.write_space();
10846 self.write_keyword("INDEX");
10847
10848 if ci.concurrently {
10850 self.write_space();
10851 self.write_keyword("CONCURRENTLY");
10852 }
10853
10854 if ci.if_not_exists {
10855 self.write_space();
10856 self.write_keyword("IF NOT EXISTS");
10857 }
10858
10859 if !ci.name.name.is_empty() {
10861 self.write_space();
10862 self.generate_identifier(&ci.name)?;
10863 }
10864 self.write_space();
10865 self.write_keyword("ON");
10866 if matches!(self.config.dialect, Some(DialectType::Hive)) {
10868 self.write_space();
10869 self.write_keyword("TABLE");
10870 }
10871 self.write_space();
10872 self.generate_table(&ci.table)?;
10873
10874 if !ci.columns.is_empty() || ci.using.is_some() {
10877 let space_before_paren = false;
10878
10879 if let Some(ref using) = ci.using {
10880 self.write_space();
10881 self.write_keyword("USING");
10882 self.write_space();
10883 self.write(using);
10884 if space_before_paren {
10885 self.write(" (");
10886 } else {
10887 self.write("(");
10888 }
10889 } else {
10890 if space_before_paren {
10891 self.write(" (");
10892 } else {
10893 self.write("(");
10894 }
10895 }
10896 for (i, col) in ci.columns.iter().enumerate() {
10897 if i > 0 {
10898 self.write(", ");
10899 }
10900 self.generate_identifier(&col.column)?;
10901 if let Some(ref opclass) = col.opclass {
10902 self.write_space();
10903 self.write(opclass);
10904 }
10905 if col.desc {
10906 self.write_space();
10907 self.write_keyword("DESC");
10908 } else if col.asc {
10909 self.write_space();
10910 self.write_keyword("ASC");
10911 }
10912 if let Some(nulls_first) = col.nulls_first {
10913 self.write_space();
10914 self.write_keyword("NULLS");
10915 self.write_space();
10916 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
10917 }
10918 }
10919 self.write(")");
10920 }
10921
10922 if !ci.include_columns.is_empty() {
10924 self.write_space();
10925 self.write_keyword("INCLUDE");
10926 self.write(" (");
10927 for (i, col) in ci.include_columns.iter().enumerate() {
10928 if i > 0 {
10929 self.write(", ");
10930 }
10931 self.generate_identifier(col)?;
10932 }
10933 self.write(")");
10934 }
10935
10936 if !ci.with_options.is_empty() {
10938 self.write_space();
10939 self.write_keyword("WITH");
10940 self.write(" (");
10941 for (i, (key, value)) in ci.with_options.iter().enumerate() {
10942 if i > 0 {
10943 self.write(", ");
10944 }
10945 self.write(key);
10946 self.write("=");
10947 self.write(value);
10948 }
10949 self.write(")");
10950 }
10951
10952 if let Some(ref where_clause) = ci.where_clause {
10954 self.write_space();
10955 self.write_keyword("WHERE");
10956 self.write_space();
10957 self.generate_expression(where_clause)?;
10958 }
10959
10960 if let Some(ref on_fg) = ci.on_filegroup {
10962 self.write_space();
10963 self.write_keyword("ON");
10964 self.write_space();
10965 self.write(on_fg);
10966 }
10967
10968 Ok(())
10969 }
10970
10971 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
10972 self.write_keyword("DROP INDEX");
10973
10974 if di.concurrently {
10975 self.write_space();
10976 self.write_keyword("CONCURRENTLY");
10977 }
10978
10979 if di.if_exists {
10980 self.write_space();
10981 self.write_keyword("IF EXISTS");
10982 }
10983
10984 self.write_space();
10985 self.generate_identifier(&di.name)?;
10986
10987 if let Some(ref table) = di.table {
10988 self.write_space();
10989 self.write_keyword("ON");
10990 self.write_space();
10991 self.generate_table(table)?;
10992 }
10993
10994 Ok(())
10995 }
10996
10997 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
10998 self.write_keyword("CREATE");
10999
11000 if let Some(ref algorithm) = cv.algorithm {
11002 self.write_space();
11003 self.write_keyword("ALGORITHM");
11004 self.write("=");
11005 self.write_keyword(algorithm);
11006 }
11007
11008 if let Some(ref definer) = cv.definer {
11010 self.write_space();
11011 self.write_keyword("DEFINER");
11012 self.write("=");
11013 self.write(definer);
11014 }
11015
11016 if cv.security_sql_style && !cv.security_after_name {
11018 if let Some(ref security) = cv.security {
11019 self.write_space();
11020 self.write_keyword("SQL SECURITY");
11021 self.write_space();
11022 match security {
11023 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11024 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11025 FunctionSecurity::None => self.write_keyword("NONE"),
11026 }
11027 }
11028 }
11029
11030 if cv.or_alter {
11031 self.write_space();
11032 self.write_keyword("OR ALTER");
11033 } else if cv.or_replace {
11034 self.write_space();
11035 self.write_keyword("OR REPLACE");
11036 }
11037
11038 if cv.temporary {
11039 self.write_space();
11040 self.write_keyword("TEMPORARY");
11041 }
11042
11043 if cv.materialized {
11044 self.write_space();
11045 self.write_keyword("MATERIALIZED");
11046 }
11047
11048 if cv.secure {
11050 self.write_space();
11051 self.write_keyword("SECURE");
11052 }
11053
11054 self.write_space();
11055 self.write_keyword("VIEW");
11056
11057 if cv.if_not_exists {
11058 self.write_space();
11059 self.write_keyword("IF NOT EXISTS");
11060 }
11061
11062 self.write_space();
11063 self.generate_table(&cv.name)?;
11064
11065 if let Some(ref on_cluster) = cv.on_cluster {
11067 self.write_space();
11068 self.generate_on_cluster(on_cluster)?;
11069 }
11070
11071 if let Some(ref to_table) = cv.to_table {
11073 self.write_space();
11074 self.write_keyword("TO");
11075 self.write_space();
11076 self.generate_table(to_table)?;
11077 }
11078
11079 if !cv.materialized {
11082 if !cv.columns.is_empty() {
11084 self.write(" (");
11085 for (i, col) in cv.columns.iter().enumerate() {
11086 if i > 0 {
11087 self.write(", ");
11088 }
11089 self.generate_identifier(&col.name)?;
11090 if !col.options.is_empty() {
11092 self.write_space();
11093 self.generate_options_clause(&col.options)?;
11094 }
11095 if let Some(ref comment) = col.comment {
11096 self.write_space();
11097 self.write_keyword("COMMENT");
11098 self.write_space();
11099 self.generate_string_literal(comment)?;
11100 }
11101 }
11102 self.write(")");
11103 }
11104
11105 if !cv.security_sql_style || cv.security_after_name {
11108 if let Some(ref security) = cv.security {
11109 self.write_space();
11110 if cv.security_sql_style {
11111 self.write_keyword("SQL SECURITY");
11112 } else {
11113 self.write_keyword("SECURITY");
11114 }
11115 self.write_space();
11116 match security {
11117 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11118 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11119 FunctionSecurity::None => self.write_keyword("NONE"),
11120 }
11121 }
11122 }
11123
11124 if cv.copy_grants {
11126 self.write_space();
11127 self.write_keyword("COPY GRANTS");
11128 }
11129 } else {
11130 if cv.copy_grants {
11132 self.write_space();
11133 self.write_keyword("COPY GRANTS");
11134 }
11135
11136 if let Some(ref schema) = cv.schema {
11138 self.write(" (");
11139 for (i, expr) in schema.expressions.iter().enumerate() {
11140 if i > 0 {
11141 self.write(", ");
11142 }
11143 self.generate_expression(expr)?;
11144 }
11145 self.write(")");
11146 } else if !cv.columns.is_empty() {
11147 self.write(" (");
11149 for (i, col) in cv.columns.iter().enumerate() {
11150 if i > 0 {
11151 self.write(", ");
11152 }
11153 self.generate_identifier(&col.name)?;
11154 if !col.options.is_empty() {
11156 self.write_space();
11157 self.generate_options_clause(&col.options)?;
11158 }
11159 if let Some(ref comment) = col.comment {
11160 self.write_space();
11161 self.write_keyword("COMMENT");
11162 self.write_space();
11163 self.generate_string_literal(comment)?;
11164 }
11165 }
11166 self.write(")");
11167 }
11168
11169 if let Some(ref unique_key) = cv.unique_key {
11171 self.write_space();
11172 self.write_keyword("KEY");
11173 self.write(" (");
11174 for (i, expr) in unique_key.expressions.iter().enumerate() {
11175 if i > 0 {
11176 self.write(", ");
11177 }
11178 self.generate_expression(expr)?;
11179 }
11180 self.write(")");
11181 }
11182 }
11183
11184 if let Some(ref comment) = cv.comment {
11186 self.write_space();
11187 self.write_keyword("COMMENT");
11188 self.write("=");
11189 self.generate_string_literal(comment)?;
11190 }
11191
11192 if !cv.tags.is_empty() {
11194 self.write_space();
11195 self.write_keyword("TAG");
11196 self.write(" (");
11197 for (i, (name, value)) in cv.tags.iter().enumerate() {
11198 if i > 0 {
11199 self.write(", ");
11200 }
11201 self.write(name);
11202 self.write("='");
11203 self.write(value);
11204 self.write("'");
11205 }
11206 self.write(")");
11207 }
11208
11209 if !cv.options.is_empty() {
11211 self.write_space();
11212 self.generate_options_clause(&cv.options)?;
11213 }
11214
11215 if let Some(ref build) = cv.build {
11217 self.write_space();
11218 self.write_keyword("BUILD");
11219 self.write_space();
11220 self.write_keyword(build);
11221 }
11222
11223 if let Some(ref refresh) = cv.refresh {
11225 self.write_space();
11226 self.generate_refresh_trigger_property(refresh)?;
11227 }
11228
11229 if let Some(auto_refresh) = cv.auto_refresh {
11231 self.write_space();
11232 self.write_keyword("AUTO REFRESH");
11233 self.write_space();
11234 if auto_refresh {
11235 self.write_keyword("YES");
11236 } else {
11237 self.write_keyword("NO");
11238 }
11239 }
11240
11241 for prop in &cv.table_properties {
11243 self.write_space();
11244 self.generate_expression(prop)?;
11245 }
11246
11247 if !matches!(&cv.query, Expression::Null(_)) {
11249 self.write_space();
11250 self.write_keyword("AS");
11251 self.write_space();
11252
11253 if let Some(ref mode) = cv.locking_mode {
11255 self.write_keyword("LOCKING");
11256 self.write_space();
11257 self.write_keyword(mode);
11258 if let Some(ref access) = cv.locking_access {
11259 self.write_space();
11260 self.write_keyword("FOR");
11261 self.write_space();
11262 self.write_keyword(access);
11263 }
11264 self.write_space();
11265 }
11266
11267 if cv.query_parenthesized {
11268 self.write("(");
11269 }
11270 self.generate_expression(&cv.query)?;
11271 if cv.query_parenthesized {
11272 self.write(")");
11273 }
11274 }
11275
11276 if cv.no_schema_binding {
11278 self.write_space();
11279 self.write_keyword("WITH NO SCHEMA BINDING");
11280 }
11281
11282 Ok(())
11283 }
11284
11285 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
11286 self.write_keyword("DROP");
11287
11288 if dv.materialized {
11289 self.write_space();
11290 self.write_keyword("MATERIALIZED");
11291 }
11292
11293 self.write_space();
11294 self.write_keyword("VIEW");
11295
11296 if dv.if_exists {
11297 self.write_space();
11298 self.write_keyword("IF EXISTS");
11299 }
11300
11301 self.write_space();
11302 self.generate_table(&dv.name)?;
11303
11304 Ok(())
11305 }
11306
11307 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
11308 match tr.target {
11309 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
11310 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
11311 }
11312 if tr.if_exists {
11313 self.write_space();
11314 self.write_keyword("IF EXISTS");
11315 }
11316 self.write_space();
11317 self.generate_table(&tr.table)?;
11318
11319 if let Some(ref on_cluster) = tr.on_cluster {
11321 self.write_space();
11322 self.generate_on_cluster(on_cluster)?;
11323 }
11324
11325 if !tr.extra_tables.is_empty() {
11327 let skip_first = if let Some(first) = tr.extra_tables.first() {
11329 first.table.name == tr.table.name && first.star
11330 } else {
11331 false
11332 };
11333
11334 let strip_star = matches!(
11336 self.config.dialect,
11337 Some(crate::dialects::DialectType::PostgreSQL)
11338 | Some(crate::dialects::DialectType::Redshift)
11339 );
11340 if skip_first && !strip_star {
11341 self.write("*");
11342 }
11343
11344 for (i, entry) in tr.extra_tables.iter().enumerate() {
11346 if i == 0 && skip_first {
11347 continue; }
11349 self.write(", ");
11350 self.generate_table(&entry.table)?;
11351 if entry.star && !strip_star {
11352 self.write("*");
11353 }
11354 }
11355 }
11356
11357 if let Some(identity) = &tr.identity {
11359 self.write_space();
11360 match identity {
11361 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
11362 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
11363 }
11364 }
11365
11366 if tr.cascade {
11367 self.write_space();
11368 self.write_keyword("CASCADE");
11369 }
11370
11371 if tr.restrict {
11372 self.write_space();
11373 self.write_keyword("RESTRICT");
11374 }
11375
11376 if let Some(ref partition) = tr.partition {
11378 self.write_space();
11379 self.generate_expression(partition)?;
11380 }
11381
11382 Ok(())
11383 }
11384
11385 fn generate_use(&mut self, u: &Use) -> Result<()> {
11386 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
11388 self.write_keyword("DATABASE");
11389 self.write_space();
11390 self.generate_identifier(&u.this)?;
11391 return Ok(());
11392 }
11393
11394 self.write_keyword("USE");
11395
11396 if let Some(kind) = &u.kind {
11397 self.write_space();
11398 match kind {
11399 UseKind::Database => self.write_keyword("DATABASE"),
11400 UseKind::Schema => self.write_keyword("SCHEMA"),
11401 UseKind::Role => self.write_keyword("ROLE"),
11402 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
11403 UseKind::Catalog => self.write_keyword("CATALOG"),
11404 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
11405 }
11406 }
11407
11408 self.write_space();
11409 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
11412 self.write(&u.this.name);
11413 } else {
11414 self.generate_identifier(&u.this)?;
11415 }
11416 Ok(())
11417 }
11418
11419 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
11420 self.write_keyword("CACHE");
11421 if c.lazy {
11422 self.write_space();
11423 self.write_keyword("LAZY");
11424 }
11425 self.write_space();
11426 self.write_keyword("TABLE");
11427 self.write_space();
11428 self.generate_identifier(&c.table)?;
11429
11430 if !c.options.is_empty() {
11432 self.write_space();
11433 self.write_keyword("OPTIONS");
11434 self.write("(");
11435 for (i, (key, value)) in c.options.iter().enumerate() {
11436 if i > 0 {
11437 self.write(", ");
11438 }
11439 self.generate_expression(key)?;
11440 self.write(" = ");
11441 self.generate_expression(value)?;
11442 }
11443 self.write(")");
11444 }
11445
11446 if let Some(query) = &c.query {
11448 self.write_space();
11449 self.write_keyword("AS");
11450 self.write_space();
11451 self.generate_expression(query)?;
11452 }
11453
11454 Ok(())
11455 }
11456
11457 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
11458 self.write_keyword("UNCACHE TABLE");
11459 if u.if_exists {
11460 self.write_space();
11461 self.write_keyword("IF EXISTS");
11462 }
11463 self.write_space();
11464 self.generate_identifier(&u.table)?;
11465 Ok(())
11466 }
11467
11468 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
11469 self.write_keyword("LOAD DATA");
11470 if l.local {
11471 self.write_space();
11472 self.write_keyword("LOCAL");
11473 }
11474 self.write_space();
11475 self.write_keyword("INPATH");
11476 self.write_space();
11477 self.write("'");
11478 self.write(&l.inpath);
11479 self.write("'");
11480
11481 if l.overwrite {
11482 self.write_space();
11483 self.write_keyword("OVERWRITE");
11484 }
11485
11486 self.write_space();
11487 self.write_keyword("INTO TABLE");
11488 self.write_space();
11489 self.generate_expression(&l.table)?;
11490
11491 if !l.partition.is_empty() {
11493 self.write_space();
11494 self.write_keyword("PARTITION");
11495 self.write("(");
11496 for (i, (col, val)) in l.partition.iter().enumerate() {
11497 if i > 0 {
11498 self.write(", ");
11499 }
11500 self.generate_identifier(col)?;
11501 self.write(" = ");
11502 self.generate_expression(val)?;
11503 }
11504 self.write(")");
11505 }
11506
11507 if let Some(fmt) = &l.input_format {
11509 self.write_space();
11510 self.write_keyword("INPUTFORMAT");
11511 self.write_space();
11512 self.write("'");
11513 self.write(fmt);
11514 self.write("'");
11515 }
11516
11517 if let Some(serde) = &l.serde {
11519 self.write_space();
11520 self.write_keyword("SERDE");
11521 self.write_space();
11522 self.write("'");
11523 self.write(serde);
11524 self.write("'");
11525 }
11526
11527 Ok(())
11528 }
11529
11530 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
11531 self.write_keyword("PRAGMA");
11532 self.write_space();
11533
11534 if let Some(schema) = &p.schema {
11536 self.generate_identifier(schema)?;
11537 self.write(".");
11538 }
11539
11540 self.generate_identifier(&p.name)?;
11542
11543 if let Some(value) = &p.value {
11545 self.write(" = ");
11546 self.generate_expression(value)?;
11547 } else if !p.args.is_empty() {
11548 self.write("(");
11549 for (i, arg) in p.args.iter().enumerate() {
11550 if i > 0 {
11551 self.write(", ");
11552 }
11553 self.generate_expression(arg)?;
11554 }
11555 self.write(")");
11556 }
11557
11558 Ok(())
11559 }
11560
11561 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
11562 self.write_keyword("GRANT");
11563 self.write_space();
11564
11565 for (i, privilege) in g.privileges.iter().enumerate() {
11567 if i > 0 {
11568 self.write(", ");
11569 }
11570 self.write_keyword(&privilege.name);
11571 if !privilege.columns.is_empty() {
11573 self.write("(");
11574 for (j, col) in privilege.columns.iter().enumerate() {
11575 if j > 0 {
11576 self.write(", ");
11577 }
11578 self.write(col);
11579 }
11580 self.write(")");
11581 }
11582 }
11583
11584 self.write_space();
11585 self.write_keyword("ON");
11586 self.write_space();
11587
11588 if let Some(kind) = &g.kind {
11590 self.write_keyword(kind);
11591 self.write_space();
11592 }
11593
11594 {
11596 use crate::dialects::DialectType;
11597 let should_upper = matches!(
11598 self.config.dialect,
11599 Some(DialectType::PostgreSQL)
11600 | Some(DialectType::CockroachDB)
11601 | Some(DialectType::Materialize)
11602 | Some(DialectType::RisingWave)
11603 ) && (g.kind.as_deref() == Some("FUNCTION")
11604 || g.kind.as_deref() == Some("PROCEDURE"));
11605 if should_upper {
11606 use crate::expressions::Identifier;
11607 let upper_id = Identifier {
11608 name: g.securable.name.to_ascii_uppercase(),
11609 quoted: g.securable.quoted,
11610 ..g.securable.clone()
11611 };
11612 self.generate_identifier(&upper_id)?;
11613 } else {
11614 self.generate_identifier(&g.securable)?;
11615 }
11616 }
11617
11618 if !g.function_params.is_empty() {
11620 self.write("(");
11621 for (i, param) in g.function_params.iter().enumerate() {
11622 if i > 0 {
11623 self.write(", ");
11624 }
11625 self.write(param);
11626 }
11627 self.write(")");
11628 }
11629
11630 self.write_space();
11631 self.write_keyword("TO");
11632 self.write_space();
11633
11634 for (i, principal) in g.principals.iter().enumerate() {
11636 if i > 0 {
11637 self.write(", ");
11638 }
11639 if principal.is_role {
11640 self.write_keyword("ROLE");
11641 self.write_space();
11642 } else if principal.is_group {
11643 self.write_keyword("GROUP");
11644 self.write_space();
11645 } else if principal.is_share {
11646 self.write_keyword("SHARE");
11647 self.write_space();
11648 }
11649 self.generate_identifier(&principal.name)?;
11650 }
11651
11652 if g.grant_option {
11654 self.write_space();
11655 self.write_keyword("WITH GRANT OPTION");
11656 }
11657
11658 if let Some(ref principal) = g.as_principal {
11660 self.write_space();
11661 self.write_keyword("AS");
11662 self.write_space();
11663 self.generate_identifier(principal)?;
11664 }
11665
11666 Ok(())
11667 }
11668
11669 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
11670 self.write_keyword("REVOKE");
11671 self.write_space();
11672
11673 if r.grant_option {
11675 self.write_keyword("GRANT OPTION FOR");
11676 self.write_space();
11677 }
11678
11679 for (i, privilege) in r.privileges.iter().enumerate() {
11681 if i > 0 {
11682 self.write(", ");
11683 }
11684 self.write_keyword(&privilege.name);
11685 if !privilege.columns.is_empty() {
11687 self.write("(");
11688 for (j, col) in privilege.columns.iter().enumerate() {
11689 if j > 0 {
11690 self.write(", ");
11691 }
11692 self.write(col);
11693 }
11694 self.write(")");
11695 }
11696 }
11697
11698 self.write_space();
11699 self.write_keyword("ON");
11700 self.write_space();
11701
11702 if let Some(kind) = &r.kind {
11704 self.write_keyword(kind);
11705 self.write_space();
11706 }
11707
11708 {
11710 use crate::dialects::DialectType;
11711 let should_upper = matches!(
11712 self.config.dialect,
11713 Some(DialectType::PostgreSQL)
11714 | Some(DialectType::CockroachDB)
11715 | Some(DialectType::Materialize)
11716 | Some(DialectType::RisingWave)
11717 ) && (r.kind.as_deref() == Some("FUNCTION")
11718 || r.kind.as_deref() == Some("PROCEDURE"));
11719 if should_upper {
11720 use crate::expressions::Identifier;
11721 let upper_id = Identifier {
11722 name: r.securable.name.to_ascii_uppercase(),
11723 quoted: r.securable.quoted,
11724 ..r.securable.clone()
11725 };
11726 self.generate_identifier(&upper_id)?;
11727 } else {
11728 self.generate_identifier(&r.securable)?;
11729 }
11730 }
11731
11732 if !r.function_params.is_empty() {
11734 self.write("(");
11735 for (i, param) in r.function_params.iter().enumerate() {
11736 if i > 0 {
11737 self.write(", ");
11738 }
11739 self.write(param);
11740 }
11741 self.write(")");
11742 }
11743
11744 self.write_space();
11745 self.write_keyword("FROM");
11746 self.write_space();
11747
11748 for (i, principal) in r.principals.iter().enumerate() {
11750 if i > 0 {
11751 self.write(", ");
11752 }
11753 if principal.is_role {
11754 self.write_keyword("ROLE");
11755 self.write_space();
11756 } else if principal.is_group {
11757 self.write_keyword("GROUP");
11758 self.write_space();
11759 } else if principal.is_share {
11760 self.write_keyword("SHARE");
11761 self.write_space();
11762 }
11763 self.generate_identifier(&principal.name)?;
11764 }
11765
11766 if r.cascade {
11768 self.write_space();
11769 self.write_keyword("CASCADE");
11770 } else if r.restrict {
11771 self.write_space();
11772 self.write_keyword("RESTRICT");
11773 }
11774
11775 Ok(())
11776 }
11777
11778 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
11779 self.write_keyword("COMMENT");
11780
11781 if c.exists {
11783 self.write_space();
11784 self.write_keyword("IF EXISTS");
11785 }
11786
11787 self.write_space();
11788 self.write_keyword("ON");
11789
11790 if c.materialized {
11792 self.write_space();
11793 self.write_keyword("MATERIALIZED");
11794 }
11795
11796 self.write_space();
11797 self.write_keyword(&c.kind);
11798 self.write_space();
11799
11800 self.generate_expression(&c.this)?;
11802
11803 self.write_space();
11804 self.write_keyword("IS");
11805 self.write_space();
11806
11807 self.generate_expression(&c.expression)?;
11809
11810 Ok(())
11811 }
11812
11813 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
11814 self.write_keyword("SET");
11815
11816 for (i, item) in s.items.iter().enumerate() {
11817 if i > 0 {
11818 self.write(",");
11819 }
11820 self.write_space();
11821
11822 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
11824 if let Some(ref kind) = item.kind {
11825 if has_variable_kind {
11829 if matches!(
11830 self.config.dialect,
11831 Some(DialectType::Spark | DialectType::Databricks | DialectType::DuckDB)
11832 ) {
11833 self.write_keyword("VARIABLE");
11834 self.write_space();
11835 }
11836 } else {
11837 self.write_keyword(kind);
11838 self.write_space();
11839 }
11840 }
11841
11842 let name_str = match &item.name {
11844 Expression::Identifier(id) => Some(id.name.as_str()),
11845 _ => None,
11846 };
11847
11848 let is_transaction = name_str == Some("TRANSACTION");
11849 let is_character_set = name_str == Some("CHARACTER SET");
11850 let is_names = name_str == Some("NAMES");
11851 let is_collate = name_str == Some("COLLATE");
11852 let is_value_only =
11853 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
11854
11855 if is_transaction {
11856 self.write_keyword("TRANSACTION");
11858 if let Expression::Identifier(id) = &item.value {
11859 if !id.name.is_empty() {
11860 self.write_space();
11861 self.write(&id.name);
11862 }
11863 }
11864 } else if is_character_set {
11865 self.write_keyword("CHARACTER SET");
11867 self.write_space();
11868 self.generate_set_value(&item.value)?;
11869 } else if is_names {
11870 self.write_keyword("NAMES");
11872 self.write_space();
11873 self.generate_set_value(&item.value)?;
11874 } else if is_collate {
11875 self.write_keyword("COLLATE");
11877 self.write_space();
11878 self.generate_set_value(&item.value)?;
11879 } else if has_variable_kind {
11880 if let Some(ns) = name_str {
11883 self.write(ns);
11884 } else {
11885 self.generate_expression(&item.name)?;
11886 }
11887 self.write(" = ");
11888 self.generate_set_value(&item.value)?;
11889 } else if is_value_only {
11890 self.generate_expression(&item.name)?;
11892 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
11893 self.generate_expression(&item.name)?;
11895 self.write_space();
11896 self.generate_set_value(&item.value)?;
11897 } else {
11898 match &item.name {
11901 Expression::Identifier(id) => {
11902 self.write(&id.name);
11903 }
11904 _ => {
11905 self.generate_expression(&item.name)?;
11906 }
11907 }
11908 self.write(" = ");
11909 self.generate_set_value(&item.value)?;
11910 }
11911 }
11912
11913 Ok(())
11914 }
11915
11916 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
11919 if let Expression::Identifier(id) = value {
11920 match id.name.as_str() {
11921 "DEFAULT" | "ON" | "OFF" => {
11922 self.write_keyword(&id.name);
11923 return Ok(());
11924 }
11925 _ => {}
11926 }
11927 }
11928 self.generate_expression(value)
11929 }
11930
11931 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
11934 self.write_keyword("ALTER");
11935 if let Some(ref algorithm) = av.algorithm {
11937 self.write_space();
11938 self.write_keyword("ALGORITHM");
11939 self.write(" = ");
11940 self.write_keyword(algorithm);
11941 }
11942 if let Some(ref definer) = av.definer {
11943 self.write_space();
11944 self.write_keyword("DEFINER");
11945 self.write(" = ");
11946 self.write(definer);
11947 }
11948 if let Some(ref sql_security) = av.sql_security {
11949 self.write_space();
11950 self.write_keyword("SQL SECURITY");
11951 self.write(" = ");
11952 self.write_keyword(sql_security);
11953 }
11954 self.write_space();
11955 self.write_keyword("VIEW");
11956 self.write_space();
11957 self.generate_table(&av.name)?;
11958
11959 if !av.columns.is_empty() {
11961 self.write(" (");
11962 for (i, col) in av.columns.iter().enumerate() {
11963 if i > 0 {
11964 self.write(", ");
11965 }
11966 self.generate_identifier(&col.name)?;
11967 if let Some(ref comment) = col.comment {
11968 self.write_space();
11969 self.write_keyword("COMMENT");
11970 self.write(" ");
11971 self.generate_string_literal(comment)?;
11972 }
11973 }
11974 self.write(")");
11975 }
11976
11977 if let Some(ref opt) = av.with_option {
11979 self.write_space();
11980 self.write_keyword("WITH");
11981 self.write_space();
11982 self.write_keyword(opt);
11983 }
11984
11985 for action in &av.actions {
11986 self.write_space();
11987 match action {
11988 AlterViewAction::Rename(new_name) => {
11989 self.write_keyword("RENAME TO");
11990 self.write_space();
11991 self.generate_table(new_name)?;
11992 }
11993 AlterViewAction::OwnerTo(owner) => {
11994 self.write_keyword("OWNER TO");
11995 self.write_space();
11996 self.generate_identifier(owner)?;
11997 }
11998 AlterViewAction::SetSchema(schema) => {
11999 self.write_keyword("SET SCHEMA");
12000 self.write_space();
12001 self.generate_identifier(schema)?;
12002 }
12003 AlterViewAction::SetAuthorization(auth) => {
12004 self.write_keyword("SET AUTHORIZATION");
12005 self.write_space();
12006 self.write(auth);
12007 }
12008 AlterViewAction::AlterColumn { name, action } => {
12009 self.write_keyword("ALTER COLUMN");
12010 self.write_space();
12011 self.generate_identifier(name)?;
12012 self.write_space();
12013 self.generate_alter_column_action(action)?;
12014 }
12015 AlterViewAction::AsSelect(query) => {
12016 self.write_keyword("AS");
12017 self.write_space();
12018 self.generate_expression(query)?;
12019 }
12020 AlterViewAction::SetTblproperties(props) => {
12021 self.write_keyword("SET TBLPROPERTIES");
12022 self.write(" (");
12023 for (i, (key, value)) in props.iter().enumerate() {
12024 if i > 0 {
12025 self.write(", ");
12026 }
12027 self.generate_string_literal(key)?;
12028 self.write("=");
12029 self.generate_string_literal(value)?;
12030 }
12031 self.write(")");
12032 }
12033 AlterViewAction::UnsetTblproperties(keys) => {
12034 self.write_keyword("UNSET TBLPROPERTIES");
12035 self.write(" (");
12036 for (i, key) in keys.iter().enumerate() {
12037 if i > 0 {
12038 self.write(", ");
12039 }
12040 self.generate_string_literal(key)?;
12041 }
12042 self.write(")");
12043 }
12044 }
12045 }
12046
12047 Ok(())
12048 }
12049
12050 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
12051 self.write_keyword("ALTER INDEX");
12052 self.write_space();
12053 self.generate_identifier(&ai.name)?;
12054
12055 if let Some(table) = &ai.table {
12056 self.write_space();
12057 self.write_keyword("ON");
12058 self.write_space();
12059 self.generate_table(table)?;
12060 }
12061
12062 for action in &ai.actions {
12063 self.write_space();
12064 match action {
12065 AlterIndexAction::Rename(new_name) => {
12066 self.write_keyword("RENAME TO");
12067 self.write_space();
12068 self.generate_identifier(new_name)?;
12069 }
12070 AlterIndexAction::SetTablespace(tablespace) => {
12071 self.write_keyword("SET TABLESPACE");
12072 self.write_space();
12073 self.generate_identifier(tablespace)?;
12074 }
12075 AlterIndexAction::Visible(visible) => {
12076 if *visible {
12077 self.write_keyword("VISIBLE");
12078 } else {
12079 self.write_keyword("INVISIBLE");
12080 }
12081 }
12082 }
12083 }
12084
12085 Ok(())
12086 }
12087
12088 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
12089 for comment in &cs.leading_comments {
12091 self.write_formatted_comment(comment);
12092 self.write_space();
12093 }
12094
12095 let saved_athena_hive_context = self.athena_hive_context;
12097 if matches!(
12098 self.config.dialect,
12099 Some(crate::dialects::DialectType::Athena)
12100 ) {
12101 self.athena_hive_context = true;
12102 }
12103
12104 self.write_keyword("CREATE SCHEMA");
12105
12106 if cs.if_not_exists {
12107 self.write_space();
12108 self.write_keyword("IF NOT EXISTS");
12109 }
12110
12111 self.write_space();
12112 for (i, part) in cs.name.iter().enumerate() {
12113 if i > 0 {
12114 self.write(".");
12115 }
12116 self.generate_identifier(part)?;
12117 }
12118
12119 if let Some(ref clone_parts) = cs.clone_from {
12120 self.write_keyword(" CLONE ");
12121 for (i, part) in clone_parts.iter().enumerate() {
12122 if i > 0 {
12123 self.write(".");
12124 }
12125 self.generate_identifier(part)?;
12126 }
12127 }
12128
12129 if let Some(ref at_clause) = cs.at_clause {
12130 self.write_space();
12131 self.generate_expression(at_clause)?;
12132 }
12133
12134 if let Some(auth) = &cs.authorization {
12135 self.write_space();
12136 self.write_keyword("AUTHORIZATION");
12137 self.write_space();
12138 self.generate_identifier(auth)?;
12139 }
12140
12141 let with_properties: Vec<_> = cs
12144 .properties
12145 .iter()
12146 .filter(|p| matches!(p, Expression::Property(_)))
12147 .collect();
12148 let other_properties: Vec<_> = cs
12149 .properties
12150 .iter()
12151 .filter(|p| !matches!(p, Expression::Property(_)))
12152 .collect();
12153
12154 if !with_properties.is_empty() {
12156 self.write_space();
12157 self.write_keyword("WITH");
12158 self.write(" (");
12159 for (i, prop) in with_properties.iter().enumerate() {
12160 if i > 0 {
12161 self.write(", ");
12162 }
12163 self.generate_expression(prop)?;
12164 }
12165 self.write(")");
12166 }
12167
12168 for prop in other_properties {
12170 self.write_space();
12171 self.generate_expression(prop)?;
12172 }
12173
12174 self.athena_hive_context = saved_athena_hive_context;
12176
12177 Ok(())
12178 }
12179
12180 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
12181 self.write_keyword("DROP SCHEMA");
12182
12183 if ds.if_exists {
12184 self.write_space();
12185 self.write_keyword("IF EXISTS");
12186 }
12187
12188 self.write_space();
12189 self.generate_identifier(&ds.name)?;
12190
12191 if ds.cascade {
12192 self.write_space();
12193 self.write_keyword("CASCADE");
12194 }
12195
12196 Ok(())
12197 }
12198
12199 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
12200 self.write_keyword("DROP NAMESPACE");
12201
12202 if dn.if_exists {
12203 self.write_space();
12204 self.write_keyword("IF EXISTS");
12205 }
12206
12207 self.write_space();
12208 self.generate_identifier(&dn.name)?;
12209
12210 if dn.cascade {
12211 self.write_space();
12212 self.write_keyword("CASCADE");
12213 }
12214
12215 Ok(())
12216 }
12217
12218 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
12219 self.write_keyword("CREATE DATABASE");
12220
12221 if cd.if_not_exists {
12222 self.write_space();
12223 self.write_keyword("IF NOT EXISTS");
12224 }
12225
12226 self.write_space();
12227 self.generate_identifier(&cd.name)?;
12228
12229 if let Some(ref clone_src) = cd.clone_from {
12230 self.write_keyword(" CLONE ");
12231 self.generate_identifier(clone_src)?;
12232 }
12233
12234 if let Some(ref at_clause) = cd.at_clause {
12236 self.write_space();
12237 self.generate_expression(at_clause)?;
12238 }
12239
12240 for option in &cd.options {
12241 self.write_space();
12242 match option {
12243 DatabaseOption::CharacterSet(charset) => {
12244 self.write_keyword("CHARACTER SET");
12245 self.write(" = ");
12246 self.write(&format!("'{}'", charset));
12247 }
12248 DatabaseOption::Collate(collate) => {
12249 self.write_keyword("COLLATE");
12250 self.write(" = ");
12251 self.write(&format!("'{}'", collate));
12252 }
12253 DatabaseOption::Owner(owner) => {
12254 self.write_keyword("OWNER");
12255 self.write(" = ");
12256 self.generate_identifier(owner)?;
12257 }
12258 DatabaseOption::Template(template) => {
12259 self.write_keyword("TEMPLATE");
12260 self.write(" = ");
12261 self.generate_identifier(template)?;
12262 }
12263 DatabaseOption::Encoding(encoding) => {
12264 self.write_keyword("ENCODING");
12265 self.write(" = ");
12266 self.write(&format!("'{}'", encoding));
12267 }
12268 DatabaseOption::Location(location) => {
12269 self.write_keyword("LOCATION");
12270 self.write(" = ");
12271 self.write(&format!("'{}'", location));
12272 }
12273 }
12274 }
12275
12276 Ok(())
12277 }
12278
12279 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
12280 self.write_keyword("DROP DATABASE");
12281
12282 if dd.if_exists {
12283 self.write_space();
12284 self.write_keyword("IF EXISTS");
12285 }
12286
12287 self.write_space();
12288 self.generate_identifier(&dd.name)?;
12289
12290 if dd.sync {
12291 self.write_space();
12292 self.write_keyword("SYNC");
12293 }
12294
12295 Ok(())
12296 }
12297
12298 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
12299 self.write_keyword("CREATE");
12300
12301 if cf.or_alter {
12302 self.write_space();
12303 self.write_keyword("OR ALTER");
12304 } else if cf.or_replace {
12305 self.write_space();
12306 self.write_keyword("OR REPLACE");
12307 }
12308
12309 if cf.temporary {
12310 self.write_space();
12311 self.write_keyword("TEMPORARY");
12312 }
12313
12314 self.write_space();
12315 if cf.is_table_function {
12316 self.write_keyword("TABLE FUNCTION");
12317 } else {
12318 self.write_keyword("FUNCTION");
12319 }
12320
12321 if cf.if_not_exists {
12322 self.write_space();
12323 self.write_keyword("IF NOT EXISTS");
12324 }
12325
12326 self.write_space();
12327 self.generate_table(&cf.name)?;
12328 if cf.has_parens {
12329 let func_multiline = self.config.pretty
12330 && matches!(
12331 self.config.dialect,
12332 Some(crate::dialects::DialectType::TSQL)
12333 | Some(crate::dialects::DialectType::Fabric)
12334 )
12335 && !cf.parameters.is_empty();
12336 if func_multiline {
12337 self.write("(\n");
12338 self.indent_level += 2;
12339 self.write_indent();
12340 self.generate_function_parameters(&cf.parameters)?;
12341 self.write("\n");
12342 self.indent_level -= 2;
12343 self.write(")");
12344 } else {
12345 self.write("(");
12346 self.generate_function_parameters(&cf.parameters)?;
12347 self.write(")");
12348 }
12349 }
12350
12351 let use_multiline = self.config.pretty
12354 && matches!(
12355 self.config.dialect,
12356 Some(crate::dialects::DialectType::BigQuery)
12357 | Some(crate::dialects::DialectType::TSQL)
12358 | Some(crate::dialects::DialectType::Fabric)
12359 );
12360
12361 if cf.language_first {
12362 if let Some(lang) = &cf.language {
12364 if use_multiline {
12365 self.write_newline();
12366 } else {
12367 self.write_space();
12368 }
12369 self.write_keyword("LANGUAGE");
12370 self.write_space();
12371 self.write(lang);
12372 }
12373
12374 if let Some(sql_data) = &cf.sql_data_access {
12376 self.write_space();
12377 match sql_data {
12378 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12379 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12380 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12381 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12382 }
12383 }
12384
12385 if let Some(ref rtb) = cf.returns_table_body {
12386 if use_multiline {
12387 self.write_newline();
12388 } else {
12389 self.write_space();
12390 }
12391 self.write_keyword("RETURNS");
12392 self.write_space();
12393 self.write(rtb);
12394 } else if let Some(return_type) = &cf.return_type {
12395 if use_multiline {
12396 self.write_newline();
12397 } else {
12398 self.write_space();
12399 }
12400 self.write_keyword("RETURNS");
12401 self.write_space();
12402 self.generate_data_type(return_type)?;
12403 }
12404 } else {
12405 let is_duckdb = matches!(
12408 self.config.dialect,
12409 Some(crate::dialects::DialectType::DuckDB)
12410 );
12411 if let Some(ref rtb) = cf.returns_table_body {
12412 if !(is_duckdb && rtb.is_empty()) {
12413 if use_multiline {
12414 self.write_newline();
12415 } else {
12416 self.write_space();
12417 }
12418 self.write_keyword("RETURNS");
12419 self.write_space();
12420 self.write(rtb);
12421 }
12422 } else if let Some(return_type) = &cf.return_type {
12423 if !is_duckdb {
12425 let is_table_return = matches!(return_type, crate::expressions::DataType::Custom { ref name } if name.eq_ignore_ascii_case("TABLE"));
12426 if use_multiline {
12427 self.write_newline();
12428 } else {
12429 self.write_space();
12430 }
12431 self.write_keyword("RETURNS");
12432 self.write_space();
12433 if is_table_return {
12434 self.write_keyword("TABLE");
12435 } else {
12436 self.generate_data_type(return_type)?;
12437 }
12438 }
12439 }
12440 }
12441
12442 if !cf.property_order.is_empty() {
12444 let is_bigquery = matches!(
12446 self.config.dialect,
12447 Some(crate::dialects::DialectType::BigQuery)
12448 );
12449 let property_order = if is_bigquery {
12450 let mut reordered = Vec::new();
12452 let mut has_as = false;
12453 let mut has_options = false;
12454 for prop in &cf.property_order {
12455 match prop {
12456 FunctionPropertyKind::As => has_as = true,
12457 FunctionPropertyKind::Options => has_options = true,
12458 _ => {}
12459 }
12460 }
12461 if has_as && has_options {
12462 for prop in &cf.property_order {
12464 if *prop != FunctionPropertyKind::As
12465 && *prop != FunctionPropertyKind::Options
12466 {
12467 reordered.push(*prop);
12468 }
12469 }
12470 reordered.push(FunctionPropertyKind::Options);
12471 reordered.push(FunctionPropertyKind::As);
12472 reordered
12473 } else {
12474 cf.property_order.clone()
12475 }
12476 } else {
12477 cf.property_order.clone()
12478 };
12479
12480 for prop in &property_order {
12481 match prop {
12482 FunctionPropertyKind::Set => {
12483 self.generate_function_set_options(cf)?;
12484 }
12485 FunctionPropertyKind::As => {
12486 self.generate_function_body(cf)?;
12487 }
12488 FunctionPropertyKind::Language => {
12489 if !cf.language_first {
12490 if let Some(lang) = &cf.language {
12492 let use_multiline = self.config.pretty
12494 && matches!(
12495 self.config.dialect,
12496 Some(crate::dialects::DialectType::BigQuery)
12497 );
12498 if use_multiline {
12499 self.write_newline();
12500 } else {
12501 self.write_space();
12502 }
12503 self.write_keyword("LANGUAGE");
12504 self.write_space();
12505 self.write(lang);
12506 }
12507 }
12508 }
12509 FunctionPropertyKind::Determinism => {
12510 self.generate_function_determinism(cf)?;
12511 }
12512 FunctionPropertyKind::NullInput => {
12513 self.generate_function_null_input(cf)?;
12514 }
12515 FunctionPropertyKind::Security => {
12516 self.generate_function_security(cf)?;
12517 }
12518 FunctionPropertyKind::SqlDataAccess => {
12519 if !cf.language_first {
12520 self.generate_function_sql_data_access(cf)?;
12522 }
12523 }
12524 FunctionPropertyKind::Options => {
12525 if !cf.options.is_empty() {
12526 self.write_space();
12527 self.generate_options_clause(&cf.options)?;
12528 }
12529 }
12530 FunctionPropertyKind::Environment => {
12531 if !cf.environment.is_empty() {
12532 self.write_space();
12533 self.generate_environment_clause(&cf.environment)?;
12534 }
12535 }
12536 FunctionPropertyKind::Handler => {
12537 if let Some(ref h) = cf.handler {
12538 self.write_space();
12539 self.write_keyword("HANDLER");
12540 self.write_space();
12541 self.write("'");
12542 self.write(h);
12543 self.write("'");
12544 }
12545 }
12546 FunctionPropertyKind::ParameterStyle => {
12547 if let Some(ref ps) = cf.parameter_style {
12548 self.write_space();
12549 self.write_keyword("PARAMETER STYLE");
12550 self.write_space();
12551 self.write_keyword(ps);
12552 }
12553 }
12554 }
12555 }
12556
12557 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
12559 {
12560 self.write_space();
12561 self.generate_options_clause(&cf.options)?;
12562 }
12563
12564 if !cf.environment.is_empty()
12566 && !cf
12567 .property_order
12568 .contains(&FunctionPropertyKind::Environment)
12569 {
12570 self.write_space();
12571 self.generate_environment_clause(&cf.environment)?;
12572 }
12573 } else {
12574 if matches!(
12577 self.config.dialect,
12578 Some(crate::dialects::DialectType::BigQuery)
12579 ) {
12580 self.generate_function_determinism(cf)?;
12581 }
12582
12583 let use_multiline = self.config.pretty
12585 && matches!(
12586 self.config.dialect,
12587 Some(crate::dialects::DialectType::BigQuery)
12588 );
12589
12590 if !cf.language_first {
12591 if let Some(lang) = &cf.language {
12592 if use_multiline {
12593 self.write_newline();
12594 } else {
12595 self.write_space();
12596 }
12597 self.write_keyword("LANGUAGE");
12598 self.write_space();
12599 self.write(lang);
12600 }
12601
12602 self.generate_function_sql_data_access(cf)?;
12604 }
12605
12606 if !matches!(
12608 self.config.dialect,
12609 Some(crate::dialects::DialectType::BigQuery)
12610 ) {
12611 self.generate_function_determinism(cf)?;
12612 }
12613
12614 self.generate_function_null_input(cf)?;
12615 self.generate_function_security(cf)?;
12616 self.generate_function_set_options(cf)?;
12617
12618 if !cf.options.is_empty() {
12620 self.write_space();
12621 self.generate_options_clause(&cf.options)?;
12622 }
12623
12624 if !cf.environment.is_empty() {
12626 self.write_space();
12627 self.generate_environment_clause(&cf.environment)?;
12628 }
12629
12630 self.generate_function_body(cf)?;
12631 }
12632
12633 Ok(())
12634 }
12635
12636 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
12638 for opt in &cf.set_options {
12639 self.write_space();
12640 self.write_keyword("SET");
12641 self.write_space();
12642 self.write(&opt.name);
12643 match &opt.value {
12644 FunctionSetValue::Value { value, use_to } => {
12645 if *use_to {
12646 self.write(" TO ");
12647 } else {
12648 self.write(" = ");
12649 }
12650 self.write(value);
12651 }
12652 FunctionSetValue::FromCurrent => {
12653 self.write_space();
12654 self.write_keyword("FROM CURRENT");
12655 }
12656 }
12657 }
12658 Ok(())
12659 }
12660
12661 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
12663 if let Some(body) = &cf.body {
12664 self.write_space();
12666 let use_multiline = self.config.pretty
12668 && matches!(
12669 self.config.dialect,
12670 Some(crate::dialects::DialectType::BigQuery)
12671 );
12672 match body {
12673 FunctionBody::Block(block) => {
12674 self.write_keyword("AS");
12675 if matches!(
12676 self.config.dialect,
12677 Some(crate::dialects::DialectType::TSQL)
12678 ) {
12679 self.write(" BEGIN ");
12680 self.write(block);
12681 self.write(" END");
12682 } else if matches!(
12683 self.config.dialect,
12684 Some(crate::dialects::DialectType::PostgreSQL)
12685 ) {
12686 self.write(" $$");
12687 self.write(block);
12688 self.write("$$");
12689 } else {
12690 let escaped = self.escape_block_for_single_quote(block);
12692 if use_multiline {
12694 self.write_newline();
12695 } else {
12696 self.write(" ");
12697 }
12698 self.write("'");
12699 self.write(&escaped);
12700 self.write("'");
12701 }
12702 }
12703 FunctionBody::StringLiteral(s) => {
12704 self.write_keyword("AS");
12705 if use_multiline {
12707 self.write_newline();
12708 } else {
12709 self.write(" ");
12710 }
12711 self.write("'");
12712 self.write(s);
12713 self.write("'");
12714 }
12715 FunctionBody::Expression(expr) => {
12716 self.write_keyword("AS");
12717 self.write_space();
12718 self.generate_expression(expr)?;
12719 }
12720 FunctionBody::External(name) => {
12721 self.write_keyword("EXTERNAL NAME");
12722 self.write(" '");
12723 self.write(name);
12724 self.write("'");
12725 }
12726 FunctionBody::Return(expr) => {
12727 if matches!(
12728 self.config.dialect,
12729 Some(crate::dialects::DialectType::DuckDB)
12730 ) {
12731 self.write_keyword("AS");
12733 self.write_space();
12734 let is_table_return = cf.returns_table_body.is_some()
12736 || matches!(&cf.return_type, Some(crate::expressions::DataType::Custom { ref name }) if name.eq_ignore_ascii_case("TABLE"));
12737 if is_table_return {
12738 self.write_keyword("TABLE");
12739 self.write_space();
12740 }
12741 self.generate_expression(expr)?;
12742 } else {
12743 if self.config.create_function_return_as {
12744 self.write_keyword("AS");
12745 if self.config.pretty
12747 && matches!(
12748 self.config.dialect,
12749 Some(crate::dialects::DialectType::TSQL)
12750 | Some(crate::dialects::DialectType::Fabric)
12751 )
12752 {
12753 self.write_newline();
12754 } else {
12755 self.write_space();
12756 }
12757 }
12758 self.write_keyword("RETURN");
12759 self.write_space();
12760 self.generate_expression(expr)?;
12761 }
12762 }
12763 FunctionBody::Statements(stmts) => {
12764 self.write_keyword("AS");
12765 self.write(" BEGIN ");
12766 for (i, stmt) in stmts.iter().enumerate() {
12767 if i > 0 {
12768 self.write(" ");
12769 }
12770 self.generate_expression(stmt)?;
12771 self.write(";");
12772 }
12773 self.write(" END");
12774 }
12775 FunctionBody::RawBlock(text) => {
12776 self.write_newline();
12777 self.write(text);
12778 }
12779 FunctionBody::DollarQuoted { content, tag } => {
12780 self.write_keyword("AS");
12781 self.write(" ");
12782 let supports_dollar_quoting = matches!(
12784 self.config.dialect,
12785 Some(crate::dialects::DialectType::PostgreSQL)
12786 | Some(crate::dialects::DialectType::Databricks)
12787 | Some(crate::dialects::DialectType::Redshift)
12788 | Some(crate::dialects::DialectType::DuckDB)
12789 );
12790 if supports_dollar_quoting {
12791 self.write("$");
12793 if let Some(t) = tag {
12794 self.write(t);
12795 }
12796 self.write("$");
12797 self.write(content);
12798 self.write("$");
12799 if let Some(t) = tag {
12800 self.write(t);
12801 }
12802 self.write("$");
12803 } else {
12804 let escaped = self.escape_block_for_single_quote(content);
12806 self.write("'");
12807 self.write(&escaped);
12808 self.write("'");
12809 }
12810 }
12811 }
12812 }
12813 Ok(())
12814 }
12815
12816 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
12818 if let Some(det) = cf.deterministic {
12819 self.write_space();
12820 if matches!(
12821 self.config.dialect,
12822 Some(crate::dialects::DialectType::BigQuery)
12823 ) {
12824 if det {
12826 self.write_keyword("DETERMINISTIC");
12827 } else {
12828 self.write_keyword("NOT DETERMINISTIC");
12829 }
12830 } else {
12831 if det {
12833 self.write_keyword("IMMUTABLE");
12834 } else {
12835 self.write_keyword("VOLATILE");
12836 }
12837 }
12838 }
12839 Ok(())
12840 }
12841
12842 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
12844 if let Some(returns_null) = cf.returns_null_on_null_input {
12845 self.write_space();
12846 if returns_null {
12847 if cf.strict {
12848 self.write_keyword("STRICT");
12849 } else {
12850 self.write_keyword("RETURNS NULL ON NULL INPUT");
12851 }
12852 } else {
12853 self.write_keyword("CALLED ON NULL INPUT");
12854 }
12855 }
12856 Ok(())
12857 }
12858
12859 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
12861 if let Some(security) = &cf.security {
12862 self.write_space();
12863 if matches!(
12865 self.config.dialect,
12866 Some(crate::dialects::DialectType::MySQL)
12867 ) {
12868 self.write_keyword("SQL SECURITY");
12869 } else {
12870 self.write_keyword("SECURITY");
12871 }
12872 self.write_space();
12873 match security {
12874 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12875 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12876 FunctionSecurity::None => self.write_keyword("NONE"),
12877 }
12878 }
12879 Ok(())
12880 }
12881
12882 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
12884 if let Some(sql_data) = &cf.sql_data_access {
12885 self.write_space();
12886 match sql_data {
12887 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12888 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12889 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12890 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12891 }
12892 }
12893 Ok(())
12894 }
12895
12896 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
12897 for (i, param) in params.iter().enumerate() {
12898 if i > 0 {
12899 self.write(", ");
12900 }
12901
12902 if let Some(mode) = ¶m.mode {
12903 if let Some(text) = ¶m.mode_text {
12904 self.write(text);
12905 } else {
12906 match mode {
12907 ParameterMode::In => self.write_keyword("IN"),
12908 ParameterMode::Out => self.write_keyword("OUT"),
12909 ParameterMode::InOut => self.write_keyword("INOUT"),
12910 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
12911 }
12912 }
12913 self.write_space();
12914 }
12915
12916 if let Some(name) = ¶m.name {
12917 self.generate_identifier(name)?;
12918 let skip_type =
12920 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
12921 if !skip_type {
12922 self.write_space();
12923 self.generate_data_type(¶m.data_type)?;
12924 }
12925 } else {
12926 self.generate_data_type(¶m.data_type)?;
12927 }
12928
12929 if let Some(default) = ¶m.default {
12930 if self.config.parameter_default_equals {
12931 self.write(" = ");
12932 } else {
12933 self.write(" DEFAULT ");
12934 }
12935 self.generate_expression(default)?;
12936 }
12937 }
12938
12939 Ok(())
12940 }
12941
12942 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
12943 self.write_keyword("DROP FUNCTION");
12944
12945 if df.if_exists {
12946 self.write_space();
12947 self.write_keyword("IF EXISTS");
12948 }
12949
12950 self.write_space();
12951 self.generate_table(&df.name)?;
12952
12953 if let Some(params) = &df.parameters {
12954 self.write(" (");
12955 for (i, dt) in params.iter().enumerate() {
12956 if i > 0 {
12957 self.write(", ");
12958 }
12959 self.generate_data_type(dt)?;
12960 }
12961 self.write(")");
12962 }
12963
12964 if df.cascade {
12965 self.write_space();
12966 self.write_keyword("CASCADE");
12967 }
12968
12969 Ok(())
12970 }
12971
12972 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
12973 self.write_keyword("CREATE");
12974
12975 if cp.or_alter {
12976 self.write_space();
12977 self.write_keyword("OR ALTER");
12978 } else if cp.or_replace {
12979 self.write_space();
12980 self.write_keyword("OR REPLACE");
12981 }
12982
12983 self.write_space();
12984 if cp.use_proc_keyword {
12985 self.write_keyword("PROC");
12986 } else {
12987 self.write_keyword("PROCEDURE");
12988 }
12989
12990 if cp.if_not_exists {
12991 self.write_space();
12992 self.write_keyword("IF NOT EXISTS");
12993 }
12994
12995 self.write_space();
12996 self.generate_table(&cp.name)?;
12997 if cp.has_parens {
12998 self.write("(");
12999 self.generate_function_parameters(&cp.parameters)?;
13000 self.write(")");
13001 } else if !cp.parameters.is_empty() {
13002 self.write_space();
13004 self.generate_function_parameters(&cp.parameters)?;
13005 }
13006
13007 if let Some(return_type) = &cp.return_type {
13009 self.write_space();
13010 self.write_keyword("RETURNS");
13011 self.write_space();
13012 self.generate_data_type(return_type)?;
13013 }
13014
13015 if let Some(execute_as) = &cp.execute_as {
13017 self.write_space();
13018 self.write_keyword("EXECUTE AS");
13019 self.write_space();
13020 self.write_keyword(execute_as);
13021 }
13022
13023 if let Some(lang) = &cp.language {
13024 self.write_space();
13025 self.write_keyword("LANGUAGE");
13026 self.write_space();
13027 self.write(lang);
13028 }
13029
13030 if let Some(security) = &cp.security {
13031 self.write_space();
13032 self.write_keyword("SECURITY");
13033 self.write_space();
13034 match security {
13035 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13036 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13037 FunctionSecurity::None => self.write_keyword("NONE"),
13038 }
13039 }
13040
13041 if !cp.with_options.is_empty() {
13043 self.write_space();
13044 self.write_keyword("WITH");
13045 self.write_space();
13046 for (i, opt) in cp.with_options.iter().enumerate() {
13047 if i > 0 {
13048 self.write(", ");
13049 }
13050 self.write(opt);
13051 }
13052 }
13053
13054 if let Some(body) = &cp.body {
13055 self.write_space();
13056 match body {
13057 FunctionBody::Block(block) => {
13058 self.write_keyword("AS");
13059 if matches!(
13060 self.config.dialect,
13061 Some(crate::dialects::DialectType::TSQL)
13062 ) {
13063 self.write(" BEGIN ");
13064 self.write(block);
13065 self.write(" END");
13066 } else if matches!(
13067 self.config.dialect,
13068 Some(crate::dialects::DialectType::PostgreSQL)
13069 ) {
13070 self.write(" $$");
13071 self.write(block);
13072 self.write("$$");
13073 } else {
13074 let escaped = self.escape_block_for_single_quote(block);
13076 self.write(" '");
13077 self.write(&escaped);
13078 self.write("'");
13079 }
13080 }
13081 FunctionBody::StringLiteral(s) => {
13082 self.write_keyword("AS");
13083 self.write(" '");
13084 self.write(s);
13085 self.write("'");
13086 }
13087 FunctionBody::Expression(expr) => {
13088 self.write_keyword("AS");
13089 self.write_space();
13090 self.generate_expression(expr)?;
13091 }
13092 FunctionBody::External(name) => {
13093 self.write_keyword("EXTERNAL NAME");
13094 self.write(" '");
13095 self.write(name);
13096 self.write("'");
13097 }
13098 FunctionBody::Return(expr) => {
13099 self.write_keyword("RETURN");
13100 self.write_space();
13101 self.generate_expression(expr)?;
13102 }
13103 FunctionBody::Statements(stmts) => {
13104 self.write_keyword("AS");
13105 self.write(" BEGIN ");
13106 for (i, stmt) in stmts.iter().enumerate() {
13107 if i > 0 {
13108 self.write(" ");
13109 }
13110 self.generate_expression(stmt)?;
13111 self.write(";");
13112 }
13113 self.write(" END");
13114 }
13115 FunctionBody::RawBlock(text) => {
13116 self.write_newline();
13117 self.write(text);
13118 }
13119 FunctionBody::DollarQuoted { content, tag } => {
13120 self.write_keyword("AS");
13121 self.write(" ");
13122 let supports_dollar_quoting = matches!(
13124 self.config.dialect,
13125 Some(crate::dialects::DialectType::PostgreSQL)
13126 | Some(crate::dialects::DialectType::Databricks)
13127 | Some(crate::dialects::DialectType::Redshift)
13128 | Some(crate::dialects::DialectType::DuckDB)
13129 );
13130 if supports_dollar_quoting {
13131 self.write("$");
13133 if let Some(t) = tag {
13134 self.write(t);
13135 }
13136 self.write("$");
13137 self.write(content);
13138 self.write("$");
13139 if let Some(t) = tag {
13140 self.write(t);
13141 }
13142 self.write("$");
13143 } else {
13144 let escaped = self.escape_block_for_single_quote(content);
13146 self.write("'");
13147 self.write(&escaped);
13148 self.write("'");
13149 }
13150 }
13151 }
13152 }
13153
13154 Ok(())
13155 }
13156
13157 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
13158 self.write_keyword("DROP PROCEDURE");
13159
13160 if dp.if_exists {
13161 self.write_space();
13162 self.write_keyword("IF EXISTS");
13163 }
13164
13165 self.write_space();
13166 self.generate_table(&dp.name)?;
13167
13168 if let Some(params) = &dp.parameters {
13169 self.write(" (");
13170 for (i, dt) in params.iter().enumerate() {
13171 if i > 0 {
13172 self.write(", ");
13173 }
13174 self.generate_data_type(dt)?;
13175 }
13176 self.write(")");
13177 }
13178
13179 if dp.cascade {
13180 self.write_space();
13181 self.write_keyword("CASCADE");
13182 }
13183
13184 Ok(())
13185 }
13186
13187 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
13188 self.write_keyword("CREATE");
13189
13190 if cs.or_replace {
13191 self.write_space();
13192 self.write_keyword("OR REPLACE");
13193 }
13194
13195 if cs.temporary {
13196 self.write_space();
13197 self.write_keyword("TEMPORARY");
13198 }
13199
13200 self.write_space();
13201 self.write_keyword("SEQUENCE");
13202
13203 if cs.if_not_exists {
13204 self.write_space();
13205 self.write_keyword("IF NOT EXISTS");
13206 }
13207
13208 self.write_space();
13209 self.generate_table(&cs.name)?;
13210
13211 if let Some(as_type) = &cs.as_type {
13213 self.write_space();
13214 self.write_keyword("AS");
13215 self.write_space();
13216 self.generate_data_type(as_type)?;
13217 }
13218
13219 if let Some(comment) = &cs.comment {
13221 self.write_space();
13222 self.write_keyword("COMMENT");
13223 self.write("=");
13224 self.generate_string_literal(comment)?;
13225 }
13226
13227 if !cs.property_order.is_empty() {
13229 for prop in &cs.property_order {
13230 match prop {
13231 SeqPropKind::Start => {
13232 if let Some(start) = cs.start {
13233 self.write_space();
13234 self.write_keyword("START WITH");
13235 self.write(&format!(" {}", start));
13236 }
13237 }
13238 SeqPropKind::Increment => {
13239 if let Some(inc) = cs.increment {
13240 self.write_space();
13241 self.write_keyword("INCREMENT BY");
13242 self.write(&format!(" {}", inc));
13243 }
13244 }
13245 SeqPropKind::Minvalue => {
13246 if let Some(min) = &cs.minvalue {
13247 self.write_space();
13248 match min {
13249 SequenceBound::Value(v) => {
13250 self.write_keyword("MINVALUE");
13251 self.write(&format!(" {}", v));
13252 }
13253 SequenceBound::None => {
13254 self.write_keyword("NO MINVALUE");
13255 }
13256 }
13257 }
13258 }
13259 SeqPropKind::Maxvalue => {
13260 if let Some(max) = &cs.maxvalue {
13261 self.write_space();
13262 match max {
13263 SequenceBound::Value(v) => {
13264 self.write_keyword("MAXVALUE");
13265 self.write(&format!(" {}", v));
13266 }
13267 SequenceBound::None => {
13268 self.write_keyword("NO MAXVALUE");
13269 }
13270 }
13271 }
13272 }
13273 SeqPropKind::Cache => {
13274 if let Some(cache) = cs.cache {
13275 self.write_space();
13276 self.write_keyword("CACHE");
13277 self.write(&format!(" {}", cache));
13278 }
13279 }
13280 SeqPropKind::NoCache => {
13281 self.write_space();
13282 self.write_keyword("NO CACHE");
13283 }
13284 SeqPropKind::NoCacheWord => {
13285 self.write_space();
13286 self.write_keyword("NOCACHE");
13287 }
13288 SeqPropKind::Cycle => {
13289 self.write_space();
13290 self.write_keyword("CYCLE");
13291 }
13292 SeqPropKind::NoCycle => {
13293 self.write_space();
13294 self.write_keyword("NO CYCLE");
13295 }
13296 SeqPropKind::NoCycleWord => {
13297 self.write_space();
13298 self.write_keyword("NOCYCLE");
13299 }
13300 SeqPropKind::OwnedBy => {
13301 if !cs.owned_by_none {
13303 if let Some(owned) = &cs.owned_by {
13304 self.write_space();
13305 self.write_keyword("OWNED BY");
13306 self.write_space();
13307 self.generate_table(owned)?;
13308 }
13309 }
13310 }
13311 SeqPropKind::Order => {
13312 self.write_space();
13313 self.write_keyword("ORDER");
13314 }
13315 SeqPropKind::NoOrder => {
13316 self.write_space();
13317 self.write_keyword("NOORDER");
13318 }
13319 SeqPropKind::Comment => {
13320 }
13322 SeqPropKind::Sharing => {
13323 if let Some(val) = &cs.sharing {
13324 self.write_space();
13325 self.write(&format!("SHARING={}", val));
13326 }
13327 }
13328 SeqPropKind::Keep => {
13329 self.write_space();
13330 self.write_keyword("KEEP");
13331 }
13332 SeqPropKind::NoKeep => {
13333 self.write_space();
13334 self.write_keyword("NOKEEP");
13335 }
13336 SeqPropKind::Scale => {
13337 self.write_space();
13338 self.write_keyword("SCALE");
13339 if let Some(modifier) = &cs.scale_modifier {
13340 if !modifier.is_empty() {
13341 self.write_space();
13342 self.write_keyword(modifier);
13343 }
13344 }
13345 }
13346 SeqPropKind::NoScale => {
13347 self.write_space();
13348 self.write_keyword("NOSCALE");
13349 }
13350 SeqPropKind::Shard => {
13351 self.write_space();
13352 self.write_keyword("SHARD");
13353 if let Some(modifier) = &cs.shard_modifier {
13354 if !modifier.is_empty() {
13355 self.write_space();
13356 self.write_keyword(modifier);
13357 }
13358 }
13359 }
13360 SeqPropKind::NoShard => {
13361 self.write_space();
13362 self.write_keyword("NOSHARD");
13363 }
13364 SeqPropKind::Session => {
13365 self.write_space();
13366 self.write_keyword("SESSION");
13367 }
13368 SeqPropKind::Global => {
13369 self.write_space();
13370 self.write_keyword("GLOBAL");
13371 }
13372 SeqPropKind::NoMinvalueWord => {
13373 self.write_space();
13374 self.write_keyword("NOMINVALUE");
13375 }
13376 SeqPropKind::NoMaxvalueWord => {
13377 self.write_space();
13378 self.write_keyword("NOMAXVALUE");
13379 }
13380 }
13381 }
13382 } else {
13383 if let Some(inc) = cs.increment {
13385 self.write_space();
13386 self.write_keyword("INCREMENT BY");
13387 self.write(&format!(" {}", inc));
13388 }
13389
13390 if let Some(min) = &cs.minvalue {
13391 self.write_space();
13392 match min {
13393 SequenceBound::Value(v) => {
13394 self.write_keyword("MINVALUE");
13395 self.write(&format!(" {}", v));
13396 }
13397 SequenceBound::None => {
13398 self.write_keyword("NO MINVALUE");
13399 }
13400 }
13401 }
13402
13403 if let Some(max) = &cs.maxvalue {
13404 self.write_space();
13405 match max {
13406 SequenceBound::Value(v) => {
13407 self.write_keyword("MAXVALUE");
13408 self.write(&format!(" {}", v));
13409 }
13410 SequenceBound::None => {
13411 self.write_keyword("NO MAXVALUE");
13412 }
13413 }
13414 }
13415
13416 if let Some(start) = cs.start {
13417 self.write_space();
13418 self.write_keyword("START WITH");
13419 self.write(&format!(" {}", start));
13420 }
13421
13422 if let Some(cache) = cs.cache {
13423 self.write_space();
13424 self.write_keyword("CACHE");
13425 self.write(&format!(" {}", cache));
13426 }
13427
13428 if cs.cycle {
13429 self.write_space();
13430 self.write_keyword("CYCLE");
13431 }
13432
13433 if let Some(owned) = &cs.owned_by {
13434 self.write_space();
13435 self.write_keyword("OWNED BY");
13436 self.write_space();
13437 self.generate_table(owned)?;
13438 }
13439 }
13440
13441 Ok(())
13442 }
13443
13444 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
13445 self.write_keyword("DROP SEQUENCE");
13446
13447 if ds.if_exists {
13448 self.write_space();
13449 self.write_keyword("IF EXISTS");
13450 }
13451
13452 self.write_space();
13453 self.generate_table(&ds.name)?;
13454
13455 if ds.cascade {
13456 self.write_space();
13457 self.write_keyword("CASCADE");
13458 }
13459
13460 Ok(())
13461 }
13462
13463 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
13464 self.write_keyword("ALTER SEQUENCE");
13465
13466 if als.if_exists {
13467 self.write_space();
13468 self.write_keyword("IF EXISTS");
13469 }
13470
13471 self.write_space();
13472 self.generate_table(&als.name)?;
13473
13474 if let Some(inc) = als.increment {
13475 self.write_space();
13476 self.write_keyword("INCREMENT BY");
13477 self.write(&format!(" {}", inc));
13478 }
13479
13480 if let Some(min) = &als.minvalue {
13481 self.write_space();
13482 match min {
13483 SequenceBound::Value(v) => {
13484 self.write_keyword("MINVALUE");
13485 self.write(&format!(" {}", v));
13486 }
13487 SequenceBound::None => {
13488 self.write_keyword("NO MINVALUE");
13489 }
13490 }
13491 }
13492
13493 if let Some(max) = &als.maxvalue {
13494 self.write_space();
13495 match max {
13496 SequenceBound::Value(v) => {
13497 self.write_keyword("MAXVALUE");
13498 self.write(&format!(" {}", v));
13499 }
13500 SequenceBound::None => {
13501 self.write_keyword("NO MAXVALUE");
13502 }
13503 }
13504 }
13505
13506 if let Some(start) = als.start {
13507 self.write_space();
13508 self.write_keyword("START WITH");
13509 self.write(&format!(" {}", start));
13510 }
13511
13512 if let Some(restart) = &als.restart {
13513 self.write_space();
13514 self.write_keyword("RESTART");
13515 if let Some(val) = restart {
13516 self.write_keyword(" WITH");
13517 self.write(&format!(" {}", val));
13518 }
13519 }
13520
13521 if let Some(cache) = als.cache {
13522 self.write_space();
13523 self.write_keyword("CACHE");
13524 self.write(&format!(" {}", cache));
13525 }
13526
13527 if let Some(cycle) = als.cycle {
13528 self.write_space();
13529 if cycle {
13530 self.write_keyword("CYCLE");
13531 } else {
13532 self.write_keyword("NO CYCLE");
13533 }
13534 }
13535
13536 if let Some(owned) = &als.owned_by {
13537 self.write_space();
13538 self.write_keyword("OWNED BY");
13539 self.write_space();
13540 if let Some(table) = owned {
13541 self.generate_table(table)?;
13542 } else {
13543 self.write_keyword("NONE");
13544 }
13545 }
13546
13547 Ok(())
13548 }
13549
13550 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
13551 self.write_keyword("CREATE");
13552
13553 if ct.or_alter {
13554 self.write_space();
13555 self.write_keyword("OR ALTER");
13556 } else if ct.or_replace {
13557 self.write_space();
13558 self.write_keyword("OR REPLACE");
13559 }
13560
13561 if ct.constraint {
13562 self.write_space();
13563 self.write_keyword("CONSTRAINT");
13564 }
13565
13566 self.write_space();
13567 self.write_keyword("TRIGGER");
13568 self.write_space();
13569 self.generate_identifier(&ct.name)?;
13570
13571 self.write_space();
13572 match ct.timing {
13573 TriggerTiming::Before => self.write_keyword("BEFORE"),
13574 TriggerTiming::After => self.write_keyword("AFTER"),
13575 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
13576 }
13577
13578 for (i, event) in ct.events.iter().enumerate() {
13580 if i > 0 {
13581 self.write_keyword(" OR");
13582 }
13583 self.write_space();
13584 match event {
13585 TriggerEvent::Insert => self.write_keyword("INSERT"),
13586 TriggerEvent::Update(cols) => {
13587 self.write_keyword("UPDATE");
13588 if let Some(cols) = cols {
13589 self.write_space();
13590 self.write_keyword("OF");
13591 for (j, col) in cols.iter().enumerate() {
13592 if j > 0 {
13593 self.write(",");
13594 }
13595 self.write_space();
13596 self.generate_identifier(col)?;
13597 }
13598 }
13599 }
13600 TriggerEvent::Delete => self.write_keyword("DELETE"),
13601 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
13602 }
13603 }
13604
13605 self.write_space();
13606 self.write_keyword("ON");
13607 self.write_space();
13608 self.generate_table(&ct.table)?;
13609
13610 if let Some(ref_clause) = &ct.referencing {
13612 self.write_space();
13613 self.write_keyword("REFERENCING");
13614 if let Some(old_table) = &ref_clause.old_table {
13615 self.write_space();
13616 self.write_keyword("OLD TABLE AS");
13617 self.write_space();
13618 self.generate_identifier(old_table)?;
13619 }
13620 if let Some(new_table) = &ref_clause.new_table {
13621 self.write_space();
13622 self.write_keyword("NEW TABLE AS");
13623 self.write_space();
13624 self.generate_identifier(new_table)?;
13625 }
13626 if let Some(old_row) = &ref_clause.old_row {
13627 self.write_space();
13628 self.write_keyword("OLD ROW AS");
13629 self.write_space();
13630 self.generate_identifier(old_row)?;
13631 }
13632 if let Some(new_row) = &ref_clause.new_row {
13633 self.write_space();
13634 self.write_keyword("NEW ROW AS");
13635 self.write_space();
13636 self.generate_identifier(new_row)?;
13637 }
13638 }
13639
13640 if let Some(deferrable) = ct.deferrable {
13642 self.write_space();
13643 if deferrable {
13644 self.write_keyword("DEFERRABLE");
13645 } else {
13646 self.write_keyword("NOT DEFERRABLE");
13647 }
13648 }
13649
13650 if let Some(initially) = ct.initially_deferred {
13651 self.write_space();
13652 self.write_keyword("INITIALLY");
13653 self.write_space();
13654 if initially {
13655 self.write_keyword("DEFERRED");
13656 } else {
13657 self.write_keyword("IMMEDIATE");
13658 }
13659 }
13660
13661 if let Some(for_each) = ct.for_each {
13662 self.write_space();
13663 self.write_keyword("FOR EACH");
13664 self.write_space();
13665 match for_each {
13666 TriggerForEach::Row => self.write_keyword("ROW"),
13667 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
13668 }
13669 }
13670
13671 if let Some(when) = &ct.when {
13673 self.write_space();
13674 self.write_keyword("WHEN");
13675 if ct.when_paren {
13676 self.write(" (");
13677 self.generate_expression(when)?;
13678 self.write(")");
13679 } else {
13680 self.write_space();
13681 self.generate_expression(when)?;
13682 }
13683 }
13684
13685 self.write_space();
13687 match &ct.body {
13688 TriggerBody::Execute { function, args } => {
13689 self.write_keyword("EXECUTE FUNCTION");
13690 self.write_space();
13691 self.generate_table(function)?;
13692 self.write("(");
13693 for (i, arg) in args.iter().enumerate() {
13694 if i > 0 {
13695 self.write(", ");
13696 }
13697 self.generate_expression(arg)?;
13698 }
13699 self.write(")");
13700 }
13701 TriggerBody::Block(block) => {
13702 self.write_keyword("BEGIN");
13703 self.write_space();
13704 self.write(block);
13705 self.write_space();
13706 self.write_keyword("END");
13707 }
13708 }
13709
13710 Ok(())
13711 }
13712
13713 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
13714 self.write_keyword("DROP TRIGGER");
13715
13716 if dt.if_exists {
13717 self.write_space();
13718 self.write_keyword("IF EXISTS");
13719 }
13720
13721 self.write_space();
13722 self.generate_identifier(&dt.name)?;
13723
13724 if let Some(table) = &dt.table {
13725 self.write_space();
13726 self.write_keyword("ON");
13727 self.write_space();
13728 self.generate_table(table)?;
13729 }
13730
13731 if dt.cascade {
13732 self.write_space();
13733 self.write_keyword("CASCADE");
13734 }
13735
13736 Ok(())
13737 }
13738
13739 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
13740 self.write_keyword("CREATE TYPE");
13741
13742 if ct.if_not_exists {
13743 self.write_space();
13744 self.write_keyword("IF NOT EXISTS");
13745 }
13746
13747 self.write_space();
13748 self.generate_table(&ct.name)?;
13749
13750 self.write_space();
13751 self.write_keyword("AS");
13752 self.write_space();
13753
13754 match &ct.definition {
13755 TypeDefinition::Enum(values) => {
13756 self.write_keyword("ENUM");
13757 self.write(" (");
13758 for (i, val) in values.iter().enumerate() {
13759 if i > 0 {
13760 self.write(", ");
13761 }
13762 self.write(&format!("'{}'", val));
13763 }
13764 self.write(")");
13765 }
13766 TypeDefinition::Composite(attrs) => {
13767 self.write("(");
13768 for (i, attr) in attrs.iter().enumerate() {
13769 if i > 0 {
13770 self.write(", ");
13771 }
13772 self.generate_identifier(&attr.name)?;
13773 self.write_space();
13774 self.generate_data_type(&attr.data_type)?;
13775 if let Some(collate) = &attr.collate {
13776 self.write_space();
13777 self.write_keyword("COLLATE");
13778 self.write_space();
13779 self.generate_identifier(collate)?;
13780 }
13781 }
13782 self.write(")");
13783 }
13784 TypeDefinition::Range {
13785 subtype,
13786 subtype_diff,
13787 canonical,
13788 } => {
13789 self.write_keyword("RANGE");
13790 self.write(" (");
13791 self.write_keyword("SUBTYPE");
13792 self.write(" = ");
13793 self.generate_data_type(subtype)?;
13794 if let Some(diff) = subtype_diff {
13795 self.write(", ");
13796 self.write_keyword("SUBTYPE_DIFF");
13797 self.write(" = ");
13798 self.write(diff);
13799 }
13800 if let Some(canon) = canonical {
13801 self.write(", ");
13802 self.write_keyword("CANONICAL");
13803 self.write(" = ");
13804 self.write(canon);
13805 }
13806 self.write(")");
13807 }
13808 TypeDefinition::Base {
13809 input,
13810 output,
13811 internallength,
13812 } => {
13813 self.write("(");
13814 self.write_keyword("INPUT");
13815 self.write(" = ");
13816 self.write(input);
13817 self.write(", ");
13818 self.write_keyword("OUTPUT");
13819 self.write(" = ");
13820 self.write(output);
13821 if let Some(len) = internallength {
13822 self.write(", ");
13823 self.write_keyword("INTERNALLENGTH");
13824 self.write(" = ");
13825 self.write(&len.to_string());
13826 }
13827 self.write(")");
13828 }
13829 TypeDefinition::Domain {
13830 base_type,
13831 default,
13832 constraints,
13833 } => {
13834 self.generate_data_type(base_type)?;
13835 if let Some(def) = default {
13836 self.write_space();
13837 self.write_keyword("DEFAULT");
13838 self.write_space();
13839 self.generate_expression(def)?;
13840 }
13841 for constr in constraints {
13842 self.write_space();
13843 if let Some(name) = &constr.name {
13844 self.write_keyword("CONSTRAINT");
13845 self.write_space();
13846 self.generate_identifier(name)?;
13847 self.write_space();
13848 }
13849 self.write_keyword("CHECK");
13850 self.write(" (");
13851 self.generate_expression(&constr.check)?;
13852 self.write(")");
13853 }
13854 }
13855 }
13856
13857 Ok(())
13858 }
13859
13860 fn generate_create_task(&mut self, task: &crate::expressions::CreateTask) -> Result<()> {
13861 self.write_keyword("CREATE");
13862 if task.or_replace {
13863 self.write_space();
13864 self.write_keyword("OR REPLACE");
13865 }
13866 self.write_space();
13867 self.write_keyword("TASK");
13868 if task.if_not_exists {
13869 self.write_space();
13870 self.write_keyword("IF NOT EXISTS");
13871 }
13872 self.write_space();
13873 self.write(&task.name);
13874 if !task.properties.is_empty() {
13875 if !task.properties.starts_with('\n') && !task.properties.starts_with(' ') {
13877 self.write_space();
13878 }
13879 self.write(&task.properties);
13880 }
13881 self.write_space();
13882 self.write_keyword("AS");
13883 self.write_space();
13884 self.generate_expression(&task.body)?;
13885 Ok(())
13886 }
13887
13888 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
13889 self.write_keyword("DROP TYPE");
13890
13891 if dt.if_exists {
13892 self.write_space();
13893 self.write_keyword("IF EXISTS");
13894 }
13895
13896 self.write_space();
13897 self.generate_table(&dt.name)?;
13898
13899 if dt.cascade {
13900 self.write_space();
13901 self.write_keyword("CASCADE");
13902 }
13903
13904 Ok(())
13905 }
13906
13907 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
13908 let saved_athena_hive_context = self.athena_hive_context;
13910 if matches!(
13911 self.config.dialect,
13912 Some(crate::dialects::DialectType::Athena)
13913 ) {
13914 self.athena_hive_context = true;
13915 }
13916
13917 for comment in &d.leading_comments {
13919 self.write_formatted_comment(comment);
13920 self.write(" ");
13921 }
13922
13923 self.write_keyword("DESCRIBE");
13924
13925 if d.extended {
13926 self.write_space();
13927 self.write_keyword("EXTENDED");
13928 } else if d.formatted {
13929 self.write_space();
13930 self.write_keyword("FORMATTED");
13931 }
13932
13933 if let Some(ref style) = d.style {
13935 self.write_space();
13936 self.write_keyword(style);
13937 }
13938
13939 let should_output_kind = match self.config.dialect {
13941 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
13943 false
13944 }
13945 Some(DialectType::Snowflake) => true,
13947 _ => d.kind.is_some(),
13948 };
13949 if should_output_kind {
13950 if let Some(ref kind) = d.kind {
13951 self.write_space();
13952 self.write_keyword(kind);
13953 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
13954 self.write_space();
13955 self.write_keyword("TABLE");
13956 }
13957 }
13958
13959 self.write_space();
13960 self.generate_expression(&d.target)?;
13961
13962 if !d.params.is_empty() {
13964 self.write("(");
13965 for (i, param) in d.params.iter().enumerate() {
13966 if i > 0 {
13967 self.write(", ");
13968 }
13969 self.write(param);
13970 }
13971 self.write(")");
13972 }
13973
13974 if let Some(ref partition) = d.partition {
13976 self.write_space();
13977 self.generate_expression(partition)?;
13978 }
13979
13980 if d.as_json {
13982 self.write_space();
13983 self.write_keyword("AS JSON");
13984 }
13985
13986 for (name, value) in &d.properties {
13988 self.write_space();
13989 self.write(name);
13990 self.write("=");
13991 self.write(value);
13992 }
13993
13994 self.athena_hive_context = saved_athena_hive_context;
13996
13997 Ok(())
13998 }
13999
14000 fn generate_show(&mut self, s: &Show) -> Result<()> {
14003 self.write_keyword("SHOW");
14004 self.write_space();
14005
14006 let show_terse = s.terse
14009 && !matches!(
14010 s.this.as_str(),
14011 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
14012 );
14013 if show_terse {
14014 self.write_keyword("TERSE");
14015 self.write_space();
14016 }
14017
14018 self.write_keyword(&s.this);
14020
14021 if let Some(ref target_expr) = s.target {
14023 self.write_space();
14024 self.generate_expression(target_expr)?;
14025 }
14026
14027 if s.history {
14029 self.write_space();
14030 self.write_keyword("HISTORY");
14031 }
14032
14033 if let Some(ref for_target) = s.for_target {
14035 self.write_space();
14036 self.write_keyword("FOR");
14037 self.write_space();
14038 self.generate_expression(for_target)?;
14039 }
14040
14041 use crate::dialects::DialectType;
14045 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
14046
14047 if !is_snowflake && s.from.is_some() {
14048 if let Some(ref scope_kind) = s.scope_kind {
14052 self.write_space();
14053 self.write_keyword("IN");
14054 self.write_space();
14055 self.write_keyword(scope_kind);
14056 if let Some(ref scope) = s.scope {
14057 self.write_space();
14058 self.generate_expression(scope)?;
14059 }
14060 } else if let Some(ref scope) = s.scope {
14061 self.write_space();
14062 self.write_keyword("IN");
14063 self.write_space();
14064 self.generate_expression(scope)?;
14065 }
14066
14067 if let Some(ref from) = s.from {
14069 self.write_space();
14070 self.write_keyword("FROM");
14071 self.write_space();
14072 self.generate_expression(from)?;
14073 }
14074
14075 if let Some(ref db) = s.db {
14077 self.write_space();
14078 self.write_keyword("FROM");
14079 self.write_space();
14080 self.generate_expression(db)?;
14081 }
14082
14083 if let Some(ref like) = s.like {
14085 self.write_space();
14086 self.write_keyword("LIKE");
14087 self.write_space();
14088 self.generate_expression(like)?;
14089 }
14090 } else {
14091 if let Some(ref like) = s.like {
14095 self.write_space();
14096 self.write_keyword("LIKE");
14097 self.write_space();
14098 self.generate_expression(like)?;
14099 }
14100
14101 if let Some(ref scope_kind) = s.scope_kind {
14103 self.write_space();
14104 self.write_keyword("IN");
14105 self.write_space();
14106 self.write_keyword(scope_kind);
14107 if let Some(ref scope) = s.scope {
14108 self.write_space();
14109 self.generate_expression(scope)?;
14110 }
14111 } else if let Some(ref scope) = s.scope {
14112 self.write_space();
14113 self.write_keyword("IN");
14114 self.write_space();
14115 self.generate_expression(scope)?;
14116 }
14117 }
14118
14119 if let Some(ref starts_with) = s.starts_with {
14121 self.write_space();
14122 self.write_keyword("STARTS WITH");
14123 self.write_space();
14124 self.generate_expression(starts_with)?;
14125 }
14126
14127 if let Some(ref limit) = s.limit {
14129 self.write_space();
14130 self.generate_limit(limit)?;
14131 }
14132
14133 if is_snowflake {
14135 if let Some(ref from) = s.from {
14136 self.write_space();
14137 self.write_keyword("FROM");
14138 self.write_space();
14139 self.generate_expression(from)?;
14140 }
14141 }
14142
14143 if let Some(ref where_clause) = s.where_clause {
14145 self.write_space();
14146 self.write_keyword("WHERE");
14147 self.write_space();
14148 self.generate_expression(where_clause)?;
14149 }
14150
14151 if let Some(is_mutex) = s.mutex {
14153 self.write_space();
14154 if is_mutex {
14155 self.write_keyword("MUTEX");
14156 } else {
14157 self.write_keyword("STATUS");
14158 }
14159 }
14160
14161 if !s.privileges.is_empty() {
14163 self.write_space();
14164 self.write_keyword("WITH PRIVILEGES");
14165 self.write_space();
14166 for (i, priv_name) in s.privileges.iter().enumerate() {
14167 if i > 0 {
14168 self.write(", ");
14169 }
14170 self.write_keyword(priv_name);
14171 }
14172 }
14173
14174 Ok(())
14175 }
14176
14177 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
14180 use crate::dialects::DialectType;
14181 match lit {
14182 Literal::String(s) => {
14183 self.generate_string_literal(s)?;
14184 }
14185 Literal::Number(n) => {
14186 if matches!(self.config.dialect, Some(DialectType::MySQL))
14187 && n.len() > 2
14188 && (n.starts_with("0x") || n.starts_with("0X"))
14189 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
14190 {
14191 return self.generate_identifier(&Identifier {
14192 name: n.clone(),
14193 quoted: true,
14194 trailing_comments: Vec::new(),
14195 span: None,
14196 });
14197 }
14198 let n = if n.contains('_')
14202 && !matches!(
14203 self.config.dialect,
14204 Some(DialectType::ClickHouse)
14205 | Some(DialectType::DuckDB)
14206 | Some(DialectType::PostgreSQL)
14207 | Some(DialectType::Hive)
14208 | Some(DialectType::Spark)
14209 | Some(DialectType::Databricks)
14210 ) {
14211 std::borrow::Cow::Owned(n.replace('_', ""))
14212 } else {
14213 std::borrow::Cow::Borrowed(n.as_str())
14214 };
14215 if n.starts_with('.') {
14218 self.write("0");
14219 self.write(&n);
14220 } else if n.starts_with("-.") {
14221 self.write("-0");
14223 self.write(&n[1..]);
14224 } else {
14225 self.write(&n);
14226 }
14227 }
14228 Literal::HexString(h) => {
14229 match self.config.dialect {
14231 Some(DialectType::Spark)
14232 | Some(DialectType::Databricks)
14233 | Some(DialectType::Teradata) => self.write("X'"),
14234 _ => self.write("x'"),
14235 }
14236 self.write(h);
14237 self.write("'");
14238 }
14239 Literal::HexNumber(h) => {
14240 match self.config.dialect {
14244 Some(DialectType::BigQuery)
14245 | Some(DialectType::TSQL)
14246 | Some(DialectType::Fabric) => {
14247 self.write("0x");
14248 self.write(h);
14249 }
14250 _ => {
14251 if let Ok(val) = u64::from_str_radix(h, 16) {
14253 self.write(&val.to_string());
14254 } else {
14255 self.write("0x");
14257 self.write(h);
14258 }
14259 }
14260 }
14261 }
14262 Literal::BitString(b) => {
14263 self.write("B'");
14265 self.write(b);
14266 self.write("'");
14267 }
14268 Literal::ByteString(b) => {
14269 self.write("b'");
14271 self.write_escaped_byte_string(b);
14273 self.write("'");
14274 }
14275 Literal::NationalString(s) => {
14276 let keep_n_prefix = matches!(
14279 self.config.dialect,
14280 Some(DialectType::TSQL)
14281 | Some(DialectType::Oracle)
14282 | Some(DialectType::MySQL)
14283 | None
14284 );
14285 if keep_n_prefix {
14286 self.write("N'");
14287 } else {
14288 self.write("'");
14289 }
14290 self.write(s);
14291 self.write("'");
14292 }
14293 Literal::Date(d) => {
14294 self.generate_date_literal(d)?;
14295 }
14296 Literal::Time(t) => {
14297 self.generate_time_literal(t)?;
14298 }
14299 Literal::Timestamp(ts) => {
14300 self.generate_timestamp_literal(ts)?;
14301 }
14302 Literal::Datetime(dt) => {
14303 self.generate_datetime_literal(dt)?;
14304 }
14305 Literal::TripleQuotedString(s, _quote_char) => {
14306 if matches!(
14308 self.config.dialect,
14309 Some(crate::dialects::DialectType::BigQuery)
14310 | Some(crate::dialects::DialectType::DuckDB)
14311 | Some(crate::dialects::DialectType::Snowflake)
14312 | Some(crate::dialects::DialectType::Spark)
14313 | Some(crate::dialects::DialectType::Hive)
14314 | Some(crate::dialects::DialectType::Presto)
14315 | Some(crate::dialects::DialectType::Trino)
14316 | Some(crate::dialects::DialectType::PostgreSQL)
14317 | Some(crate::dialects::DialectType::MySQL)
14318 | Some(crate::dialects::DialectType::Redshift)
14319 | Some(crate::dialects::DialectType::TSQL)
14320 | Some(crate::dialects::DialectType::Oracle)
14321 | Some(crate::dialects::DialectType::ClickHouse)
14322 | Some(crate::dialects::DialectType::Databricks)
14323 | Some(crate::dialects::DialectType::SQLite)
14324 ) {
14325 self.generate_string_literal(s)?;
14326 } else {
14327 let quotes = format!("{0}{0}{0}", _quote_char);
14329 self.write("es);
14330 self.write(s);
14331 self.write("es);
14332 }
14333 }
14334 Literal::EscapeString(s) => {
14335 use crate::dialects::DialectType;
14339 let content = if let Some(c) = s.strip_prefix("e:") {
14340 c
14341 } else if let Some(c) = s.strip_prefix("E:") {
14342 c
14343 } else {
14344 s.as_str()
14345 };
14346
14347 if matches!(
14349 self.config.dialect,
14350 Some(DialectType::MySQL) | Some(DialectType::TiDB)
14351 ) {
14352 self.write(content);
14353 } else {
14354 let prefix = if matches!(
14356 self.config.dialect,
14357 Some(DialectType::SingleStore)
14358 | Some(DialectType::DuckDB)
14359 | Some(DialectType::PostgreSQL)
14360 | Some(DialectType::CockroachDB)
14361 | Some(DialectType::Materialize)
14362 | Some(DialectType::RisingWave)
14363 ) {
14364 "e'"
14365 } else {
14366 "E'"
14367 };
14368
14369 let normalized = content.replace("\\'", "''");
14371 self.write(prefix);
14372 self.write(&normalized);
14373 self.write("'");
14374 }
14375 }
14376 Literal::DollarString(s) => {
14377 use crate::dialects::DialectType;
14380 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
14382 let escape_backslash = matches!(self.config.dialect, Some(DialectType::Snowflake));
14384 let use_backslash_quote =
14388 matches!(self.config.dialect, Some(DialectType::Snowflake));
14389
14390 let mut escaped = String::with_capacity(content.len() + 4);
14391 for ch in content.chars() {
14392 if escape_backslash && ch == '\\' {
14393 escaped.push('\\');
14395 escaped.push('\\');
14396 } else if ch == '\'' {
14397 if use_backslash_quote {
14398 escaped.push('\\');
14399 escaped.push('\'');
14400 } else {
14401 escaped.push('\'');
14402 escaped.push('\'');
14403 }
14404 } else {
14405 escaped.push(ch);
14406 }
14407 }
14408 self.write("'");
14409 self.write(&escaped);
14410 self.write("'");
14411 }
14412 Literal::RawString(s) => {
14413 use crate::dialects::DialectType;
14419
14420 let escape_backslash = matches!(
14422 self.config.dialect,
14423 Some(DialectType::BigQuery)
14424 | Some(DialectType::MySQL)
14425 | Some(DialectType::SingleStore)
14426 | Some(DialectType::TiDB)
14427 | Some(DialectType::Hive)
14428 | Some(DialectType::Spark)
14429 | Some(DialectType::Databricks)
14430 | Some(DialectType::Drill)
14431 | Some(DialectType::Snowflake)
14432 | Some(DialectType::Redshift)
14433 | Some(DialectType::ClickHouse)
14434 );
14435
14436 let backslash_escapes_quote = matches!(
14439 self.config.dialect,
14440 Some(DialectType::BigQuery)
14441 | Some(DialectType::Hive)
14442 | Some(DialectType::Spark)
14443 | Some(DialectType::Databricks)
14444 | Some(DialectType::Drill)
14445 | Some(DialectType::Snowflake)
14446 | Some(DialectType::Redshift)
14447 );
14448
14449 let supports_escape_sequences = escape_backslash;
14452
14453 let mut escaped = String::with_capacity(s.len() + 4);
14454 for ch in s.chars() {
14455 if escape_backslash && ch == '\\' {
14456 escaped.push('\\');
14458 escaped.push('\\');
14459 } else if ch == '\'' {
14460 if backslash_escapes_quote {
14461 escaped.push('\\');
14463 escaped.push('\'');
14464 } else {
14465 escaped.push('\'');
14467 escaped.push('\'');
14468 }
14469 } else if supports_escape_sequences {
14470 match ch {
14473 '\n' => {
14474 escaped.push('\\');
14475 escaped.push('n');
14476 }
14477 '\r' => {
14478 escaped.push('\\');
14479 escaped.push('r');
14480 }
14481 '\t' => {
14482 escaped.push('\\');
14483 escaped.push('t');
14484 }
14485 '\x07' => {
14486 escaped.push('\\');
14487 escaped.push('a');
14488 }
14489 '\x08' => {
14490 escaped.push('\\');
14491 escaped.push('b');
14492 }
14493 '\x0C' => {
14494 escaped.push('\\');
14495 escaped.push('f');
14496 }
14497 '\x0B' => {
14498 escaped.push('\\');
14499 escaped.push('v');
14500 }
14501 _ => escaped.push(ch),
14502 }
14503 } else {
14504 escaped.push(ch);
14505 }
14506 }
14507 self.write("'");
14508 self.write(&escaped);
14509 self.write("'");
14510 }
14511 }
14512 Ok(())
14513 }
14514
14515 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
14517 use crate::dialects::DialectType;
14518
14519 match self.config.dialect {
14520 Some(DialectType::TSQL) => {
14522 self.write("CAST('");
14523 self.write(d);
14524 self.write("' AS DATE)");
14525 }
14526 Some(DialectType::BigQuery) => {
14529 self.write("CAST('");
14530 self.write(d);
14531 self.write("' AS DATE)");
14532 }
14533 Some(DialectType::Exasol) => {
14536 self.write("CAST('");
14537 self.write(d);
14538 self.write("' AS DATE)");
14539 }
14540 Some(DialectType::Snowflake) => {
14543 self.write("CAST('");
14544 self.write(d);
14545 self.write("' AS DATE)");
14546 }
14547 Some(DialectType::PostgreSQL)
14549 | Some(DialectType::MySQL)
14550 | Some(DialectType::SingleStore)
14551 | Some(DialectType::TiDB)
14552 | Some(DialectType::Redshift) => {
14553 self.write("CAST('");
14554 self.write(d);
14555 self.write("' AS DATE)");
14556 }
14557 Some(DialectType::DuckDB)
14559 | Some(DialectType::Presto)
14560 | Some(DialectType::Trino)
14561 | Some(DialectType::Athena)
14562 | Some(DialectType::Spark)
14563 | Some(DialectType::Databricks)
14564 | Some(DialectType::Hive) => {
14565 self.write("CAST('");
14566 self.write(d);
14567 self.write("' AS DATE)");
14568 }
14569 Some(DialectType::Oracle) => {
14571 self.write("TO_DATE('");
14572 self.write(d);
14573 self.write("', 'YYYY-MM-DD')");
14574 }
14575 _ => {
14577 self.write_keyword("DATE");
14578 self.write(" '");
14579 self.write(d);
14580 self.write("'");
14581 }
14582 }
14583 Ok(())
14584 }
14585
14586 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
14588 use crate::dialects::DialectType;
14589
14590 match self.config.dialect {
14591 Some(DialectType::TSQL) => {
14593 self.write("CAST('");
14594 self.write(t);
14595 self.write("' AS TIME)");
14596 }
14597 _ => {
14599 self.write_keyword("TIME");
14600 self.write(" '");
14601 self.write(t);
14602 self.write("'");
14603 }
14604 }
14605 Ok(())
14606 }
14607
14608 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
14610 use crate::expressions::Literal;
14611
14612 match expr {
14613 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
14614 let Literal::Date(d) = lit.as_ref() else {
14615 unreachable!()
14616 };
14617 self.write("CAST('");
14619 self.write(d);
14620 self.write("' AS DATE)");
14621 }
14622 _ => {
14623 self.generate_expression(expr)?;
14625 }
14626 }
14627 Ok(())
14628 }
14629
14630 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
14632 use crate::dialects::DialectType;
14633
14634 match self.config.dialect {
14635 Some(DialectType::TSQL) => {
14637 self.write("CAST('");
14638 self.write(ts);
14639 self.write("' AS DATETIME2)");
14640 }
14641 Some(DialectType::BigQuery) => {
14644 self.write("CAST('");
14645 self.write(ts);
14646 self.write("' AS TIMESTAMP)");
14647 }
14648 Some(DialectType::Snowflake) => {
14651 self.write("CAST('");
14652 self.write(ts);
14653 self.write("' AS TIMESTAMP)");
14654 }
14655 Some(DialectType::Dremio) => {
14658 self.write("CAST('");
14659 self.write(ts);
14660 self.write("' AS TIMESTAMP)");
14661 }
14662 Some(DialectType::Exasol) => {
14665 self.write("CAST('");
14666 self.write(ts);
14667 self.write("' AS TIMESTAMP)");
14668 }
14669 Some(DialectType::Oracle) => {
14672 self.write("TO_TIMESTAMP('");
14673 self.write(ts);
14674 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
14675 }
14676 Some(DialectType::Presto) | Some(DialectType::Trino) => {
14678 if Self::timestamp_has_timezone(ts) {
14679 self.write("CAST('");
14680 self.write(ts);
14681 self.write("' AS TIMESTAMP WITH TIME ZONE)");
14682 } else {
14683 self.write("CAST('");
14684 self.write(ts);
14685 self.write("' AS TIMESTAMP)");
14686 }
14687 }
14688 Some(DialectType::ClickHouse) => {
14690 self.write("CAST('");
14691 self.write(ts);
14692 self.write("' AS Nullable(DateTime))");
14693 }
14694 Some(DialectType::Spark) => {
14696 self.write("CAST('");
14697 self.write(ts);
14698 self.write("' AS TIMESTAMP)");
14699 }
14700 Some(DialectType::Redshift) => {
14703 if ts == "epoch" {
14704 self.write_keyword("TIMESTAMP");
14705 self.write(" '");
14706 self.write(ts);
14707 self.write("'");
14708 } else {
14709 self.write("CAST('");
14710 self.write(ts);
14711 self.write("' AS TIMESTAMP)");
14712 }
14713 }
14714 Some(DialectType::PostgreSQL)
14716 | Some(DialectType::Hive)
14717 | Some(DialectType::SQLite)
14718 | Some(DialectType::DuckDB)
14719 | Some(DialectType::Athena)
14720 | Some(DialectType::Drill)
14721 | Some(DialectType::Teradata) => {
14722 self.write("CAST('");
14723 self.write(ts);
14724 self.write("' AS TIMESTAMP)");
14725 }
14726 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
14728 self.write("CAST('");
14729 self.write(ts);
14730 self.write("' AS DATETIME)");
14731 }
14732 Some(DialectType::Databricks) => {
14734 self.write("CAST('");
14735 self.write(ts);
14736 self.write("' AS TIMESTAMP_NTZ)");
14737 }
14738 _ => {
14740 self.write_keyword("TIMESTAMP");
14741 self.write(" '");
14742 self.write(ts);
14743 self.write("'");
14744 }
14745 }
14746 Ok(())
14747 }
14748
14749 fn timestamp_has_timezone(ts: &str) -> bool {
14752 let ts_lower = ts.to_ascii_lowercase();
14756
14757 let continent_prefixes = [
14759 "africa/",
14760 "america/",
14761 "antarctica/",
14762 "arctic/",
14763 "asia/",
14764 "atlantic/",
14765 "australia/",
14766 "europe/",
14767 "indian/",
14768 "pacific/",
14769 "etc/",
14770 "brazil/",
14771 "canada/",
14772 "chile/",
14773 "mexico/",
14774 "us/",
14775 ];
14776
14777 for prefix in &continent_prefixes {
14778 if ts_lower.contains(prefix) {
14779 return true;
14780 }
14781 }
14782
14783 let tz_abbrevs = [
14786 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
14787 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
14788 " sgt", " aest", " aedt", " acst", " acdt", " awst",
14789 ];
14790
14791 for abbrev in &tz_abbrevs {
14792 if ts_lower.ends_with(abbrev) {
14793 return true;
14794 }
14795 }
14796
14797 let trimmed = ts.trim();
14801 if let Some(last_space) = trimmed.rfind(' ') {
14802 let suffix = &trimmed[last_space + 1..];
14803 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
14804 let rest = &suffix[1..];
14806 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
14807 return true;
14808 }
14809 }
14810 }
14811
14812 false
14813 }
14814
14815 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
14817 use crate::dialects::DialectType;
14818
14819 match self.config.dialect {
14820 Some(DialectType::BigQuery) => {
14823 self.write("CAST('");
14824 self.write(dt);
14825 self.write("' AS DATETIME)");
14826 }
14827 Some(DialectType::DuckDB) => {
14829 self.write("CAST('");
14830 self.write(dt);
14831 self.write("' AS TIMESTAMP)");
14832 }
14833 _ => {
14836 self.write_keyword("DATETIME");
14837 self.write(" '");
14838 self.write(dt);
14839 self.write("'");
14840 }
14841 }
14842 Ok(())
14843 }
14844
14845 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
14847 use crate::dialects::DialectType;
14848
14849 match self.config.dialect {
14850 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
14854 self.write("'");
14856 for c in s.chars() {
14857 match c {
14858 '\'' => self.write("\\'"),
14859 '\\' => self.write("\\\\"),
14860 '\n' => self.write("\\n"),
14861 '\r' => self.write("\\r"),
14862 '\t' => self.write("\\t"),
14863 '\0' => self.write("\\0"),
14864 _ => self.output.push(c),
14865 }
14866 }
14867 self.write("'");
14868 }
14869 Some(DialectType::Drill) => {
14870 self.write("'");
14873 for c in s.chars() {
14874 match c {
14875 '\'' => self.write("''"),
14876 '\\' => self.write("\\\\"),
14877 '\n' => self.write("\\n"),
14878 '\r' => self.write("\\r"),
14879 '\t' => self.write("\\t"),
14880 '\0' => self.write("\\0"),
14881 _ => self.output.push(c),
14882 }
14883 }
14884 self.write("'");
14885 }
14886 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
14887 self.write("'");
14888 for c in s.chars() {
14889 match c {
14890 '\'' => self.write("''"),
14892 '\\' => self.write("\\\\"),
14893 '\n' => self.write("\\n"),
14894 '\r' => self.write("\\r"),
14895 '\t' => self.write("\\t"),
14896 '\0' => self.output.push('\0'),
14898 _ => self.output.push(c),
14899 }
14900 }
14901 self.write("'");
14902 }
14903 Some(DialectType::BigQuery) => {
14905 self.write("'");
14906 for c in s.chars() {
14907 match c {
14908 '\'' => self.write("\\'"),
14909 '\\' => self.write("\\\\"),
14910 '\n' => self.write("\\n"),
14911 '\r' => self.write("\\r"),
14912 '\t' => self.write("\\t"),
14913 '\0' => self.write("\\0"),
14914 '\x07' => self.write("\\a"),
14915 '\x08' => self.write("\\b"),
14916 '\x0C' => self.write("\\f"),
14917 '\x0B' => self.write("\\v"),
14918 _ => self.output.push(c),
14919 }
14920 }
14921 self.write("'");
14922 }
14923 Some(DialectType::Athena) => {
14927 if self.athena_hive_context {
14928 self.write("'");
14930 for c in s.chars() {
14931 match c {
14932 '\'' => self.write("\\'"),
14933 '\\' => self.write("\\\\"),
14934 '\n' => self.write("\\n"),
14935 '\r' => self.write("\\r"),
14936 '\t' => self.write("\\t"),
14937 '\0' => self.write("\\0"),
14938 _ => self.output.push(c),
14939 }
14940 }
14941 self.write("'");
14942 } else {
14943 self.write("'");
14945 for c in s.chars() {
14946 match c {
14947 '\'' => self.write("''"),
14948 _ => self.output.push(c),
14950 }
14951 }
14952 self.write("'");
14953 }
14954 }
14955 Some(DialectType::Snowflake) => {
14960 self.write("'");
14961 for c in s.chars() {
14962 match c {
14963 '\'' => self.write("\\'"),
14964 '\n' => self.write("\\n"),
14967 '\r' => self.write("\\r"),
14968 '\t' => self.write("\\t"),
14969 _ => self.output.push(c),
14970 }
14971 }
14972 self.write("'");
14973 }
14974 Some(DialectType::PostgreSQL) => {
14976 self.write("'");
14977 for c in s.chars() {
14978 match c {
14979 '\'' => self.write("''"),
14980 _ => self.output.push(c),
14981 }
14982 }
14983 self.write("'");
14984 }
14985 Some(DialectType::Redshift) => {
14987 self.write("'");
14988 for c in s.chars() {
14989 match c {
14990 '\'' => self.write("\\'"),
14991 _ => self.output.push(c),
14992 }
14993 }
14994 self.write("'");
14995 }
14996 Some(DialectType::Oracle) => {
14998 self.write("'");
14999 for ch in s.chars() {
15000 if ch == '\'' {
15001 self.output.push_str("''");
15002 } else {
15003 self.output.push(ch);
15004 }
15005 }
15006 self.write("'");
15007 }
15008 Some(DialectType::ClickHouse) => {
15011 self.write("'");
15012 for c in s.chars() {
15013 match c {
15014 '\'' => self.write("''"),
15015 '\\' => self.write("\\\\"),
15016 '\n' => self.write("\\n"),
15017 '\r' => self.write("\\r"),
15018 '\t' => self.write("\\t"),
15019 '\0' => self.write("\\0"),
15020 '\x07' => self.write("\\a"),
15021 '\x08' => self.write("\\b"),
15022 '\x0C' => self.write("\\f"),
15023 '\x0B' => self.write("\\v"),
15024 c if c.is_control() || (c as u32) < 0x20 => {
15026 let byte = c as u32;
15027 if byte < 256 {
15028 self.write(&format!("\\x{:02X}", byte));
15029 } else {
15030 self.output.push(c);
15031 }
15032 }
15033 _ => self.output.push(c),
15034 }
15035 }
15036 self.write("'");
15037 }
15038 _ => {
15041 self.write("'");
15042 for ch in s.chars() {
15043 if ch == '\'' {
15044 self.output.push_str("''");
15045 } else {
15046 self.output.push(ch);
15047 }
15048 }
15049 self.write("'");
15050 }
15051 }
15052 Ok(())
15053 }
15054
15055 fn write_escaped_byte_string(&mut self, s: &str) {
15058 for c in s.chars() {
15059 match c {
15060 '\'' => self.write("\\'"),
15062 '\\' => self.write("\\\\"),
15064 _ if !c.is_control() => self.output.push(c),
15066 _ => {
15068 let byte = c as u32;
15069 if byte < 256 {
15070 self.write(&format!("\\x{:02x}", byte));
15071 } else {
15072 for b in c.to_string().as_bytes() {
15074 self.write(&format!("\\x{:02x}", b));
15075 }
15076 }
15077 }
15078 }
15079 }
15080 }
15081
15082 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
15083 use crate::dialects::DialectType;
15084
15085 match self.config.dialect {
15087 Some(DialectType::TSQL) => {
15090 self.write(if b.value { "1" } else { "0" });
15091 }
15092 Some(DialectType::Oracle) => {
15094 self.write(if b.value { "1" } else { "0" });
15095 }
15096 Some(DialectType::MySQL) => {
15098 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15099 }
15100 _ => {
15102 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15103 }
15104 }
15105 Ok(())
15106 }
15107
15108 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
15111 let name = &id.name;
15112 let quote_style = &self.config.identifier_quote_style;
15113
15114 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
15118
15119 let output_name = if self.config.normalize_identifiers && !id.quoted {
15121 name.to_ascii_lowercase()
15122 } else {
15123 name.to_string()
15124 };
15125
15126 if needs_quoting {
15127 let escaped_name = if quote_style.start == quote_style.end {
15129 output_name.replace(
15130 quote_style.end,
15131 &format!("{}{}", quote_style.end, quote_style.end),
15132 )
15133 } else {
15134 output_name.replace(
15135 quote_style.end,
15136 &format!("{}{}", quote_style.end, quote_style.end),
15137 )
15138 };
15139 self.write(&format!(
15140 "{}{}{}",
15141 quote_style.start, escaped_name, quote_style.end
15142 ));
15143 } else {
15144 self.write(&output_name);
15145 }
15146
15147 for comment in &id.trailing_comments {
15149 self.write(" ");
15150 self.write_formatted_comment(comment);
15151 }
15152 Ok(())
15153 }
15154
15155 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
15156 use crate::dialects::DialectType;
15157
15158 let name = &id.name;
15159
15160 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
15162 && self.athena_hive_context
15163 {
15164 &IdentifierQuoteStyle::BACKTICK
15165 } else {
15166 &self.config.identifier_quote_style
15167 };
15168
15169 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
15176 let needs_digit_quoting = starts_with_digit
15177 && !self.config.identifiers_can_start_with_digit
15178 && self.config.dialect.is_some();
15179 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
15180 && name.len() > 2
15181 && (name.starts_with("0x") || name.starts_with("0X"))
15182 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
15183 let needs_quoting = id.quoted
15184 || self.is_reserved_keyword(name)
15185 || self.config.always_quote_identifiers
15186 || needs_digit_quoting
15187 || mysql_invalid_hex_identifier;
15188
15189 let (base_name, suffix) = if needs_quoting {
15192 if let Some(paren_pos) = name.find('(') {
15194 let base = &name[..paren_pos];
15195 let rest = &name[paren_pos..];
15196 if rest.starts_with('(')
15198 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
15199 {
15200 let close_paren = rest.find(')').unwrap_or(rest.len());
15202 let inside = &rest[1..close_paren];
15203 if inside.chars().all(|c| c.is_ascii_digit()) {
15204 (base.to_string(), rest.to_string())
15205 } else {
15206 (name.to_string(), String::new())
15207 }
15208 } else {
15209 (name.to_string(), String::new())
15210 }
15211 } else if name.ends_with(" ASC") {
15212 let base = &name[..name.len() - 4];
15213 (base.to_string(), " ASC".to_string())
15214 } else if name.ends_with(" DESC") {
15215 let base = &name[..name.len() - 5];
15216 (base.to_string(), " DESC".to_string())
15217 } else {
15218 (name.to_string(), String::new())
15219 }
15220 } else {
15221 (name.to_string(), String::new())
15222 };
15223
15224 let output_name = if self.config.normalize_identifiers && !id.quoted {
15228 base_name.to_ascii_lowercase()
15229 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
15230 && !id.quoted
15231 && self.is_reserved_keyword(name)
15232 {
15233 base_name.to_ascii_uppercase()
15236 } else {
15237 base_name
15238 };
15239
15240 if needs_quoting {
15241 let escaped_name = if quote_style.start == quote_style.end {
15243 output_name.replace(
15245 quote_style.end,
15246 &format!("{}{}", quote_style.end, quote_style.end),
15247 )
15248 } else {
15249 output_name.replace(
15251 quote_style.end,
15252 &format!("{}{}", quote_style.end, quote_style.end),
15253 )
15254 };
15255 self.write(&format!(
15256 "{}{}{}{}",
15257 quote_style.start, escaped_name, quote_style.end, suffix
15258 ));
15259 } else {
15260 self.write(&output_name);
15261 }
15262
15263 for comment in &id.trailing_comments {
15265 self.write(" ");
15266 self.write_formatted_comment(comment);
15267 }
15268 Ok(())
15269 }
15270
15271 fn generate_column(&mut self, col: &Column) -> Result<()> {
15272 use crate::dialects::DialectType;
15273
15274 if let Some(table) = &col.table {
15275 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
15279 && !table.quoted
15280 && table.name.eq_ignore_ascii_case("LOCAL");
15281
15282 if is_exasol_local_prefix {
15283 self.write("LOCAL");
15285 } else {
15286 self.generate_identifier(table)?;
15287 }
15288 self.write(".");
15289 }
15290 self.generate_identifier(&col.name)?;
15291 if col.join_mark && self.config.supports_column_join_marks {
15294 self.write(" (+)");
15295 }
15296 for comment in &col.trailing_comments {
15298 self.write_space();
15299 self.write_formatted_comment(comment);
15300 }
15301 Ok(())
15302 }
15303
15304 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
15307 use crate::dialects::DialectType;
15308 use crate::expressions::PseudocolumnType;
15309
15310 if pc.kind == PseudocolumnType::Sysdate
15312 && !matches!(
15313 self.config.dialect,
15314 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
15315 )
15316 {
15317 self.write_keyword("CURRENT_TIMESTAMP");
15318 if matches!(
15320 self.config.dialect,
15321 Some(DialectType::MySQL)
15322 | Some(DialectType::ClickHouse)
15323 | Some(DialectType::Spark)
15324 | Some(DialectType::Databricks)
15325 | Some(DialectType::Hive)
15326 ) {
15327 self.write("()");
15328 }
15329 } else {
15330 self.write(pc.kind.as_str());
15331 }
15332 Ok(())
15333 }
15334
15335 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
15337 use crate::dialects::DialectType;
15338
15339 let supports_connect_by = matches!(
15342 self.config.dialect,
15343 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
15344 );
15345
15346 if !supports_connect_by && self.config.dialect.is_some() {
15347 if self.config.pretty {
15349 self.write_newline();
15350 } else {
15351 self.write_space();
15352 }
15353 self.write_unsupported_comment(
15354 "CONNECT BY requires manual conversion to recursive CTE",
15355 )?;
15356 }
15357
15358 if let Some(start) = &connect.start {
15360 if self.config.pretty {
15361 self.write_newline();
15362 } else {
15363 self.write_space();
15364 }
15365 self.write_keyword("START WITH");
15366 self.write_space();
15367 self.generate_expression(start)?;
15368 }
15369
15370 if self.config.pretty {
15372 self.write_newline();
15373 } else {
15374 self.write_space();
15375 }
15376 self.write_keyword("CONNECT BY");
15377 if connect.nocycle {
15378 self.write_space();
15379 self.write_keyword("NOCYCLE");
15380 }
15381 self.write_space();
15382 self.generate_expression(&connect.connect)?;
15383
15384 Ok(())
15385 }
15386
15387 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
15389 self.generate_connect(connect)
15390 }
15391
15392 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
15394 self.write_keyword("PRIOR");
15395 self.write_space();
15396 self.generate_expression(&prior.this)?;
15397 Ok(())
15398 }
15399
15400 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
15403 self.write_keyword("CONNECT_BY_ROOT");
15404 self.write_space();
15405 self.generate_expression(&cbr.this)?;
15406 Ok(())
15407 }
15408
15409 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
15411 use crate::dialects::DialectType;
15412
15413 let supports_match_recognize = matches!(
15415 self.config.dialect,
15416 Some(DialectType::Oracle)
15417 | Some(DialectType::Snowflake)
15418 | Some(DialectType::Presto)
15419 | Some(DialectType::Trino)
15420 );
15421
15422 if let Some(source) = &mr.this {
15424 self.generate_expression(source)?;
15425 }
15426
15427 if !supports_match_recognize {
15428 self.write_unsupported_comment("MATCH_RECOGNIZE not supported in this dialect")?;
15429 return Ok(());
15430 }
15431
15432 if self.config.pretty {
15434 self.write_newline();
15435 } else {
15436 self.write_space();
15437 }
15438
15439 self.write_keyword("MATCH_RECOGNIZE");
15440 self.write(" (");
15441
15442 if self.config.pretty {
15443 self.indent_level += 1;
15444 }
15445
15446 let mut needs_separator = false;
15447
15448 if let Some(partition_by) = &mr.partition_by {
15450 if !partition_by.is_empty() {
15451 if self.config.pretty {
15452 self.write_newline();
15453 self.write_indent();
15454 }
15455 self.write_keyword("PARTITION BY");
15456 self.write_space();
15457 for (i, expr) in partition_by.iter().enumerate() {
15458 if i > 0 {
15459 self.write(", ");
15460 }
15461 self.generate_expression(expr)?;
15462 }
15463 needs_separator = true;
15464 }
15465 }
15466
15467 if let Some(order_by) = &mr.order_by {
15469 if !order_by.is_empty() {
15470 if needs_separator {
15471 if self.config.pretty {
15472 self.write_newline();
15473 self.write_indent();
15474 } else {
15475 self.write_space();
15476 }
15477 } else if self.config.pretty {
15478 self.write_newline();
15479 self.write_indent();
15480 }
15481 self.write_keyword("ORDER BY");
15482 if self.config.pretty {
15484 self.indent_level += 1;
15485 for (i, ordered) in order_by.iter().enumerate() {
15486 if i > 0 {
15487 self.write(",");
15488 }
15489 self.write_newline();
15490 self.write_indent();
15491 self.generate_ordered(ordered)?;
15492 }
15493 self.indent_level -= 1;
15494 } else {
15495 self.write_space();
15496 for (i, ordered) in order_by.iter().enumerate() {
15497 if i > 0 {
15498 self.write(", ");
15499 }
15500 self.generate_ordered(ordered)?;
15501 }
15502 }
15503 needs_separator = true;
15504 }
15505 }
15506
15507 if let Some(measures) = &mr.measures {
15509 if !measures.is_empty() {
15510 if needs_separator {
15511 if self.config.pretty {
15512 self.write_newline();
15513 self.write_indent();
15514 } else {
15515 self.write_space();
15516 }
15517 } else if self.config.pretty {
15518 self.write_newline();
15519 self.write_indent();
15520 }
15521 self.write_keyword("MEASURES");
15522 if self.config.pretty {
15524 self.indent_level += 1;
15525 for (i, measure) in measures.iter().enumerate() {
15526 if i > 0 {
15527 self.write(",");
15528 }
15529 self.write_newline();
15530 self.write_indent();
15531 if let Some(semantics) = &measure.window_frame {
15533 match semantics {
15534 MatchRecognizeSemantics::Running => {
15535 self.write_keyword("RUNNING");
15536 self.write_space();
15537 }
15538 MatchRecognizeSemantics::Final => {
15539 self.write_keyword("FINAL");
15540 self.write_space();
15541 }
15542 }
15543 }
15544 self.generate_expression(&measure.this)?;
15545 }
15546 self.indent_level -= 1;
15547 } else {
15548 self.write_space();
15549 for (i, measure) in measures.iter().enumerate() {
15550 if i > 0 {
15551 self.write(", ");
15552 }
15553 if let Some(semantics) = &measure.window_frame {
15555 match semantics {
15556 MatchRecognizeSemantics::Running => {
15557 self.write_keyword("RUNNING");
15558 self.write_space();
15559 }
15560 MatchRecognizeSemantics::Final => {
15561 self.write_keyword("FINAL");
15562 self.write_space();
15563 }
15564 }
15565 }
15566 self.generate_expression(&measure.this)?;
15567 }
15568 }
15569 needs_separator = true;
15570 }
15571 }
15572
15573 if let Some(rows) = &mr.rows {
15575 if needs_separator {
15576 if self.config.pretty {
15577 self.write_newline();
15578 self.write_indent();
15579 } else {
15580 self.write_space();
15581 }
15582 } else if self.config.pretty {
15583 self.write_newline();
15584 self.write_indent();
15585 }
15586 match rows {
15587 MatchRecognizeRows::OneRowPerMatch => {
15588 self.write_keyword("ONE ROW PER MATCH");
15589 }
15590 MatchRecognizeRows::AllRowsPerMatch => {
15591 self.write_keyword("ALL ROWS PER MATCH");
15592 }
15593 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
15594 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
15595 }
15596 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
15597 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
15598 }
15599 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
15600 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
15601 }
15602 }
15603 needs_separator = true;
15604 }
15605
15606 if let Some(after) = &mr.after {
15608 if needs_separator {
15609 if self.config.pretty {
15610 self.write_newline();
15611 self.write_indent();
15612 } else {
15613 self.write_space();
15614 }
15615 } else if self.config.pretty {
15616 self.write_newline();
15617 self.write_indent();
15618 }
15619 match after {
15620 MatchRecognizeAfter::PastLastRow => {
15621 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
15622 }
15623 MatchRecognizeAfter::ToNextRow => {
15624 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
15625 }
15626 MatchRecognizeAfter::ToFirst(ident) => {
15627 self.write_keyword("AFTER MATCH SKIP TO FIRST");
15628 self.write_space();
15629 self.generate_identifier(ident)?;
15630 }
15631 MatchRecognizeAfter::ToLast(ident) => {
15632 self.write_keyword("AFTER MATCH SKIP TO LAST");
15633 self.write_space();
15634 self.generate_identifier(ident)?;
15635 }
15636 }
15637 needs_separator = true;
15638 }
15639
15640 if let Some(pattern) = &mr.pattern {
15642 if needs_separator {
15643 if self.config.pretty {
15644 self.write_newline();
15645 self.write_indent();
15646 } else {
15647 self.write_space();
15648 }
15649 } else if self.config.pretty {
15650 self.write_newline();
15651 self.write_indent();
15652 }
15653 self.write_keyword("PATTERN");
15654 self.write_space();
15655 self.write("(");
15656 self.write(pattern);
15657 self.write(")");
15658 needs_separator = true;
15659 }
15660
15661 if let Some(define) = &mr.define {
15663 if !define.is_empty() {
15664 if needs_separator {
15665 if self.config.pretty {
15666 self.write_newline();
15667 self.write_indent();
15668 } else {
15669 self.write_space();
15670 }
15671 } else if self.config.pretty {
15672 self.write_newline();
15673 self.write_indent();
15674 }
15675 self.write_keyword("DEFINE");
15676 if self.config.pretty {
15678 self.indent_level += 1;
15679 for (i, (name, expr)) in define.iter().enumerate() {
15680 if i > 0 {
15681 self.write(",");
15682 }
15683 self.write_newline();
15684 self.write_indent();
15685 self.generate_identifier(name)?;
15686 self.write(" AS ");
15687 self.generate_expression(expr)?;
15688 }
15689 self.indent_level -= 1;
15690 } else {
15691 self.write_space();
15692 for (i, (name, expr)) in define.iter().enumerate() {
15693 if i > 0 {
15694 self.write(", ");
15695 }
15696 self.generate_identifier(name)?;
15697 self.write(" AS ");
15698 self.generate_expression(expr)?;
15699 }
15700 }
15701 }
15702 }
15703
15704 if self.config.pretty {
15705 self.indent_level -= 1;
15706 self.write_newline();
15707 }
15708 self.write(")");
15709
15710 if let Some(alias) = &mr.alias {
15712 self.write(" ");
15713 if mr.alias_explicit_as {
15714 self.write_keyword("AS");
15715 self.write(" ");
15716 }
15717 self.generate_identifier(alias)?;
15718 }
15719
15720 Ok(())
15721 }
15722
15723 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
15725 use crate::dialects::DialectType;
15726
15727 let supports_hints = matches!(
15729 self.config.dialect,
15730 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
15732 Some(DialectType::Spark) | Some(DialectType::Hive) |
15733 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
15734 );
15735
15736 if !supports_hints || hint.expressions.is_empty() {
15737 return Ok(());
15738 }
15739
15740 let mut hint_strings: Vec<String> = Vec::new();
15743 for expr in &hint.expressions {
15744 match expr {
15745 HintExpression::Raw(text) => {
15746 let parsed = self.parse_raw_hint_text(text);
15748 hint_strings.extend(parsed);
15749 }
15750 _ => {
15751 hint_strings.push(self.hint_expression_to_string(expr)?);
15752 }
15753 }
15754 }
15755
15756 let use_multiline = self.config.pretty && hint_strings.len() > 1;
15760
15761 if use_multiline {
15762 self.write(" /*+ ");
15764 for (i, hint_str) in hint_strings.iter().enumerate() {
15765 if i > 0 {
15766 self.write_newline();
15767 self.write(" "); }
15769 self.write(hint_str);
15770 }
15771 self.write(" */");
15772 } else {
15773 self.write(" /*+ ");
15775 let sep = match self.config.dialect {
15776 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
15777 _ => " ",
15778 };
15779 for (i, hint_str) in hint_strings.iter().enumerate() {
15780 if i > 0 {
15781 self.write(sep);
15782 }
15783 self.write(hint_str);
15784 }
15785 self.write(" */");
15786 }
15787
15788 Ok(())
15789 }
15790
15791 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
15795 let mut results = Vec::new();
15796 let mut chars = text.chars().peekable();
15797 let mut current = String::new();
15798 let mut paren_depth = 0;
15799 let mut has_unparseable_content = false;
15800 let mut position_after_last_function = 0;
15801 let mut char_position = 0;
15802
15803 while let Some(c) = chars.next() {
15804 char_position += c.len_utf8();
15805 match c {
15806 '(' => {
15807 paren_depth += 1;
15808 current.push(c);
15809 }
15810 ')' => {
15811 paren_depth -= 1;
15812 current.push(c);
15813 if paren_depth == 0 {
15815 let trimmed = current.trim().to_string();
15816 if !trimmed.is_empty() {
15817 let formatted = self.format_hint_function(&trimmed);
15819 results.push(formatted);
15820 }
15821 current.clear();
15822 position_after_last_function = char_position;
15823 }
15824 }
15825 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
15826 }
15828 _ if paren_depth == 0 => {
15829 current.push(c);
15831 }
15832 _ => {
15833 current.push(c);
15834 }
15835 }
15836 }
15837
15838 let remaining_text = text[position_after_last_function..].trim();
15840 if !remaining_text.is_empty() {
15841 let words: Vec<&str> = remaining_text.split_whitespace().collect();
15845 let looks_like_hint_functions = words.iter().all(|word| {
15846 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
15848 });
15849
15850 if !looks_like_hint_functions && words.len() > 1 {
15851 has_unparseable_content = true;
15852 }
15853 }
15854
15855 if has_unparseable_content {
15857 return vec![text.trim().to_string()];
15858 }
15859
15860 if results.is_empty() {
15862 results.push(text.trim().to_string());
15863 }
15864
15865 results
15866 }
15867
15868 fn format_hint_function(&self, hint: &str) -> String {
15871 if !self.config.pretty {
15872 return hint.to_string();
15873 }
15874
15875 if let Some(paren_pos) = hint.find('(') {
15877 if hint.ends_with(')') {
15878 let name = &hint[..paren_pos];
15879 let args_str = &hint[paren_pos + 1..hint.len() - 1];
15880
15881 let args: Vec<&str> = args_str.split_whitespace().collect();
15883
15884 let total_args_width: usize =
15886 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() {
15890 let mut result = format!("{}(\n", name);
15891 for arg in &args {
15892 result.push_str(" "); result.push_str(arg);
15894 result.push('\n');
15895 }
15896 result.push_str(" )"); return result;
15898 }
15899 }
15900 }
15901
15902 hint.to_string()
15903 }
15904
15905 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
15907 match expr {
15908 HintExpression::Function { name, args } => {
15909 let arg_strings: Vec<String> = args
15911 .iter()
15912 .map(|arg| {
15913 let mut gen = Generator::with_arc_config(self.config.clone());
15914 gen.generate_expression(arg)?;
15915 Ok(gen.output)
15916 })
15917 .collect::<Result<Vec<_>>>()?;
15918
15919 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
15921 + arg_strings.len().saturating_sub(1); let args_multiline =
15926 self.config.pretty && total_args_width > self.config.max_text_width;
15927
15928 if args_multiline && !arg_strings.is_empty() {
15929 let mut result = format!("{}(\n", name);
15931 for arg_str in &arg_strings {
15932 result.push_str(" "); result.push_str(arg_str);
15934 result.push('\n');
15935 }
15936 result.push_str(" )"); Ok(result)
15938 } else {
15939 let args_str = arg_strings.join(" ");
15941 Ok(format!("{}({})", name, args_str))
15942 }
15943 }
15944 HintExpression::Identifier(name) => Ok(name.clone()),
15945 HintExpression::Raw(text) => {
15946 if self.config.pretty {
15948 Ok(self.format_hint_function(text))
15949 } else {
15950 Ok(text.clone())
15951 }
15952 }
15953 }
15954 }
15955
15956 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
15957 if table.only {
15959 self.write_keyword("ONLY");
15960 self.write_space();
15961 }
15962
15963 if let Some(ref identifier_func) = table.identifier_func {
15965 self.generate_expression(identifier_func)?;
15966 if !table.name.name.is_empty() {
15968 if let Some(catalog) = &table.catalog {
15969 self.write(".");
15970 self.generate_identifier(catalog)?;
15971 }
15972 if let Some(schema) = &table.schema {
15973 self.write(".");
15974 self.generate_identifier(schema)?;
15975 }
15976 self.write(".");
15977 self.generate_identifier(&table.name)?;
15978 }
15979 } else {
15980 if let Some(catalog) = &table.catalog {
15981 self.generate_identifier(catalog)?;
15982 self.write(".");
15983 }
15984 if let Some(schema) = &table.schema {
15985 self.generate_identifier(schema)?;
15986 self.write(".");
15987 }
15988 self.generate_identifier(&table.name)?;
15989 }
15990
15991 if let Some(changes) = &table.changes {
15993 self.write(" ");
15994 self.generate_changes(changes)?;
15995 }
15996
15997 if !table.partitions.is_empty() {
15999 self.write_space();
16000 self.write_keyword("PARTITION");
16001 self.write("(");
16002 for (i, partition) in table.partitions.iter().enumerate() {
16003 if i > 0 {
16004 self.write(", ");
16005 }
16006 self.generate_identifier(partition)?;
16007 }
16008 self.write(")");
16009 }
16010
16011 if table.changes.is_none() {
16014 if let Some(when) = &table.when {
16015 self.write_space();
16016 self.generate_historical_data(when)?;
16017 }
16018 }
16019
16020 let system_time_post_alias = matches!(self.config.dialect, Some(DialectType::BigQuery));
16022 if !system_time_post_alias {
16023 if let Some(ref system_time) = table.system_time {
16024 self.write_space();
16025 self.write(system_time);
16026 }
16027 }
16028
16029 if let Some(ref version) = table.version {
16031 self.write_space();
16032 self.generate_version(version)?;
16033 }
16034
16035 let alias_post_tablesample = self.config.alias_post_tablesample;
16039
16040 if alias_post_tablesample {
16041 self.generate_table_sample_clause(table)?;
16043 }
16044
16045 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
16048 && table.hints.iter().any(|h| {
16049 if let Expression::Identifier(id) = h {
16050 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
16051 } else {
16052 false
16053 }
16054 });
16055 if !table.hints.is_empty() && !is_sqlite_hint {
16056 for hint in &table.hints {
16057 self.write_space();
16058 self.generate_expression(hint)?;
16059 }
16060 }
16061
16062 if let Some(alias) = &table.alias {
16063 self.write_space();
16064 let always_use_as = self.config.dialect.is_none()
16067 || matches!(
16068 self.config.dialect,
16069 Some(DialectType::Generic)
16070 | Some(DialectType::PostgreSQL)
16071 | Some(DialectType::Redshift)
16072 | Some(DialectType::Snowflake)
16073 | Some(DialectType::BigQuery)
16074 | Some(DialectType::DuckDB)
16075 | Some(DialectType::Presto)
16076 | Some(DialectType::Trino)
16077 | Some(DialectType::TSQL)
16078 | Some(DialectType::Fabric)
16079 | Some(DialectType::MySQL)
16080 | Some(DialectType::Spark)
16081 | Some(DialectType::Hive)
16082 | Some(DialectType::SQLite)
16083 | Some(DialectType::Drill)
16084 );
16085 let is_stage_ref = table.name.name.starts_with('@');
16086 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
16088 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
16089 self.write_keyword("AS");
16090 self.write_space();
16091 }
16092 self.generate_identifier(alias)?;
16093
16094 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
16097 self.write("(");
16098 for (i, col_alias) in table.column_aliases.iter().enumerate() {
16099 if i > 0 {
16100 self.write(", ");
16101 }
16102 self.generate_identifier(col_alias)?;
16103 }
16104 self.write(")");
16105 }
16106 }
16107
16108 if system_time_post_alias {
16110 if let Some(ref system_time) = table.system_time {
16111 self.write_space();
16112 self.write(system_time);
16113 }
16114 }
16115
16116 if !alias_post_tablesample {
16118 self.generate_table_sample_clause(table)?;
16119 }
16120
16121 if is_sqlite_hint {
16123 for hint in &table.hints {
16124 self.write_space();
16125 self.generate_expression(hint)?;
16126 }
16127 }
16128
16129 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
16131 self.write_space();
16132 self.write_keyword("FINAL");
16133 }
16134
16135 for comment in &table.trailing_comments {
16137 self.write_space();
16138 self.write_formatted_comment(comment);
16139 }
16140 Ok(())
16144 }
16145
16146 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
16148 if let Some(ref ts) = table.table_sample {
16149 self.write_space();
16150 if ts.is_using_sample {
16151 self.write_keyword("USING SAMPLE");
16152 } else {
16153 self.write_keyword(self.config.tablesample_keywords);
16155 }
16156 self.generate_sample_body(ts)?;
16157 if let Some(ref seed) = ts.seed {
16159 self.write_space();
16160 self.write_keyword(self.config.tablesample_seed_keyword);
16161 self.write(" (");
16162 self.generate_expression(seed)?;
16163 self.write(")");
16164 }
16165 }
16166 Ok(())
16167 }
16168
16169 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
16170 if sr.quoted {
16174 self.write("'");
16175 }
16176
16177 self.write(&sr.name);
16178 if let Some(path) = &sr.path {
16179 self.write(path);
16180 }
16181
16182 if sr.quoted {
16183 self.write("'");
16184 }
16185
16186 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
16188 if has_options {
16189 self.write(" (");
16190 let mut first = true;
16191
16192 if let Some(file_format) = &sr.file_format {
16193 if !first {
16194 self.write(", ");
16195 }
16196 self.write_keyword("FILE_FORMAT");
16197 self.write(" => ");
16198 self.generate_expression(file_format)?;
16199 first = false;
16200 }
16201
16202 if let Some(pattern) = &sr.pattern {
16203 if !first {
16204 self.write(", ");
16205 }
16206 self.write_keyword("PATTERN");
16207 self.write(" => '");
16208 self.write(pattern);
16209 self.write("'");
16210 }
16211
16212 self.write(")");
16213 }
16214 Ok(())
16215 }
16216
16217 fn generate_star(&mut self, star: &Star) -> Result<()> {
16218 use crate::dialects::DialectType;
16219
16220 if let Some(table) = &star.table {
16221 self.generate_identifier(table)?;
16222 self.write(".");
16223 }
16224 self.write("*");
16225
16226 if let Some(except) = &star.except {
16228 if !except.is_empty() {
16229 self.write_space();
16230 match self.config.dialect {
16232 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
16233 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
16234 self.write_keyword("EXCLUDE")
16235 }
16236 _ => self.write_keyword("EXCEPT"), }
16238 self.write(" (");
16239 for (i, col) in except.iter().enumerate() {
16240 if i > 0 {
16241 self.write(", ");
16242 }
16243 self.generate_identifier(col)?;
16244 }
16245 self.write(")");
16246 }
16247 }
16248
16249 if let Some(replace) = &star.replace {
16251 if !replace.is_empty() {
16252 self.write_space();
16253 self.write_keyword("REPLACE");
16254 self.write(" (");
16255 for (i, alias) in replace.iter().enumerate() {
16256 if i > 0 {
16257 self.write(", ");
16258 }
16259 self.generate_expression(&alias.this)?;
16260 self.write_space();
16261 self.write_keyword("AS");
16262 self.write_space();
16263 self.generate_identifier(&alias.alias)?;
16264 }
16265 self.write(")");
16266 }
16267 }
16268
16269 if let Some(rename) = &star.rename {
16271 if !rename.is_empty() {
16272 self.write_space();
16273 self.write_keyword("RENAME");
16274 self.write(" (");
16275 for (i, (old_name, new_name)) in rename.iter().enumerate() {
16276 if i > 0 {
16277 self.write(", ");
16278 }
16279 self.generate_identifier(old_name)?;
16280 self.write_space();
16281 self.write_keyword("AS");
16282 self.write_space();
16283 self.generate_identifier(new_name)?;
16284 }
16285 self.write(")");
16286 }
16287 }
16288
16289 for comment in &star.trailing_comments {
16291 self.write_space();
16292 self.write_formatted_comment(comment);
16293 }
16294
16295 Ok(())
16296 }
16297
16298 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
16300 self.write("{");
16301 match expr {
16302 Expression::Star(star) => {
16303 self.generate_star(star)?;
16305 }
16306 Expression::ILike(ilike) => {
16307 self.generate_expression(&ilike.left)?;
16309 self.write_space();
16310 self.write_keyword("ILIKE");
16311 self.write_space();
16312 self.generate_expression(&ilike.right)?;
16313 }
16314 _ => {
16315 self.generate_expression(expr)?;
16316 }
16317 }
16318 self.write("}");
16319 Ok(())
16320 }
16321
16322 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
16323 match &alias.this {
16327 Expression::Column(col) => {
16328 if let Some(table) = &col.table {
16330 self.generate_identifier(table)?;
16331 self.write(".");
16332 }
16333 self.generate_identifier(&col.name)?;
16334 }
16335 _ => {
16336 self.generate_expression(&alias.this)?;
16337 }
16338 }
16339
16340 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
16344 for comment in &alias.pre_alias_comments {
16345 self.write_space();
16346 self.write_formatted_comment(comment);
16347 }
16348 }
16349
16350 use crate::dialects::DialectType;
16351
16352 let is_table_source = matches!(
16358 &alias.this,
16359 Expression::JSONTable(_)
16360 | Expression::XMLTable(_)
16361 | Expression::TableFromRows(_)
16362 | Expression::Unnest(_)
16363 | Expression::MatchRecognize(_)
16364 | Expression::Select(_)
16365 | Expression::Subquery(_)
16366 | Expression::Paren(_)
16367 );
16368 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
16369 let skip_as = is_table_source && dialect_skips_table_alias_as;
16370
16371 self.write_space();
16372 if !skip_as {
16373 self.write_keyword("AS");
16374 self.write_space();
16375 }
16376
16377 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
16379
16380 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
16382 self.write("(");
16384 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16385 if i > 0 {
16386 self.write(", ");
16387 }
16388 self.generate_alias_identifier(col_alias)?;
16389 }
16390 self.write(")");
16391 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
16392 self.generate_alias_identifier(&alias.alias)?;
16394 self.write("(");
16395 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16396 if i > 0 {
16397 self.write(", ");
16398 }
16399 self.generate_alias_identifier(col_alias)?;
16400 }
16401 self.write(")");
16402 } else {
16403 self.generate_alias_identifier(&alias.alias)?;
16405 }
16406
16407 for comment in &alias.trailing_comments {
16409 self.write_space();
16410 self.write_formatted_comment(comment);
16411 }
16412
16413 if alias.trailing_comments.is_empty() {
16418 for comment in &alias.pre_alias_comments {
16419 self.write_space();
16420 self.write_formatted_comment(comment);
16421 }
16422 }
16423
16424 Ok(())
16425 }
16426
16427 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
16428 use crate::dialects::DialectType;
16429
16430 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
16432 self.generate_expression(&cast.this)?;
16433 self.write(" :> ");
16434 self.generate_data_type(&cast.to)?;
16435 return Ok(());
16436 }
16437
16438 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
16440 let is_unknown_type = matches!(cast.to, DataType::Unknown)
16441 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
16442 if is_unknown_type {
16443 if let Some(format) = &cast.format {
16444 self.write_keyword("CAST");
16445 self.write("(");
16446 self.generate_expression(&cast.this)?;
16447 self.write_space();
16448 self.write_keyword("AS");
16449 self.write_space();
16450 self.write_keyword("FORMAT");
16451 self.write_space();
16452 self.generate_expression(format)?;
16453 self.write(")");
16454 return Ok(());
16455 }
16456 }
16457 }
16458
16459 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
16462 if let Some(format) = &cast.format {
16463 let is_date = matches!(cast.to, DataType::Date);
16465 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
16466
16467 if is_date || is_timestamp {
16468 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
16469 self.write_keyword(func_name);
16470 self.write("(");
16471 self.generate_expression(&cast.this)?;
16472 self.write(", ");
16473
16474 if let Expression::Literal(lit) = format.as_ref() {
16477 if let Literal::String(fmt_str) = lit.as_ref() {
16478 let normalized = self.normalize_oracle_format(fmt_str);
16479 self.write("'");
16480 self.write(&normalized);
16481 self.write("'");
16482 }
16483 } else {
16484 self.generate_expression(format)?;
16485 }
16486
16487 self.write(")");
16488 return Ok(());
16489 }
16490 }
16491 }
16492
16493 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
16496 if let Expression::Array(arr) = &cast.this {
16497 self.generate_data_type(&cast.to)?;
16498 self.write("[");
16500 for (i, expr) in arr.expressions.iter().enumerate() {
16501 if i > 0 {
16502 self.write(", ");
16503 }
16504 self.generate_expression(expr)?;
16505 }
16506 self.write("]");
16507 return Ok(());
16508 }
16509 if matches!(&cast.this, Expression::ArrayFunc(_)) {
16510 self.generate_data_type(&cast.to)?;
16511 self.generate_expression(&cast.this)?;
16512 return Ok(());
16513 }
16514 }
16515
16516 if matches!(
16519 self.config.dialect,
16520 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
16521 ) {
16522 if let Expression::Struct(ref s) = cast.this {
16523 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
16524 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
16525 self.write_keyword("CAST");
16526 self.write("(");
16527 self.generate_struct_as_row(s)?;
16528 self.write_space();
16529 self.write_keyword("AS");
16530 self.write_space();
16531 self.generate_data_type(&cast.to)?;
16532 self.write(")");
16533 return Ok(());
16534 }
16535 }
16536 }
16537
16538 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
16541
16542 if use_double_colon {
16543 self.generate_expression(&cast.this)?;
16545 self.write("::");
16546 self.generate_data_type(&cast.to)?;
16547 } else {
16548 self.write_keyword("CAST");
16550 self.write("(");
16551 self.generate_expression(&cast.this)?;
16552 self.write_space();
16553 self.write_keyword("AS");
16554 self.write_space();
16555 if matches!(
16558 self.config.dialect,
16559 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
16560 ) {
16561 match &cast.to {
16562 DataType::Custom { ref name } => {
16563 if name.eq_ignore_ascii_case("LONGTEXT")
16564 || name.eq_ignore_ascii_case("MEDIUMTEXT")
16565 || name.eq_ignore_ascii_case("TINYTEXT")
16566 || name.eq_ignore_ascii_case("LONGBLOB")
16567 || name.eq_ignore_ascii_case("MEDIUMBLOB")
16568 || name.eq_ignore_ascii_case("TINYBLOB")
16569 {
16570 self.write_keyword("CHAR");
16571 } else {
16572 self.generate_data_type(&cast.to)?;
16573 }
16574 }
16575 DataType::VarChar { length, .. } => {
16576 self.write_keyword("CHAR");
16578 if let Some(n) = length {
16579 self.write(&format!("({})", n));
16580 }
16581 }
16582 DataType::Text => {
16583 self.write_keyword("CHAR");
16585 }
16586 DataType::Timestamp {
16587 precision,
16588 timezone: false,
16589 } => {
16590 self.write_keyword("DATETIME");
16592 if let Some(p) = precision {
16593 self.write(&format!("({})", p));
16594 }
16595 }
16596 _ => {
16597 self.generate_data_type(&cast.to)?;
16598 }
16599 }
16600 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
16601 match &cast.to {
16603 DataType::String { length } => {
16604 self.write_keyword("VARCHAR");
16605 if let Some(n) = length {
16606 self.write(&format!("({})", n));
16607 }
16608 }
16609 _ => {
16610 self.generate_data_type(&cast.to)?;
16611 }
16612 }
16613 } else {
16614 self.generate_data_type(&cast.to)?;
16615 }
16616
16617 if let Some(default) = &cast.default {
16619 self.write_space();
16620 self.write_keyword("DEFAULT");
16621 self.write_space();
16622 self.generate_expression(default)?;
16623 self.write_space();
16624 self.write_keyword("ON");
16625 self.write_space();
16626 self.write_keyword("CONVERSION");
16627 self.write_space();
16628 self.write_keyword("ERROR");
16629 }
16630
16631 if let Some(format) = &cast.format {
16634 if matches!(
16636 self.config.dialect,
16637 Some(crate::dialects::DialectType::Oracle)
16638 ) {
16639 self.write(", ");
16640 } else {
16641 self.write_space();
16642 self.write_keyword("FORMAT");
16643 self.write_space();
16644 }
16645 self.generate_expression(format)?;
16646 }
16647
16648 self.write(")");
16649 for comment in &cast.trailing_comments {
16651 self.write_space();
16652 self.write_formatted_comment(comment);
16653 }
16654 }
16655 Ok(())
16656 }
16657
16658 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
16661 self.write_keyword("ROW");
16662 self.write("(");
16663 for (i, (_, expr)) in s.fields.iter().enumerate() {
16664 if i > 0 {
16665 self.write(", ");
16666 }
16667 if let Expression::Struct(ref inner_s) = expr {
16669 self.generate_struct_as_row(inner_s)?;
16670 } else {
16671 self.generate_expression(expr)?;
16672 }
16673 }
16674 self.write(")");
16675 Ok(())
16676 }
16677
16678 fn normalize_oracle_format(&self, format: &str) -> String {
16681 let mut result = String::new();
16684 let chars: Vec<char> = format.chars().collect();
16685 let mut i = 0;
16686
16687 while i < chars.len() {
16688 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
16689 if i + 2 < chars.len() {
16691 let next = chars[i + 2];
16692 if next == '1' || next == '2' {
16693 result.push('H');
16695 result.push('H');
16696 i += 2;
16697 continue;
16698 }
16699 }
16700 result.push_str("HH12");
16702 i += 2;
16703 } else {
16704 result.push(chars[i]);
16705 i += 1;
16706 }
16707 }
16708
16709 result
16710 }
16711
16712 fn dialect_prefers_double_colon(&self) -> bool {
16716 false
16719 }
16720
16721 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16723 use crate::dialects::DialectType;
16724
16725 let use_percent_operator = matches!(
16727 self.config.dialect,
16728 Some(DialectType::Snowflake)
16729 | Some(DialectType::MySQL)
16730 | Some(DialectType::Presto)
16731 | Some(DialectType::Trino)
16732 | Some(DialectType::PostgreSQL)
16733 | Some(DialectType::DuckDB)
16734 | Some(DialectType::Hive)
16735 | Some(DialectType::Spark)
16736 | Some(DialectType::Databricks)
16737 | Some(DialectType::Athena)
16738 );
16739
16740 if use_percent_operator {
16741 let needs_paren = |e: &Expression| matches!(e, Expression::Add(_) | Expression::Sub(_));
16744 if needs_paren(&f.this) {
16745 self.write("(");
16746 self.generate_expression(&f.this)?;
16747 self.write(")");
16748 } else {
16749 self.generate_expression(&f.this)?;
16750 }
16751 self.write(" % ");
16752 if needs_paren(&f.expression) {
16753 self.write("(");
16754 self.generate_expression(&f.expression)?;
16755 self.write(")");
16756 } else {
16757 self.generate_expression(&f.expression)?;
16758 }
16759 Ok(())
16760 } else {
16761 self.generate_binary_func("MOD", &f.this, &f.expression)
16762 }
16763 }
16764
16765 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16767 use crate::dialects::DialectType;
16768
16769 let func_name = match self.config.dialect {
16771 Some(DialectType::Snowflake) => "COALESCE",
16772 _ => "IFNULL",
16773 };
16774
16775 self.generate_binary_func(func_name, &f.this, &f.expression)
16776 }
16777
16778 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16780 if let Some(ref original_name) = f.original_name {
16782 return self.generate_binary_func(original_name, &f.this, &f.expression);
16783 }
16784
16785 use crate::dialects::DialectType;
16787 let func_name = match self.config.dialect {
16788 Some(DialectType::Snowflake)
16789 | Some(DialectType::ClickHouse)
16790 | Some(DialectType::PostgreSQL)
16791 | Some(DialectType::Presto)
16792 | Some(DialectType::Trino)
16793 | Some(DialectType::Athena)
16794 | Some(DialectType::DuckDB)
16795 | Some(DialectType::BigQuery)
16796 | Some(DialectType::Spark)
16797 | Some(DialectType::Databricks)
16798 | Some(DialectType::Hive) => "COALESCE",
16799 Some(DialectType::MySQL)
16800 | Some(DialectType::Doris)
16801 | Some(DialectType::StarRocks)
16802 | Some(DialectType::SingleStore)
16803 | Some(DialectType::TiDB) => "IFNULL",
16804 _ => "NVL",
16805 };
16806
16807 self.generate_binary_func(func_name, &f.this, &f.expression)
16808 }
16809
16810 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
16812 use crate::dialects::DialectType;
16813
16814 let func_name = match self.config.dialect {
16816 Some(DialectType::Snowflake) => "STDDEV",
16817 _ => "STDDEV_SAMP",
16818 };
16819
16820 self.generate_agg_func(func_name, f)
16821 }
16822
16823 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
16824 self.generate_expression(&coll.this)?;
16825 self.write_space();
16826 self.write_keyword("COLLATE");
16827 self.write_space();
16828 if coll.quoted {
16829 self.write("'");
16831 self.write(&coll.collation);
16832 self.write("'");
16833 } else if coll.double_quoted {
16834 self.write("\"");
16836 self.write(&coll.collation);
16837 self.write("\"");
16838 } else {
16839 self.write(&coll.collation);
16841 }
16842 Ok(())
16843 }
16844
16845 fn generate_case(&mut self, case: &Case) -> Result<()> {
16846 let multiline_case = if self.config.pretty {
16848 let mut statements: Vec<String> = Vec::new();
16850 let operand_str = if let Some(operand) = &case.operand {
16851 let s = self.generate_to_string(operand)?;
16852 statements.push(format!("CASE {}", s));
16853 s
16854 } else {
16855 statements.push("CASE".to_string());
16856 String::new()
16857 };
16858 let _ = operand_str;
16859 for (condition, result) in &case.whens {
16860 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
16861 statements.push(format!("THEN {}", self.generate_to_string(result)?));
16862 }
16863 if let Some(else_) = &case.else_ {
16864 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
16865 }
16866 statements.push("END".to_string());
16867 self.too_wide(&statements)
16868 } else {
16869 false
16870 };
16871
16872 self.write_keyword("CASE");
16873 if let Some(operand) = &case.operand {
16874 self.write_space();
16875 self.generate_expression(operand)?;
16876 }
16877 if multiline_case {
16878 self.indent_level += 1;
16879 }
16880 for (condition, result) in &case.whens {
16881 if multiline_case {
16882 self.write_newline();
16883 self.write_indent();
16884 } else {
16885 self.write_space();
16886 }
16887 self.write_keyword("WHEN");
16888 self.write_space();
16889 self.generate_expression(condition)?;
16890 if multiline_case {
16891 self.write_newline();
16892 self.write_indent();
16893 } else {
16894 self.write_space();
16895 }
16896 self.write_keyword("THEN");
16897 self.write_space();
16898 self.generate_expression(result)?;
16899 }
16900 if let Some(else_) = &case.else_ {
16901 if multiline_case {
16902 self.write_newline();
16903 self.write_indent();
16904 } else {
16905 self.write_space();
16906 }
16907 self.write_keyword("ELSE");
16908 self.write_space();
16909 self.generate_expression(else_)?;
16910 }
16911 if multiline_case {
16912 self.indent_level -= 1;
16913 self.write_newline();
16914 self.write_indent();
16915 } else {
16916 self.write_space();
16917 }
16918 self.write_keyword("END");
16919 for comment in &case.comments {
16921 self.write(" ");
16922 self.write_formatted_comment(comment);
16923 }
16924 Ok(())
16925 }
16926
16927 fn generate_function(&mut self, func: &Function) -> Result<()> {
16928 let normalized_name = self.normalize_func_name(&func.name);
16930
16931 if matches!(self.config.dialect, Some(DialectType::DuckDB))
16933 && func.name.eq_ignore_ascii_case("ARRAY_CONSTRUCT_COMPACT")
16934 {
16935 self.write("LIST_FILTER(");
16936 self.write("[");
16937 for (i, arg) in func.args.iter().enumerate() {
16938 if i > 0 {
16939 self.write(", ");
16940 }
16941 self.generate_expression(arg)?;
16942 }
16943 self.write("], _u -> NOT _u IS NULL)");
16944 return Ok(());
16945 }
16946
16947 if func.name.eq_ignore_ascii_case("STRUCT")
16949 && !matches!(
16950 self.config.dialect,
16951 Some(DialectType::BigQuery)
16952 | Some(DialectType::Spark)
16953 | Some(DialectType::Databricks)
16954 | Some(DialectType::Hive)
16955 | None
16956 )
16957 {
16958 return self.generate_struct_function_cross_dialect(func);
16959 }
16960
16961 if func.name.eq_ignore_ascii_case("__SS_JSON_PATH_QMARK__") && func.args.len() == 2 {
16964 self.generate_expression(&func.args[0])?;
16965 self.write("::?");
16966 if let Expression::Literal(lit) = &func.args[1] {
16968 if let crate::expressions::Literal::String(key) = lit.as_ref() {
16969 self.write(key);
16970 }
16971 } else {
16972 self.generate_expression(&func.args[1])?;
16973 }
16974 return Ok(());
16975 }
16976
16977 if func.name.eq_ignore_ascii_case("__PG_BITWISE_XOR__") && func.args.len() == 2 {
16979 self.generate_expression(&func.args[0])?;
16980 self.write(" # ");
16981 self.generate_expression(&func.args[1])?;
16982 return Ok(());
16983 }
16984
16985 if matches!(
16987 self.config.dialect,
16988 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
16989 ) && func.name.eq_ignore_ascii_case("TRY")
16990 && func.args.len() == 1
16991 {
16992 self.generate_expression(&func.args[0])?;
16993 return Ok(());
16994 }
16995
16996 if self.config.dialect == Some(DialectType::ClickHouse)
16998 && func.name.eq_ignore_ascii_case("TOSTARTOFDAY")
16999 && func.args.len() == 1
17000 {
17001 self.write("dateTrunc('DAY', ");
17002 self.generate_expression(&func.args[0])?;
17003 self.write(")");
17004 return Ok(());
17005 }
17006
17007 if self.config.dialect == Some(DialectType::Redshift)
17009 && func.name.eq_ignore_ascii_case("CONCAT")
17010 && func.args.len() >= 2
17011 {
17012 for (i, arg) in func.args.iter().enumerate() {
17013 if i > 0 {
17014 self.write(" || ");
17015 }
17016 self.generate_expression(arg)?;
17017 }
17018 return Ok(());
17019 }
17020
17021 if self.config.dialect == Some(DialectType::Redshift)
17023 && func.name.eq_ignore_ascii_case("CONCAT_WS")
17024 && func.args.len() >= 2
17025 {
17026 let sep = &func.args[0];
17027 for (i, arg) in func.args.iter().skip(1).enumerate() {
17028 if i > 0 {
17029 self.write(" || ");
17030 self.generate_expression(sep)?;
17031 self.write(" || ");
17032 }
17033 self.generate_expression(arg)?;
17034 }
17035 return Ok(());
17036 }
17037
17038 if self.config.dialect == Some(DialectType::Redshift)
17041 && (func.name.eq_ignore_ascii_case("DATEDIFF")
17042 || func.name.eq_ignore_ascii_case("DATE_DIFF"))
17043 && func.args.len() == 3
17044 {
17045 self.write_keyword("DATEDIFF");
17046 self.write("(");
17047 self.write_redshift_date_part(&func.args[0]);
17049 self.write(", ");
17050 self.generate_expression(&func.args[1])?;
17051 self.write(", ");
17052 self.generate_expression(&func.args[2])?;
17053 self.write(")");
17054 return Ok(());
17055 }
17056
17057 if self.config.dialect == Some(DialectType::Redshift)
17060 && (func.name.eq_ignore_ascii_case("DATEADD")
17061 || func.name.eq_ignore_ascii_case("DATE_ADD"))
17062 && func.args.len() == 3
17063 {
17064 self.write_keyword("DATEADD");
17065 self.write("(");
17066 self.write_redshift_date_part(&func.args[0]);
17068 self.write(", ");
17069 self.generate_expression(&func.args[1])?;
17070 self.write(", ");
17071 self.generate_expression(&func.args[2])?;
17072 self.write(")");
17073 return Ok(());
17074 }
17075
17076 if func.name.eq_ignore_ascii_case("UUID_STRING")
17078 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
17079 {
17080 let func_name = match self.config.dialect {
17081 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
17082 Some(DialectType::BigQuery) => "GENERATE_UUID",
17083 _ => "UUID",
17084 };
17085 self.write_keyword(func_name);
17086 self.write("()");
17087 return Ok(());
17088 }
17089
17090 if matches!(self.config.dialect, Some(DialectType::Snowflake))
17094 && func.name.eq_ignore_ascii_case("GENERATOR")
17095 {
17096 let has_positional_args =
17097 !func.args.is_empty() && !matches!(&func.args[0], Expression::NamedArgument(_));
17098 if has_positional_args {
17099 let param_names = ["ROWCOUNT", "TIMELIMIT"];
17100 self.write_keyword("GENERATOR");
17101 self.write("(");
17102 for (i, arg) in func.args.iter().enumerate() {
17103 if i > 0 {
17104 self.write(", ");
17105 }
17106 if i < param_names.len() {
17107 self.write_keyword(param_names[i]);
17108 self.write(" => ");
17109 self.generate_expression(arg)?;
17110 } else {
17111 self.generate_expression(arg)?;
17112 }
17113 }
17114 self.write(")");
17115 return Ok(());
17116 }
17117 }
17118
17119 if self.config.dialect == Some(DialectType::Redshift)
17122 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
17123 && func.args.len() == 2
17124 {
17125 self.write_keyword("DATE_TRUNC");
17126 self.write("(");
17127 self.write_redshift_date_part_quoted(&func.args[0]);
17129 self.write(", ");
17130 self.generate_expression(&func.args[1])?;
17131 self.write(")");
17132 return Ok(());
17133 }
17134
17135 if matches!(
17137 self.config.dialect,
17138 Some(DialectType::TSQL) | Some(DialectType::Fabric)
17139 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17140 || func.name.eq_ignore_ascii_case("DATEPART"))
17141 && func.args.len() == 2
17142 {
17143 self.write_keyword("DATEPART");
17144 self.write("(");
17145 self.generate_expression(&func.args[0])?;
17146 self.write(", ");
17147 self.generate_expression(&func.args[1])?;
17148 self.write(")");
17149 return Ok(());
17150 }
17151
17152 if matches!(
17154 self.config.dialect,
17155 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
17156 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17157 || func.name.eq_ignore_ascii_case("DATEPART"))
17158 && func.args.len() == 2
17159 {
17160 self.write_keyword("EXTRACT");
17161 self.write("(");
17162 match &func.args[0] {
17164 Expression::Literal(lit)
17165 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
17166 {
17167 let crate::expressions::Literal::String(s) = lit.as_ref() else {
17168 unreachable!()
17169 };
17170 self.write(&s.to_ascii_lowercase());
17171 }
17172 _ => self.generate_expression(&func.args[0])?,
17173 }
17174 self.write_space();
17175 self.write_keyword("FROM");
17176 self.write_space();
17177 self.generate_expression(&func.args[1])?;
17178 self.write(")");
17179 return Ok(());
17180 }
17181
17182 if self.config.dialect == Some(DialectType::Dremio)
17185 && (func.name.eq_ignore_ascii_case("DATE_PART")
17186 || func.name.eq_ignore_ascii_case("DATEPART"))
17187 && func.args.len() == 2
17188 {
17189 self.write_keyword("EXTRACT");
17190 self.write("(");
17191 self.generate_expression(&func.args[0])?;
17192 self.write_space();
17193 self.write_keyword("FROM");
17194 self.write_space();
17195 self.generate_dremio_date_expression(&func.args[1])?;
17197 self.write(")");
17198 return Ok(());
17199 }
17200
17201 if self.config.dialect == Some(DialectType::Dremio)
17203 && func.name.eq_ignore_ascii_case("CURRENT_DATE_UTC")
17204 && func.args.is_empty()
17205 {
17206 self.write_keyword("CURRENT_DATE_UTC");
17207 return Ok(());
17208 }
17209
17210 if self.config.dialect == Some(DialectType::Dremio)
17214 && func.name.eq_ignore_ascii_case("DATETYPE")
17215 && func.args.len() == 3
17216 {
17217 fn get_int_literal(expr: &Expression) -> Option<i64> {
17219 if let Expression::Literal(lit) = expr {
17220 if let crate::expressions::Literal::Number(s) = lit.as_ref() {
17221 s.parse::<i64>().ok()
17222 } else {
17223 None
17224 }
17225 } else {
17226 None
17227 }
17228 }
17229
17230 if let (Some(year), Some(month), Some(day)) = (
17232 get_int_literal(&func.args[0]),
17233 get_int_literal(&func.args[1]),
17234 get_int_literal(&func.args[2]),
17235 ) {
17236 self.write_keyword("DATE");
17238 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
17239 return Ok(());
17240 }
17241
17242 self.write_keyword("CAST");
17244 self.write("(");
17245 self.write_keyword("CONCAT");
17246 self.write("(");
17247 self.generate_expression(&func.args[0])?;
17248 self.write(", '-', ");
17249 self.generate_expression(&func.args[1])?;
17250 self.write(", '-', ");
17251 self.generate_expression(&func.args[2])?;
17252 self.write(")");
17253 self.write_space();
17254 self.write_keyword("AS");
17255 self.write_space();
17256 self.write_keyword("DATE");
17257 self.write(")");
17258 return Ok(());
17259 }
17260
17261 let is_presto_like = matches!(
17264 self.config.dialect,
17265 Some(DialectType::Presto) | Some(DialectType::Trino)
17266 );
17267 if is_presto_like && func.name.eq_ignore_ascii_case("DATE_ADD") && func.args.len() == 3 {
17268 self.write_keyword("DATE_ADD");
17269 self.write("(");
17270 self.generate_expression(&func.args[0])?;
17272 self.write(", ");
17273 let interval = &func.args[1];
17275 let needs_cast = !self.returns_integer_type(interval);
17276 if needs_cast {
17277 self.write_keyword("CAST");
17278 self.write("(");
17279 }
17280 self.generate_expression(interval)?;
17281 if needs_cast {
17282 self.write_space();
17283 self.write_keyword("AS");
17284 self.write_space();
17285 self.write_keyword("BIGINT");
17286 self.write(")");
17287 }
17288 self.write(", ");
17289 self.generate_expression(&func.args[2])?;
17291 self.write(")");
17292 return Ok(());
17293 }
17294
17295 let use_brackets = func.use_bracket_syntax;
17297
17298 let has_ordinality = func.name.len() >= 16
17303 && func.name[func.name.len() - 16..].eq_ignore_ascii_case(" WITH ORDINALITY");
17304 let output_name = if has_ordinality {
17305 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
17306 self.normalize_func_name(base_name)
17307 } else {
17308 normalized_name.clone()
17309 };
17310
17311 if func.name.contains('.') && !has_ordinality {
17314 if func.quoted {
17317 self.write("`");
17318 self.write(&func.name);
17319 self.write("`");
17320 } else {
17321 self.write(&func.name);
17322 }
17323 } else {
17324 self.write(&output_name);
17325 }
17326
17327 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
17330 let needs_parens = if func.name.eq_ignore_ascii_case("CURRENT_USER")
17331 || func.name.eq_ignore_ascii_case("SESSION_USER")
17332 || func.name.eq_ignore_ascii_case("SYSTEM_USER")
17333 {
17334 matches!(
17335 self.config.dialect,
17336 Some(DialectType::Snowflake)
17337 | Some(DialectType::Spark)
17338 | Some(DialectType::Databricks)
17339 | Some(DialectType::Hive)
17340 )
17341 } else {
17342 false
17343 };
17344 !needs_parens
17345 };
17346 if force_parens {
17347 for comment in &func.trailing_comments {
17349 self.write_space();
17350 self.write_formatted_comment(comment);
17351 }
17352 return Ok(());
17353 }
17354
17355 if func.name.eq_ignore_ascii_case("CUBE")
17357 || func.name.eq_ignore_ascii_case("ROLLUP")
17358 || func.name.eq_ignore_ascii_case("GROUPING SETS")
17359 {
17360 self.write(" (");
17361 } else if use_brackets {
17362 self.write("[");
17363 } else {
17364 self.write("(");
17365 }
17366 if func.distinct {
17367 self.write_keyword("DISTINCT");
17368 self.write_space();
17369 }
17370
17371 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
17373 && (func.name.eq_ignore_ascii_case("TABLE")
17374 || func.name.eq_ignore_ascii_case("FLATTEN"));
17375 let is_grouping_func = func.name.eq_ignore_ascii_case("GROUPING SETS")
17377 || func.name.eq_ignore_ascii_case("CUBE")
17378 || func.name.eq_ignore_ascii_case("ROLLUP");
17379 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
17380 if is_grouping_func {
17381 true
17382 } else {
17383 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
17385 for arg in &func.args {
17386 let mut temp_gen = Generator::with_arc_config(self.config.clone());
17387 Arc::make_mut(&mut temp_gen.config).pretty = false; temp_gen.generate_expression(arg)?;
17389 expr_strings.push(temp_gen.output);
17390 }
17391 self.too_wide(&expr_strings)
17392 }
17393 } else {
17394 false
17395 };
17396
17397 if should_split {
17398 self.write_newline();
17400 self.indent_level += 1;
17401 for (i, arg) in func.args.iter().enumerate() {
17402 self.write_indent();
17403 self.generate_expression(arg)?;
17404 if i + 1 < func.args.len() {
17405 self.write(",");
17406 }
17407 self.write_newline();
17408 }
17409 self.indent_level -= 1;
17410 self.write_indent();
17411 } else {
17412 for (i, arg) in func.args.iter().enumerate() {
17414 if i > 0 {
17415 self.write(", ");
17416 }
17417 self.generate_expression(arg)?;
17418 }
17419 }
17420
17421 if use_brackets {
17422 self.write("]");
17423 } else {
17424 self.write(")");
17425 }
17426 if has_ordinality {
17428 self.write_space();
17429 self.write_keyword("WITH ORDINALITY");
17430 }
17431 for comment in &func.trailing_comments {
17433 self.write_space();
17434 self.write_formatted_comment(comment);
17435 }
17436 Ok(())
17437 }
17438
17439 fn generate_function_emits(&mut self, fe: &FunctionEmits) -> Result<()> {
17440 self.generate_expression(&fe.this)?;
17441 self.write_keyword(" EMITS ");
17442 self.generate_expression(&fe.emits)?;
17443 Ok(())
17444 }
17445
17446 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
17447 let mut normalized_name = self.normalize_func_name(&func.name);
17449
17450 if func.name.eq_ignore_ascii_case("MAX_BY") || func.name.eq_ignore_ascii_case("MIN_BY") {
17452 let is_max = func.name.eq_ignore_ascii_case("MAX_BY");
17453 match self.config.dialect {
17454 Some(DialectType::ClickHouse) => {
17455 normalized_name = if is_max {
17456 Cow::Borrowed("argMax")
17457 } else {
17458 Cow::Borrowed("argMin")
17459 };
17460 }
17461 Some(DialectType::DuckDB) => {
17462 normalized_name = if is_max {
17463 Cow::Borrowed("ARG_MAX")
17464 } else {
17465 Cow::Borrowed("ARG_MIN")
17466 };
17467 }
17468 _ => {}
17469 }
17470 }
17471 self.write(normalized_name.as_ref());
17472 self.write("(");
17473 if func.distinct {
17474 self.write_keyword("DISTINCT");
17475 self.write_space();
17476 }
17477
17478 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
17482 let needs_multi_arg_transform =
17483 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
17484
17485 if needs_multi_arg_transform {
17486 self.write_keyword("CASE");
17488 for arg in &func.args {
17489 self.write_space();
17490 self.write_keyword("WHEN");
17491 self.write_space();
17492 self.generate_expression(arg)?;
17493 self.write_space();
17494 self.write_keyword("IS NULL THEN NULL");
17495 }
17496 self.write_space();
17497 self.write_keyword("ELSE");
17498 self.write(" (");
17499 for (i, arg) in func.args.iter().enumerate() {
17500 if i > 0 {
17501 self.write(", ");
17502 }
17503 self.generate_expression(arg)?;
17504 }
17505 self.write(")");
17506 self.write_space();
17507 self.write_keyword("END");
17508 } else {
17509 for (i, arg) in func.args.iter().enumerate() {
17510 if i > 0 {
17511 self.write(", ");
17512 }
17513 self.generate_expression(arg)?;
17514 }
17515 }
17516
17517 if self.config.ignore_nulls_in_func
17519 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
17520 {
17521 if let Some(ignore) = func.ignore_nulls {
17522 self.write_space();
17523 if ignore {
17524 self.write_keyword("IGNORE NULLS");
17525 } else {
17526 self.write_keyword("RESPECT NULLS");
17527 }
17528 }
17529 }
17530
17531 if !func.order_by.is_empty() {
17533 self.write_space();
17534 self.write_keyword("ORDER BY");
17535 self.write_space();
17536 for (i, ord) in func.order_by.iter().enumerate() {
17537 if i > 0 {
17538 self.write(", ");
17539 }
17540 self.generate_ordered(ord)?;
17541 }
17542 }
17543
17544 if let Some(limit) = &func.limit {
17546 self.write_space();
17547 self.write_keyword("LIMIT");
17548 self.write_space();
17549 if let Expression::Tuple(t) = limit.as_ref() {
17551 if t.expressions.len() == 2 {
17552 self.generate_expression(&t.expressions[0])?;
17553 self.write(", ");
17554 self.generate_expression(&t.expressions[1])?;
17555 } else {
17556 self.generate_expression(limit)?;
17557 }
17558 } else {
17559 self.generate_expression(limit)?;
17560 }
17561 }
17562
17563 self.write(")");
17564
17565 if !self.config.ignore_nulls_in_func
17567 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
17568 {
17569 if let Some(ignore) = func.ignore_nulls {
17570 self.write_space();
17571 if ignore {
17572 self.write_keyword("IGNORE NULLS");
17573 } else {
17574 self.write_keyword("RESPECT NULLS");
17575 }
17576 }
17577 }
17578
17579 if let Some(filter) = &func.filter {
17580 self.write_space();
17581 self.write_keyword("FILTER");
17582 self.write("(");
17583 self.write_keyword("WHERE");
17584 self.write_space();
17585 self.generate_expression(filter)?;
17586 self.write(")");
17587 }
17588
17589 Ok(())
17590 }
17591
17592 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
17593 self.generate_expression(&wf.this)?;
17594
17595 if let Some(keep) = &wf.keep {
17597 self.write_space();
17598 self.write_keyword("KEEP");
17599 self.write(" (");
17600 self.write_keyword("DENSE_RANK");
17601 self.write_space();
17602 if keep.first {
17603 self.write_keyword("FIRST");
17604 } else {
17605 self.write_keyword("LAST");
17606 }
17607 self.write_space();
17608 self.write_keyword("ORDER BY");
17609 self.write_space();
17610 for (i, ord) in keep.order_by.iter().enumerate() {
17611 if i > 0 {
17612 self.write(", ");
17613 }
17614 self.generate_ordered(ord)?;
17615 }
17616 self.write(")");
17617 }
17618
17619 let has_over = !wf.over.partition_by.is_empty()
17621 || !wf.over.order_by.is_empty()
17622 || wf.over.frame.is_some()
17623 || wf.over.window_name.is_some();
17624
17625 if has_over {
17627 self.write_space();
17628 self.write_keyword("OVER");
17629
17630 let has_specs = !wf.over.partition_by.is_empty()
17632 || !wf.over.order_by.is_empty()
17633 || wf.over.frame.is_some();
17634
17635 if wf.over.window_name.is_some() && !has_specs {
17636 self.write_space();
17638 self.write(&wf.over.window_name.as_ref().unwrap().name);
17639 } else {
17640 self.write(" (");
17642 self.generate_over(&wf.over)?;
17643 self.write(")");
17644 }
17645 } else if wf.keep.is_none() {
17646 self.write_space();
17648 self.write_keyword("OVER");
17649 self.write(" ()");
17650 }
17651
17652 Ok(())
17653 }
17654
17655 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
17657 self.generate_expression(&wg.this)?;
17658 self.write_space();
17659 self.write_keyword("WITHIN GROUP");
17660 self.write(" (");
17661 self.write_keyword("ORDER BY");
17662 self.write_space();
17663 for (i, ord) in wg.order_by.iter().enumerate() {
17664 if i > 0 {
17665 self.write(", ");
17666 }
17667 self.generate_ordered(ord)?;
17668 }
17669 self.write(")");
17670 Ok(())
17671 }
17672
17673 fn generate_over(&mut self, over: &Over) -> Result<()> {
17675 let mut has_content = false;
17676
17677 if let Some(name) = &over.window_name {
17679 self.write(&name.name);
17680 has_content = true;
17681 }
17682
17683 if !over.partition_by.is_empty() {
17685 if has_content {
17686 self.write_space();
17687 }
17688 self.write_keyword("PARTITION BY");
17689 self.write_space();
17690 for (i, expr) in over.partition_by.iter().enumerate() {
17691 if i > 0 {
17692 self.write(", ");
17693 }
17694 self.generate_expression(expr)?;
17695 }
17696 has_content = true;
17697 }
17698
17699 if !over.order_by.is_empty() {
17701 if has_content {
17702 self.write_space();
17703 }
17704 self.write_keyword("ORDER BY");
17705 self.write_space();
17706 for (i, ordered) in over.order_by.iter().enumerate() {
17707 if i > 0 {
17708 self.write(", ");
17709 }
17710 self.generate_ordered(ordered)?;
17711 }
17712 has_content = true;
17713 }
17714
17715 if let Some(frame) = &over.frame {
17717 if has_content {
17718 self.write_space();
17719 }
17720 self.generate_window_frame(frame)?;
17721 }
17722
17723 Ok(())
17724 }
17725
17726 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
17727 let lowercase_frame = self.config.lowercase_window_frame_keywords;
17729
17730 if !lowercase_frame {
17732 if let Some(kind_text) = &frame.kind_text {
17733 self.write(kind_text);
17734 } else {
17735 match frame.kind {
17736 WindowFrameKind::Rows => self.write_keyword("ROWS"),
17737 WindowFrameKind::Range => self.write_keyword("RANGE"),
17738 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
17739 }
17740 }
17741 } else {
17742 match frame.kind {
17743 WindowFrameKind::Rows => self.write("rows"),
17744 WindowFrameKind::Range => self.write("range"),
17745 WindowFrameKind::Groups => self.write("groups"),
17746 }
17747 }
17748
17749 self.write_space();
17752 let should_normalize = self.config.normalize_window_frame_between
17753 && frame.end.is_none()
17754 && matches!(
17755 frame.start,
17756 WindowFrameBound::Preceding(_)
17757 | WindowFrameBound::Following(_)
17758 | WindowFrameBound::UnboundedPreceding
17759 | WindowFrameBound::UnboundedFollowing
17760 );
17761
17762 if let Some(end) = &frame.end {
17763 self.write_keyword("BETWEEN");
17765 self.write_space();
17766 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
17767 self.write_space();
17768 self.write_keyword("AND");
17769 self.write_space();
17770 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
17771 } else if should_normalize {
17772 self.write_keyword("BETWEEN");
17774 self.write_space();
17775 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
17776 self.write_space();
17777 self.write_keyword("AND");
17778 self.write_space();
17779 self.write_keyword("CURRENT ROW");
17780 } else {
17781 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
17783 }
17784
17785 if let Some(exclude) = &frame.exclude {
17787 self.write_space();
17788 self.write_keyword("EXCLUDE");
17789 self.write_space();
17790 match exclude {
17791 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
17792 WindowFrameExclude::Group => self.write_keyword("GROUP"),
17793 WindowFrameExclude::Ties => self.write_keyword("TIES"),
17794 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
17795 }
17796 }
17797
17798 Ok(())
17799 }
17800
17801 fn generate_window_frame_bound(
17802 &mut self,
17803 bound: &WindowFrameBound,
17804 side_text: Option<&str>,
17805 ) -> Result<()> {
17806 let lowercase_frame = self.config.lowercase_window_frame_keywords;
17808
17809 match bound {
17810 WindowFrameBound::CurrentRow => {
17811 self.write_keyword("CURRENT ROW");
17812 }
17813 WindowFrameBound::UnboundedPreceding => {
17814 self.write_keyword("UNBOUNDED");
17815 self.write_space();
17816 if lowercase_frame {
17817 self.write("preceding");
17818 } else if let Some(text) = side_text {
17819 self.write(text);
17820 } else {
17821 self.write_keyword("PRECEDING");
17822 }
17823 }
17824 WindowFrameBound::UnboundedFollowing => {
17825 self.write_keyword("UNBOUNDED");
17826 self.write_space();
17827 if lowercase_frame {
17828 self.write("following");
17829 } else if let Some(text) = side_text {
17830 self.write(text);
17831 } else {
17832 self.write_keyword("FOLLOWING");
17833 }
17834 }
17835 WindowFrameBound::Preceding(expr) => {
17836 self.generate_expression(expr)?;
17837 self.write_space();
17838 if lowercase_frame {
17839 self.write("preceding");
17840 } else if let Some(text) = side_text {
17841 self.write(text);
17842 } else {
17843 self.write_keyword("PRECEDING");
17844 }
17845 }
17846 WindowFrameBound::Following(expr) => {
17847 self.generate_expression(expr)?;
17848 self.write_space();
17849 if lowercase_frame {
17850 self.write("following");
17851 } else if let Some(text) = side_text {
17852 self.write(text);
17853 } else {
17854 self.write_keyword("FOLLOWING");
17855 }
17856 }
17857 WindowFrameBound::BarePreceding => {
17858 if lowercase_frame {
17859 self.write("preceding");
17860 } else if let Some(text) = side_text {
17861 self.write(text);
17862 } else {
17863 self.write_keyword("PRECEDING");
17864 }
17865 }
17866 WindowFrameBound::BareFollowing => {
17867 if lowercase_frame {
17868 self.write("following");
17869 } else if let Some(text) = side_text {
17870 self.write(text);
17871 } else {
17872 self.write_keyword("FOLLOWING");
17873 }
17874 }
17875 WindowFrameBound::Value(expr) => {
17876 self.generate_expression(expr)?;
17878 }
17879 }
17880 Ok(())
17881 }
17882
17883 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
17884 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
17887 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
17888 && !matches!(&interval.this, Some(Expression::Literal(_)));
17889
17890 if self.config.single_string_interval {
17893 if let (
17894 Some(Expression::Literal(lit)),
17895 Some(IntervalUnitSpec::Simple {
17896 ref unit,
17897 ref use_plural,
17898 }),
17899 ) = (&interval.this, &interval.unit)
17900 {
17901 if let Literal::String(ref val) = lit.as_ref() {
17902 self.write_keyword("INTERVAL");
17903 self.write_space();
17904 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
17905 let unit_str = self.interval_unit_str(unit, effective_plural);
17906 self.write("'");
17907 self.write(val);
17908 self.write(" ");
17909 self.write(&unit_str);
17910 self.write("'");
17911 return Ok(());
17912 }
17913 }
17914 }
17915
17916 if !skip_interval_keyword {
17917 self.write_keyword("INTERVAL");
17918 }
17919
17920 if let Some(ref value) = interval.this {
17922 if !skip_interval_keyword {
17923 self.write_space();
17924 }
17925 let needs_parens = interval.unit.is_some()
17929 && matches!(
17930 value,
17931 Expression::Add(_)
17932 | Expression::Sub(_)
17933 | Expression::Mul(_)
17934 | Expression::Div(_)
17935 | Expression::Mod(_)
17936 | Expression::BitwiseAnd(_)
17937 | Expression::BitwiseOr(_)
17938 | Expression::BitwiseXor(_)
17939 );
17940 if needs_parens {
17941 self.write("(");
17942 }
17943 self.generate_expression(value)?;
17944 if needs_parens {
17945 self.write(")");
17946 }
17947 }
17948
17949 if let Some(ref unit_spec) = interval.unit {
17951 self.write_space();
17952 self.write_interval_unit_spec(unit_spec)?;
17953 }
17954
17955 Ok(())
17956 }
17957
17958 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
17960 match (unit, use_plural) {
17961 (IntervalUnit::Year, false) => "YEAR",
17962 (IntervalUnit::Year, true) => "YEARS",
17963 (IntervalUnit::Quarter, false) => "QUARTER",
17964 (IntervalUnit::Quarter, true) => "QUARTERS",
17965 (IntervalUnit::Month, false) => "MONTH",
17966 (IntervalUnit::Month, true) => "MONTHS",
17967 (IntervalUnit::Week, false) => "WEEK",
17968 (IntervalUnit::Week, true) => "WEEKS",
17969 (IntervalUnit::Day, false) => "DAY",
17970 (IntervalUnit::Day, true) => "DAYS",
17971 (IntervalUnit::Hour, false) => "HOUR",
17972 (IntervalUnit::Hour, true) => "HOURS",
17973 (IntervalUnit::Minute, false) => "MINUTE",
17974 (IntervalUnit::Minute, true) => "MINUTES",
17975 (IntervalUnit::Second, false) => "SECOND",
17976 (IntervalUnit::Second, true) => "SECONDS",
17977 (IntervalUnit::Millisecond, false) => "MILLISECOND",
17978 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
17979 (IntervalUnit::Microsecond, false) => "MICROSECOND",
17980 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
17981 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
17982 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
17983 }
17984 }
17985
17986 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
17987 match unit_spec {
17988 IntervalUnitSpec::Simple { unit, use_plural } => {
17989 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
17991 self.write_simple_interval_unit(unit, effective_plural);
17992 }
17993 IntervalUnitSpec::Span(span) => {
17994 self.write_simple_interval_unit(&span.this, false);
17995 self.write_space();
17996 self.write_keyword("TO");
17997 self.write_space();
17998 self.write_simple_interval_unit(&span.expression, false);
17999 }
18000 IntervalUnitSpec::ExprSpan(span) => {
18001 self.generate_expression(&span.this)?;
18003 self.write_space();
18004 self.write_keyword("TO");
18005 self.write_space();
18006 self.generate_expression(&span.expression)?;
18007 }
18008 IntervalUnitSpec::Expr(expr) => {
18009 self.generate_expression(expr)?;
18010 }
18011 }
18012 Ok(())
18013 }
18014
18015 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
18016 match (unit, use_plural) {
18018 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
18019 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
18020 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
18021 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
18022 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
18023 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
18024 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
18025 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
18026 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
18027 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
18028 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
18029 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
18030 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
18031 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
18032 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
18033 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
18034 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
18035 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
18036 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
18037 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
18038 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
18039 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
18040 }
18041 }
18042
18043 fn write_redshift_date_part(&mut self, expr: &Expression) {
18046 let part_str = self.extract_date_part_string(expr);
18047 if let Some(part) = part_str {
18048 let normalized = self.normalize_date_part(&part);
18049 self.write_keyword(&normalized);
18050 } else {
18051 let _ = self.generate_expression(expr);
18053 }
18054 }
18055
18056 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
18059 let part_str = self.extract_date_part_string(expr);
18060 if let Some(part) = part_str {
18061 let normalized = self.normalize_date_part(&part);
18062 self.write("'");
18063 self.write(&normalized);
18064 self.write("'");
18065 } else {
18066 let _ = self.generate_expression(expr);
18068 }
18069 }
18070
18071 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
18073 match expr {
18074 Expression::Literal(lit)
18075 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
18076 {
18077 let crate::expressions::Literal::String(s) = lit.as_ref() else {
18078 unreachable!()
18079 };
18080 Some(s.clone())
18081 }
18082 Expression::Identifier(id) => Some(id.name.clone()),
18083 Expression::Var(v) => Some(v.this.clone()),
18084 Expression::Column(col) if col.table.is_none() => {
18085 Some(col.name.name.clone())
18087 }
18088 _ => None,
18089 }
18090 }
18091
18092 fn normalize_date_part(&self, part: &str) -> String {
18095 let mut buf = [0u8; 64];
18096 let lower: &str = if part.len() <= 64 {
18097 for (i, b) in part.bytes().enumerate() {
18098 buf[i] = b.to_ascii_lowercase();
18099 }
18100 std::str::from_utf8(&buf[..part.len()]).unwrap_or(part)
18101 } else {
18102 return part.to_ascii_uppercase();
18103 };
18104 match lower {
18105 "day" | "days" | "d" => "DAY".to_string(),
18106 "month" | "months" | "mon" | "mm" => "MONTH".to_string(),
18107 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
18108 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
18109 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
18110 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
18111 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
18112 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
18113 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
18114 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
18115 _ => part.to_ascii_uppercase(),
18116 }
18117 }
18118
18119 fn write_datetime_field(&mut self, field: &DateTimeField) {
18120 match field {
18121 DateTimeField::Year => self.write_keyword("YEAR"),
18122 DateTimeField::Month => self.write_keyword("MONTH"),
18123 DateTimeField::Day => self.write_keyword("DAY"),
18124 DateTimeField::Hour => self.write_keyword("HOUR"),
18125 DateTimeField::Minute => self.write_keyword("MINUTE"),
18126 DateTimeField::Second => self.write_keyword("SECOND"),
18127 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
18128 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
18129 DateTimeField::DayOfWeek => {
18130 let name = match self.config.dialect {
18131 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
18132 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "WEEKDAY",
18133 _ => "DOW",
18134 };
18135 self.write_keyword(name);
18136 }
18137 DateTimeField::DayOfYear => {
18138 let name = match self.config.dialect {
18139 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
18140 _ => "DOY",
18141 };
18142 self.write_keyword(name);
18143 }
18144 DateTimeField::Week => self.write_keyword("WEEK"),
18145 DateTimeField::WeekWithModifier(modifier) => {
18146 self.write_keyword("WEEK");
18147 self.write("(");
18148 self.write(modifier);
18149 self.write(")");
18150 }
18151 DateTimeField::Quarter => self.write_keyword("QUARTER"),
18152 DateTimeField::Epoch => self.write_keyword("EPOCH"),
18153 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
18154 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
18155 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
18156 DateTimeField::Date => self.write_keyword("DATE"),
18157 DateTimeField::Time => self.write_keyword("TIME"),
18158 DateTimeField::Custom(name) => self.write(name),
18159 }
18160 }
18161
18162 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
18164 match field {
18165 DateTimeField::Year => self.write("year"),
18166 DateTimeField::Month => self.write("month"),
18167 DateTimeField::Day => self.write("day"),
18168 DateTimeField::Hour => self.write("hour"),
18169 DateTimeField::Minute => self.write("minute"),
18170 DateTimeField::Second => self.write("second"),
18171 DateTimeField::Millisecond => self.write("millisecond"),
18172 DateTimeField::Microsecond => self.write("microsecond"),
18173 DateTimeField::DayOfWeek => self.write("dow"),
18174 DateTimeField::DayOfYear => self.write("doy"),
18175 DateTimeField::Week => self.write("week"),
18176 DateTimeField::WeekWithModifier(modifier) => {
18177 self.write("week(");
18178 self.write(modifier);
18179 self.write(")");
18180 }
18181 DateTimeField::Quarter => self.write("quarter"),
18182 DateTimeField::Epoch => self.write("epoch"),
18183 DateTimeField::Timezone => self.write("timezone"),
18184 DateTimeField::TimezoneHour => self.write("timezone_hour"),
18185 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
18186 DateTimeField::Date => self.write("date"),
18187 DateTimeField::Time => self.write("time"),
18188 DateTimeField::Custom(name) => self.write(name),
18189 }
18190 }
18191
18192 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
18195 self.write_keyword(name);
18196 self.write("(");
18197 self.generate_expression(arg)?;
18198 self.write(")");
18199 Ok(())
18200 }
18201
18202 fn generate_unary_func(
18204 &mut self,
18205 default_name: &str,
18206 f: &crate::expressions::UnaryFunc,
18207 ) -> Result<()> {
18208 let name = f.original_name.as_deref().unwrap_or(default_name);
18209 self.write_keyword(name);
18210 self.write("(");
18211 self.generate_expression(&f.this)?;
18212 self.write(")");
18213 Ok(())
18214 }
18215
18216 fn generate_sqrt_cbrt(
18218 &mut self,
18219 f: &crate::expressions::UnaryFunc,
18220 func_name: &str,
18221 _op: &str,
18222 ) -> Result<()> {
18223 self.write_keyword(func_name);
18226 self.write("(");
18227 self.generate_expression(&f.this)?;
18228 self.write(")");
18229 Ok(())
18230 }
18231
18232 fn generate_binary_func(
18233 &mut self,
18234 name: &str,
18235 arg1: &Expression,
18236 arg2: &Expression,
18237 ) -> Result<()> {
18238 self.write_keyword(name);
18239 self.write("(");
18240 self.generate_expression(arg1)?;
18241 self.write(", ");
18242 self.generate_expression(arg2)?;
18243 self.write(")");
18244 Ok(())
18245 }
18246
18247 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
18251 let func_name = f.name.as_deref().unwrap_or("CHAR");
18253 self.write_keyword(func_name);
18254 self.write("(");
18255 for (i, arg) in f.args.iter().enumerate() {
18256 if i > 0 {
18257 self.write(", ");
18258 }
18259 self.generate_expression(arg)?;
18260 }
18261 if let Some(ref charset) = f.charset {
18262 self.write(" ");
18263 self.write_keyword("USING");
18264 self.write(" ");
18265 self.write(charset);
18266 }
18267 self.write(")");
18268 Ok(())
18269 }
18270
18271 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
18272 use crate::dialects::DialectType;
18273
18274 match self.config.dialect {
18275 Some(DialectType::Teradata) => {
18276 self.generate_expression(&f.this)?;
18278 self.write(" ** ");
18279 self.generate_expression(&f.expression)?;
18280 Ok(())
18281 }
18282 _ => {
18283 self.generate_binary_func("POWER", &f.this, &f.expression)
18285 }
18286 }
18287 }
18288
18289 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
18290 self.write_func_name(name);
18291 self.write("(");
18292 for (i, arg) in args.iter().enumerate() {
18293 if i > 0 {
18294 self.write(", ");
18295 }
18296 self.generate_expression(arg)?;
18297 }
18298 self.write(")");
18299 Ok(())
18300 }
18301
18302 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
18305 self.write_keyword("CONCAT_WS");
18306 self.write("(");
18307 self.generate_expression(&f.separator)?;
18308 for expr in &f.expressions {
18309 self.write(", ");
18310 self.generate_expression(expr)?;
18311 }
18312 self.write(")");
18313 Ok(())
18314 }
18315
18316 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
18317 if let Expression::Concat(op) = expr {
18318 Self::collect_concat_operands(&op.left, out);
18319 Self::collect_concat_operands(&op.right, out);
18320 } else {
18321 out.push(expr);
18322 }
18323 }
18324
18325 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
18326 let mut operands = Vec::new();
18327 Self::collect_concat_operands(&op.left, &mut operands);
18328 Self::collect_concat_operands(&op.right, &mut operands);
18329
18330 self.write_keyword("CONCAT");
18331 self.write("(");
18332 for (i, operand) in operands.iter().enumerate() {
18333 if i > 0 {
18334 self.write(", ");
18335 }
18336 self.generate_expression(operand)?;
18337 }
18338 self.write(")");
18339 Ok(())
18340 }
18341
18342 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
18343 if let Expression::DPipe(dpipe) = expr {
18344 Self::collect_dpipe_operands(&dpipe.this, out);
18345 Self::collect_dpipe_operands(&dpipe.expression, out);
18346 } else {
18347 out.push(expr);
18348 }
18349 }
18350
18351 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
18352 let mut operands = Vec::new();
18353 Self::collect_dpipe_operands(&e.this, &mut operands);
18354 Self::collect_dpipe_operands(&e.expression, &mut operands);
18355
18356 self.write_keyword("CONCAT");
18357 self.write("(");
18358 for (i, operand) in operands.iter().enumerate() {
18359 if i > 0 {
18360 self.write(", ");
18361 }
18362 self.generate_expression(operand)?;
18363 }
18364 self.write(")");
18365 Ok(())
18366 }
18367
18368 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
18369 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
18371 if is_oracle {
18372 self.write_keyword("SUBSTR");
18373 } else {
18374 self.write_keyword("SUBSTRING");
18375 }
18376 self.write("(");
18377 self.generate_expression(&f.this)?;
18378 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
18380 let use_comma_syntax = matches!(
18382 self.config.dialect,
18383 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
18384 );
18385 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
18386 self.write_space();
18388 self.write_keyword("FROM");
18389 self.write_space();
18390 self.generate_expression(&f.start)?;
18391 if let Some(length) = &f.length {
18392 self.write_space();
18393 self.write_keyword("FOR");
18394 self.write_space();
18395 self.generate_expression(length)?;
18396 }
18397 } else {
18398 self.write(", ");
18400 self.generate_expression(&f.start)?;
18401 if let Some(length) = &f.length {
18402 self.write(", ");
18403 self.generate_expression(length)?;
18404 }
18405 }
18406 self.write(")");
18407 Ok(())
18408 }
18409
18410 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
18411 self.write_keyword("OVERLAY");
18412 self.write("(");
18413 self.generate_expression(&f.this)?;
18414 self.write_space();
18415 self.write_keyword("PLACING");
18416 self.write_space();
18417 self.generate_expression(&f.replacement)?;
18418 self.write_space();
18419 self.write_keyword("FROM");
18420 self.write_space();
18421 self.generate_expression(&f.from)?;
18422 if let Some(length) = &f.length {
18423 self.write_space();
18424 self.write_keyword("FOR");
18425 self.write_space();
18426 self.generate_expression(length)?;
18427 }
18428 self.write(")");
18429 Ok(())
18430 }
18431
18432 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
18433 if f.position_explicit && f.characters.is_none() {
18436 match f.position {
18437 TrimPosition::Leading => {
18438 self.write_keyword("LTRIM");
18439 self.write("(");
18440 self.generate_expression(&f.this)?;
18441 self.write(")");
18442 return Ok(());
18443 }
18444 TrimPosition::Trailing => {
18445 self.write_keyword("RTRIM");
18446 self.write("(");
18447 self.generate_expression(&f.this)?;
18448 self.write(")");
18449 return Ok(());
18450 }
18451 TrimPosition::Both => {
18452 }
18455 }
18456 }
18457
18458 self.write_keyword("TRIM");
18459 self.write("(");
18460 let force_standard = f.characters.is_some()
18463 && !f.sql_standard_syntax
18464 && matches!(
18465 self.config.dialect,
18466 Some(DialectType::Hive)
18467 | Some(DialectType::Spark)
18468 | Some(DialectType::Databricks)
18469 | Some(DialectType::ClickHouse)
18470 );
18471 let use_standard = (f.sql_standard_syntax || force_standard)
18472 && !(f.position_explicit
18473 && f.characters.is_none()
18474 && matches!(f.position, TrimPosition::Both));
18475 if use_standard {
18476 if f.position_explicit {
18479 match f.position {
18480 TrimPosition::Both => self.write_keyword("BOTH"),
18481 TrimPosition::Leading => self.write_keyword("LEADING"),
18482 TrimPosition::Trailing => self.write_keyword("TRAILING"),
18483 }
18484 self.write_space();
18485 }
18486 if let Some(chars) = &f.characters {
18487 self.generate_expression(chars)?;
18488 self.write_space();
18489 }
18490 self.write_keyword("FROM");
18491 self.write_space();
18492 self.generate_expression(&f.this)?;
18493 } else {
18494 self.generate_expression(&f.this)?;
18496 if let Some(chars) = &f.characters {
18497 self.write(", ");
18498 self.generate_expression(chars)?;
18499 }
18500 }
18501 self.write(")");
18502 Ok(())
18503 }
18504
18505 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
18506 self.write_keyword("REPLACE");
18507 self.write("(");
18508 self.generate_expression(&f.this)?;
18509 self.write(", ");
18510 self.generate_expression(&f.old)?;
18511 self.write(", ");
18512 self.generate_expression(&f.new)?;
18513 self.write(")");
18514 Ok(())
18515 }
18516
18517 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
18518 self.write_keyword(name);
18519 self.write("(");
18520 self.generate_expression(&f.this)?;
18521 self.write(", ");
18522 self.generate_expression(&f.length)?;
18523 self.write(")");
18524 Ok(())
18525 }
18526
18527 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
18528 self.write_keyword("REPEAT");
18529 self.write("(");
18530 self.generate_expression(&f.this)?;
18531 self.write(", ");
18532 self.generate_expression(&f.times)?;
18533 self.write(")");
18534 Ok(())
18535 }
18536
18537 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
18538 self.write_keyword(name);
18539 self.write("(");
18540 self.generate_expression(&f.this)?;
18541 self.write(", ");
18542 self.generate_expression(&f.length)?;
18543 if let Some(fill) = &f.fill {
18544 self.write(", ");
18545 self.generate_expression(fill)?;
18546 }
18547 self.write(")");
18548 Ok(())
18549 }
18550
18551 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
18552 self.write_keyword("SPLIT");
18553 self.write("(");
18554 self.generate_expression(&f.this)?;
18555 self.write(", ");
18556 self.generate_expression(&f.delimiter)?;
18557 self.write(")");
18558 Ok(())
18559 }
18560
18561 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
18562 use crate::dialects::DialectType;
18563 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
18565 self.generate_expression(&f.this)?;
18566 self.write(" ~ ");
18567 self.generate_expression(&f.pattern)?;
18568 } else if matches!(self.config.dialect, Some(DialectType::Exasol)) && f.flags.is_none() {
18569 self.generate_expression(&f.this)?;
18571 self.write_keyword(" REGEXP_LIKE ");
18572 self.generate_expression(&f.pattern)?;
18573 } else if matches!(
18574 self.config.dialect,
18575 Some(DialectType::SingleStore)
18576 | Some(DialectType::Spark)
18577 | Some(DialectType::Hive)
18578 | Some(DialectType::Databricks)
18579 ) && f.flags.is_none()
18580 {
18581 self.generate_expression(&f.this)?;
18583 self.write_keyword(" RLIKE ");
18584 self.generate_expression(&f.pattern)?;
18585 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
18586 self.write_keyword("REGEXP");
18588 self.write("(");
18589 self.generate_expression(&f.this)?;
18590 self.write(", ");
18591 self.generate_expression(&f.pattern)?;
18592 if let Some(flags) = &f.flags {
18593 self.write(", ");
18594 self.generate_expression(flags)?;
18595 }
18596 self.write(")");
18597 } else {
18598 self.write_keyword("REGEXP_LIKE");
18599 self.write("(");
18600 self.generate_expression(&f.this)?;
18601 self.write(", ");
18602 self.generate_expression(&f.pattern)?;
18603 if let Some(flags) = &f.flags {
18604 self.write(", ");
18605 self.generate_expression(flags)?;
18606 }
18607 self.write(")");
18608 }
18609 Ok(())
18610 }
18611
18612 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
18613 self.write_keyword("REGEXP_REPLACE");
18614 self.write("(");
18615 self.generate_expression(&f.this)?;
18616 self.write(", ");
18617 self.generate_expression(&f.pattern)?;
18618 self.write(", ");
18619 self.generate_expression(&f.replacement)?;
18620 if let Some(flags) = &f.flags {
18621 self.write(", ");
18622 self.generate_expression(flags)?;
18623 }
18624 self.write(")");
18625 Ok(())
18626 }
18627
18628 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
18629 self.write_keyword("REGEXP_EXTRACT");
18630 self.write("(");
18631 self.generate_expression(&f.this)?;
18632 self.write(", ");
18633 self.generate_expression(&f.pattern)?;
18634 if let Some(group) = &f.group {
18635 self.write(", ");
18636 self.generate_expression(group)?;
18637 }
18638 self.write(")");
18639 Ok(())
18640 }
18641
18642 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
18645 self.write_keyword("ROUND");
18646 self.write("(");
18647 self.generate_expression(&f.this)?;
18648 if let Some(decimals) = &f.decimals {
18649 self.write(", ");
18650 self.generate_expression(decimals)?;
18651 }
18652 self.write(")");
18653 Ok(())
18654 }
18655
18656 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
18657 self.write_keyword("FLOOR");
18658 self.write("(");
18659 self.generate_expression(&f.this)?;
18660 if let Some(to) = &f.to {
18662 self.write(" ");
18663 self.write_keyword("TO");
18664 self.write(" ");
18665 self.generate_expression(to)?;
18666 } else if let Some(scale) = &f.scale {
18667 self.write(", ");
18668 self.generate_expression(scale)?;
18669 }
18670 self.write(")");
18671 Ok(())
18672 }
18673
18674 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
18675 self.write_keyword("CEIL");
18676 self.write("(");
18677 self.generate_expression(&f.this)?;
18678 if let Some(to) = &f.to {
18680 self.write(" ");
18681 self.write_keyword("TO");
18682 self.write(" ");
18683 self.generate_expression(to)?;
18684 } else if let Some(decimals) = &f.decimals {
18685 self.write(", ");
18686 self.generate_expression(decimals)?;
18687 }
18688 self.write(")");
18689 Ok(())
18690 }
18691
18692 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
18693 use crate::expressions::Literal;
18694
18695 if let Some(base) = &f.base {
18696 if self.is_log_base_none() {
18699 if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "2"))
18700 {
18701 self.write_func_name("LOG2");
18702 self.write("(");
18703 self.generate_expression(&f.this)?;
18704 self.write(")");
18705 return Ok(());
18706 } else if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "10"))
18707 {
18708 self.write_func_name("LOG10");
18709 self.write("(");
18710 self.generate_expression(&f.this)?;
18711 self.write(")");
18712 return Ok(());
18713 }
18714 }
18716
18717 self.write_func_name("LOG");
18718 self.write("(");
18719 if self.is_log_value_first() {
18720 self.generate_expression(&f.this)?;
18722 self.write(", ");
18723 self.generate_expression(base)?;
18724 } else {
18725 self.generate_expression(base)?;
18727 self.write(", ");
18728 self.generate_expression(&f.this)?;
18729 }
18730 self.write(")");
18731 } else {
18732 self.write_func_name("LOG");
18734 self.write("(");
18735 self.generate_expression(&f.this)?;
18736 self.write(")");
18737 }
18738 Ok(())
18739 }
18740
18741 fn is_log_value_first(&self) -> bool {
18744 use crate::dialects::DialectType;
18745 matches!(
18746 self.config.dialect,
18747 Some(DialectType::BigQuery)
18748 | Some(DialectType::TSQL)
18749 | Some(DialectType::Tableau)
18750 | Some(DialectType::Fabric)
18751 )
18752 }
18753
18754 fn is_log_base_none(&self) -> bool {
18757 use crate::dialects::DialectType;
18758 matches!(
18759 self.config.dialect,
18760 Some(DialectType::Presto)
18761 | Some(DialectType::Trino)
18762 | Some(DialectType::ClickHouse)
18763 | Some(DialectType::Athena)
18764 )
18765 }
18766
18767 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
18770 self.write_keyword("CURRENT_TIME");
18771 if let Some(precision) = f.precision {
18772 self.write(&format!("({})", precision));
18773 } else if matches!(
18774 self.config.dialect,
18775 Some(crate::dialects::DialectType::MySQL)
18776 | Some(crate::dialects::DialectType::SingleStore)
18777 | Some(crate::dialects::DialectType::TiDB)
18778 ) {
18779 self.write("()");
18780 }
18781 Ok(())
18782 }
18783
18784 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
18785 use crate::dialects::DialectType;
18786
18787 if f.sysdate {
18789 match self.config.dialect {
18790 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
18791 self.write_keyword("SYSDATE");
18792 return Ok(());
18793 }
18794 Some(DialectType::Snowflake) => {
18795 self.write_keyword("SYSDATE");
18797 self.write("()");
18798 return Ok(());
18799 }
18800 _ => {
18801 }
18803 }
18804 }
18805
18806 self.write_keyword("CURRENT_TIMESTAMP");
18807 if let Some(precision) = f.precision {
18809 self.write(&format!("({})", precision));
18810 } else if matches!(
18811 self.config.dialect,
18812 Some(crate::dialects::DialectType::MySQL)
18813 | Some(crate::dialects::DialectType::SingleStore)
18814 | Some(crate::dialects::DialectType::TiDB)
18815 | Some(crate::dialects::DialectType::Spark)
18816 | Some(crate::dialects::DialectType::Hive)
18817 | Some(crate::dialects::DialectType::Databricks)
18818 | Some(crate::dialects::DialectType::ClickHouse)
18819 | Some(crate::dialects::DialectType::BigQuery)
18820 | Some(crate::dialects::DialectType::Snowflake)
18821 | Some(crate::dialects::DialectType::Exasol)
18822 ) {
18823 self.write("()");
18824 }
18825 Ok(())
18826 }
18827
18828 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
18829 if self.config.dialect == Some(DialectType::Exasol) {
18831 self.write_keyword("CONVERT_TZ");
18832 self.write("(");
18833 self.generate_expression(&f.this)?;
18834 self.write(", 'UTC', ");
18835 self.generate_expression(&f.zone)?;
18836 self.write(")");
18837 return Ok(());
18838 }
18839
18840 self.generate_expression(&f.this)?;
18841 self.write_space();
18842 self.write_keyword("AT TIME ZONE");
18843 self.write_space();
18844 self.generate_expression(&f.zone)?;
18845 Ok(())
18846 }
18847
18848 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
18849 use crate::dialects::DialectType;
18850
18851 let is_presto_like = matches!(
18854 self.config.dialect,
18855 Some(DialectType::Presto) | Some(DialectType::Trino)
18856 );
18857
18858 if is_presto_like {
18859 self.write_keyword(name);
18860 self.write("(");
18861 self.write("'");
18863 self.write_simple_interval_unit(&f.unit, false);
18864 self.write("'");
18865 self.write(", ");
18866 let needs_cast = !self.returns_integer_type(&f.interval);
18868 if needs_cast {
18869 self.write_keyword("CAST");
18870 self.write("(");
18871 }
18872 self.generate_expression(&f.interval)?;
18873 if needs_cast {
18874 self.write_space();
18875 self.write_keyword("AS");
18876 self.write_space();
18877 self.write_keyword("BIGINT");
18878 self.write(")");
18879 }
18880 self.write(", ");
18881 self.generate_expression(&f.this)?;
18882 self.write(")");
18883 } else {
18884 self.write_keyword(name);
18885 self.write("(");
18886 self.generate_expression(&f.this)?;
18887 self.write(", ");
18888 self.write_keyword("INTERVAL");
18889 self.write_space();
18890 self.generate_expression(&f.interval)?;
18891 self.write_space();
18892 self.write_simple_interval_unit(&f.unit, false); self.write(")");
18894 }
18895 Ok(())
18896 }
18897
18898 fn returns_integer_type(&self, expr: &Expression) -> bool {
18901 use crate::expressions::{DataType, Literal};
18902 match expr {
18903 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
18905 let Literal::Number(n) = lit.as_ref() else {
18906 unreachable!()
18907 };
18908 !n.contains('.')
18909 }
18910
18911 Expression::Floor(f) => self.returns_integer_type(&f.this),
18913
18914 Expression::Round(f) => {
18916 f.decimals.is_none() && self.returns_integer_type(&f.this)
18918 }
18919
18920 Expression::Sign(f) => self.returns_integer_type(&f.this),
18922
18923 Expression::Abs(f) => self.returns_integer_type(&f.this),
18925
18926 Expression::Mul(op) => {
18928 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
18929 }
18930 Expression::Add(op) => {
18931 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
18932 }
18933 Expression::Sub(op) => {
18934 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
18935 }
18936 Expression::Mod(op) => self.returns_integer_type(&op.left),
18937
18938 Expression::Cast(c) => matches!(
18940 &c.to,
18941 DataType::BigInt { .. }
18942 | DataType::Int { .. }
18943 | DataType::SmallInt { .. }
18944 | DataType::TinyInt { .. }
18945 ),
18946
18947 Expression::Neg(op) => self.returns_integer_type(&op.this),
18949
18950 Expression::Paren(p) => self.returns_integer_type(&p.this),
18952
18953 _ => false,
18956 }
18957 }
18958
18959 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
18960 self.write_keyword("DATEDIFF");
18961 self.write("(");
18962 if let Some(unit) = &f.unit {
18963 self.write_simple_interval_unit(unit, false); self.write(", ");
18965 }
18966 self.generate_expression(&f.this)?;
18967 self.write(", ");
18968 self.generate_expression(&f.expression)?;
18969 self.write(")");
18970 Ok(())
18971 }
18972
18973 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
18974 self.write_keyword("DATE_TRUNC");
18975 self.write("('");
18976 self.write_datetime_field(&f.unit);
18977 self.write("', ");
18978 self.generate_expression(&f.this)?;
18979 self.write(")");
18980 Ok(())
18981 }
18982
18983 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
18984 use crate::dialects::DialectType;
18985 use crate::expressions::DateTimeField;
18986
18987 self.write_keyword("LAST_DAY");
18988 self.write("(");
18989 self.generate_expression(&f.this)?;
18990 if let Some(unit) = &f.unit {
18991 self.write(", ");
18992 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
18995 if let DateTimeField::WeekWithModifier(_) = unit {
18996 self.write_keyword("WEEK");
18997 } else {
18998 self.write_datetime_field(unit);
18999 }
19000 } else {
19001 self.write_datetime_field(unit);
19002 }
19003 }
19004 self.write(")");
19005 Ok(())
19006 }
19007
19008 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
19009 if matches!(
19011 self.config.dialect,
19012 Some(DialectType::TSQL) | Some(DialectType::Fabric)
19013 ) {
19014 self.write_keyword("DATEPART");
19015 self.write("(");
19016 self.write_datetime_field(&f.field);
19017 self.write(", ");
19018 self.generate_expression(&f.this)?;
19019 self.write(")");
19020 return Ok(());
19021 }
19022 self.write_keyword("EXTRACT");
19023 self.write("(");
19024 if matches!(
19026 self.config.dialect,
19027 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
19028 ) {
19029 self.write_datetime_field_lower(&f.field);
19030 } else {
19031 self.write_datetime_field(&f.field);
19032 }
19033 self.write_space();
19034 self.write_keyword("FROM");
19035 self.write_space();
19036 self.generate_expression(&f.this)?;
19037 self.write(")");
19038 Ok(())
19039 }
19040
19041 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
19042 self.write_keyword("TO_DATE");
19043 self.write("(");
19044 self.generate_expression(&f.this)?;
19045 if let Some(format) = &f.format {
19046 self.write(", ");
19047 self.generate_expression(format)?;
19048 }
19049 self.write(")");
19050 Ok(())
19051 }
19052
19053 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
19054 self.write_keyword("TO_TIMESTAMP");
19055 self.write("(");
19056 self.generate_expression(&f.this)?;
19057 if let Some(format) = &f.format {
19058 self.write(", ");
19059 self.generate_expression(format)?;
19060 }
19061 self.write(")");
19062 Ok(())
19063 }
19064
19065 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
19068 use crate::dialects::DialectType;
19069
19070 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
19072 self.write_keyword("CASE WHEN");
19073 self.write_space();
19074 self.generate_expression(&f.condition)?;
19075 self.write_space();
19076 self.write_keyword("THEN");
19077 self.write_space();
19078 self.generate_expression(&f.true_value)?;
19079 if let Some(false_val) = &f.false_value {
19080 self.write_space();
19081 self.write_keyword("ELSE");
19082 self.write_space();
19083 self.generate_expression(false_val)?;
19084 }
19085 self.write_space();
19086 self.write_keyword("END");
19087 return Ok(());
19088 }
19089
19090 if self.config.dialect == Some(DialectType::Exasol) {
19092 self.write_keyword("IF");
19093 self.write_space();
19094 self.generate_expression(&f.condition)?;
19095 self.write_space();
19096 self.write_keyword("THEN");
19097 self.write_space();
19098 self.generate_expression(&f.true_value)?;
19099 if let Some(false_val) = &f.false_value {
19100 self.write_space();
19101 self.write_keyword("ELSE");
19102 self.write_space();
19103 self.generate_expression(false_val)?;
19104 }
19105 self.write_space();
19106 self.write_keyword("ENDIF");
19107 return Ok(());
19108 }
19109
19110 let func_name = match self.config.dialect {
19112 Some(DialectType::Snowflake) => "IFF",
19113 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
19114 Some(DialectType::Drill) => "`IF`",
19115 _ => "IF",
19116 };
19117 self.write(func_name);
19118 self.write("(");
19119 self.generate_expression(&f.condition)?;
19120 self.write(", ");
19121 self.generate_expression(&f.true_value)?;
19122 if let Some(false_val) = &f.false_value {
19123 self.write(", ");
19124 self.generate_expression(false_val)?;
19125 }
19126 self.write(")");
19127 Ok(())
19128 }
19129
19130 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
19131 self.write_keyword("NVL2");
19132 self.write("(");
19133 self.generate_expression(&f.this)?;
19134 self.write(", ");
19135 self.generate_expression(&f.true_value)?;
19136 self.write(", ");
19137 self.generate_expression(&f.false_value)?;
19138 self.write(")");
19139 Ok(())
19140 }
19141
19142 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
19145 let count_name = match self.config.normalize_functions {
19147 NormalizeFunctions::Upper => "COUNT".to_string(),
19148 NormalizeFunctions::Lower => "count".to_string(),
19149 NormalizeFunctions::None => f
19150 .original_name
19151 .clone()
19152 .unwrap_or_else(|| "COUNT".to_string()),
19153 };
19154 self.write(&count_name);
19155 self.write("(");
19156 if f.distinct {
19157 self.write_keyword("DISTINCT");
19158 self.write_space();
19159 }
19160 if f.star {
19161 self.write("*");
19162 } else if let Some(ref expr) = f.this {
19163 if let Expression::Tuple(tuple) = expr {
19165 let needs_transform =
19169 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
19170
19171 if needs_transform {
19172 self.write_keyword("CASE");
19174 for e in &tuple.expressions {
19175 self.write_space();
19176 self.write_keyword("WHEN");
19177 self.write_space();
19178 self.generate_expression(e)?;
19179 self.write_space();
19180 self.write_keyword("IS NULL THEN NULL");
19181 }
19182 self.write_space();
19183 self.write_keyword("ELSE");
19184 self.write(" (");
19185 for (i, e) in tuple.expressions.iter().enumerate() {
19186 if i > 0 {
19187 self.write(", ");
19188 }
19189 self.generate_expression(e)?;
19190 }
19191 self.write(")");
19192 self.write_space();
19193 self.write_keyword("END");
19194 } else {
19195 for (i, e) in tuple.expressions.iter().enumerate() {
19196 if i > 0 {
19197 self.write(", ");
19198 }
19199 self.generate_expression(e)?;
19200 }
19201 }
19202 } else {
19203 self.generate_expression(expr)?;
19204 }
19205 }
19206 if let Some(ignore) = f.ignore_nulls {
19208 self.write_space();
19209 if ignore {
19210 self.write_keyword("IGNORE NULLS");
19211 } else {
19212 self.write_keyword("RESPECT NULLS");
19213 }
19214 }
19215 self.write(")");
19216 if let Some(ref filter) = f.filter {
19217 self.write_space();
19218 self.write_keyword("FILTER");
19219 self.write("(");
19220 self.write_keyword("WHERE");
19221 self.write_space();
19222 self.generate_expression(filter)?;
19223 self.write(")");
19224 }
19225 Ok(())
19226 }
19227
19228 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
19229 let func_name: Cow<'_, str> = match self.config.normalize_functions {
19231 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
19232 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
19233 NormalizeFunctions::None => {
19234 if let Some(ref original) = f.name {
19237 Cow::Owned(original.clone())
19238 } else {
19239 Cow::Owned(name.to_ascii_lowercase())
19240 }
19241 }
19242 };
19243 self.write(func_name.as_ref());
19244 self.write("(");
19245 if f.distinct {
19246 self.write_keyword("DISTINCT");
19247 self.write_space();
19248 }
19249 if !matches!(f.this, Expression::Null(_)) {
19251 self.generate_expression(&f.this)?;
19252 }
19253 if self.config.ignore_nulls_in_func
19256 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19257 {
19258 match f.ignore_nulls {
19259 Some(true) => {
19260 self.write_space();
19261 self.write_keyword("IGNORE NULLS");
19262 }
19263 Some(false) => {
19264 self.write_space();
19265 self.write_keyword("RESPECT NULLS");
19266 }
19267 None => {}
19268 }
19269 }
19270 if let Some((ref expr, is_max)) = f.having_max {
19273 self.write_space();
19274 self.write_keyword("HAVING");
19275 self.write_space();
19276 if is_max {
19277 self.write_keyword("MAX");
19278 } else {
19279 self.write_keyword("MIN");
19280 }
19281 self.write_space();
19282 self.generate_expression(expr)?;
19283 }
19284 if !f.order_by.is_empty() {
19286 self.write_space();
19287 self.write_keyword("ORDER BY");
19288 self.write_space();
19289 for (i, ord) in f.order_by.iter().enumerate() {
19290 if i > 0 {
19291 self.write(", ");
19292 }
19293 self.generate_ordered(ord)?;
19294 }
19295 }
19296 if let Some(ref limit) = f.limit {
19298 self.write_space();
19299 self.write_keyword("LIMIT");
19300 self.write_space();
19301 if let Expression::Tuple(t) = limit.as_ref() {
19303 if t.expressions.len() == 2 {
19304 self.generate_expression(&t.expressions[0])?;
19305 self.write(", ");
19306 self.generate_expression(&t.expressions[1])?;
19307 } else {
19308 self.generate_expression(limit)?;
19309 }
19310 } else {
19311 self.generate_expression(limit)?;
19312 }
19313 }
19314 self.write(")");
19315 if !self.config.ignore_nulls_in_func
19318 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19319 {
19320 match f.ignore_nulls {
19321 Some(true) => {
19322 self.write_space();
19323 self.write_keyword("IGNORE NULLS");
19324 }
19325 Some(false) => {
19326 self.write_space();
19327 self.write_keyword("RESPECT NULLS");
19328 }
19329 None => {}
19330 }
19331 }
19332 if let Some(ref filter) = f.filter {
19333 self.write_space();
19334 self.write_keyword("FILTER");
19335 self.write("(");
19336 self.write_keyword("WHERE");
19337 self.write_space();
19338 self.generate_expression(filter)?;
19339 self.write(")");
19340 }
19341 Ok(())
19342 }
19343
19344 fn generate_agg_func_with_ignore_nulls_bool(&mut self, name: &str, f: &AggFunc) -> Result<()> {
19347 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
19349 let func_name: Cow<'_, str> = match self.config.normalize_functions {
19351 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
19352 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
19353 NormalizeFunctions::None => {
19354 if let Some(ref original) = f.name {
19355 Cow::Owned(original.clone())
19356 } else {
19357 Cow::Owned(name.to_ascii_lowercase())
19358 }
19359 }
19360 };
19361 self.write(func_name.as_ref());
19362 self.write("(");
19363 if f.distinct {
19364 self.write_keyword("DISTINCT");
19365 self.write_space();
19366 }
19367 if !matches!(f.this, Expression::Null(_)) {
19368 self.generate_expression(&f.this)?;
19369 }
19370 self.write(", ");
19371 self.write_keyword("TRUE");
19372 self.write(")");
19373 return Ok(());
19374 }
19375 self.generate_agg_func(name, f)
19376 }
19377
19378 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
19379 self.write_keyword("GROUP_CONCAT");
19380 self.write("(");
19381 if f.distinct {
19382 self.write_keyword("DISTINCT");
19383 self.write_space();
19384 }
19385 self.generate_expression(&f.this)?;
19386 if let Some(ref order_by) = f.order_by {
19387 self.write_space();
19388 self.write_keyword("ORDER BY");
19389 self.write_space();
19390 for (i, ord) in order_by.iter().enumerate() {
19391 if i > 0 {
19392 self.write(", ");
19393 }
19394 self.generate_ordered(ord)?;
19395 }
19396 }
19397 if let Some(ref sep) = f.separator {
19398 if matches!(
19401 self.config.dialect,
19402 Some(crate::dialects::DialectType::SQLite)
19403 ) {
19404 self.write(", ");
19405 self.generate_expression(sep)?;
19406 } else {
19407 self.write_space();
19408 self.write_keyword("SEPARATOR");
19409 self.write_space();
19410 self.generate_expression(sep)?;
19411 }
19412 }
19413 if let Some(ref limit) = f.limit {
19414 self.write_space();
19415 self.write_keyword("LIMIT");
19416 self.write_space();
19417 self.generate_expression(limit)?;
19418 }
19419 self.write(")");
19420 if let Some(ref filter) = f.filter {
19421 self.write_space();
19422 self.write_keyword("FILTER");
19423 self.write("(");
19424 self.write_keyword("WHERE");
19425 self.write_space();
19426 self.generate_expression(filter)?;
19427 self.write(")");
19428 }
19429 Ok(())
19430 }
19431
19432 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
19433 let is_tsql = matches!(
19434 self.config.dialect,
19435 Some(crate::dialects::DialectType::TSQL)
19436 );
19437 self.write_keyword("STRING_AGG");
19438 self.write("(");
19439 if f.distinct {
19440 self.write_keyword("DISTINCT");
19441 self.write_space();
19442 }
19443 self.generate_expression(&f.this)?;
19444 if let Some(ref separator) = f.separator {
19445 self.write(", ");
19446 self.generate_expression(separator)?;
19447 }
19448 if !is_tsql {
19450 if let Some(ref order_by) = f.order_by {
19451 self.write_space();
19452 self.write_keyword("ORDER BY");
19453 self.write_space();
19454 for (i, ord) in order_by.iter().enumerate() {
19455 if i > 0 {
19456 self.write(", ");
19457 }
19458 self.generate_ordered(ord)?;
19459 }
19460 }
19461 }
19462 if let Some(ref limit) = f.limit {
19463 self.write_space();
19464 self.write_keyword("LIMIT");
19465 self.write_space();
19466 self.generate_expression(limit)?;
19467 }
19468 self.write(")");
19469 if is_tsql {
19471 if let Some(ref order_by) = f.order_by {
19472 self.write_space();
19473 self.write_keyword("WITHIN GROUP");
19474 self.write(" (");
19475 self.write_keyword("ORDER BY");
19476 self.write_space();
19477 for (i, ord) in order_by.iter().enumerate() {
19478 if i > 0 {
19479 self.write(", ");
19480 }
19481 self.generate_ordered(ord)?;
19482 }
19483 self.write(")");
19484 }
19485 }
19486 if let Some(ref filter) = f.filter {
19487 self.write_space();
19488 self.write_keyword("FILTER");
19489 self.write("(");
19490 self.write_keyword("WHERE");
19491 self.write_space();
19492 self.generate_expression(filter)?;
19493 self.write(")");
19494 }
19495 Ok(())
19496 }
19497
19498 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
19499 use crate::dialects::DialectType;
19500 self.write_keyword("LISTAGG");
19501 self.write("(");
19502 if f.distinct {
19503 self.write_keyword("DISTINCT");
19504 self.write_space();
19505 }
19506 self.generate_expression(&f.this)?;
19507 if let Some(ref sep) = f.separator {
19508 self.write(", ");
19509 self.generate_expression(sep)?;
19510 } else if matches!(
19511 self.config.dialect,
19512 Some(DialectType::Trino) | Some(DialectType::Presto)
19513 ) {
19514 self.write(", ','");
19516 }
19517 if let Some(ref overflow) = f.on_overflow {
19518 self.write_space();
19519 self.write_keyword("ON OVERFLOW");
19520 self.write_space();
19521 match overflow {
19522 ListAggOverflow::Error => self.write_keyword("ERROR"),
19523 ListAggOverflow::Truncate { filler, with_count } => {
19524 self.write_keyword("TRUNCATE");
19525 if let Some(ref fill) = filler {
19526 self.write_space();
19527 self.generate_expression(fill)?;
19528 }
19529 if *with_count {
19530 self.write_space();
19531 self.write_keyword("WITH COUNT");
19532 } else {
19533 self.write_space();
19534 self.write_keyword("WITHOUT COUNT");
19535 }
19536 }
19537 }
19538 }
19539 self.write(")");
19540 if let Some(ref order_by) = f.order_by {
19541 self.write_space();
19542 self.write_keyword("WITHIN GROUP");
19543 self.write(" (");
19544 self.write_keyword("ORDER BY");
19545 self.write_space();
19546 for (i, ord) in order_by.iter().enumerate() {
19547 if i > 0 {
19548 self.write(", ");
19549 }
19550 self.generate_ordered(ord)?;
19551 }
19552 self.write(")");
19553 }
19554 if let Some(ref filter) = f.filter {
19555 self.write_space();
19556 self.write_keyword("FILTER");
19557 self.write("(");
19558 self.write_keyword("WHERE");
19559 self.write_space();
19560 self.generate_expression(filter)?;
19561 self.write(")");
19562 }
19563 Ok(())
19564 }
19565
19566 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
19567 self.write_keyword("SUM_IF");
19568 self.write("(");
19569 self.generate_expression(&f.this)?;
19570 self.write(", ");
19571 self.generate_expression(&f.condition)?;
19572 self.write(")");
19573 if let Some(ref filter) = f.filter {
19574 self.write_space();
19575 self.write_keyword("FILTER");
19576 self.write("(");
19577 self.write_keyword("WHERE");
19578 self.write_space();
19579 self.generate_expression(filter)?;
19580 self.write(")");
19581 }
19582 Ok(())
19583 }
19584
19585 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
19586 self.write_keyword("APPROX_PERCENTILE");
19587 self.write("(");
19588 self.generate_expression(&f.this)?;
19589 self.write(", ");
19590 self.generate_expression(&f.percentile)?;
19591 if let Some(ref acc) = f.accuracy {
19592 self.write(", ");
19593 self.generate_expression(acc)?;
19594 }
19595 self.write(")");
19596 if let Some(ref filter) = f.filter {
19597 self.write_space();
19598 self.write_keyword("FILTER");
19599 self.write("(");
19600 self.write_keyword("WHERE");
19601 self.write_space();
19602 self.generate_expression(filter)?;
19603 self.write(")");
19604 }
19605 Ok(())
19606 }
19607
19608 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
19609 self.write_keyword(name);
19610 self.write("(");
19611 self.generate_expression(&f.percentile)?;
19612 self.write(")");
19613 if let Some(ref order_by) = f.order_by {
19614 self.write_space();
19615 self.write_keyword("WITHIN GROUP");
19616 self.write(" (");
19617 self.write_keyword("ORDER BY");
19618 self.write_space();
19619 self.generate_expression(&f.this)?;
19620 for ord in order_by.iter() {
19621 if ord.desc {
19622 self.write_space();
19623 self.write_keyword("DESC");
19624 }
19625 }
19626 self.write(")");
19627 }
19628 if let Some(ref filter) = f.filter {
19629 self.write_space();
19630 self.write_keyword("FILTER");
19631 self.write("(");
19632 self.write_keyword("WHERE");
19633 self.write_space();
19634 self.generate_expression(filter)?;
19635 self.write(")");
19636 }
19637 Ok(())
19638 }
19639
19640 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
19643 self.write_keyword("NTILE");
19644 self.write("(");
19645 if let Some(num_buckets) = &f.num_buckets {
19646 self.generate_expression(num_buckets)?;
19647 }
19648 if let Some(order_by) = &f.order_by {
19649 self.write_keyword(" ORDER BY ");
19650 for (i, ob) in order_by.iter().enumerate() {
19651 if i > 0 {
19652 self.write(", ");
19653 }
19654 self.generate_ordered(ob)?;
19655 }
19656 }
19657 self.write(")");
19658 Ok(())
19659 }
19660
19661 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
19662 self.write_keyword(name);
19663 self.write("(");
19664 self.generate_expression(&f.this)?;
19665 if let Some(ref offset) = f.offset {
19666 self.write(", ");
19667 self.generate_expression(offset)?;
19668 if let Some(ref default) = f.default {
19669 self.write(", ");
19670 self.generate_expression(default)?;
19671 }
19672 }
19673 if self.config.ignore_nulls_in_func {
19675 match f.ignore_nulls {
19676 Some(true) => {
19677 self.write_space();
19678 self.write_keyword("IGNORE NULLS");
19679 }
19680 Some(false) => {
19681 self.write_space();
19682 self.write_keyword("RESPECT NULLS");
19683 }
19684 None => {}
19685 }
19686 }
19687 self.write(")");
19688 if !self.config.ignore_nulls_in_func {
19690 match f.ignore_nulls {
19691 Some(true) => {
19692 self.write_space();
19693 self.write_keyword("IGNORE NULLS");
19694 }
19695 Some(false) => {
19696 self.write_space();
19697 self.write_keyword("RESPECT NULLS");
19698 }
19699 None => {}
19700 }
19701 }
19702 Ok(())
19703 }
19704
19705 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
19706 self.write_keyword(name);
19707 self.write("(");
19708 self.generate_expression(&f.this)?;
19709 if !f.order_by.is_empty() {
19711 self.write_space();
19712 self.write_keyword("ORDER BY");
19713 self.write_space();
19714 for (i, ordered) in f.order_by.iter().enumerate() {
19715 if i > 0 {
19716 self.write(", ");
19717 }
19718 self.generate_ordered(ordered)?;
19719 }
19720 }
19721 if self.config.ignore_nulls_in_func {
19723 match f.ignore_nulls {
19724 Some(true) => {
19725 self.write_space();
19726 self.write_keyword("IGNORE NULLS");
19727 }
19728 Some(false) => {
19729 self.write_space();
19730 self.write_keyword("RESPECT NULLS");
19731 }
19732 None => {}
19733 }
19734 }
19735 self.write(")");
19736 if !self.config.ignore_nulls_in_func {
19738 match f.ignore_nulls {
19739 Some(true) => {
19740 self.write_space();
19741 self.write_keyword("IGNORE NULLS");
19742 }
19743 Some(false) => {
19744 self.write_space();
19745 self.write_keyword("RESPECT NULLS");
19746 }
19747 None => {}
19748 }
19749 }
19750 Ok(())
19751 }
19752
19753 fn generate_value_func_with_ignore_nulls_bool(
19756 &mut self,
19757 name: &str,
19758 f: &ValueFunc,
19759 ) -> Result<()> {
19760 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
19761 self.write_keyword(name);
19762 self.write("(");
19763 self.generate_expression(&f.this)?;
19764 self.write(", ");
19765 self.write_keyword("TRUE");
19766 self.write(")");
19767 return Ok(());
19768 }
19769 self.generate_value_func(name, f)
19770 }
19771
19772 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
19773 self.write_keyword("NTH_VALUE");
19774 self.write("(");
19775 self.generate_expression(&f.this)?;
19776 self.write(", ");
19777 self.generate_expression(&f.offset)?;
19778 if self.config.ignore_nulls_in_func {
19780 match f.ignore_nulls {
19781 Some(true) => {
19782 self.write_space();
19783 self.write_keyword("IGNORE NULLS");
19784 }
19785 Some(false) => {
19786 self.write_space();
19787 self.write_keyword("RESPECT NULLS");
19788 }
19789 None => {}
19790 }
19791 }
19792 self.write(")");
19793 if matches!(
19795 self.config.dialect,
19796 Some(crate::dialects::DialectType::Snowflake)
19797 ) {
19798 match f.from_first {
19799 Some(true) => {
19800 self.write_space();
19801 self.write_keyword("FROM FIRST");
19802 }
19803 Some(false) => {
19804 self.write_space();
19805 self.write_keyword("FROM LAST");
19806 }
19807 None => {}
19808 }
19809 }
19810 if !self.config.ignore_nulls_in_func {
19812 match f.ignore_nulls {
19813 Some(true) => {
19814 self.write_space();
19815 self.write_keyword("IGNORE NULLS");
19816 }
19817 Some(false) => {
19818 self.write_space();
19819 self.write_keyword("RESPECT NULLS");
19820 }
19821 None => {}
19822 }
19823 }
19824 Ok(())
19825 }
19826
19827 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
19830 if matches!(
19833 self.config.dialect,
19834 Some(crate::dialects::DialectType::ClickHouse)
19835 ) {
19836 self.write_keyword("POSITION");
19837 self.write("(");
19838 self.generate_expression(&f.string)?;
19839 self.write(", ");
19840 self.generate_expression(&f.substring)?;
19841 if let Some(ref start) = f.start {
19842 self.write(", ");
19843 self.generate_expression(start)?;
19844 }
19845 self.write(")");
19846 return Ok(());
19847 }
19848
19849 self.write_keyword("POSITION");
19850 self.write("(");
19851 self.generate_expression(&f.substring)?;
19852 self.write_space();
19853 self.write_keyword("IN");
19854 self.write_space();
19855 self.generate_expression(&f.string)?;
19856 if let Some(ref start) = f.start {
19857 self.write(", ");
19858 self.generate_expression(start)?;
19859 }
19860 self.write(")");
19861 Ok(())
19862 }
19863
19864 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
19867 if f.lower.is_some() || f.upper.is_some() {
19869 self.write_keyword("RANDOM");
19870 self.write("(");
19871 if let Some(ref lower) = f.lower {
19872 self.generate_expression(lower)?;
19873 }
19874 if let Some(ref upper) = f.upper {
19875 self.write(", ");
19876 self.generate_expression(upper)?;
19877 }
19878 self.write(")");
19879 return Ok(());
19880 }
19881 let func_name = match self.config.dialect {
19883 Some(crate::dialects::DialectType::Snowflake)
19884 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
19885 _ => "RAND",
19886 };
19887 self.write_keyword(func_name);
19888 self.write("(");
19889 if !matches!(
19891 self.config.dialect,
19892 Some(crate::dialects::DialectType::DuckDB)
19893 ) {
19894 if let Some(ref seed) = f.seed {
19895 self.generate_expression(seed)?;
19896 }
19897 }
19898 self.write(")");
19899 Ok(())
19900 }
19901
19902 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
19903 self.write_keyword("TRUNCATE");
19904 self.write("(");
19905 self.generate_expression(&f.this)?;
19906 if let Some(ref decimals) = f.decimals {
19907 self.write(", ");
19908 self.generate_expression(decimals)?;
19909 }
19910 self.write(")");
19911 Ok(())
19912 }
19913
19914 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
19917 self.write_keyword("DECODE");
19918 self.write("(");
19919 self.generate_expression(&f.this)?;
19920 for (search, result) in &f.search_results {
19921 self.write(", ");
19922 self.generate_expression(search)?;
19923 self.write(", ");
19924 self.generate_expression(result)?;
19925 }
19926 if let Some(ref default) = f.default {
19927 self.write(", ");
19928 self.generate_expression(default)?;
19929 }
19930 self.write(")");
19931 Ok(())
19932 }
19933
19934 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
19937 self.write_keyword(name);
19938 self.write("(");
19939 self.generate_expression(&f.this)?;
19940 self.write(", ");
19941 self.generate_expression(&f.format)?;
19942 self.write(")");
19943 Ok(())
19944 }
19945
19946 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
19947 self.write_keyword("FROM_UNIXTIME");
19948 self.write("(");
19949 self.generate_expression(&f.this)?;
19950 if let Some(ref format) = f.format {
19951 self.write(", ");
19952 self.generate_expression(format)?;
19953 }
19954 self.write(")");
19955 Ok(())
19956 }
19957
19958 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
19959 self.write_keyword("UNIX_TIMESTAMP");
19960 self.write("(");
19961 if let Some(ref expr) = f.this {
19962 self.generate_expression(expr)?;
19963 if let Some(ref format) = f.format {
19964 self.write(", ");
19965 self.generate_expression(format)?;
19966 }
19967 } else if matches!(
19968 self.config.dialect,
19969 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
19970 ) {
19971 self.write_keyword("CURRENT_TIMESTAMP");
19973 self.write("()");
19974 }
19975 self.write(")");
19976 Ok(())
19977 }
19978
19979 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
19980 self.write_keyword("MAKE_DATE");
19981 self.write("(");
19982 self.generate_expression(&f.year)?;
19983 self.write(", ");
19984 self.generate_expression(&f.month)?;
19985 self.write(", ");
19986 self.generate_expression(&f.day)?;
19987 self.write(")");
19988 Ok(())
19989 }
19990
19991 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
19992 self.write_keyword("MAKE_TIMESTAMP");
19993 self.write("(");
19994 self.generate_expression(&f.year)?;
19995 self.write(", ");
19996 self.generate_expression(&f.month)?;
19997 self.write(", ");
19998 self.generate_expression(&f.day)?;
19999 self.write(", ");
20000 self.generate_expression(&f.hour)?;
20001 self.write(", ");
20002 self.generate_expression(&f.minute)?;
20003 self.write(", ");
20004 self.generate_expression(&f.second)?;
20005 if let Some(ref tz) = f.timezone {
20006 self.write(", ");
20007 self.generate_expression(tz)?;
20008 }
20009 self.write(")");
20010 Ok(())
20011 }
20012
20013 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
20015 match expr {
20016 Expression::Struct(s) => {
20017 if s.fields.iter().all(|(name, _)| name.is_some()) {
20018 Some(
20019 s.fields
20020 .iter()
20021 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
20022 .collect(),
20023 )
20024 } else {
20025 None
20026 }
20027 }
20028 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20029 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
20031 Some(
20032 f.args
20033 .iter()
20034 .filter_map(|a| {
20035 if let Expression::Alias(alias) = a {
20036 Some(alias.alias.name.clone())
20037 } else {
20038 None
20039 }
20040 })
20041 .collect(),
20042 )
20043 } else {
20044 None
20045 }
20046 }
20047 _ => None,
20048 }
20049 }
20050
20051 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
20053 match expr {
20054 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
20055 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20056 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
20057 }
20058 _ => false,
20059 }
20060 }
20061
20062 fn struct_field_count(expr: &Expression) -> usize {
20064 match expr {
20065 Expression::Struct(s) => s.fields.len(),
20066 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => f.args.len(),
20067 _ => 0,
20068 }
20069 }
20070
20071 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
20073 match expr {
20074 Expression::Struct(s) => {
20075 let mut new_fields = Vec::with_capacity(s.fields.len());
20076 for (i, (name, value)) in s.fields.iter().enumerate() {
20077 if name.is_none() && i < field_names.len() {
20078 new_fields.push((Some(field_names[i].clone()), value.clone()));
20079 } else {
20080 new_fields.push((name.clone(), value.clone()));
20081 }
20082 }
20083 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
20084 }
20085 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20086 let mut new_args = Vec::with_capacity(f.args.len());
20087 for (i, arg) in f.args.iter().enumerate() {
20088 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
20089 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
20091 this: arg.clone(),
20092 alias: crate::expressions::Identifier::new(field_names[i].clone()),
20093 column_aliases: Vec::new(),
20094 pre_alias_comments: Vec::new(),
20095 trailing_comments: Vec::new(),
20096 inferred_type: None,
20097 })));
20098 } else {
20099 new_args.push(arg.clone());
20100 }
20101 }
20102 Expression::Function(Box::new(crate::expressions::Function {
20103 name: f.name.clone(),
20104 args: new_args,
20105 distinct: f.distinct,
20106 trailing_comments: f.trailing_comments.clone(),
20107 use_bracket_syntax: f.use_bracket_syntax,
20108 no_parens: f.no_parens,
20109 quoted: f.quoted,
20110 span: None,
20111 inferred_type: None,
20112 }))
20113 }
20114 _ => expr.clone(),
20115 }
20116 }
20117
20118 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
20122 let first = match expressions.first() {
20123 Some(e) => e,
20124 None => return expressions.to_vec(),
20125 };
20126
20127 let field_names = match Self::extract_struct_field_names(first) {
20128 Some(names) if !names.is_empty() => names,
20129 _ => return expressions.to_vec(),
20130 };
20131
20132 let mut result = Vec::with_capacity(expressions.len());
20133 for (idx, expr) in expressions.iter().enumerate() {
20134 if idx == 0 {
20135 result.push(expr.clone());
20136 continue;
20137 }
20138 if Self::struct_field_count(expr) == field_names.len()
20140 && Self::struct_has_unnamed_fields(expr)
20141 {
20142 result.push(Self::apply_struct_field_names(expr, &field_names));
20143 } else {
20144 result.push(expr.clone());
20145 }
20146 }
20147 result
20148 }
20149
20150 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
20153 let needs_inheritance = matches!(
20156 self.config.dialect,
20157 Some(DialectType::DuckDB)
20158 | Some(DialectType::Spark)
20159 | Some(DialectType::Databricks)
20160 | Some(DialectType::Hive)
20161 | Some(DialectType::Snowflake)
20162 | Some(DialectType::Presto)
20163 | Some(DialectType::Trino)
20164 );
20165 let propagated: Vec<Expression>;
20166 let expressions = if needs_inheritance && f.expressions.len() > 1 {
20167 propagated = Self::inherit_struct_field_names(&f.expressions);
20168 &propagated
20169 } else {
20170 &f.expressions
20171 };
20172
20173 let should_split = if self.config.pretty && !expressions.is_empty() {
20175 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
20176 for expr in expressions {
20177 let mut temp_gen = Generator::with_arc_config(self.config.clone());
20178 Arc::make_mut(&mut temp_gen.config).pretty = false;
20179 temp_gen.generate_expression(expr)?;
20180 expr_strings.push(temp_gen.output);
20181 }
20182 self.too_wide(&expr_strings)
20183 } else {
20184 false
20185 };
20186
20187 if f.bracket_notation {
20188 let (open, close) = match self.config.dialect {
20192 None
20193 | Some(DialectType::Generic)
20194 | Some(DialectType::Spark)
20195 | Some(DialectType::Databricks)
20196 | Some(DialectType::Hive) => {
20197 self.write_keyword("ARRAY");
20198 ("(", ")")
20199 }
20200 Some(DialectType::Presto)
20201 | Some(DialectType::Trino)
20202 | Some(DialectType::PostgreSQL)
20203 | Some(DialectType::Redshift)
20204 | Some(DialectType::Materialize)
20205 | Some(DialectType::RisingWave)
20206 | Some(DialectType::CockroachDB) => {
20207 self.write_keyword("ARRAY");
20208 ("[", "]")
20209 }
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 } else {
20236 if f.use_list_keyword {
20238 self.write_keyword("LIST");
20239 } else {
20240 self.write_keyword("ARRAY");
20241 }
20242 let has_subquery = expressions
20245 .iter()
20246 .any(|e| matches!(e, Expression::Select(_)));
20247 let (open, close) = if matches!(
20248 self.config.dialect,
20249 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
20250 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
20251 && has_subquery)
20252 {
20253 ("(", ")")
20254 } else {
20255 ("[", "]")
20256 };
20257 self.write(open);
20258 if should_split {
20259 self.write_newline();
20260 self.indent_level += 1;
20261 for (i, expr) in expressions.iter().enumerate() {
20262 self.write_indent();
20263 self.generate_expression(expr)?;
20264 if i + 1 < expressions.len() {
20265 self.write(",");
20266 }
20267 self.write_newline();
20268 }
20269 self.indent_level -= 1;
20270 self.write_indent();
20271 } else {
20272 for (i, expr) in expressions.iter().enumerate() {
20273 if i > 0 {
20274 self.write(", ");
20275 }
20276 self.generate_expression(expr)?;
20277 }
20278 }
20279 self.write(close);
20280 }
20281 Ok(())
20282 }
20283
20284 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
20285 self.write_keyword("ARRAY_SORT");
20286 self.write("(");
20287 self.generate_expression(&f.this)?;
20288 if let Some(ref comp) = f.comparator {
20289 self.write(", ");
20290 self.generate_expression(comp)?;
20291 }
20292 self.write(")");
20293 Ok(())
20294 }
20295
20296 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
20297 self.write_keyword(name);
20298 self.write("(");
20299 self.generate_expression(&f.this)?;
20300 self.write(", ");
20301 self.generate_expression(&f.separator)?;
20302 if let Some(ref null_rep) = f.null_replacement {
20303 self.write(", ");
20304 self.generate_expression(null_rep)?;
20305 }
20306 self.write(")");
20307 Ok(())
20308 }
20309
20310 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
20311 self.write_keyword("UNNEST");
20312 self.write("(");
20313 self.generate_expression(&f.this)?;
20314 for extra in &f.expressions {
20315 self.write(", ");
20316 self.generate_expression(extra)?;
20317 }
20318 self.write(")");
20319 if f.with_ordinality {
20320 self.write_space();
20321 if self.config.unnest_with_ordinality {
20322 self.write_keyword("WITH ORDINALITY");
20324 } else if f.offset_alias.is_some() {
20325 if let Some(ref alias) = f.alias {
20328 self.write_keyword("AS");
20329 self.write_space();
20330 self.generate_identifier(alias)?;
20331 self.write_space();
20332 }
20333 self.write_keyword("WITH OFFSET");
20334 if let Some(ref offset_alias) = f.offset_alias {
20335 self.write_space();
20336 self.write_keyword("AS");
20337 self.write_space();
20338 self.generate_identifier(offset_alias)?;
20339 }
20340 } else {
20341 self.write_keyword("WITH OFFSET");
20343 if f.alias.is_none() {
20344 self.write(" AS offset");
20345 }
20346 }
20347 }
20348 if let Some(ref alias) = f.alias {
20349 let should_add_alias = if !f.with_ordinality {
20351 true
20352 } else if self.config.unnest_with_ordinality {
20353 true
20355 } else if f.offset_alias.is_some() {
20356 false
20358 } else {
20359 true
20361 };
20362 if should_add_alias {
20363 self.write_space();
20364 self.write_keyword("AS");
20365 self.write_space();
20366 self.generate_identifier(alias)?;
20367 }
20368 }
20369 Ok(())
20370 }
20371
20372 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
20373 self.write_keyword("FILTER");
20374 self.write("(");
20375 self.generate_expression(&f.this)?;
20376 self.write(", ");
20377 self.generate_expression(&f.filter)?;
20378 self.write(")");
20379 Ok(())
20380 }
20381
20382 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
20383 self.write_keyword("TRANSFORM");
20384 self.write("(");
20385 self.generate_expression(&f.this)?;
20386 self.write(", ");
20387 self.generate_expression(&f.transform)?;
20388 self.write(")");
20389 Ok(())
20390 }
20391
20392 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
20393 self.write_keyword(name);
20394 self.write("(");
20395 self.generate_expression(&f.start)?;
20396 self.write(", ");
20397 self.generate_expression(&f.stop)?;
20398 if let Some(ref step) = f.step {
20399 self.write(", ");
20400 self.generate_expression(step)?;
20401 }
20402 self.write(")");
20403 Ok(())
20404 }
20405
20406 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
20409 self.write_keyword("STRUCT");
20410 self.write("(");
20411 for (i, (name, expr)) in f.fields.iter().enumerate() {
20412 if i > 0 {
20413 self.write(", ");
20414 }
20415 if let Some(ref id) = name {
20416 self.generate_identifier(id)?;
20417 self.write(" ");
20418 self.write_keyword("AS");
20419 self.write(" ");
20420 }
20421 self.generate_expression(expr)?;
20422 }
20423 self.write(")");
20424 Ok(())
20425 }
20426
20427 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
20429 let mut names: Vec<Option<String>> = Vec::new();
20432 let mut values: Vec<&Expression> = Vec::new();
20433 let mut all_named = true;
20434
20435 for arg in &func.args {
20436 match arg {
20437 Expression::Alias(a) => {
20438 names.push(Some(a.alias.name.clone()));
20439 values.push(&a.this);
20440 }
20441 _ => {
20442 names.push(None);
20443 values.push(arg);
20444 all_named = false;
20445 }
20446 }
20447 }
20448
20449 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
20450 self.write("{");
20452 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20453 if i > 0 {
20454 self.write(", ");
20455 }
20456 if let Some(n) = name {
20457 self.write("'");
20458 self.write(n);
20459 self.write("'");
20460 } else {
20461 self.write("'_");
20462 self.write(&i.to_string());
20463 self.write("'");
20464 }
20465 self.write(": ");
20466 self.generate_expression(value)?;
20467 }
20468 self.write("}");
20469 return Ok(());
20470 }
20471
20472 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
20473 self.write_keyword("OBJECT_CONSTRUCT");
20475 self.write("(");
20476 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20477 if i > 0 {
20478 self.write(", ");
20479 }
20480 if let Some(n) = name {
20481 self.write("'");
20482 self.write(n);
20483 self.write("'");
20484 } else {
20485 self.write("'_");
20486 self.write(&i.to_string());
20487 self.write("'");
20488 }
20489 self.write(", ");
20490 self.generate_expression(value)?;
20491 }
20492 self.write(")");
20493 return Ok(());
20494 }
20495
20496 if matches!(
20497 self.config.dialect,
20498 Some(DialectType::Presto) | Some(DialectType::Trino)
20499 ) {
20500 if all_named && !names.is_empty() {
20501 self.write_keyword("CAST");
20504 self.write("(");
20505 self.write_keyword("ROW");
20506 self.write("(");
20507 for (i, value) in values.iter().enumerate() {
20508 if i > 0 {
20509 self.write(", ");
20510 }
20511 self.generate_expression(value)?;
20512 }
20513 self.write(")");
20514 self.write(" ");
20515 self.write_keyword("AS");
20516 self.write(" ");
20517 self.write_keyword("ROW");
20518 self.write("(");
20519 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20520 if i > 0 {
20521 self.write(", ");
20522 }
20523 if let Some(n) = name {
20524 self.write(n);
20525 }
20526 self.write(" ");
20527 let type_str = Self::infer_sql_type_for_presto(value);
20528 self.write_keyword(&type_str);
20529 }
20530 self.write(")");
20531 self.write(")");
20532 } else {
20533 self.write_keyword("ROW");
20535 self.write("(");
20536 for (i, value) in values.iter().enumerate() {
20537 if i > 0 {
20538 self.write(", ");
20539 }
20540 self.generate_expression(value)?;
20541 }
20542 self.write(")");
20543 }
20544 return Ok(());
20545 }
20546
20547 self.write_keyword("ROW");
20549 self.write("(");
20550 for (i, value) in values.iter().enumerate() {
20551 if i > 0 {
20552 self.write(", ");
20553 }
20554 self.generate_expression(value)?;
20555 }
20556 self.write(")");
20557 Ok(())
20558 }
20559
20560 fn infer_sql_type_for_presto(expr: &Expression) -> String {
20562 match expr {
20563 Expression::Literal(lit)
20564 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
20565 {
20566 "VARCHAR".to_string()
20567 }
20568 Expression::Literal(lit)
20569 if matches!(lit.as_ref(), crate::expressions::Literal::Number(_)) =>
20570 {
20571 let crate::expressions::Literal::Number(n) = lit.as_ref() else {
20572 unreachable!()
20573 };
20574 if n.contains('.') {
20575 "DOUBLE".to_string()
20576 } else {
20577 "INTEGER".to_string()
20578 }
20579 }
20580 Expression::Boolean(_) => "BOOLEAN".to_string(),
20581 Expression::Literal(lit)
20582 if matches!(lit.as_ref(), crate::expressions::Literal::Date(_)) =>
20583 {
20584 "DATE".to_string()
20585 }
20586 Expression::Literal(lit)
20587 if matches!(lit.as_ref(), crate::expressions::Literal::Timestamp(_)) =>
20588 {
20589 "TIMESTAMP".to_string()
20590 }
20591 Expression::Literal(lit)
20592 if matches!(lit.as_ref(), crate::expressions::Literal::Datetime(_)) =>
20593 {
20594 "TIMESTAMP".to_string()
20595 }
20596 Expression::Array(_) | Expression::ArrayFunc(_) => {
20597 "ARRAY(VARCHAR)".to_string()
20599 }
20600 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
20602 Expression::Function(f) => {
20603 if f.name.eq_ignore_ascii_case("STRUCT") {
20604 "ROW".to_string()
20605 } else if f.name.eq_ignore_ascii_case("CURRENT_DATE") {
20606 "DATE".to_string()
20607 } else if f.name.eq_ignore_ascii_case("CURRENT_TIMESTAMP")
20608 || f.name.eq_ignore_ascii_case("NOW")
20609 {
20610 "TIMESTAMP".to_string()
20611 } else {
20612 "VARCHAR".to_string()
20613 }
20614 }
20615 _ => "VARCHAR".to_string(),
20616 }
20617 }
20618
20619 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
20620 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
20622 self.write_keyword("STRUCT_EXTRACT");
20623 self.write("(");
20624 self.generate_expression(&f.this)?;
20625 self.write(", ");
20626 self.write("'");
20628 self.write(&f.field.name);
20629 self.write("'");
20630 self.write(")");
20631 return Ok(());
20632 }
20633 self.generate_expression(&f.this)?;
20634 self.write(".");
20635 self.generate_identifier(&f.field)
20636 }
20637
20638 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
20639 self.write_keyword("NAMED_STRUCT");
20640 self.write("(");
20641 for (i, (name, value)) in f.pairs.iter().enumerate() {
20642 if i > 0 {
20643 self.write(", ");
20644 }
20645 self.generate_expression(name)?;
20646 self.write(", ");
20647 self.generate_expression(value)?;
20648 }
20649 self.write(")");
20650 Ok(())
20651 }
20652
20653 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
20656 if f.curly_brace_syntax {
20657 if f.with_map_keyword {
20659 self.write_keyword("MAP");
20660 self.write(" ");
20661 }
20662 self.write("{");
20663 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
20664 if i > 0 {
20665 self.write(", ");
20666 }
20667 self.generate_expression(key)?;
20668 self.write(": ");
20669 self.generate_expression(val)?;
20670 }
20671 self.write("}");
20672 } else {
20673 self.write_keyword("MAP");
20675 self.write("(");
20676 self.write_keyword("ARRAY");
20677 self.write("[");
20678 for (i, key) in f.keys.iter().enumerate() {
20679 if i > 0 {
20680 self.write(", ");
20681 }
20682 self.generate_expression(key)?;
20683 }
20684 self.write("], ");
20685 self.write_keyword("ARRAY");
20686 self.write("[");
20687 for (i, val) in f.values.iter().enumerate() {
20688 if i > 0 {
20689 self.write(", ");
20690 }
20691 self.generate_expression(val)?;
20692 }
20693 self.write("])");
20694 }
20695 Ok(())
20696 }
20697
20698 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
20699 self.write_keyword(name);
20700 self.write("(");
20701 self.generate_expression(&f.this)?;
20702 self.write(", ");
20703 self.generate_expression(&f.transform)?;
20704 self.write(")");
20705 Ok(())
20706 }
20707
20708 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
20711 use crate::dialects::DialectType;
20712
20713 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
20715
20716 if use_arrow {
20717 self.generate_expression(&f.this)?;
20719 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
20720 self.write(" ->> ");
20721 } else {
20722 self.write(" -> ");
20723 }
20724 self.generate_expression(&f.path)?;
20725 return Ok(());
20726 }
20727
20728 if f.hash_arrow_syntax
20730 && matches!(
20731 self.config.dialect,
20732 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
20733 )
20734 {
20735 self.generate_expression(&f.this)?;
20736 self.write(" #>> ");
20737 self.generate_expression(&f.path)?;
20738 return Ok(());
20739 }
20740
20741 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
20744 match name {
20745 "JSON_EXTRACT_SCALAR"
20746 | "JSON_EXTRACT_PATH_TEXT"
20747 | "JSON_EXTRACT"
20748 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
20749 _ => name,
20750 }
20751 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
20752 match name {
20753 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
20754 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
20755 _ => name,
20756 }
20757 } else {
20758 name
20759 };
20760
20761 self.write_keyword(func_name);
20762 self.write("(");
20763 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
20765 if let Expression::Cast(ref cast) = f.this {
20766 if matches!(cast.to, crate::expressions::DataType::Json) {
20767 self.generate_expression(&cast.this)?;
20768 } else {
20769 self.generate_expression(&f.this)?;
20770 }
20771 } else {
20772 self.generate_expression(&f.this)?;
20773 }
20774 } else {
20775 self.generate_expression(&f.this)?;
20776 }
20777 if matches!(
20780 self.config.dialect,
20781 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
20782 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
20783 {
20784 if let Expression::Literal(ref lit) = f.path {
20785 if let Literal::String(ref s) = lit.as_ref() {
20786 let parts = Self::decompose_json_path(s);
20787 for part in &parts {
20788 self.write(", '");
20789 self.write(part);
20790 self.write("'");
20791 }
20792 }
20793 } else {
20794 self.write(", ");
20795 self.generate_expression(&f.path)?;
20796 }
20797 } else {
20798 self.write(", ");
20799 self.generate_expression(&f.path)?;
20800 }
20801
20802 if let Some(ref wrapper) = f.wrapper_option {
20805 self.write_space();
20806 self.write_keyword(wrapper);
20807 }
20808 if let Some(ref quotes) = f.quotes_option {
20809 self.write_space();
20810 self.write_keyword(quotes);
20811 if f.on_scalar_string {
20812 self.write_space();
20813 self.write_keyword("ON SCALAR STRING");
20814 }
20815 }
20816 if let Some(ref on_err) = f.on_error {
20817 self.write_space();
20818 self.write_keyword(on_err);
20819 }
20820 if let Some(ref ret_type) = f.returning {
20821 self.write_space();
20822 self.write_keyword("RETURNING");
20823 self.write_space();
20824 self.generate_data_type(ret_type)?;
20825 }
20826
20827 self.write(")");
20828 Ok(())
20829 }
20830
20831 fn dialect_supports_json_arrow(&self) -> bool {
20833 use crate::dialects::DialectType;
20834 match self.config.dialect {
20835 Some(DialectType::PostgreSQL) => true,
20837 Some(DialectType::MySQL) => true,
20838 Some(DialectType::DuckDB) => true,
20839 Some(DialectType::CockroachDB) => true,
20840 Some(DialectType::StarRocks) => true,
20841 Some(DialectType::SQLite) => true,
20842 _ => false,
20844 }
20845 }
20846
20847 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
20848 use crate::dialects::DialectType;
20849
20850 if matches!(
20852 self.config.dialect,
20853 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
20854 ) && name == "JSON_EXTRACT_PATH"
20855 {
20856 self.generate_expression(&f.this)?;
20857 self.write(" #> ");
20858 if f.paths.len() == 1 {
20859 self.generate_expression(&f.paths[0])?;
20860 } else {
20861 self.write_keyword("ARRAY");
20863 self.write("[");
20864 for (i, path) in f.paths.iter().enumerate() {
20865 if i > 0 {
20866 self.write(", ");
20867 }
20868 self.generate_expression(path)?;
20869 }
20870 self.write("]");
20871 }
20872 return Ok(());
20873 }
20874
20875 self.write_keyword(name);
20876 self.write("(");
20877 self.generate_expression(&f.this)?;
20878 for path in &f.paths {
20879 self.write(", ");
20880 self.generate_expression(path)?;
20881 }
20882 self.write(")");
20883 Ok(())
20884 }
20885
20886 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
20887 use crate::dialects::DialectType;
20888
20889 self.write_keyword("JSON_OBJECT");
20890 self.write("(");
20891 if f.star {
20892 self.write("*");
20893 } else {
20894 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
20898 || matches!(
20899 self.config.dialect,
20900 Some(DialectType::BigQuery)
20901 | Some(DialectType::MySQL)
20902 | Some(DialectType::SQLite)
20903 );
20904
20905 for (i, (key, value)) in f.pairs.iter().enumerate() {
20906 if i > 0 {
20907 self.write(", ");
20908 }
20909 self.generate_expression(key)?;
20910 if use_comma_syntax {
20911 self.write(", ");
20912 } else {
20913 self.write(": ");
20914 }
20915 self.generate_expression(value)?;
20916 }
20917 }
20918 if let Some(null_handling) = f.null_handling {
20919 self.write_space();
20920 match null_handling {
20921 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
20922 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
20923 }
20924 }
20925 if f.with_unique_keys {
20926 self.write_space();
20927 self.write_keyword("WITH UNIQUE KEYS");
20928 }
20929 if let Some(ref ret_type) = f.returning_type {
20930 self.write_space();
20931 self.write_keyword("RETURNING");
20932 self.write_space();
20933 self.generate_data_type(ret_type)?;
20934 if f.format_json {
20935 self.write_space();
20936 self.write_keyword("FORMAT JSON");
20937 }
20938 if let Some(ref enc) = f.encoding {
20939 self.write_space();
20940 self.write_keyword("ENCODING");
20941 self.write_space();
20942 self.write(enc);
20943 }
20944 }
20945 self.write(")");
20946 Ok(())
20947 }
20948
20949 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
20950 self.write_keyword(name);
20951 self.write("(");
20952 self.generate_expression(&f.this)?;
20953 for (path, value) in &f.path_values {
20954 self.write(", ");
20955 self.generate_expression(path)?;
20956 self.write(", ");
20957 self.generate_expression(value)?;
20958 }
20959 self.write(")");
20960 Ok(())
20961 }
20962
20963 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
20964 self.write_keyword("JSON_ARRAYAGG");
20965 self.write("(");
20966 self.generate_expression(&f.this)?;
20967 if let Some(ref order_by) = f.order_by {
20968 self.write_space();
20969 self.write_keyword("ORDER BY");
20970 self.write_space();
20971 for (i, ord) in order_by.iter().enumerate() {
20972 if i > 0 {
20973 self.write(", ");
20974 }
20975 self.generate_ordered(ord)?;
20976 }
20977 }
20978 if let Some(null_handling) = f.null_handling {
20979 self.write_space();
20980 match null_handling {
20981 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
20982 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
20983 }
20984 }
20985 self.write(")");
20986 if let Some(ref filter) = f.filter {
20987 self.write_space();
20988 self.write_keyword("FILTER");
20989 self.write("(");
20990 self.write_keyword("WHERE");
20991 self.write_space();
20992 self.generate_expression(filter)?;
20993 self.write(")");
20994 }
20995 Ok(())
20996 }
20997
20998 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
20999 self.write_keyword("JSON_OBJECTAGG");
21000 self.write("(");
21001 self.generate_expression(&f.key)?;
21002 self.write(": ");
21003 self.generate_expression(&f.value)?;
21004 if let Some(null_handling) = f.null_handling {
21005 self.write_space();
21006 match null_handling {
21007 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21008 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21009 }
21010 }
21011 self.write(")");
21012 if let Some(ref filter) = f.filter {
21013 self.write_space();
21014 self.write_keyword("FILTER");
21015 self.write("(");
21016 self.write_keyword("WHERE");
21017 self.write_space();
21018 self.generate_expression(filter)?;
21019 self.write(")");
21020 }
21021 Ok(())
21022 }
21023
21024 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
21027 use crate::dialects::DialectType;
21028
21029 if self.config.dialect == Some(DialectType::Redshift) {
21031 self.write_keyword("CAST");
21032 self.write("(");
21033 self.generate_expression(&f.this)?;
21034 self.write_space();
21035 self.write_keyword("AS");
21036 self.write_space();
21037 self.generate_data_type(&f.to)?;
21038 self.write(")");
21039 return Ok(());
21040 }
21041
21042 self.write_keyword("CONVERT");
21043 self.write("(");
21044 self.generate_data_type(&f.to)?;
21045 self.write(", ");
21046 self.generate_expression(&f.this)?;
21047 if let Some(ref style) = f.style {
21048 self.write(", ");
21049 self.generate_expression(style)?;
21050 }
21051 self.write(")");
21052 Ok(())
21053 }
21054
21055 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
21058 if f.colon {
21059 self.write_keyword("LAMBDA");
21061 self.write_space();
21062 for (i, param) in f.parameters.iter().enumerate() {
21063 if i > 0 {
21064 self.write(", ");
21065 }
21066 self.generate_identifier(param)?;
21067 }
21068 self.write(" : ");
21069 } else {
21070 if f.parameters.len() == 1 {
21072 self.generate_identifier(&f.parameters[0])?;
21073 } else {
21074 self.write("(");
21075 for (i, param) in f.parameters.iter().enumerate() {
21076 if i > 0 {
21077 self.write(", ");
21078 }
21079 self.generate_identifier(param)?;
21080 }
21081 self.write(")");
21082 }
21083 self.write(" -> ");
21084 }
21085 self.generate_expression(&f.body)
21086 }
21087
21088 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
21089 self.generate_identifier(&f.name)?;
21090 match f.separator {
21091 NamedArgSeparator::DArrow => self.write(" => "),
21092 NamedArgSeparator::ColonEq => self.write(" := "),
21093 NamedArgSeparator::Eq => self.write(" = "),
21094 }
21095 self.generate_expression(&f.value)
21096 }
21097
21098 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
21099 self.write_keyword(&f.prefix);
21100 self.write(" ");
21101 self.generate_expression(&f.this)
21102 }
21103
21104 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
21105 match f.style {
21106 ParameterStyle::Question => self.write("?"),
21107 ParameterStyle::Dollar => {
21108 self.write("$");
21109 if let Some(idx) = f.index {
21110 self.write(&idx.to_string());
21111 } else if let Some(ref name) = f.name {
21112 self.write(name);
21114 }
21115 }
21116 ParameterStyle::DollarBrace => {
21117 self.write("${");
21119 if let Some(ref name) = f.name {
21120 self.write(name);
21121 }
21122 if let Some(ref expr) = f.expression {
21123 self.write(":");
21124 self.write(expr);
21125 }
21126 self.write("}");
21127 }
21128 ParameterStyle::Colon => {
21129 self.write(":");
21130 if let Some(idx) = f.index {
21131 self.write(&idx.to_string());
21132 } else if let Some(ref name) = f.name {
21133 self.write(name);
21134 }
21135 }
21136 ParameterStyle::At => {
21137 self.write("@");
21138 if let Some(ref name) = f.name {
21139 if f.string_quoted {
21140 self.write("'");
21141 self.write(name);
21142 self.write("'");
21143 } else if f.quoted {
21144 self.write("\"");
21145 self.write(name);
21146 self.write("\"");
21147 } else {
21148 self.write(name);
21149 }
21150 }
21151 }
21152 ParameterStyle::DoubleAt => {
21153 self.write("@@");
21154 if let Some(ref name) = f.name {
21155 self.write(name);
21156 }
21157 }
21158 ParameterStyle::DoubleDollar => {
21159 self.write("$$");
21160 if let Some(ref name) = f.name {
21161 self.write(name);
21162 }
21163 }
21164 ParameterStyle::Percent => {
21165 if let Some(ref name) = f.name {
21166 self.write("%(");
21168 self.write(name);
21169 self.write(")s");
21170 } else {
21171 self.write("%s");
21173 }
21174 }
21175 ParameterStyle::Brace => {
21176 self.write("{");
21179 if let Some(ref name) = f.name {
21180 self.write(name);
21181 }
21182 if let Some(ref expr) = f.expression {
21183 self.write(": ");
21184 self.write(expr);
21185 }
21186 self.write("}");
21187 }
21188 }
21189 Ok(())
21190 }
21191
21192 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
21193 self.write("?");
21194 if let Some(idx) = f.index {
21195 self.write(&idx.to_string());
21196 }
21197 Ok(())
21198 }
21199
21200 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
21201 if f.is_block {
21202 self.write("/*");
21203 self.write(&f.text);
21204 self.write("*/");
21205 } else {
21206 self.write("--");
21207 self.write(&f.text);
21208 }
21209 Ok(())
21210 }
21211
21212 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
21215 self.generate_expression(&f.this)?;
21216 if f.not {
21217 self.write_space();
21218 self.write_keyword("NOT");
21219 }
21220 self.write_space();
21221 self.write_keyword("SIMILAR TO");
21222 self.write_space();
21223 self.generate_expression(&f.pattern)?;
21224 if let Some(ref escape) = f.escape {
21225 self.write_space();
21226 self.write_keyword("ESCAPE");
21227 self.write_space();
21228 self.generate_expression(escape)?;
21229 }
21230 Ok(())
21231 }
21232
21233 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
21234 self.generate_expression(&f.this)?;
21235 self.write_space();
21236 if let Some(op) = &f.op {
21238 match op {
21239 QuantifiedOp::Eq => self.write("="),
21240 QuantifiedOp::Neq => self.write("<>"),
21241 QuantifiedOp::Lt => self.write("<"),
21242 QuantifiedOp::Lte => self.write("<="),
21243 QuantifiedOp::Gt => self.write(">"),
21244 QuantifiedOp::Gte => self.write(">="),
21245 }
21246 self.write_space();
21247 }
21248 self.write_keyword(name);
21249
21250 if matches!(&f.subquery, Expression::Subquery(_)) {
21252 self.write_space();
21253 self.generate_expression(&f.subquery)?;
21254 } else {
21255 self.write("(");
21256
21257 let is_statement = matches!(
21258 &f.subquery,
21259 Expression::Select(_)
21260 | Expression::Union(_)
21261 | Expression::Intersect(_)
21262 | Expression::Except(_)
21263 );
21264
21265 if self.config.pretty && is_statement {
21266 self.write_newline();
21267 self.indent_level += 1;
21268 self.write_indent();
21269 }
21270 self.generate_expression(&f.subquery)?;
21271 if self.config.pretty && is_statement {
21272 self.write_newline();
21273 self.indent_level -= 1;
21274 self.write_indent();
21275 }
21276 self.write(")");
21277 }
21278 Ok(())
21279 }
21280
21281 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
21282 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
21284 self.generate_expression(this)?;
21285 self.write_space();
21286 self.write_keyword("OVERLAPS");
21287 self.write_space();
21288 self.generate_expression(expr)?;
21289 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
21290 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
21291 {
21292 self.write("(");
21294 self.generate_expression(ls)?;
21295 self.write(", ");
21296 self.generate_expression(le)?;
21297 self.write(")");
21298 self.write_space();
21299 self.write_keyword("OVERLAPS");
21300 self.write_space();
21301 self.write("(");
21302 self.generate_expression(rs)?;
21303 self.write(", ");
21304 self.generate_expression(re)?;
21305 self.write(")");
21306 }
21307 Ok(())
21308 }
21309
21310 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
21313 use crate::dialects::DialectType;
21314
21315 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
21317 self.generate_expression(&cast.this)?;
21318 self.write(" !:> ");
21319 self.generate_data_type(&cast.to)?;
21320 return Ok(());
21321 }
21322
21323 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
21325 self.write_keyword("TRYCAST");
21326 self.write("(");
21327 self.generate_expression(&cast.this)?;
21328 self.write_space();
21329 self.write_keyword("AS");
21330 self.write_space();
21331 self.generate_data_type(&cast.to)?;
21332 self.write(")");
21333 return Ok(());
21334 }
21335
21336 let keyword = if matches!(
21338 self.config.dialect,
21339 Some(DialectType::Hive)
21340 | Some(DialectType::MySQL)
21341 | Some(DialectType::SQLite)
21342 | Some(DialectType::Oracle)
21343 | Some(DialectType::ClickHouse)
21344 | Some(DialectType::Redshift)
21345 | Some(DialectType::PostgreSQL)
21346 | Some(DialectType::StarRocks)
21347 | Some(DialectType::Doris)
21348 ) {
21349 "CAST"
21350 } else {
21351 "TRY_CAST"
21352 };
21353
21354 self.write_keyword(keyword);
21355 self.write("(");
21356 self.generate_expression(&cast.this)?;
21357 self.write_space();
21358 self.write_keyword("AS");
21359 self.write_space();
21360 self.generate_data_type(&cast.to)?;
21361
21362 if let Some(format) = &cast.format {
21364 self.write_space();
21365 self.write_keyword("FORMAT");
21366 self.write_space();
21367 self.generate_expression(format)?;
21368 }
21369
21370 self.write(")");
21371 Ok(())
21372 }
21373
21374 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
21375 self.write_keyword("SAFE_CAST");
21376 self.write("(");
21377 self.generate_expression(&cast.this)?;
21378 self.write_space();
21379 self.write_keyword("AS");
21380 self.write_space();
21381 self.generate_data_type(&cast.to)?;
21382
21383 if let Some(format) = &cast.format {
21385 self.write_space();
21386 self.write_keyword("FORMAT");
21387 self.write_space();
21388 self.generate_expression(format)?;
21389 }
21390
21391 self.write(")");
21392 Ok(())
21393 }
21394
21395 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
21398 let needs_parens = matches!(&s.this, Expression::JsonExtract(ref f) if f.arrow_syntax);
21402 if needs_parens {
21403 self.write("(");
21404 }
21405 self.generate_expression(&s.this)?;
21406 if needs_parens {
21407 self.write(")");
21408 }
21409 self.write("[");
21410 self.generate_expression(&s.index)?;
21411 self.write("]");
21412 Ok(())
21413 }
21414
21415 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
21416 self.generate_expression(&d.this)?;
21417 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
21420 && matches!(
21421 &d.this,
21422 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
21423 );
21424 if use_colon {
21425 self.write(":");
21426 } else {
21427 self.write(".");
21428 }
21429 self.generate_identifier(&d.field)
21430 }
21431
21432 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
21433 self.generate_expression(&m.this)?;
21434 self.write(".");
21435 if m.method.quoted {
21438 let q = self.config.identifier_quote;
21439 self.write(&format!("{}{}{}", q, m.method.name, q));
21440 } else {
21441 self.write(&m.method.name);
21442 }
21443 self.write("(");
21444 for (i, arg) in m.args.iter().enumerate() {
21445 if i > 0 {
21446 self.write(", ");
21447 }
21448 self.generate_expression(arg)?;
21449 }
21450 self.write(")");
21451 Ok(())
21452 }
21453
21454 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
21455 let needs_parens = matches!(
21458 &s.this,
21459 Expression::JsonExtract(f) if f.arrow_syntax
21460 ) || matches!(
21461 &s.this,
21462 Expression::JsonExtractScalar(f) if f.arrow_syntax
21463 );
21464
21465 if needs_parens {
21466 self.write("(");
21467 }
21468 self.generate_expression(&s.this)?;
21469 if needs_parens {
21470 self.write(")");
21471 }
21472 self.write("[");
21473 if let Some(start) = &s.start {
21474 self.generate_expression(start)?;
21475 }
21476 self.write(":");
21477 if let Some(end) = &s.end {
21478 self.generate_expression(end)?;
21479 }
21480 self.write("]");
21481 Ok(())
21482 }
21483
21484 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
21485 match &op.left {
21489 Expression::Column(col) => {
21490 if let Some(table) = &col.table {
21493 self.generate_identifier(table)?;
21494 self.write(".");
21495 }
21496 self.generate_identifier(&col.name)?;
21497 if col.join_mark && self.config.supports_column_join_marks {
21499 self.write(" (+)");
21500 }
21501 if op.left_comments.is_empty() {
21503 for comment in &col.trailing_comments {
21504 self.write_space();
21505 self.write_formatted_comment(comment);
21506 }
21507 }
21508 }
21509 Expression::Add(inner_op)
21510 | Expression::Sub(inner_op)
21511 | Expression::Mul(inner_op)
21512 | Expression::Div(inner_op)
21513 | Expression::Concat(inner_op) => {
21514 self.generate_binary_op_no_trailing(inner_op, match &op.left {
21516 Expression::Add(_) => "+",
21517 Expression::Sub(_) => "-",
21518 Expression::Mul(_) => "*",
21519 Expression::Div(_) => "/",
21520 Expression::Concat(_) => "||",
21521 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
21522 })?;
21523 }
21524 _ => {
21525 self.generate_expression(&op.left)?;
21526 }
21527 }
21528 for comment in &op.left_comments {
21530 self.write_space();
21531 self.write_formatted_comment(comment);
21532 }
21533 if self.config.pretty
21534 && matches!(self.config.dialect, Some(DialectType::Snowflake))
21535 && (operator == "AND" || operator == "OR")
21536 {
21537 self.write_newline();
21538 self.write_indent();
21539 self.write_keyword(operator);
21540 } else {
21541 self.write_space();
21542 if operator.chars().all(|c| c.is_alphabetic()) {
21543 self.write_keyword(operator);
21544 } else {
21545 self.write(operator);
21546 }
21547 }
21548 for comment in &op.operator_comments {
21550 self.write_space();
21551 self.write_formatted_comment(comment);
21552 }
21553 self.write_space();
21554 self.generate_expression(&op.right)?;
21555 for comment in &op.trailing_comments {
21557 self.write_space();
21558 self.write_formatted_comment(comment);
21559 }
21560 Ok(())
21561 }
21562
21563 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
21564 let keyword = connector.keyword();
21565 let Some(terms) = self.flatten_connector_terms(op, connector) else {
21566 return self.generate_binary_op(op, keyword);
21567 };
21568
21569 self.generate_expression(terms[0])?;
21570 for term in terms.iter().skip(1) {
21571 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
21572 self.write_newline();
21573 self.write_indent();
21574 self.write_keyword(keyword);
21575 } else {
21576 self.write_space();
21577 self.write_keyword(keyword);
21578 }
21579 self.write_space();
21580 self.generate_expression(term)?;
21581 }
21582
21583 Ok(())
21584 }
21585
21586 fn flatten_connector_terms<'a>(
21587 &self,
21588 root: &'a BinaryOp,
21589 connector: ConnectorOperator,
21590 ) -> Option<Vec<&'a Expression>> {
21591 if !root.left_comments.is_empty()
21592 || !root.operator_comments.is_empty()
21593 || !root.trailing_comments.is_empty()
21594 {
21595 return None;
21596 }
21597
21598 let mut terms = Vec::new();
21599 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
21600
21601 while let Some(expr) = stack.pop() {
21602 match (connector, expr) {
21603 (ConnectorOperator::And, Expression::And(inner))
21604 if inner.left_comments.is_empty()
21605 && inner.operator_comments.is_empty()
21606 && inner.trailing_comments.is_empty() =>
21607 {
21608 stack.push(&inner.right);
21609 stack.push(&inner.left);
21610 }
21611 (ConnectorOperator::Or, Expression::Or(inner))
21612 if inner.left_comments.is_empty()
21613 && inner.operator_comments.is_empty()
21614 && inner.trailing_comments.is_empty() =>
21615 {
21616 stack.push(&inner.right);
21617 stack.push(&inner.left);
21618 }
21619 _ => terms.push(expr),
21620 }
21621 }
21622
21623 if terms.len() > 1 {
21624 Some(terms)
21625 } else {
21626 None
21627 }
21628 }
21629
21630 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
21632 self.generate_expression(&op.left)?;
21633 self.write_space();
21634 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
21636 self.write("`ILIKE`");
21637 } else {
21638 self.write_keyword(operator);
21639 }
21640 if let Some(quantifier) = &op.quantifier {
21641 self.write_space();
21642 self.write_keyword(quantifier);
21643 let is_any =
21648 quantifier.eq_ignore_ascii_case("ANY") || quantifier.eq_ignore_ascii_case("SOME");
21649 if !(is_any && matches!(&op.right, Expression::Paren(_))) {
21650 self.write_space();
21651 }
21652 } else {
21653 self.write_space();
21654 }
21655 self.generate_expression(&op.right)?;
21656 if let Some(escape) = &op.escape {
21657 self.write_space();
21658 self.write_keyword("ESCAPE");
21659 self.write_space();
21660 self.generate_expression(escape)?;
21661 }
21662 Ok(())
21663 }
21664
21665 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
21668 use crate::dialects::DialectType;
21669 self.generate_expression(&op.left)?;
21670 self.write_space();
21671 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
21672 self.write("<=>");
21673 } else {
21674 self.write_keyword("IS NOT DISTINCT FROM");
21675 }
21676 self.write_space();
21677 self.generate_expression(&op.right)?;
21678 Ok(())
21679 }
21680
21681 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
21683 self.generate_expression(&op.left)?;
21684 self.write_space();
21685 self.write_keyword("IS DISTINCT FROM");
21686 self.write_space();
21687 self.generate_expression(&op.right)?;
21688 Ok(())
21689 }
21690
21691 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
21693 match &op.left {
21695 Expression::Column(col) => {
21696 if let Some(table) = &col.table {
21697 self.generate_identifier(table)?;
21698 self.write(".");
21699 }
21700 self.generate_identifier(&col.name)?;
21701 if col.join_mark && self.config.supports_column_join_marks {
21703 self.write(" (+)");
21704 }
21705 }
21706 Expression::Add(inner_op)
21707 | Expression::Sub(inner_op)
21708 | Expression::Mul(inner_op)
21709 | Expression::Div(inner_op)
21710 | Expression::Concat(inner_op) => {
21711 self.generate_binary_op_no_trailing(inner_op, match &op.left {
21712 Expression::Add(_) => "+",
21713 Expression::Sub(_) => "-",
21714 Expression::Mul(_) => "*",
21715 Expression::Div(_) => "/",
21716 Expression::Concat(_) => "||",
21717 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
21718 })?;
21719 }
21720 _ => {
21721 self.generate_expression(&op.left)?;
21722 }
21723 }
21724 for comment in &op.left_comments {
21726 self.write_space();
21727 self.write_formatted_comment(comment);
21728 }
21729 self.write_space();
21730 if operator.chars().all(|c| c.is_alphabetic()) {
21731 self.write_keyword(operator);
21732 } else {
21733 self.write(operator);
21734 }
21735 for comment in &op.operator_comments {
21737 self.write_space();
21738 self.write_formatted_comment(comment);
21739 }
21740 self.write_space();
21741 match &op.right {
21744 Expression::Column(col) => {
21745 if let Some(table) = &col.table {
21746 self.generate_identifier(table)?;
21747 self.write(".");
21748 }
21749 self.generate_identifier(&col.name)?;
21750 if col.join_mark && self.config.supports_column_join_marks {
21752 self.write(" (+)");
21753 }
21754 }
21755 _ => {
21756 self.generate_expression(&op.right)?;
21757 }
21758 }
21759 Ok(())
21761 }
21762
21763 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
21764 if operator.chars().all(|c| c.is_alphabetic()) {
21765 self.write_keyword(operator);
21766 self.write_space();
21767 } else {
21768 self.write(operator);
21769 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
21771 self.write_space();
21772 }
21773 }
21774 self.generate_expression(&op.this)
21775 }
21776
21777 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
21778 let is_generic =
21782 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
21783 let use_prefix_not =
21784 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
21785 if use_prefix_not {
21786 self.write_keyword("NOT");
21787 self.write_space();
21788 }
21789 self.generate_expression(&in_expr.this)?;
21790 if in_expr.global {
21791 self.write_space();
21792 self.write_keyword("GLOBAL");
21793 }
21794 if in_expr.not && !use_prefix_not {
21795 self.write_space();
21796 self.write_keyword("NOT");
21797 }
21798 self.write_space();
21799 self.write_keyword("IN");
21800
21801 if let Some(unnest_expr) = &in_expr.unnest {
21803 self.write_space();
21804 self.write_keyword("UNNEST");
21805 self.write("(");
21806 self.generate_expression(unnest_expr)?;
21807 self.write(")");
21808 return Ok(());
21809 }
21810
21811 if let Some(query) = &in_expr.query {
21812 let is_bare = in_expr.expressions.is_empty()
21815 && !matches!(
21816 query,
21817 Expression::Select(_)
21818 | Expression::Union(_)
21819 | Expression::Intersect(_)
21820 | Expression::Except(_)
21821 | Expression::Subquery(_)
21822 );
21823 if is_bare {
21824 self.write_space();
21826 self.generate_expression(query)?;
21827 } else {
21828 self.write(" (");
21830 let is_statement = matches!(
21831 query,
21832 Expression::Select(_)
21833 | Expression::Union(_)
21834 | Expression::Intersect(_)
21835 | Expression::Except(_)
21836 | Expression::Subquery(_)
21837 );
21838 if self.config.pretty && is_statement {
21839 self.write_newline();
21840 self.indent_level += 1;
21841 self.write_indent();
21842 }
21843 self.generate_expression(query)?;
21844 if self.config.pretty && is_statement {
21845 self.write_newline();
21846 self.indent_level -= 1;
21847 self.write_indent();
21848 }
21849 self.write(")");
21850 }
21851 } else {
21852 let is_duckdb = matches!(
21856 self.config.dialect,
21857 Some(crate::dialects::DialectType::DuckDB)
21858 );
21859 let is_clickhouse = matches!(
21860 self.config.dialect,
21861 Some(crate::dialects::DialectType::ClickHouse)
21862 );
21863 let single_expr = in_expr.expressions.len() == 1;
21864 if is_clickhouse && single_expr {
21865 if let Expression::Array(arr) = &in_expr.expressions[0] {
21866 self.write(" (");
21868 for (i, expr) in arr.expressions.iter().enumerate() {
21869 if i > 0 {
21870 self.write(", ");
21871 }
21872 self.generate_expression(expr)?;
21873 }
21874 self.write(")");
21875 } else {
21876 self.write_space();
21877 self.generate_expression(&in_expr.expressions[0])?;
21878 }
21879 } else {
21880 let is_bare_ref = single_expr
21881 && matches!(
21882 &in_expr.expressions[0],
21883 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
21884 );
21885 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
21886 self.write_space();
21889 self.generate_expression(&in_expr.expressions[0])?;
21890 } else {
21891 self.write(" (");
21893 for (i, expr) in in_expr.expressions.iter().enumerate() {
21894 if i > 0 {
21895 self.write(", ");
21896 }
21897 self.generate_expression(expr)?;
21898 }
21899 self.write(")");
21900 }
21901 }
21902 }
21903
21904 Ok(())
21905 }
21906
21907 fn generate_between(&mut self, between: &Between) -> Result<()> {
21908 let use_prefix_not = between.not
21910 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
21911 if use_prefix_not {
21912 self.write_keyword("NOT");
21913 self.write_space();
21914 }
21915 self.generate_expression(&between.this)?;
21916 if between.not && !use_prefix_not {
21917 self.write_space();
21918 self.write_keyword("NOT");
21919 }
21920 self.write_space();
21921 self.write_keyword("BETWEEN");
21922 if let Some(sym) = between.symmetric {
21924 if sym {
21925 self.write(" SYMMETRIC");
21926 } else {
21927 self.write(" ASYMMETRIC");
21928 }
21929 }
21930 self.write_space();
21931 self.generate_expression(&between.low)?;
21932 self.write_space();
21933 self.write_keyword("AND");
21934 self.write_space();
21935 self.generate_expression(&between.high)
21936 }
21937
21938 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
21939 let use_prefix_not = is_null.not
21941 && (self.config.dialect.is_none()
21942 || self.config.dialect == Some(DialectType::Generic)
21943 || is_null.postfix_form);
21944 if use_prefix_not {
21945 self.write_keyword("NOT");
21947 self.write_space();
21948 self.generate_expression(&is_null.this)?;
21949 self.write_space();
21950 self.write_keyword("IS");
21951 self.write_space();
21952 self.write_keyword("NULL");
21953 } else {
21954 self.generate_expression(&is_null.this)?;
21955 self.write_space();
21956 self.write_keyword("IS");
21957 if is_null.not {
21958 self.write_space();
21959 self.write_keyword("NOT");
21960 }
21961 self.write_space();
21962 self.write_keyword("NULL");
21963 }
21964 Ok(())
21965 }
21966
21967 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
21968 self.generate_expression(&is_true.this)?;
21969 self.write_space();
21970 self.write_keyword("IS");
21971 if is_true.not {
21972 self.write_space();
21973 self.write_keyword("NOT");
21974 }
21975 self.write_space();
21976 self.write_keyword("TRUE");
21977 Ok(())
21978 }
21979
21980 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
21981 self.generate_expression(&is_false.this)?;
21982 self.write_space();
21983 self.write_keyword("IS");
21984 if is_false.not {
21985 self.write_space();
21986 self.write_keyword("NOT");
21987 }
21988 self.write_space();
21989 self.write_keyword("FALSE");
21990 Ok(())
21991 }
21992
21993 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
21994 self.generate_expression(&is_json.this)?;
21995 self.write_space();
21996 self.write_keyword("IS");
21997 if is_json.negated {
21998 self.write_space();
21999 self.write_keyword("NOT");
22000 }
22001 self.write_space();
22002 self.write_keyword("JSON");
22003
22004 if let Some(ref json_type) = is_json.json_type {
22006 self.write_space();
22007 self.write_keyword(json_type);
22008 }
22009
22010 match &is_json.unique_keys {
22012 Some(JsonUniqueKeys::With) => {
22013 self.write_space();
22014 self.write_keyword("WITH UNIQUE KEYS");
22015 }
22016 Some(JsonUniqueKeys::Without) => {
22017 self.write_space();
22018 self.write_keyword("WITHOUT UNIQUE KEYS");
22019 }
22020 Some(JsonUniqueKeys::Shorthand) => {
22021 self.write_space();
22022 self.write_keyword("UNIQUE KEYS");
22023 }
22024 None => {}
22025 }
22026
22027 Ok(())
22028 }
22029
22030 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
22031 self.generate_expression(&is_expr.left)?;
22032 self.write_space();
22033 self.write_keyword("IS");
22034 self.write_space();
22035 self.generate_expression(&is_expr.right)
22036 }
22037
22038 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
22039 if exists.not {
22040 self.write_keyword("NOT");
22041 self.write_space();
22042 }
22043 self.write_keyword("EXISTS");
22044 self.write("(");
22045 let is_statement = matches!(
22046 &exists.this,
22047 Expression::Select(_)
22048 | Expression::Union(_)
22049 | Expression::Intersect(_)
22050 | Expression::Except(_)
22051 );
22052 if self.config.pretty && is_statement {
22053 self.write_newline();
22054 self.indent_level += 1;
22055 self.write_indent();
22056 self.generate_expression(&exists.this)?;
22057 self.write_newline();
22058 self.indent_level -= 1;
22059 self.write_indent();
22060 self.write(")");
22061 } else {
22062 self.generate_expression(&exists.this)?;
22063 self.write(")");
22064 }
22065 Ok(())
22066 }
22067
22068 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
22069 self.generate_expression(&op.left)?;
22070 self.write_space();
22071 self.write_keyword("MEMBER OF");
22072 self.write("(");
22073 self.generate_expression(&op.right)?;
22074 self.write(")");
22075 Ok(())
22076 }
22077
22078 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
22079 if subquery.lateral {
22080 self.write_keyword("LATERAL");
22081 self.write_space();
22082 }
22083
22084 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
22088 matches!(
22089 &p.this,
22090 Expression::Select(_)
22091 | Expression::Union(_)
22092 | Expression::Intersect(_)
22093 | Expression::Except(_)
22094 | Expression::Subquery(_)
22095 )
22096 } else {
22097 false
22098 };
22099
22100 let is_statement = matches!(
22102 &subquery.this,
22103 Expression::Select(_)
22104 | Expression::Union(_)
22105 | Expression::Intersect(_)
22106 | Expression::Except(_)
22107 | Expression::Merge(_)
22108 );
22109
22110 if !skip_outer_parens {
22111 self.write("(");
22112 if self.config.pretty && is_statement {
22113 self.write_newline();
22114 self.indent_level += 1;
22115 self.write_indent();
22116 }
22117 }
22118 self.generate_expression(&subquery.this)?;
22119
22120 if subquery.modifiers_inside {
22122 if let Some(order_by) = &subquery.order_by {
22124 self.write_space();
22125 self.write_keyword("ORDER BY");
22126 self.write_space();
22127 for (i, ord) in order_by.expressions.iter().enumerate() {
22128 if i > 0 {
22129 self.write(", ");
22130 }
22131 self.generate_ordered(ord)?;
22132 }
22133 }
22134
22135 if let Some(limit) = &subquery.limit {
22136 self.write_space();
22137 self.write_keyword("LIMIT");
22138 self.write_space();
22139 self.generate_expression(&limit.this)?;
22140 if limit.percent {
22141 self.write_space();
22142 self.write_keyword("PERCENT");
22143 }
22144 }
22145
22146 if let Some(offset) = &subquery.offset {
22147 self.write_space();
22148 self.write_keyword("OFFSET");
22149 self.write_space();
22150 self.generate_expression(&offset.this)?;
22151 }
22152 }
22153
22154 if !skip_outer_parens {
22155 if self.config.pretty && is_statement {
22156 self.write_newline();
22157 self.indent_level -= 1;
22158 self.write_indent();
22159 }
22160 self.write(")");
22161 }
22162
22163 if !subquery.modifiers_inside {
22165 if let Some(order_by) = &subquery.order_by {
22166 self.write_space();
22167 self.write_keyword("ORDER BY");
22168 self.write_space();
22169 for (i, ord) in order_by.expressions.iter().enumerate() {
22170 if i > 0 {
22171 self.write(", ");
22172 }
22173 self.generate_ordered(ord)?;
22174 }
22175 }
22176
22177 if let Some(limit) = &subquery.limit {
22178 self.write_space();
22179 self.write_keyword("LIMIT");
22180 self.write_space();
22181 self.generate_expression(&limit.this)?;
22182 if limit.percent {
22183 self.write_space();
22184 self.write_keyword("PERCENT");
22185 }
22186 }
22187
22188 if let Some(offset) = &subquery.offset {
22189 self.write_space();
22190 self.write_keyword("OFFSET");
22191 self.write_space();
22192 self.generate_expression(&offset.this)?;
22193 }
22194
22195 if let Some(distribute_by) = &subquery.distribute_by {
22197 self.write_space();
22198 self.write_keyword("DISTRIBUTE BY");
22199 self.write_space();
22200 for (i, expr) in distribute_by.expressions.iter().enumerate() {
22201 if i > 0 {
22202 self.write(", ");
22203 }
22204 self.generate_expression(expr)?;
22205 }
22206 }
22207
22208 if let Some(sort_by) = &subquery.sort_by {
22210 self.write_space();
22211 self.write_keyword("SORT BY");
22212 self.write_space();
22213 for (i, ord) in sort_by.expressions.iter().enumerate() {
22214 if i > 0 {
22215 self.write(", ");
22216 }
22217 self.generate_ordered(ord)?;
22218 }
22219 }
22220
22221 if let Some(cluster_by) = &subquery.cluster_by {
22223 self.write_space();
22224 self.write_keyword("CLUSTER BY");
22225 self.write_space();
22226 for (i, ord) in cluster_by.expressions.iter().enumerate() {
22227 if i > 0 {
22228 self.write(", ");
22229 }
22230 self.generate_ordered(ord)?;
22231 }
22232 }
22233 }
22234
22235 if let Some(alias) = &subquery.alias {
22236 self.write_space();
22237 let skip_as = matches!(
22239 self.config.dialect,
22240 Some(crate::dialects::DialectType::Oracle)
22241 );
22242 if !skip_as {
22243 self.write_keyword("AS");
22244 self.write_space();
22245 }
22246 self.generate_identifier(alias)?;
22247 if !subquery.column_aliases.is_empty() {
22248 self.write("(");
22249 for (i, col) in subquery.column_aliases.iter().enumerate() {
22250 if i > 0 {
22251 self.write(", ");
22252 }
22253 self.generate_identifier(col)?;
22254 }
22255 self.write(")");
22256 }
22257 }
22258 for comment in &subquery.trailing_comments {
22260 self.write(" ");
22261 self.write_formatted_comment(comment);
22262 }
22263 Ok(())
22264 }
22265
22266 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
22267 if let Some(ref with) = pivot.with {
22269 self.generate_with(with)?;
22270 self.write_space();
22271 }
22272
22273 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
22274
22275 let is_redshift_unpivot = pivot.unpivot
22279 && pivot.expressions.is_empty()
22280 && pivot.fields.is_empty()
22281 && pivot.using.is_empty()
22282 && pivot.into.is_none()
22283 && !matches!(&pivot.this, Expression::Null(_));
22284
22285 if is_redshift_unpivot {
22286 self.write_keyword("UNPIVOT");
22288 self.write_space();
22289 self.generate_expression(&pivot.this)?;
22290 if let Some(alias) = &pivot.alias {
22292 self.write_space();
22293 self.write_keyword("AS");
22294 self.write_space();
22295 self.write(&alias.name);
22297 }
22298 return Ok(());
22299 }
22300
22301 let is_simplified = !pivot.using.is_empty()
22303 || pivot.into.is_some()
22304 || (pivot.fields.is_empty()
22305 && !pivot.expressions.is_empty()
22306 && !matches!(&pivot.this, Expression::Null(_)));
22307
22308 if is_simplified {
22309 self.write_keyword(direction);
22313 self.write_space();
22314 self.generate_expression(&pivot.this)?;
22315
22316 if !pivot.expressions.is_empty() {
22317 self.write_space();
22318 self.write_keyword("ON");
22319 self.write_space();
22320 for (i, expr) in pivot.expressions.iter().enumerate() {
22321 if i > 0 {
22322 self.write(", ");
22323 }
22324 self.generate_expression(expr)?;
22325 }
22326 }
22327
22328 if let Some(into) = &pivot.into {
22330 self.write_space();
22331 self.write_keyword("INTO");
22332 self.write_space();
22333 self.generate_expression(into)?;
22334 }
22335
22336 if !pivot.using.is_empty() {
22338 self.write_space();
22339 self.write_keyword("USING");
22340 self.write_space();
22341 for (i, expr) in pivot.using.iter().enumerate() {
22342 if i > 0 {
22343 self.write(", ");
22344 }
22345 self.generate_expression(expr)?;
22346 }
22347 }
22348
22349 if let Some(group) = &pivot.group {
22351 self.write_space();
22352 self.generate_expression(group)?;
22353 }
22354 } else {
22355 if !matches!(&pivot.this, Expression::Null(_)) {
22360 self.generate_expression(&pivot.this)?;
22361 self.write_space();
22362 }
22363 self.write_keyword(direction);
22364 self.write("(");
22365
22366 for (i, expr) in pivot.expressions.iter().enumerate() {
22368 if i > 0 {
22369 self.write(", ");
22370 }
22371 self.generate_expression(expr)?;
22372 }
22373
22374 if !pivot.fields.is_empty() {
22376 if !pivot.expressions.is_empty() {
22377 self.write_space();
22378 }
22379 self.write_keyword("FOR");
22380 self.write_space();
22381 for (i, field) in pivot.fields.iter().enumerate() {
22382 if i > 0 {
22383 self.write_space();
22384 }
22385 self.generate_expression(field)?;
22387 }
22388 }
22389
22390 if let Some(default_val) = &pivot.default_on_null {
22392 self.write_space();
22393 self.write_keyword("DEFAULT ON NULL");
22394 self.write(" (");
22395 self.generate_expression(default_val)?;
22396 self.write(")");
22397 }
22398
22399 if let Some(group) = &pivot.group {
22401 self.write_space();
22402 self.generate_expression(group)?;
22403 }
22404
22405 self.write(")");
22406 }
22407
22408 if let Some(alias) = &pivot.alias {
22410 self.write_space();
22411 self.write_keyword("AS");
22412 self.write_space();
22413 self.generate_identifier(alias)?;
22414 }
22415
22416 Ok(())
22417 }
22418
22419 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
22420 self.generate_expression(&unpivot.this)?;
22421 self.write_space();
22422 self.write_keyword("UNPIVOT");
22423 if let Some(include) = unpivot.include_nulls {
22425 self.write_space();
22426 if include {
22427 self.write_keyword("INCLUDE NULLS");
22428 } else {
22429 self.write_keyword("EXCLUDE NULLS");
22430 }
22431 self.write_space();
22432 }
22433 self.write("(");
22434 if unpivot.value_column_parenthesized {
22435 self.write("(");
22436 }
22437 self.generate_identifier(&unpivot.value_column)?;
22438 for extra_col in &unpivot.extra_value_columns {
22440 self.write(", ");
22441 self.generate_identifier(extra_col)?;
22442 }
22443 if unpivot.value_column_parenthesized {
22444 self.write(")");
22445 }
22446 self.write_space();
22447 self.write_keyword("FOR");
22448 self.write_space();
22449 self.generate_identifier(&unpivot.name_column)?;
22450 self.write_space();
22451 self.write_keyword("IN");
22452 self.write(" (");
22453 for (i, col) in unpivot.columns.iter().enumerate() {
22454 if i > 0 {
22455 self.write(", ");
22456 }
22457 self.generate_expression(col)?;
22458 }
22459 self.write("))");
22460 if let Some(alias) = &unpivot.alias {
22461 self.write_space();
22462 self.write_keyword("AS");
22463 self.write_space();
22464 self.generate_identifier(alias)?;
22465 }
22466 Ok(())
22467 }
22468
22469 fn generate_values(&mut self, values: &Values) -> Result<()> {
22470 self.write_keyword("VALUES");
22471 for (i, row) in values.expressions.iter().enumerate() {
22472 if i > 0 {
22473 self.write(",");
22474 }
22475 self.write(" (");
22476 for (j, expr) in row.expressions.iter().enumerate() {
22477 if j > 0 {
22478 self.write(", ");
22479 }
22480 self.generate_expression(expr)?;
22481 }
22482 self.write(")");
22483 }
22484 if let Some(alias) = &values.alias {
22485 self.write_space();
22486 self.write_keyword("AS");
22487 self.write_space();
22488 self.generate_identifier(alias)?;
22489 if !values.column_aliases.is_empty() {
22490 self.write("(");
22491 for (i, col) in values.column_aliases.iter().enumerate() {
22492 if i > 0 {
22493 self.write(", ");
22494 }
22495 self.generate_identifier(col)?;
22496 }
22497 self.write(")");
22498 }
22499 }
22500 Ok(())
22501 }
22502
22503 fn generate_array(&mut self, arr: &Array) -> Result<()> {
22504 let needs_inheritance = matches!(
22506 self.config.dialect,
22507 Some(DialectType::DuckDB)
22508 | Some(DialectType::Spark)
22509 | Some(DialectType::Databricks)
22510 | Some(DialectType::Hive)
22511 | Some(DialectType::Snowflake)
22512 | Some(DialectType::Presto)
22513 | Some(DialectType::Trino)
22514 );
22515 let propagated: Vec<Expression>;
22516 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
22517 propagated = Self::inherit_struct_field_names(&arr.expressions);
22518 &propagated
22519 } else {
22520 &arr.expressions
22521 };
22522
22523 let use_parens =
22526 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
22527 if !self.config.array_bracket_only {
22528 self.write_keyword("ARRAY");
22529 }
22530 if use_parens {
22531 self.write("(");
22532 } else {
22533 self.write("[");
22534 }
22535 for (i, expr) in expressions.iter().enumerate() {
22536 if i > 0 {
22537 self.write(", ");
22538 }
22539 self.generate_expression(expr)?;
22540 }
22541 if use_parens {
22542 self.write(")");
22543 } else {
22544 self.write("]");
22545 }
22546 Ok(())
22547 }
22548
22549 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
22550 if tuple.expressions.len() == 2 {
22553 if let Expression::TableAlias(_) = &tuple.expressions[1] {
22554 self.generate_expression(&tuple.expressions[0])?;
22556 self.write_space();
22557 self.write_keyword("AS");
22558 self.write_space();
22559 self.generate_expression(&tuple.expressions[1])?;
22560 return Ok(());
22561 }
22562 }
22563
22564 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
22567 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
22568 for expr in &tuple.expressions {
22569 expr_strings.push(self.generate_to_string(expr)?);
22570 }
22571 self.too_wide(&expr_strings)
22572 } else {
22573 false
22574 };
22575
22576 if expand_tuple {
22577 self.write("(");
22578 self.write_newline();
22579 self.indent_level += 1;
22580 for (i, expr) in tuple.expressions.iter().enumerate() {
22581 if i > 0 {
22582 self.write(",");
22583 self.write_newline();
22584 }
22585 self.write_indent();
22586 self.generate_expression(expr)?;
22587 }
22588 self.indent_level -= 1;
22589 self.write_newline();
22590 self.write_indent();
22591 self.write(")");
22592 } else {
22593 self.write("(");
22594 for (i, expr) in tuple.expressions.iter().enumerate() {
22595 if i > 0 {
22596 self.write(", ");
22597 }
22598 self.generate_expression(expr)?;
22599 }
22600 self.write(")");
22601 }
22602 Ok(())
22603 }
22604
22605 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
22606 self.generate_expression(&pipe.this)?;
22607 self.write(" |> ");
22608 self.generate_expression(&pipe.expression)?;
22609 Ok(())
22610 }
22611
22612 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
22613 self.generate_expression(&ordered.this)?;
22614 if ordered.desc {
22615 self.write_space();
22616 self.write_keyword("DESC");
22617 } else if ordered.explicit_asc {
22618 self.write_space();
22619 self.write_keyword("ASC");
22620 }
22621 if let Some(nulls_first) = ordered.nulls_first {
22622 let is_asc = !ordered.desc;
22636 let is_nulls_are_large = matches!(
22637 self.config.dialect,
22638 Some(DialectType::Oracle)
22639 | Some(DialectType::PostgreSQL)
22640 | Some(DialectType::Redshift)
22641 | Some(DialectType::Snowflake)
22642 );
22643 let is_nulls_are_last = matches!(
22644 self.config.dialect,
22645 Some(DialectType::Dremio)
22646 | Some(DialectType::DuckDB)
22647 | Some(DialectType::Presto)
22648 | Some(DialectType::Trino)
22649 | Some(DialectType::Athena)
22650 | Some(DialectType::ClickHouse)
22651 | Some(DialectType::Drill)
22652 | Some(DialectType::Exasol)
22653 );
22654
22655 let is_default_nulls = if is_nulls_are_large {
22657 (is_asc && !nulls_first) || (!is_asc && nulls_first)
22659 } else if is_nulls_are_last {
22660 !nulls_first
22662 } else {
22663 false
22664 };
22665
22666 if !is_default_nulls {
22667 self.write_space();
22668 self.write_keyword("NULLS");
22669 self.write_space();
22670 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
22671 }
22672 }
22673 if let Some(ref with_fill) = ordered.with_fill {
22675 self.write_space();
22676 self.generate_with_fill(with_fill)?;
22677 }
22678 Ok(())
22679 }
22680
22681 fn write_clickhouse_type(&mut self, type_str: &str) {
22683 if self.clickhouse_nullable_depth < 0 {
22684 self.write(type_str);
22686 } else {
22687 self.write(&format!("Nullable({})", type_str));
22688 }
22689 }
22690
22691 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
22692 use crate::dialects::DialectType;
22693
22694 match dt {
22695 DataType::Boolean => {
22696 match self.config.dialect {
22698 Some(DialectType::TSQL) => self.write_keyword("BIT"),
22699 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
22701 self.write_keyword("NUMBER(1)")
22703 }
22704 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
22706 }
22707 }
22708 DataType::TinyInt { length } => {
22709 match self.config.dialect {
22713 Some(DialectType::PostgreSQL)
22714 | Some(DialectType::Redshift)
22715 | Some(DialectType::Oracle)
22716 | Some(DialectType::Exasol) => {
22717 self.write_keyword("SMALLINT");
22718 }
22719 Some(DialectType::Teradata) => {
22720 self.write_keyword("BYTEINT");
22722 }
22723 Some(DialectType::Dremio) => {
22724 self.write_keyword("INT");
22726 }
22727 Some(DialectType::ClickHouse) => {
22728 self.write_clickhouse_type("Int8");
22729 }
22730 _ => {
22731 self.write_keyword("TINYINT");
22732 }
22733 }
22734 if let Some(n) = length {
22735 if !matches!(
22736 self.config.dialect,
22737 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
22738 ) {
22739 self.write(&format!("({})", n));
22740 }
22741 }
22742 }
22743 DataType::SmallInt { length } => {
22744 match self.config.dialect {
22746 Some(DialectType::Dremio) => {
22747 self.write_keyword("INT");
22748 }
22749 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
22750 self.write_keyword("INTEGER");
22751 }
22752 Some(DialectType::BigQuery) => {
22753 self.write_keyword("INT64");
22754 }
22755 Some(DialectType::ClickHouse) => {
22756 self.write_clickhouse_type("Int16");
22757 }
22758 _ => {
22759 self.write_keyword("SMALLINT");
22760 if let Some(n) = length {
22761 self.write(&format!("({})", n));
22762 }
22763 }
22764 }
22765 }
22766 DataType::Int {
22767 length,
22768 integer_spelling: _,
22769 } => {
22770 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
22772 self.write_keyword("INT64");
22773 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22774 self.write_clickhouse_type("Int32");
22775 } else {
22776 let use_integer = match self.config.dialect {
22778 Some(DialectType::TSQL)
22779 | Some(DialectType::Fabric)
22780 | Some(DialectType::Presto)
22781 | Some(DialectType::Trino)
22782 | Some(DialectType::SQLite)
22783 | Some(DialectType::Redshift) => true,
22784 _ => false,
22785 };
22786 if use_integer {
22787 self.write_keyword("INTEGER");
22788 } else {
22789 self.write_keyword("INT");
22790 }
22791 if let Some(n) = length {
22792 self.write(&format!("({})", n));
22793 }
22794 }
22795 }
22796 DataType::BigInt { length } => {
22797 match self.config.dialect {
22799 Some(DialectType::Oracle) => {
22800 self.write_keyword("INT");
22802 }
22803 Some(DialectType::ClickHouse) => {
22804 self.write_clickhouse_type("Int64");
22805 }
22806 _ => {
22807 self.write_keyword("BIGINT");
22808 if let Some(n) = length {
22809 self.write(&format!("({})", n));
22810 }
22811 }
22812 }
22813 }
22814 DataType::Float {
22815 precision,
22816 scale,
22817 real_spelling,
22818 } => {
22819 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22823 self.write_clickhouse_type("Float32");
22824 } else if *real_spelling
22825 && !matches!(
22826 self.config.dialect,
22827 Some(DialectType::Spark)
22828 | Some(DialectType::Databricks)
22829 | Some(DialectType::Hive)
22830 | Some(DialectType::Snowflake)
22831 | Some(DialectType::MySQL)
22832 | Some(DialectType::BigQuery)
22833 )
22834 {
22835 self.write_keyword("REAL")
22836 } else {
22837 match self.config.dialect {
22838 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
22839 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
22840 _ => self.write_keyword("FLOAT"),
22841 }
22842 }
22843 if !matches!(
22846 self.config.dialect,
22847 Some(DialectType::Spark)
22848 | Some(DialectType::Databricks)
22849 | Some(DialectType::Hive)
22850 | Some(DialectType::Presto)
22851 | Some(DialectType::Trino)
22852 ) {
22853 if let Some(p) = precision {
22854 self.write(&format!("({}", p));
22855 if let Some(s) = scale {
22856 self.write(&format!(", {})", s));
22857 } else {
22858 self.write(")");
22859 }
22860 }
22861 }
22862 }
22863 DataType::Double { precision, scale } => {
22864 match self.config.dialect {
22866 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22867 self.write_keyword("FLOAT")
22868 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
22870 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
22871 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
22872 Some(DialectType::SQLite) => self.write_keyword("REAL"),
22873 Some(DialectType::PostgreSQL)
22874 | Some(DialectType::Redshift)
22875 | Some(DialectType::Teradata)
22876 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
22877 _ => self.write_keyword("DOUBLE"),
22878 }
22879 if let Some(p) = precision {
22881 self.write(&format!("({}", p));
22882 if let Some(s) = scale {
22883 self.write(&format!(", {})", s));
22884 } else {
22885 self.write(")");
22886 }
22887 }
22888 }
22889 DataType::Decimal { precision, scale } => {
22890 match self.config.dialect {
22892 Some(DialectType::ClickHouse) => {
22893 self.write("Decimal");
22894 if let Some(p) = precision {
22895 self.write(&format!("({}", p));
22896 if let Some(s) = scale {
22897 self.write(&format!(", {}", s));
22898 }
22899 self.write(")");
22900 }
22901 }
22902 Some(DialectType::Oracle) => {
22903 self.write_keyword("NUMBER");
22905 if let Some(p) = precision {
22906 self.write(&format!("({}", p));
22907 if let Some(s) = scale {
22908 self.write(&format!(", {}", s));
22909 }
22910 self.write(")");
22911 }
22912 }
22913 Some(DialectType::BigQuery) => {
22914 self.write_keyword("NUMERIC");
22916 if let Some(p) = precision {
22917 self.write(&format!("({}", p));
22918 if let Some(s) = scale {
22919 self.write(&format!(", {}", s));
22920 }
22921 self.write(")");
22922 }
22923 }
22924 _ => {
22925 self.write_keyword("DECIMAL");
22926 if let Some(p) = precision {
22927 self.write(&format!("({}", p));
22928 if let Some(s) = scale {
22929 self.write(&format!(", {}", s));
22930 }
22931 self.write(")");
22932 }
22933 }
22934 }
22935 }
22936 DataType::Char { length } => {
22937 match self.config.dialect {
22939 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
22940 self.write_keyword("TEXT");
22942 }
22943 Some(DialectType::Hive)
22944 | Some(DialectType::Spark)
22945 | Some(DialectType::Databricks) => {
22946 if length.is_some()
22949 && !matches!(self.config.dialect, Some(DialectType::Hive))
22950 {
22951 self.write_keyword("CHAR");
22952 if let Some(n) = length {
22953 self.write(&format!("({})", n));
22954 }
22955 } else {
22956 self.write_keyword("STRING");
22957 }
22958 }
22959 Some(DialectType::Dremio) => {
22960 self.write_keyword("VARCHAR");
22962 if let Some(n) = length {
22963 self.write(&format!("({})", n));
22964 }
22965 }
22966 _ => {
22967 self.write_keyword("CHAR");
22968 if let Some(n) = length {
22969 self.write(&format!("({})", n));
22970 }
22971 }
22972 }
22973 }
22974 DataType::VarChar {
22975 length,
22976 parenthesized_length,
22977 } => {
22978 match self.config.dialect {
22980 Some(DialectType::Oracle) => {
22981 self.write_keyword("VARCHAR2");
22982 if let Some(n) = length {
22983 self.write(&format!("({})", n));
22984 }
22985 }
22986 Some(DialectType::DuckDB) => {
22987 self.write_keyword("TEXT");
22989 if let Some(n) = length {
22990 self.write(&format!("({})", n));
22991 }
22992 }
22993 Some(DialectType::SQLite) => {
22994 self.write_keyword("TEXT");
22996 if let Some(n) = length {
22997 self.write(&format!("({})", n));
22998 }
22999 }
23000 Some(DialectType::MySQL) if length.is_none() => {
23001 self.write_keyword("TEXT");
23003 }
23004 Some(DialectType::Hive)
23005 | Some(DialectType::Spark)
23006 | Some(DialectType::Databricks)
23007 if length.is_none() =>
23008 {
23009 self.write_keyword("STRING");
23011 }
23012 _ => {
23013 self.write_keyword("VARCHAR");
23014 if let Some(n) = length {
23015 if *parenthesized_length {
23017 self.write(&format!("(({}))", n));
23018 } else {
23019 self.write(&format!("({})", n));
23020 }
23021 }
23022 }
23023 }
23024 }
23025 DataType::Text => {
23026 match self.config.dialect {
23028 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
23029 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23030 self.write_keyword("VARCHAR(MAX)")
23031 }
23032 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
23033 Some(DialectType::Snowflake)
23034 | Some(DialectType::Dremio)
23035 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
23036 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
23037 Some(DialectType::Presto)
23038 | Some(DialectType::Trino)
23039 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
23040 Some(DialectType::Spark)
23041 | Some(DialectType::Databricks)
23042 | Some(DialectType::Hive) => self.write_keyword("STRING"),
23043 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
23044 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
23045 self.write_keyword("STRING")
23046 }
23047 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
23048 _ => self.write_keyword("TEXT"),
23049 }
23050 }
23051 DataType::TextWithLength { length } => {
23052 match self.config.dialect {
23054 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
23055 Some(DialectType::Hive)
23056 | Some(DialectType::Spark)
23057 | Some(DialectType::Databricks) => {
23058 self.write(&format!("VARCHAR({})", length));
23059 }
23060 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
23061 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
23062 Some(DialectType::Snowflake)
23063 | Some(DialectType::Presto)
23064 | Some(DialectType::Trino)
23065 | Some(DialectType::Athena)
23066 | Some(DialectType::Drill)
23067 | Some(DialectType::Dremio) => {
23068 self.write(&format!("VARCHAR({})", length));
23069 }
23070 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23071 self.write(&format!("VARCHAR({})", length))
23072 }
23073 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
23074 self.write(&format!("STRING({})", length))
23075 }
23076 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
23077 _ => self.write(&format!("TEXT({})", length)),
23078 }
23079 }
23080 DataType::String { length } => {
23081 match self.config.dialect {
23083 Some(DialectType::ClickHouse) => {
23084 self.write("String");
23086 if let Some(n) = length {
23087 self.write(&format!("({})", n));
23088 }
23089 }
23090 Some(DialectType::BigQuery)
23091 | Some(DialectType::Hive)
23092 | Some(DialectType::Spark)
23093 | Some(DialectType::Databricks)
23094 | Some(DialectType::StarRocks)
23095 | Some(DialectType::Doris) => {
23096 self.write_keyword("STRING");
23097 if let Some(n) = length {
23098 self.write(&format!("({})", n));
23099 }
23100 }
23101 Some(DialectType::PostgreSQL) => {
23102 if let Some(n) = length {
23104 self.write_keyword("VARCHAR");
23105 self.write(&format!("({})", n));
23106 } else {
23107 self.write_keyword("TEXT");
23108 }
23109 }
23110 Some(DialectType::Redshift) => {
23111 if let Some(n) = length {
23113 self.write_keyword("VARCHAR");
23114 self.write(&format!("({})", n));
23115 } else {
23116 self.write_keyword("VARCHAR(MAX)");
23117 }
23118 }
23119 Some(DialectType::MySQL) => {
23120 if let Some(n) = length {
23122 self.write_keyword("VARCHAR");
23123 self.write(&format!("({})", n));
23124 } else {
23125 self.write_keyword("TEXT");
23126 }
23127 }
23128 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23129 if let Some(n) = length {
23131 self.write_keyword("VARCHAR");
23132 self.write(&format!("({})", n));
23133 } else {
23134 self.write_keyword("VARCHAR(MAX)");
23135 }
23136 }
23137 Some(DialectType::Oracle) => {
23138 self.write_keyword("CLOB");
23140 }
23141 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
23142 self.write_keyword("TEXT");
23144 if let Some(n) = length {
23145 self.write(&format!("({})", n));
23146 }
23147 }
23148 Some(DialectType::Presto)
23149 | Some(DialectType::Trino)
23150 | Some(DialectType::Drill)
23151 | Some(DialectType::Dremio) => {
23152 self.write_keyword("VARCHAR");
23154 if let Some(n) = length {
23155 self.write(&format!("({})", n));
23156 }
23157 }
23158 Some(DialectType::Snowflake) => {
23159 self.write_keyword("STRING");
23162 if let Some(n) = length {
23163 self.write(&format!("({})", n));
23164 }
23165 }
23166 _ => {
23167 self.write_keyword("STRING");
23169 if let Some(n) = length {
23170 self.write(&format!("({})", n));
23171 }
23172 }
23173 }
23174 }
23175 DataType::Binary { length } => {
23176 match self.config.dialect {
23178 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
23179 self.write_keyword("BYTEA");
23180 if let Some(n) = length {
23181 self.write(&format!("({})", n));
23182 }
23183 }
23184 Some(DialectType::Redshift) => {
23185 self.write_keyword("VARBYTE");
23186 if let Some(n) = length {
23187 self.write(&format!("({})", n));
23188 }
23189 }
23190 Some(DialectType::DuckDB)
23191 | Some(DialectType::SQLite)
23192 | Some(DialectType::Oracle) => {
23193 self.write_keyword("BLOB");
23195 if let Some(n) = length {
23196 self.write(&format!("({})", n));
23197 }
23198 }
23199 Some(DialectType::Presto)
23200 | Some(DialectType::Trino)
23201 | Some(DialectType::Athena)
23202 | Some(DialectType::Drill)
23203 | Some(DialectType::Dremio) => {
23204 self.write_keyword("VARBINARY");
23206 if let Some(n) = length {
23207 self.write(&format!("({})", n));
23208 }
23209 }
23210 Some(DialectType::ClickHouse) => {
23211 if self.clickhouse_nullable_depth < 0 {
23213 self.write("BINARY");
23214 } else {
23215 self.write("Nullable(BINARY");
23216 }
23217 if let Some(n) = length {
23218 self.write(&format!("({})", n));
23219 }
23220 if self.clickhouse_nullable_depth >= 0 {
23221 self.write(")");
23222 }
23223 }
23224 _ => {
23225 self.write_keyword("BINARY");
23226 if let Some(n) = length {
23227 self.write(&format!("({})", n));
23228 }
23229 }
23230 }
23231 }
23232 DataType::VarBinary { length } => {
23233 match self.config.dialect {
23235 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
23236 self.write_keyword("BYTEA");
23237 if let Some(n) = length {
23238 self.write(&format!("({})", n));
23239 }
23240 }
23241 Some(DialectType::Redshift) => {
23242 self.write_keyword("VARBYTE");
23243 if let Some(n) = length {
23244 self.write(&format!("({})", n));
23245 }
23246 }
23247 Some(DialectType::DuckDB)
23248 | Some(DialectType::SQLite)
23249 | Some(DialectType::Oracle) => {
23250 self.write_keyword("BLOB");
23252 if let Some(n) = length {
23253 self.write(&format!("({})", n));
23254 }
23255 }
23256 Some(DialectType::Exasol) => {
23257 self.write_keyword("VARCHAR");
23259 }
23260 Some(DialectType::Spark)
23261 | Some(DialectType::Hive)
23262 | Some(DialectType::Databricks) => {
23263 self.write_keyword("BINARY");
23265 if let Some(n) = length {
23266 self.write(&format!("({})", n));
23267 }
23268 }
23269 Some(DialectType::ClickHouse) => {
23270 self.write_clickhouse_type("String");
23272 }
23273 _ => {
23274 self.write_keyword("VARBINARY");
23275 if let Some(n) = length {
23276 self.write(&format!("({})", n));
23277 }
23278 }
23279 }
23280 }
23281 DataType::Blob => {
23282 match self.config.dialect {
23284 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
23285 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
23286 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23287 self.write_keyword("VARBINARY")
23288 }
23289 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
23290 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
23291 Some(DialectType::Presto)
23292 | Some(DialectType::Trino)
23293 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
23294 Some(DialectType::DuckDB) => {
23295 self.write_keyword("VARBINARY");
23298 }
23299 Some(DialectType::Spark)
23300 | Some(DialectType::Databricks)
23301 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
23302 Some(DialectType::ClickHouse) => {
23303 self.write("Nullable(String)");
23307 }
23308 _ => self.write_keyword("BLOB"),
23309 }
23310 }
23311 DataType::Bit { length } => {
23312 match self.config.dialect {
23314 Some(DialectType::Dremio)
23315 | Some(DialectType::Spark)
23316 | Some(DialectType::Databricks)
23317 | Some(DialectType::Hive)
23318 | Some(DialectType::Snowflake)
23319 | Some(DialectType::BigQuery)
23320 | Some(DialectType::Presto)
23321 | Some(DialectType::Trino)
23322 | Some(DialectType::ClickHouse)
23323 | Some(DialectType::Redshift) => {
23324 self.write_keyword("BOOLEAN");
23326 }
23327 _ => {
23328 self.write_keyword("BIT");
23329 if let Some(n) = length {
23330 self.write(&format!("({})", n));
23331 }
23332 }
23333 }
23334 }
23335 DataType::VarBit { length } => {
23336 self.write_keyword("VARBIT");
23337 if let Some(n) = length {
23338 self.write(&format!("({})", n));
23339 }
23340 }
23341 DataType::Date => self.write_keyword("DATE"),
23342 DataType::Time {
23343 precision,
23344 timezone,
23345 } => {
23346 if *timezone {
23347 match self.config.dialect {
23349 Some(DialectType::DuckDB) => {
23350 self.write_keyword("TIMETZ");
23352 }
23353 Some(DialectType::PostgreSQL) => {
23354 self.write_keyword("TIMETZ");
23356 if let Some(p) = precision {
23357 self.write(&format!("({})", p));
23358 }
23359 }
23360 _ => {
23361 self.write_keyword("TIME");
23363 if let Some(p) = precision {
23364 self.write(&format!("({})", p));
23365 }
23366 self.write_keyword(" WITH TIME ZONE");
23367 }
23368 }
23369 } else {
23370 if matches!(
23372 self.config.dialect,
23373 Some(DialectType::Spark)
23374 | Some(DialectType::Databricks)
23375 | Some(DialectType::Hive)
23376 ) {
23377 self.write_keyword("TIMESTAMP");
23378 } else {
23379 self.write_keyword("TIME");
23380 if let Some(p) = precision {
23381 self.write(&format!("({})", p));
23382 }
23383 }
23384 }
23385 }
23386 DataType::Timestamp {
23387 precision,
23388 timezone,
23389 } => {
23390 match self.config.dialect {
23392 Some(DialectType::ClickHouse) => {
23393 self.write("DateTime");
23394 if let Some(p) = precision {
23395 self.write(&format!("({})", p));
23396 }
23397 }
23398 Some(DialectType::TSQL) => {
23399 if *timezone {
23400 self.write_keyword("DATETIMEOFFSET");
23401 } else {
23402 self.write_keyword("DATETIME2");
23403 }
23404 if let Some(p) = precision {
23405 self.write(&format!("({})", p));
23406 }
23407 }
23408 Some(DialectType::MySQL) => {
23409 self.write_keyword("TIMESTAMP");
23411 if let Some(p) = precision {
23412 self.write(&format!("({})", p));
23413 }
23414 }
23415 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
23416 self.write_keyword("DATETIME");
23418 if let Some(p) = precision {
23419 self.write(&format!("({})", p));
23420 }
23421 }
23422 Some(DialectType::BigQuery) => {
23423 if *timezone {
23425 self.write_keyword("TIMESTAMP");
23426 } else {
23427 self.write_keyword("DATETIME");
23428 }
23429 }
23430 Some(DialectType::DuckDB) => {
23431 if *timezone {
23433 self.write_keyword("TIMESTAMPTZ");
23434 } else {
23435 self.write_keyword("TIMESTAMP");
23436 if let Some(p) = precision {
23437 self.write(&format!("({})", p));
23438 }
23439 }
23440 }
23441 _ => {
23442 if *timezone && !self.config.tz_to_with_time_zone {
23443 self.write_keyword("TIMESTAMPTZ");
23445 if let Some(p) = precision {
23446 self.write(&format!("({})", p));
23447 }
23448 } else {
23449 self.write_keyword("TIMESTAMP");
23450 if let Some(p) = precision {
23451 self.write(&format!("({})", p));
23452 }
23453 if *timezone {
23454 self.write_space();
23455 self.write_keyword("WITH TIME ZONE");
23456 }
23457 }
23458 }
23459 }
23460 }
23461 DataType::Interval { unit, to } => {
23462 self.write_keyword("INTERVAL");
23463 if let Some(u) = unit {
23464 self.write_space();
23465 self.write_keyword(u);
23466 }
23467 if let Some(t) = to {
23469 self.write_space();
23470 self.write_keyword("TO");
23471 self.write_space();
23472 self.write_keyword(t);
23473 }
23474 }
23475 DataType::Json => {
23476 match self.config.dialect {
23478 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
23481 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
23482 _ => self.write_keyword("JSON"),
23483 }
23484 }
23485 DataType::JsonB => {
23486 match self.config.dialect {
23488 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
23489 Some(DialectType::Doris) => self.write_keyword("JSONB"),
23490 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
23491 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
23492 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
23495 }
23496 DataType::Uuid => {
23497 match self.config.dialect {
23499 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
23500 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
23501 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
23502 Some(DialectType::BigQuery)
23503 | Some(DialectType::Spark)
23504 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
23505 _ => self.write_keyword("UUID"),
23506 }
23507 }
23508 DataType::Array {
23509 element_type,
23510 dimension,
23511 } => {
23512 match self.config.dialect {
23514 Some(DialectType::PostgreSQL)
23515 | Some(DialectType::Redshift)
23516 | Some(DialectType::DuckDB) => {
23517 self.generate_data_type(element_type)?;
23519 if let Some(dim) = dimension {
23520 self.write(&format!("[{}]", dim));
23521 } else {
23522 self.write("[]");
23523 }
23524 }
23525 Some(DialectType::BigQuery) => {
23526 self.write_keyword("ARRAY<");
23527 self.generate_data_type(element_type)?;
23528 self.write(">");
23529 }
23530 Some(DialectType::Snowflake)
23531 | Some(DialectType::Presto)
23532 | Some(DialectType::Trino)
23533 | Some(DialectType::ClickHouse) => {
23534 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23536 self.write("Array(");
23537 } else {
23538 self.write_keyword("ARRAY(");
23539 }
23540 self.generate_data_type(element_type)?;
23541 self.write(")");
23542 }
23543 Some(DialectType::TSQL)
23544 | Some(DialectType::MySQL)
23545 | Some(DialectType::Oracle) => {
23546 match self.config.dialect {
23549 Some(DialectType::MySQL) => self.write_keyword("JSON"),
23550 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
23551 _ => self.write_keyword("JSON"),
23552 }
23553 }
23554 _ => {
23555 self.write_keyword("ARRAY<");
23557 self.generate_data_type(element_type)?;
23558 self.write(">");
23559 }
23560 }
23561 }
23562 DataType::List { element_type } => {
23563 self.generate_data_type(element_type)?;
23565 self.write_keyword(" LIST");
23566 }
23567 DataType::Map {
23568 key_type,
23569 value_type,
23570 } => {
23571 match self.config.dialect {
23573 Some(DialectType::Materialize) => {
23574 self.write_keyword("MAP[");
23576 self.generate_data_type(key_type)?;
23577 self.write(" => ");
23578 self.generate_data_type(value_type)?;
23579 self.write("]");
23580 }
23581 Some(DialectType::Snowflake)
23582 | Some(DialectType::RisingWave)
23583 | Some(DialectType::DuckDB)
23584 | Some(DialectType::Presto)
23585 | Some(DialectType::Trino)
23586 | Some(DialectType::Athena) => {
23587 self.write_keyword("MAP(");
23588 self.generate_data_type(key_type)?;
23589 self.write(", ");
23590 self.generate_data_type(value_type)?;
23591 self.write(")");
23592 }
23593 Some(DialectType::ClickHouse) => {
23594 self.write("Map(");
23597 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
23599 self.clickhouse_nullable_depth = 0;
23600 self.write(", ");
23601 self.generate_data_type(value_type)?;
23602 self.write(")");
23603 }
23604 _ => {
23605 self.write_keyword("MAP<");
23606 self.generate_data_type(key_type)?;
23607 self.write(", ");
23608 self.generate_data_type(value_type)?;
23609 self.write(">");
23610 }
23611 }
23612 }
23613 DataType::Vector {
23614 element_type,
23615 dimension,
23616 } => {
23617 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
23618 self.write_keyword("VECTOR(");
23620 if let Some(dim) = dimension {
23621 self.write(&dim.to_string());
23622 }
23623 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
23625 DataType::TinyInt { .. } => Some("I8"),
23626 DataType::SmallInt { .. } => Some("I16"),
23627 DataType::Int { .. } => Some("I32"),
23628 DataType::BigInt { .. } => Some("I64"),
23629 DataType::Float { .. } => Some("F32"),
23630 DataType::Double { .. } => Some("F64"),
23631 _ => None,
23632 });
23633 if let Some(alias) = type_alias {
23634 if dimension.is_some() {
23635 self.write(", ");
23636 }
23637 self.write(alias);
23638 }
23639 self.write(")");
23640 } else {
23641 self.write_keyword("VECTOR(");
23643 if let Some(ref et) = element_type {
23644 self.generate_data_type(et)?;
23645 if dimension.is_some() {
23646 self.write(", ");
23647 }
23648 }
23649 if let Some(dim) = dimension {
23650 self.write(&dim.to_string());
23651 }
23652 self.write(")");
23653 }
23654 }
23655 DataType::Object { fields, modifier } => {
23656 self.write_keyword("OBJECT(");
23657 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
23658 if i > 0 {
23659 self.write(", ");
23660 }
23661 self.write(name);
23662 self.write(" ");
23663 self.generate_data_type(dt)?;
23664 if *not_null {
23665 self.write_keyword(" NOT NULL");
23666 }
23667 }
23668 self.write(")");
23669 if let Some(mod_str) = modifier {
23670 self.write(" ");
23671 self.write_keyword(mod_str);
23672 }
23673 }
23674 DataType::Struct { fields, nested } => {
23675 match self.config.dialect {
23677 Some(DialectType::Snowflake) => {
23678 self.write_keyword("OBJECT(");
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::Presto) | Some(DialectType::Trino) => {
23693 self.write_keyword("ROW(");
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 Some(DialectType::DuckDB) => {
23708 self.write_keyword("STRUCT(");
23710 for (i, field) in fields.iter().enumerate() {
23711 if i > 0 {
23712 self.write(", ");
23713 }
23714 if !field.name.is_empty() {
23715 self.write(&field.name);
23716 self.write(" ");
23717 }
23718 self.generate_data_type(&field.data_type)?;
23719 }
23720 self.write(")");
23721 }
23722 Some(DialectType::ClickHouse) => {
23723 self.write("Tuple(");
23725 for (i, field) in fields.iter().enumerate() {
23726 if i > 0 {
23727 self.write(", ");
23728 }
23729 if !field.name.is_empty() {
23730 self.write(&field.name);
23731 self.write(" ");
23732 }
23733 self.generate_data_type(&field.data_type)?;
23734 }
23735 self.write(")");
23736 }
23737 Some(DialectType::SingleStore) => {
23738 self.write_keyword("RECORD(");
23740 for (i, field) in fields.iter().enumerate() {
23741 if i > 0 {
23742 self.write(", ");
23743 }
23744 if !field.name.is_empty() {
23745 self.write(&field.name);
23746 self.write(" ");
23747 }
23748 self.generate_data_type(&field.data_type)?;
23749 }
23750 self.write(")");
23751 }
23752 _ => {
23753 let force_angle_brackets = matches!(
23755 self.config.dialect,
23756 Some(DialectType::Hive)
23757 | Some(DialectType::Spark)
23758 | Some(DialectType::Databricks)
23759 );
23760 if *nested && !force_angle_brackets {
23761 self.write_keyword("STRUCT(");
23762 for (i, field) in fields.iter().enumerate() {
23763 if i > 0 {
23764 self.write(", ");
23765 }
23766 if !field.name.is_empty() {
23767 self.write(&field.name);
23768 self.write(" ");
23769 }
23770 self.generate_data_type(&field.data_type)?;
23771 }
23772 self.write(")");
23773 } else {
23774 self.write_keyword("STRUCT<");
23775 for (i, field) in fields.iter().enumerate() {
23776 if i > 0 {
23777 self.write(", ");
23778 }
23779 if !field.name.is_empty() {
23780 self.write(&field.name);
23782 self.write(self.config.struct_field_sep);
23783 }
23784 self.generate_data_type(&field.data_type)?;
23786 if let Some(comment) = &field.comment {
23788 self.write(" COMMENT '");
23789 self.write(comment);
23790 self.write("'");
23791 }
23792 if !field.options.is_empty() {
23794 self.write(" ");
23795 self.generate_options_clause(&field.options)?;
23796 }
23797 }
23798 self.write(">");
23799 }
23800 }
23801 }
23802 }
23803 DataType::Enum {
23804 values,
23805 assignments,
23806 } => {
23807 if self.config.dialect == Some(DialectType::ClickHouse) {
23810 self.write("Enum(");
23811 } else {
23812 self.write_keyword("ENUM(");
23813 }
23814 for (i, val) in values.iter().enumerate() {
23815 if i > 0 {
23816 self.write(", ");
23817 }
23818 self.write("'");
23819 self.write(val);
23820 self.write("'");
23821 if let Some(Some(assignment)) = assignments.get(i) {
23822 self.write(" = ");
23823 self.write(assignment);
23824 }
23825 }
23826 self.write(")");
23827 }
23828 DataType::Set { values } => {
23829 self.write_keyword("SET(");
23831 for (i, val) in values.iter().enumerate() {
23832 if i > 0 {
23833 self.write(", ");
23834 }
23835 self.write("'");
23836 self.write(val);
23837 self.write("'");
23838 }
23839 self.write(")");
23840 }
23841 DataType::Union { fields } => {
23842 self.write_keyword("UNION(");
23844 for (i, (name, dt)) in fields.iter().enumerate() {
23845 if i > 0 {
23846 self.write(", ");
23847 }
23848 if !name.is_empty() {
23849 self.write(name);
23850 self.write(" ");
23851 }
23852 self.generate_data_type(dt)?;
23853 }
23854 self.write(")");
23855 }
23856 DataType::Nullable { inner } => {
23857 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23859 self.write("Nullable(");
23860 let saved_depth = self.clickhouse_nullable_depth;
23862 self.clickhouse_nullable_depth = -1;
23863 self.generate_data_type(inner)?;
23864 self.clickhouse_nullable_depth = saved_depth;
23865 self.write(")");
23866 } else {
23867 match inner.as_ref() {
23869 DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
23870 self.generate_data_type(&DataType::Timestamp {
23871 precision: None,
23872 timezone: false,
23873 })?;
23874 }
23875 _ => {
23876 self.generate_data_type(inner)?;
23877 }
23878 }
23879 }
23880 }
23881 DataType::Custom { name } => {
23882 let name_upper = name.to_ascii_uppercase();
23884 match self.config.dialect {
23885 Some(DialectType::ClickHouse) => {
23886 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
23887 (name_upper[..idx].to_string(), &name[idx..])
23888 } else {
23889 (name_upper.clone(), "")
23890 };
23891 let mapped = match base_upper.as_str() {
23892 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
23893 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
23894 "DATETIME64" => "DateTime64",
23895 "DATE32" => "Date32",
23896 "INT" => "Int32",
23897 "MEDIUMINT" => "Int32",
23898 "INT8" => "Int8",
23899 "INT16" => "Int16",
23900 "INT32" => "Int32",
23901 "INT64" => "Int64",
23902 "INT128" => "Int128",
23903 "INT256" => "Int256",
23904 "UINT8" => "UInt8",
23905 "UINT16" => "UInt16",
23906 "UINT32" => "UInt32",
23907 "UINT64" => "UInt64",
23908 "UINT128" => "UInt128",
23909 "UINT256" => "UInt256",
23910 "FLOAT32" => "Float32",
23911 "FLOAT64" => "Float64",
23912 "DECIMAL32" => "Decimal32",
23913 "DECIMAL64" => "Decimal64",
23914 "DECIMAL128" => "Decimal128",
23915 "DECIMAL256" => "Decimal256",
23916 "ENUM" => "Enum",
23917 "ENUM8" => "Enum8",
23918 "ENUM16" => "Enum16",
23919 "FIXEDSTRING" => "FixedString",
23920 "NESTED" => "Nested",
23921 "LOWCARDINALITY" => "LowCardinality",
23922 "NULLABLE" => "Nullable",
23923 "IPV4" => "IPv4",
23924 "IPV6" => "IPv6",
23925 "POINT" => "Point",
23926 "RING" => "Ring",
23927 "LINESTRING" => "LineString",
23928 "MULTILINESTRING" => "MultiLineString",
23929 "POLYGON" => "Polygon",
23930 "MULTIPOLYGON" => "MultiPolygon",
23931 "AGGREGATEFUNCTION" => "AggregateFunction",
23932 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
23933 "DYNAMIC" => "Dynamic",
23934 _ => "",
23935 };
23936 if mapped.is_empty() {
23937 self.write(name);
23938 } else {
23939 self.write(mapped);
23940 self.write(suffix);
23941 }
23942 }
23943 Some(DialectType::MySQL)
23944 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
23945 {
23946 self.write_keyword("TIMESTAMP");
23948 }
23949 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
23950 self.write_keyword("SQL_VARIANT");
23951 }
23952 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
23953 self.write_keyword("DECIMAL(38, 5)");
23954 }
23955 Some(DialectType::Exasol) => {
23956 match name_upper.as_str() {
23958 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
23960 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
23962 "MEDIUMINT" => self.write_keyword("INT"),
23964 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
23966 self.write_keyword("DECIMAL")
23967 }
23968 "DATETIME" => self.write_keyword("TIMESTAMP"),
23970 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
23971 _ => self.write(name),
23972 }
23973 }
23974 Some(DialectType::Dremio) => {
23975 match name_upper.as_str() {
23977 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
23978 "ARRAY" => self.write_keyword("LIST"),
23979 "NCHAR" => self.write_keyword("VARCHAR"),
23980 _ => self.write(name),
23981 }
23982 }
23983 _ => {
23985 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
23987 (name_upper[..idx].to_string(), Some(&name[idx..]))
23988 } else {
23989 (name_upper.clone(), None)
23990 };
23991
23992 match base_upper.as_str() {
23993 "INT64"
23994 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
23995 {
23996 self.write_keyword("BIGINT");
23997 }
23998 "FLOAT64"
23999 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24000 {
24001 self.write_keyword("DOUBLE");
24002 }
24003 "BOOL"
24004 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24005 {
24006 self.write_keyword("BOOLEAN");
24007 }
24008 "BYTES"
24009 if matches!(
24010 self.config.dialect,
24011 Some(DialectType::Spark)
24012 | Some(DialectType::Hive)
24013 | Some(DialectType::Databricks)
24014 ) =>
24015 {
24016 self.write_keyword("BINARY");
24017 }
24018 "BYTES"
24019 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24020 {
24021 self.write_keyword("VARBINARY");
24022 }
24023 "DATETIME2" | "SMALLDATETIME"
24025 if !matches!(
24026 self.config.dialect,
24027 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24028 ) =>
24029 {
24030 if matches!(
24032 self.config.dialect,
24033 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
24034 ) {
24035 self.write_keyword("TIMESTAMP");
24036 if let Some(args) = _args_str {
24037 self.write(args);
24038 }
24039 } else {
24040 self.write_keyword("TIMESTAMP");
24041 }
24042 }
24043 "DATETIMEOFFSET"
24045 if !matches!(
24046 self.config.dialect,
24047 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24048 ) =>
24049 {
24050 if matches!(
24051 self.config.dialect,
24052 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
24053 ) {
24054 self.write_keyword("TIMESTAMPTZ");
24055 if let Some(args) = _args_str {
24056 self.write(args);
24057 }
24058 } else {
24059 self.write_keyword("TIMESTAMPTZ");
24060 }
24061 }
24062 "UNIQUEIDENTIFIER"
24064 if !matches!(
24065 self.config.dialect,
24066 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24067 ) =>
24068 {
24069 match self.config.dialect {
24070 Some(DialectType::Spark)
24071 | Some(DialectType::Databricks)
24072 | Some(DialectType::Hive) => self.write_keyword("STRING"),
24073 _ => self.write_keyword("UUID"),
24074 }
24075 }
24076 "BIT"
24078 if !matches!(
24079 self.config.dialect,
24080 Some(DialectType::TSQL)
24081 | Some(DialectType::Fabric)
24082 | Some(DialectType::PostgreSQL)
24083 | Some(DialectType::MySQL)
24084 | Some(DialectType::DuckDB)
24085 ) =>
24086 {
24087 self.write_keyword("BOOLEAN");
24088 }
24089 "NVARCHAR"
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("NVARCHAR2");
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::SQLite) | Some(DialectType::DuckDB) => {
24109 self.write_keyword("TEXT");
24110 if let Some(args) = _args_str {
24111 self.write(args);
24112 }
24113 }
24114 Some(DialectType::Hive) => {
24115 self.write_keyword("STRING");
24117 }
24118 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
24119 if _args_str.is_some() {
24120 self.write_keyword("VARCHAR");
24121 self.write(_args_str.unwrap());
24122 } else {
24123 self.write_keyword("STRING");
24124 }
24125 }
24126 _ => {
24127 self.write_keyword("VARCHAR");
24128 if let Some(args) = _args_str {
24129 self.write(args);
24130 }
24131 }
24132 }
24133 }
24134 "NCHAR"
24136 if !matches!(
24137 self.config.dialect,
24138 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24139 ) =>
24140 {
24141 match self.config.dialect {
24142 Some(DialectType::Oracle) => {
24143 self.write_keyword("NCHAR");
24145 if let Some(args) = _args_str {
24146 self.write(args);
24147 }
24148 }
24149 Some(DialectType::BigQuery) => {
24150 self.write_keyword("STRING");
24152 }
24153 Some(DialectType::Hive) => {
24154 self.write_keyword("STRING");
24156 }
24157 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
24158 self.write_keyword("TEXT");
24159 if let Some(args) = _args_str {
24160 self.write(args);
24161 }
24162 }
24163 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
24164 if _args_str.is_some() {
24165 self.write_keyword("CHAR");
24166 self.write(_args_str.unwrap());
24167 } else {
24168 self.write_keyword("STRING");
24169 }
24170 }
24171 _ => {
24172 self.write_keyword("CHAR");
24173 if let Some(args) = _args_str {
24174 self.write(args);
24175 }
24176 }
24177 }
24178 }
24179 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
24182 Some(DialectType::MySQL)
24183 | Some(DialectType::SingleStore)
24184 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
24185 Some(DialectType::Spark)
24186 | Some(DialectType::Databricks)
24187 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
24188 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
24189 Some(DialectType::Presto)
24190 | Some(DialectType::Trino)
24191 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
24192 Some(DialectType::Snowflake)
24193 | Some(DialectType::Redshift)
24194 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
24195 _ => self.write_keyword("TEXT"),
24196 },
24197 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
24200 Some(DialectType::MySQL)
24201 | Some(DialectType::SingleStore)
24202 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
24203 Some(DialectType::Spark)
24204 | Some(DialectType::Databricks)
24205 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
24206 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
24207 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
24208 Some(DialectType::Presto)
24209 | Some(DialectType::Trino)
24210 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
24211 Some(DialectType::Snowflake)
24212 | Some(DialectType::Redshift)
24213 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
24214 _ => self.write_keyword("BLOB"),
24215 },
24216 "LONGVARCHAR" => match self.config.dialect {
24218 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
24219 _ => self.write_keyword("VARCHAR"),
24220 },
24221 "DATETIME" => {
24223 match self.config.dialect {
24224 Some(DialectType::MySQL)
24225 | Some(DialectType::Doris)
24226 | Some(DialectType::StarRocks)
24227 | Some(DialectType::TSQL)
24228 | Some(DialectType::Fabric)
24229 | Some(DialectType::BigQuery)
24230 | Some(DialectType::SQLite)
24231 | Some(DialectType::Snowflake) => {
24232 self.write_keyword("DATETIME");
24233 if let Some(args) = _args_str {
24234 self.write(args);
24235 }
24236 }
24237 Some(_) => {
24238 self.write_keyword("TIMESTAMP");
24240 if let Some(args) = _args_str {
24241 self.write(args);
24242 }
24243 }
24244 None => {
24245 self.write(name);
24247 }
24248 }
24249 }
24250 "VARCHAR2"
24252 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
24253 {
24254 match self.config.dialect {
24255 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24256 self.write_keyword("TEXT");
24257 }
24258 Some(DialectType::Hive)
24259 | Some(DialectType::Spark)
24260 | Some(DialectType::Databricks)
24261 | Some(DialectType::BigQuery)
24262 | Some(DialectType::ClickHouse)
24263 | Some(DialectType::StarRocks)
24264 | Some(DialectType::Doris) => {
24265 self.write_keyword("STRING");
24266 }
24267 _ => {
24268 self.write_keyword("VARCHAR");
24269 if let Some(args) = _args_str {
24270 self.write(args);
24271 }
24272 }
24273 }
24274 }
24275 "NVARCHAR2"
24276 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
24277 {
24278 match self.config.dialect {
24279 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24280 self.write_keyword("TEXT");
24281 }
24282 Some(DialectType::Hive)
24283 | Some(DialectType::Spark)
24284 | Some(DialectType::Databricks)
24285 | Some(DialectType::BigQuery)
24286 | Some(DialectType::ClickHouse)
24287 | Some(DialectType::StarRocks)
24288 | Some(DialectType::Doris) => {
24289 self.write_keyword("STRING");
24290 }
24291 _ => {
24292 self.write_keyword("VARCHAR");
24293 if let Some(args) = _args_str {
24294 self.write(args);
24295 }
24296 }
24297 }
24298 }
24299 _ => self.write(name),
24300 }
24301 }
24302 }
24303 }
24304 DataType::Geometry { subtype, srid } => {
24305 match self.config.dialect {
24307 Some(DialectType::MySQL) => {
24308 if let Some(sub) = subtype {
24310 self.write_keyword(sub);
24311 if let Some(s) = srid {
24312 self.write(" SRID ");
24313 self.write(&s.to_string());
24314 }
24315 } else {
24316 self.write_keyword("GEOMETRY");
24317 }
24318 }
24319 Some(DialectType::BigQuery) => {
24320 self.write_keyword("GEOGRAPHY");
24322 }
24323 Some(DialectType::Teradata) => {
24324 self.write_keyword("ST_GEOMETRY");
24326 if subtype.is_some() || srid.is_some() {
24327 self.write("(");
24328 if let Some(sub) = subtype {
24329 self.write_keyword(sub);
24330 }
24331 if let Some(s) = srid {
24332 if subtype.is_some() {
24333 self.write(", ");
24334 }
24335 self.write(&s.to_string());
24336 }
24337 self.write(")");
24338 }
24339 }
24340 _ => {
24341 self.write_keyword("GEOMETRY");
24343 if subtype.is_some() || srid.is_some() {
24344 self.write("(");
24345 if let Some(sub) = subtype {
24346 self.write_keyword(sub);
24347 }
24348 if let Some(s) = srid {
24349 if subtype.is_some() {
24350 self.write(", ");
24351 }
24352 self.write(&s.to_string());
24353 }
24354 self.write(")");
24355 }
24356 }
24357 }
24358 }
24359 DataType::Geography { subtype, srid } => {
24360 match self.config.dialect {
24362 Some(DialectType::MySQL) => {
24363 if let Some(sub) = subtype {
24365 self.write_keyword(sub);
24366 } else {
24367 self.write_keyword("GEOMETRY");
24368 }
24369 let effective_srid = srid.unwrap_or(4326);
24371 self.write(" SRID ");
24372 self.write(&effective_srid.to_string());
24373 }
24374 Some(DialectType::BigQuery) => {
24375 self.write_keyword("GEOGRAPHY");
24377 }
24378 Some(DialectType::Snowflake) => {
24379 self.write_keyword("GEOGRAPHY");
24381 }
24382 _ => {
24383 self.write_keyword("GEOGRAPHY");
24385 if subtype.is_some() || srid.is_some() {
24386 self.write("(");
24387 if let Some(sub) = subtype {
24388 self.write_keyword(sub);
24389 }
24390 if let Some(s) = srid {
24391 if subtype.is_some() {
24392 self.write(", ");
24393 }
24394 self.write(&s.to_string());
24395 }
24396 self.write(")");
24397 }
24398 }
24399 }
24400 }
24401 DataType::CharacterSet { name } => {
24402 self.write_keyword("CHAR CHARACTER SET ");
24404 self.write(name);
24405 }
24406 _ => self.write("UNKNOWN"),
24407 }
24408 Ok(())
24409 }
24410
24411 #[inline]
24414 fn write(&mut self, s: &str) {
24415 self.output.push_str(s);
24416 }
24417
24418 #[inline]
24419 fn write_space(&mut self) {
24420 self.output.push(' ');
24421 }
24422
24423 #[inline]
24424 fn write_keyword(&mut self, keyword: &str) {
24425 if self.config.uppercase_keywords {
24426 self.output.push_str(keyword);
24427 } else {
24428 for b in keyword.bytes() {
24429 self.output.push(b.to_ascii_lowercase() as char);
24430 }
24431 }
24432 }
24433
24434 fn write_func_name(&mut self, name: &str) {
24436 let normalized = self.normalize_func_name(name);
24437 self.output.push_str(normalized.as_ref());
24438 }
24439
24440 fn convert_strptime_to_exasol_format(format: &str) -> String {
24444 let mut result = String::new();
24445 let chars: Vec<char> = format.chars().collect();
24446 let mut i = 0;
24447 while i < chars.len() {
24448 if chars[i] == '%' && i + 1 < chars.len() {
24449 let spec = chars[i + 1];
24450 let exasol_spec = match spec {
24451 'Y' => "YYYY",
24452 'y' => "YY",
24453 'm' => "MM",
24454 'd' => "DD",
24455 'H' => "HH",
24456 'M' => "MI",
24457 'S' => "SS",
24458 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
24470 result.push('%');
24472 result.push(spec);
24473 i += 2;
24474 continue;
24475 }
24476 };
24477 result.push_str(exasol_spec);
24478 i += 2;
24479 } else {
24480 result.push(chars[i]);
24481 i += 1;
24482 }
24483 }
24484 result
24485 }
24486
24487 fn convert_strptime_to_postgres_format(format: &str) -> String {
24491 let mut result = String::new();
24492 let chars: Vec<char> = format.chars().collect();
24493 let mut i = 0;
24494 while i < chars.len() {
24495 if chars[i] == '%' && i + 1 < chars.len() {
24496 if chars[i + 1] == '-' && i + 2 < chars.len() {
24498 let spec = chars[i + 2];
24499 let pg_spec = match spec {
24500 'd' => "FMDD",
24501 'm' => "FMMM",
24502 'H' => "FMHH24",
24503 'M' => "FMMI",
24504 'S' => "FMSS",
24505 _ => {
24506 result.push('%');
24507 result.push('-');
24508 result.push(spec);
24509 i += 3;
24510 continue;
24511 }
24512 };
24513 result.push_str(pg_spec);
24514 i += 3;
24515 continue;
24516 }
24517 let spec = chars[i + 1];
24518 let pg_spec = match spec {
24519 'Y' => "YYYY",
24520 'y' => "YY",
24521 'm' => "MM",
24522 'd' => "DD",
24523 'H' => "HH24",
24524 'I' => "HH12",
24525 'M' => "MI",
24526 'S' => "SS",
24527 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
24538 result.push('%');
24540 result.push(spec);
24541 i += 2;
24542 continue;
24543 }
24544 };
24545 result.push_str(pg_spec);
24546 i += 2;
24547 } else {
24548 result.push(chars[i]);
24549 i += 1;
24550 }
24551 }
24552 result
24553 }
24554
24555 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
24557 if self.config.limit_only_literals {
24558 if let Some(value) = Self::try_evaluate_constant(expr) {
24559 self.write(&value.to_string());
24560 return Ok(());
24561 }
24562 }
24563 self.generate_expression(expr)
24564 }
24565
24566 fn write_formatted_comment(&mut self, comment: &str) {
24570 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
24573 &comment[2..comment.len() - 2]
24576 } else if comment.starts_with("--") {
24577 &comment[2..]
24580 } else {
24581 comment
24583 };
24584 if content.trim().is_empty() {
24586 return;
24587 }
24588 let sanitized = content.replace("*/", "* /").replace("/*", "/ *");
24591 let content = &sanitized;
24592 self.output.push_str("/*");
24594 if !content.starts_with(' ') {
24595 self.output.push(' ');
24596 }
24597 self.output.push_str(content);
24598 if !content.ends_with(' ') {
24599 self.output.push(' ');
24600 }
24601 self.output.push_str("*/");
24602 }
24603
24604 fn escape_block_for_single_quote(&self, block: &str) -> String {
24607 let escape_backslash = matches!(
24608 self.config.dialect,
24609 Some(crate::dialects::DialectType::Snowflake)
24610 );
24611 let mut escaped = String::with_capacity(block.len() + 4);
24612 for ch in block.chars() {
24613 if ch == '\'' {
24614 escaped.push('\\');
24615 escaped.push('\'');
24616 } else if escape_backslash && ch == '\\' {
24617 escaped.push('\\');
24618 escaped.push('\\');
24619 } else {
24620 escaped.push(ch);
24621 }
24622 }
24623 escaped
24624 }
24625
24626 fn write_newline(&mut self) {
24627 self.output.push('\n');
24628 }
24629
24630 fn write_indent(&mut self) {
24631 for _ in 0..self.indent_level {
24632 self.output.push_str(self.config.indent);
24633 }
24634 }
24635
24636 fn too_wide(&self, args: &[String]) -> bool {
24642 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
24643 }
24644
24645 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
24648 let config = GeneratorConfig {
24649 pretty: false,
24650 dialect: self.config.dialect,
24651 ..Default::default()
24652 };
24653 let mut gen = Generator::with_config(config);
24654 gen.generate_expression(expr)?;
24655 Ok(gen.output)
24656 }
24657
24658 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
24661 if self.config.pretty {
24662 self.write_newline();
24663 self.write_indent();
24664 self.write_keyword(keyword);
24665 self.write_newline();
24666 self.indent_level += 1;
24667 self.write_indent();
24668 self.generate_expression(condition)?;
24669 self.indent_level -= 1;
24670 } else {
24671 self.write_space();
24672 self.write_keyword(keyword);
24673 self.write_space();
24674 self.generate_expression(condition)?;
24675 }
24676 Ok(())
24677 }
24678
24679 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
24682 if exprs.is_empty() {
24683 return Ok(());
24684 }
24685
24686 if self.config.pretty {
24687 self.write_newline();
24688 self.write_indent();
24689 self.write_keyword(keyword);
24690 self.write_newline();
24691 self.indent_level += 1;
24692 for (i, expr) in exprs.iter().enumerate() {
24693 if i > 0 {
24694 self.write(",");
24695 self.write_newline();
24696 }
24697 self.write_indent();
24698 self.generate_expression(expr)?;
24699 }
24700 self.indent_level -= 1;
24701 } else {
24702 self.write_space();
24703 self.write_keyword(keyword);
24704 self.write_space();
24705 for (i, expr) in exprs.iter().enumerate() {
24706 if i > 0 {
24707 self.write(", ");
24708 }
24709 self.generate_expression(expr)?;
24710 }
24711 }
24712 Ok(())
24713 }
24714
24715 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
24717 if orderings.is_empty() {
24718 return Ok(());
24719 }
24720
24721 if self.config.pretty {
24722 self.write_newline();
24723 self.write_indent();
24724 self.write_keyword(keyword);
24725 self.write_newline();
24726 self.indent_level += 1;
24727 for (i, ordered) in orderings.iter().enumerate() {
24728 if i > 0 {
24729 self.write(",");
24730 self.write_newline();
24731 }
24732 self.write_indent();
24733 self.generate_ordered(ordered)?;
24734 }
24735 self.indent_level -= 1;
24736 } else {
24737 self.write_space();
24738 self.write_keyword(keyword);
24739 self.write_space();
24740 for (i, ordered) in orderings.iter().enumerate() {
24741 if i > 0 {
24742 self.write(", ");
24743 }
24744 self.generate_ordered(ordered)?;
24745 }
24746 }
24747 Ok(())
24748 }
24749
24750 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
24752 if windows.is_empty() {
24753 return Ok(());
24754 }
24755
24756 if self.config.pretty {
24757 self.write_newline();
24758 self.write_indent();
24759 self.write_keyword("WINDOW");
24760 self.write_newline();
24761 self.indent_level += 1;
24762 for (i, named_window) in windows.iter().enumerate() {
24763 if i > 0 {
24764 self.write(",");
24765 self.write_newline();
24766 }
24767 self.write_indent();
24768 self.generate_identifier(&named_window.name)?;
24769 self.write_space();
24770 self.write_keyword("AS");
24771 self.write(" (");
24772 self.generate_over(&named_window.spec)?;
24773 self.write(")");
24774 }
24775 self.indent_level -= 1;
24776 } else {
24777 self.write_space();
24778 self.write_keyword("WINDOW");
24779 self.write_space();
24780 for (i, named_window) in windows.iter().enumerate() {
24781 if i > 0 {
24782 self.write(", ");
24783 }
24784 self.generate_identifier(&named_window.name)?;
24785 self.write_space();
24786 self.write_keyword("AS");
24787 self.write(" (");
24788 self.generate_over(&named_window.spec)?;
24789 self.write(")");
24790 }
24791 }
24792 Ok(())
24793 }
24794
24795 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
24797 self.write_keyword("AI_AGG");
24799 self.write("(");
24800 self.generate_expression(&e.this)?;
24801 self.write(", ");
24802 self.generate_expression(&e.expression)?;
24803 self.write(")");
24804 Ok(())
24805 }
24806
24807 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
24808 self.write_keyword("AI_CLASSIFY");
24810 self.write("(");
24811 self.generate_expression(&e.this)?;
24812 if let Some(categories) = &e.categories {
24813 self.write(", ");
24814 self.generate_expression(categories)?;
24815 }
24816 if let Some(config) = &e.config {
24817 self.write(", ");
24818 self.generate_expression(config)?;
24819 }
24820 self.write(")");
24821 Ok(())
24822 }
24823
24824 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
24825 self.write_keyword("ADD");
24827 self.write_space();
24828 if e.exists {
24829 self.write_keyword("IF NOT EXISTS");
24830 self.write_space();
24831 }
24832 self.generate_expression(&e.this)?;
24833 if let Some(location) = &e.location {
24834 self.write_space();
24835 self.generate_expression(location)?;
24836 }
24837 Ok(())
24838 }
24839
24840 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
24841 self.write_keyword("ALGORITHM");
24843 self.write("=");
24844 self.generate_expression(&e.this)?;
24845 Ok(())
24846 }
24847
24848 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
24849 self.generate_expression(&e.this)?;
24851 self.write_space();
24852 self.write_keyword("AS");
24853 self.write(" (");
24854 for (i, expr) in e.expressions.iter().enumerate() {
24855 if i > 0 {
24856 self.write(", ");
24857 }
24858 self.generate_expression(expr)?;
24859 }
24860 self.write(")");
24861 Ok(())
24862 }
24863
24864 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
24865 self.write_keyword("ALLOWED_VALUES");
24867 self.write_space();
24868 for (i, expr) in e.expressions.iter().enumerate() {
24869 if i > 0 {
24870 self.write(", ");
24871 }
24872 self.generate_expression(expr)?;
24873 }
24874 Ok(())
24875 }
24876
24877 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
24878 self.write_keyword("ALTER COLUMN");
24880 self.write_space();
24881 self.generate_expression(&e.this)?;
24882
24883 if let Some(dtype) = &e.dtype {
24884 self.write_space();
24885 self.write_keyword("SET DATA TYPE");
24886 self.write_space();
24887 self.generate_expression(dtype)?;
24888 if let Some(collate) = &e.collate {
24889 self.write_space();
24890 self.write_keyword("COLLATE");
24891 self.write_space();
24892 self.generate_expression(collate)?;
24893 }
24894 if let Some(using) = &e.using {
24895 self.write_space();
24896 self.write_keyword("USING");
24897 self.write_space();
24898 self.generate_expression(using)?;
24899 }
24900 } else if let Some(default) = &e.default {
24901 self.write_space();
24902 self.write_keyword("SET DEFAULT");
24903 self.write_space();
24904 self.generate_expression(default)?;
24905 } else if let Some(comment) = &e.comment {
24906 self.write_space();
24907 self.write_keyword("COMMENT");
24908 self.write_space();
24909 self.generate_expression(comment)?;
24910 } else if let Some(drop) = &e.drop {
24911 self.write_space();
24912 self.write_keyword("DROP");
24913 self.write_space();
24914 self.generate_expression(drop)?;
24915 } else if let Some(visible) = &e.visible {
24916 self.write_space();
24917 self.generate_expression(visible)?;
24918 } else if let Some(rename_to) = &e.rename_to {
24919 self.write_space();
24920 self.write_keyword("RENAME TO");
24921 self.write_space();
24922 self.generate_expression(rename_to)?;
24923 } else if let Some(allow_null) = &e.allow_null {
24924 self.write_space();
24925 self.generate_expression(allow_null)?;
24926 }
24927 Ok(())
24928 }
24929
24930 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
24931 self.write_keyword("ALTER SESSION");
24933 self.write_space();
24934 if e.unset.is_some() {
24935 self.write_keyword("UNSET");
24936 } else {
24937 self.write_keyword("SET");
24938 }
24939 self.write_space();
24940 for (i, expr) in e.expressions.iter().enumerate() {
24941 if i > 0 {
24942 self.write(", ");
24943 }
24944 self.generate_expression(expr)?;
24945 }
24946 Ok(())
24947 }
24948
24949 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
24950 self.write_keyword("SET");
24952
24953 if let Some(opt) = &e.option {
24955 self.write_space();
24956 self.generate_expression(opt)?;
24957 }
24958
24959 if !e.expressions.is_empty() {
24962 let is_properties = e
24964 .expressions
24965 .iter()
24966 .any(|expr| matches!(expr, Expression::Eq(_)));
24967 if is_properties && e.option.is_none() {
24968 self.write_space();
24969 self.write_keyword("PROPERTIES");
24970 }
24971 self.write_space();
24972 for (i, expr) in e.expressions.iter().enumerate() {
24973 if i > 0 {
24974 self.write(", ");
24975 }
24976 self.generate_expression(expr)?;
24977 }
24978 }
24979
24980 if let Some(file_format) = &e.file_format {
24982 self.write(" ");
24983 self.write_keyword("STAGE_FILE_FORMAT");
24984 self.write(" = (");
24985 self.generate_space_separated_properties(file_format)?;
24986 self.write(")");
24987 }
24988
24989 if let Some(copy_options) = &e.copy_options {
24991 self.write(" ");
24992 self.write_keyword("STAGE_COPY_OPTIONS");
24993 self.write(" = (");
24994 self.generate_space_separated_properties(copy_options)?;
24995 self.write(")");
24996 }
24997
24998 if let Some(tag) = &e.tag {
25000 self.write(" ");
25001 self.write_keyword("TAG");
25002 self.write(" ");
25003 self.generate_expression(tag)?;
25004 }
25005
25006 Ok(())
25007 }
25008
25009 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
25011 match expr {
25012 Expression::Tuple(t) => {
25013 for (i, prop) in t.expressions.iter().enumerate() {
25014 if i > 0 {
25015 self.write(" ");
25016 }
25017 self.generate_expression(prop)?;
25018 }
25019 }
25020 _ => {
25021 self.generate_expression(expr)?;
25022 }
25023 }
25024 Ok(())
25025 }
25026
25027 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
25028 self.write_keyword("ALTER");
25030 if e.compound.is_some() {
25031 self.write_space();
25032 self.write_keyword("COMPOUND");
25033 }
25034 self.write_space();
25035 self.write_keyword("SORTKEY");
25036 self.write_space();
25037 if let Some(this) = &e.this {
25038 self.generate_expression(this)?;
25039 } else if !e.expressions.is_empty() {
25040 self.write("(");
25041 for (i, expr) in e.expressions.iter().enumerate() {
25042 if i > 0 {
25043 self.write(", ");
25044 }
25045 self.generate_expression(expr)?;
25046 }
25047 self.write(")");
25048 }
25049 Ok(())
25050 }
25051
25052 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
25053 self.write_keyword("ANALYZE");
25055 if !e.options.is_empty() {
25056 self.write_space();
25057 for (i, opt) in e.options.iter().enumerate() {
25058 if i > 0 {
25059 self.write_space();
25060 }
25061 if let Expression::Identifier(id) = opt {
25063 self.write_keyword(&id.name);
25064 } else {
25065 self.generate_expression(opt)?;
25066 }
25067 }
25068 }
25069 if let Some(kind) = &e.kind {
25070 self.write_space();
25071 self.write_keyword(kind);
25072 }
25073 if let Some(this) = &e.this {
25074 self.write_space();
25075 self.generate_expression(this)?;
25076 }
25077 if !e.columns.is_empty() {
25079 self.write("(");
25080 for (i, col) in e.columns.iter().enumerate() {
25081 if i > 0 {
25082 self.write(", ");
25083 }
25084 self.write(col);
25085 }
25086 self.write(")");
25087 }
25088 if let Some(partition) = &e.partition {
25089 self.write_space();
25090 self.generate_expression(partition)?;
25091 }
25092 if let Some(mode) = &e.mode {
25093 self.write_space();
25094 self.generate_expression(mode)?;
25095 }
25096 if let Some(expression) = &e.expression {
25097 self.write_space();
25098 self.generate_expression(expression)?;
25099 }
25100 if !e.properties.is_empty() {
25101 self.write_space();
25102 self.write_keyword(self.config.with_properties_prefix);
25103 self.write(" (");
25104 for (i, prop) in e.properties.iter().enumerate() {
25105 if i > 0 {
25106 self.write(", ");
25107 }
25108 self.generate_expression(prop)?;
25109 }
25110 self.write(")");
25111 }
25112 Ok(())
25113 }
25114
25115 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
25116 self.write_keyword("DELETE");
25118 if let Some(kind) = &e.kind {
25119 self.write_space();
25120 self.write_keyword(kind);
25121 }
25122 self.write_space();
25123 self.write_keyword("STATISTICS");
25124 Ok(())
25125 }
25126
25127 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
25128 if let Expression::Identifier(id) = e.this.as_ref() {
25131 self.write_keyword(&id.name);
25132 } else {
25133 self.generate_expression(&e.this)?;
25134 }
25135 self.write_space();
25136 self.write_keyword("HISTOGRAM ON");
25137 self.write_space();
25138 for (i, expr) in e.expressions.iter().enumerate() {
25139 if i > 0 {
25140 self.write(", ");
25141 }
25142 self.generate_expression(expr)?;
25143 }
25144 if let Some(expression) = &e.expression {
25145 self.write_space();
25146 self.generate_expression(expression)?;
25147 }
25148 if let Some(update_options) = &e.update_options {
25149 self.write_space();
25150 self.generate_expression(update_options)?;
25151 self.write_space();
25152 self.write_keyword("UPDATE");
25153 }
25154 Ok(())
25155 }
25156
25157 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
25158 self.write_keyword("LIST CHAINED ROWS");
25160 if let Some(expression) = &e.expression {
25161 self.write_space();
25162 self.write_keyword("INTO");
25163 self.write_space();
25164 self.generate_expression(expression)?;
25165 }
25166 Ok(())
25167 }
25168
25169 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
25170 self.write_keyword("SAMPLE");
25172 self.write_space();
25173 if let Some(sample) = &e.sample {
25174 self.generate_expression(sample)?;
25175 self.write_space();
25176 }
25177 self.write_keyword(&e.kind);
25178 Ok(())
25179 }
25180
25181 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
25182 self.write_keyword(&e.kind);
25184 if let Some(option) = &e.option {
25185 self.write_space();
25186 self.generate_expression(option)?;
25187 }
25188 self.write_space();
25189 self.write_keyword("STATISTICS");
25190 if let Some(this) = &e.this {
25191 self.write_space();
25192 self.generate_expression(this)?;
25193 }
25194 if !e.expressions.is_empty() {
25195 self.write_space();
25196 for (i, expr) in e.expressions.iter().enumerate() {
25197 if i > 0 {
25198 self.write(", ");
25199 }
25200 self.generate_expression(expr)?;
25201 }
25202 }
25203 Ok(())
25204 }
25205
25206 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
25207 self.write_keyword("VALIDATE");
25209 self.write_space();
25210 self.write_keyword(&e.kind);
25211 if let Some(this) = &e.this {
25212 self.write_space();
25213 if let Expression::Identifier(id) = this.as_ref() {
25215 self.write_keyword(&id.name);
25216 } else {
25217 self.generate_expression(this)?;
25218 }
25219 }
25220 if let Some(expression) = &e.expression {
25221 self.write_space();
25222 self.write_keyword("INTO");
25223 self.write_space();
25224 self.generate_expression(expression)?;
25225 }
25226 Ok(())
25227 }
25228
25229 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
25230 self.write_keyword("WITH");
25232 self.write_space();
25233 for (i, expr) in e.expressions.iter().enumerate() {
25234 if i > 0 {
25235 self.write(", ");
25236 }
25237 self.generate_expression(expr)?;
25238 }
25239 Ok(())
25240 }
25241
25242 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
25243 self.generate_expression(&e.this)?;
25246 self.write("(");
25247 for (i, arg) in e.expressions.iter().enumerate() {
25248 if i > 0 {
25249 self.write(", ");
25250 }
25251 self.generate_expression(arg)?;
25252 }
25253 self.write(")");
25254 Ok(())
25255 }
25256
25257 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
25258 self.generate_expression(&e.this)?;
25260 self.write("(");
25261 for (i, arg) in e.expressions.iter().enumerate() {
25262 if i > 0 {
25263 self.write(", ");
25264 }
25265 self.generate_expression(arg)?;
25266 }
25267 self.write(")");
25268 Ok(())
25269 }
25270
25271 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
25272 self.generate_expression(&e.this)?;
25274 self.write_space();
25275 self.write_keyword("APPLY");
25276 self.write("(");
25277 self.generate_expression(&e.expression)?;
25278 self.write(")");
25279 Ok(())
25280 }
25281
25282 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
25283 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
25285 self.write("(");
25286 self.generate_expression(&e.this)?;
25287 if let Some(percentile) = &e.percentile {
25288 self.write(", ");
25289 self.generate_expression(percentile)?;
25290 }
25291 self.write(")");
25292 Ok(())
25293 }
25294
25295 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
25296 self.write_keyword("APPROX_QUANTILE");
25298 self.write("(");
25299 self.generate_expression(&e.this)?;
25300 if let Some(quantile) = &e.quantile {
25301 self.write(", ");
25302 self.generate_expression(quantile)?;
25303 }
25304 if let Some(accuracy) = &e.accuracy {
25305 self.write(", ");
25306 self.generate_expression(accuracy)?;
25307 }
25308 if let Some(weight) = &e.weight {
25309 self.write(", ");
25310 self.generate_expression(weight)?;
25311 }
25312 self.write(")");
25313 Ok(())
25314 }
25315
25316 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
25317 self.write_keyword("APPROX_QUANTILES");
25319 self.write("(");
25320 self.generate_expression(&e.this)?;
25321 if let Some(expression) = &e.expression {
25322 self.write(", ");
25323 self.generate_expression(expression)?;
25324 }
25325 self.write(")");
25326 Ok(())
25327 }
25328
25329 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
25330 self.write_keyword("APPROX_TOP_K");
25332 self.write("(");
25333 self.generate_expression(&e.this)?;
25334 if let Some(expression) = &e.expression {
25335 self.write(", ");
25336 self.generate_expression(expression)?;
25337 }
25338 if let Some(counters) = &e.counters {
25339 self.write(", ");
25340 self.generate_expression(counters)?;
25341 }
25342 self.write(")");
25343 Ok(())
25344 }
25345
25346 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
25347 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
25349 self.write("(");
25350 self.generate_expression(&e.this)?;
25351 if let Some(expression) = &e.expression {
25352 self.write(", ");
25353 self.generate_expression(expression)?;
25354 }
25355 self.write(")");
25356 Ok(())
25357 }
25358
25359 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
25360 self.write_keyword("APPROX_TOP_K_COMBINE");
25362 self.write("(");
25363 self.generate_expression(&e.this)?;
25364 if let Some(expression) = &e.expression {
25365 self.write(", ");
25366 self.generate_expression(expression)?;
25367 }
25368 self.write(")");
25369 Ok(())
25370 }
25371
25372 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
25373 self.write_keyword("APPROX_TOP_K_ESTIMATE");
25375 self.write("(");
25376 self.generate_expression(&e.this)?;
25377 if let Some(expression) = &e.expression {
25378 self.write(", ");
25379 self.generate_expression(expression)?;
25380 }
25381 self.write(")");
25382 Ok(())
25383 }
25384
25385 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
25386 self.write_keyword("APPROX_TOP_SUM");
25388 self.write("(");
25389 self.generate_expression(&e.this)?;
25390 self.write(", ");
25391 self.generate_expression(&e.expression)?;
25392 if let Some(count) = &e.count {
25393 self.write(", ");
25394 self.generate_expression(count)?;
25395 }
25396 self.write(")");
25397 Ok(())
25398 }
25399
25400 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
25401 self.write_keyword("ARG_MAX");
25403 self.write("(");
25404 self.generate_expression(&e.this)?;
25405 self.write(", ");
25406 self.generate_expression(&e.expression)?;
25407 if let Some(count) = &e.count {
25408 self.write(", ");
25409 self.generate_expression(count)?;
25410 }
25411 self.write(")");
25412 Ok(())
25413 }
25414
25415 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
25416 self.write_keyword("ARG_MIN");
25418 self.write("(");
25419 self.generate_expression(&e.this)?;
25420 self.write(", ");
25421 self.generate_expression(&e.expression)?;
25422 if let Some(count) = &e.count {
25423 self.write(", ");
25424 self.generate_expression(count)?;
25425 }
25426 self.write(")");
25427 Ok(())
25428 }
25429
25430 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
25431 self.write_keyword("ARRAY_ALL");
25433 self.write("(");
25434 self.generate_expression(&e.this)?;
25435 self.write(", ");
25436 self.generate_expression(&e.expression)?;
25437 self.write(")");
25438 Ok(())
25439 }
25440
25441 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
25442 self.write_keyword("ARRAY_ANY");
25444 self.write("(");
25445 self.generate_expression(&e.this)?;
25446 self.write(", ");
25447 self.generate_expression(&e.expression)?;
25448 self.write(")");
25449 Ok(())
25450 }
25451
25452 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
25453 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
25455 self.write("(");
25456 for (i, expr) in e.expressions.iter().enumerate() {
25457 if i > 0 {
25458 self.write(", ");
25459 }
25460 self.generate_expression(expr)?;
25461 }
25462 self.write(")");
25463 Ok(())
25464 }
25465
25466 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
25467 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
25469 self.write("arraySum");
25470 } else {
25471 self.write_keyword("ARRAY_SUM");
25472 }
25473 self.write("(");
25474 self.generate_expression(&e.this)?;
25475 if let Some(expression) = &e.expression {
25476 self.write(", ");
25477 self.generate_expression(expression)?;
25478 }
25479 self.write(")");
25480 Ok(())
25481 }
25482
25483 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
25484 self.generate_expression(&e.this)?;
25486 self.write_space();
25487 self.write_keyword("AT");
25488 self.write_space();
25489 self.generate_expression(&e.expression)?;
25490 Ok(())
25491 }
25492
25493 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
25494 self.write_keyword("ATTACH");
25496 if e.exists {
25497 self.write_space();
25498 self.write_keyword("IF NOT EXISTS");
25499 }
25500 self.write_space();
25501 self.generate_expression(&e.this)?;
25502 if !e.expressions.is_empty() {
25503 self.write(" (");
25504 for (i, expr) in e.expressions.iter().enumerate() {
25505 if i > 0 {
25506 self.write(", ");
25507 }
25508 self.generate_expression(expr)?;
25509 }
25510 self.write(")");
25511 }
25512 Ok(())
25513 }
25514
25515 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
25516 self.generate_expression(&e.this)?;
25519 if let Some(expression) = &e.expression {
25520 self.write_space();
25521 self.generate_expression(expression)?;
25522 }
25523 Ok(())
25524 }
25525
25526 fn generate_auto_increment_keyword(
25530 &mut self,
25531 col: &crate::expressions::ColumnDef,
25532 ) -> Result<()> {
25533 use crate::dialects::DialectType;
25534 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
25535 self.write_keyword("IDENTITY");
25536 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25537 self.write("(");
25538 if let Some(ref start) = col.auto_increment_start {
25539 self.generate_expression(start)?;
25540 } else {
25541 self.write("0");
25542 }
25543 self.write(", ");
25544 if let Some(ref inc) = col.auto_increment_increment {
25545 self.generate_expression(inc)?;
25546 } else {
25547 self.write("1");
25548 }
25549 self.write(")");
25550 }
25551 } else if matches!(
25552 self.config.dialect,
25553 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
25554 ) {
25555 self.write_keyword("AUTOINCREMENT");
25556 if let Some(ref start) = col.auto_increment_start {
25557 self.write_space();
25558 self.write_keyword("START");
25559 self.write_space();
25560 self.generate_expression(start)?;
25561 }
25562 if let Some(ref inc) = col.auto_increment_increment {
25563 self.write_space();
25564 self.write_keyword("INCREMENT");
25565 self.write_space();
25566 self.generate_expression(inc)?;
25567 }
25568 if let Some(order) = col.auto_increment_order {
25569 self.write_space();
25570 if order {
25571 self.write_keyword("ORDER");
25572 } else {
25573 self.write_keyword("NOORDER");
25574 }
25575 }
25576 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
25577 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
25578 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25579 self.write(" (");
25580 let mut first = true;
25581 if let Some(ref start) = col.auto_increment_start {
25582 self.write_keyword("START WITH");
25583 self.write_space();
25584 self.generate_expression(start)?;
25585 first = false;
25586 }
25587 if let Some(ref inc) = col.auto_increment_increment {
25588 if !first {
25589 self.write_space();
25590 }
25591 self.write_keyword("INCREMENT BY");
25592 self.write_space();
25593 self.generate_expression(inc)?;
25594 }
25595 self.write(")");
25596 }
25597 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
25598 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25601 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
25602 } else {
25603 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
25604 }
25605 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25606 self.write(" (");
25607 let mut first = true;
25608 if let Some(ref start) = col.auto_increment_start {
25609 self.write_keyword("START WITH");
25610 self.write_space();
25611 self.generate_expression(start)?;
25612 first = false;
25613 }
25614 if let Some(ref inc) = col.auto_increment_increment {
25615 if !first {
25616 self.write_space();
25617 }
25618 self.write_keyword("INCREMENT BY");
25619 self.write_space();
25620 self.generate_expression(inc)?;
25621 }
25622 self.write(")");
25623 }
25624 } else if matches!(
25625 self.config.dialect,
25626 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25627 ) {
25628 self.write_keyword("IDENTITY");
25629 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25630 self.write("(");
25631 if let Some(ref start) = col.auto_increment_start {
25632 self.generate_expression(start)?;
25633 } else {
25634 self.write("0");
25635 }
25636 self.write(", ");
25637 if let Some(ref inc) = col.auto_increment_increment {
25638 self.generate_expression(inc)?;
25639 } else {
25640 self.write("1");
25641 }
25642 self.write(")");
25643 }
25644 } else {
25645 self.write_keyword("AUTO_INCREMENT");
25646 if let Some(ref start) = col.auto_increment_start {
25647 self.write_space();
25648 self.write_keyword("START");
25649 self.write_space();
25650 self.generate_expression(start)?;
25651 }
25652 if let Some(ref inc) = col.auto_increment_increment {
25653 self.write_space();
25654 self.write_keyword("INCREMENT");
25655 self.write_space();
25656 self.generate_expression(inc)?;
25657 }
25658 if let Some(order) = col.auto_increment_order {
25659 self.write_space();
25660 if order {
25661 self.write_keyword("ORDER");
25662 } else {
25663 self.write_keyword("NOORDER");
25664 }
25665 }
25666 }
25667 Ok(())
25668 }
25669
25670 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
25671 self.write_keyword("AUTO_INCREMENT");
25673 self.write("=");
25674 self.generate_expression(&e.this)?;
25675 Ok(())
25676 }
25677
25678 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
25679 self.write_keyword("AUTO_REFRESH");
25681 self.write("=");
25682 self.generate_expression(&e.this)?;
25683 Ok(())
25684 }
25685
25686 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
25687 self.write_keyword("BACKUP");
25689 self.write_space();
25690 self.generate_expression(&e.this)?;
25691 Ok(())
25692 }
25693
25694 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
25695 self.write_keyword("BASE64_DECODE_BINARY");
25697 self.write("(");
25698 self.generate_expression(&e.this)?;
25699 if let Some(alphabet) = &e.alphabet {
25700 self.write(", ");
25701 self.generate_expression(alphabet)?;
25702 }
25703 self.write(")");
25704 Ok(())
25705 }
25706
25707 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
25708 self.write_keyword("BASE64_DECODE_STRING");
25710 self.write("(");
25711 self.generate_expression(&e.this)?;
25712 if let Some(alphabet) = &e.alphabet {
25713 self.write(", ");
25714 self.generate_expression(alphabet)?;
25715 }
25716 self.write(")");
25717 Ok(())
25718 }
25719
25720 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
25721 self.write_keyword("BASE64_ENCODE");
25723 self.write("(");
25724 self.generate_expression(&e.this)?;
25725 if let Some(max_line_length) = &e.max_line_length {
25726 self.write(", ");
25727 self.generate_expression(max_line_length)?;
25728 }
25729 if let Some(alphabet) = &e.alphabet {
25730 self.write(", ");
25731 self.generate_expression(alphabet)?;
25732 }
25733 self.write(")");
25734 Ok(())
25735 }
25736
25737 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
25738 self.write_keyword("BLOCKCOMPRESSION");
25740 self.write("=");
25741 if let Some(autotemp) = &e.autotemp {
25742 self.write_keyword("AUTOTEMP");
25743 self.write("(");
25744 self.generate_expression(autotemp)?;
25745 self.write(")");
25746 }
25747 if let Some(always) = &e.always {
25748 self.generate_expression(always)?;
25749 }
25750 if let Some(default) = &e.default {
25751 self.generate_expression(default)?;
25752 }
25753 if let Some(manual) = &e.manual {
25754 self.generate_expression(manual)?;
25755 }
25756 if let Some(never) = &e.never {
25757 self.generate_expression(never)?;
25758 }
25759 Ok(())
25760 }
25761
25762 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
25763 self.write("((");
25765 self.generate_expression(&e.this)?;
25766 self.write(") ");
25767 self.write_keyword("AND");
25768 self.write(" (");
25769 self.generate_expression(&e.expression)?;
25770 self.write("))");
25771 Ok(())
25772 }
25773
25774 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
25775 self.write("((");
25777 self.generate_expression(&e.this)?;
25778 self.write(") ");
25779 self.write_keyword("OR");
25780 self.write(" (");
25781 self.generate_expression(&e.expression)?;
25782 self.write("))");
25783 Ok(())
25784 }
25785
25786 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
25787 self.write_keyword("BUILD");
25789 self.write_space();
25790 self.generate_expression(&e.this)?;
25791 Ok(())
25792 }
25793
25794 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
25795 self.generate_expression(&e.this)?;
25797 Ok(())
25798 }
25799
25800 fn generate_case_specific_column_constraint(
25801 &mut self,
25802 e: &CaseSpecificColumnConstraint,
25803 ) -> Result<()> {
25804 if e.not_.is_some() {
25806 self.write_keyword("NOT");
25807 self.write_space();
25808 }
25809 self.write_keyword("CASESPECIFIC");
25810 Ok(())
25811 }
25812
25813 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
25814 self.write_keyword("CAST");
25816 self.write("(");
25817 self.generate_expression(&e.this)?;
25818 if self.config.dialect == Some(DialectType::ClickHouse) {
25819 self.write(", ");
25821 } else {
25822 self.write_space();
25823 self.write_keyword("AS");
25824 self.write_space();
25825 }
25826 if let Some(to) = &e.to {
25827 self.generate_expression(to)?;
25828 }
25829 self.write(")");
25830 Ok(())
25831 }
25832
25833 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
25834 self.write_keyword("CHANGES");
25837 self.write(" (");
25838 if let Some(information) = &e.information {
25839 self.write_keyword("INFORMATION");
25840 self.write(" => ");
25841 self.generate_expression(information)?;
25842 }
25843 self.write(")");
25844 if let Some(at_before) = &e.at_before {
25846 self.write(" ");
25847 self.generate_expression(at_before)?;
25848 }
25849 if let Some(end) = &e.end {
25850 self.write(" ");
25851 self.generate_expression(end)?;
25852 }
25853 Ok(())
25854 }
25855
25856 fn generate_character_set_column_constraint(
25857 &mut self,
25858 e: &CharacterSetColumnConstraint,
25859 ) -> Result<()> {
25860 self.write_keyword("CHARACTER SET");
25862 self.write_space();
25863 self.generate_expression(&e.this)?;
25864 Ok(())
25865 }
25866
25867 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
25868 if e.default.is_some() {
25870 self.write_keyword("DEFAULT");
25871 self.write_space();
25872 }
25873 self.write_keyword("CHARACTER SET");
25874 self.write("=");
25875 self.generate_expression(&e.this)?;
25876 Ok(())
25877 }
25878
25879 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
25880 self.write_keyword("CHECK");
25882 self.write(" (");
25883 self.generate_expression(&e.this)?;
25884 self.write(")");
25885 if e.enforced.is_some() {
25886 self.write_space();
25887 self.write_keyword("ENFORCED");
25888 }
25889 Ok(())
25890 }
25891
25892 fn generate_assume_column_constraint(&mut self, e: &AssumeColumnConstraint) -> Result<()> {
25893 self.write_keyword("ASSUME");
25895 self.write(" (");
25896 self.generate_expression(&e.this)?;
25897 self.write(")");
25898 Ok(())
25899 }
25900
25901 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
25902 self.write_keyword("CHECK_JSON");
25904 self.write("(");
25905 self.generate_expression(&e.this)?;
25906 self.write(")");
25907 Ok(())
25908 }
25909
25910 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
25911 self.write_keyword("CHECK_XML");
25913 self.write("(");
25914 self.generate_expression(&e.this)?;
25915 self.write(")");
25916 Ok(())
25917 }
25918
25919 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
25920 self.write_keyword("CHECKSUM");
25922 self.write("=");
25923 if e.on.is_some() {
25924 self.write_keyword("ON");
25925 } else if e.default.is_some() {
25926 self.write_keyword("DEFAULT");
25927 } else {
25928 self.write_keyword("OFF");
25929 }
25930 Ok(())
25931 }
25932
25933 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
25934 if e.shallow.is_some() {
25936 self.write_keyword("SHALLOW");
25937 self.write_space();
25938 }
25939 if e.copy.is_some() {
25940 self.write_keyword("COPY");
25941 } else {
25942 self.write_keyword("CLONE");
25943 }
25944 self.write_space();
25945 self.generate_expression(&e.this)?;
25946 Ok(())
25947 }
25948
25949 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
25950 self.write_keyword("CLUSTER BY");
25952 self.write(" (");
25953 for (i, ord) in e.expressions.iter().enumerate() {
25954 if i > 0 {
25955 self.write(", ");
25956 }
25957 self.generate_ordered(ord)?;
25958 }
25959 self.write(")");
25960 Ok(())
25961 }
25962
25963 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
25964 self.write_keyword("CLUSTER BY");
25966 self.write_space();
25967 for (i, col) in e.columns.iter().enumerate() {
25968 if i > 0 {
25969 self.write(", ");
25970 }
25971 self.generate_identifier(col)?;
25972 }
25973 Ok(())
25974 }
25975
25976 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
25977 self.write_keyword("CLUSTERED BY");
25979 self.write(" (");
25980 for (i, expr) in e.expressions.iter().enumerate() {
25981 if i > 0 {
25982 self.write(", ");
25983 }
25984 self.generate_expression(expr)?;
25985 }
25986 self.write(")");
25987 if let Some(sorted_by) = &e.sorted_by {
25988 self.write_space();
25989 self.write_keyword("SORTED BY");
25990 self.write(" (");
25991 if let Expression::Tuple(t) = sorted_by.as_ref() {
25993 for (i, expr) in t.expressions.iter().enumerate() {
25994 if i > 0 {
25995 self.write(", ");
25996 }
25997 self.generate_expression(expr)?;
25998 }
25999 } else {
26000 self.generate_expression(sorted_by)?;
26001 }
26002 self.write(")");
26003 }
26004 if let Some(buckets) = &e.buckets {
26005 self.write_space();
26006 self.write_keyword("INTO");
26007 self.write_space();
26008 self.generate_expression(buckets)?;
26009 self.write_space();
26010 self.write_keyword("BUCKETS");
26011 }
26012 Ok(())
26013 }
26014
26015 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
26016 if e.default.is_some() {
26020 self.write_keyword("DEFAULT");
26021 self.write_space();
26022 }
26023 self.write_keyword("COLLATE");
26024 match self.config.dialect {
26026 Some(DialectType::BigQuery) => self.write_space(),
26027 _ => self.write("="),
26028 }
26029 self.generate_expression(&e.this)?;
26030 Ok(())
26031 }
26032
26033 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
26034 match e {
26036 ColumnConstraint::NotNull => {
26037 self.write_keyword("NOT NULL");
26038 }
26039 ColumnConstraint::Null => {
26040 self.write_keyword("NULL");
26041 }
26042 ColumnConstraint::Unique => {
26043 self.write_keyword("UNIQUE");
26044 }
26045 ColumnConstraint::PrimaryKey => {
26046 self.write_keyword("PRIMARY KEY");
26047 }
26048 ColumnConstraint::Default(expr) => {
26049 self.write_keyword("DEFAULT");
26050 self.write_space();
26051 self.generate_expression(expr)?;
26052 }
26053 ColumnConstraint::Check(expr) => {
26054 self.write_keyword("CHECK");
26055 self.write(" (");
26056 self.generate_expression(expr)?;
26057 self.write(")");
26058 }
26059 ColumnConstraint::References(fk_ref) => {
26060 if fk_ref.has_foreign_key_keywords {
26061 self.write_keyword("FOREIGN KEY");
26062 self.write_space();
26063 }
26064 self.write_keyword("REFERENCES");
26065 self.write_space();
26066 self.generate_table(&fk_ref.table)?;
26067 if !fk_ref.columns.is_empty() {
26068 self.write(" (");
26069 for (i, col) in fk_ref.columns.iter().enumerate() {
26070 if i > 0 {
26071 self.write(", ");
26072 }
26073 self.generate_identifier(col)?;
26074 }
26075 self.write(")");
26076 }
26077 }
26078 ColumnConstraint::GeneratedAsIdentity(gen) => {
26079 self.write_keyword("GENERATED");
26080 self.write_space();
26081 if gen.always {
26082 self.write_keyword("ALWAYS");
26083 } else {
26084 self.write_keyword("BY DEFAULT");
26085 if gen.on_null {
26086 self.write_space();
26087 self.write_keyword("ON NULL");
26088 }
26089 }
26090 self.write_space();
26091 self.write_keyword("AS IDENTITY");
26092 }
26093 ColumnConstraint::Collate(collation) => {
26094 self.write_keyword("COLLATE");
26095 self.write_space();
26096 self.generate_identifier(collation)?;
26097 }
26098 ColumnConstraint::Comment(comment) => {
26099 self.write_keyword("COMMENT");
26100 self.write(" '");
26101 self.write(comment);
26102 self.write("'");
26103 }
26104 ColumnConstraint::ComputedColumn(cc) => {
26105 self.generate_computed_column_inline(cc)?;
26106 }
26107 ColumnConstraint::GeneratedAsRow(gar) => {
26108 self.generate_generated_as_row_inline(gar)?;
26109 }
26110 ColumnConstraint::Tags(tags) => {
26111 self.write_keyword("TAG");
26112 self.write(" (");
26113 for (i, expr) in tags.expressions.iter().enumerate() {
26114 if i > 0 {
26115 self.write(", ");
26116 }
26117 self.generate_expression(expr)?;
26118 }
26119 self.write(")");
26120 }
26121 ColumnConstraint::Path(path_expr) => {
26122 self.write_keyword("PATH");
26123 self.write_space();
26124 self.generate_expression(path_expr)?;
26125 }
26126 }
26127 Ok(())
26128 }
26129
26130 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
26131 match e {
26133 ColumnPosition::First => {
26134 self.write_keyword("FIRST");
26135 }
26136 ColumnPosition::After(ident) => {
26137 self.write_keyword("AFTER");
26138 self.write_space();
26139 self.generate_identifier(ident)?;
26140 }
26141 }
26142 Ok(())
26143 }
26144
26145 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
26146 self.generate_expression(&e.this)?;
26148 self.write("(");
26149 self.generate_expression(&e.expression)?;
26150 self.write(")");
26151 Ok(())
26152 }
26153
26154 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
26155 if let Some(ref unpack) = e.unpack {
26158 if let Expression::Boolean(b) = unpack.as_ref() {
26159 if b.value {
26160 self.write("*");
26161 }
26162 }
26163 }
26164 self.write_keyword("COLUMNS");
26165 self.write("(");
26166 self.generate_expression(&e.this)?;
26167 self.write(")");
26168 Ok(())
26169 }
26170
26171 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
26172 self.generate_expression(&e.this)?;
26174 self.write("(");
26175 for (i, expr) in e.expressions.iter().enumerate() {
26176 if i > 0 {
26177 self.write(", ");
26178 }
26179 self.generate_expression(expr)?;
26180 }
26181 self.write(")");
26182 Ok(())
26183 }
26184
26185 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
26186 self.generate_expression(&e.this)?;
26188 self.write("(");
26189 for (i, param) in e.params.iter().enumerate() {
26190 if i > 0 {
26191 self.write(", ");
26192 }
26193 self.generate_expression(param)?;
26194 }
26195 self.write(")(");
26196 for (i, expr) in e.expressions.iter().enumerate() {
26197 if i > 0 {
26198 self.write(", ");
26199 }
26200 self.generate_expression(expr)?;
26201 }
26202 self.write(")");
26203 Ok(())
26204 }
26205
26206 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
26207 self.write_keyword("COMMIT");
26209
26210 if e.this.is_none()
26212 && matches!(
26213 self.config.dialect,
26214 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26215 )
26216 {
26217 self.write_space();
26218 self.write_keyword("TRANSACTION");
26219 }
26220
26221 if let Some(this) = &e.this {
26223 let is_transaction_marker = matches!(
26225 this.as_ref(),
26226 Expression::Identifier(id) if id.name == "TRANSACTION"
26227 );
26228
26229 self.write_space();
26230 self.write_keyword("TRANSACTION");
26231
26232 if !is_transaction_marker {
26234 self.write_space();
26235 self.generate_expression(this)?;
26236 }
26237 }
26238
26239 if let Some(durability) = &e.durability {
26241 self.write_space();
26242 self.write_keyword("WITH");
26243 self.write(" (");
26244 self.write_keyword("DELAYED_DURABILITY");
26245 self.write(" = ");
26246 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
26247 self.write_keyword("ON");
26248 } else {
26249 self.write_keyword("OFF");
26250 }
26251 self.write(")");
26252 }
26253
26254 if let Some(chain) = &e.chain {
26256 self.write_space();
26257 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
26258 self.write_keyword("AND NO CHAIN");
26259 } else {
26260 self.write_keyword("AND CHAIN");
26261 }
26262 }
26263 Ok(())
26264 }
26265
26266 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
26267 self.write("[");
26269 self.generate_expression(&e.this)?;
26270 self.write_space();
26271 self.write_keyword("FOR");
26272 self.write_space();
26273 self.generate_expression(&e.expression)?;
26274 if let Some(pos) = &e.position {
26276 self.write(", ");
26277 self.generate_expression(pos)?;
26278 }
26279 if let Some(iterator) = &e.iterator {
26280 self.write_space();
26281 self.write_keyword("IN");
26282 self.write_space();
26283 self.generate_expression(iterator)?;
26284 }
26285 if let Some(condition) = &e.condition {
26286 self.write_space();
26287 self.write_keyword("IF");
26288 self.write_space();
26289 self.generate_expression(condition)?;
26290 }
26291 self.write("]");
26292 Ok(())
26293 }
26294
26295 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
26296 self.write_keyword("COMPRESS");
26298 self.write("(");
26299 self.generate_expression(&e.this)?;
26300 if let Some(method) = &e.method {
26301 self.write(", '");
26302 self.write(method);
26303 self.write("'");
26304 }
26305 self.write(")");
26306 Ok(())
26307 }
26308
26309 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
26310 self.write_keyword("COMPRESS");
26312 if let Some(this) = &e.this {
26313 self.write_space();
26314 self.generate_expression(this)?;
26315 }
26316 Ok(())
26317 }
26318
26319 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
26320 self.write_keyword("AS");
26322 self.write_space();
26323 self.generate_expression(&e.this)?;
26324 if e.not_null.is_some() {
26325 self.write_space();
26326 self.write_keyword("PERSISTED NOT NULL");
26327 } else if e.persisted.is_some() {
26328 self.write_space();
26329 self.write_keyword("PERSISTED");
26330 }
26331 Ok(())
26332 }
26333
26334 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
26338 let computed_expr = if matches!(
26339 self.config.dialect,
26340 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26341 ) {
26342 match &*cc.expression {
26343 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
26344 {
26345 let wrapped = Expression::Cast(Box::new(Cast {
26346 this: y.this.clone(),
26347 to: DataType::Date,
26348 trailing_comments: Vec::new(),
26349 double_colon_syntax: false,
26350 format: None,
26351 default: None,
26352 inferred_type: None,
26353 }));
26354 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
26355 }
26356 Expression::Function(f)
26357 if f.name.eq_ignore_ascii_case("YEAR")
26358 && f.args.len() == 1
26359 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
26360 {
26361 let wrapped = Expression::Cast(Box::new(Cast {
26362 this: f.args[0].clone(),
26363 to: DataType::Date,
26364 trailing_comments: Vec::new(),
26365 double_colon_syntax: false,
26366 format: None,
26367 default: None,
26368 inferred_type: None,
26369 }));
26370 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
26371 }
26372 _ => *cc.expression.clone(),
26373 }
26374 } else {
26375 *cc.expression.clone()
26376 };
26377
26378 match cc.persistence_kind.as_deref() {
26379 Some("STORED") | Some("VIRTUAL") => {
26380 self.write_keyword("GENERATED ALWAYS AS");
26382 self.write(" (");
26383 self.generate_expression(&computed_expr)?;
26384 self.write(")");
26385 self.write_space();
26386 if cc.persisted {
26387 self.write_keyword("STORED");
26388 } else {
26389 self.write_keyword("VIRTUAL");
26390 }
26391 }
26392 Some("PERSISTED") => {
26393 self.write_keyword("AS");
26395 self.write(" (");
26396 self.generate_expression(&computed_expr)?;
26397 self.write(")");
26398 self.write_space();
26399 self.write_keyword("PERSISTED");
26400 if let Some(ref dt) = cc.data_type {
26402 self.write_space();
26403 self.generate_data_type(dt)?;
26404 }
26405 if cc.not_null {
26406 self.write_space();
26407 self.write_keyword("NOT NULL");
26408 }
26409 }
26410 _ => {
26411 if matches!(
26414 self.config.dialect,
26415 Some(DialectType::Spark)
26416 | Some(DialectType::Databricks)
26417 | Some(DialectType::Hive)
26418 ) {
26419 self.write_keyword("GENERATED ALWAYS AS");
26420 self.write(" (");
26421 self.generate_expression(&computed_expr)?;
26422 self.write(")");
26423 } else if matches!(
26424 self.config.dialect,
26425 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26426 ) {
26427 self.write_keyword("AS");
26428 let omit_parens = matches!(computed_expr, Expression::Year(_))
26429 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
26430 if omit_parens {
26431 self.write_space();
26432 self.generate_expression(&computed_expr)?;
26433 } else {
26434 self.write(" (");
26435 self.generate_expression(&computed_expr)?;
26436 self.write(")");
26437 }
26438 } else {
26439 self.write_keyword("AS");
26440 self.write(" (");
26441 self.generate_expression(&computed_expr)?;
26442 self.write(")");
26443 }
26444 }
26445 }
26446 Ok(())
26447 }
26448
26449 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
26452 self.write_keyword("GENERATED ALWAYS AS ROW ");
26453 if gar.start {
26454 self.write_keyword("START");
26455 } else {
26456 self.write_keyword("END");
26457 }
26458 if gar.hidden {
26459 self.write_space();
26460 self.write_keyword("HIDDEN");
26461 }
26462 Ok(())
26463 }
26464
26465 fn generate_system_versioning_content(
26467 &mut self,
26468 e: &WithSystemVersioningProperty,
26469 ) -> Result<()> {
26470 let mut parts = Vec::new();
26471
26472 if let Some(this) = &e.this {
26473 let mut s = String::from("HISTORY_TABLE=");
26474 let mut gen = Generator::with_arc_config(self.config.clone());
26475 gen.generate_expression(this)?;
26476 s.push_str(&gen.output);
26477 parts.push(s);
26478 }
26479
26480 if let Some(data_consistency) = &e.data_consistency {
26481 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
26482 let mut gen = Generator::with_arc_config(self.config.clone());
26483 gen.generate_expression(data_consistency)?;
26484 s.push_str(&gen.output);
26485 parts.push(s);
26486 }
26487
26488 if let Some(retention_period) = &e.retention_period {
26489 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
26490 let mut gen = Generator::with_arc_config(self.config.clone());
26491 gen.generate_expression(retention_period)?;
26492 s.push_str(&gen.output);
26493 parts.push(s);
26494 }
26495
26496 self.write_keyword("SYSTEM_VERSIONING");
26497 self.write("=");
26498
26499 if !parts.is_empty() {
26500 self.write_keyword("ON");
26501 self.write("(");
26502 self.write(&parts.join(", "));
26503 self.write(")");
26504 } else if e.on.is_some() {
26505 self.write_keyword("ON");
26506 } else {
26507 self.write_keyword("OFF");
26508 }
26509
26510 Ok(())
26511 }
26512
26513 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
26514 if e.else_.is_some() {
26517 self.write_keyword("ELSE");
26518 self.write_space();
26519 } else if let Some(expression) = &e.expression {
26520 self.write_keyword("WHEN");
26521 self.write_space();
26522 self.generate_expression(expression)?;
26523 self.write_space();
26524 self.write_keyword("THEN");
26525 self.write_space();
26526 }
26527
26528 if let Expression::Insert(insert) = e.this.as_ref() {
26531 self.write_keyword("INTO");
26532 self.write_space();
26533 self.generate_table(&insert.table)?;
26534
26535 if !insert.columns.is_empty() {
26537 self.write(" (");
26538 for (i, col) in insert.columns.iter().enumerate() {
26539 if i > 0 {
26540 self.write(", ");
26541 }
26542 self.generate_identifier(col)?;
26543 }
26544 self.write(")");
26545 }
26546
26547 if !insert.values.is_empty() {
26549 self.write_space();
26550 self.write_keyword("VALUES");
26551 for (row_idx, row) in insert.values.iter().enumerate() {
26552 if row_idx > 0 {
26553 self.write(", ");
26554 }
26555 self.write(" (");
26556 for (i, val) in row.iter().enumerate() {
26557 if i > 0 {
26558 self.write(", ");
26559 }
26560 self.generate_expression(val)?;
26561 }
26562 self.write(")");
26563 }
26564 }
26565 } else {
26566 self.generate_expression(&e.this)?;
26568 }
26569 Ok(())
26570 }
26571
26572 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
26573 self.write_keyword("CONSTRAINT");
26575 self.write_space();
26576 self.generate_expression(&e.this)?;
26577 if !e.expressions.is_empty() {
26578 self.write_space();
26579 for (i, expr) in e.expressions.iter().enumerate() {
26580 if i > 0 {
26581 self.write_space();
26582 }
26583 self.generate_expression(expr)?;
26584 }
26585 }
26586 Ok(())
26587 }
26588
26589 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
26590 self.write_keyword("CONVERT_TIMEZONE");
26592 self.write("(");
26593 let mut first = true;
26594 if let Some(source_tz) = &e.source_tz {
26595 self.generate_expression(source_tz)?;
26596 first = false;
26597 }
26598 if let Some(target_tz) = &e.target_tz {
26599 if !first {
26600 self.write(", ");
26601 }
26602 self.generate_expression(target_tz)?;
26603 first = false;
26604 }
26605 if let Some(timestamp) = &e.timestamp {
26606 if !first {
26607 self.write(", ");
26608 }
26609 self.generate_expression(timestamp)?;
26610 }
26611 self.write(")");
26612 Ok(())
26613 }
26614
26615 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
26616 self.write_keyword("CONVERT");
26618 self.write("(");
26619 self.generate_expression(&e.this)?;
26620 if let Some(dest) = &e.dest {
26621 self.write_space();
26622 self.write_keyword("USING");
26623 self.write_space();
26624 self.generate_expression(dest)?;
26625 }
26626 self.write(")");
26627 Ok(())
26628 }
26629
26630 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
26631 self.write_keyword("COPY");
26632 if e.is_into {
26633 self.write_space();
26634 self.write_keyword("INTO");
26635 }
26636 self.write_space();
26637
26638 if let Expression::Literal(lit) = &e.this {
26640 if let Literal::String(s) = lit.as_ref() {
26641 if s.starts_with('@') {
26642 self.write(s);
26643 } else {
26644 self.generate_expression(&e.this)?;
26645 }
26646 }
26647 } else {
26648 self.generate_expression(&e.this)?;
26649 }
26650
26651 if e.kind {
26653 if self.config.pretty {
26655 self.write_newline();
26656 } else {
26657 self.write_space();
26658 }
26659 self.write_keyword("FROM");
26660 self.write_space();
26661 } else if !e.files.is_empty() {
26662 if self.config.pretty {
26664 self.write_newline();
26665 } else {
26666 self.write_space();
26667 }
26668 self.write_keyword("TO");
26669 self.write_space();
26670 }
26671
26672 for (i, file) in e.files.iter().enumerate() {
26674 if i > 0 {
26675 self.write_space();
26676 }
26677 if let Expression::Literal(lit) = file {
26679 if let Literal::String(s) = lit.as_ref() {
26680 if s.starts_with('@') {
26681 self.write(s);
26682 } else {
26683 self.generate_expression(file)?;
26684 }
26685 }
26686 } else if let Expression::Identifier(id) = file {
26687 if id.quoted {
26689 self.write("`");
26690 self.write(&id.name);
26691 self.write("`");
26692 } else {
26693 self.generate_expression(file)?;
26694 }
26695 } else {
26696 self.generate_expression(file)?;
26697 }
26698 }
26699
26700 if !e.with_wrapped {
26702 if let Some(ref creds) = e.credentials {
26703 if let Some(ref storage) = creds.storage {
26704 if self.config.pretty {
26705 self.write_newline();
26706 } else {
26707 self.write_space();
26708 }
26709 self.write_keyword("STORAGE_INTEGRATION");
26710 self.write(" = ");
26711 self.write(storage);
26712 }
26713 if creds.credentials.is_empty() {
26714 if self.config.pretty {
26716 self.write_newline();
26717 } else {
26718 self.write_space();
26719 }
26720 self.write_keyword("CREDENTIALS");
26721 self.write(" = ()");
26722 } else {
26723 if self.config.pretty {
26724 self.write_newline();
26725 } else {
26726 self.write_space();
26727 }
26728 self.write_keyword("CREDENTIALS");
26729 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
26732 self.write(" '");
26734 self.write(&creds.credentials[0].1);
26735 self.write("'");
26736 } else {
26737 self.write(" = (");
26739 for (i, (k, v)) in creds.credentials.iter().enumerate() {
26740 if i > 0 {
26741 self.write_space();
26742 }
26743 self.write(k);
26744 self.write("='");
26745 self.write(v);
26746 self.write("'");
26747 }
26748 self.write(")");
26749 }
26750 }
26751 if let Some(ref encryption) = creds.encryption {
26752 self.write_space();
26753 self.write_keyword("ENCRYPTION");
26754 self.write(" = ");
26755 self.write(encryption);
26756 }
26757 }
26758 }
26759
26760 if !e.params.is_empty() {
26762 if e.with_wrapped {
26763 self.write_space();
26765 self.write_keyword("WITH");
26766 self.write(" (");
26767 for (i, param) in e.params.iter().enumerate() {
26768 if i > 0 {
26769 self.write(", ");
26770 }
26771 self.generate_copy_param_with_format(param)?;
26772 }
26773 self.write(")");
26774 } else {
26775 for param in &e.params {
26779 if self.config.pretty {
26780 self.write_newline();
26781 } else {
26782 self.write_space();
26783 }
26784 self.write(¶m.name);
26786 if let Some(ref value) = param.value {
26787 if param.eq {
26789 self.write(" = ");
26790 } else {
26791 self.write(" ");
26792 }
26793 if !param.values.is_empty() {
26794 self.write("(");
26795 for (i, v) in param.values.iter().enumerate() {
26796 if i > 0 {
26797 self.write_space();
26798 }
26799 self.generate_copy_nested_param(v)?;
26800 }
26801 self.write(")");
26802 } else {
26803 self.generate_copy_param_value(value)?;
26805 }
26806 } else if !param.values.is_empty() {
26807 if param.eq {
26809 self.write(" = (");
26810 } else {
26811 self.write(" (");
26812 }
26813 let is_key_value_pairs = param
26818 .values
26819 .first()
26820 .map_or(false, |v| matches!(v, Expression::Eq(_)));
26821 let sep = if is_key_value_pairs && param.eq {
26822 " "
26823 } else {
26824 ", "
26825 };
26826 for (i, v) in param.values.iter().enumerate() {
26827 if i > 0 {
26828 self.write(sep);
26829 }
26830 self.generate_copy_nested_param(v)?;
26831 }
26832 self.write(")");
26833 }
26834 }
26835 }
26836 }
26837
26838 Ok(())
26839 }
26840
26841 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
26844 self.write_keyword(¶m.name);
26845 if !param.values.is_empty() {
26846 self.write(" = (");
26848 for (i, v) in param.values.iter().enumerate() {
26849 if i > 0 {
26850 self.write(", ");
26851 }
26852 self.generate_copy_nested_param(v)?;
26853 }
26854 self.write(")");
26855 } else if let Some(ref value) = param.value {
26856 if param.eq {
26857 self.write(" = ");
26858 } else {
26859 self.write(" ");
26860 }
26861 self.generate_expression(value)?;
26862 }
26863 Ok(())
26864 }
26865
26866 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
26868 match expr {
26869 Expression::Eq(eq) => {
26870 match &eq.left {
26872 Expression::Column(c) => self.write(&c.name.name),
26873 _ => self.generate_expression(&eq.left)?,
26874 }
26875 self.write("=");
26876 match &eq.right {
26878 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
26879 let Literal::String(s) = lit.as_ref() else {
26880 unreachable!()
26881 };
26882 self.write("'");
26883 self.write(s);
26884 self.write("'");
26885 }
26886 Expression::Tuple(t) => {
26887 self.write("(");
26889 if self.config.pretty {
26890 self.write_newline();
26891 self.indent_level += 1;
26892 for (i, item) in t.expressions.iter().enumerate() {
26893 if i > 0 {
26894 self.write(", ");
26895 }
26896 self.write_indent();
26897 self.generate_expression(item)?;
26898 }
26899 self.write_newline();
26900 self.indent_level -= 1;
26901 } else {
26902 for (i, item) in t.expressions.iter().enumerate() {
26903 if i > 0 {
26904 self.write(", ");
26905 }
26906 self.generate_expression(item)?;
26907 }
26908 }
26909 self.write(")");
26910 }
26911 _ => self.generate_expression(&eq.right)?,
26912 }
26913 Ok(())
26914 }
26915 Expression::Column(c) => {
26916 self.write(&c.name.name);
26918 Ok(())
26919 }
26920 _ => self.generate_expression(expr),
26921 }
26922 }
26923
26924 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
26927 match expr {
26928 Expression::Column(c) => {
26929 if c.name.quoted {
26931 self.write("\"");
26932 self.write(&c.name.name);
26933 self.write("\"");
26934 } else {
26935 self.write(&c.name.name);
26936 }
26937 Ok(())
26938 }
26939 Expression::Identifier(id) => {
26940 if id.quoted {
26942 self.write("\"");
26943 self.write(&id.name);
26944 self.write("\"");
26945 } else {
26946 self.write(&id.name);
26947 }
26948 Ok(())
26949 }
26950 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
26951 let Literal::String(s) = lit.as_ref() else {
26952 unreachable!()
26953 };
26954 self.write("'");
26956 self.write(s);
26957 self.write("'");
26958 Ok(())
26959 }
26960 _ => self.generate_expression(expr),
26961 }
26962 }
26963
26964 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
26965 self.write_keyword(&e.name);
26966 if let Some(ref value) = e.value {
26967 if e.eq {
26968 self.write(" = ");
26969 } else {
26970 self.write(" ");
26971 }
26972 self.generate_expression(value)?;
26973 }
26974 if !e.values.is_empty() {
26975 if e.eq {
26976 self.write(" = ");
26977 } else {
26978 self.write(" ");
26979 }
26980 self.write("(");
26981 for (i, v) in e.values.iter().enumerate() {
26982 if i > 0 {
26983 self.write(", ");
26984 }
26985 self.generate_expression(v)?;
26986 }
26987 self.write(")");
26988 }
26989 Ok(())
26990 }
26991
26992 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
26993 self.write_keyword("CORR");
26995 self.write("(");
26996 self.generate_expression(&e.this)?;
26997 self.write(", ");
26998 self.generate_expression(&e.expression)?;
26999 self.write(")");
27000 Ok(())
27001 }
27002
27003 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
27004 self.write_keyword("COSINE_DISTANCE");
27006 self.write("(");
27007 self.generate_expression(&e.this)?;
27008 self.write(", ");
27009 self.generate_expression(&e.expression)?;
27010 self.write(")");
27011 Ok(())
27012 }
27013
27014 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
27015 self.write_keyword("COVAR_POP");
27017 self.write("(");
27018 self.generate_expression(&e.this)?;
27019 self.write(", ");
27020 self.generate_expression(&e.expression)?;
27021 self.write(")");
27022 Ok(())
27023 }
27024
27025 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
27026 self.write_keyword("COVAR_SAMP");
27028 self.write("(");
27029 self.generate_expression(&e.this)?;
27030 self.write(", ");
27031 self.generate_expression(&e.expression)?;
27032 self.write(")");
27033 Ok(())
27034 }
27035
27036 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
27037 self.write_keyword("CREDENTIALS");
27039 self.write(" (");
27040 for (i, (key, value)) in e.credentials.iter().enumerate() {
27041 if i > 0 {
27042 self.write(", ");
27043 }
27044 self.write(key);
27045 self.write("='");
27046 self.write(value);
27047 self.write("'");
27048 }
27049 self.write(")");
27050 Ok(())
27051 }
27052
27053 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
27054 self.write_keyword("CREDENTIALS");
27056 self.write("=(");
27057 for (i, expr) in e.expressions.iter().enumerate() {
27058 if i > 0 {
27059 self.write(", ");
27060 }
27061 self.generate_expression(expr)?;
27062 }
27063 self.write(")");
27064 Ok(())
27065 }
27066
27067 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
27068 use crate::dialects::DialectType;
27069
27070 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
27073 self.generate_expression(&e.this)?;
27074 self.write_space();
27075 self.write_keyword("AS");
27076 self.write_space();
27077 self.generate_identifier(&e.alias)?;
27078 return Ok(());
27079 }
27080 self.write(&e.alias.name);
27081
27082 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
27084
27085 if !e.columns.is_empty() && !skip_cte_columns {
27086 self.write("(");
27087 for (i, col) in e.columns.iter().enumerate() {
27088 if i > 0 {
27089 self.write(", ");
27090 }
27091 self.write(&col.name);
27092 }
27093 self.write(")");
27094 }
27095 if !e.key_expressions.is_empty() {
27097 self.write_space();
27098 self.write_keyword("USING KEY");
27099 self.write(" (");
27100 for (i, key) in e.key_expressions.iter().enumerate() {
27101 if i > 0 {
27102 self.write(", ");
27103 }
27104 self.write(&key.name);
27105 }
27106 self.write(")");
27107 }
27108 self.write_space();
27109 self.write_keyword("AS");
27110 self.write_space();
27111 if let Some(materialized) = e.materialized {
27112 if materialized {
27113 self.write_keyword("MATERIALIZED");
27114 } else {
27115 self.write_keyword("NOT MATERIALIZED");
27116 }
27117 self.write_space();
27118 }
27119 self.write("(");
27120 self.generate_expression(&e.this)?;
27121 self.write(")");
27122 Ok(())
27123 }
27124
27125 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
27126 if e.expressions.is_empty() {
27128 self.write_keyword("WITH CUBE");
27129 } else {
27130 self.write_keyword("CUBE");
27131 self.write("(");
27132 for (i, expr) in e.expressions.iter().enumerate() {
27133 if i > 0 {
27134 self.write(", ");
27135 }
27136 self.generate_expression(expr)?;
27137 }
27138 self.write(")");
27139 }
27140 Ok(())
27141 }
27142
27143 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
27144 self.write_keyword("CURRENT_DATETIME");
27146 if let Some(this) = &e.this {
27147 self.write("(");
27148 self.generate_expression(this)?;
27149 self.write(")");
27150 }
27151 Ok(())
27152 }
27153
27154 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
27155 self.write_keyword("CURRENT_SCHEMA");
27157 Ok(())
27158 }
27159
27160 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
27161 self.write_keyword("CURRENT_SCHEMAS");
27163 self.write("(");
27164 if !matches!(
27166 self.config.dialect,
27167 Some(crate::dialects::DialectType::Snowflake)
27168 ) {
27169 if let Some(this) = &e.this {
27170 self.generate_expression(this)?;
27171 }
27172 }
27173 self.write(")");
27174 Ok(())
27175 }
27176
27177 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
27178 self.write_keyword("CURRENT_USER");
27180 let needs_parens = e.this.is_some()
27182 || matches!(
27183 self.config.dialect,
27184 Some(DialectType::Snowflake)
27185 | Some(DialectType::Spark)
27186 | Some(DialectType::Hive)
27187 | Some(DialectType::DuckDB)
27188 | Some(DialectType::BigQuery)
27189 | Some(DialectType::MySQL)
27190 | Some(DialectType::Databricks)
27191 );
27192 if needs_parens {
27193 self.write("()");
27194 }
27195 Ok(())
27196 }
27197
27198 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
27199 if self.config.dialect == Some(DialectType::Solr) {
27201 self.generate_expression(&e.this)?;
27202 self.write(" ");
27203 self.write_keyword("OR");
27204 self.write(" ");
27205 self.generate_expression(&e.expression)?;
27206 } else if self.config.dialect == Some(DialectType::MySQL) {
27207 self.generate_mysql_concat_from_dpipe(e)?;
27208 } else {
27209 self.generate_expression(&e.this)?;
27211 self.write(" || ");
27212 self.generate_expression(&e.expression)?;
27213 }
27214 Ok(())
27215 }
27216
27217 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
27218 self.write_keyword("DATABLOCKSIZE");
27220 self.write("=");
27221 if let Some(size) = e.size {
27222 self.write(&size.to_string());
27223 if let Some(units) = &e.units {
27224 self.write_space();
27225 self.generate_expression(units)?;
27226 }
27227 } else if e.minimum.is_some() {
27228 self.write_keyword("MINIMUM");
27229 } else if e.maximum.is_some() {
27230 self.write_keyword("MAXIMUM");
27231 } else if e.default.is_some() {
27232 self.write_keyword("DEFAULT");
27233 }
27234 Ok(())
27235 }
27236
27237 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
27238 self.write_keyword("DATA_DELETION");
27240 self.write("=");
27241
27242 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
27243 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
27244
27245 if is_on {
27246 self.write_keyword("ON");
27247 if has_options {
27248 self.write("(");
27249 let mut first = true;
27250 if let Some(filter_column) = &e.filter_column {
27251 self.write_keyword("FILTER_COLUMN");
27252 self.write("=");
27253 self.generate_expression(filter_column)?;
27254 first = false;
27255 }
27256 if let Some(retention_period) = &e.retention_period {
27257 if !first {
27258 self.write(", ");
27259 }
27260 self.write_keyword("RETENTION_PERIOD");
27261 self.write("=");
27262 self.generate_expression(retention_period)?;
27263 }
27264 self.write(")");
27265 }
27266 } else {
27267 self.write_keyword("OFF");
27268 }
27269 Ok(())
27270 }
27271
27272 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
27276 use crate::dialects::DialectType;
27277 use crate::expressions::Literal;
27278
27279 match self.config.dialect {
27280 Some(DialectType::Exasol) => {
27282 self.write_keyword("TO_DATE");
27283 self.write("(");
27284 match &e.this {
27286 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27287 let Literal::String(s) = lit.as_ref() else {
27288 unreachable!()
27289 };
27290 self.write("'");
27291 self.write(s);
27292 self.write("'");
27293 }
27294 _ => {
27295 self.generate_expression(&e.this)?;
27296 }
27297 }
27298 self.write(")");
27299 }
27300 _ => {
27302 self.write_keyword("DATE");
27303 self.write("(");
27304 self.generate_expression(&e.this)?;
27305 self.write(")");
27306 }
27307 }
27308 Ok(())
27309 }
27310
27311 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
27312 self.write_keyword("DATE_BIN");
27314 self.write("(");
27315 self.generate_expression(&e.this)?;
27316 self.write(", ");
27317 self.generate_expression(&e.expression)?;
27318 if let Some(origin) = &e.origin {
27319 self.write(", ");
27320 self.generate_expression(origin)?;
27321 }
27322 self.write(")");
27323 Ok(())
27324 }
27325
27326 fn generate_date_format_column_constraint(
27327 &mut self,
27328 e: &DateFormatColumnConstraint,
27329 ) -> Result<()> {
27330 self.write_keyword("FORMAT");
27332 self.write_space();
27333 self.generate_expression(&e.this)?;
27334 Ok(())
27335 }
27336
27337 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
27338 self.write_keyword("DATE_FROM_PARTS");
27340 self.write("(");
27341 let mut first = true;
27342 if let Some(year) = &e.year {
27343 self.generate_expression(year)?;
27344 first = false;
27345 }
27346 if let Some(month) = &e.month {
27347 if !first {
27348 self.write(", ");
27349 }
27350 self.generate_expression(month)?;
27351 first = false;
27352 }
27353 if let Some(day) = &e.day {
27354 if !first {
27355 self.write(", ");
27356 }
27357 self.generate_expression(day)?;
27358 }
27359 self.write(")");
27360 Ok(())
27361 }
27362
27363 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
27364 self.write_keyword("DATETIME");
27366 self.write("(");
27367 self.generate_expression(&e.this)?;
27368 if let Some(expr) = &e.expression {
27369 self.write(", ");
27370 self.generate_expression(expr)?;
27371 }
27372 self.write(")");
27373 Ok(())
27374 }
27375
27376 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
27377 self.write_keyword("DATETIME_ADD");
27379 self.write("(");
27380 self.generate_expression(&e.this)?;
27381 self.write(", ");
27382 self.generate_expression(&e.expression)?;
27383 if let Some(unit) = &e.unit {
27384 self.write(", ");
27385 self.write_keyword(unit);
27386 }
27387 self.write(")");
27388 Ok(())
27389 }
27390
27391 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
27392 self.write_keyword("DATETIME_DIFF");
27394 self.write("(");
27395 self.generate_expression(&e.this)?;
27396 self.write(", ");
27397 self.generate_expression(&e.expression)?;
27398 if let Some(unit) = &e.unit {
27399 self.write(", ");
27400 self.write_keyword(unit);
27401 }
27402 self.write(")");
27403 Ok(())
27404 }
27405
27406 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
27407 self.write_keyword("DATETIME_SUB");
27409 self.write("(");
27410 self.generate_expression(&e.this)?;
27411 self.write(", ");
27412 self.generate_expression(&e.expression)?;
27413 if let Some(unit) = &e.unit {
27414 self.write(", ");
27415 self.write_keyword(unit);
27416 }
27417 self.write(")");
27418 Ok(())
27419 }
27420
27421 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
27422 self.write_keyword("DATETIME_TRUNC");
27424 self.write("(");
27425 self.generate_expression(&e.this)?;
27426 self.write(", ");
27427 self.write_keyword(&e.unit);
27428 if let Some(zone) = &e.zone {
27429 self.write(", ");
27430 self.generate_expression(zone)?;
27431 }
27432 self.write(")");
27433 Ok(())
27434 }
27435
27436 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
27437 self.write_keyword("DAYNAME");
27439 self.write("(");
27440 self.generate_expression(&e.this)?;
27441 self.write(")");
27442 Ok(())
27443 }
27444
27445 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
27446 self.write_keyword("DECLARE");
27448 self.write_space();
27449 if e.replace {
27450 self.write_keyword("OR");
27451 self.write_space();
27452 self.write_keyword("REPLACE");
27453 self.write_space();
27454 }
27455 for (i, expr) in e.expressions.iter().enumerate() {
27456 if i > 0 {
27457 self.write(", ");
27458 }
27459 self.generate_expression(expr)?;
27460 }
27461 Ok(())
27462 }
27463
27464 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
27465 use crate::dialects::DialectType;
27466
27467 self.generate_expression(&e.this)?;
27469 for name in &e.additional_names {
27471 self.write(", ");
27472 self.generate_expression(name)?;
27473 }
27474 if let Some(kind) = &e.kind {
27475 self.write_space();
27476 match self.config.dialect {
27480 Some(DialectType::BigQuery) => {
27481 self.write(kind);
27482 }
27483 Some(DialectType::TSQL) => {
27484 let is_complex_table = kind.starts_with("TABLE")
27488 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
27489 if is_complex_table {
27490 self.write(kind);
27491 } else if kind == "INT" {
27492 self.write("INTEGER");
27493 } else if kind.starts_with("TABLE") {
27494 let normalized = kind
27496 .replace(" INT ", " INTEGER ")
27497 .replace(" INT,", " INTEGER,")
27498 .replace(" INT)", " INTEGER)")
27499 .replace("(INT ", "(INTEGER ");
27500 self.write(&normalized);
27501 } else {
27502 self.write(kind);
27503 }
27504 }
27505 _ => {
27506 if e.has_as {
27507 self.write_keyword("AS");
27508 self.write_space();
27509 }
27510 self.write(kind);
27511 }
27512 }
27513 }
27514 if let Some(default) = &e.default {
27515 match self.config.dialect {
27517 Some(DialectType::BigQuery) => {
27518 self.write_space();
27519 self.write_keyword("DEFAULT");
27520 self.write_space();
27521 }
27522 _ => {
27523 self.write(" = ");
27524 }
27525 }
27526 self.generate_expression(default)?;
27527 }
27528 Ok(())
27529 }
27530
27531 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
27532 self.write_keyword("DECODE");
27534 self.write("(");
27535 for (i, expr) in e.expressions.iter().enumerate() {
27536 if i > 0 {
27537 self.write(", ");
27538 }
27539 self.generate_expression(expr)?;
27540 }
27541 self.write(")");
27542 Ok(())
27543 }
27544
27545 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
27546 self.write_keyword("DECOMPRESS");
27548 self.write("(");
27549 self.generate_expression(&e.this)?;
27550 self.write(", '");
27551 self.write(&e.method);
27552 self.write("')");
27553 Ok(())
27554 }
27555
27556 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
27557 self.write_keyword("DECOMPRESS");
27559 self.write("(");
27560 self.generate_expression(&e.this)?;
27561 self.write(", '");
27562 self.write(&e.method);
27563 self.write("')");
27564 Ok(())
27565 }
27566
27567 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
27568 self.write_keyword("DECRYPT");
27570 self.write("(");
27571 self.generate_expression(&e.this)?;
27572 if let Some(passphrase) = &e.passphrase {
27573 self.write(", ");
27574 self.generate_expression(passphrase)?;
27575 }
27576 if let Some(aad) = &e.aad {
27577 self.write(", ");
27578 self.generate_expression(aad)?;
27579 }
27580 if let Some(method) = &e.encryption_method {
27581 self.write(", ");
27582 self.generate_expression(method)?;
27583 }
27584 self.write(")");
27585 Ok(())
27586 }
27587
27588 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
27589 self.write_keyword("DECRYPT_RAW");
27591 self.write("(");
27592 self.generate_expression(&e.this)?;
27593 if let Some(key) = &e.key {
27594 self.write(", ");
27595 self.generate_expression(key)?;
27596 }
27597 if let Some(iv) = &e.iv {
27598 self.write(", ");
27599 self.generate_expression(iv)?;
27600 }
27601 if let Some(aad) = &e.aad {
27602 self.write(", ");
27603 self.generate_expression(aad)?;
27604 }
27605 if let Some(method) = &e.encryption_method {
27606 self.write(", ");
27607 self.generate_expression(method)?;
27608 }
27609 self.write(")");
27610 Ok(())
27611 }
27612
27613 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
27614 self.write_keyword("DEFINER");
27616 self.write(" = ");
27617 self.generate_expression(&e.this)?;
27618 Ok(())
27619 }
27620
27621 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
27622 self.write_keyword("DETACH");
27624 if e.exists {
27625 self.write_keyword(" DATABASE IF EXISTS");
27626 }
27627 self.write_space();
27628 self.generate_expression(&e.this)?;
27629 Ok(())
27630 }
27631
27632 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
27633 let property_name = match e.this.as_ref() {
27634 Expression::Identifier(id) => id.name.as_str(),
27635 Expression::Var(v) => v.this.as_str(),
27636 _ => "DICTIONARY",
27637 };
27638 self.write_keyword(property_name);
27639 self.write("(");
27640 self.write(&e.kind);
27641 if let Some(settings) = &e.settings {
27642 self.write("(");
27643 if let Expression::Tuple(t) = settings.as_ref() {
27644 if self.config.pretty && !t.expressions.is_empty() {
27645 self.write_newline();
27646 self.indent_level += 1;
27647 for (i, pair) in t.expressions.iter().enumerate() {
27648 if i > 0 {
27649 self.write(",");
27650 self.write_newline();
27651 }
27652 self.write_indent();
27653 if let Expression::Tuple(pair_tuple) = pair {
27654 if let Some(k) = pair_tuple.expressions.first() {
27655 self.generate_expression(k)?;
27656 }
27657 if let Some(v) = pair_tuple.expressions.get(1) {
27658 self.write(" ");
27659 self.generate_expression(v)?;
27660 }
27661 } else {
27662 self.generate_expression(pair)?;
27663 }
27664 }
27665 self.indent_level -= 1;
27666 self.write_newline();
27667 self.write_indent();
27668 } else {
27669 for (i, pair) in t.expressions.iter().enumerate() {
27670 if i > 0 {
27671 self.write(" ");
27673 }
27674 if let Expression::Tuple(pair_tuple) = pair {
27675 if let Some(k) = pair_tuple.expressions.first() {
27676 self.generate_expression(k)?;
27677 }
27678 if let Some(v) = pair_tuple.expressions.get(1) {
27679 self.write(" ");
27680 self.generate_expression(v)?;
27681 }
27682 } else {
27683 self.generate_expression(pair)?;
27684 }
27685 }
27686 }
27687 } else {
27688 self.generate_expression(settings)?;
27689 }
27690 self.write(")");
27691 } else {
27692 self.write("()");
27694 }
27695 self.write(")");
27696 Ok(())
27697 }
27698
27699 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
27700 let property_name = match e.this.as_ref() {
27701 Expression::Identifier(id) => id.name.as_str(),
27702 Expression::Var(v) => v.this.as_str(),
27703 _ => "RANGE",
27704 };
27705 self.write_keyword(property_name);
27706 self.write("(");
27707 if let Some(min) = &e.min {
27708 self.write_keyword("MIN");
27709 self.write_space();
27710 self.generate_expression(min)?;
27711 }
27712 if let Some(max) = &e.max {
27713 self.write_space();
27714 self.write_keyword("MAX");
27715 self.write_space();
27716 self.generate_expression(max)?;
27717 }
27718 self.write(")");
27719 Ok(())
27720 }
27721
27722 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
27723 if e.local.is_some() {
27725 self.write_keyword("LOCAL ");
27726 }
27727 self.write_keyword("DIRECTORY");
27728 self.write_space();
27729 self.generate_expression(&e.this)?;
27730 if let Some(row_format) = &e.row_format {
27731 self.write_space();
27732 self.generate_expression(row_format)?;
27733 }
27734 Ok(())
27735 }
27736
27737 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
27738 self.write_keyword("DISTKEY");
27740 self.write("(");
27741 self.generate_expression(&e.this)?;
27742 self.write(")");
27743 Ok(())
27744 }
27745
27746 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
27747 self.write_keyword("DISTSTYLE");
27749 self.write_space();
27750 self.generate_expression(&e.this)?;
27751 Ok(())
27752 }
27753
27754 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
27755 self.write_keyword("DISTRIBUTE BY");
27757 self.write_space();
27758 for (i, expr) in e.expressions.iter().enumerate() {
27759 if i > 0 {
27760 self.write(", ");
27761 }
27762 self.generate_expression(expr)?;
27763 }
27764 Ok(())
27765 }
27766
27767 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
27768 self.write_keyword("DISTRIBUTED BY");
27770 self.write_space();
27771 self.write(&e.kind);
27772 if !e.expressions.is_empty() {
27773 self.write(" (");
27774 for (i, expr) in e.expressions.iter().enumerate() {
27775 if i > 0 {
27776 self.write(", ");
27777 }
27778 self.generate_expression(expr)?;
27779 }
27780 self.write(")");
27781 }
27782 if let Some(buckets) = &e.buckets {
27783 self.write_space();
27784 self.write_keyword("BUCKETS");
27785 self.write_space();
27786 self.generate_expression(buckets)?;
27787 }
27788 if let Some(order) = &e.order {
27789 self.write_space();
27790 self.generate_expression(order)?;
27791 }
27792 Ok(())
27793 }
27794
27795 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
27796 self.write_keyword("DOT_PRODUCT");
27798 self.write("(");
27799 self.generate_expression(&e.this)?;
27800 self.write(", ");
27801 self.generate_expression(&e.expression)?;
27802 self.write(")");
27803 Ok(())
27804 }
27805
27806 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
27807 self.write_keyword("DROP");
27809 if e.exists {
27810 self.write_keyword(" IF EXISTS ");
27811 } else {
27812 self.write_space();
27813 }
27814 for (i, expr) in e.expressions.iter().enumerate() {
27815 if i > 0 {
27816 self.write(", ");
27817 }
27818 self.generate_expression(expr)?;
27819 }
27820 Ok(())
27821 }
27822
27823 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
27824 self.write_keyword("DUPLICATE KEY");
27826 self.write(" (");
27827 for (i, expr) in e.expressions.iter().enumerate() {
27828 if i > 0 {
27829 self.write(", ");
27830 }
27831 self.generate_expression(expr)?;
27832 }
27833 self.write(")");
27834 Ok(())
27835 }
27836
27837 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
27838 self.write_keyword("ELT");
27840 self.write("(");
27841 self.generate_expression(&e.this)?;
27842 for expr in &e.expressions {
27843 self.write(", ");
27844 self.generate_expression(expr)?;
27845 }
27846 self.write(")");
27847 Ok(())
27848 }
27849
27850 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
27851 self.write_keyword("ENCODE");
27853 self.write("(");
27854 self.generate_expression(&e.this)?;
27855 if let Some(charset) = &e.charset {
27856 self.write(", ");
27857 self.generate_expression(charset)?;
27858 }
27859 self.write(")");
27860 Ok(())
27861 }
27862
27863 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
27864 if e.key.is_some() {
27866 self.write_keyword("KEY ");
27867 }
27868 self.write_keyword("ENCODE");
27869 self.write_space();
27870 self.generate_expression(&e.this)?;
27871 if !e.properties.is_empty() {
27872 self.write(" (");
27873 for (i, prop) in e.properties.iter().enumerate() {
27874 if i > 0 {
27875 self.write(", ");
27876 }
27877 self.generate_expression(prop)?;
27878 }
27879 self.write(")");
27880 }
27881 Ok(())
27882 }
27883
27884 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
27885 self.write_keyword("ENCRYPT");
27887 self.write("(");
27888 self.generate_expression(&e.this)?;
27889 if let Some(passphrase) = &e.passphrase {
27890 self.write(", ");
27891 self.generate_expression(passphrase)?;
27892 }
27893 if let Some(aad) = &e.aad {
27894 self.write(", ");
27895 self.generate_expression(aad)?;
27896 }
27897 if let Some(method) = &e.encryption_method {
27898 self.write(", ");
27899 self.generate_expression(method)?;
27900 }
27901 self.write(")");
27902 Ok(())
27903 }
27904
27905 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
27906 self.write_keyword("ENCRYPT_RAW");
27908 self.write("(");
27909 self.generate_expression(&e.this)?;
27910 if let Some(key) = &e.key {
27911 self.write(", ");
27912 self.generate_expression(key)?;
27913 }
27914 if let Some(iv) = &e.iv {
27915 self.write(", ");
27916 self.generate_expression(iv)?;
27917 }
27918 if let Some(aad) = &e.aad {
27919 self.write(", ");
27920 self.generate_expression(aad)?;
27921 }
27922 if let Some(method) = &e.encryption_method {
27923 self.write(", ");
27924 self.generate_expression(method)?;
27925 }
27926 self.write(")");
27927 Ok(())
27928 }
27929
27930 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
27931 self.write_keyword("ENGINE");
27933 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
27934 self.write("=");
27935 } else {
27936 self.write(" = ");
27937 }
27938 self.generate_expression(&e.this)?;
27939 Ok(())
27940 }
27941
27942 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
27943 self.write_keyword("ENVIRONMENT");
27945 self.write(" (");
27946 for (i, expr) in e.expressions.iter().enumerate() {
27947 if i > 0 {
27948 self.write(", ");
27949 }
27950 self.generate_expression(expr)?;
27951 }
27952 self.write(")");
27953 Ok(())
27954 }
27955
27956 fn generate_ephemeral_column_constraint(
27957 &mut self,
27958 e: &EphemeralColumnConstraint,
27959 ) -> Result<()> {
27960 self.write_keyword("EPHEMERAL");
27962 if let Some(this) = &e.this {
27963 self.write_space();
27964 self.generate_expression(this)?;
27965 }
27966 Ok(())
27967 }
27968
27969 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
27970 self.write_keyword("EQUAL_NULL");
27972 self.write("(");
27973 self.generate_expression(&e.this)?;
27974 self.write(", ");
27975 self.generate_expression(&e.expression)?;
27976 self.write(")");
27977 Ok(())
27978 }
27979
27980 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
27981 use crate::dialects::DialectType;
27982
27983 match self.config.dialect {
27985 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
27986 self.generate_expression(&e.this)?;
27987 self.write(" <-> ");
27988 self.generate_expression(&e.expression)?;
27989 }
27990 _ => {
27991 self.write_keyword("EUCLIDEAN_DISTANCE");
27993 self.write("(");
27994 self.generate_expression(&e.this)?;
27995 self.write(", ");
27996 self.generate_expression(&e.expression)?;
27997 self.write(")");
27998 }
27999 }
28000 Ok(())
28001 }
28002
28003 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
28004 self.write_keyword("EXECUTE AS");
28006 self.write_space();
28007 self.generate_expression(&e.this)?;
28008 Ok(())
28009 }
28010
28011 fn generate_export(&mut self, e: &Export) -> Result<()> {
28012 self.write_keyword("EXPORT DATA");
28014 if let Some(connection) = &e.connection {
28015 self.write_space();
28016 self.write_keyword("WITH CONNECTION");
28017 self.write_space();
28018 self.generate_expression(connection)?;
28019 }
28020 if !e.options.is_empty() {
28021 self.write_space();
28022 self.generate_options_clause(&e.options)?;
28023 }
28024 self.write_space();
28025 self.write_keyword("AS");
28026 self.write_space();
28027 self.generate_expression(&e.this)?;
28028 Ok(())
28029 }
28030
28031 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
28032 self.write_keyword("EXTERNAL");
28034 if let Some(this) = &e.this {
28035 self.write_space();
28036 self.generate_expression(this)?;
28037 }
28038 Ok(())
28039 }
28040
28041 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
28042 if e.no.is_some() {
28044 self.write_keyword("NO ");
28045 }
28046 self.write_keyword("FALLBACK");
28047 if e.protection.is_some() {
28048 self.write_keyword(" PROTECTION");
28049 }
28050 Ok(())
28051 }
28052
28053 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
28054 self.write_keyword("FARM_FINGERPRINT");
28056 self.write("(");
28057 for (i, expr) in e.expressions.iter().enumerate() {
28058 if i > 0 {
28059 self.write(", ");
28060 }
28061 self.generate_expression(expr)?;
28062 }
28063 self.write(")");
28064 Ok(())
28065 }
28066
28067 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
28068 self.write_keyword("FEATURES_AT_TIME");
28070 self.write("(");
28071 self.generate_expression(&e.this)?;
28072 if let Some(time) = &e.time {
28073 self.write(", ");
28074 self.generate_expression(time)?;
28075 }
28076 if let Some(num_rows) = &e.num_rows {
28077 self.write(", ");
28078 self.generate_expression(num_rows)?;
28079 }
28080 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
28081 self.write(", ");
28082 self.generate_expression(ignore_nulls)?;
28083 }
28084 self.write(")");
28085 Ok(())
28086 }
28087
28088 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
28089 let use_limit = !e.percent
28091 && !e.with_ties
28092 && e.count.is_some()
28093 && matches!(
28094 self.config.dialect,
28095 Some(DialectType::Spark)
28096 | Some(DialectType::Hive)
28097 | Some(DialectType::DuckDB)
28098 | Some(DialectType::SQLite)
28099 | Some(DialectType::MySQL)
28100 | Some(DialectType::BigQuery)
28101 | Some(DialectType::Databricks)
28102 | Some(DialectType::StarRocks)
28103 | Some(DialectType::Doris)
28104 | Some(DialectType::Athena)
28105 | Some(DialectType::ClickHouse)
28106 );
28107
28108 if use_limit {
28109 self.write_keyword("LIMIT");
28110 self.write_space();
28111 self.generate_expression(e.count.as_ref().unwrap())?;
28112 return Ok(());
28113 }
28114
28115 self.write_keyword("FETCH");
28117 if !e.direction.is_empty() {
28118 self.write_space();
28119 self.write_keyword(&e.direction);
28120 }
28121 if let Some(count) = &e.count {
28122 self.write_space();
28123 self.generate_expression(count)?;
28124 }
28125 if e.percent {
28127 self.write_keyword(" PERCENT");
28128 }
28129 if e.rows {
28130 self.write_keyword(" ROWS");
28131 }
28132 if e.with_ties {
28133 self.write_keyword(" WITH TIES");
28134 } else if e.rows {
28135 self.write_keyword(" ONLY");
28136 } else {
28137 self.write_keyword(" ROWS ONLY");
28138 }
28139 Ok(())
28140 }
28141
28142 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
28143 if e.hive_format.is_some() {
28147 self.write_keyword("STORED AS");
28149 self.write_space();
28150 if let Some(this) = &e.this {
28151 if let Expression::Identifier(id) = this.as_ref() {
28153 self.write_keyword(&id.name.to_ascii_uppercase());
28154 } else {
28155 self.generate_expression(this)?;
28156 }
28157 }
28158 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
28159 self.write_keyword("STORED AS");
28161 self.write_space();
28162 if let Some(this) = &e.this {
28163 if let Expression::Identifier(id) = this.as_ref() {
28164 self.write_keyword(&id.name.to_ascii_uppercase());
28165 } else {
28166 self.generate_expression(this)?;
28167 }
28168 }
28169 } else if matches!(
28170 self.config.dialect,
28171 Some(DialectType::Spark) | Some(DialectType::Databricks)
28172 ) {
28173 self.write_keyword("USING");
28175 self.write_space();
28176 if let Some(this) = &e.this {
28177 self.generate_expression(this)?;
28178 }
28179 } else {
28180 self.write_keyword("FILE_FORMAT");
28182 self.write(" = ");
28183 if let Some(this) = &e.this {
28184 self.generate_expression(this)?;
28185 } else if !e.expressions.is_empty() {
28186 self.write("(");
28187 for (i, expr) in e.expressions.iter().enumerate() {
28188 if i > 0 {
28189 self.write(", ");
28190 }
28191 self.generate_expression(expr)?;
28192 }
28193 self.write(")");
28194 }
28195 }
28196 Ok(())
28197 }
28198
28199 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
28200 self.generate_expression(&e.this)?;
28202 self.write_space();
28203 self.write_keyword("FILTER");
28204 self.write("(");
28205 self.write_keyword("WHERE");
28206 self.write_space();
28207 self.generate_expression(&e.expression)?;
28208 self.write(")");
28209 Ok(())
28210 }
28211
28212 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
28213 self.write_keyword("FLOAT64");
28215 self.write("(");
28216 self.generate_expression(&e.this)?;
28217 if let Some(expr) = &e.expression {
28218 self.write(", ");
28219 self.generate_expression(expr)?;
28220 }
28221 self.write(")");
28222 Ok(())
28223 }
28224
28225 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
28226 self.write_keyword("FOR");
28228 self.write_space();
28229 self.generate_expression(&e.this)?;
28230 self.write_space();
28231 self.write_keyword("DO");
28232 self.write_space();
28233 self.generate_expression(&e.expression)?;
28234 Ok(())
28235 }
28236
28237 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
28238 self.write_keyword("FOREIGN KEY");
28240 if !e.expressions.is_empty() {
28241 self.write(" (");
28242 for (i, expr) in e.expressions.iter().enumerate() {
28243 if i > 0 {
28244 self.write(", ");
28245 }
28246 self.generate_expression(expr)?;
28247 }
28248 self.write(")");
28249 }
28250 if let Some(reference) = &e.reference {
28251 self.write_space();
28252 self.generate_expression(reference)?;
28253 }
28254 if let Some(delete) = &e.delete {
28255 self.write_space();
28256 self.write_keyword("ON DELETE");
28257 self.write_space();
28258 self.generate_expression(delete)?;
28259 }
28260 if let Some(update) = &e.update {
28261 self.write_space();
28262 self.write_keyword("ON UPDATE");
28263 self.write_space();
28264 self.generate_expression(update)?;
28265 }
28266 if !e.options.is_empty() {
28267 self.write_space();
28268 for (i, opt) in e.options.iter().enumerate() {
28269 if i > 0 {
28270 self.write_space();
28271 }
28272 self.generate_expression(opt)?;
28273 }
28274 }
28275 Ok(())
28276 }
28277
28278 fn generate_format(&mut self, e: &Format) -> Result<()> {
28279 self.write_keyword("FORMAT");
28281 self.write("(");
28282 self.generate_expression(&e.this)?;
28283 for expr in &e.expressions {
28284 self.write(", ");
28285 self.generate_expression(expr)?;
28286 }
28287 self.write(")");
28288 Ok(())
28289 }
28290
28291 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
28292 self.generate_expression(&e.this)?;
28294 self.write(" (");
28295 self.write_keyword("FORMAT");
28296 self.write(" '");
28297 self.write(&e.format);
28298 self.write("')");
28299 Ok(())
28300 }
28301
28302 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
28303 self.write_keyword("FREESPACE");
28305 self.write("=");
28306 self.generate_expression(&e.this)?;
28307 if e.percent.is_some() {
28308 self.write_keyword(" PERCENT");
28309 }
28310 Ok(())
28311 }
28312
28313 fn generate_from(&mut self, e: &From) -> Result<()> {
28314 self.write_keyword("FROM");
28316 self.write_space();
28317
28318 use crate::dialects::DialectType;
28322 let has_tablesample = e
28323 .expressions
28324 .iter()
28325 .any(|expr| matches!(expr, Expression::TableSample(_)));
28326 let is_cross_join_dialect = matches!(
28327 self.config.dialect,
28328 Some(DialectType::BigQuery)
28329 | Some(DialectType::Hive)
28330 | Some(DialectType::Spark)
28331 | Some(DialectType::Databricks)
28332 | Some(DialectType::SQLite)
28333 | Some(DialectType::ClickHouse)
28334 );
28335 let source_is_same_as_target2 = self.config.source_dialect.is_some()
28336 && self.config.source_dialect == self.config.dialect;
28337 let source_is_cross_join_dialect2 = matches!(
28338 self.config.source_dialect,
28339 Some(DialectType::BigQuery)
28340 | Some(DialectType::Hive)
28341 | Some(DialectType::Spark)
28342 | Some(DialectType::Databricks)
28343 | Some(DialectType::SQLite)
28344 | Some(DialectType::ClickHouse)
28345 );
28346 let use_cross_join = !has_tablesample
28347 && is_cross_join_dialect
28348 && (source_is_same_as_target2
28349 || source_is_cross_join_dialect2
28350 || self.config.source_dialect.is_none());
28351
28352 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
28354
28355 for (i, expr) in e.expressions.iter().enumerate() {
28356 if i > 0 {
28357 if use_cross_join {
28358 self.write(" CROSS JOIN ");
28359 } else {
28360 self.write(", ");
28361 }
28362 }
28363 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
28364 self.write("(");
28365 self.generate_expression(expr)?;
28366 self.write(")");
28367 } else {
28368 self.generate_expression(expr)?;
28369 }
28370 let leading = Self::extract_table_leading_comments(expr);
28373 for comment in &leading {
28374 self.write_space();
28375 self.write_formatted_comment(comment);
28376 }
28377 }
28378 Ok(())
28379 }
28380
28381 fn extract_table_leading_comments(expr: &Expression) -> Vec<String> {
28383 match expr {
28384 Expression::Table(t) => t.leading_comments.clone(),
28385 Expression::Pivot(p) => {
28386 if let Expression::Table(t) = &p.this {
28387 t.leading_comments.clone()
28388 } else {
28389 Vec::new()
28390 }
28391 }
28392 _ => Vec::new(),
28393 }
28394 }
28395
28396 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
28397 self.write_keyword("FROM_BASE");
28399 self.write("(");
28400 self.generate_expression(&e.this)?;
28401 self.write(", ");
28402 self.generate_expression(&e.expression)?;
28403 self.write(")");
28404 Ok(())
28405 }
28406
28407 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
28408 self.generate_expression(&e.this)?;
28410 if let Some(zone) = &e.zone {
28411 self.write_space();
28412 self.write_keyword("AT TIME ZONE");
28413 self.write_space();
28414 self.generate_expression(zone)?;
28415 self.write_space();
28416 self.write_keyword("AT TIME ZONE");
28417 self.write(" 'UTC'");
28418 }
28419 Ok(())
28420 }
28421
28422 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
28423 self.write_keyword("GAP_FILL");
28425 self.write("(");
28426 self.generate_expression(&e.this)?;
28427 if let Some(ts_column) = &e.ts_column {
28428 self.write(", ");
28429 self.generate_expression(ts_column)?;
28430 }
28431 if let Some(bucket_width) = &e.bucket_width {
28432 self.write(", ");
28433 self.generate_expression(bucket_width)?;
28434 }
28435 if let Some(partitioning_columns) = &e.partitioning_columns {
28436 self.write(", ");
28437 self.generate_expression(partitioning_columns)?;
28438 }
28439 if let Some(value_columns) = &e.value_columns {
28440 self.write(", ");
28441 self.generate_expression(value_columns)?;
28442 }
28443 self.write(")");
28444 Ok(())
28445 }
28446
28447 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
28448 self.write_keyword("GENERATE_DATE_ARRAY");
28450 self.write("(");
28451 let mut first = true;
28452 if let Some(start) = &e.start {
28453 self.generate_expression(start)?;
28454 first = false;
28455 }
28456 if let Some(end) = &e.end {
28457 if !first {
28458 self.write(", ");
28459 }
28460 self.generate_expression(end)?;
28461 first = false;
28462 }
28463 if let Some(step) = &e.step {
28464 if !first {
28465 self.write(", ");
28466 }
28467 self.generate_expression(step)?;
28468 }
28469 self.write(")");
28470 Ok(())
28471 }
28472
28473 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
28474 self.write_keyword("ML.GENERATE_EMBEDDING");
28476 self.write("(");
28477 self.generate_expression(&e.this)?;
28478 self.write(", ");
28479 self.generate_expression(&e.expression)?;
28480 if let Some(params) = &e.params_struct {
28481 self.write(", ");
28482 self.generate_expression(params)?;
28483 }
28484 self.write(")");
28485 Ok(())
28486 }
28487
28488 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
28489 let fn_name = match self.config.dialect {
28491 Some(DialectType::Presto)
28492 | Some(DialectType::Trino)
28493 | Some(DialectType::Athena)
28494 | Some(DialectType::Spark)
28495 | Some(DialectType::Databricks)
28496 | Some(DialectType::Hive) => "SEQUENCE",
28497 _ => "GENERATE_SERIES",
28498 };
28499 self.write_keyword(fn_name);
28500 self.write("(");
28501 let mut first = true;
28502 if let Some(start) = &e.start {
28503 self.generate_expression(start)?;
28504 first = false;
28505 }
28506 if let Some(end) = &e.end {
28507 if !first {
28508 self.write(", ");
28509 }
28510 self.generate_expression(end)?;
28511 first = false;
28512 }
28513 if let Some(step) = &e.step {
28514 if !first {
28515 self.write(", ");
28516 }
28517 if matches!(
28520 self.config.dialect,
28521 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
28522 ) {
28523 if let Some(converted) = self.convert_week_interval_to_day(step) {
28524 self.generate_expression(&converted)?;
28525 } else {
28526 self.generate_expression(step)?;
28527 }
28528 } else {
28529 self.generate_expression(step)?;
28530 }
28531 }
28532 self.write(")");
28533 Ok(())
28534 }
28535
28536 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
28539 use crate::expressions::*;
28540 if let Expression::Interval(ref iv) = expr {
28541 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
28543 unit: IntervalUnit::Week,
28544 ..
28545 }) = &iv.unit
28546 {
28547 let count = match &iv.this {
28549 Some(Expression::Literal(lit)) => match lit.as_ref() {
28550 Literal::String(s) | Literal::Number(s) => s.clone(),
28551 _ => return None,
28552 },
28553 _ => return None,
28554 };
28555 (true, count)
28556 } else if iv.unit.is_none() {
28557 if let Some(Expression::Literal(lit)) = &iv.this {
28559 if let Literal::String(s) = lit.as_ref() {
28560 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
28561 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
28562 (true, parts[0].to_string())
28563 } else {
28564 (false, String::new())
28565 }
28566 } else {
28567 (false, String::new())
28568 }
28569 } else {
28570 (false, String::new())
28571 }
28572 } else {
28573 (false, String::new())
28574 };
28575
28576 if is_week {
28577 let count_expr = Expression::Literal(Box::new(Literal::Number(count_str)));
28579 let day_interval = Expression::Interval(Box::new(Interval {
28580 this: Some(Expression::Literal(Box::new(Literal::String(
28581 "7".to_string(),
28582 )))),
28583 unit: Some(IntervalUnitSpec::Simple {
28584 unit: IntervalUnit::Day,
28585 use_plural: false,
28586 }),
28587 }));
28588 let mul = Expression::Mul(Box::new(BinaryOp {
28589 left: count_expr,
28590 right: day_interval,
28591 left_comments: vec![],
28592 operator_comments: vec![],
28593 trailing_comments: vec![],
28594 inferred_type: None,
28595 }));
28596 return Some(Expression::Paren(Box::new(Paren {
28597 this: mul,
28598 trailing_comments: vec![],
28599 })));
28600 }
28601 }
28602 None
28603 }
28604
28605 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
28606 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
28608 self.write("(");
28609 let mut first = true;
28610 if let Some(start) = &e.start {
28611 self.generate_expression(start)?;
28612 first = false;
28613 }
28614 if let Some(end) = &e.end {
28615 if !first {
28616 self.write(", ");
28617 }
28618 self.generate_expression(end)?;
28619 first = false;
28620 }
28621 if let Some(step) = &e.step {
28622 if !first {
28623 self.write(", ");
28624 }
28625 self.generate_expression(step)?;
28626 }
28627 self.write(")");
28628 Ok(())
28629 }
28630
28631 fn generate_generated_as_identity_column_constraint(
28632 &mut self,
28633 e: &GeneratedAsIdentityColumnConstraint,
28634 ) -> Result<()> {
28635 use crate::dialects::DialectType;
28636
28637 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
28639 self.write_keyword("AUTOINCREMENT");
28640 if let Some(start) = &e.start {
28641 self.write_keyword(" START ");
28642 self.generate_expression(start)?;
28643 }
28644 if let Some(increment) = &e.increment {
28645 self.write_keyword(" INCREMENT ");
28646 self.generate_expression(increment)?;
28647 }
28648 return Ok(());
28649 }
28650
28651 self.write_keyword("GENERATED");
28653 if let Some(this) = &e.this {
28654 if let Expression::Boolean(b) = this.as_ref() {
28656 if b.value {
28657 self.write_keyword(" ALWAYS");
28658 } else {
28659 self.write_keyword(" BY DEFAULT");
28660 if e.on_null.is_some() {
28661 self.write_keyword(" ON NULL");
28662 }
28663 }
28664 } else {
28665 self.write_keyword(" ALWAYS");
28666 }
28667 }
28668 self.write_keyword(" AS IDENTITY");
28669 let has_options = e.start.is_some()
28671 || e.increment.is_some()
28672 || e.minvalue.is_some()
28673 || e.maxvalue.is_some();
28674 if has_options {
28675 self.write(" (");
28676 let mut first = true;
28677 if let Some(start) = &e.start {
28678 self.write_keyword("START WITH ");
28679 self.generate_expression(start)?;
28680 first = false;
28681 }
28682 if let Some(increment) = &e.increment {
28683 if !first {
28684 self.write(" ");
28685 }
28686 self.write_keyword("INCREMENT BY ");
28687 self.generate_expression(increment)?;
28688 first = false;
28689 }
28690 if let Some(minvalue) = &e.minvalue {
28691 if !first {
28692 self.write(" ");
28693 }
28694 self.write_keyword("MINVALUE ");
28695 self.generate_expression(minvalue)?;
28696 first = false;
28697 }
28698 if let Some(maxvalue) = &e.maxvalue {
28699 if !first {
28700 self.write(" ");
28701 }
28702 self.write_keyword("MAXVALUE ");
28703 self.generate_expression(maxvalue)?;
28704 }
28705 self.write(")");
28706 }
28707 Ok(())
28708 }
28709
28710 fn generate_generated_as_row_column_constraint(
28711 &mut self,
28712 e: &GeneratedAsRowColumnConstraint,
28713 ) -> Result<()> {
28714 self.write_keyword("GENERATED ALWAYS AS ROW ");
28716 if e.start.is_some() {
28717 self.write_keyword("START");
28718 } else {
28719 self.write_keyword("END");
28720 }
28721 if e.hidden.is_some() {
28722 self.write_keyword(" HIDDEN");
28723 }
28724 Ok(())
28725 }
28726
28727 fn generate_get(&mut self, e: &Get) -> Result<()> {
28728 self.write_keyword("GET");
28730 self.write_space();
28731 self.generate_expression(&e.this)?;
28732 if let Some(target) = &e.target {
28733 self.write_space();
28734 self.generate_expression(target)?;
28735 }
28736 for prop in &e.properties {
28737 self.write_space();
28738 self.generate_expression(prop)?;
28739 }
28740 Ok(())
28741 }
28742
28743 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
28744 self.generate_expression(&e.this)?;
28746 self.write("[");
28747 self.generate_expression(&e.expression)?;
28748 self.write("]");
28749 Ok(())
28750 }
28751
28752 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
28753 self.write_keyword("GETBIT");
28755 self.write("(");
28756 self.generate_expression(&e.this)?;
28757 self.write(", ");
28758 self.generate_expression(&e.expression)?;
28759 self.write(")");
28760 Ok(())
28761 }
28762
28763 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
28764 if e.is_role {
28766 self.write_keyword("ROLE");
28767 self.write_space();
28768 } else if e.is_group {
28769 self.write_keyword("GROUP");
28770 self.write_space();
28771 } else if e.is_share {
28772 self.write_keyword("SHARE");
28773 self.write_space();
28774 }
28775 self.write(&e.name.name);
28776 Ok(())
28777 }
28778
28779 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
28780 self.generate_expression(&e.this)?;
28782 if !e.expressions.is_empty() {
28783 self.write("(");
28784 for (i, expr) in e.expressions.iter().enumerate() {
28785 if i > 0 {
28786 self.write(", ");
28787 }
28788 self.generate_expression(expr)?;
28789 }
28790 self.write(")");
28791 }
28792 Ok(())
28793 }
28794
28795 fn generate_group(&mut self, e: &Group) -> Result<()> {
28796 self.write_keyword("GROUP BY");
28798 match e.all {
28800 Some(true) => {
28801 self.write_space();
28802 self.write_keyword("ALL");
28803 }
28804 Some(false) => {
28805 self.write_space();
28806 self.write_keyword("DISTINCT");
28807 }
28808 None => {}
28809 }
28810 if !e.expressions.is_empty() {
28811 self.write_space();
28812 for (i, expr) in e.expressions.iter().enumerate() {
28813 if i > 0 {
28814 self.write(", ");
28815 }
28816 self.generate_expression(expr)?;
28817 }
28818 }
28819 if let Some(cube) = &e.cube {
28821 if !e.expressions.is_empty() {
28822 self.write(", ");
28823 } else {
28824 self.write_space();
28825 }
28826 self.generate_expression(cube)?;
28827 }
28828 if let Some(rollup) = &e.rollup {
28829 if !e.expressions.is_empty() || e.cube.is_some() {
28830 self.write(", ");
28831 } else {
28832 self.write_space();
28833 }
28834 self.generate_expression(rollup)?;
28835 }
28836 if let Some(grouping_sets) = &e.grouping_sets {
28837 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
28838 self.write(", ");
28839 } else {
28840 self.write_space();
28841 }
28842 self.generate_expression(grouping_sets)?;
28843 }
28844 if let Some(totals) = &e.totals {
28845 self.write_space();
28846 self.write_keyword("WITH TOTALS");
28847 self.generate_expression(totals)?;
28848 }
28849 Ok(())
28850 }
28851
28852 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
28853 self.write_keyword("GROUP BY");
28855 match e.all {
28857 Some(true) => {
28858 self.write_space();
28859 self.write_keyword("ALL");
28860 }
28861 Some(false) => {
28862 self.write_space();
28863 self.write_keyword("DISTINCT");
28864 }
28865 None => {}
28866 }
28867
28868 let mut trailing_cube = false;
28871 let mut trailing_rollup = false;
28872 let mut regular_expressions: Vec<&Expression> = Vec::new();
28873
28874 for expr in &e.expressions {
28875 match expr {
28876 Expression::Cube(c) if c.expressions.is_empty() => {
28877 trailing_cube = true;
28878 }
28879 Expression::Rollup(r) if r.expressions.is_empty() => {
28880 trailing_rollup = true;
28881 }
28882 _ => {
28883 regular_expressions.push(expr);
28884 }
28885 }
28886 }
28887
28888 if self.config.pretty {
28890 self.write_newline();
28891 self.indent_level += 1;
28892 for (i, expr) in regular_expressions.iter().enumerate() {
28893 if i > 0 {
28894 self.write(",");
28895 self.write_newline();
28896 }
28897 self.write_indent();
28898 self.generate_expression(expr)?;
28899 }
28900 self.indent_level -= 1;
28901 } else {
28902 self.write_space();
28903 for (i, expr) in regular_expressions.iter().enumerate() {
28904 if i > 0 {
28905 self.write(", ");
28906 }
28907 self.generate_expression(expr)?;
28908 }
28909 }
28910
28911 if trailing_cube {
28913 self.write_space();
28914 self.write_keyword("WITH CUBE");
28915 } else if trailing_rollup {
28916 self.write_space();
28917 self.write_keyword("WITH ROLLUP");
28918 }
28919
28920 if e.totals {
28922 self.write_space();
28923 self.write_keyword("WITH TOTALS");
28924 }
28925
28926 Ok(())
28927 }
28928
28929 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
28930 self.write_keyword("GROUPING");
28932 self.write("(");
28933 for (i, expr) in e.expressions.iter().enumerate() {
28934 if i > 0 {
28935 self.write(", ");
28936 }
28937 self.generate_expression(expr)?;
28938 }
28939 self.write(")");
28940 Ok(())
28941 }
28942
28943 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
28944 self.write_keyword("GROUPING_ID");
28946 self.write("(");
28947 for (i, expr) in e.expressions.iter().enumerate() {
28948 if i > 0 {
28949 self.write(", ");
28950 }
28951 self.generate_expression(expr)?;
28952 }
28953 self.write(")");
28954 Ok(())
28955 }
28956
28957 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
28958 self.write_keyword("GROUPING SETS");
28960 self.write(" (");
28961 for (i, expr) in e.expressions.iter().enumerate() {
28962 if i > 0 {
28963 self.write(", ");
28964 }
28965 self.generate_expression(expr)?;
28966 }
28967 self.write(")");
28968 Ok(())
28969 }
28970
28971 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
28972 self.write_keyword("HASH_AGG");
28974 self.write("(");
28975 self.generate_expression(&e.this)?;
28976 for expr in &e.expressions {
28977 self.write(", ");
28978 self.generate_expression(expr)?;
28979 }
28980 self.write(")");
28981 Ok(())
28982 }
28983
28984 fn generate_having(&mut self, e: &Having) -> Result<()> {
28985 self.write_keyword("HAVING");
28987 self.write_space();
28988 self.generate_expression(&e.this)?;
28989 Ok(())
28990 }
28991
28992 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
28993 self.generate_expression(&e.this)?;
28995 self.write_space();
28996 self.write_keyword("HAVING");
28997 self.write_space();
28998 if e.max.is_some() {
28999 self.write_keyword("MAX");
29000 } else {
29001 self.write_keyword("MIN");
29002 }
29003 self.write_space();
29004 self.generate_expression(&e.expression)?;
29005 Ok(())
29006 }
29007
29008 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
29009 use crate::dialects::DialectType;
29010 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
29012 if let Expression::Literal(ref lit) = *e.this {
29014 if let Literal::String(ref s) = lit.as_ref() {
29015 return self.generate_string_literal(s);
29016 }
29017 }
29018 }
29019 if matches!(
29021 self.config.dialect,
29022 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
29023 ) {
29024 self.write("$");
29025 if let Some(tag) = &e.tag {
29026 self.generate_expression(tag)?;
29027 }
29028 self.write("$");
29029 self.generate_expression(&e.this)?;
29030 self.write("$");
29031 if let Some(tag) = &e.tag {
29032 self.generate_expression(tag)?;
29033 }
29034 self.write("$");
29035 return Ok(());
29036 }
29037 self.write("$");
29039 if let Some(tag) = &e.tag {
29040 self.generate_expression(tag)?;
29041 }
29042 self.write("$");
29043 self.generate_expression(&e.this)?;
29044 self.write("$");
29045 if let Some(tag) = &e.tag {
29046 self.generate_expression(tag)?;
29047 }
29048 self.write("$");
29049 Ok(())
29050 }
29051
29052 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
29053 self.write_keyword("HEX_ENCODE");
29055 self.write("(");
29056 self.generate_expression(&e.this)?;
29057 self.write(")");
29058 Ok(())
29059 }
29060
29061 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
29062 match e.this.as_ref() {
29065 Expression::Identifier(id) => self.write(&id.name),
29066 other => self.generate_expression(other)?,
29067 }
29068 self.write(" (");
29069 self.write(&e.kind);
29070 self.write(" => ");
29071 self.generate_expression(&e.expression)?;
29072 self.write(")");
29073 Ok(())
29074 }
29075
29076 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
29077 self.write_keyword("HLL");
29079 self.write("(");
29080 self.generate_expression(&e.this)?;
29081 for expr in &e.expressions {
29082 self.write(", ");
29083 self.generate_expression(expr)?;
29084 }
29085 self.write(")");
29086 Ok(())
29087 }
29088
29089 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
29090 if e.input_.is_some() && e.output.is_some() {
29092 self.write_keyword("IN OUT");
29093 } else if e.input_.is_some() {
29094 self.write_keyword("IN");
29095 } else if e.output.is_some() {
29096 self.write_keyword("OUT");
29097 }
29098 Ok(())
29099 }
29100
29101 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
29102 self.write_keyword("INCLUDE");
29104 self.write_space();
29105 self.generate_expression(&e.this)?;
29106 if let Some(column_def) = &e.column_def {
29107 self.write_space();
29108 self.generate_expression(column_def)?;
29109 }
29110 if let Some(alias) = &e.alias {
29111 self.write_space();
29112 self.write_keyword("AS");
29113 self.write_space();
29114 self.write(alias);
29115 }
29116 Ok(())
29117 }
29118
29119 fn generate_index(&mut self, e: &Index) -> Result<()> {
29120 if e.unique {
29122 self.write_keyword("UNIQUE");
29123 self.write_space();
29124 }
29125 if e.primary.is_some() {
29126 self.write_keyword("PRIMARY");
29127 self.write_space();
29128 }
29129 if e.amp.is_some() {
29130 self.write_keyword("AMP");
29131 self.write_space();
29132 }
29133 if e.table.is_none() {
29134 self.write_keyword("INDEX");
29135 self.write_space();
29136 }
29137 if let Some(name) = &e.this {
29138 self.generate_expression(name)?;
29139 self.write_space();
29140 }
29141 if let Some(table) = &e.table {
29142 self.write_keyword("ON");
29143 self.write_space();
29144 self.generate_expression(table)?;
29145 }
29146 if !e.params.is_empty() {
29147 self.write("(");
29148 for (i, param) in e.params.iter().enumerate() {
29149 if i > 0 {
29150 self.write(", ");
29151 }
29152 self.generate_expression(param)?;
29153 }
29154 self.write(")");
29155 }
29156 Ok(())
29157 }
29158
29159 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
29160 if let Some(kind) = &e.kind {
29162 self.write(kind);
29163 self.write_space();
29164 }
29165 self.write_keyword("INDEX");
29166 if let Some(this) = &e.this {
29167 self.write_space();
29168 self.generate_expression(this)?;
29169 }
29170 if let Some(index_type) = &e.index_type {
29171 self.write_space();
29172 self.write_keyword("USING");
29173 self.write_space();
29174 self.generate_expression(index_type)?;
29175 }
29176 if !e.expressions.is_empty() {
29177 self.write(" (");
29178 for (i, expr) in e.expressions.iter().enumerate() {
29179 if i > 0 {
29180 self.write(", ");
29181 }
29182 self.generate_expression(expr)?;
29183 }
29184 self.write(")");
29185 }
29186 for opt in &e.options {
29187 self.write_space();
29188 self.generate_expression(opt)?;
29189 }
29190 Ok(())
29191 }
29192
29193 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
29194 if let Some(key_block_size) = &e.key_block_size {
29196 self.write_keyword("KEY_BLOCK_SIZE");
29197 self.write(" = ");
29198 self.generate_expression(key_block_size)?;
29199 } else if let Some(using) = &e.using {
29200 self.write_keyword("USING");
29201 self.write_space();
29202 self.generate_expression(using)?;
29203 } else if let Some(parser) = &e.parser {
29204 self.write_keyword("WITH PARSER");
29205 self.write_space();
29206 self.generate_expression(parser)?;
29207 } else if let Some(comment) = &e.comment {
29208 self.write_keyword("COMMENT");
29209 self.write_space();
29210 self.generate_expression(comment)?;
29211 } else if let Some(visible) = &e.visible {
29212 self.generate_expression(visible)?;
29213 } else if let Some(engine_attr) = &e.engine_attr {
29214 self.write_keyword("ENGINE_ATTRIBUTE");
29215 self.write(" = ");
29216 self.generate_expression(engine_attr)?;
29217 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
29218 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
29219 self.write(" = ");
29220 self.generate_expression(secondary_engine_attr)?;
29221 }
29222 Ok(())
29223 }
29224
29225 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
29226 if let Some(using) = &e.using {
29228 self.write_keyword("USING");
29229 self.write_space();
29230 self.generate_expression(using)?;
29231 }
29232 if !e.columns.is_empty() {
29233 self.write("(");
29234 for (i, col) in e.columns.iter().enumerate() {
29235 if i > 0 {
29236 self.write(", ");
29237 }
29238 self.generate_expression(col)?;
29239 }
29240 self.write(")");
29241 }
29242 if let Some(partition_by) = &e.partition_by {
29243 self.write_space();
29244 self.write_keyword("PARTITION BY");
29245 self.write_space();
29246 self.generate_expression(partition_by)?;
29247 }
29248 if let Some(where_) = &e.where_ {
29249 self.write_space();
29250 self.generate_expression(where_)?;
29251 }
29252 if let Some(include) = &e.include {
29253 self.write_space();
29254 self.write_keyword("INCLUDE");
29255 self.write(" (");
29256 self.generate_expression(include)?;
29257 self.write(")");
29258 }
29259 if let Some(with_storage) = &e.with_storage {
29260 self.write_space();
29261 self.write_keyword("WITH");
29262 self.write(" (");
29263 self.generate_expression(with_storage)?;
29264 self.write(")");
29265 }
29266 if let Some(tablespace) = &e.tablespace {
29267 self.write_space();
29268 self.write_keyword("USING INDEX TABLESPACE");
29269 self.write_space();
29270 self.generate_expression(tablespace)?;
29271 }
29272 Ok(())
29273 }
29274
29275 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
29276 if let Expression::Identifier(id) = &*e.this {
29280 self.write_keyword(&id.name);
29281 } else {
29282 self.generate_expression(&e.this)?;
29283 }
29284 self.write_space();
29285 self.write_keyword("INDEX");
29286 if let Some(target) = &e.target {
29287 self.write_space();
29288 self.write_keyword("FOR");
29289 self.write_space();
29290 if let Expression::Identifier(id) = &**target {
29291 self.write_keyword(&id.name);
29292 } else {
29293 self.generate_expression(target)?;
29294 }
29295 }
29296 self.write(" (");
29298 for (i, expr) in e.expressions.iter().enumerate() {
29299 if i > 0 {
29300 self.write(", ");
29301 }
29302 self.generate_expression(expr)?;
29303 }
29304 self.write(")");
29305 Ok(())
29306 }
29307
29308 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
29309 self.write_keyword("INHERITS");
29311 self.write(" (");
29312 for (i, expr) in e.expressions.iter().enumerate() {
29313 if i > 0 {
29314 self.write(", ");
29315 }
29316 self.generate_expression(expr)?;
29317 }
29318 self.write(")");
29319 Ok(())
29320 }
29321
29322 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
29323 self.write_keyword("INPUT");
29325 self.write("(");
29326 self.generate_expression(&e.this)?;
29327 self.write(")");
29328 Ok(())
29329 }
29330
29331 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
29332 if let Some(input_format) = &e.input_format {
29334 self.write_keyword("INPUTFORMAT");
29335 self.write_space();
29336 self.generate_expression(input_format)?;
29337 }
29338 if let Some(output_format) = &e.output_format {
29339 if e.input_format.is_some() {
29340 self.write(" ");
29341 }
29342 self.write_keyword("OUTPUTFORMAT");
29343 self.write_space();
29344 self.generate_expression(output_format)?;
29345 }
29346 Ok(())
29347 }
29348
29349 fn generate_install(&mut self, e: &Install) -> Result<()> {
29350 if e.force.is_some() {
29352 self.write_keyword("FORCE");
29353 self.write_space();
29354 }
29355 self.write_keyword("INSTALL");
29356 self.write_space();
29357 self.generate_expression(&e.this)?;
29358 if let Some(from) = &e.from_ {
29359 self.write_space();
29360 self.write_keyword("FROM");
29361 self.write_space();
29362 self.generate_expression(from)?;
29363 }
29364 Ok(())
29365 }
29366
29367 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
29368 self.write_keyword("INTERVAL");
29370 self.write_space();
29371 self.generate_expression(&e.expression)?;
29373 if let Some(unit) = &e.unit {
29374 self.write_space();
29375 self.write(unit);
29376 }
29377 Ok(())
29378 }
29379
29380 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
29381 self.write(&format!("{:?}", e.this).to_ascii_uppercase());
29383 self.write_space();
29384 self.write_keyword("TO");
29385 self.write_space();
29386 self.write(&format!("{:?}", e.expression).to_ascii_uppercase());
29387 Ok(())
29388 }
29389
29390 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
29391 self.write_keyword("INTO");
29393 if e.temporary {
29394 self.write_keyword(" TEMPORARY");
29395 }
29396 if e.unlogged.is_some() {
29397 self.write_keyword(" UNLOGGED");
29398 }
29399 if let Some(this) = &e.this {
29400 self.write_space();
29401 self.generate_expression(this)?;
29402 }
29403 if !e.expressions.is_empty() {
29404 self.write(" (");
29405 for (i, expr) in e.expressions.iter().enumerate() {
29406 if i > 0 {
29407 self.write(", ");
29408 }
29409 self.generate_expression(expr)?;
29410 }
29411 self.write(")");
29412 }
29413 Ok(())
29414 }
29415
29416 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
29417 self.generate_expression(&e.this)?;
29419 self.write_space();
29420 self.generate_expression(&e.expression)?;
29421 Ok(())
29422 }
29423
29424 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
29425 self.write_keyword("WITH");
29427 if e.no.is_some() {
29428 self.write_keyword(" NO");
29429 }
29430 if e.concurrent.is_some() {
29431 self.write_keyword(" CONCURRENT");
29432 }
29433 self.write_keyword(" ISOLATED LOADING");
29434 if let Some(target) = &e.target {
29435 self.write_space();
29436 self.generate_expression(target)?;
29437 }
29438 Ok(())
29439 }
29440
29441 fn generate_json(&mut self, e: &JSON) -> Result<()> {
29442 self.write_keyword("JSON");
29444 if let Some(this) = &e.this {
29445 self.write_space();
29446 self.generate_expression(this)?;
29447 }
29448 if let Some(with_) = &e.with_ {
29449 if let Expression::Boolean(b) = with_.as_ref() {
29451 if b.value {
29452 self.write_keyword(" WITH");
29453 } else {
29454 self.write_keyword(" WITHOUT");
29455 }
29456 }
29457 }
29458 if e.unique {
29459 self.write_keyword(" UNIQUE KEYS");
29460 }
29461 Ok(())
29462 }
29463
29464 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
29465 self.write_keyword("JSON_ARRAY");
29467 self.write("(");
29468 for (i, expr) in e.expressions.iter().enumerate() {
29469 if i > 0 {
29470 self.write(", ");
29471 }
29472 self.generate_expression(expr)?;
29473 }
29474 if let Some(null_handling) = &e.null_handling {
29475 self.write_space();
29476 self.generate_expression(null_handling)?;
29477 }
29478 if let Some(return_type) = &e.return_type {
29479 self.write_space();
29480 self.write_keyword("RETURNING");
29481 self.write_space();
29482 self.generate_expression(return_type)?;
29483 }
29484 if e.strict.is_some() {
29485 self.write_space();
29486 self.write_keyword("STRICT");
29487 }
29488 self.write(")");
29489 Ok(())
29490 }
29491
29492 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
29493 self.write_keyword("JSON_ARRAYAGG");
29495 self.write("(");
29496 self.generate_expression(&e.this)?;
29497 if let Some(order) = &e.order {
29498 self.write_space();
29499 if let Expression::OrderBy(ob) = order.as_ref() {
29501 self.write_keyword("ORDER BY");
29502 self.write_space();
29503 for (i, ord) in ob.expressions.iter().enumerate() {
29504 if i > 0 {
29505 self.write(", ");
29506 }
29507 self.generate_ordered(ord)?;
29508 }
29509 } else {
29510 self.generate_expression(order)?;
29512 }
29513 }
29514 if let Some(null_handling) = &e.null_handling {
29515 self.write_space();
29516 self.generate_expression(null_handling)?;
29517 }
29518 if let Some(return_type) = &e.return_type {
29519 self.write_space();
29520 self.write_keyword("RETURNING");
29521 self.write_space();
29522 self.generate_expression(return_type)?;
29523 }
29524 if e.strict.is_some() {
29525 self.write_space();
29526 self.write_keyword("STRICT");
29527 }
29528 self.write(")");
29529 Ok(())
29530 }
29531
29532 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
29533 self.write_keyword("JSON_OBJECTAGG");
29535 self.write("(");
29536 for (i, expr) in e.expressions.iter().enumerate() {
29537 if i > 0 {
29538 self.write(", ");
29539 }
29540 self.generate_expression(expr)?;
29541 }
29542 if let Some(null_handling) = &e.null_handling {
29543 self.write_space();
29544 self.generate_expression(null_handling)?;
29545 }
29546 if let Some(unique_keys) = &e.unique_keys {
29547 self.write_space();
29548 if let Expression::Boolean(b) = unique_keys.as_ref() {
29549 if b.value {
29550 self.write_keyword("WITH UNIQUE KEYS");
29551 } else {
29552 self.write_keyword("WITHOUT UNIQUE KEYS");
29553 }
29554 }
29555 }
29556 if let Some(return_type) = &e.return_type {
29557 self.write_space();
29558 self.write_keyword("RETURNING");
29559 self.write_space();
29560 self.generate_expression(return_type)?;
29561 }
29562 self.write(")");
29563 Ok(())
29564 }
29565
29566 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
29567 self.write_keyword("JSON_ARRAY_APPEND");
29569 self.write("(");
29570 self.generate_expression(&e.this)?;
29571 for expr in &e.expressions {
29572 self.write(", ");
29573 self.generate_expression(expr)?;
29574 }
29575 self.write(")");
29576 Ok(())
29577 }
29578
29579 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
29580 self.write_keyword("JSON_ARRAY_CONTAINS");
29582 self.write("(");
29583 self.generate_expression(&e.this)?;
29584 self.write(", ");
29585 self.generate_expression(&e.expression)?;
29586 self.write(")");
29587 Ok(())
29588 }
29589
29590 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
29591 self.write_keyword("JSON_ARRAY_INSERT");
29593 self.write("(");
29594 self.generate_expression(&e.this)?;
29595 for expr in &e.expressions {
29596 self.write(", ");
29597 self.generate_expression(expr)?;
29598 }
29599 self.write(")");
29600 Ok(())
29601 }
29602
29603 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
29604 self.write_keyword("JSONB_EXISTS");
29606 self.write("(");
29607 self.generate_expression(&e.this)?;
29608 if let Some(path) = &e.path {
29609 self.write(", ");
29610 self.generate_expression(path)?;
29611 }
29612 self.write(")");
29613 Ok(())
29614 }
29615
29616 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
29617 self.write_keyword("JSONB_EXTRACT_SCALAR");
29619 self.write("(");
29620 self.generate_expression(&e.this)?;
29621 self.write(", ");
29622 self.generate_expression(&e.expression)?;
29623 self.write(")");
29624 Ok(())
29625 }
29626
29627 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
29628 self.write_keyword("JSONB_OBJECT_AGG");
29630 self.write("(");
29631 self.generate_expression(&e.this)?;
29632 self.write(", ");
29633 self.generate_expression(&e.expression)?;
29634 self.write(")");
29635 Ok(())
29636 }
29637
29638 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
29639 if let Some(nested_schema) = &e.nested_schema {
29641 self.write_keyword("NESTED");
29642 if let Some(path) = &e.path {
29643 self.write_space();
29644 self.write_keyword("PATH");
29645 self.write_space();
29646 self.generate_expression(path)?;
29647 }
29648 self.write_space();
29649 self.generate_expression(nested_schema)?;
29650 } else {
29651 if let Some(this) = &e.this {
29652 self.generate_expression(this)?;
29653 }
29654 if let Some(kind) = &e.kind {
29655 self.write_space();
29656 self.write(kind);
29657 }
29658 if let Some(path) = &e.path {
29659 self.write_space();
29660 self.write_keyword("PATH");
29661 self.write_space();
29662 self.generate_expression(path)?;
29663 }
29664 if e.ordinality.is_some() {
29665 self.write_keyword(" FOR ORDINALITY");
29666 }
29667 }
29668 Ok(())
29669 }
29670
29671 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
29672 self.write_keyword("JSON_EXISTS");
29674 self.write("(");
29675 self.generate_expression(&e.this)?;
29676 if let Some(path) = &e.path {
29677 self.write(", ");
29678 self.generate_expression(path)?;
29679 }
29680 if let Some(passing) = &e.passing {
29681 self.write_space();
29682 self.write_keyword("PASSING");
29683 self.write_space();
29684 self.generate_expression(passing)?;
29685 }
29686 if let Some(on_condition) = &e.on_condition {
29687 self.write_space();
29688 self.generate_expression(on_condition)?;
29689 }
29690 self.write(")");
29691 Ok(())
29692 }
29693
29694 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
29695 self.generate_expression(&e.this)?;
29696 self.write(".:");
29697 if Self::data_type_has_nested_expressions(&e.to) {
29701 let saved = std::mem::take(&mut self.output);
29703 self.generate_data_type(&e.to)?;
29704 let type_sql = std::mem::replace(&mut self.output, saved);
29705 self.write("\"");
29706 self.write(&type_sql);
29707 self.write("\"");
29708 } else {
29709 self.generate_data_type(&e.to)?;
29710 }
29711 Ok(())
29712 }
29713
29714 fn data_type_has_nested_expressions(dt: &DataType) -> bool {
29717 matches!(
29718 dt,
29719 DataType::Array { .. } | DataType::Map { .. } | DataType::Struct { .. }
29720 )
29721 }
29722
29723 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
29724 self.write_keyword("JSON_EXTRACT_ARRAY");
29726 self.write("(");
29727 self.generate_expression(&e.this)?;
29728 if let Some(expr) = &e.expression {
29729 self.write(", ");
29730 self.generate_expression(expr)?;
29731 }
29732 self.write(")");
29733 Ok(())
29734 }
29735
29736 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
29737 if let Some(option) = &e.option {
29739 self.generate_expression(option)?;
29740 self.write_space();
29741 }
29742 self.write_keyword("QUOTES");
29743 if e.scalar.is_some() {
29744 self.write_keyword(" SCALAR_ONLY");
29745 }
29746 Ok(())
29747 }
29748
29749 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
29750 self.write_keyword("JSON_EXTRACT_SCALAR");
29752 self.write("(");
29753 self.generate_expression(&e.this)?;
29754 self.write(", ");
29755 self.generate_expression(&e.expression)?;
29756 self.write(")");
29757 Ok(())
29758 }
29759
29760 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
29761 if e.variant_extract.is_some() {
29765 use crate::dialects::DialectType;
29766 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
29767 self.generate_expression(&e.this)?;
29771 self.write(":");
29772 match e.expression.as_ref() {
29773 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
29774 let Literal::String(s) = lit.as_ref() else {
29775 unreachable!()
29776 };
29777 self.write_databricks_json_path(s);
29778 }
29779 _ => {
29780 self.generate_expression(&e.expression)?;
29782 }
29783 }
29784 } else {
29785 self.write_keyword("GET_PATH");
29787 self.write("(");
29788 self.generate_expression(&e.this)?;
29789 self.write(", ");
29790 self.generate_expression(&e.expression)?;
29791 self.write(")");
29792 }
29793 } else {
29794 self.write_keyword("JSON_EXTRACT");
29795 self.write("(");
29796 self.generate_expression(&e.this)?;
29797 self.write(", ");
29798 self.generate_expression(&e.expression)?;
29799 for expr in &e.expressions {
29800 self.write(", ");
29801 self.generate_expression(expr)?;
29802 }
29803 self.write(")");
29804 }
29805 Ok(())
29806 }
29807
29808 fn write_databricks_json_path(&mut self, path: &str) {
29812 if path.starts_with("[\"") || path.starts_with("['") {
29815 self.write(path);
29816 return;
29817 }
29818 let mut first = true;
29822 for segment in path.split('.') {
29823 if !first {
29824 self.write(".");
29825 }
29826 first = false;
29827 if let Some(bracket_pos) = segment.find('[') {
29829 let key = &segment[..bracket_pos];
29830 let subscript = &segment[bracket_pos..];
29831 if key.is_empty() {
29832 self.write(segment);
29834 } else if Self::is_safe_json_path_key(key) {
29835 self.write(key);
29836 self.write(subscript);
29837 } else {
29838 self.write("[\"");
29839 self.write(key);
29840 self.write("\"]");
29841 self.write(subscript);
29842 }
29843 } else if Self::is_safe_json_path_key(segment) {
29844 self.write(segment);
29845 } else {
29846 self.write("[\"");
29847 self.write(segment);
29848 self.write("\"]");
29849 }
29850 }
29851 }
29852
29853 fn is_safe_json_path_key(key: &str) -> bool {
29856 if key.is_empty() {
29857 return false;
29858 }
29859 let mut chars = key.chars();
29860 let first = chars.next().unwrap();
29861 if first != '_' && !first.is_ascii_alphabetic() {
29862 return false;
29863 }
29864 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
29865 }
29866
29867 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
29868 if let Some(this) = &e.this {
29871 self.generate_expression(this)?;
29872 self.write_space();
29873 }
29874 self.write_keyword("FORMAT JSON");
29875 Ok(())
29876 }
29877
29878 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
29879 self.generate_expression(&e.this)?;
29881 self.write(": ");
29882 self.generate_expression(&e.expression)?;
29883 Ok(())
29884 }
29885
29886 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
29887 self.write_keyword("JSON_KEYS");
29889 self.write("(");
29890 self.generate_expression(&e.this)?;
29891 if let Some(expr) = &e.expression {
29892 self.write(", ");
29893 self.generate_expression(expr)?;
29894 }
29895 for expr in &e.expressions {
29896 self.write(", ");
29897 self.generate_expression(expr)?;
29898 }
29899 self.write(")");
29900 Ok(())
29901 }
29902
29903 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
29904 self.write_keyword("JSON_KEYS");
29906 self.write("(");
29907 self.generate_expression(&e.this)?;
29908 if let Some(expr) = &e.expression {
29909 self.write(", ");
29910 self.generate_expression(expr)?;
29911 }
29912 self.write(")");
29913 Ok(())
29914 }
29915
29916 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
29917 let mut path_str = String::new();
29920 for expr in &e.expressions {
29921 match expr {
29922 Expression::JSONPathRoot(_) => {
29923 path_str.push('$');
29924 }
29925 Expression::JSONPathKey(k) => {
29926 if let Expression::Literal(lit) = k.this.as_ref() {
29928 if let crate::expressions::Literal::String(s) = lit.as_ref() {
29929 path_str.push('.');
29930 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
29932 if needs_quoting {
29933 path_str.push('"');
29934 path_str.push_str(s);
29935 path_str.push('"');
29936 } else {
29937 path_str.push_str(s);
29938 }
29939 }
29940 }
29941 }
29942 Expression::JSONPathSubscript(s) => {
29943 if let Expression::Literal(lit) = s.this.as_ref() {
29945 if let crate::expressions::Literal::Number(n) = lit.as_ref() {
29946 path_str.push('[');
29947 path_str.push_str(n);
29948 path_str.push(']');
29949 }
29950 }
29951 }
29952 _ => {
29953 let mut temp_gen = Self::with_arc_config(self.config.clone());
29955 temp_gen.generate_expression(expr)?;
29956 path_str.push_str(&temp_gen.output);
29957 }
29958 }
29959 }
29960 self.write("'");
29962 self.write(&path_str);
29963 self.write("'");
29964 Ok(())
29965 }
29966
29967 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
29968 self.write("?(");
29970 self.generate_expression(&e.this)?;
29971 self.write(")");
29972 Ok(())
29973 }
29974
29975 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
29976 self.write(".");
29978 self.generate_expression(&e.this)?;
29979 Ok(())
29980 }
29981
29982 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
29983 self.write("..");
29985 if let Some(this) = &e.this {
29986 self.generate_expression(this)?;
29987 }
29988 Ok(())
29989 }
29990
29991 fn generate_json_path_root(&mut self) -> Result<()> {
29992 self.write("$");
29994 Ok(())
29995 }
29996
29997 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
29998 self.write("(");
30000 self.generate_expression(&e.this)?;
30001 self.write(")");
30002 Ok(())
30003 }
30004
30005 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
30006 self.generate_expression(&e.this)?;
30008 Ok(())
30009 }
30010
30011 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
30012 self.write("[");
30014 if let Some(start) = &e.start {
30015 self.generate_expression(start)?;
30016 }
30017 self.write(":");
30018 if let Some(end) = &e.end {
30019 self.generate_expression(end)?;
30020 }
30021 if let Some(step) = &e.step {
30022 self.write(":");
30023 self.generate_expression(step)?;
30024 }
30025 self.write("]");
30026 Ok(())
30027 }
30028
30029 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
30030 self.write("[");
30032 self.generate_expression(&e.this)?;
30033 self.write("]");
30034 Ok(())
30035 }
30036
30037 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
30038 self.write("[");
30040 for (i, expr) in e.expressions.iter().enumerate() {
30041 if i > 0 {
30042 self.write(", ");
30043 }
30044 self.generate_expression(expr)?;
30045 }
30046 self.write("]");
30047 Ok(())
30048 }
30049
30050 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
30051 self.write_keyword("JSON_REMOVE");
30053 self.write("(");
30054 self.generate_expression(&e.this)?;
30055 for expr in &e.expressions {
30056 self.write(", ");
30057 self.generate_expression(expr)?;
30058 }
30059 self.write(")");
30060 Ok(())
30061 }
30062
30063 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
30064 self.write_keyword("COLUMNS");
30067 self.write("(");
30068
30069 if self.config.pretty && !e.expressions.is_empty() {
30070 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
30072 for expr in &e.expressions {
30073 let mut temp_gen = Generator::with_arc_config(self.config.clone());
30074 temp_gen.generate_expression(expr)?;
30075 expr_strings.push(temp_gen.output);
30076 }
30077
30078 if self.too_wide(&expr_strings) {
30080 self.write_newline();
30082 self.indent_level += 1;
30083 for (i, expr_str) in expr_strings.iter().enumerate() {
30084 if i > 0 {
30085 self.write(",");
30086 self.write_newline();
30087 }
30088 self.write_indent();
30089 self.write(expr_str);
30090 }
30091 self.write_newline();
30092 self.indent_level -= 1;
30093 self.write_indent();
30094 } else {
30095 for (i, expr_str) in expr_strings.iter().enumerate() {
30097 if i > 0 {
30098 self.write(", ");
30099 }
30100 self.write(expr_str);
30101 }
30102 }
30103 } else {
30104 for (i, expr) in e.expressions.iter().enumerate() {
30106 if i > 0 {
30107 self.write(", ");
30108 }
30109 self.generate_expression(expr)?;
30110 }
30111 }
30112 self.write(")");
30113 Ok(())
30114 }
30115
30116 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
30117 self.write_keyword("JSON_SET");
30119 self.write("(");
30120 self.generate_expression(&e.this)?;
30121 for expr in &e.expressions {
30122 self.write(", ");
30123 self.generate_expression(expr)?;
30124 }
30125 self.write(")");
30126 Ok(())
30127 }
30128
30129 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
30130 self.write_keyword("JSON_STRIP_NULLS");
30132 self.write("(");
30133 self.generate_expression(&e.this)?;
30134 if let Some(expr) = &e.expression {
30135 self.write(", ");
30136 self.generate_expression(expr)?;
30137 }
30138 self.write(")");
30139 Ok(())
30140 }
30141
30142 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
30143 self.write_keyword("JSON_TABLE");
30145 self.write("(");
30146 self.generate_expression(&e.this)?;
30147 if let Some(path) = &e.path {
30148 self.write(", ");
30149 self.generate_expression(path)?;
30150 }
30151 if let Some(error_handling) = &e.error_handling {
30152 self.write_space();
30153 self.generate_expression(error_handling)?;
30154 }
30155 if let Some(empty_handling) = &e.empty_handling {
30156 self.write_space();
30157 self.generate_expression(empty_handling)?;
30158 }
30159 if let Some(schema) = &e.schema {
30160 self.write_space();
30161 self.generate_expression(schema)?;
30162 }
30163 self.write(")");
30164 Ok(())
30165 }
30166
30167 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
30168 self.write_keyword("JSON_TYPE");
30170 self.write("(");
30171 self.generate_expression(&e.this)?;
30172 self.write(")");
30173 Ok(())
30174 }
30175
30176 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
30177 self.write_keyword("JSON_VALUE");
30179 self.write("(");
30180 self.generate_expression(&e.this)?;
30181 if let Some(path) = &e.path {
30182 self.write(", ");
30183 self.generate_expression(path)?;
30184 }
30185 if let Some(returning) = &e.returning {
30186 self.write_space();
30187 self.write_keyword("RETURNING");
30188 self.write_space();
30189 self.generate_expression(returning)?;
30190 }
30191 if let Some(on_condition) = &e.on_condition {
30192 self.write_space();
30193 self.generate_expression(on_condition)?;
30194 }
30195 self.write(")");
30196 Ok(())
30197 }
30198
30199 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
30200 self.write_keyword("JSON_VALUE_ARRAY");
30202 self.write("(");
30203 self.generate_expression(&e.this)?;
30204 self.write(")");
30205 Ok(())
30206 }
30207
30208 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
30209 self.write_keyword("JAROWINKLER_SIMILARITY");
30211 self.write("(");
30212 self.generate_expression(&e.this)?;
30213 self.write(", ");
30214 self.generate_expression(&e.expression)?;
30215 self.write(")");
30216 Ok(())
30217 }
30218
30219 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
30220 self.generate_expression(&e.this)?;
30222 self.write("(");
30223 for (i, expr) in e.expressions.iter().enumerate() {
30224 if i > 0 {
30225 self.write(", ");
30226 }
30227 self.generate_expression(expr)?;
30228 }
30229 self.write(")");
30230 Ok(())
30231 }
30232
30233 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
30234 if e.no.is_some() {
30236 self.write_keyword("NO ");
30237 }
30238 if let Some(local) = &e.local {
30239 self.generate_expression(local)?;
30240 self.write_space();
30241 }
30242 if e.dual.is_some() {
30243 self.write_keyword("DUAL ");
30244 }
30245 if e.before.is_some() {
30246 self.write_keyword("BEFORE ");
30247 }
30248 if e.after.is_some() {
30249 self.write_keyword("AFTER ");
30250 }
30251 self.write_keyword("JOURNAL");
30252 Ok(())
30253 }
30254
30255 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
30256 self.write_keyword("LANGUAGE");
30258 self.write_space();
30259 self.generate_expression(&e.this)?;
30260 Ok(())
30261 }
30262
30263 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
30264 if e.view.is_some() {
30266 self.write_keyword("LATERAL VIEW");
30268 if e.outer.is_some() {
30269 self.write_space();
30270 self.write_keyword("OUTER");
30271 }
30272 self.write_space();
30273 self.generate_expression(&e.this)?;
30274 if let Some(alias) = &e.alias {
30275 self.write_space();
30276 self.write(alias);
30277 }
30278 } else {
30279 self.write_keyword("LATERAL");
30281 self.write_space();
30282 self.generate_expression(&e.this)?;
30283 if e.ordinality.is_some() {
30284 self.write_space();
30285 self.write_keyword("WITH ORDINALITY");
30286 }
30287 if let Some(alias) = &e.alias {
30288 self.write_space();
30289 self.write_keyword("AS");
30290 self.write_space();
30291 self.write(alias);
30292 if !e.column_aliases.is_empty() {
30293 self.write("(");
30294 for (i, col) in e.column_aliases.iter().enumerate() {
30295 if i > 0 {
30296 self.write(", ");
30297 }
30298 self.write(col);
30299 }
30300 self.write(")");
30301 }
30302 }
30303 }
30304 Ok(())
30305 }
30306
30307 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
30308 self.write_keyword("LIKE");
30310 self.write_space();
30311 self.generate_expression(&e.this)?;
30312 for expr in &e.expressions {
30313 self.write_space();
30314 self.generate_expression(expr)?;
30315 }
30316 Ok(())
30317 }
30318
30319 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
30320 self.write_keyword("LIMIT");
30321 self.write_space();
30322 self.write_limit_expr(&e.this)?;
30323 if e.percent {
30324 self.write_space();
30325 self.write_keyword("PERCENT");
30326 }
30327 for comment in &e.comments {
30329 self.write(" ");
30330 self.write_formatted_comment(comment);
30331 }
30332 Ok(())
30333 }
30334
30335 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
30336 if e.percent.is_some() {
30338 self.write_keyword(" PERCENT");
30339 }
30340 if e.rows.is_some() {
30341 self.write_keyword(" ROWS");
30342 }
30343 if e.with_ties.is_some() {
30344 self.write_keyword(" WITH TIES");
30345 } else if e.rows.is_some() {
30346 self.write_keyword(" ONLY");
30347 }
30348 Ok(())
30349 }
30350
30351 fn generate_list(&mut self, e: &List) -> Result<()> {
30352 use crate::dialects::DialectType;
30353 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
30354
30355 if e.expressions.len() == 1 {
30357 if let Expression::Select(_) = &e.expressions[0] {
30358 self.write_keyword("LIST");
30359 self.write("(");
30360 self.generate_expression(&e.expressions[0])?;
30361 self.write(")");
30362 return Ok(());
30363 }
30364 }
30365
30366 if is_materialize {
30368 self.write_keyword("LIST");
30369 self.write("[");
30370 for (i, expr) in e.expressions.iter().enumerate() {
30371 if i > 0 {
30372 self.write(", ");
30373 }
30374 self.generate_expression(expr)?;
30375 }
30376 self.write("]");
30377 } else {
30378 self.write_keyword("LIST");
30380 self.write("(");
30381 for (i, expr) in e.expressions.iter().enumerate() {
30382 if i > 0 {
30383 self.write(", ");
30384 }
30385 self.generate_expression(expr)?;
30386 }
30387 self.write(")");
30388 }
30389 Ok(())
30390 }
30391
30392 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
30393 if let Expression::Select(_) = &*e.this {
30395 self.write_keyword("MAP");
30396 self.write("(");
30397 self.generate_expression(&e.this)?;
30398 self.write(")");
30399 return Ok(());
30400 }
30401
30402 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
30403
30404 self.write_keyword("MAP");
30406 if is_duckdb {
30407 self.write(" {");
30408 } else {
30409 self.write("[");
30410 }
30411 if let Expression::Struct(s) = &*e.this {
30412 for (i, (_, expr)) in s.fields.iter().enumerate() {
30413 if i > 0 {
30414 self.write(", ");
30415 }
30416 if let Expression::PropertyEQ(op) = expr {
30417 self.generate_expression(&op.left)?;
30418 if is_duckdb {
30419 self.write(": ");
30420 } else {
30421 self.write(" => ");
30422 }
30423 self.generate_expression(&op.right)?;
30424 } else {
30425 self.generate_expression(expr)?;
30426 }
30427 }
30428 }
30429 if is_duckdb {
30430 self.write("}");
30431 } else {
30432 self.write("]");
30433 }
30434 Ok(())
30435 }
30436
30437 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
30438 self.write_keyword("LOCALTIME");
30440 if let Some(precision) = &e.this {
30441 self.write("(");
30442 self.generate_expression(precision)?;
30443 self.write(")");
30444 }
30445 Ok(())
30446 }
30447
30448 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
30449 self.write_keyword("LOCALTIMESTAMP");
30451 if let Some(precision) = &e.this {
30452 self.write("(");
30453 self.generate_expression(precision)?;
30454 self.write(")");
30455 }
30456 Ok(())
30457 }
30458
30459 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
30460 self.write_keyword("LOCATION");
30462 self.write_space();
30463 self.generate_expression(&e.this)?;
30464 Ok(())
30465 }
30466
30467 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
30468 if e.update.is_some() {
30470 if e.key.is_some() {
30471 self.write_keyword("FOR NO KEY UPDATE");
30472 } else {
30473 self.write_keyword("FOR UPDATE");
30474 }
30475 } else {
30476 if e.key.is_some() {
30477 self.write_keyword("FOR KEY SHARE");
30478 } else {
30479 self.write_keyword("FOR SHARE");
30480 }
30481 }
30482 if !e.expressions.is_empty() {
30483 self.write_keyword(" OF ");
30484 for (i, expr) in e.expressions.iter().enumerate() {
30485 if i > 0 {
30486 self.write(", ");
30487 }
30488 self.generate_expression(expr)?;
30489 }
30490 }
30491 if let Some(wait) = &e.wait {
30496 match wait.as_ref() {
30497 Expression::Boolean(b) => {
30498 if b.value {
30499 self.write_keyword(" NOWAIT");
30500 } else {
30501 self.write_keyword(" SKIP LOCKED");
30502 }
30503 }
30504 _ => {
30505 self.write_keyword(" WAIT ");
30507 self.generate_expression(wait)?;
30508 }
30509 }
30510 }
30511 Ok(())
30512 }
30513
30514 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
30515 self.write_keyword("LOCK");
30517 self.write_space();
30518 self.generate_expression(&e.this)?;
30519 Ok(())
30520 }
30521
30522 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
30523 self.write_keyword("LOCKING");
30525 self.write_space();
30526 self.write(&e.kind);
30527 if let Some(this) = &e.this {
30528 self.write_space();
30529 self.generate_expression(this)?;
30530 }
30531 if let Some(for_or_in) = &e.for_or_in {
30532 self.write_space();
30533 self.generate_expression(for_or_in)?;
30534 }
30535 if let Some(lock_type) = &e.lock_type {
30536 self.write_space();
30537 self.generate_expression(lock_type)?;
30538 }
30539 if e.override_.is_some() {
30540 self.write_keyword(" OVERRIDE");
30541 }
30542 Ok(())
30543 }
30544
30545 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
30546 self.generate_expression(&e.this)?;
30548 self.write_space();
30549 self.generate_expression(&e.expression)?;
30550 Ok(())
30551 }
30552
30553 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
30554 if e.no.is_some() {
30556 self.write_keyword("NO ");
30557 }
30558 self.write_keyword("LOG");
30559 Ok(())
30560 }
30561
30562 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
30563 self.write_keyword("MD5");
30565 self.write("(");
30566 self.generate_expression(&e.this)?;
30567 for expr in &e.expressions {
30568 self.write(", ");
30569 self.generate_expression(expr)?;
30570 }
30571 self.write(")");
30572 Ok(())
30573 }
30574
30575 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
30576 self.write_keyword("ML.FORECAST");
30578 self.write("(");
30579 self.generate_expression(&e.this)?;
30580 if let Some(expression) = &e.expression {
30581 self.write(", ");
30582 self.generate_expression(expression)?;
30583 }
30584 if let Some(params) = &e.params_struct {
30585 self.write(", ");
30586 self.generate_expression(params)?;
30587 }
30588 self.write(")");
30589 Ok(())
30590 }
30591
30592 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
30593 self.write_keyword("ML.TRANSLATE");
30595 self.write("(");
30596 self.generate_expression(&e.this)?;
30597 self.write(", ");
30598 self.generate_expression(&e.expression)?;
30599 if let Some(params) = &e.params_struct {
30600 self.write(", ");
30601 self.generate_expression(params)?;
30602 }
30603 self.write(")");
30604 Ok(())
30605 }
30606
30607 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
30608 self.write_keyword("MAKE_INTERVAL");
30610 self.write("(");
30611 let mut first = true;
30612 if let Some(year) = &e.year {
30613 self.write("years => ");
30614 self.generate_expression(year)?;
30615 first = false;
30616 }
30617 if let Some(month) = &e.month {
30618 if !first {
30619 self.write(", ");
30620 }
30621 self.write("months => ");
30622 self.generate_expression(month)?;
30623 first = false;
30624 }
30625 if let Some(week) = &e.week {
30626 if !first {
30627 self.write(", ");
30628 }
30629 self.write("weeks => ");
30630 self.generate_expression(week)?;
30631 first = false;
30632 }
30633 if let Some(day) = &e.day {
30634 if !first {
30635 self.write(", ");
30636 }
30637 self.write("days => ");
30638 self.generate_expression(day)?;
30639 first = false;
30640 }
30641 if let Some(hour) = &e.hour {
30642 if !first {
30643 self.write(", ");
30644 }
30645 self.write("hours => ");
30646 self.generate_expression(hour)?;
30647 first = false;
30648 }
30649 if let Some(minute) = &e.minute {
30650 if !first {
30651 self.write(", ");
30652 }
30653 self.write("mins => ");
30654 self.generate_expression(minute)?;
30655 first = false;
30656 }
30657 if let Some(second) = &e.second {
30658 if !first {
30659 self.write(", ");
30660 }
30661 self.write("secs => ");
30662 self.generate_expression(second)?;
30663 }
30664 self.write(")");
30665 Ok(())
30666 }
30667
30668 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
30669 self.write_keyword("MANHATTAN_DISTANCE");
30671 self.write("(");
30672 self.generate_expression(&e.this)?;
30673 self.write(", ");
30674 self.generate_expression(&e.expression)?;
30675 self.write(")");
30676 Ok(())
30677 }
30678
30679 fn generate_map(&mut self, e: &Map) -> Result<()> {
30680 self.write_keyword("MAP");
30682 self.write("(");
30683 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
30684 if i > 0 {
30685 self.write(", ");
30686 }
30687 self.generate_expression(key)?;
30688 self.write(", ");
30689 self.generate_expression(value)?;
30690 }
30691 self.write(")");
30692 Ok(())
30693 }
30694
30695 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
30696 self.write_keyword("MAP_CAT");
30698 self.write("(");
30699 self.generate_expression(&e.this)?;
30700 self.write(", ");
30701 self.generate_expression(&e.expression)?;
30702 self.write(")");
30703 Ok(())
30704 }
30705
30706 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
30707 self.write_keyword("MAP_DELETE");
30709 self.write("(");
30710 self.generate_expression(&e.this)?;
30711 for expr in &e.expressions {
30712 self.write(", ");
30713 self.generate_expression(expr)?;
30714 }
30715 self.write(")");
30716 Ok(())
30717 }
30718
30719 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
30720 self.write_keyword("MAP_INSERT");
30722 self.write("(");
30723 self.generate_expression(&e.this)?;
30724 if let Some(key) = &e.key {
30725 self.write(", ");
30726 self.generate_expression(key)?;
30727 }
30728 if let Some(value) = &e.value {
30729 self.write(", ");
30730 self.generate_expression(value)?;
30731 }
30732 if let Some(update_flag) = &e.update_flag {
30733 self.write(", ");
30734 self.generate_expression(update_flag)?;
30735 }
30736 self.write(")");
30737 Ok(())
30738 }
30739
30740 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
30741 self.write_keyword("MAP_PICK");
30743 self.write("(");
30744 self.generate_expression(&e.this)?;
30745 for expr in &e.expressions {
30746 self.write(", ");
30747 self.generate_expression(expr)?;
30748 }
30749 self.write(")");
30750 Ok(())
30751 }
30752
30753 fn generate_masking_policy_column_constraint(
30754 &mut self,
30755 e: &MaskingPolicyColumnConstraint,
30756 ) -> Result<()> {
30757 self.write_keyword("MASKING POLICY");
30759 self.write_space();
30760 self.generate_expression(&e.this)?;
30761 if !e.expressions.is_empty() {
30762 self.write_keyword(" USING");
30763 self.write(" (");
30764 for (i, expr) in e.expressions.iter().enumerate() {
30765 if i > 0 {
30766 self.write(", ");
30767 }
30768 self.generate_expression(expr)?;
30769 }
30770 self.write(")");
30771 }
30772 Ok(())
30773 }
30774
30775 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
30776 if matches!(
30777 self.config.dialect,
30778 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
30779 ) {
30780 if e.expressions.len() > 1 {
30781 self.write("(");
30782 }
30783 for (i, expr) in e.expressions.iter().enumerate() {
30784 if i > 0 {
30785 self.write_keyword(" OR ");
30786 }
30787 self.generate_expression(expr)?;
30788 self.write_space();
30789 self.write("@@");
30790 self.write_space();
30791 self.generate_expression(&e.this)?;
30792 }
30793 if e.expressions.len() > 1 {
30794 self.write(")");
30795 }
30796 return Ok(());
30797 }
30798
30799 self.write_keyword("MATCH");
30801 self.write("(");
30802 for (i, expr) in e.expressions.iter().enumerate() {
30803 if i > 0 {
30804 self.write(", ");
30805 }
30806 self.generate_expression(expr)?;
30807 }
30808 self.write(")");
30809 self.write_keyword(" AGAINST");
30810 self.write("(");
30811 self.generate_expression(&e.this)?;
30812 if let Some(modifier) = &e.modifier {
30813 self.write_space();
30814 self.generate_expression(modifier)?;
30815 }
30816 self.write(")");
30817 Ok(())
30818 }
30819
30820 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
30821 if let Some(window_frame) = &e.window_frame {
30823 self.write(&format!("{:?}", window_frame).to_ascii_uppercase());
30824 self.write_space();
30825 }
30826 self.generate_expression(&e.this)?;
30827 Ok(())
30828 }
30829
30830 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
30831 self.write_keyword("MATERIALIZED");
30833 if let Some(this) = &e.this {
30834 self.write_space();
30835 self.generate_expression(this)?;
30836 }
30837 Ok(())
30838 }
30839
30840 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
30841 if let Some(with_) = &e.with_ {
30844 self.generate_expression(with_)?;
30845 self.write_space();
30846 }
30847 self.write_keyword("MERGE INTO");
30848 self.write_space();
30849 self.generate_expression(&e.this)?;
30850
30851 if self.config.pretty {
30853 self.write_newline();
30854 self.write_indent();
30855 } else {
30856 self.write_space();
30857 }
30858 self.write_keyword("USING");
30859 self.write_space();
30860 self.generate_expression(&e.using)?;
30861
30862 if let Some(on) = &e.on {
30864 if self.config.pretty {
30865 self.write_newline();
30866 self.write_indent();
30867 } else {
30868 self.write_space();
30869 }
30870 self.write_keyword("ON");
30871 self.write_space();
30872 self.generate_expression(on)?;
30873 }
30874 if let Some(using_cond) = &e.using_cond {
30876 self.write_space();
30877 self.write_keyword("USING");
30878 self.write_space();
30879 self.write("(");
30880 if let Expression::Tuple(tuple) = using_cond.as_ref() {
30882 for (i, col) in tuple.expressions.iter().enumerate() {
30883 if i > 0 {
30884 self.write(", ");
30885 }
30886 self.generate_expression(col)?;
30887 }
30888 } else {
30889 self.generate_expression(using_cond)?;
30890 }
30891 self.write(")");
30892 }
30893 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
30895 if matches!(
30896 self.config.dialect,
30897 Some(crate::DialectType::PostgreSQL)
30898 | Some(crate::DialectType::Redshift)
30899 | Some(crate::DialectType::Trino)
30900 | Some(crate::DialectType::Presto)
30901 | Some(crate::DialectType::Athena)
30902 ) {
30903 let mut names = Vec::new();
30904 match e.this.as_ref() {
30905 Expression::Alias(a) => {
30906 if let Expression::Table(t) = &a.this {
30908 names.push(t.name.name.clone());
30909 } else if let Expression::Identifier(id) = &a.this {
30910 names.push(id.name.clone());
30911 }
30912 names.push(a.alias.name.clone());
30913 }
30914 Expression::Table(t) => {
30915 names.push(t.name.name.clone());
30916 }
30917 Expression::Identifier(id) => {
30918 names.push(id.name.clone());
30919 }
30920 _ => {}
30921 }
30922 self.merge_strip_qualifiers = names;
30923 }
30924
30925 if let Some(whens) = &e.whens {
30927 if self.config.pretty {
30928 self.write_newline();
30929 self.write_indent();
30930 } else {
30931 self.write_space();
30932 }
30933 self.generate_expression(whens)?;
30934 }
30935
30936 self.merge_strip_qualifiers = saved_merge_strip;
30938
30939 if let Some(returning) = &e.returning {
30941 if self.config.pretty {
30942 self.write_newline();
30943 self.write_indent();
30944 } else {
30945 self.write_space();
30946 }
30947 self.generate_expression(returning)?;
30948 }
30949 Ok(())
30950 }
30951
30952 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
30953 if e.no.is_some() {
30955 self.write_keyword("NO MERGEBLOCKRATIO");
30956 } else if e.default.is_some() {
30957 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
30958 } else {
30959 self.write_keyword("MERGEBLOCKRATIO");
30960 self.write("=");
30961 if let Some(this) = &e.this {
30962 self.generate_expression(this)?;
30963 }
30964 if e.percent.is_some() {
30965 self.write_keyword(" PERCENT");
30966 }
30967 }
30968 Ok(())
30969 }
30970
30971 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
30972 self.write_keyword("TTL");
30974 let pretty_clickhouse = self.config.pretty
30975 && matches!(
30976 self.config.dialect,
30977 Some(crate::dialects::DialectType::ClickHouse)
30978 );
30979
30980 if pretty_clickhouse {
30981 self.write_newline();
30982 self.indent_level += 1;
30983 for (i, expr) in e.expressions.iter().enumerate() {
30984 if i > 0 {
30985 self.write(",");
30986 self.write_newline();
30987 }
30988 self.write_indent();
30989 self.generate_expression(expr)?;
30990 }
30991 self.indent_level -= 1;
30992 } else {
30993 self.write_space();
30994 for (i, expr) in e.expressions.iter().enumerate() {
30995 if i > 0 {
30996 self.write(", ");
30997 }
30998 self.generate_expression(expr)?;
30999 }
31000 }
31001
31002 if let Some(where_) = &e.where_ {
31003 if pretty_clickhouse {
31004 self.write_newline();
31005 if let Expression::Where(w) = where_.as_ref() {
31006 self.write_indent();
31007 self.write_keyword("WHERE");
31008 self.write_newline();
31009 self.indent_level += 1;
31010 self.write_indent();
31011 self.generate_expression(&w.this)?;
31012 self.indent_level -= 1;
31013 } else {
31014 self.write_indent();
31015 self.generate_expression(where_)?;
31016 }
31017 } else {
31018 self.write_space();
31019 self.generate_expression(where_)?;
31020 }
31021 }
31022 if let Some(group) = &e.group {
31023 if pretty_clickhouse {
31024 self.write_newline();
31025 if let Expression::Group(g) = group.as_ref() {
31026 self.write_indent();
31027 self.write_keyword("GROUP BY");
31028 self.write_newline();
31029 self.indent_level += 1;
31030 for (i, expr) in g.expressions.iter().enumerate() {
31031 if i > 0 {
31032 self.write(",");
31033 self.write_newline();
31034 }
31035 self.write_indent();
31036 self.generate_expression(expr)?;
31037 }
31038 self.indent_level -= 1;
31039 } else {
31040 self.write_indent();
31041 self.generate_expression(group)?;
31042 }
31043 } else {
31044 self.write_space();
31045 self.generate_expression(group)?;
31046 }
31047 }
31048 if let Some(aggregates) = &e.aggregates {
31049 if pretty_clickhouse {
31050 self.write_newline();
31051 self.write_indent();
31052 self.write_keyword("SET");
31053 self.write_newline();
31054 self.indent_level += 1;
31055 if let Expression::Tuple(t) = aggregates.as_ref() {
31056 for (i, agg) in t.expressions.iter().enumerate() {
31057 if i > 0 {
31058 self.write(",");
31059 self.write_newline();
31060 }
31061 self.write_indent();
31062 self.generate_expression(agg)?;
31063 }
31064 } else {
31065 self.write_indent();
31066 self.generate_expression(aggregates)?;
31067 }
31068 self.indent_level -= 1;
31069 } else {
31070 self.write_space();
31071 self.write_keyword("SET");
31072 self.write_space();
31073 self.generate_expression(aggregates)?;
31074 }
31075 }
31076 Ok(())
31077 }
31078
31079 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
31080 self.generate_expression(&e.this)?;
31082 if e.delete.is_some() {
31083 self.write_keyword(" DELETE");
31084 }
31085 if let Some(recompress) = &e.recompress {
31086 self.write_keyword(" RECOMPRESS ");
31087 self.generate_expression(recompress)?;
31088 }
31089 if let Some(to_disk) = &e.to_disk {
31090 self.write_keyword(" TO DISK ");
31091 self.generate_expression(to_disk)?;
31092 }
31093 if let Some(to_volume) = &e.to_volume {
31094 self.write_keyword(" TO VOLUME ");
31095 self.generate_expression(to_volume)?;
31096 }
31097 Ok(())
31098 }
31099
31100 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
31101 self.write_keyword("MINHASH");
31103 self.write("(");
31104 self.generate_expression(&e.this)?;
31105 for expr in &e.expressions {
31106 self.write(", ");
31107 self.generate_expression(expr)?;
31108 }
31109 self.write(")");
31110 Ok(())
31111 }
31112
31113 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
31114 self.generate_expression(&e.this)?;
31116 self.write("!");
31117 self.generate_expression(&e.expression)?;
31118 Ok(())
31119 }
31120
31121 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
31122 self.write_keyword("MONTHNAME");
31124 self.write("(");
31125 self.generate_expression(&e.this)?;
31126 self.write(")");
31127 Ok(())
31128 }
31129
31130 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
31131 for comment in &e.leading_comments {
31133 self.write_formatted_comment(comment);
31134 if self.config.pretty {
31135 self.write_newline();
31136 self.write_indent();
31137 } else {
31138 self.write_space();
31139 }
31140 }
31141 self.write_keyword("INSERT");
31143 self.write_space();
31144 self.write(&e.kind);
31145 if self.config.pretty {
31146 self.indent_level += 1;
31147 for expr in &e.expressions {
31148 self.write_newline();
31149 self.write_indent();
31150 self.generate_expression(expr)?;
31151 }
31152 self.indent_level -= 1;
31153 } else {
31154 for expr in &e.expressions {
31155 self.write_space();
31156 self.generate_expression(expr)?;
31157 }
31158 }
31159 if let Some(source) = &e.source {
31160 if self.config.pretty {
31161 self.write_newline();
31162 self.write_indent();
31163 } else {
31164 self.write_space();
31165 }
31166 self.generate_expression(source)?;
31167 }
31168 Ok(())
31169 }
31170
31171 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
31172 self.write_keyword("NEXT VALUE FOR");
31174 self.write_space();
31175 self.generate_expression(&e.this)?;
31176 if let Some(order) = &e.order {
31177 self.write_space();
31178 self.write_keyword("OVER");
31179 self.write(" (");
31180 self.generate_expression(order)?;
31181 self.write(")");
31182 }
31183 Ok(())
31184 }
31185
31186 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
31187 self.write_keyword("NORMAL");
31189 self.write("(");
31190 self.generate_expression(&e.this)?;
31191 if let Some(stddev) = &e.stddev {
31192 self.write(", ");
31193 self.generate_expression(stddev)?;
31194 }
31195 if let Some(gen) = &e.gen {
31196 self.write(", ");
31197 self.generate_expression(gen)?;
31198 }
31199 self.write(")");
31200 Ok(())
31201 }
31202
31203 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
31204 if e.is_casefold.is_some() {
31206 self.write_keyword("NORMALIZE_AND_CASEFOLD");
31207 } else {
31208 self.write_keyword("NORMALIZE");
31209 }
31210 self.write("(");
31211 self.generate_expression(&e.this)?;
31212 if let Some(form) = &e.form {
31213 self.write(", ");
31214 self.generate_expression(form)?;
31215 }
31216 self.write(")");
31217 Ok(())
31218 }
31219
31220 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
31221 if e.allow_null.is_none() {
31223 self.write_keyword("NOT ");
31224 }
31225 self.write_keyword("NULL");
31226 Ok(())
31227 }
31228
31229 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
31230 self.write_keyword("NULLIF");
31232 self.write("(");
31233 self.generate_expression(&e.this)?;
31234 self.write(", ");
31235 self.generate_expression(&e.expression)?;
31236 self.write(")");
31237 Ok(())
31238 }
31239
31240 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
31241 self.write_keyword("FORMAT");
31243 self.write("(");
31244 self.generate_expression(&e.this)?;
31245 self.write(", '");
31246 self.write(&e.format);
31247 self.write("'");
31248 if let Some(culture) = &e.culture {
31249 self.write(", ");
31250 self.generate_expression(culture)?;
31251 }
31252 self.write(")");
31253 Ok(())
31254 }
31255
31256 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
31257 self.write_keyword("OBJECT_AGG");
31259 self.write("(");
31260 self.generate_expression(&e.this)?;
31261 self.write(", ");
31262 self.generate_expression(&e.expression)?;
31263 self.write(")");
31264 Ok(())
31265 }
31266
31267 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
31268 self.generate_expression(&e.this)?;
31270 Ok(())
31271 }
31272
31273 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
31274 self.write_keyword("OBJECT_INSERT");
31276 self.write("(");
31277 self.generate_expression(&e.this)?;
31278 if let Some(key) = &e.key {
31279 self.write(", ");
31280 self.generate_expression(key)?;
31281 }
31282 if let Some(value) = &e.value {
31283 self.write(", ");
31284 self.generate_expression(value)?;
31285 }
31286 if let Some(update_flag) = &e.update_flag {
31287 self.write(", ");
31288 self.generate_expression(update_flag)?;
31289 }
31290 self.write(")");
31291 Ok(())
31292 }
31293
31294 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
31295 self.write_keyword("OFFSET");
31297 self.write_space();
31298 self.generate_expression(&e.this)?;
31299 if e.rows == Some(true)
31301 && matches!(
31302 self.config.dialect,
31303 Some(crate::dialects::DialectType::TSQL)
31304 | Some(crate::dialects::DialectType::Oracle)
31305 )
31306 {
31307 self.write_space();
31308 self.write_keyword("ROWS");
31309 }
31310 Ok(())
31311 }
31312
31313 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
31314 self.write_keyword("QUALIFY");
31316 self.write_space();
31317 self.generate_expression(&e.this)?;
31318 Ok(())
31319 }
31320
31321 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
31322 self.write_keyword("ON CLUSTER");
31324 self.write_space();
31325 self.generate_expression(&e.this)?;
31326 Ok(())
31327 }
31328
31329 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
31330 self.write_keyword("ON COMMIT");
31332 if e.delete.is_some() {
31333 self.write_keyword(" DELETE ROWS");
31334 } else {
31335 self.write_keyword(" PRESERVE ROWS");
31336 }
31337 Ok(())
31338 }
31339
31340 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
31341 if let Some(empty) = &e.empty {
31343 self.generate_expression(empty)?;
31344 self.write_keyword(" ON EMPTY");
31345 }
31346 if let Some(error) = &e.error {
31347 if e.empty.is_some() {
31348 self.write_space();
31349 }
31350 self.generate_expression(error)?;
31351 self.write_keyword(" ON ERROR");
31352 }
31353 if let Some(null) = &e.null {
31354 if e.empty.is_some() || e.error.is_some() {
31355 self.write_space();
31356 }
31357 self.generate_expression(null)?;
31358 self.write_keyword(" ON NULL");
31359 }
31360 Ok(())
31361 }
31362
31363 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
31364 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
31366 return Ok(());
31367 }
31368 if e.duplicate.is_some() {
31370 self.write_keyword("ON DUPLICATE KEY UPDATE");
31372 for (i, expr) in e.expressions.iter().enumerate() {
31373 if i > 0 {
31374 self.write(",");
31375 }
31376 self.write_space();
31377 self.generate_expression(expr)?;
31378 }
31379 return Ok(());
31380 } else {
31381 self.write_keyword("ON CONFLICT");
31382 }
31383 if let Some(constraint) = &e.constraint {
31384 self.write_keyword(" ON CONSTRAINT ");
31385 self.generate_expression(constraint)?;
31386 }
31387 if let Some(conflict_keys) = &e.conflict_keys {
31388 if let Expression::Tuple(t) = conflict_keys.as_ref() {
31390 self.write("(");
31391 for (i, expr) in t.expressions.iter().enumerate() {
31392 if i > 0 {
31393 self.write(", ");
31394 }
31395 self.generate_expression(expr)?;
31396 }
31397 self.write(")");
31398 } else {
31399 self.write("(");
31400 self.generate_expression(conflict_keys)?;
31401 self.write(")");
31402 }
31403 }
31404 if let Some(index_predicate) = &e.index_predicate {
31405 self.write_keyword(" WHERE ");
31406 self.generate_expression(index_predicate)?;
31407 }
31408 if let Some(action) = &e.action {
31409 if let Expression::Identifier(id) = action.as_ref() {
31411 if id.name.eq_ignore_ascii_case("NOTHING") {
31412 self.write_keyword(" DO NOTHING");
31413 } else {
31414 self.write_keyword(" DO ");
31415 self.generate_expression(action)?;
31416 }
31417 } else if let Expression::Tuple(t) = action.as_ref() {
31418 self.write_keyword(" DO UPDATE SET ");
31420 for (i, expr) in t.expressions.iter().enumerate() {
31421 if i > 0 {
31422 self.write(", ");
31423 }
31424 self.generate_expression(expr)?;
31425 }
31426 } else {
31427 self.write_keyword(" DO ");
31428 self.generate_expression(action)?;
31429 }
31430 }
31431 if let Some(where_) = &e.where_ {
31433 self.write_keyword(" WHERE ");
31434 self.generate_expression(where_)?;
31435 }
31436 Ok(())
31437 }
31438
31439 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
31440 self.write_keyword("ON");
31442 self.write_space();
31443 self.generate_expression(&e.this)?;
31444 Ok(())
31445 }
31446
31447 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
31448 self.generate_expression(&e.this)?;
31450 self.write_space();
31451 self.generate_expression(&e.expression)?;
31452 Ok(())
31453 }
31454
31455 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
31456 self.write_keyword("OPENJSON");
31458 self.write("(");
31459 self.generate_expression(&e.this)?;
31460 if let Some(path) = &e.path {
31461 self.write(", ");
31462 self.generate_expression(path)?;
31463 }
31464 self.write(")");
31465 if !e.expressions.is_empty() {
31466 self.write_keyword(" WITH");
31467 if self.config.pretty {
31468 self.write(" (\n");
31469 self.indent_level += 2;
31470 for (i, expr) in e.expressions.iter().enumerate() {
31471 if i > 0 {
31472 self.write(",\n");
31473 }
31474 self.write_indent();
31475 self.generate_expression(expr)?;
31476 }
31477 self.write("\n");
31478 self.indent_level -= 2;
31479 self.write(")");
31480 } else {
31481 self.write(" (");
31482 for (i, expr) in e.expressions.iter().enumerate() {
31483 if i > 0 {
31484 self.write(", ");
31485 }
31486 self.generate_expression(expr)?;
31487 }
31488 self.write(")");
31489 }
31490 }
31491 Ok(())
31492 }
31493
31494 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
31495 self.generate_expression(&e.this)?;
31497 self.write_space();
31498 if let Some(ref dt) = e.data_type {
31500 self.generate_data_type(dt)?;
31501 } else if !e.kind.is_empty() {
31502 self.write(&e.kind);
31503 }
31504 if let Some(path) = &e.path {
31505 self.write_space();
31506 self.generate_expression(path)?;
31507 }
31508 if e.as_json.is_some() {
31509 self.write_keyword(" AS JSON");
31510 }
31511 Ok(())
31512 }
31513
31514 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
31515 self.generate_expression(&e.this)?;
31517 self.write_space();
31518 if let Some(op) = &e.operator {
31519 self.write_keyword("OPERATOR");
31520 self.write("(");
31521 self.generate_expression(op)?;
31522 self.write(")");
31523 }
31524 for comment in &e.comments {
31526 self.write_space();
31527 self.write_formatted_comment(comment);
31528 }
31529 self.write_space();
31530 self.generate_expression(&e.expression)?;
31531 Ok(())
31532 }
31533
31534 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
31535 self.write_keyword("ORDER BY");
31537 let pretty_clickhouse_single_paren = self.config.pretty
31538 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
31539 && e.expressions.len() == 1
31540 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
31541 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
31542 && e.expressions.len() == 1
31543 && matches!(e.expressions[0].this, Expression::Tuple(_))
31544 && !e.expressions[0].desc
31545 && e.expressions[0].nulls_first.is_none();
31546
31547 if pretty_clickhouse_single_paren {
31548 self.write_space();
31549 if let Expression::Paren(p) = &e.expressions[0].this {
31550 self.write("(");
31551 self.write_newline();
31552 self.indent_level += 1;
31553 self.write_indent();
31554 self.generate_expression(&p.this)?;
31555 self.indent_level -= 1;
31556 self.write_newline();
31557 self.write(")");
31558 }
31559 return Ok(());
31560 }
31561
31562 if clickhouse_single_tuple {
31563 self.write_space();
31564 if let Expression::Tuple(t) = &e.expressions[0].this {
31565 self.write("(");
31566 for (i, expr) in t.expressions.iter().enumerate() {
31567 if i > 0 {
31568 self.write(", ");
31569 }
31570 self.generate_expression(expr)?;
31571 }
31572 self.write(")");
31573 }
31574 return Ok(());
31575 }
31576
31577 self.write_space();
31578 for (i, ordered) in e.expressions.iter().enumerate() {
31579 if i > 0 {
31580 self.write(", ");
31581 }
31582 self.generate_expression(&ordered.this)?;
31583 if ordered.desc {
31584 self.write_space();
31585 self.write_keyword("DESC");
31586 } else if ordered.explicit_asc {
31587 self.write_space();
31588 self.write_keyword("ASC");
31589 }
31590 if let Some(nulls_first) = ordered.nulls_first {
31591 let skip_nulls_last =
31593 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
31594 if !skip_nulls_last {
31595 self.write_space();
31596 self.write_keyword("NULLS");
31597 self.write_space();
31598 if nulls_first {
31599 self.write_keyword("FIRST");
31600 } else {
31601 self.write_keyword("LAST");
31602 }
31603 }
31604 }
31605 }
31606 Ok(())
31607 }
31608
31609 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
31610 self.write_keyword("OUTPUT");
31612 self.write("(");
31613 if self.config.pretty {
31614 self.indent_level += 1;
31615 self.write_newline();
31616 self.write_indent();
31617 self.generate_expression(&e.this)?;
31618 self.indent_level -= 1;
31619 self.write_newline();
31620 } else {
31621 self.generate_expression(&e.this)?;
31622 }
31623 self.write(")");
31624 Ok(())
31625 }
31626
31627 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
31628 self.write_keyword("TRUNCATE");
31630 if let Some(this) = &e.this {
31631 self.write_space();
31632 self.generate_expression(this)?;
31633 }
31634 if e.with_count.is_some() {
31635 self.write_keyword(" WITH COUNT");
31636 } else {
31637 self.write_keyword(" WITHOUT COUNT");
31638 }
31639 Ok(())
31640 }
31641
31642 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
31643 self.generate_expression(&e.this)?;
31645 self.write("(");
31646 for (i, expr) in e.expressions.iter().enumerate() {
31647 if i > 0 {
31648 self.write(", ");
31649 }
31650 self.generate_expression(expr)?;
31651 }
31652 self.write(")(");
31653 for (i, param) in e.params.iter().enumerate() {
31654 if i > 0 {
31655 self.write(", ");
31656 }
31657 self.generate_expression(param)?;
31658 }
31659 self.write(")");
31660 Ok(())
31661 }
31662
31663 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
31664 self.write_keyword("PARSE_DATETIME");
31666 self.write("(");
31667 if let Some(format) = &e.format {
31668 self.write("'");
31669 self.write(format);
31670 self.write("', ");
31671 }
31672 self.generate_expression(&e.this)?;
31673 if let Some(zone) = &e.zone {
31674 self.write(", ");
31675 self.generate_expression(zone)?;
31676 }
31677 self.write(")");
31678 Ok(())
31679 }
31680
31681 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
31682 self.write_keyword("PARSE_IP");
31684 self.write("(");
31685 self.generate_expression(&e.this)?;
31686 if let Some(type_) = &e.type_ {
31687 self.write(", ");
31688 self.generate_expression(type_)?;
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_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
31699 self.write_keyword("PARSE_JSON");
31701 self.write("(");
31702 self.generate_expression(&e.this)?;
31703 if let Some(expression) = &e.expression {
31704 self.write(", ");
31705 self.generate_expression(expression)?;
31706 }
31707 self.write(")");
31708 Ok(())
31709 }
31710
31711 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
31712 self.write_keyword("PARSE_TIME");
31714 self.write("(");
31715 self.write(&format!("'{}'", e.format));
31716 self.write(", ");
31717 self.generate_expression(&e.this)?;
31718 self.write(")");
31719 Ok(())
31720 }
31721
31722 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
31723 self.write_keyword("PARSE_URL");
31725 self.write("(");
31726 self.generate_expression(&e.this)?;
31727 if let Some(part) = &e.part_to_extract {
31728 self.write(", ");
31729 self.generate_expression(part)?;
31730 }
31731 if let Some(key) = &e.key {
31732 self.write(", ");
31733 self.generate_expression(key)?;
31734 }
31735 if let Some(permissive) = &e.permissive {
31736 self.write(", ");
31737 self.generate_expression(permissive)?;
31738 }
31739 self.write(")");
31740 Ok(())
31741 }
31742
31743 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
31744 if e.subpartition {
31746 self.write_keyword("SUBPARTITION");
31747 } else {
31748 self.write_keyword("PARTITION");
31749 }
31750 self.write("(");
31751 for (i, expr) in e.expressions.iter().enumerate() {
31752 if i > 0 {
31753 self.write(", ");
31754 }
31755 self.generate_expression(expr)?;
31756 }
31757 self.write(")");
31758 Ok(())
31759 }
31760
31761 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
31762 if let Some(this) = &e.this {
31764 if let Some(expression) = &e.expression {
31765 self.write_keyword("WITH");
31767 self.write(" (");
31768 self.write_keyword("MODULUS");
31769 self.write_space();
31770 self.generate_expression(this)?;
31771 self.write(", ");
31772 self.write_keyword("REMAINDER");
31773 self.write_space();
31774 self.generate_expression(expression)?;
31775 self.write(")");
31776 } else {
31777 self.write_keyword("IN");
31779 self.write(" (");
31780 self.generate_partition_bound_values(this)?;
31781 self.write(")");
31782 }
31783 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
31784 self.write_keyword("FROM");
31786 self.write(" (");
31787 self.generate_partition_bound_values(from)?;
31788 self.write(") ");
31789 self.write_keyword("TO");
31790 self.write(" (");
31791 self.generate_partition_bound_values(to)?;
31792 self.write(")");
31793 }
31794 Ok(())
31795 }
31796
31797 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
31800 if let Expression::Tuple(t) = expr {
31801 for (i, e) in t.expressions.iter().enumerate() {
31802 if i > 0 {
31803 self.write(", ");
31804 }
31805 self.generate_expression(e)?;
31806 }
31807 Ok(())
31808 } else {
31809 self.generate_expression(expr)
31810 }
31811 }
31812
31813 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
31814 self.write_keyword("PARTITION BY LIST");
31816 if let Some(partition_exprs) = &e.partition_expressions {
31817 self.write(" (");
31818 self.generate_doris_partition_expressions(partition_exprs)?;
31820 self.write(")");
31821 }
31822 if let Some(create_exprs) = &e.create_expressions {
31823 self.write(" (");
31824 self.generate_doris_partition_definitions(create_exprs)?;
31826 self.write(")");
31827 }
31828 Ok(())
31829 }
31830
31831 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
31832 self.write_keyword("PARTITION BY RANGE");
31834 if let Some(partition_exprs) = &e.partition_expressions {
31835 self.write(" (");
31836 self.generate_doris_partition_expressions(partition_exprs)?;
31838 self.write(")");
31839 }
31840 if let Some(create_exprs) = &e.create_expressions {
31841 self.write(" (");
31842 self.generate_doris_partition_definitions(create_exprs)?;
31844 self.write(")");
31845 }
31846 Ok(())
31847 }
31848
31849 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
31851 if let Expression::Tuple(t) = expr {
31852 for (i, e) in t.expressions.iter().enumerate() {
31853 if i > 0 {
31854 self.write(", ");
31855 }
31856 self.generate_expression(e)?;
31857 }
31858 } else {
31859 self.generate_expression(expr)?;
31860 }
31861 Ok(())
31862 }
31863
31864 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
31866 match expr {
31867 Expression::Tuple(t) => {
31868 for (i, part) in t.expressions.iter().enumerate() {
31870 if i > 0 {
31871 self.write(", ");
31872 }
31873 if let Expression::Partition(p) = part {
31875 for (j, inner) in p.expressions.iter().enumerate() {
31876 if j > 0 {
31877 self.write(", ");
31878 }
31879 self.generate_expression(inner)?;
31880 }
31881 } else {
31882 self.generate_expression(part)?;
31883 }
31884 }
31885 }
31886 Expression::PartitionByRangePropertyDynamic(_) => {
31887 self.generate_expression(expr)?;
31889 }
31890 _ => {
31891 self.generate_expression(expr)?;
31892 }
31893 }
31894 Ok(())
31895 }
31896
31897 fn generate_partition_by_range_property_dynamic(
31898 &mut self,
31899 e: &PartitionByRangePropertyDynamic,
31900 ) -> Result<()> {
31901 if e.use_start_end {
31902 if let Some(start) = &e.start {
31904 self.write_keyword("START");
31905 self.write(" (");
31906 self.generate_expression(start)?;
31907 self.write(")");
31908 }
31909 if let Some(end) = &e.end {
31910 self.write_space();
31911 self.write_keyword("END");
31912 self.write(" (");
31913 self.generate_expression(end)?;
31914 self.write(")");
31915 }
31916 if let Some(every) = &e.every {
31917 self.write_space();
31918 self.write_keyword("EVERY");
31919 self.write(" (");
31920 self.generate_doris_interval(every)?;
31922 self.write(")");
31923 }
31924 } else {
31925 if let Some(start) = &e.start {
31927 self.write_keyword("FROM");
31928 self.write(" (");
31929 self.generate_expression(start)?;
31930 self.write(")");
31931 }
31932 if let Some(end) = &e.end {
31933 self.write_space();
31934 self.write_keyword("TO");
31935 self.write(" (");
31936 self.generate_expression(end)?;
31937 self.write(")");
31938 }
31939 if let Some(every) = &e.every {
31940 self.write_space();
31941 self.generate_doris_interval(every)?;
31943 }
31944 }
31945 Ok(())
31946 }
31947
31948 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
31950 if let Expression::Interval(interval) = expr {
31951 self.write_keyword("INTERVAL");
31952 if let Some(ref value) = interval.this {
31953 self.write_space();
31954 match value {
31958 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()) => {
31959 if let Literal::String(s) = lit.as_ref() {
31960 self.write(s);
31961 }
31962 }
31963 _ => {
31964 self.generate_expression(value)?;
31965 }
31966 }
31967 }
31968 if let Some(ref unit_spec) = interval.unit {
31969 self.write_space();
31970 self.write_interval_unit_spec(unit_spec)?;
31971 }
31972 Ok(())
31973 } else {
31974 self.generate_expression(expr)
31975 }
31976 }
31977
31978 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
31979 self.write_keyword("TRUNCATE");
31981 self.write("(");
31982 self.generate_expression(&e.expression)?;
31983 self.write(", ");
31984 self.generate_expression(&e.this)?;
31985 self.write(")");
31986 Ok(())
31987 }
31988
31989 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
31990 self.write_keyword("PARTITION");
31992 self.write_space();
31993 self.generate_expression(&e.this)?;
31994 self.write_space();
31995 self.write_keyword("VALUES IN");
31996 self.write(" (");
31997 for (i, expr) in e.expressions.iter().enumerate() {
31998 if i > 0 {
31999 self.write(", ");
32000 }
32001 self.generate_expression(expr)?;
32002 }
32003 self.write(")");
32004 Ok(())
32005 }
32006
32007 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
32008 if e.expressions.is_empty() && e.expression.is_some() {
32011 self.generate_expression(&e.this)?;
32013 self.write_space();
32014 self.write_keyword("TO");
32015 self.write_space();
32016 self.generate_expression(e.expression.as_ref().unwrap())?;
32017 return Ok(());
32018 }
32019
32020 self.write_keyword("PARTITION");
32022 self.write_space();
32023 self.generate_expression(&e.this)?;
32024 self.write_space();
32025
32026 if e.expressions.len() == 1 {
32028 self.write_keyword("VALUES LESS THAN");
32030 self.write(" (");
32031 self.generate_expression(&e.expressions[0])?;
32032 self.write(")");
32033 } else if !e.expressions.is_empty() {
32034 self.write_keyword("VALUES");
32036 self.write(" [");
32037 for (i, expr) in e.expressions.iter().enumerate() {
32038 if i > 0 {
32039 self.write(", ");
32040 }
32041 if let Expression::Tuple(t) = expr {
32043 self.write("(");
32044 for (j, inner) in t.expressions.iter().enumerate() {
32045 if j > 0 {
32046 self.write(", ");
32047 }
32048 self.generate_expression(inner)?;
32049 }
32050 self.write(")");
32051 } else {
32052 self.write("(");
32053 self.generate_expression(expr)?;
32054 self.write(")");
32055 }
32056 }
32057 self.write(")");
32058 }
32059 Ok(())
32060 }
32061
32062 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
32063 self.write_keyword("BUCKET");
32065 self.write("(");
32066 self.generate_expression(&e.this)?;
32067 self.write(", ");
32068 self.generate_expression(&e.expression)?;
32069 self.write(")");
32070 Ok(())
32071 }
32072
32073 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
32074 self.write_keyword("PARTITION BY");
32076 self.write_space();
32077 for (i, expr) in e.expressions.iter().enumerate() {
32078 if i > 0 {
32079 self.write(", ");
32080 }
32081 self.generate_expression(expr)?;
32082 }
32083 Ok(())
32084 }
32085
32086 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
32087 if matches!(
32089 self.config.dialect,
32090 Some(crate::dialects::DialectType::Teradata)
32091 | Some(crate::dialects::DialectType::ClickHouse)
32092 ) {
32093 self.write_keyword("PARTITION BY");
32094 } else {
32095 self.write_keyword("PARTITIONED BY");
32096 }
32097 self.write_space();
32098 if self.config.pretty {
32100 if let Expression::Tuple(ref tuple) = *e.this {
32101 self.write("(");
32102 self.write_newline();
32103 self.indent_level += 1;
32104 for (i, expr) in tuple.expressions.iter().enumerate() {
32105 if i > 0 {
32106 self.write(",");
32107 self.write_newline();
32108 }
32109 self.write_indent();
32110 self.generate_expression(expr)?;
32111 }
32112 self.indent_level -= 1;
32113 self.write_newline();
32114 self.write(")");
32115 } else {
32116 self.generate_expression(&e.this)?;
32117 }
32118 } else {
32119 self.generate_expression(&e.this)?;
32120 }
32121 Ok(())
32122 }
32123
32124 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
32125 self.write_keyword("PARTITION OF");
32127 self.write_space();
32128 self.generate_expression(&e.this)?;
32129 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
32131 self.write_space();
32132 self.write_keyword("FOR VALUES");
32133 self.write_space();
32134 self.generate_expression(&e.expression)?;
32135 } else {
32136 self.write_space();
32137 self.write_keyword("DEFAULT");
32138 }
32139 Ok(())
32140 }
32141
32142 fn generate_period_for_system_time_constraint(
32143 &mut self,
32144 e: &PeriodForSystemTimeConstraint,
32145 ) -> Result<()> {
32146 self.write_keyword("PERIOD FOR SYSTEM_TIME");
32148 self.write(" (");
32149 self.generate_expression(&e.this)?;
32150 self.write(", ");
32151 self.generate_expression(&e.expression)?;
32152 self.write(")");
32153 Ok(())
32154 }
32155
32156 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
32157 self.generate_expression(&e.this)?;
32160 self.write_space();
32161 self.write_keyword("AS");
32162 self.write_space();
32163 if self.config.unpivot_aliases_are_identifiers {
32165 match &e.alias {
32166 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
32167 let Literal::String(s) = lit.as_ref() else {
32168 unreachable!()
32169 };
32170 self.generate_identifier(&Identifier::new(s.clone()))?;
32172 }
32173 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
32174 let Literal::Number(n) = lit.as_ref() else {
32175 unreachable!()
32176 };
32177 let mut id = Identifier::new(n.clone());
32179 id.quoted = true;
32180 self.generate_identifier(&id)?;
32181 }
32182 other => {
32183 self.generate_expression(other)?;
32184 }
32185 }
32186 } else {
32187 self.generate_expression(&e.alias)?;
32188 }
32189 Ok(())
32190 }
32191
32192 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
32193 self.write_keyword("ANY");
32195 if let Some(this) = &e.this {
32196 self.write_space();
32197 self.generate_expression(this)?;
32198 }
32199 Ok(())
32200 }
32201
32202 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
32203 self.write_keyword("ML.PREDICT");
32205 self.write("(");
32206 self.write_keyword("MODEL");
32207 self.write_space();
32208 self.generate_expression(&e.this)?;
32209 self.write(", ");
32210 self.generate_expression(&e.expression)?;
32211 if let Some(params) = &e.params_struct {
32212 self.write(", ");
32213 self.generate_expression(params)?;
32214 }
32215 self.write(")");
32216 Ok(())
32217 }
32218
32219 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
32220 self.write_keyword("PREVIOUS_DAY");
32222 self.write("(");
32223 self.generate_expression(&e.this)?;
32224 self.write(", ");
32225 self.generate_expression(&e.expression)?;
32226 self.write(")");
32227 Ok(())
32228 }
32229
32230 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
32231 self.write_keyword("PRIMARY KEY");
32233 if let Some(name) = &e.this {
32234 self.write_space();
32235 self.generate_expression(name)?;
32236 }
32237 if !e.expressions.is_empty() {
32238 self.write(" (");
32239 for (i, expr) in e.expressions.iter().enumerate() {
32240 if i > 0 {
32241 self.write(", ");
32242 }
32243 self.generate_expression(expr)?;
32244 }
32245 self.write(")");
32246 }
32247 if let Some(include) = &e.include {
32248 self.write_space();
32249 self.generate_expression(include)?;
32250 }
32251 if !e.options.is_empty() {
32252 self.write_space();
32253 for (i, opt) in e.options.iter().enumerate() {
32254 if i > 0 {
32255 self.write_space();
32256 }
32257 self.generate_expression(opt)?;
32258 }
32259 }
32260 Ok(())
32261 }
32262
32263 fn generate_primary_key_column_constraint(
32264 &mut self,
32265 _e: &PrimaryKeyColumnConstraint,
32266 ) -> Result<()> {
32267 self.write_keyword("PRIMARY KEY");
32269 Ok(())
32270 }
32271
32272 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
32273 self.write_keyword("PATH");
32275 self.write_space();
32276 self.generate_expression(&e.this)?;
32277 Ok(())
32278 }
32279
32280 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
32281 self.write_keyword("PROJECTION");
32283 self.write_space();
32284 self.generate_expression(&e.this)?;
32285 self.write(" (");
32286 self.generate_expression(&e.expression)?;
32287 self.write(")");
32288 Ok(())
32289 }
32290
32291 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
32292 for (i, prop) in e.expressions.iter().enumerate() {
32294 if i > 0 {
32295 self.write(", ");
32296 }
32297 self.generate_expression(prop)?;
32298 }
32299 Ok(())
32300 }
32301
32302 fn generate_property(&mut self, e: &Property) -> Result<()> {
32303 self.generate_expression(&e.this)?;
32305 if let Some(value) = &e.value {
32306 self.write("=");
32307 self.generate_expression(value)?;
32308 }
32309 Ok(())
32310 }
32311
32312 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
32313 self.write_keyword("OPTIONS");
32314 if e.entries.is_empty() {
32315 self.write(" ()");
32316 return Ok(());
32317 }
32318
32319 if self.config.pretty {
32320 self.write(" (");
32321 self.write_newline();
32322 self.indent_level += 1;
32323 for (i, entry) in e.entries.iter().enumerate() {
32324 if i > 0 {
32325 self.write(",");
32326 self.write_newline();
32327 }
32328 self.write_indent();
32329 self.generate_identifier(&entry.key)?;
32330 self.write("=");
32331 self.generate_expression(&entry.value)?;
32332 }
32333 self.indent_level -= 1;
32334 self.write_newline();
32335 self.write(")");
32336 } else {
32337 self.write(" (");
32338 for (i, entry) in e.entries.iter().enumerate() {
32339 if i > 0 {
32340 self.write(", ");
32341 }
32342 self.generate_identifier(&entry.key)?;
32343 self.write("=");
32344 self.generate_expression(&entry.value)?;
32345 }
32346 self.write(")");
32347 }
32348 Ok(())
32349 }
32350
32351 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
32353 self.write_keyword("OPTIONS");
32354 self.write(" (");
32355 for (i, opt) in options.iter().enumerate() {
32356 if i > 0 {
32357 self.write(", ");
32358 }
32359 self.generate_option_expression(opt)?;
32360 }
32361 self.write(")");
32362 Ok(())
32363 }
32364
32365 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
32367 self.write_keyword("PROPERTIES");
32368 self.write(" (");
32369 for (i, prop) in properties.iter().enumerate() {
32370 if i > 0 {
32371 self.write(", ");
32372 }
32373 self.generate_option_expression(prop)?;
32374 }
32375 self.write(")");
32376 Ok(())
32377 }
32378
32379 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
32381 self.write_keyword("ENVIRONMENT");
32382 self.write(" (");
32383 for (i, env_item) in environment.iter().enumerate() {
32384 if i > 0 {
32385 self.write(", ");
32386 }
32387 self.generate_environment_expression(env_item)?;
32388 }
32389 self.write(")");
32390 Ok(())
32391 }
32392
32393 fn generate_environment_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_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
32409 self.write_keyword("TBLPROPERTIES");
32410 if self.config.pretty {
32411 self.write(" (");
32412 self.write_newline();
32413 self.indent_level += 1;
32414 for (i, opt) in options.iter().enumerate() {
32415 if i > 0 {
32416 self.write(",");
32417 self.write_newline();
32418 }
32419 self.write_indent();
32420 self.generate_option_expression(opt)?;
32421 }
32422 self.indent_level -= 1;
32423 self.write_newline();
32424 self.write(")");
32425 } else {
32426 self.write(" (");
32427 for (i, opt) in options.iter().enumerate() {
32428 if i > 0 {
32429 self.write(", ");
32430 }
32431 self.generate_option_expression(opt)?;
32432 }
32433 self.write(")");
32434 }
32435 Ok(())
32436 }
32437
32438 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
32440 match expr {
32441 Expression::Eq(eq) => {
32442 self.generate_expression(&eq.left)?;
32444 self.write("=");
32445 self.generate_expression(&eq.right)?;
32446 Ok(())
32447 }
32448 _ => self.generate_expression(expr),
32449 }
32450 }
32451
32452 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
32453 self.generate_expression(&e.this)?;
32455 Ok(())
32456 }
32457
32458 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
32459 self.write_keyword("PUT");
32461 self.write_space();
32462
32463 if e.source_quoted {
32465 self.write("'");
32466 self.write(&e.source);
32467 self.write("'");
32468 } else {
32469 self.write(&e.source);
32470 }
32471
32472 self.write_space();
32473
32474 if let Expression::Literal(lit) = &e.target {
32476 if let Literal::String(s) = lit.as_ref() {
32477 self.write(s);
32478 }
32479 } else {
32480 self.generate_expression(&e.target)?;
32481 }
32482
32483 for param in &e.params {
32485 self.write_space();
32486 self.write(¶m.name);
32487 if let Some(ref value) = param.value {
32488 self.write("=");
32489 self.generate_expression(value)?;
32490 }
32491 }
32492
32493 Ok(())
32494 }
32495
32496 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
32497 self.write_keyword("QUANTILE");
32499 self.write("(");
32500 self.generate_expression(&e.this)?;
32501 if let Some(quantile) = &e.quantile {
32502 self.write(", ");
32503 self.generate_expression(quantile)?;
32504 }
32505 self.write(")");
32506 Ok(())
32507 }
32508
32509 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
32510 if matches!(
32512 self.config.dialect,
32513 Some(crate::dialects::DialectType::Teradata)
32514 ) {
32515 self.write_keyword("SET");
32516 self.write_space();
32517 }
32518 self.write_keyword("QUERY_BAND");
32519 self.write(" = ");
32520 self.generate_expression(&e.this)?;
32521 if e.update.is_some() {
32522 self.write_space();
32523 self.write_keyword("UPDATE");
32524 }
32525 if let Some(scope) = &e.scope {
32526 self.write_space();
32527 self.write_keyword("FOR");
32528 self.write_space();
32529 self.generate_expression(scope)?;
32530 }
32531 Ok(())
32532 }
32533
32534 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
32535 self.generate_expression(&e.this)?;
32537 if let Some(expression) = &e.expression {
32538 self.write(" = ");
32539 self.generate_expression(expression)?;
32540 }
32541 Ok(())
32542 }
32543
32544 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
32545 self.write_keyword("TRANSFORM");
32547 self.write("(");
32548 for (i, expr) in e.expressions.iter().enumerate() {
32549 if i > 0 {
32550 self.write(", ");
32551 }
32552 self.generate_expression(expr)?;
32553 }
32554 self.write(")");
32555 if let Some(row_format_before) = &e.row_format_before {
32556 self.write_space();
32557 self.generate_expression(row_format_before)?;
32558 }
32559 if let Some(record_writer) = &e.record_writer {
32560 self.write_space();
32561 self.write_keyword("RECORDWRITER");
32562 self.write_space();
32563 self.generate_expression(record_writer)?;
32564 }
32565 if let Some(command_script) = &e.command_script {
32566 self.write_space();
32567 self.write_keyword("USING");
32568 self.write_space();
32569 self.generate_expression(command_script)?;
32570 }
32571 if let Some(schema) = &e.schema {
32572 self.write_space();
32573 self.write_keyword("AS");
32574 self.write_space();
32575 self.generate_expression(schema)?;
32576 }
32577 if let Some(row_format_after) = &e.row_format_after {
32578 self.write_space();
32579 self.generate_expression(row_format_after)?;
32580 }
32581 if let Some(record_reader) = &e.record_reader {
32582 self.write_space();
32583 self.write_keyword("RECORDREADER");
32584 self.write_space();
32585 self.generate_expression(record_reader)?;
32586 }
32587 Ok(())
32588 }
32589
32590 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
32591 self.write_keyword("RANDN");
32593 self.write("(");
32594 if let Some(this) = &e.this {
32595 self.generate_expression(this)?;
32596 }
32597 self.write(")");
32598 Ok(())
32599 }
32600
32601 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
32602 self.write_keyword("RANDSTR");
32604 self.write("(");
32605 self.generate_expression(&e.this)?;
32606 if let Some(generator) = &e.generator {
32607 self.write(", ");
32608 self.generate_expression(generator)?;
32609 }
32610 self.write(")");
32611 Ok(())
32612 }
32613
32614 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
32615 self.write_keyword("RANGE_BUCKET");
32617 self.write("(");
32618 self.generate_expression(&e.this)?;
32619 self.write(", ");
32620 self.generate_expression(&e.expression)?;
32621 self.write(")");
32622 Ok(())
32623 }
32624
32625 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
32626 self.write_keyword("RANGE_N");
32628 self.write("(");
32629 self.generate_expression(&e.this)?;
32630 self.write_space();
32631 self.write_keyword("BETWEEN");
32632 self.write_space();
32633 for (i, expr) in e.expressions.iter().enumerate() {
32634 if i > 0 {
32635 self.write(", ");
32636 }
32637 self.generate_expression(expr)?;
32638 }
32639 if let Some(each) = &e.each {
32640 self.write_space();
32641 self.write_keyword("EACH");
32642 self.write_space();
32643 self.generate_expression(each)?;
32644 }
32645 self.write(")");
32646 Ok(())
32647 }
32648
32649 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
32650 self.write_keyword("READ_CSV");
32652 self.write("(");
32653 self.generate_expression(&e.this)?;
32654 for expr in &e.expressions {
32655 self.write(", ");
32656 self.generate_expression(expr)?;
32657 }
32658 self.write(")");
32659 Ok(())
32660 }
32661
32662 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
32663 self.write_keyword("READ_PARQUET");
32665 self.write("(");
32666 for (i, expr) in e.expressions.iter().enumerate() {
32667 if i > 0 {
32668 self.write(", ");
32669 }
32670 self.generate_expression(expr)?;
32671 }
32672 self.write(")");
32673 Ok(())
32674 }
32675
32676 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
32677 if e.kind == "CYCLE" {
32680 self.write_keyword("CYCLE");
32681 } else {
32682 self.write_keyword("SEARCH");
32683 self.write_space();
32684 self.write(&e.kind);
32685 self.write_space();
32686 self.write_keyword("FIRST BY");
32687 }
32688 self.write_space();
32689 self.generate_expression(&e.this)?;
32690 self.write_space();
32691 self.write_keyword("SET");
32692 self.write_space();
32693 self.generate_expression(&e.expression)?;
32694 if let Some(using) = &e.using {
32695 self.write_space();
32696 self.write_keyword("USING");
32697 self.write_space();
32698 self.generate_expression(using)?;
32699 }
32700 Ok(())
32701 }
32702
32703 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
32704 self.write_keyword("REDUCE");
32706 self.write("(");
32707 self.generate_expression(&e.this)?;
32708 if let Some(initial) = &e.initial {
32709 self.write(", ");
32710 self.generate_expression(initial)?;
32711 }
32712 if let Some(merge) = &e.merge {
32713 self.write(", ");
32714 self.generate_expression(merge)?;
32715 }
32716 if let Some(finish) = &e.finish {
32717 self.write(", ");
32718 self.generate_expression(finish)?;
32719 }
32720 self.write(")");
32721 Ok(())
32722 }
32723
32724 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
32725 self.write_keyword("REFERENCES");
32727 self.write_space();
32728 self.generate_expression(&e.this)?;
32729 if !e.expressions.is_empty() {
32730 self.write(" (");
32731 for (i, expr) in e.expressions.iter().enumerate() {
32732 if i > 0 {
32733 self.write(", ");
32734 }
32735 self.generate_expression(expr)?;
32736 }
32737 self.write(")");
32738 }
32739 for opt in &e.options {
32740 self.write_space();
32741 self.generate_expression(opt)?;
32742 }
32743 Ok(())
32744 }
32745
32746 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
32747 self.write_keyword("REFRESH");
32749 if !e.kind.is_empty() {
32750 self.write_space();
32751 self.write_keyword(&e.kind);
32752 }
32753 self.write_space();
32754 self.generate_expression(&e.this)?;
32755 Ok(())
32756 }
32757
32758 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
32759 self.write_keyword("REFRESH");
32761 self.write_space();
32762 self.write_keyword(&e.method);
32763
32764 if let Some(ref kind) = e.kind {
32765 self.write_space();
32766 self.write_keyword("ON");
32767 self.write_space();
32768 self.write_keyword(kind);
32769
32770 if let Some(ref every) = e.every {
32772 self.write_space();
32773 self.write_keyword("EVERY");
32774 self.write_space();
32775 self.generate_expression(every)?;
32776 if let Some(ref unit) = e.unit {
32777 self.write_space();
32778 self.write_keyword(unit);
32779 }
32780 }
32781
32782 if let Some(ref starts) = e.starts {
32784 self.write_space();
32785 self.write_keyword("STARTS");
32786 self.write_space();
32787 self.generate_expression(starts)?;
32788 }
32789 }
32790 Ok(())
32791 }
32792
32793 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
32794 self.write_keyword("REGEXP_COUNT");
32796 self.write("(");
32797 self.generate_expression(&e.this)?;
32798 self.write(", ");
32799 self.generate_expression(&e.expression)?;
32800 if let Some(position) = &e.position {
32801 self.write(", ");
32802 self.generate_expression(position)?;
32803 }
32804 if let Some(parameters) = &e.parameters {
32805 self.write(", ");
32806 self.generate_expression(parameters)?;
32807 }
32808 self.write(")");
32809 Ok(())
32810 }
32811
32812 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
32813 self.write_keyword("REGEXP_EXTRACT_ALL");
32815 self.write("(");
32816 self.generate_expression(&e.this)?;
32817 self.write(", ");
32818 self.generate_expression(&e.expression)?;
32819 if let Some(group) = &e.group {
32820 self.write(", ");
32821 self.generate_expression(group)?;
32822 }
32823 self.write(")");
32824 Ok(())
32825 }
32826
32827 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
32828 self.write_keyword("REGEXP_FULL_MATCH");
32830 self.write("(");
32831 self.generate_expression(&e.this)?;
32832 self.write(", ");
32833 self.generate_expression(&e.expression)?;
32834 self.write(")");
32835 Ok(())
32836 }
32837
32838 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
32839 use crate::dialects::DialectType;
32840 if matches!(
32842 self.config.dialect,
32843 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
32844 ) && e.flag.is_none()
32845 {
32846 self.generate_expression(&e.this)?;
32847 self.write(" ~* ");
32848 self.generate_expression(&e.expression)?;
32849 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
32850 self.write_keyword("REGEXP_LIKE");
32852 self.write("(");
32853 self.generate_expression(&e.this)?;
32854 self.write(", ");
32855 self.generate_expression(&e.expression)?;
32856 self.write(", ");
32857 if let Some(flag) = &e.flag {
32858 self.generate_expression(flag)?;
32859 } else {
32860 self.write("'i'");
32861 }
32862 self.write(")");
32863 } else {
32864 self.generate_expression(&e.this)?;
32866 self.write_space();
32867 self.write_keyword("REGEXP_ILIKE");
32868 self.write_space();
32869 self.generate_expression(&e.expression)?;
32870 if let Some(flag) = &e.flag {
32871 self.write(", ");
32872 self.generate_expression(flag)?;
32873 }
32874 }
32875 Ok(())
32876 }
32877
32878 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
32879 self.write_keyword("REGEXP_INSTR");
32881 self.write("(");
32882 self.generate_expression(&e.this)?;
32883 self.write(", ");
32884 self.generate_expression(&e.expression)?;
32885 if let Some(position) = &e.position {
32886 self.write(", ");
32887 self.generate_expression(position)?;
32888 }
32889 if let Some(occurrence) = &e.occurrence {
32890 self.write(", ");
32891 self.generate_expression(occurrence)?;
32892 }
32893 if let Some(option) = &e.option {
32894 self.write(", ");
32895 self.generate_expression(option)?;
32896 }
32897 if let Some(parameters) = &e.parameters {
32898 self.write(", ");
32899 self.generate_expression(parameters)?;
32900 }
32901 if let Some(group) = &e.group {
32902 self.write(", ");
32903 self.generate_expression(group)?;
32904 }
32905 self.write(")");
32906 Ok(())
32907 }
32908
32909 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
32910 self.write_keyword("REGEXP_SPLIT");
32912 self.write("(");
32913 self.generate_expression(&e.this)?;
32914 self.write(", ");
32915 self.generate_expression(&e.expression)?;
32916 if let Some(limit) = &e.limit {
32917 self.write(", ");
32918 self.generate_expression(limit)?;
32919 }
32920 self.write(")");
32921 Ok(())
32922 }
32923
32924 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
32925 self.write_keyword("REGR_AVGX");
32927 self.write("(");
32928 self.generate_expression(&e.this)?;
32929 self.write(", ");
32930 self.generate_expression(&e.expression)?;
32931 self.write(")");
32932 Ok(())
32933 }
32934
32935 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
32936 self.write_keyword("REGR_AVGY");
32938 self.write("(");
32939 self.generate_expression(&e.this)?;
32940 self.write(", ");
32941 self.generate_expression(&e.expression)?;
32942 self.write(")");
32943 Ok(())
32944 }
32945
32946 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
32947 self.write_keyword("REGR_COUNT");
32949 self.write("(");
32950 self.generate_expression(&e.this)?;
32951 self.write(", ");
32952 self.generate_expression(&e.expression)?;
32953 self.write(")");
32954 Ok(())
32955 }
32956
32957 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
32958 self.write_keyword("REGR_INTERCEPT");
32960 self.write("(");
32961 self.generate_expression(&e.this)?;
32962 self.write(", ");
32963 self.generate_expression(&e.expression)?;
32964 self.write(")");
32965 Ok(())
32966 }
32967
32968 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
32969 self.write_keyword("REGR_R2");
32971 self.write("(");
32972 self.generate_expression(&e.this)?;
32973 self.write(", ");
32974 self.generate_expression(&e.expression)?;
32975 self.write(")");
32976 Ok(())
32977 }
32978
32979 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
32980 self.write_keyword("REGR_SLOPE");
32982 self.write("(");
32983 self.generate_expression(&e.this)?;
32984 self.write(", ");
32985 self.generate_expression(&e.expression)?;
32986 self.write(")");
32987 Ok(())
32988 }
32989
32990 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
32991 self.write_keyword("REGR_SXX");
32993 self.write("(");
32994 self.generate_expression(&e.this)?;
32995 self.write(", ");
32996 self.generate_expression(&e.expression)?;
32997 self.write(")");
32998 Ok(())
32999 }
33000
33001 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
33002 self.write_keyword("REGR_SXY");
33004 self.write("(");
33005 self.generate_expression(&e.this)?;
33006 self.write(", ");
33007 self.generate_expression(&e.expression)?;
33008 self.write(")");
33009 Ok(())
33010 }
33011
33012 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
33013 self.write_keyword("REGR_SYY");
33015 self.write("(");
33016 self.generate_expression(&e.this)?;
33017 self.write(", ");
33018 self.generate_expression(&e.expression)?;
33019 self.write(")");
33020 Ok(())
33021 }
33022
33023 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
33024 self.write_keyword("REGR_VALX");
33026 self.write("(");
33027 self.generate_expression(&e.this)?;
33028 self.write(", ");
33029 self.generate_expression(&e.expression)?;
33030 self.write(")");
33031 Ok(())
33032 }
33033
33034 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
33035 self.write_keyword("REGR_VALY");
33037 self.write("(");
33038 self.generate_expression(&e.this)?;
33039 self.write(", ");
33040 self.generate_expression(&e.expression)?;
33041 self.write(")");
33042 Ok(())
33043 }
33044
33045 fn generate_remote_with_connection_model_property(
33046 &mut self,
33047 e: &RemoteWithConnectionModelProperty,
33048 ) -> Result<()> {
33049 self.write_keyword("REMOTE WITH CONNECTION");
33051 self.write_space();
33052 self.generate_expression(&e.this)?;
33053 Ok(())
33054 }
33055
33056 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
33057 self.write_keyword("RENAME COLUMN");
33059 if e.exists {
33060 self.write_space();
33061 self.write_keyword("IF EXISTS");
33062 }
33063 self.write_space();
33064 self.generate_expression(&e.this)?;
33065 if let Some(to) = &e.to {
33066 self.write_space();
33067 self.write_keyword("TO");
33068 self.write_space();
33069 self.generate_expression(to)?;
33070 }
33071 Ok(())
33072 }
33073
33074 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
33075 self.write_keyword("REPLACE PARTITION");
33077 self.write_space();
33078 self.generate_expression(&e.expression)?;
33079 if let Some(source) = &e.source {
33080 self.write_space();
33081 self.write_keyword("FROM");
33082 self.write_space();
33083 self.generate_expression(source)?;
33084 }
33085 Ok(())
33086 }
33087
33088 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
33089 let keyword = match self.config.dialect {
33092 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
33093 _ => "RETURNING",
33094 };
33095 self.write_keyword(keyword);
33096 self.write_space();
33097 for (i, expr) in e.expressions.iter().enumerate() {
33098 if i > 0 {
33099 self.write(", ");
33100 }
33101 self.generate_expression(expr)?;
33102 }
33103 if let Some(into) = &e.into {
33104 self.write_space();
33105 self.write_keyword("INTO");
33106 self.write_space();
33107 self.generate_expression(into)?;
33108 }
33109 Ok(())
33110 }
33111
33112 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
33113 self.write_space();
33115 self.write_keyword("OUTPUT");
33116 self.write_space();
33117 for (i, expr) in output.columns.iter().enumerate() {
33118 if i > 0 {
33119 self.write(", ");
33120 }
33121 self.generate_expression(expr)?;
33122 }
33123 if let Some(into_table) = &output.into_table {
33124 self.write_space();
33125 self.write_keyword("INTO");
33126 self.write_space();
33127 self.generate_expression(into_table)?;
33128 }
33129 Ok(())
33130 }
33131
33132 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
33133 self.write_keyword("RETURNS");
33135 if e.is_table.is_some() {
33136 self.write_space();
33137 self.write_keyword("TABLE");
33138 }
33139 if let Some(table) = &e.table {
33140 self.write_space();
33141 self.generate_expression(table)?;
33142 } else if let Some(this) = &e.this {
33143 self.write_space();
33144 self.generate_expression(this)?;
33145 }
33146 if e.null.is_some() {
33147 self.write_space();
33148 self.write_keyword("NULL ON NULL INPUT");
33149 }
33150 Ok(())
33151 }
33152
33153 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
33154 self.write_keyword("ROLLBACK");
33156
33157 if e.this.is_none()
33159 && matches!(
33160 self.config.dialect,
33161 Some(DialectType::TSQL) | Some(DialectType::Fabric)
33162 )
33163 {
33164 self.write_space();
33165 self.write_keyword("TRANSACTION");
33166 }
33167
33168 if let Some(this) = &e.this {
33170 let is_transaction_marker = matches!(
33172 this.as_ref(),
33173 Expression::Identifier(id) if id.name == "TRANSACTION"
33174 );
33175
33176 self.write_space();
33177 self.write_keyword("TRANSACTION");
33178
33179 if !is_transaction_marker {
33181 self.write_space();
33182 self.generate_expression(this)?;
33183 }
33184 }
33185
33186 if let Some(savepoint) = &e.savepoint {
33188 self.write_space();
33189 self.write_keyword("TO");
33190 self.write_space();
33191 self.generate_expression(savepoint)?;
33192 }
33193 Ok(())
33194 }
33195
33196 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
33197 if e.expressions.is_empty() {
33199 self.write_keyword("WITH ROLLUP");
33200 } else {
33201 self.write_keyword("ROLLUP");
33202 self.write("(");
33203 for (i, expr) in e.expressions.iter().enumerate() {
33204 if i > 0 {
33205 self.write(", ");
33206 }
33207 self.generate_expression(expr)?;
33208 }
33209 self.write(")");
33210 }
33211 Ok(())
33212 }
33213
33214 fn generate_row_format_delimited_property(
33215 &mut self,
33216 e: &RowFormatDelimitedProperty,
33217 ) -> Result<()> {
33218 self.write_keyword("ROW FORMAT DELIMITED");
33220 if let Some(fields) = &e.fields {
33221 self.write_space();
33222 self.write_keyword("FIELDS TERMINATED BY");
33223 self.write_space();
33224 self.generate_expression(fields)?;
33225 }
33226 if let Some(escaped) = &e.escaped {
33227 self.write_space();
33228 self.write_keyword("ESCAPED BY");
33229 self.write_space();
33230 self.generate_expression(escaped)?;
33231 }
33232 if let Some(items) = &e.collection_items {
33233 self.write_space();
33234 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
33235 self.write_space();
33236 self.generate_expression(items)?;
33237 }
33238 if let Some(keys) = &e.map_keys {
33239 self.write_space();
33240 self.write_keyword("MAP KEYS TERMINATED BY");
33241 self.write_space();
33242 self.generate_expression(keys)?;
33243 }
33244 if let Some(lines) = &e.lines {
33245 self.write_space();
33246 self.write_keyword("LINES TERMINATED BY");
33247 self.write_space();
33248 self.generate_expression(lines)?;
33249 }
33250 if let Some(null) = &e.null {
33251 self.write_space();
33252 self.write_keyword("NULL DEFINED AS");
33253 self.write_space();
33254 self.generate_expression(null)?;
33255 }
33256 if let Some(serde) = &e.serde {
33257 self.write_space();
33258 self.generate_expression(serde)?;
33259 }
33260 Ok(())
33261 }
33262
33263 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
33264 self.write_keyword("ROW FORMAT");
33266 self.write_space();
33267 self.generate_expression(&e.this)?;
33268 Ok(())
33269 }
33270
33271 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
33272 self.write_keyword("ROW FORMAT SERDE");
33274 self.write_space();
33275 self.generate_expression(&e.this)?;
33276 if let Some(props) = &e.serde_properties {
33277 self.write_space();
33278 self.generate_expression(props)?;
33280 }
33281 Ok(())
33282 }
33283
33284 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
33285 self.write_keyword("SHA2");
33287 self.write("(");
33288 self.generate_expression(&e.this)?;
33289 if let Some(length) = e.length {
33290 self.write(", ");
33291 self.write(&length.to_string());
33292 }
33293 self.write(")");
33294 Ok(())
33295 }
33296
33297 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
33298 self.write_keyword("SHA2_DIGEST");
33300 self.write("(");
33301 self.generate_expression(&e.this)?;
33302 if let Some(length) = e.length {
33303 self.write(", ");
33304 self.write(&length.to_string());
33305 }
33306 self.write(")");
33307 Ok(())
33308 }
33309
33310 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
33311 let name = if matches!(
33312 self.config.dialect,
33313 Some(crate::dialects::DialectType::Spark)
33314 | Some(crate::dialects::DialectType::Databricks)
33315 ) {
33316 "TRY_ADD"
33317 } else {
33318 "SAFE_ADD"
33319 };
33320 self.write_keyword(name);
33321 self.write("(");
33322 self.generate_expression(&e.this)?;
33323 self.write(", ");
33324 self.generate_expression(&e.expression)?;
33325 self.write(")");
33326 Ok(())
33327 }
33328
33329 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
33330 self.write_keyword("SAFE_DIVIDE");
33332 self.write("(");
33333 self.generate_expression(&e.this)?;
33334 self.write(", ");
33335 self.generate_expression(&e.expression)?;
33336 self.write(")");
33337 Ok(())
33338 }
33339
33340 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
33341 let name = if matches!(
33342 self.config.dialect,
33343 Some(crate::dialects::DialectType::Spark)
33344 | Some(crate::dialects::DialectType::Databricks)
33345 ) {
33346 "TRY_MULTIPLY"
33347 } else {
33348 "SAFE_MULTIPLY"
33349 };
33350 self.write_keyword(name);
33351 self.write("(");
33352 self.generate_expression(&e.this)?;
33353 self.write(", ");
33354 self.generate_expression(&e.expression)?;
33355 self.write(")");
33356 Ok(())
33357 }
33358
33359 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
33360 let name = if matches!(
33361 self.config.dialect,
33362 Some(crate::dialects::DialectType::Spark)
33363 | Some(crate::dialects::DialectType::Databricks)
33364 ) {
33365 "TRY_SUBTRACT"
33366 } else {
33367 "SAFE_SUBTRACT"
33368 };
33369 self.write_keyword(name);
33370 self.write("(");
33371 self.generate_expression(&e.this)?;
33372 self.write(", ");
33373 self.generate_expression(&e.expression)?;
33374 self.write(")");
33375 Ok(())
33376 }
33377
33378 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
33381 if matches!(sample.method, SampleMethod::Bucket) {
33383 self.write(" (");
33384 self.write_keyword("BUCKET");
33385 self.write_space();
33386 if let Some(ref num) = sample.bucket_numerator {
33387 self.generate_expression(num)?;
33388 }
33389 self.write_space();
33390 self.write_keyword("OUT OF");
33391 self.write_space();
33392 if let Some(ref denom) = sample.bucket_denominator {
33393 self.generate_expression(denom)?;
33394 }
33395 if let Some(ref field) = sample.bucket_field {
33396 self.write_space();
33397 self.write_keyword("ON");
33398 self.write_space();
33399 self.generate_expression(field)?;
33400 }
33401 self.write(")");
33402 return Ok(());
33403 }
33404
33405 let is_snowflake = matches!(
33407 self.config.dialect,
33408 Some(crate::dialects::DialectType::Snowflake)
33409 );
33410 let is_postgres = matches!(
33411 self.config.dialect,
33412 Some(crate::dialects::DialectType::PostgreSQL)
33413 | Some(crate::dialects::DialectType::Redshift)
33414 );
33415 let is_databricks = matches!(
33417 self.config.dialect,
33418 Some(crate::dialects::DialectType::Databricks)
33419 );
33420 let is_spark = matches!(
33421 self.config.dialect,
33422 Some(crate::dialects::DialectType::Spark)
33423 );
33424 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
33425 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
33427 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
33428 self.write_space();
33429 if !sample.explicit_method && (is_snowflake || force_method) {
33430 self.write_keyword("BERNOULLI");
33432 } else {
33433 match sample.method {
33434 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
33435 SampleMethod::System => self.write_keyword("SYSTEM"),
33436 SampleMethod::Block => self.write_keyword("BLOCK"),
33437 SampleMethod::Row => self.write_keyword("ROW"),
33438 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
33439 SampleMethod::Percent => self.write_keyword("SYSTEM"),
33440 SampleMethod::Bucket => {} }
33442 }
33443 }
33444
33445 let emit_size_no_parens = !self.config.tablesample_requires_parens;
33447 if emit_size_no_parens {
33448 self.write_space();
33449 match &sample.size {
33450 Expression::Tuple(tuple) => {
33451 for (i, expr) in tuple.expressions.iter().enumerate() {
33452 if i > 0 {
33453 self.write(", ");
33454 }
33455 self.generate_expression(expr)?;
33456 }
33457 }
33458 expr => self.generate_expression(expr)?,
33459 }
33460 } else {
33461 self.write(" (");
33462 self.generate_expression(&sample.size)?;
33463 }
33464
33465 let is_rows_method = matches!(
33467 sample.method,
33468 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
33469 );
33470 let is_percent = matches!(
33471 sample.method,
33472 SampleMethod::Percent
33473 | SampleMethod::System
33474 | SampleMethod::Bernoulli
33475 | SampleMethod::Block
33476 );
33477
33478 let is_presto = matches!(
33482 self.config.dialect,
33483 Some(crate::dialects::DialectType::Presto)
33484 | Some(crate::dialects::DialectType::Trino)
33485 | Some(crate::dialects::DialectType::Athena)
33486 );
33487 let should_output_unit = if is_databricks || is_spark {
33488 is_percent || is_rows_method || sample.unit_after_size
33490 } else if is_snowflake || is_postgres || is_presto {
33491 sample.unit_after_size
33492 } else {
33493 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
33494 };
33495
33496 if should_output_unit {
33497 self.write_space();
33498 if sample.is_percent {
33499 self.write_keyword("PERCENT");
33500 } else if is_rows_method && !sample.unit_after_size {
33501 self.write_keyword("ROWS");
33502 } else if sample.unit_after_size {
33503 match sample.method {
33504 SampleMethod::Percent
33505 | SampleMethod::System
33506 | SampleMethod::Bernoulli
33507 | SampleMethod::Block => {
33508 self.write_keyword("PERCENT");
33509 }
33510 SampleMethod::Row | SampleMethod::Reservoir => {
33511 self.write_keyword("ROWS");
33512 }
33513 _ => self.write_keyword("ROWS"),
33514 }
33515 } else {
33516 self.write_keyword("PERCENT");
33517 }
33518 }
33519
33520 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
33521 if let Some(ref offset) = sample.offset {
33522 self.write_space();
33523 self.write_keyword("OFFSET");
33524 self.write_space();
33525 self.generate_expression(offset)?;
33526 }
33527 }
33528 if !emit_size_no_parens {
33529 self.write(")");
33530 }
33531
33532 Ok(())
33533 }
33534
33535 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
33536 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
33538 self.write_keyword("SAMPLE BY");
33539 } else {
33540 self.write_keyword("SAMPLE");
33541 }
33542 self.write_space();
33543 self.generate_expression(&e.this)?;
33544 Ok(())
33545 }
33546
33547 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
33548 if let Some(this) = &e.this {
33550 self.generate_expression(this)?;
33551 }
33552 if !e.expressions.is_empty() {
33553 if e.this.is_some() {
33555 self.write_space();
33556 }
33557 self.write("(");
33558 for (i, expr) in e.expressions.iter().enumerate() {
33559 if i > 0 {
33560 self.write(", ");
33561 }
33562 self.generate_expression(expr)?;
33563 }
33564 self.write(")");
33565 }
33566 Ok(())
33567 }
33568
33569 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
33570 self.write_keyword("COMMENT");
33572 self.write_space();
33573 self.generate_expression(&e.this)?;
33574 Ok(())
33575 }
33576
33577 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
33578 if let Some(this) = &e.this {
33580 self.generate_expression(this)?;
33581 self.write("::");
33582 }
33583 self.generate_expression(&e.expression)?;
33584 Ok(())
33585 }
33586
33587 fn generate_search(&mut self, e: &Search) -> Result<()> {
33588 self.write_keyword("SEARCH");
33590 self.write("(");
33591 self.generate_expression(&e.this)?;
33592 self.write(", ");
33593 self.generate_expression(&e.expression)?;
33594 if let Some(json_scope) = &e.json_scope {
33595 self.write(", ");
33596 self.generate_expression(json_scope)?;
33597 }
33598 if let Some(analyzer) = &e.analyzer {
33599 self.write(", ");
33600 self.generate_expression(analyzer)?;
33601 }
33602 if let Some(analyzer_options) = &e.analyzer_options {
33603 self.write(", ");
33604 self.generate_expression(analyzer_options)?;
33605 }
33606 if let Some(search_mode) = &e.search_mode {
33607 self.write(", ");
33608 self.generate_expression(search_mode)?;
33609 }
33610 self.write(")");
33611 Ok(())
33612 }
33613
33614 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
33615 self.write_keyword("SEARCH_IP");
33617 self.write("(");
33618 self.generate_expression(&e.this)?;
33619 self.write(", ");
33620 self.generate_expression(&e.expression)?;
33621 self.write(")");
33622 Ok(())
33623 }
33624
33625 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
33626 self.write_keyword("SECURITY");
33628 self.write_space();
33629 self.generate_expression(&e.this)?;
33630 Ok(())
33631 }
33632
33633 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
33634 self.write("SEMANTIC_VIEW(");
33636
33637 if self.config.pretty {
33638 self.write_newline();
33640 self.indent_level += 1;
33641 self.write_indent();
33642 self.generate_expression(&e.this)?;
33643
33644 if let Some(metrics) = &e.metrics {
33645 self.write_newline();
33646 self.write_indent();
33647 self.write_keyword("METRICS");
33648 self.write_space();
33649 self.generate_semantic_view_tuple(metrics)?;
33650 }
33651 if let Some(dimensions) = &e.dimensions {
33652 self.write_newline();
33653 self.write_indent();
33654 self.write_keyword("DIMENSIONS");
33655 self.write_space();
33656 self.generate_semantic_view_tuple(dimensions)?;
33657 }
33658 if let Some(facts) = &e.facts {
33659 self.write_newline();
33660 self.write_indent();
33661 self.write_keyword("FACTS");
33662 self.write_space();
33663 self.generate_semantic_view_tuple(facts)?;
33664 }
33665 if let Some(where_) = &e.where_ {
33666 self.write_newline();
33667 self.write_indent();
33668 self.write_keyword("WHERE");
33669 self.write_space();
33670 self.generate_expression(where_)?;
33671 }
33672 self.write_newline();
33673 self.indent_level -= 1;
33674 self.write_indent();
33675 } else {
33676 self.generate_expression(&e.this)?;
33678 if let Some(metrics) = &e.metrics {
33679 self.write_space();
33680 self.write_keyword("METRICS");
33681 self.write_space();
33682 self.generate_semantic_view_tuple(metrics)?;
33683 }
33684 if let Some(dimensions) = &e.dimensions {
33685 self.write_space();
33686 self.write_keyword("DIMENSIONS");
33687 self.write_space();
33688 self.generate_semantic_view_tuple(dimensions)?;
33689 }
33690 if let Some(facts) = &e.facts {
33691 self.write_space();
33692 self.write_keyword("FACTS");
33693 self.write_space();
33694 self.generate_semantic_view_tuple(facts)?;
33695 }
33696 if let Some(where_) = &e.where_ {
33697 self.write_space();
33698 self.write_keyword("WHERE");
33699 self.write_space();
33700 self.generate_expression(where_)?;
33701 }
33702 }
33703 self.write(")");
33704 Ok(())
33705 }
33706
33707 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
33709 if let Expression::Tuple(t) = expr {
33710 for (i, e) in t.expressions.iter().enumerate() {
33711 if i > 0 {
33712 self.write(", ");
33713 }
33714 self.generate_expression(e)?;
33715 }
33716 } else {
33717 self.generate_expression(expr)?;
33718 }
33719 Ok(())
33720 }
33721
33722 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
33723 if let Some(start) = &e.start {
33725 self.write_keyword("START WITH");
33726 self.write_space();
33727 self.generate_expression(start)?;
33728 }
33729 if let Some(increment) = &e.increment {
33730 self.write_space();
33731 self.write_keyword("INCREMENT BY");
33732 self.write_space();
33733 self.generate_expression(increment)?;
33734 }
33735 if let Some(minvalue) = &e.minvalue {
33736 self.write_space();
33737 self.write_keyword("MINVALUE");
33738 self.write_space();
33739 self.generate_expression(minvalue)?;
33740 }
33741 if let Some(maxvalue) = &e.maxvalue {
33742 self.write_space();
33743 self.write_keyword("MAXVALUE");
33744 self.write_space();
33745 self.generate_expression(maxvalue)?;
33746 }
33747 if let Some(cache) = &e.cache {
33748 self.write_space();
33749 self.write_keyword("CACHE");
33750 self.write_space();
33751 self.generate_expression(cache)?;
33752 }
33753 if let Some(owned) = &e.owned {
33754 self.write_space();
33755 self.write_keyword("OWNED BY");
33756 self.write_space();
33757 self.generate_expression(owned)?;
33758 }
33759 for opt in &e.options {
33760 self.write_space();
33761 self.generate_expression(opt)?;
33762 }
33763 Ok(())
33764 }
33765
33766 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
33767 if e.with_.is_some() {
33769 self.write_keyword("WITH");
33770 self.write_space();
33771 }
33772 self.write_keyword("SERDEPROPERTIES");
33773 self.write(" (");
33774 for (i, expr) in e.expressions.iter().enumerate() {
33775 if i > 0 {
33776 self.write(", ");
33777 }
33778 match expr {
33780 Expression::Eq(eq) => {
33781 self.generate_expression(&eq.left)?;
33782 self.write("=");
33783 self.generate_expression(&eq.right)?;
33784 }
33785 _ => self.generate_expression(expr)?,
33786 }
33787 }
33788 self.write(")");
33789 Ok(())
33790 }
33791
33792 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
33793 self.write("@@");
33795 if let Some(kind) = &e.kind {
33796 self.write(kind);
33797 self.write(".");
33798 }
33799 self.generate_expression(&e.this)?;
33800 Ok(())
33801 }
33802
33803 fn generate_set(&mut self, e: &Set) -> Result<()> {
33804 if e.unset.is_some() {
33806 self.write_keyword("UNSET");
33807 } else {
33808 self.write_keyword("SET");
33809 }
33810 if e.tag.is_some() {
33811 self.write_space();
33812 self.write_keyword("TAG");
33813 }
33814 if !e.expressions.is_empty() {
33815 self.write_space();
33816 for (i, expr) in e.expressions.iter().enumerate() {
33817 if i > 0 {
33818 self.write(", ");
33819 }
33820 self.generate_expression(expr)?;
33821 }
33822 }
33823 Ok(())
33824 }
33825
33826 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
33827 self.write_keyword("SET");
33829 self.write_space();
33830 self.generate_expression(&e.this)?;
33831 Ok(())
33832 }
33833
33834 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
33835 if let Some(kind) = &e.kind {
33837 self.write_keyword(kind);
33838 self.write_space();
33839 }
33840 self.generate_expression(&e.name)?;
33841 self.write(" = ");
33842 self.generate_expression(&e.value)?;
33843 Ok(())
33844 }
33845
33846 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
33847 if let Some(with_) = &e.with_ {
33849 self.generate_expression(with_)?;
33850 self.write_space();
33851 }
33852 self.generate_expression(&e.this)?;
33853 self.write_space();
33854 if let Some(kind) = &e.kind {
33856 self.write_keyword(kind);
33857 }
33858 if e.distinct {
33859 self.write_space();
33860 self.write_keyword("DISTINCT");
33861 } else {
33862 self.write_space();
33863 self.write_keyword("ALL");
33864 }
33865 if e.by_name.is_some() {
33866 self.write_space();
33867 self.write_keyword("BY NAME");
33868 }
33869 self.write_space();
33870 self.generate_expression(&e.expression)?;
33871 Ok(())
33872 }
33873
33874 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
33875 if e.multi.is_some() {
33877 self.write_keyword("MULTISET");
33878 } else {
33879 self.write_keyword("SET");
33880 }
33881 Ok(())
33882 }
33883
33884 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
33885 self.write_keyword("SETTINGS");
33887 if self.config.pretty && e.expressions.len() > 1 {
33888 self.indent_level += 1;
33890 for (i, expr) in e.expressions.iter().enumerate() {
33891 if i > 0 {
33892 self.write(",");
33893 }
33894 self.write_newline();
33895 self.write_indent();
33896 self.generate_expression(expr)?;
33897 }
33898 self.indent_level -= 1;
33899 } else {
33900 self.write_space();
33901 for (i, expr) in e.expressions.iter().enumerate() {
33902 if i > 0 {
33903 self.write(", ");
33904 }
33905 self.generate_expression(expr)?;
33906 }
33907 }
33908 Ok(())
33909 }
33910
33911 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
33912 self.write_keyword("SHARING");
33914 if let Some(this) = &e.this {
33915 self.write(" = ");
33916 self.generate_expression(this)?;
33917 }
33918 Ok(())
33919 }
33920
33921 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
33922 if let Some(begin) = &e.this {
33924 self.generate_expression(begin)?;
33925 }
33926 self.write(":");
33927 if let Some(end) = &e.expression {
33928 self.generate_expression(end)?;
33929 }
33930 if let Some(step) = &e.step {
33931 self.write(":");
33932 self.generate_expression(step)?;
33933 }
33934 Ok(())
33935 }
33936
33937 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
33938 self.write_keyword("SORT_ARRAY");
33940 self.write("(");
33941 self.generate_expression(&e.this)?;
33942 if let Some(asc) = &e.asc {
33943 self.write(", ");
33944 self.generate_expression(asc)?;
33945 }
33946 self.write(")");
33947 Ok(())
33948 }
33949
33950 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
33951 self.write_keyword("SORT BY");
33953 self.write_space();
33954 for (i, expr) in e.expressions.iter().enumerate() {
33955 if i > 0 {
33956 self.write(", ");
33957 }
33958 self.generate_ordered(expr)?;
33959 }
33960 Ok(())
33961 }
33962
33963 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
33964 if e.compound.is_some() {
33966 self.write_keyword("COMPOUND");
33967 self.write_space();
33968 }
33969 self.write_keyword("SORTKEY");
33970 self.write("(");
33971 if let Expression::Tuple(t) = e.this.as_ref() {
33973 for (i, expr) in t.expressions.iter().enumerate() {
33974 if i > 0 {
33975 self.write(", ");
33976 }
33977 self.generate_expression(expr)?;
33978 }
33979 } else {
33980 self.generate_expression(&e.this)?;
33981 }
33982 self.write(")");
33983 Ok(())
33984 }
33985
33986 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
33987 self.write_keyword("SPLIT_PART");
33989 self.write("(");
33990 self.generate_expression(&e.this)?;
33991 if let Some(delimiter) = &e.delimiter {
33992 self.write(", ");
33993 self.generate_expression(delimiter)?;
33994 }
33995 if let Some(part_index) = &e.part_index {
33996 self.write(", ");
33997 self.generate_expression(part_index)?;
33998 }
33999 self.write(")");
34000 Ok(())
34001 }
34002
34003 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
34004 self.generate_expression(&e.this)?;
34006 Ok(())
34007 }
34008
34009 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
34010 self.write_keyword("SQL SECURITY");
34012 self.write_space();
34013 self.generate_expression(&e.this)?;
34014 Ok(())
34015 }
34016
34017 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
34018 self.write_keyword("ST_DISTANCE");
34020 self.write("(");
34021 self.generate_expression(&e.this)?;
34022 self.write(", ");
34023 self.generate_expression(&e.expression)?;
34024 if let Some(use_spheroid) = &e.use_spheroid {
34025 self.write(", ");
34026 self.generate_expression(use_spheroid)?;
34027 }
34028 self.write(")");
34029 Ok(())
34030 }
34031
34032 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
34033 self.write_keyword("ST_POINT");
34035 self.write("(");
34036 self.generate_expression(&e.this)?;
34037 self.write(", ");
34038 self.generate_expression(&e.expression)?;
34039 self.write(")");
34040 Ok(())
34041 }
34042
34043 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
34044 self.generate_expression(&e.this)?;
34046 Ok(())
34047 }
34048
34049 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
34050 self.write_keyword("STANDARD_HASH");
34052 self.write("(");
34053 self.generate_expression(&e.this)?;
34054 if let Some(expression) = &e.expression {
34055 self.write(", ");
34056 self.generate_expression(expression)?;
34057 }
34058 self.write(")");
34059 Ok(())
34060 }
34061
34062 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
34063 self.write_keyword("STORED BY");
34065 self.write_space();
34066 self.generate_expression(&e.this)?;
34067 Ok(())
34068 }
34069
34070 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
34071 use crate::dialects::DialectType;
34074 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
34075 self.write_keyword("CHARINDEX");
34077 self.write("(");
34078 if let Some(substr) = &e.substr {
34079 self.generate_expression(substr)?;
34080 self.write(", ");
34081 }
34082 self.generate_expression(&e.this)?;
34083 if let Some(position) = &e.position {
34084 self.write(", ");
34085 self.generate_expression(position)?;
34086 }
34087 self.write(")");
34088 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34089 self.write_keyword("POSITION");
34090 self.write("(");
34091 self.generate_expression(&e.this)?;
34092 if let Some(substr) = &e.substr {
34093 self.write(", ");
34094 self.generate_expression(substr)?;
34095 }
34096 if let Some(position) = &e.position {
34097 self.write(", ");
34098 self.generate_expression(position)?;
34099 }
34100 if let Some(occurrence) = &e.occurrence {
34101 self.write(", ");
34102 self.generate_expression(occurrence)?;
34103 }
34104 self.write(")");
34105 } else if matches!(
34106 self.config.dialect,
34107 Some(DialectType::SQLite)
34108 | Some(DialectType::Oracle)
34109 | Some(DialectType::BigQuery)
34110 | Some(DialectType::Teradata)
34111 ) {
34112 self.write_keyword("INSTR");
34113 self.write("(");
34114 self.generate_expression(&e.this)?;
34115 if let Some(substr) = &e.substr {
34116 self.write(", ");
34117 self.generate_expression(substr)?;
34118 }
34119 if let Some(position) = &e.position {
34120 self.write(", ");
34121 self.generate_expression(position)?;
34122 } else if e.occurrence.is_some() {
34123 self.write(", 1");
34126 }
34127 if let Some(occurrence) = &e.occurrence {
34128 self.write(", ");
34129 self.generate_expression(occurrence)?;
34130 }
34131 self.write(")");
34132 } else if matches!(
34133 self.config.dialect,
34134 Some(DialectType::MySQL)
34135 | Some(DialectType::SingleStore)
34136 | Some(DialectType::Doris)
34137 | Some(DialectType::StarRocks)
34138 | Some(DialectType::Hive)
34139 | Some(DialectType::Spark)
34140 | Some(DialectType::Databricks)
34141 ) {
34142 self.write_keyword("LOCATE");
34144 self.write("(");
34145 if let Some(substr) = &e.substr {
34146 self.generate_expression(substr)?;
34147 self.write(", ");
34148 }
34149 self.generate_expression(&e.this)?;
34150 if let Some(position) = &e.position {
34151 self.write(", ");
34152 self.generate_expression(position)?;
34153 }
34154 self.write(")");
34155 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
34156 self.write_keyword("CHARINDEX");
34158 self.write("(");
34159 if let Some(substr) = &e.substr {
34160 self.generate_expression(substr)?;
34161 self.write(", ");
34162 }
34163 self.generate_expression(&e.this)?;
34164 if let Some(position) = &e.position {
34165 self.write(", ");
34166 self.generate_expression(position)?;
34167 }
34168 self.write(")");
34169 } else if matches!(
34170 self.config.dialect,
34171 Some(DialectType::PostgreSQL)
34172 | Some(DialectType::Materialize)
34173 | Some(DialectType::RisingWave)
34174 | Some(DialectType::Redshift)
34175 ) {
34176 self.write_keyword("POSITION");
34178 self.write("(");
34179 if let Some(substr) = &e.substr {
34180 self.generate_expression(substr)?;
34181 self.write(" IN ");
34182 }
34183 self.generate_expression(&e.this)?;
34184 self.write(")");
34185 } else {
34186 self.write_keyword("STRPOS");
34187 self.write("(");
34188 self.generate_expression(&e.this)?;
34189 if let Some(substr) = &e.substr {
34190 self.write(", ");
34191 self.generate_expression(substr)?;
34192 }
34193 if let Some(position) = &e.position {
34194 self.write(", ");
34195 self.generate_expression(position)?;
34196 }
34197 if let Some(occurrence) = &e.occurrence {
34198 self.write(", ");
34199 self.generate_expression(occurrence)?;
34200 }
34201 self.write(")");
34202 }
34203 Ok(())
34204 }
34205
34206 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
34207 match self.config.dialect {
34208 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
34209 self.write_keyword("TO_DATE");
34211 self.write("(");
34212 self.generate_expression(&e.this)?;
34213 if let Some(format) = &e.format {
34214 self.write(", '");
34215 self.write(&Self::strftime_to_java_format(format));
34216 self.write("'");
34217 }
34218 self.write(")");
34219 }
34220 Some(DialectType::DuckDB) => {
34221 self.write_keyword("CAST");
34223 self.write("(");
34224 self.write_keyword("STRPTIME");
34225 self.write("(");
34226 self.generate_expression(&e.this)?;
34227 if let Some(format) = &e.format {
34228 self.write(", '");
34229 self.write(format);
34230 self.write("'");
34231 }
34232 self.write(")");
34233 self.write_keyword(" AS ");
34234 self.write_keyword("DATE");
34235 self.write(")");
34236 }
34237 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
34238 self.write_keyword("TO_DATE");
34240 self.write("(");
34241 self.generate_expression(&e.this)?;
34242 if let Some(format) = &e.format {
34243 self.write(", '");
34244 self.write(&Self::strftime_to_postgres_format(format));
34245 self.write("'");
34246 }
34247 self.write(")");
34248 }
34249 Some(DialectType::BigQuery) => {
34250 self.write_keyword("PARSE_DATE");
34252 self.write("(");
34253 if let Some(format) = &e.format {
34254 self.write("'");
34255 self.write(format);
34256 self.write("'");
34257 self.write(", ");
34258 }
34259 self.generate_expression(&e.this)?;
34260 self.write(")");
34261 }
34262 Some(DialectType::Teradata) => {
34263 self.write_keyword("CAST");
34265 self.write("(");
34266 self.generate_expression(&e.this)?;
34267 self.write_keyword(" AS ");
34268 self.write_keyword("DATE");
34269 if let Some(format) = &e.format {
34270 self.write_keyword(" FORMAT ");
34271 self.write("'");
34272 self.write(&Self::strftime_to_teradata_format(format));
34273 self.write("'");
34274 }
34275 self.write(")");
34276 }
34277 _ => {
34278 self.write_keyword("STR_TO_DATE");
34280 self.write("(");
34281 self.generate_expression(&e.this)?;
34282 if let Some(format) = &e.format {
34283 self.write(", '");
34284 self.write(format);
34285 self.write("'");
34286 }
34287 self.write(")");
34288 }
34289 }
34290 Ok(())
34291 }
34292
34293 fn strftime_to_teradata_format(fmt: &str) -> String {
34295 let mut result = String::with_capacity(fmt.len() * 2);
34296 let bytes = fmt.as_bytes();
34297 let len = bytes.len();
34298 let mut i = 0;
34299 while i < len {
34300 if bytes[i] == b'%' && i + 1 < len {
34301 let replacement = match bytes[i + 1] {
34302 b'Y' => "YYYY",
34303 b'y' => "YY",
34304 b'm' => "MM",
34305 b'B' => "MMMM",
34306 b'b' => "MMM",
34307 b'd' => "DD",
34308 b'j' => "DDD",
34309 b'H' => "HH",
34310 b'M' => "MI",
34311 b'S' => "SS",
34312 b'f' => "SSSSSS",
34313 b'A' => "EEEE",
34314 b'a' => "EEE",
34315 _ => {
34316 result.push('%');
34317 i += 1;
34318 continue;
34319 }
34320 };
34321 result.push_str(replacement);
34322 i += 2;
34323 } else {
34324 result.push(bytes[i] as char);
34325 i += 1;
34326 }
34327 }
34328 result
34329 }
34330
34331 pub fn strftime_to_java_format_static(fmt: &str) -> String {
34334 Self::strftime_to_java_format(fmt)
34335 }
34336
34337 fn strftime_to_java_format(fmt: &str) -> String {
34339 let mut result = String::with_capacity(fmt.len() * 2);
34340 let bytes = fmt.as_bytes();
34341 let len = bytes.len();
34342 let mut i = 0;
34343 while i < len {
34344 if bytes[i] == b'%' && i + 1 < len {
34345 if bytes[i + 1] == b'-' && i + 2 < len {
34347 let replacement = match bytes[i + 2] {
34348 b'd' => "d",
34349 b'm' => "M",
34350 b'H' => "H",
34351 b'M' => "m",
34352 b'S' => "s",
34353 _ => {
34354 result.push('%');
34355 i += 1;
34356 continue;
34357 }
34358 };
34359 result.push_str(replacement);
34360 i += 3;
34361 } else {
34362 let replacement = match bytes[i + 1] {
34363 b'Y' => "yyyy",
34364 b'y' => "yy",
34365 b'm' => "MM",
34366 b'B' => "MMMM",
34367 b'b' => "MMM",
34368 b'd' => "dd",
34369 b'j' => "DDD",
34370 b'H' => "HH",
34371 b'M' => "mm",
34372 b'S' => "ss",
34373 b'f' => "SSSSSS",
34374 b'A' => "EEEE",
34375 b'a' => "EEE",
34376 _ => {
34377 result.push('%');
34378 i += 1;
34379 continue;
34380 }
34381 };
34382 result.push_str(replacement);
34383 i += 2;
34384 }
34385 } else {
34386 result.push(bytes[i] as char);
34387 i += 1;
34388 }
34389 }
34390 result
34391 }
34392
34393 fn strftime_to_tsql_format(fmt: &str) -> String {
34396 let mut result = String::with_capacity(fmt.len() * 2);
34397 let bytes = fmt.as_bytes();
34398 let len = bytes.len();
34399 let mut i = 0;
34400 while i < len {
34401 if bytes[i] == b'%' && i + 1 < len {
34402 if bytes[i + 1] == b'-' && i + 2 < len {
34404 let replacement = match bytes[i + 2] {
34405 b'd' => "d",
34406 b'm' => "M",
34407 b'H' => "H",
34408 b'M' => "m",
34409 b'S' => "s",
34410 _ => {
34411 result.push('%');
34412 i += 1;
34413 continue;
34414 }
34415 };
34416 result.push_str(replacement);
34417 i += 3;
34418 } else {
34419 let replacement = match bytes[i + 1] {
34420 b'Y' => "yyyy",
34421 b'y' => "yy",
34422 b'm' => "MM",
34423 b'B' => "MMMM",
34424 b'b' => "MMM",
34425 b'd' => "dd",
34426 b'j' => "DDD",
34427 b'H' => "HH",
34428 b'M' => "mm",
34429 b'S' => "ss",
34430 b'f' => "ffffff",
34431 b'A' => "dddd",
34432 b'a' => "ddd",
34433 _ => {
34434 result.push('%');
34435 i += 1;
34436 continue;
34437 }
34438 };
34439 result.push_str(replacement);
34440 i += 2;
34441 }
34442 } else {
34443 result.push(bytes[i] as char);
34444 i += 1;
34445 }
34446 }
34447 result
34448 }
34449
34450 fn decompose_json_path(path: &str) -> Vec<String> {
34453 let mut parts = Vec::new();
34454 let path = if path.starts_with("$.") {
34456 &path[2..]
34457 } else if path.starts_with('$') {
34458 &path[1..]
34459 } else {
34460 path
34461 };
34462 if path.is_empty() {
34463 return parts;
34464 }
34465 let mut current = String::new();
34466 let chars: Vec<char> = path.chars().collect();
34467 let mut i = 0;
34468 while i < chars.len() {
34469 match chars[i] {
34470 '.' => {
34471 if !current.is_empty() {
34472 parts.push(current.clone());
34473 current.clear();
34474 }
34475 i += 1;
34476 }
34477 '[' => {
34478 if !current.is_empty() {
34479 parts.push(current.clone());
34480 current.clear();
34481 }
34482 i += 1;
34483 let mut bracket_content = String::new();
34485 while i < chars.len() && chars[i] != ']' {
34486 if chars[i] == '"' || chars[i] == '\'' {
34488 let quote = chars[i];
34489 i += 1;
34490 while i < chars.len() && chars[i] != quote {
34491 bracket_content.push(chars[i]);
34492 i += 1;
34493 }
34494 if i < chars.len() {
34495 i += 1;
34496 } } else {
34498 bracket_content.push(chars[i]);
34499 i += 1;
34500 }
34501 }
34502 if i < chars.len() {
34503 i += 1;
34504 } if bracket_content != "*" {
34507 parts.push(bracket_content);
34508 }
34509 }
34510 _ => {
34511 current.push(chars[i]);
34512 i += 1;
34513 }
34514 }
34515 }
34516 if !current.is_empty() {
34517 parts.push(current);
34518 }
34519 parts
34520 }
34521
34522 fn strftime_to_postgres_format(fmt: &str) -> String {
34524 let mut result = String::with_capacity(fmt.len() * 2);
34525 let bytes = fmt.as_bytes();
34526 let len = bytes.len();
34527 let mut i = 0;
34528 while i < len {
34529 if bytes[i] == b'%' && i + 1 < len {
34530 if bytes[i + 1] == b'-' && i + 2 < len {
34532 let replacement = match bytes[i + 2] {
34533 b'd' => "FMDD",
34534 b'm' => "FMMM",
34535 b'H' => "FMHH24",
34536 b'M' => "FMMI",
34537 b'S' => "FMSS",
34538 _ => {
34539 result.push('%');
34540 i += 1;
34541 continue;
34542 }
34543 };
34544 result.push_str(replacement);
34545 i += 3;
34546 } else {
34547 let replacement = match bytes[i + 1] {
34548 b'Y' => "YYYY",
34549 b'y' => "YY",
34550 b'm' => "MM",
34551 b'B' => "Month",
34552 b'b' => "Mon",
34553 b'd' => "DD",
34554 b'j' => "DDD",
34555 b'H' => "HH24",
34556 b'M' => "MI",
34557 b'S' => "SS",
34558 b'f' => "US",
34559 b'A' => "Day",
34560 b'a' => "Dy",
34561 _ => {
34562 result.push('%');
34563 i += 1;
34564 continue;
34565 }
34566 };
34567 result.push_str(replacement);
34568 i += 2;
34569 }
34570 } else {
34571 result.push(bytes[i] as char);
34572 i += 1;
34573 }
34574 }
34575 result
34576 }
34577
34578 fn strftime_to_snowflake_format(fmt: &str) -> String {
34580 let mut result = String::with_capacity(fmt.len() * 2);
34581 let bytes = fmt.as_bytes();
34582 let len = bytes.len();
34583 let mut i = 0;
34584 while i < len {
34585 if bytes[i] == b'%' && i + 1 < len {
34586 if bytes[i + 1] == b'-' && i + 2 < len {
34588 let replacement = match bytes[i + 2] {
34589 b'd' => "dd",
34590 b'm' => "mm",
34591 _ => {
34592 result.push('%');
34593 i += 1;
34594 continue;
34595 }
34596 };
34597 result.push_str(replacement);
34598 i += 3;
34599 } else {
34600 let replacement = match bytes[i + 1] {
34601 b'Y' => "yyyy",
34602 b'y' => "yy",
34603 b'm' => "mm",
34604 b'd' => "DD",
34605 b'H' => "hh24",
34606 b'M' => "mi",
34607 b'S' => "ss",
34608 b'f' => "ff",
34609 _ => {
34610 result.push('%');
34611 i += 1;
34612 continue;
34613 }
34614 };
34615 result.push_str(replacement);
34616 i += 2;
34617 }
34618 } else {
34619 result.push(bytes[i] as char);
34620 i += 1;
34621 }
34622 }
34623 result
34624 }
34625
34626 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
34627 self.write_keyword("STR_TO_MAP");
34629 self.write("(");
34630 self.generate_expression(&e.this)?;
34631 let needs_defaults = matches!(
34633 self.config.dialect,
34634 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
34635 );
34636 if let Some(pair_delim) = &e.pair_delim {
34637 self.write(", ");
34638 self.generate_expression(pair_delim)?;
34639 } else if needs_defaults {
34640 self.write(", ','");
34641 }
34642 if let Some(key_value_delim) = &e.key_value_delim {
34643 self.write(", ");
34644 self.generate_expression(key_value_delim)?;
34645 } else if needs_defaults {
34646 self.write(", ':'");
34647 }
34648 self.write(")");
34649 Ok(())
34650 }
34651
34652 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
34653 let is_strftime = e.format.contains('%');
34655 let to_strftime = |f: &str| -> String {
34657 if is_strftime {
34658 f.to_string()
34659 } else {
34660 Self::snowflake_format_to_strftime(f)
34661 }
34662 };
34663 let to_java = |f: &str| -> String {
34665 if is_strftime {
34666 Self::strftime_to_java_format(f)
34667 } else {
34668 Self::snowflake_format_to_spark(f)
34669 }
34670 };
34671 let to_pg = |f: &str| -> String {
34673 if is_strftime {
34674 Self::strftime_to_postgres_format(f)
34675 } else {
34676 Self::convert_strptime_to_postgres_format(f)
34677 }
34678 };
34679
34680 match self.config.dialect {
34681 Some(DialectType::Exasol) => {
34682 self.write_keyword("TO_DATE");
34683 self.write("(");
34684 self.generate_expression(&e.this)?;
34685 self.write(", '");
34686 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
34687 self.write("'");
34688 self.write(")");
34689 }
34690 Some(DialectType::BigQuery) => {
34691 let fmt = to_strftime(&e.format);
34693 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
34695 self.write_keyword("PARSE_TIMESTAMP");
34696 self.write("('");
34697 self.write(&fmt);
34698 self.write("', ");
34699 self.generate_expression(&e.this)?;
34700 self.write(")");
34701 }
34702 Some(DialectType::Hive) => {
34703 let java_fmt = to_java(&e.format);
34706 if java_fmt == "yyyy-MM-dd HH:mm:ss"
34707 || java_fmt == "yyyy-MM-dd"
34708 || e.format == "yyyy-MM-dd HH:mm:ss"
34709 || e.format == "yyyy-MM-dd"
34710 {
34711 self.write_keyword("CAST");
34712 self.write("(");
34713 self.generate_expression(&e.this)?;
34714 self.write(" ");
34715 self.write_keyword("AS TIMESTAMP");
34716 self.write(")");
34717 } else {
34718 self.write_keyword("CAST");
34720 self.write("(");
34721 self.write_keyword("FROM_UNIXTIME");
34722 self.write("(");
34723 self.write_keyword("UNIX_TIMESTAMP");
34724 self.write("(");
34725 self.generate_expression(&e.this)?;
34726 self.write(", '");
34727 self.write(&java_fmt);
34728 self.write("')");
34729 self.write(") ");
34730 self.write_keyword("AS TIMESTAMP");
34731 self.write(")");
34732 }
34733 }
34734 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
34735 let java_fmt = to_java(&e.format);
34737 self.write_keyword("TO_TIMESTAMP");
34738 self.write("(");
34739 self.generate_expression(&e.this)?;
34740 self.write(", '");
34741 self.write(&java_fmt);
34742 self.write("')");
34743 }
34744 Some(DialectType::MySQL) => {
34745 let mut fmt = to_strftime(&e.format);
34747 fmt = fmt.replace("%-d", "%e");
34749 fmt = fmt.replace("%-m", "%c");
34750 fmt = fmt.replace("%H:%M:%S", "%T");
34751 self.write_keyword("STR_TO_DATE");
34752 self.write("(");
34753 self.generate_expression(&e.this)?;
34754 self.write(", '");
34755 self.write(&fmt);
34756 self.write("')");
34757 }
34758 Some(DialectType::Drill) => {
34759 let java_fmt = to_java(&e.format);
34761 let java_fmt = java_fmt.replace('T', "''T''");
34763 self.write_keyword("TO_TIMESTAMP");
34764 self.write("(");
34765 self.generate_expression(&e.this)?;
34766 self.write(", '");
34767 self.write(&java_fmt);
34768 self.write("')");
34769 }
34770 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
34771 let mut fmt = to_strftime(&e.format);
34773 fmt = fmt.replace("%-d", "%e");
34775 fmt = fmt.replace("%-m", "%c");
34776 fmt = fmt.replace("%H:%M:%S", "%T");
34777 self.write_keyword("DATE_PARSE");
34778 self.write("(");
34779 self.generate_expression(&e.this)?;
34780 self.write(", '");
34781 self.write(&fmt);
34782 self.write("')");
34783 }
34784 Some(DialectType::DuckDB) => {
34785 let fmt = to_strftime(&e.format);
34787 self.write_keyword("STRPTIME");
34788 self.write("(");
34789 self.generate_expression(&e.this)?;
34790 self.write(", '");
34791 self.write(&fmt);
34792 self.write("')");
34793 }
34794 Some(DialectType::PostgreSQL)
34795 | Some(DialectType::Redshift)
34796 | Some(DialectType::Materialize) => {
34797 let pg_fmt = to_pg(&e.format);
34799 self.write_keyword("TO_TIMESTAMP");
34800 self.write("(");
34801 self.generate_expression(&e.this)?;
34802 self.write(", '");
34803 self.write(&pg_fmt);
34804 self.write("')");
34805 }
34806 Some(DialectType::Oracle) => {
34807 let pg_fmt = to_pg(&e.format);
34809 self.write_keyword("TO_TIMESTAMP");
34810 self.write("(");
34811 self.generate_expression(&e.this)?;
34812 self.write(", '");
34813 self.write(&pg_fmt);
34814 self.write("')");
34815 }
34816 Some(DialectType::Snowflake) => {
34817 self.write_keyword("TO_TIMESTAMP");
34819 self.write("(");
34820 self.generate_expression(&e.this)?;
34821 self.write(", '");
34822 self.write(&e.format);
34823 self.write("')");
34824 }
34825 _ => {
34826 self.write_keyword("STR_TO_TIME");
34828 self.write("(");
34829 self.generate_expression(&e.this)?;
34830 self.write(", '");
34831 self.write(&e.format);
34832 self.write("'");
34833 self.write(")");
34834 }
34835 }
34836 Ok(())
34837 }
34838
34839 fn snowflake_format_to_strftime(format: &str) -> String {
34841 let mut result = String::new();
34842 let chars: Vec<char> = format.chars().collect();
34843 let mut i = 0;
34844 while i < chars.len() {
34845 let remaining = &format[i..];
34846 if remaining.starts_with("yyyy") {
34847 result.push_str("%Y");
34848 i += 4;
34849 } else if remaining.starts_with("yy") {
34850 result.push_str("%y");
34851 i += 2;
34852 } else if remaining.starts_with("mmmm") {
34853 result.push_str("%B"); i += 4;
34855 } else if remaining.starts_with("mon") {
34856 result.push_str("%b"); i += 3;
34858 } else if remaining.starts_with("mm") {
34859 result.push_str("%m");
34860 i += 2;
34861 } else if remaining.starts_with("DD") {
34862 result.push_str("%d");
34863 i += 2;
34864 } else if remaining.starts_with("dy") {
34865 result.push_str("%a"); i += 2;
34867 } else if remaining.starts_with("hh24") {
34868 result.push_str("%H");
34869 i += 4;
34870 } else if remaining.starts_with("hh12") {
34871 result.push_str("%I");
34872 i += 4;
34873 } else if remaining.starts_with("hh") {
34874 result.push_str("%H");
34875 i += 2;
34876 } else if remaining.starts_with("mi") {
34877 result.push_str("%M");
34878 i += 2;
34879 } else if remaining.starts_with("ss") {
34880 result.push_str("%S");
34881 i += 2;
34882 } else if remaining.starts_with("ff") {
34883 result.push_str("%f");
34885 i += 2;
34886 while i < chars.len() && chars[i].is_ascii_digit() {
34888 i += 1;
34889 }
34890 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
34891 result.push_str("%p");
34892 i += 2;
34893 } else if remaining.starts_with("tz") {
34894 result.push_str("%Z");
34895 i += 2;
34896 } else {
34897 result.push(chars[i]);
34898 i += 1;
34899 }
34900 }
34901 result
34902 }
34903
34904 fn snowflake_format_to_spark(format: &str) -> String {
34906 let mut result = String::new();
34907 let chars: Vec<char> = format.chars().collect();
34908 let mut i = 0;
34909 while i < chars.len() {
34910 let remaining = &format[i..];
34911 if remaining.starts_with("yyyy") {
34912 result.push_str("yyyy");
34913 i += 4;
34914 } else if remaining.starts_with("yy") {
34915 result.push_str("yy");
34916 i += 2;
34917 } else if remaining.starts_with("mmmm") {
34918 result.push_str("MMMM"); i += 4;
34920 } else if remaining.starts_with("mon") {
34921 result.push_str("MMM"); i += 3;
34923 } else if remaining.starts_with("mm") {
34924 result.push_str("MM");
34925 i += 2;
34926 } else if remaining.starts_with("DD") {
34927 result.push_str("dd");
34928 i += 2;
34929 } else if remaining.starts_with("dy") {
34930 result.push_str("EEE"); i += 2;
34932 } else if remaining.starts_with("hh24") {
34933 result.push_str("HH");
34934 i += 4;
34935 } else if remaining.starts_with("hh12") {
34936 result.push_str("hh");
34937 i += 4;
34938 } else if remaining.starts_with("hh") {
34939 result.push_str("HH");
34940 i += 2;
34941 } else if remaining.starts_with("mi") {
34942 result.push_str("mm");
34943 i += 2;
34944 } else if remaining.starts_with("ss") {
34945 result.push_str("ss");
34946 i += 2;
34947 } else if remaining.starts_with("ff") {
34948 result.push_str("SSS"); i += 2;
34950 while i < chars.len() && chars[i].is_ascii_digit() {
34952 i += 1;
34953 }
34954 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
34955 result.push_str("a");
34956 i += 2;
34957 } else if remaining.starts_with("tz") {
34958 result.push_str("z");
34959 i += 2;
34960 } else {
34961 result.push(chars[i]);
34962 i += 1;
34963 }
34964 }
34965 result
34966 }
34967
34968 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
34969 match self.config.dialect {
34970 Some(DialectType::DuckDB) => {
34971 self.write_keyword("EPOCH");
34973 self.write("(");
34974 self.write_keyword("STRPTIME");
34975 self.write("(");
34976 if let Some(this) = &e.this {
34977 self.generate_expression(this)?;
34978 }
34979 if let Some(format) = &e.format {
34980 self.write(", '");
34981 self.write(format);
34982 self.write("'");
34983 }
34984 self.write("))");
34985 }
34986 Some(DialectType::Hive) => {
34987 self.write_keyword("UNIX_TIMESTAMP");
34989 self.write("(");
34990 if let Some(this) = &e.this {
34991 self.generate_expression(this)?;
34992 }
34993 if let Some(format) = &e.format {
34994 let java_fmt = Self::strftime_to_java_format(format);
34995 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
34996 self.write(", '");
34997 self.write(&java_fmt);
34998 self.write("'");
34999 }
35000 }
35001 self.write(")");
35002 }
35003 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35004 self.write_keyword("UNIX_TIMESTAMP");
35006 self.write("(");
35007 if let Some(this) = &e.this {
35008 self.generate_expression(this)?;
35009 }
35010 if let Some(format) = &e.format {
35011 self.write(", '");
35012 self.write(format);
35013 self.write("'");
35014 }
35015 self.write(")");
35016 }
35017 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35018 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
35021 let java_fmt = Self::strftime_to_java_format(c_fmt);
35022 self.write_keyword("TO_UNIXTIME");
35023 self.write("(");
35024 self.write_keyword("COALESCE");
35025 self.write("(");
35026 self.write_keyword("TRY");
35027 self.write("(");
35028 self.write_keyword("DATE_PARSE");
35029 self.write("(");
35030 self.write_keyword("CAST");
35031 self.write("(");
35032 if let Some(this) = &e.this {
35033 self.generate_expression(this)?;
35034 }
35035 self.write(" ");
35036 self.write_keyword("AS VARCHAR");
35037 self.write("), '");
35038 self.write(c_fmt);
35039 self.write("')), ");
35040 self.write_keyword("PARSE_DATETIME");
35041 self.write("(");
35042 self.write_keyword("DATE_FORMAT");
35043 self.write("(");
35044 self.write_keyword("CAST");
35045 self.write("(");
35046 if let Some(this) = &e.this {
35047 self.generate_expression(this)?;
35048 }
35049 self.write(" ");
35050 self.write_keyword("AS TIMESTAMP");
35051 self.write("), '");
35052 self.write(c_fmt);
35053 self.write("'), '");
35054 self.write(&java_fmt);
35055 self.write("')))");
35056 }
35057 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35058 self.write_keyword("UNIX_TIMESTAMP");
35060 self.write("(");
35061 if let Some(this) = &e.this {
35062 self.generate_expression(this)?;
35063 }
35064 if let Some(format) = &e.format {
35065 let java_fmt = Self::strftime_to_java_format(format);
35066 self.write(", '");
35067 self.write(&java_fmt);
35068 self.write("'");
35069 }
35070 self.write(")");
35071 }
35072 _ => {
35073 self.write_keyword("STR_TO_UNIX");
35075 self.write("(");
35076 if let Some(this) = &e.this {
35077 self.generate_expression(this)?;
35078 }
35079 if let Some(format) = &e.format {
35080 self.write(", '");
35081 self.write(format);
35082 self.write("'");
35083 }
35084 self.write(")");
35085 }
35086 }
35087 Ok(())
35088 }
35089
35090 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
35091 self.write_keyword("STRING_TO_ARRAY");
35093 self.write("(");
35094 self.generate_expression(&e.this)?;
35095 if let Some(expression) = &e.expression {
35096 self.write(", ");
35097 self.generate_expression(expression)?;
35098 }
35099 if let Some(null_val) = &e.null {
35100 self.write(", ");
35101 self.generate_expression(null_val)?;
35102 }
35103 self.write(")");
35104 Ok(())
35105 }
35106
35107 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
35108 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35109 self.write_keyword("OBJECT_CONSTRUCT");
35111 self.write("(");
35112 for (i, (name, expr)) in e.fields.iter().enumerate() {
35113 if i > 0 {
35114 self.write(", ");
35115 }
35116 if let Some(name) = name {
35117 self.write("'");
35118 self.write(name);
35119 self.write("'");
35120 self.write(", ");
35121 } else {
35122 self.write("'_");
35123 self.write(&i.to_string());
35124 self.write("'");
35125 self.write(", ");
35126 }
35127 self.generate_expression(expr)?;
35128 }
35129 self.write(")");
35130 } else if self.config.struct_curly_brace_notation {
35131 self.write("{");
35133 for (i, (name, expr)) in e.fields.iter().enumerate() {
35134 if i > 0 {
35135 self.write(", ");
35136 }
35137 if let Some(name) = name {
35138 self.write("'");
35140 self.write(name);
35141 self.write("'");
35142 self.write(": ");
35143 } else {
35144 self.write("'_");
35146 self.write(&i.to_string());
35147 self.write("'");
35148 self.write(": ");
35149 }
35150 self.generate_expression(expr)?;
35151 }
35152 self.write("}");
35153 } else {
35154 let value_as_name = matches!(
35158 self.config.dialect,
35159 Some(DialectType::BigQuery)
35160 | Some(DialectType::Spark)
35161 | Some(DialectType::Databricks)
35162 | Some(DialectType::Hive)
35163 );
35164 self.write_keyword("STRUCT");
35165 self.write("(");
35166 for (i, (name, expr)) in e.fields.iter().enumerate() {
35167 if i > 0 {
35168 self.write(", ");
35169 }
35170 if let Some(name) = name {
35171 if value_as_name {
35172 self.generate_expression(expr)?;
35174 self.write_space();
35175 self.write_keyword("AS");
35176 self.write_space();
35177 let needs_quoting = name.contains(' ') || name.contains('-');
35179 if needs_quoting {
35180 if matches!(
35181 self.config.dialect,
35182 Some(DialectType::Spark)
35183 | Some(DialectType::Databricks)
35184 | Some(DialectType::Hive)
35185 ) {
35186 self.write("`");
35187 self.write(name);
35188 self.write("`");
35189 } else {
35190 self.write(name);
35191 }
35192 } else {
35193 self.write(name);
35194 }
35195 } else {
35196 self.write(name);
35198 self.write_space();
35199 self.write_keyword("AS");
35200 self.write_space();
35201 self.generate_expression(expr)?;
35202 }
35203 } else {
35204 self.generate_expression(expr)?;
35205 }
35206 }
35207 self.write(")");
35208 }
35209 Ok(())
35210 }
35211
35212 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
35213 self.write_keyword("STUFF");
35215 self.write("(");
35216 self.generate_expression(&e.this)?;
35217 if let Some(start) = &e.start {
35218 self.write(", ");
35219 self.generate_expression(start)?;
35220 }
35221 if let Some(length) = e.length {
35222 self.write(", ");
35223 self.write(&length.to_string());
35224 }
35225 self.write(", ");
35226 self.generate_expression(&e.expression)?;
35227 self.write(")");
35228 Ok(())
35229 }
35230
35231 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
35232 self.write_keyword("SUBSTRING_INDEX");
35234 self.write("(");
35235 self.generate_expression(&e.this)?;
35236 if let Some(delimiter) = &e.delimiter {
35237 self.write(", ");
35238 self.generate_expression(delimiter)?;
35239 }
35240 if let Some(count) = &e.count {
35241 self.write(", ");
35242 self.generate_expression(count)?;
35243 }
35244 self.write(")");
35245 Ok(())
35246 }
35247
35248 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
35249 self.write_keyword("SUMMARIZE");
35251 if e.table.is_some() {
35252 self.write_space();
35253 self.write_keyword("TABLE");
35254 }
35255 self.write_space();
35256 self.generate_expression(&e.this)?;
35257 Ok(())
35258 }
35259
35260 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
35261 self.write_keyword("SYSTIMESTAMP");
35263 Ok(())
35264 }
35265
35266 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
35267 if let Some(this) = &e.this {
35269 self.generate_expression(this)?;
35270 }
35271 if !e.columns.is_empty() {
35272 self.write("(");
35273 for (i, col) in e.columns.iter().enumerate() {
35274 if i > 0 {
35275 self.write(", ");
35276 }
35277 self.generate_expression(col)?;
35278 }
35279 self.write(")");
35280 }
35281 Ok(())
35282 }
35283
35284 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
35285 self.write_keyword("TABLE");
35287 self.write("(");
35288 self.generate_expression(&e.this)?;
35289 self.write(")");
35290 if let Some(alias) = &e.alias {
35291 self.write_space();
35292 self.write_keyword("AS");
35293 self.write_space();
35294 self.write(alias);
35295 }
35296 Ok(())
35297 }
35298
35299 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
35300 self.write_keyword("ROWS FROM");
35302 self.write(" (");
35303 for (i, expr) in e.expressions.iter().enumerate() {
35304 if i > 0 {
35305 self.write(", ");
35306 }
35307 match expr {
35311 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
35312 self.generate_expression(&tuple.expressions[0])?;
35314 self.write_space();
35315 self.write_keyword("AS");
35316 self.write_space();
35317 self.generate_expression(&tuple.expressions[1])?;
35318 }
35319 _ => {
35320 self.generate_expression(expr)?;
35321 }
35322 }
35323 }
35324 self.write(")");
35325 if e.ordinality {
35326 self.write_space();
35327 self.write_keyword("WITH ORDINALITY");
35328 }
35329 if let Some(alias) = &e.alias {
35330 self.write_space();
35331 self.write_keyword("AS");
35332 self.write_space();
35333 self.generate_expression(alias)?;
35334 }
35335 Ok(())
35336 }
35337
35338 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
35339 use crate::dialects::DialectType;
35340
35341 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
35343 if self.config.alias_post_tablesample {
35345 if let Expression::Subquery(ref s) = **this {
35347 if let Some(ref alias) = s.alias {
35348 let mut subquery_no_alias = (**s).clone();
35350 subquery_no_alias.alias = None;
35351 subquery_no_alias.column_aliases = Vec::new();
35352 self.generate_expression(&Expression::Subquery(Box::new(
35353 subquery_no_alias,
35354 )))?;
35355 self.write_space();
35356 self.write_keyword("TABLESAMPLE");
35357 self.generate_sample_body(sample)?;
35358 if let Some(ref seed) = sample.seed {
35359 self.write_space();
35360 let use_seed = sample.use_seed_keyword
35361 && !matches!(
35362 self.config.dialect,
35363 Some(crate::dialects::DialectType::Databricks)
35364 | Some(crate::dialects::DialectType::Spark)
35365 );
35366 if use_seed {
35367 self.write_keyword("SEED");
35368 } else {
35369 self.write_keyword("REPEATABLE");
35370 }
35371 self.write(" (");
35372 self.generate_expression(seed)?;
35373 self.write(")");
35374 }
35375 self.write_space();
35376 self.write_keyword("AS");
35377 self.write_space();
35378 self.generate_identifier(alias)?;
35379 return Ok(());
35380 }
35381 } else if let Expression::Alias(ref a) = **this {
35382 self.generate_expression(&a.this)?;
35384 self.write_space();
35385 self.write_keyword("TABLESAMPLE");
35386 self.generate_sample_body(sample)?;
35387 if let Some(ref seed) = sample.seed {
35388 self.write_space();
35389 let use_seed = sample.use_seed_keyword
35390 && !matches!(
35391 self.config.dialect,
35392 Some(crate::dialects::DialectType::Databricks)
35393 | Some(crate::dialects::DialectType::Spark)
35394 );
35395 if use_seed {
35396 self.write_keyword("SEED");
35397 } else {
35398 self.write_keyword("REPEATABLE");
35399 }
35400 self.write(" (");
35401 self.generate_expression(seed)?;
35402 self.write(")");
35403 }
35404 self.write_space();
35406 self.write_keyword("AS");
35407 self.write_space();
35408 self.generate_identifier(&a.alias)?;
35409 return Ok(());
35410 }
35411 }
35412 self.generate_expression(this)?;
35414 self.write_space();
35415 self.write_keyword("TABLESAMPLE");
35416 self.generate_sample_body(sample)?;
35417 if let Some(ref seed) = sample.seed {
35419 self.write_space();
35420 let use_seed = sample.use_seed_keyword
35422 && !matches!(
35423 self.config.dialect,
35424 Some(crate::dialects::DialectType::Databricks)
35425 | Some(crate::dialects::DialectType::Spark)
35426 );
35427 if use_seed {
35428 self.write_keyword("SEED");
35429 } else {
35430 self.write_keyword("REPEATABLE");
35431 }
35432 self.write(" (");
35433 self.generate_expression(seed)?;
35434 self.write(")");
35435 }
35436 return Ok(());
35437 }
35438
35439 self.write_keyword("TABLESAMPLE");
35441 if let Some(method) = &e.method {
35442 self.write_space();
35443 self.write_keyword(method);
35444 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35445 self.write_space();
35447 self.write_keyword("BERNOULLI");
35448 }
35449 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
35450 self.write_space();
35451 self.write_keyword("BUCKET");
35452 self.write_space();
35453 self.generate_expression(numerator)?;
35454 self.write_space();
35455 self.write_keyword("OUT OF");
35456 self.write_space();
35457 self.generate_expression(denominator)?;
35458 if let Some(field) = &e.bucket_field {
35459 self.write_space();
35460 self.write_keyword("ON");
35461 self.write_space();
35462 self.generate_expression(field)?;
35463 }
35464 } else if !e.expressions.is_empty() {
35465 self.write(" (");
35466 for (i, expr) in e.expressions.iter().enumerate() {
35467 if i > 0 {
35468 self.write(", ");
35469 }
35470 self.generate_expression(expr)?;
35471 }
35472 self.write(")");
35473 } else if let Some(percent) = &e.percent {
35474 self.write(" (");
35475 self.generate_expression(percent)?;
35476 self.write_space();
35477 self.write_keyword("PERCENT");
35478 self.write(")");
35479 }
35480 Ok(())
35481 }
35482
35483 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
35484 if let Some(prefix) = &e.prefix {
35486 self.generate_expression(prefix)?;
35487 }
35488 if let Some(this) = &e.this {
35489 self.generate_expression(this)?;
35490 }
35491 if let Some(postfix) = &e.postfix {
35492 self.generate_expression(postfix)?;
35493 }
35494 Ok(())
35495 }
35496
35497 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
35498 self.write_keyword("TAG");
35500 self.write(" (");
35501 for (i, expr) in e.expressions.iter().enumerate() {
35502 if i > 0 {
35503 self.write(", ");
35504 }
35505 self.generate_expression(expr)?;
35506 }
35507 self.write(")");
35508 Ok(())
35509 }
35510
35511 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
35512 if let Some(this) = &e.this {
35514 self.generate_expression(this)?;
35515 self.write_space();
35516 }
35517 self.write_keyword("TEMPORARY");
35518 Ok(())
35519 }
35520
35521 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
35524 self.write_keyword("TIME");
35526 self.write("(");
35527 self.generate_expression(&e.this)?;
35528 self.write(")");
35529 Ok(())
35530 }
35531
35532 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
35533 self.write_keyword("TIME_ADD");
35535 self.write("(");
35536 self.generate_expression(&e.this)?;
35537 self.write(", ");
35538 self.generate_expression(&e.expression)?;
35539 if let Some(unit) = &e.unit {
35540 self.write(", ");
35541 self.write_keyword(unit);
35542 }
35543 self.write(")");
35544 Ok(())
35545 }
35546
35547 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
35548 self.write_keyword("TIME_DIFF");
35550 self.write("(");
35551 self.generate_expression(&e.this)?;
35552 self.write(", ");
35553 self.generate_expression(&e.expression)?;
35554 if let Some(unit) = &e.unit {
35555 self.write(", ");
35556 self.write_keyword(unit);
35557 }
35558 self.write(")");
35559 Ok(())
35560 }
35561
35562 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
35563 self.write_keyword("TIME_FROM_PARTS");
35565 self.write("(");
35566 let mut first = true;
35567 if let Some(hour) = &e.hour {
35568 self.generate_expression(hour)?;
35569 first = false;
35570 }
35571 if let Some(minute) = &e.min {
35572 if !first {
35573 self.write(", ");
35574 }
35575 self.generate_expression(minute)?;
35576 first = false;
35577 }
35578 if let Some(second) = &e.sec {
35579 if !first {
35580 self.write(", ");
35581 }
35582 self.generate_expression(second)?;
35583 first = false;
35584 }
35585 if let Some(ns) = &e.nano {
35586 if !first {
35587 self.write(", ");
35588 }
35589 self.generate_expression(ns)?;
35590 }
35591 self.write(")");
35592 Ok(())
35593 }
35594
35595 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
35596 self.write_keyword("TIME_SLICE");
35598 self.write("(");
35599 self.generate_expression(&e.this)?;
35600 self.write(", ");
35601 self.generate_expression(&e.expression)?;
35602 self.write(", ");
35603 self.write_keyword(&e.unit);
35604 self.write(")");
35605 Ok(())
35606 }
35607
35608 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
35609 self.write_keyword("TIME_STR_TO_TIME");
35611 self.write("(");
35612 self.generate_expression(&e.this)?;
35613 self.write(")");
35614 Ok(())
35615 }
35616
35617 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
35618 self.write_keyword("TIME_SUB");
35620 self.write("(");
35621 self.generate_expression(&e.this)?;
35622 self.write(", ");
35623 self.generate_expression(&e.expression)?;
35624 if let Some(unit) = &e.unit {
35625 self.write(", ");
35626 self.write_keyword(unit);
35627 }
35628 self.write(")");
35629 Ok(())
35630 }
35631
35632 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
35633 match self.config.dialect {
35634 Some(DialectType::Exasol) => {
35635 self.write_keyword("TO_CHAR");
35637 self.write("(");
35638 self.generate_expression(&e.this)?;
35639 self.write(", '");
35640 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
35641 self.write("'");
35642 self.write(")");
35643 }
35644 Some(DialectType::PostgreSQL)
35645 | Some(DialectType::Redshift)
35646 | Some(DialectType::Materialize) => {
35647 self.write_keyword("TO_CHAR");
35649 self.write("(");
35650 self.generate_expression(&e.this)?;
35651 self.write(", '");
35652 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
35653 self.write("'");
35654 self.write(")");
35655 }
35656 Some(DialectType::Oracle) => {
35657 self.write_keyword("TO_CHAR");
35659 self.write("(");
35660 self.generate_expression(&e.this)?;
35661 self.write(", '");
35662 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
35663 self.write("'");
35664 self.write(")");
35665 }
35666 Some(DialectType::Drill) => {
35667 self.write_keyword("TO_CHAR");
35669 self.write("(");
35670 self.generate_expression(&e.this)?;
35671 self.write(", '");
35672 self.write(&Self::strftime_to_java_format(&e.format));
35673 self.write("'");
35674 self.write(")");
35675 }
35676 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
35677 self.write_keyword("FORMAT");
35679 self.write("(");
35680 self.generate_expression(&e.this)?;
35681 self.write(", '");
35682 self.write(&Self::strftime_to_tsql_format(&e.format));
35683 self.write("'");
35684 self.write(")");
35685 }
35686 Some(DialectType::DuckDB) => {
35687 self.write_keyword("STRFTIME");
35689 self.write("(");
35690 self.generate_expression(&e.this)?;
35691 self.write(", '");
35692 self.write(&e.format);
35693 self.write("'");
35694 self.write(")");
35695 }
35696 Some(DialectType::BigQuery) => {
35697 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
35700 self.write_keyword("FORMAT_DATE");
35701 self.write("('");
35702 self.write(&fmt);
35703 self.write("', ");
35704 self.generate_expression(&e.this)?;
35705 self.write(")");
35706 }
35707 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35708 self.write_keyword("DATE_FORMAT");
35710 self.write("(");
35711 self.generate_expression(&e.this)?;
35712 self.write(", '");
35713 self.write(&Self::strftime_to_java_format(&e.format));
35714 self.write("'");
35715 self.write(")");
35716 }
35717 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
35718 self.write_keyword("DATE_FORMAT");
35720 self.write("(");
35721 self.generate_expression(&e.this)?;
35722 self.write(", '");
35723 self.write(&e.format);
35724 self.write("'");
35725 self.write(")");
35726 }
35727 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35728 self.write_keyword("DATE_FORMAT");
35730 self.write("(");
35731 self.generate_expression(&e.this)?;
35732 self.write(", '");
35733 self.write(&e.format);
35734 self.write("'");
35735 self.write(")");
35736 }
35737 _ => {
35738 self.write_keyword("TIME_TO_STR");
35740 self.write("(");
35741 self.generate_expression(&e.this)?;
35742 self.write(", '");
35743 self.write(&e.format);
35744 self.write("'");
35745 self.write(")");
35746 }
35747 }
35748 Ok(())
35749 }
35750
35751 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
35752 match self.config.dialect {
35753 Some(DialectType::DuckDB) => {
35754 self.write_keyword("EPOCH");
35756 self.write("(");
35757 self.generate_expression(&e.this)?;
35758 self.write(")");
35759 }
35760 Some(DialectType::Hive)
35761 | Some(DialectType::Spark)
35762 | Some(DialectType::Databricks)
35763 | Some(DialectType::Doris)
35764 | Some(DialectType::StarRocks)
35765 | Some(DialectType::Drill) => {
35766 self.write_keyword("UNIX_TIMESTAMP");
35768 self.write("(");
35769 self.generate_expression(&e.this)?;
35770 self.write(")");
35771 }
35772 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35773 self.write_keyword("TO_UNIXTIME");
35775 self.write("(");
35776 self.generate_expression(&e.this)?;
35777 self.write(")");
35778 }
35779 _ => {
35780 self.write_keyword("TIME_TO_UNIX");
35782 self.write("(");
35783 self.generate_expression(&e.this)?;
35784 self.write(")");
35785 }
35786 }
35787 Ok(())
35788 }
35789
35790 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
35791 match self.config.dialect {
35792 Some(DialectType::Hive) => {
35793 self.write_keyword("TO_DATE");
35795 self.write("(");
35796 self.generate_expression(&e.this)?;
35797 self.write(")");
35798 }
35799 _ => {
35800 self.write_keyword("TIME_STR_TO_DATE");
35802 self.write("(");
35803 self.generate_expression(&e.this)?;
35804 self.write(")");
35805 }
35806 }
35807 Ok(())
35808 }
35809
35810 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
35811 self.write_keyword("TIME_TRUNC");
35813 self.write("(");
35814 self.generate_expression(&e.this)?;
35815 self.write(", ");
35816 self.write_keyword(&e.unit);
35817 self.write(")");
35818 Ok(())
35819 }
35820
35821 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
35822 if let Some(unit) = &e.unit {
35824 self.write_keyword(unit);
35825 }
35826 Ok(())
35827 }
35828
35829 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
35833 use crate::dialects::DialectType;
35834 use crate::expressions::Literal;
35835
35836 match self.config.dialect {
35837 Some(DialectType::Exasol) => {
35839 self.write_keyword("TO_TIMESTAMP");
35840 self.write("(");
35841 if let Some(this) = &e.this {
35843 match this.as_ref() {
35844 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
35845 let Literal::String(s) = lit.as_ref() else {
35846 unreachable!()
35847 };
35848 self.write("'");
35849 self.write(s);
35850 self.write("'");
35851 }
35852 _ => {
35853 self.generate_expression(this)?;
35854 }
35855 }
35856 }
35857 self.write(")");
35858 }
35859 _ => {
35861 self.write_keyword("TIMESTAMP");
35862 self.write("(");
35863 if let Some(this) = &e.this {
35864 self.generate_expression(this)?;
35865 }
35866 if let Some(zone) = &e.zone {
35867 self.write(", ");
35868 self.generate_expression(zone)?;
35869 }
35870 self.write(")");
35871 }
35872 }
35873 Ok(())
35874 }
35875
35876 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
35877 self.write_keyword("TIMESTAMP_ADD");
35879 self.write("(");
35880 self.generate_expression(&e.this)?;
35881 self.write(", ");
35882 self.generate_expression(&e.expression)?;
35883 if let Some(unit) = &e.unit {
35884 self.write(", ");
35885 self.write_keyword(unit);
35886 }
35887 self.write(")");
35888 Ok(())
35889 }
35890
35891 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
35892 self.write_keyword("TIMESTAMP_DIFF");
35894 self.write("(");
35895 self.generate_expression(&e.this)?;
35896 self.write(", ");
35897 self.generate_expression(&e.expression)?;
35898 if let Some(unit) = &e.unit {
35899 self.write(", ");
35900 self.write_keyword(unit);
35901 }
35902 self.write(")");
35903 Ok(())
35904 }
35905
35906 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
35907 self.write_keyword("TIMESTAMP_FROM_PARTS");
35909 self.write("(");
35910 if let Some(this) = &e.this {
35911 self.generate_expression(this)?;
35912 }
35913 if let Some(expression) = &e.expression {
35914 self.write(", ");
35915 self.generate_expression(expression)?;
35916 }
35917 if let Some(zone) = &e.zone {
35918 self.write(", ");
35919 self.generate_expression(zone)?;
35920 }
35921 if let Some(milli) = &e.milli {
35922 self.write(", ");
35923 self.generate_expression(milli)?;
35924 }
35925 self.write(")");
35926 Ok(())
35927 }
35928
35929 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
35930 self.write_keyword("TIMESTAMP_SUB");
35932 self.write("(");
35933 self.generate_expression(&e.this)?;
35934 self.write(", ");
35935 self.write_keyword("INTERVAL");
35936 self.write_space();
35937 self.generate_expression(&e.expression)?;
35938 if let Some(unit) = &e.unit {
35939 self.write_space();
35940 self.write_keyword(unit);
35941 }
35942 self.write(")");
35943 Ok(())
35944 }
35945
35946 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
35947 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
35949 self.write("(");
35950 if let Some(zone) = &e.zone {
35951 self.generate_expression(zone)?;
35952 }
35953 self.write(")");
35954 Ok(())
35955 }
35956
35957 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
35958 self.write_keyword("TO_BINARY");
35960 self.write("(");
35961 self.generate_expression(&e.this)?;
35962 if let Some(format) = &e.format {
35963 self.write(", '");
35964 self.write(format);
35965 self.write("'");
35966 }
35967 self.write(")");
35968 Ok(())
35969 }
35970
35971 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
35972 self.write_keyword("TO_BOOLEAN");
35974 self.write("(");
35975 self.generate_expression(&e.this)?;
35976 self.write(")");
35977 Ok(())
35978 }
35979
35980 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
35981 self.write_keyword("TO_CHAR");
35983 self.write("(");
35984 self.generate_expression(&e.this)?;
35985 if let Some(format) = &e.format {
35986 self.write(", '");
35987 self.write(format);
35988 self.write("'");
35989 }
35990 if let Some(nlsparam) = &e.nlsparam {
35991 self.write(", ");
35992 self.generate_expression(nlsparam)?;
35993 }
35994 self.write(")");
35995 Ok(())
35996 }
35997
35998 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
35999 self.write_keyword("TO_DECFLOAT");
36001 self.write("(");
36002 self.generate_expression(&e.this)?;
36003 if let Some(format) = &e.format {
36004 self.write(", '");
36005 self.write(format);
36006 self.write("'");
36007 }
36008 self.write(")");
36009 Ok(())
36010 }
36011
36012 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
36013 self.write_keyword("TO_DOUBLE");
36015 self.write("(");
36016 self.generate_expression(&e.this)?;
36017 if let Some(format) = &e.format {
36018 self.write(", '");
36019 self.write(format);
36020 self.write("'");
36021 }
36022 self.write(")");
36023 Ok(())
36024 }
36025
36026 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
36027 self.write_keyword("TO_FILE");
36029 self.write("(");
36030 self.generate_expression(&e.this)?;
36031 if let Some(path) = &e.path {
36032 self.write(", ");
36033 self.generate_expression(path)?;
36034 }
36035 self.write(")");
36036 Ok(())
36037 }
36038
36039 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
36040 let is_safe = e.safe.is_some();
36043 if is_safe {
36044 self.write_keyword("TRY_TO_NUMBER");
36045 } else {
36046 self.write_keyword("TO_NUMBER");
36047 }
36048 self.write("(");
36049 self.generate_expression(&e.this)?;
36050 if let Some(format) = &e.format {
36051 self.write(", ");
36052 self.generate_expression(format)?;
36053 }
36054 if let Some(nlsparam) = &e.nlsparam {
36055 self.write(", ");
36056 self.generate_expression(nlsparam)?;
36057 }
36058 if let Some(precision) = &e.precision {
36059 self.write(", ");
36060 self.generate_expression(precision)?;
36061 }
36062 if let Some(scale) = &e.scale {
36063 self.write(", ");
36064 self.generate_expression(scale)?;
36065 }
36066 self.write(")");
36067 Ok(())
36068 }
36069
36070 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
36071 self.write_keyword("TO_TABLE");
36073 self.write_space();
36074 self.generate_expression(&e.this)?;
36075 Ok(())
36076 }
36077
36078 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
36079 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
36081 Expression::Identifier(id) => id.name.clone(),
36082 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
36083 let Literal::String(s) = lit.as_ref() else {
36084 unreachable!()
36085 };
36086 s.clone()
36087 }
36088 _ => String::new(),
36089 });
36090
36091 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
36092 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
36093 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
36094 matches!(m.as_ref(), Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)))
36095 });
36096
36097 let use_start_transaction = matches!(
36099 self.config.dialect,
36100 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
36101 );
36102 let strip_transaction = matches!(
36104 self.config.dialect,
36105 Some(DialectType::Snowflake)
36106 | Some(DialectType::PostgreSQL)
36107 | Some(DialectType::Redshift)
36108 | Some(DialectType::MySQL)
36109 | Some(DialectType::Hive)
36110 | Some(DialectType::Spark)
36111 | Some(DialectType::Databricks)
36112 | Some(DialectType::DuckDB)
36113 | Some(DialectType::Oracle)
36114 | Some(DialectType::Doris)
36115 | Some(DialectType::StarRocks)
36116 | Some(DialectType::Materialize)
36117 | Some(DialectType::ClickHouse)
36118 );
36119
36120 if is_start || use_start_transaction {
36121 self.write_keyword("START TRANSACTION");
36123 if let Some(modes) = &e.modes {
36124 self.write_space();
36125 self.generate_expression(modes)?;
36126 }
36127 } else {
36128 self.write_keyword("BEGIN");
36130
36131 let is_kind = e.this.as_ref().map_or(false, |t| {
36133 if let Expression::Identifier(id) = t.as_ref() {
36134 id.name.eq_ignore_ascii_case("DEFERRED")
36135 || id.name.eq_ignore_ascii_case("IMMEDIATE")
36136 || id.name.eq_ignore_ascii_case("EXCLUSIVE")
36137 } else {
36138 false
36139 }
36140 });
36141
36142 if is_kind {
36144 if let Some(this) = &e.this {
36145 self.write_space();
36146 if let Expression::Identifier(id) = this.as_ref() {
36147 self.write_keyword(&id.name);
36148 }
36149 }
36150 }
36151
36152 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
36154 self.write_space();
36155 self.write_keyword("TRANSACTION");
36156 }
36157
36158 if !is_kind {
36160 if let Some(this) = &e.this {
36161 self.write_space();
36162 self.generate_expression(this)?;
36163 }
36164 }
36165
36166 if has_with_mark {
36168 self.write_space();
36169 self.write_keyword("WITH MARK");
36170 if let Some(Expression::Literal(lit)) = e.mark.as_deref() {
36171 if let Literal::String(desc) = lit.as_ref() {
36172 if !desc.is_empty() {
36173 self.write_space();
36174 self.write(&format!("'{}'", desc));
36175 }
36176 }
36177 }
36178 }
36179
36180 if let Some(modes) = &e.modes {
36182 self.write_space();
36183 self.generate_expression(modes)?;
36184 }
36185 }
36186 Ok(())
36187 }
36188
36189 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
36190 self.write_keyword("TRANSFORM");
36192 self.write("(");
36193 self.generate_expression(&e.this)?;
36194 self.write(", ");
36195 self.generate_expression(&e.expression)?;
36196 self.write(")");
36197 Ok(())
36198 }
36199
36200 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
36201 self.write_keyword("TRANSFORM");
36203 self.write("(");
36204 if self.config.pretty && !e.expressions.is_empty() {
36205 self.indent_level += 1;
36206 for (i, expr) in e.expressions.iter().enumerate() {
36207 if i > 0 {
36208 self.write(",");
36209 }
36210 self.write_newline();
36211 self.write_indent();
36212 self.generate_expression(expr)?;
36213 }
36214 self.indent_level -= 1;
36215 self.write_newline();
36216 self.write(")");
36217 } else {
36218 for (i, expr) in e.expressions.iter().enumerate() {
36219 if i > 0 {
36220 self.write(", ");
36221 }
36222 self.generate_expression(expr)?;
36223 }
36224 self.write(")");
36225 }
36226 Ok(())
36227 }
36228
36229 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
36230 use crate::dialects::DialectType;
36231 if let Some(this) = &e.this {
36233 self.generate_expression(this)?;
36234 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
36235 self.write_space();
36236 }
36237 }
36238 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
36239 self.write_keyword("TRANSIENT");
36240 }
36241 Ok(())
36242 }
36243
36244 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
36245 self.write_keyword("TRANSLATE");
36247 self.write("(");
36248 self.generate_expression(&e.this)?;
36249 if let Some(from) = &e.from_ {
36250 self.write(", ");
36251 self.generate_expression(from)?;
36252 }
36253 if let Some(to) = &e.to {
36254 self.write(", ");
36255 self.generate_expression(to)?;
36256 }
36257 self.write(")");
36258 Ok(())
36259 }
36260
36261 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
36262 self.write_keyword("TRANSLATE");
36264 self.write("(");
36265 self.generate_expression(&e.this)?;
36266 self.write_space();
36267 self.write_keyword("USING");
36268 self.write_space();
36269 self.generate_expression(&e.expression)?;
36270 if e.with_error.is_some() {
36271 self.write_space();
36272 self.write_keyword("WITH ERROR");
36273 }
36274 self.write(")");
36275 Ok(())
36276 }
36277
36278 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
36279 self.write_keyword("TRUNCATE TABLE");
36281 self.write_space();
36282 for (i, expr) in e.expressions.iter().enumerate() {
36283 if i > 0 {
36284 self.write(", ");
36285 }
36286 self.generate_expression(expr)?;
36287 }
36288 Ok(())
36289 }
36290
36291 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
36292 self.write_keyword("TRY_BASE64_DECODE_BINARY");
36294 self.write("(");
36295 self.generate_expression(&e.this)?;
36296 if let Some(alphabet) = &e.alphabet {
36297 self.write(", ");
36298 self.generate_expression(alphabet)?;
36299 }
36300 self.write(")");
36301 Ok(())
36302 }
36303
36304 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
36305 self.write_keyword("TRY_BASE64_DECODE_STRING");
36307 self.write("(");
36308 self.generate_expression(&e.this)?;
36309 if let Some(alphabet) = &e.alphabet {
36310 self.write(", ");
36311 self.generate_expression(alphabet)?;
36312 }
36313 self.write(")");
36314 Ok(())
36315 }
36316
36317 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
36318 self.write_keyword("TRY_TO_DECFLOAT");
36320 self.write("(");
36321 self.generate_expression(&e.this)?;
36322 if let Some(format) = &e.format {
36323 self.write(", '");
36324 self.write(format);
36325 self.write("'");
36326 }
36327 self.write(")");
36328 Ok(())
36329 }
36330
36331 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
36332 self.write_keyword("TS_OR_DS_ADD");
36334 self.write("(");
36335 self.generate_expression(&e.this)?;
36336 self.write(", ");
36337 self.generate_expression(&e.expression)?;
36338 if let Some(unit) = &e.unit {
36339 self.write(", ");
36340 self.write_keyword(unit);
36341 }
36342 if let Some(return_type) = &e.return_type {
36343 self.write(", ");
36344 self.generate_expression(return_type)?;
36345 }
36346 self.write(")");
36347 Ok(())
36348 }
36349
36350 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
36351 self.write_keyword("TS_OR_DS_DIFF");
36353 self.write("(");
36354 self.generate_expression(&e.this)?;
36355 self.write(", ");
36356 self.generate_expression(&e.expression)?;
36357 if let Some(unit) = &e.unit {
36358 self.write(", ");
36359 self.write_keyword(unit);
36360 }
36361 self.write(")");
36362 Ok(())
36363 }
36364
36365 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
36366 let default_time_format = "%Y-%m-%d %H:%M:%S";
36367 let default_date_format = "%Y-%m-%d";
36368 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
36369 f != default_time_format && f != default_date_format
36370 });
36371
36372 if has_non_default_format {
36373 let fmt = e.format.as_ref().unwrap();
36375 match self.config.dialect {
36376 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
36377 let str_to_time = crate::expressions::StrToTime {
36380 this: Box::new((*e.this).clone()),
36381 format: fmt.clone(),
36382 zone: None,
36383 safe: None,
36384 target_type: None,
36385 };
36386 self.generate_str_to_time(&str_to_time)?;
36387 }
36388 Some(DialectType::Hive)
36389 | Some(DialectType::Spark)
36390 | Some(DialectType::Databricks) => {
36391 self.write_keyword("TO_DATE");
36393 self.write("(");
36394 self.generate_expression(&e.this)?;
36395 self.write(", '");
36396 self.write(&Self::strftime_to_java_format(fmt));
36397 self.write("')");
36398 }
36399 Some(DialectType::Snowflake) => {
36400 self.write_keyword("TO_DATE");
36402 self.write("(");
36403 self.generate_expression(&e.this)?;
36404 self.write(", '");
36405 self.write(&Self::strftime_to_snowflake_format(fmt));
36406 self.write("')");
36407 }
36408 Some(DialectType::Doris) => {
36409 self.write_keyword("TO_DATE");
36411 self.write("(");
36412 self.generate_expression(&e.this)?;
36413 self.write(")");
36414 }
36415 _ => {
36416 self.write_keyword("CAST");
36418 self.write("(");
36419 let str_to_time = crate::expressions::StrToTime {
36420 this: Box::new((*e.this).clone()),
36421 format: fmt.clone(),
36422 zone: None,
36423 safe: None,
36424 target_type: None,
36425 };
36426 self.generate_str_to_time(&str_to_time)?;
36427 self.write_keyword(" AS ");
36428 self.write_keyword("DATE");
36429 self.write(")");
36430 }
36431 }
36432 } else {
36433 match self.config.dialect {
36435 Some(DialectType::MySQL)
36436 | Some(DialectType::SQLite)
36437 | Some(DialectType::StarRocks) => {
36438 self.write_keyword("DATE");
36440 self.write("(");
36441 self.generate_expression(&e.this)?;
36442 self.write(")");
36443 }
36444 Some(DialectType::Hive)
36445 | Some(DialectType::Spark)
36446 | Some(DialectType::Databricks)
36447 | Some(DialectType::Snowflake)
36448 | Some(DialectType::Doris) => {
36449 self.write_keyword("TO_DATE");
36451 self.write("(");
36452 self.generate_expression(&e.this)?;
36453 self.write(")");
36454 }
36455 Some(DialectType::Presto)
36456 | Some(DialectType::Trino)
36457 | Some(DialectType::Athena) => {
36458 self.write_keyword("CAST");
36460 self.write("(");
36461 self.write_keyword("CAST");
36462 self.write("(");
36463 self.generate_expression(&e.this)?;
36464 self.write_keyword(" AS ");
36465 self.write_keyword("TIMESTAMP");
36466 self.write(")");
36467 self.write_keyword(" AS ");
36468 self.write_keyword("DATE");
36469 self.write(")");
36470 }
36471 Some(DialectType::ClickHouse) => {
36472 self.write_keyword("CAST");
36474 self.write("(");
36475 self.generate_expression(&e.this)?;
36476 self.write_keyword(" AS ");
36477 self.write("Nullable(DATE)");
36478 self.write(")");
36479 }
36480 _ => {
36481 self.write_keyword("CAST");
36483 self.write("(");
36484 self.generate_expression(&e.this)?;
36485 self.write_keyword(" AS ");
36486 self.write_keyword("DATE");
36487 self.write(")");
36488 }
36489 }
36490 }
36491 Ok(())
36492 }
36493
36494 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
36495 self.write_keyword("TS_OR_DS_TO_TIME");
36497 self.write("(");
36498 self.generate_expression(&e.this)?;
36499 if let Some(format) = &e.format {
36500 self.write(", '");
36501 self.write(format);
36502 self.write("'");
36503 }
36504 self.write(")");
36505 Ok(())
36506 }
36507
36508 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
36509 self.write_keyword("UNHEX");
36511 self.write("(");
36512 self.generate_expression(&e.this)?;
36513 if let Some(expression) = &e.expression {
36514 self.write(", ");
36515 self.generate_expression(expression)?;
36516 }
36517 self.write(")");
36518 Ok(())
36519 }
36520
36521 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
36522 self.write("U&");
36524 self.generate_expression(&e.this)?;
36525 if let Some(escape) = &e.escape {
36526 self.write_space();
36527 self.write_keyword("UESCAPE");
36528 self.write_space();
36529 self.generate_expression(escape)?;
36530 }
36531 Ok(())
36532 }
36533
36534 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
36535 self.write_keyword("UNIFORM");
36537 self.write("(");
36538 self.generate_expression(&e.this)?;
36539 self.write(", ");
36540 self.generate_expression(&e.expression)?;
36541 if let Some(gen) = &e.gen {
36542 self.write(", ");
36543 self.generate_expression(gen)?;
36544 }
36545 if let Some(seed) = &e.seed {
36546 self.write(", ");
36547 self.generate_expression(seed)?;
36548 }
36549 self.write(")");
36550 Ok(())
36551 }
36552
36553 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
36554 self.write_keyword("UNIQUE");
36556 if e.nulls.is_some() {
36558 self.write(" NULLS NOT DISTINCT");
36559 }
36560 if let Some(this) = &e.this {
36561 self.write_space();
36562 self.generate_expression(this)?;
36563 }
36564 if let Some(index_type) = &e.index_type {
36565 self.write(" USING ");
36566 self.generate_expression(index_type)?;
36567 }
36568 if let Some(on_conflict) = &e.on_conflict {
36569 self.write_space();
36570 self.generate_expression(on_conflict)?;
36571 }
36572 for opt in &e.options {
36573 self.write_space();
36574 self.generate_expression(opt)?;
36575 }
36576 Ok(())
36577 }
36578
36579 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
36580 self.write_keyword("UNIQUE KEY");
36582 self.write(" (");
36583 for (i, expr) in e.expressions.iter().enumerate() {
36584 if i > 0 {
36585 self.write(", ");
36586 }
36587 self.generate_expression(expr)?;
36588 }
36589 self.write(")");
36590 Ok(())
36591 }
36592
36593 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
36594 self.write_keyword("ROLLUP");
36596 self.write(" (");
36597 for (i, index) in e.expressions.iter().enumerate() {
36598 if i > 0 {
36599 self.write(", ");
36600 }
36601 self.generate_identifier(&index.name)?;
36602 self.write("(");
36603 for (j, col) in index.expressions.iter().enumerate() {
36604 if j > 0 {
36605 self.write(", ");
36606 }
36607 self.generate_identifier(col)?;
36608 }
36609 self.write(")");
36610 }
36611 self.write(")");
36612 Ok(())
36613 }
36614
36615 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
36616 match self.config.dialect {
36617 Some(DialectType::DuckDB) => {
36618 self.write_keyword("STRFTIME");
36620 self.write("(");
36621 self.write_keyword("TO_TIMESTAMP");
36622 self.write("(");
36623 self.generate_expression(&e.this)?;
36624 self.write("), '");
36625 if let Some(format) = &e.format {
36626 self.write(format);
36627 }
36628 self.write("')");
36629 }
36630 Some(DialectType::Hive) => {
36631 self.write_keyword("FROM_UNIXTIME");
36633 self.write("(");
36634 self.generate_expression(&e.this)?;
36635 if let Some(format) = &e.format {
36636 if format != "yyyy-MM-dd HH:mm:ss" {
36637 self.write(", '");
36638 self.write(format);
36639 self.write("'");
36640 }
36641 }
36642 self.write(")");
36643 }
36644 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36645 self.write_keyword("DATE_FORMAT");
36647 self.write("(");
36648 self.write_keyword("FROM_UNIXTIME");
36649 self.write("(");
36650 self.generate_expression(&e.this)?;
36651 self.write("), '");
36652 if let Some(format) = &e.format {
36653 self.write(format);
36654 }
36655 self.write("')");
36656 }
36657 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36658 self.write_keyword("FROM_UNIXTIME");
36660 self.write("(");
36661 self.generate_expression(&e.this)?;
36662 if let Some(format) = &e.format {
36663 self.write(", '");
36664 self.write(format);
36665 self.write("'");
36666 }
36667 self.write(")");
36668 }
36669 _ => {
36670 self.write_keyword("UNIX_TO_STR");
36672 self.write("(");
36673 self.generate_expression(&e.this)?;
36674 if let Some(format) = &e.format {
36675 self.write(", '");
36676 self.write(format);
36677 self.write("'");
36678 }
36679 self.write(")");
36680 }
36681 }
36682 Ok(())
36683 }
36684
36685 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
36686 use crate::dialects::DialectType;
36687 let scale = e.scale.unwrap_or(0); match self.config.dialect {
36690 Some(DialectType::Snowflake) => {
36691 self.write_keyword("TO_TIMESTAMP");
36693 self.write("(");
36694 self.generate_expression(&e.this)?;
36695 if let Some(s) = e.scale {
36696 if s > 0 {
36697 self.write(", ");
36698 self.write(&s.to_string());
36699 }
36700 }
36701 self.write(")");
36702 }
36703 Some(DialectType::BigQuery) => {
36704 match scale {
36707 0 => {
36708 self.write_keyword("TIMESTAMP_SECONDS");
36709 self.write("(");
36710 self.generate_expression(&e.this)?;
36711 self.write(")");
36712 }
36713 3 => {
36714 self.write_keyword("TIMESTAMP_MILLIS");
36715 self.write("(");
36716 self.generate_expression(&e.this)?;
36717 self.write(")");
36718 }
36719 6 => {
36720 self.write_keyword("TIMESTAMP_MICROS");
36721 self.write("(");
36722 self.generate_expression(&e.this)?;
36723 self.write(")");
36724 }
36725 _ => {
36726 self.write_keyword("TIMESTAMP_SECONDS");
36728 self.write("(CAST(");
36729 self.generate_expression(&e.this)?;
36730 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
36731 }
36732 }
36733 }
36734 Some(DialectType::Spark) => {
36735 match scale {
36740 0 => {
36741 self.write_keyword("CAST");
36742 self.write("(");
36743 self.write_keyword("FROM_UNIXTIME");
36744 self.write("(");
36745 self.generate_expression(&e.this)?;
36746 self.write(") ");
36747 self.write_keyword("AS TIMESTAMP");
36748 self.write(")");
36749 }
36750 3 => {
36751 self.write_keyword("TIMESTAMP_MILLIS");
36752 self.write("(");
36753 self.generate_expression(&e.this)?;
36754 self.write(")");
36755 }
36756 6 => {
36757 self.write_keyword("TIMESTAMP_MICROS");
36758 self.write("(");
36759 self.generate_expression(&e.this)?;
36760 self.write(")");
36761 }
36762 _ => {
36763 self.write_keyword("TIMESTAMP_SECONDS");
36764 self.write("(");
36765 self.generate_expression(&e.this)?;
36766 self.write(&format!(" / POWER(10, {}))", scale));
36767 }
36768 }
36769 }
36770 Some(DialectType::Databricks) => {
36771 match scale {
36775 0 => {
36776 self.write_keyword("CAST");
36777 self.write("(");
36778 self.write_keyword("FROM_UNIXTIME");
36779 self.write("(");
36780 self.generate_expression(&e.this)?;
36781 self.write(") ");
36782 self.write_keyword("AS TIMESTAMP");
36783 self.write(")");
36784 }
36785 3 => {
36786 self.write_keyword("TIMESTAMP_MILLIS");
36787 self.write("(");
36788 self.generate_expression(&e.this)?;
36789 self.write(")");
36790 }
36791 6 => {
36792 self.write_keyword("TIMESTAMP_MICROS");
36793 self.write("(");
36794 self.generate_expression(&e.this)?;
36795 self.write(")");
36796 }
36797 _ => {
36798 self.write_keyword("TIMESTAMP_SECONDS");
36799 self.write("(");
36800 self.generate_expression(&e.this)?;
36801 self.write(&format!(" / POWER(10, {}))", scale));
36802 }
36803 }
36804 }
36805 Some(DialectType::Hive) => {
36806 if scale == 0 {
36808 self.write_keyword("FROM_UNIXTIME");
36809 self.write("(");
36810 self.generate_expression(&e.this)?;
36811 self.write(")");
36812 } else {
36813 self.write_keyword("FROM_UNIXTIME");
36814 self.write("(");
36815 self.generate_expression(&e.this)?;
36816 self.write(&format!(" / POWER(10, {})", scale));
36817 self.write(")");
36818 }
36819 }
36820 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36821 if scale == 0 {
36824 self.write_keyword("FROM_UNIXTIME");
36825 self.write("(");
36826 self.generate_expression(&e.this)?;
36827 self.write(")");
36828 } else {
36829 self.write_keyword("FROM_UNIXTIME");
36830 self.write("(CAST(");
36831 self.generate_expression(&e.this)?;
36832 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
36833 }
36834 }
36835 Some(DialectType::DuckDB) => {
36836 match scale {
36840 0 => {
36841 self.write_keyword("TO_TIMESTAMP");
36842 self.write("(");
36843 self.generate_expression(&e.this)?;
36844 self.write(")");
36845 }
36846 3 => {
36847 self.write_keyword("EPOCH_MS");
36848 self.write("(");
36849 self.generate_expression(&e.this)?;
36850 self.write(")");
36851 }
36852 6 => {
36853 self.write_keyword("MAKE_TIMESTAMP");
36854 self.write("(");
36855 self.generate_expression(&e.this)?;
36856 self.write(")");
36857 }
36858 _ => {
36859 self.write_keyword("TO_TIMESTAMP");
36860 self.write("(");
36861 self.generate_expression(&e.this)?;
36862 self.write(&format!(" / POWER(10, {}))", scale));
36863 self.write_keyword(" AT TIME ZONE");
36864 self.write(" 'UTC'");
36865 }
36866 }
36867 }
36868 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
36869 self.write_keyword("FROM_UNIXTIME");
36871 self.write("(");
36872 self.generate_expression(&e.this)?;
36873 self.write(")");
36874 }
36875 Some(DialectType::Oracle) => {
36876 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
36878 self.generate_expression(&e.this)?;
36879 self.write(" / 86400)");
36880 }
36881 Some(DialectType::Redshift) => {
36882 self.write("(TIMESTAMP 'epoch' + ");
36885 if scale == 0 {
36886 self.generate_expression(&e.this)?;
36887 } else {
36888 self.write("(");
36889 self.generate_expression(&e.this)?;
36890 self.write(&format!(" / POWER(10, {}))", scale));
36891 }
36892 self.write(" * INTERVAL '1 SECOND')");
36893 }
36894 Some(DialectType::Exasol) => {
36895 self.write_keyword("FROM_POSIX_TIME");
36897 self.write("(");
36898 self.generate_expression(&e.this)?;
36899 self.write(")");
36900 }
36901 _ => {
36902 self.write_keyword("TO_TIMESTAMP");
36904 self.write("(");
36905 self.generate_expression(&e.this)?;
36906 if let Some(s) = e.scale {
36907 self.write(", ");
36908 self.write(&s.to_string());
36909 }
36910 self.write(")");
36911 }
36912 }
36913 Ok(())
36914 }
36915
36916 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
36917 if !matches!(&*e.this, Expression::Null(_)) {
36919 self.write_keyword("NAME");
36920 self.write_space();
36921 self.generate_expression(&e.this)?;
36922 }
36923 if !e.expressions.is_empty() {
36924 self.write_space();
36925 self.write_keyword("VALUE");
36926 self.write_space();
36927 for (i, expr) in e.expressions.iter().enumerate() {
36928 if i > 0 {
36929 self.write(", ");
36930 }
36931 self.generate_expression(expr)?;
36932 }
36933 }
36934 Ok(())
36935 }
36936
36937 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
36938 if e.wrapped.is_some() {
36940 self.write("(");
36941 }
36942 self.generate_expression(&e.this)?;
36943 if e.wrapped.is_some() {
36944 self.write(")");
36945 }
36946 self.write("(");
36947 for (i, expr) in e.expressions.iter().enumerate() {
36948 if i > 0 {
36949 self.write(", ");
36950 }
36951 self.generate_expression(expr)?;
36952 }
36953 self.write(")");
36954 Ok(())
36955 }
36956
36957 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
36958 self.write_keyword("USING TEMPLATE");
36960 self.write_space();
36961 self.generate_expression(&e.this)?;
36962 Ok(())
36963 }
36964
36965 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
36966 self.write_keyword("UTC_TIME");
36968 Ok(())
36969 }
36970
36971 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
36972 if matches!(
36973 self.config.dialect,
36974 Some(crate::dialects::DialectType::ClickHouse)
36975 ) {
36976 self.write_keyword("CURRENT_TIMESTAMP");
36977 self.write("('UTC')");
36978 } else {
36979 self.write_keyword("UTC_TIMESTAMP");
36980 }
36981 Ok(())
36982 }
36983
36984 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
36985 use crate::dialects::DialectType;
36986 let func_name = match self.config.dialect {
36988 Some(DialectType::Snowflake) => "UUID_STRING",
36989 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
36990 Some(DialectType::BigQuery) => "GENERATE_UUID",
36991 _ => {
36992 if let Some(name) = &e.name {
36993 name.as_str()
36994 } else {
36995 "UUID"
36996 }
36997 }
36998 };
36999 self.write_keyword(func_name);
37000 self.write("(");
37001 if let Some(this) = &e.this {
37002 self.generate_expression(this)?;
37003 }
37004 self.write(")");
37005 Ok(())
37006 }
37007
37008 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
37009 self.write_keyword("MAP");
37011 self.write("(");
37012 let mut first = true;
37013 for (k, v) in e.keys.iter().zip(e.values.iter()) {
37014 if !first {
37015 self.write(", ");
37016 }
37017 self.generate_expression(k)?;
37018 self.write(", ");
37019 self.generate_expression(v)?;
37020 first = false;
37021 }
37022 self.write(")");
37023 Ok(())
37024 }
37025
37026 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
37027 self.write_keyword("VECTOR_SEARCH");
37029 self.write("(");
37030 self.generate_expression(&e.this)?;
37031 if let Some(col) = &e.column_to_search {
37032 self.write(", ");
37033 self.generate_expression(col)?;
37034 }
37035 if let Some(query_table) = &e.query_table {
37036 self.write(", ");
37037 self.generate_expression(query_table)?;
37038 }
37039 if let Some(query_col) = &e.query_column_to_search {
37040 self.write(", ");
37041 self.generate_expression(query_col)?;
37042 }
37043 if let Some(top_k) = &e.top_k {
37044 self.write(", ");
37045 self.generate_expression(top_k)?;
37046 }
37047 if let Some(dist_type) = &e.distance_type {
37048 self.write(", ");
37049 self.generate_expression(dist_type)?;
37050 }
37051 self.write(")");
37052 Ok(())
37053 }
37054
37055 fn generate_version(&mut self, e: &Version) -> Result<()> {
37056 use crate::dialects::DialectType;
37062 let skip_for = matches!(
37063 self.config.dialect,
37064 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
37065 );
37066 if !skip_for {
37067 self.write_keyword("FOR");
37068 self.write_space();
37069 }
37070 match e.this.as_ref() {
37072 Expression::Identifier(ident) => {
37073 self.write_keyword(&ident.name);
37074 }
37075 _ => {
37076 self.generate_expression(&e.this)?;
37077 }
37078 }
37079 self.write_space();
37080 self.write_keyword(&e.kind);
37081 if let Some(expression) = &e.expression {
37082 self.write_space();
37083 self.generate_expression(expression)?;
37084 }
37085 Ok(())
37086 }
37087
37088 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
37089 self.generate_expression(&e.this)?;
37091 Ok(())
37092 }
37093
37094 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
37095 if e.this.is_some() {
37097 self.write_keyword("NOT VOLATILE");
37098 } else {
37099 self.write_keyword("VOLATILE");
37100 }
37101 Ok(())
37102 }
37103
37104 fn generate_watermark_column_constraint(
37105 &mut self,
37106 e: &WatermarkColumnConstraint,
37107 ) -> Result<()> {
37108 self.write_keyword("WATERMARK FOR");
37110 self.write_space();
37111 self.generate_expression(&e.this)?;
37112 self.write_space();
37113 self.write_keyword("AS");
37114 self.write_space();
37115 self.generate_expression(&e.expression)?;
37116 Ok(())
37117 }
37118
37119 fn generate_week(&mut self, e: &Week) -> Result<()> {
37120 self.write_keyword("WEEK");
37122 self.write("(");
37123 self.generate_expression(&e.this)?;
37124 if let Some(mode) = &e.mode {
37125 self.write(", ");
37126 self.generate_expression(mode)?;
37127 }
37128 self.write(")");
37129 Ok(())
37130 }
37131
37132 fn generate_when(&mut self, e: &When) -> Result<()> {
37133 self.write_keyword("WHEN");
37137 self.write_space();
37138
37139 if let Some(matched) = &e.matched {
37141 match matched.as_ref() {
37143 Expression::Boolean(b) if b.value => {
37144 self.write_keyword("MATCHED");
37145 }
37146 _ => {
37147 self.write_keyword("NOT MATCHED");
37148 }
37149 }
37150 } else {
37151 self.write_keyword("NOT MATCHED");
37152 }
37153
37154 if self.config.matched_by_source {
37159 if let Some(source) = &e.source {
37160 if let Expression::Boolean(b) = source.as_ref() {
37161 if b.value {
37162 self.write_space();
37164 self.write_keyword("BY SOURCE");
37165 }
37166 } else {
37168 self.write_space();
37170 self.write_keyword("BY SOURCE");
37171 }
37172 }
37173 }
37174
37175 if let Some(condition) = &e.condition {
37177 self.write_space();
37178 self.write_keyword("AND");
37179 self.write_space();
37180 self.generate_expression(condition)?;
37181 }
37182
37183 self.write_space();
37184 self.write_keyword("THEN");
37185 self.write_space();
37186
37187 self.generate_merge_action(&e.then)?;
37190
37191 Ok(())
37192 }
37193
37194 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
37195 match action {
37196 Expression::Tuple(tuple) => {
37197 let elements = &tuple.expressions;
37198 if elements.is_empty() {
37199 return self.generate_expression(action);
37200 }
37201 match &elements[0] {
37203 Expression::Var(v) if v.this == "INSERT" => {
37204 self.write_keyword("INSERT");
37205 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
37207 self.write(" *");
37208 } else {
37209 let mut values_idx = 1;
37210 if elements.len() > 1 {
37212 if let Expression::Tuple(cols) = &elements[1] {
37213 if elements.len() > 2 {
37215 self.write(" (");
37217 for (i, col) in cols.expressions.iter().enumerate() {
37218 if i > 0 {
37219 self.write(", ");
37220 }
37221 if !self.merge_strip_qualifiers.is_empty() {
37223 let stripped = self.strip_merge_qualifier(col);
37224 self.generate_expression(&stripped)?;
37225 } else {
37226 self.generate_expression(col)?;
37227 }
37228 }
37229 self.write(")");
37230 values_idx = 2;
37231 } else {
37232 values_idx = 1;
37234 }
37235 }
37236 }
37237 if values_idx < elements.len() {
37239 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
37241 if !is_row {
37242 self.write_space();
37243 self.write_keyword("VALUES");
37244 }
37245 self.write(" ");
37246 if let Expression::Tuple(vals) = &elements[values_idx] {
37247 self.write("(");
37248 for (i, val) in vals.expressions.iter().enumerate() {
37249 if i > 0 {
37250 self.write(", ");
37251 }
37252 self.generate_expression(val)?;
37253 }
37254 self.write(")");
37255 } else {
37256 self.generate_expression(&elements[values_idx])?;
37257 }
37258 }
37259 } }
37261 Expression::Var(v) if v.this == "UPDATE" => {
37262 self.write_keyword("UPDATE");
37263 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
37265 self.write(" *");
37266 } else if elements.len() > 1 {
37267 self.write_space();
37268 self.write_keyword("SET");
37269 if self.config.pretty {
37271 self.write_newline();
37272 self.indent_level += 1;
37273 self.write_indent();
37274 } else {
37275 self.write_space();
37276 }
37277 if let Expression::Tuple(assignments) = &elements[1] {
37278 for (i, assignment) in assignments.expressions.iter().enumerate() {
37279 if i > 0 {
37280 if self.config.pretty {
37281 self.write(",");
37282 self.write_newline();
37283 self.write_indent();
37284 } else {
37285 self.write(", ");
37286 }
37287 }
37288 if !self.merge_strip_qualifiers.is_empty() {
37290 self.generate_merge_set_assignment(assignment)?;
37291 } else {
37292 self.generate_expression(assignment)?;
37293 }
37294 }
37295 } else {
37296 self.generate_expression(&elements[1])?;
37297 }
37298 if self.config.pretty {
37299 self.indent_level -= 1;
37300 }
37301 }
37302 }
37303 _ => {
37304 self.generate_expression(action)?;
37306 }
37307 }
37308 }
37309 Expression::Var(v)
37310 if v.this == "INSERT"
37311 || v.this == "UPDATE"
37312 || v.this == "DELETE"
37313 || v.this == "DO NOTHING" =>
37314 {
37315 self.write_keyword(&v.this);
37316 }
37317 _ => {
37318 self.generate_expression(action)?;
37319 }
37320 }
37321 Ok(())
37322 }
37323
37324 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
37326 match assignment {
37327 Expression::Eq(eq) => {
37328 let stripped_left = self.strip_merge_qualifier(&eq.left);
37330 self.generate_expression(&stripped_left)?;
37331 self.write(" = ");
37332 self.generate_expression(&eq.right)?;
37333 Ok(())
37334 }
37335 other => self.generate_expression(other),
37336 }
37337 }
37338
37339 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
37341 match expr {
37342 Expression::Column(col) => {
37343 if let Some(ref table_ident) = col.table {
37344 if self
37345 .merge_strip_qualifiers
37346 .iter()
37347 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
37348 {
37349 let mut col = col.clone();
37351 col.table = None;
37352 return Expression::Column(col);
37353 }
37354 }
37355 expr.clone()
37356 }
37357 Expression::Dot(dot) => {
37358 if let Expression::Identifier(id) = &dot.this {
37360 if self
37361 .merge_strip_qualifiers
37362 .iter()
37363 .any(|n| n.eq_ignore_ascii_case(&id.name))
37364 {
37365 return Expression::Identifier(dot.field.clone());
37366 }
37367 }
37368 expr.clone()
37369 }
37370 _ => expr.clone(),
37371 }
37372 }
37373
37374 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
37375 for (i, expr) in e.expressions.iter().enumerate() {
37377 if i > 0 {
37378 if self.config.pretty {
37380 self.write_newline();
37381 self.write_indent();
37382 } else {
37383 self.write_space();
37384 }
37385 }
37386 self.generate_expression(expr)?;
37387 }
37388 Ok(())
37389 }
37390
37391 fn generate_where(&mut self, e: &Where) -> Result<()> {
37392 self.write_keyword("WHERE");
37394 self.write_space();
37395 self.generate_expression(&e.this)?;
37396 Ok(())
37397 }
37398
37399 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
37400 self.write_keyword("WIDTH_BUCKET");
37402 self.write("(");
37403 self.generate_expression(&e.this)?;
37404 if let Some(min_value) = &e.min_value {
37405 self.write(", ");
37406 self.generate_expression(min_value)?;
37407 }
37408 if let Some(max_value) = &e.max_value {
37409 self.write(", ");
37410 self.generate_expression(max_value)?;
37411 }
37412 if let Some(num_buckets) = &e.num_buckets {
37413 self.write(", ");
37414 self.generate_expression(num_buckets)?;
37415 }
37416 self.write(")");
37417 Ok(())
37418 }
37419
37420 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
37421 self.generate_window_spec(e)
37423 }
37424
37425 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
37426 let mut has_content = false;
37428
37429 if !e.partition_by.is_empty() {
37431 self.write_keyword("PARTITION BY");
37432 self.write_space();
37433 for (i, expr) in e.partition_by.iter().enumerate() {
37434 if i > 0 {
37435 self.write(", ");
37436 }
37437 self.generate_expression(expr)?;
37438 }
37439 has_content = true;
37440 }
37441
37442 if !e.order_by.is_empty() {
37444 if has_content {
37445 self.write_space();
37446 }
37447 self.write_keyword("ORDER BY");
37448 self.write_space();
37449 for (i, ordered) in e.order_by.iter().enumerate() {
37450 if i > 0 {
37451 self.write(", ");
37452 }
37453 self.generate_expression(&ordered.this)?;
37454 if ordered.desc {
37455 self.write_space();
37456 self.write_keyword("DESC");
37457 } else if ordered.explicit_asc {
37458 self.write_space();
37459 self.write_keyword("ASC");
37460 }
37461 if let Some(nulls_first) = ordered.nulls_first {
37462 self.write_space();
37463 self.write_keyword("NULLS");
37464 self.write_space();
37465 if nulls_first {
37466 self.write_keyword("FIRST");
37467 } else {
37468 self.write_keyword("LAST");
37469 }
37470 }
37471 }
37472 has_content = true;
37473 }
37474
37475 if let Some(frame) = &e.frame {
37477 if has_content {
37478 self.write_space();
37479 }
37480 self.generate_window_frame(frame)?;
37481 }
37482
37483 Ok(())
37484 }
37485
37486 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
37487 self.write_keyword("WITH");
37489 self.write_space();
37490 if e.no.is_some() {
37491 self.write_keyword("NO");
37492 self.write_space();
37493 }
37494 self.write_keyword("DATA");
37495
37496 if let Some(statistics) = &e.statistics {
37498 self.write_space();
37499 self.write_keyword("AND");
37500 self.write_space();
37501 match statistics.as_ref() {
37503 Expression::Boolean(b) if !b.value => {
37504 self.write_keyword("NO");
37505 self.write_space();
37506 }
37507 _ => {}
37508 }
37509 self.write_keyword("STATISTICS");
37510 }
37511 Ok(())
37512 }
37513
37514 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
37515 self.write_keyword("WITH FILL");
37517
37518 if let Some(from_) = &e.from_ {
37519 self.write_space();
37520 self.write_keyword("FROM");
37521 self.write_space();
37522 self.generate_expression(from_)?;
37523 }
37524
37525 if let Some(to) = &e.to {
37526 self.write_space();
37527 self.write_keyword("TO");
37528 self.write_space();
37529 self.generate_expression(to)?;
37530 }
37531
37532 if let Some(step) = &e.step {
37533 self.write_space();
37534 self.write_keyword("STEP");
37535 self.write_space();
37536 self.generate_expression(step)?;
37537 }
37538
37539 if let Some(staleness) = &e.staleness {
37540 self.write_space();
37541 self.write_keyword("STALENESS");
37542 self.write_space();
37543 self.generate_expression(staleness)?;
37544 }
37545
37546 if let Some(interpolate) = &e.interpolate {
37547 self.write_space();
37548 self.write_keyword("INTERPOLATE");
37549 self.write(" (");
37550 self.generate_interpolate_item(interpolate)?;
37552 self.write(")");
37553 }
37554
37555 Ok(())
37556 }
37557
37558 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
37560 match expr {
37561 Expression::Alias(alias) => {
37562 self.generate_identifier(&alias.alias)?;
37564 self.write_space();
37565 self.write_keyword("AS");
37566 self.write_space();
37567 self.generate_expression(&alias.this)?;
37568 }
37569 Expression::Tuple(tuple) => {
37570 for (i, item) in tuple.expressions.iter().enumerate() {
37571 if i > 0 {
37572 self.write(", ");
37573 }
37574 self.generate_interpolate_item(item)?;
37575 }
37576 }
37577 other => {
37578 self.generate_expression(other)?;
37579 }
37580 }
37581 Ok(())
37582 }
37583
37584 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
37585 self.write_keyword("WITH JOURNAL TABLE");
37587 self.write("=");
37588 self.generate_expression(&e.this)?;
37589 Ok(())
37590 }
37591
37592 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
37593 self.generate_expression(&e.this)?;
37595 self.write_space();
37596 self.write_keyword("WITH");
37597 self.write_space();
37598 self.write_keyword(&e.op);
37599 Ok(())
37600 }
37601
37602 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
37603 self.write_keyword("WITH");
37605 self.write_space();
37606 for (i, expr) in e.expressions.iter().enumerate() {
37607 if i > 0 {
37608 self.write(", ");
37609 }
37610 self.generate_expression(expr)?;
37611 }
37612 Ok(())
37613 }
37614
37615 fn generate_with_schema_binding_property(
37616 &mut self,
37617 e: &WithSchemaBindingProperty,
37618 ) -> Result<()> {
37619 self.write_keyword("WITH");
37621 self.write_space();
37622 self.generate_expression(&e.this)?;
37623 Ok(())
37624 }
37625
37626 fn generate_with_system_versioning_property(
37627 &mut self,
37628 e: &WithSystemVersioningProperty,
37629 ) -> Result<()> {
37630 let mut parts = Vec::new();
37636
37637 if let Some(this) = &e.this {
37638 let mut s = String::from("HISTORY_TABLE=");
37640 let mut gen = Generator::new();
37641 gen.generate_expression(this)?;
37642 s.push_str(&gen.output);
37643 parts.push(s);
37644 }
37645
37646 if let Some(data_consistency) = &e.data_consistency {
37647 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
37648 let mut gen = Generator::new();
37649 gen.generate_expression(data_consistency)?;
37650 s.push_str(&gen.output);
37651 parts.push(s);
37652 }
37653
37654 if let Some(retention_period) = &e.retention_period {
37655 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
37656 let mut gen = Generator::new();
37657 gen.generate_expression(retention_period)?;
37658 s.push_str(&gen.output);
37659 parts.push(s);
37660 }
37661
37662 self.write_keyword("SYSTEM_VERSIONING");
37663 self.write("=");
37664
37665 if !parts.is_empty() {
37666 self.write_keyword("ON");
37667 self.write("(");
37668 self.write(&parts.join(", "));
37669 self.write(")");
37670 } else if e.on.is_some() {
37671 self.write_keyword("ON");
37672 } else {
37673 self.write_keyword("OFF");
37674 }
37675
37676 if e.with_.is_some() {
37678 let inner = self.output.clone();
37679 self.output.clear();
37680 self.write("WITH(");
37681 self.write(&inner);
37682 self.write(")");
37683 }
37684
37685 Ok(())
37686 }
37687
37688 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
37689 self.write_keyword("WITH");
37691 self.write(" (");
37692 for (i, expr) in e.expressions.iter().enumerate() {
37693 if i > 0 {
37694 self.write(", ");
37695 }
37696 self.generate_expression(expr)?;
37697 }
37698 self.write(")");
37699 Ok(())
37700 }
37701
37702 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
37703 self.write_keyword("XMLELEMENT");
37706 self.write("(");
37707
37708 if e.evalname.is_some() {
37709 self.write_keyword("EVALNAME");
37710 } else {
37711 self.write_keyword("NAME");
37712 }
37713 self.write_space();
37714 self.generate_expression(&e.this)?;
37715
37716 for expr in &e.expressions {
37717 self.write(", ");
37718 self.generate_expression(expr)?;
37719 }
37720 self.write(")");
37721 Ok(())
37722 }
37723
37724 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
37725 self.write_keyword("XMLGET");
37727 self.write("(");
37728 self.generate_expression(&e.this)?;
37729 self.write(", ");
37730 self.generate_expression(&e.expression)?;
37731 if let Some(instance) = &e.instance {
37732 self.write(", ");
37733 self.generate_expression(instance)?;
37734 }
37735 self.write(")");
37736 Ok(())
37737 }
37738
37739 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
37740 self.generate_expression(&e.this)?;
37742 if let Some(expression) = &e.expression {
37743 self.write("(");
37744 self.generate_expression(expression)?;
37745 self.write(")");
37746 }
37747 Ok(())
37748 }
37749
37750 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
37751 self.write_keyword("XMLTABLE");
37753 self.write("(");
37754
37755 if self.config.pretty {
37756 self.indent_level += 1;
37757 self.write_newline();
37758 self.write_indent();
37759 self.generate_expression(&e.this)?;
37760
37761 if let Some(passing) = &e.passing {
37762 self.write_newline();
37763 self.write_indent();
37764 self.write_keyword("PASSING");
37765 if let Expression::Tuple(tuple) = passing.as_ref() {
37766 for expr in &tuple.expressions {
37767 self.write_newline();
37768 self.indent_level += 1;
37769 self.write_indent();
37770 self.generate_expression(expr)?;
37771 self.indent_level -= 1;
37772 }
37773 } else {
37774 self.write_newline();
37775 self.indent_level += 1;
37776 self.write_indent();
37777 self.generate_expression(passing)?;
37778 self.indent_level -= 1;
37779 }
37780 }
37781
37782 if e.by_ref.is_some() {
37783 self.write_newline();
37784 self.write_indent();
37785 self.write_keyword("RETURNING SEQUENCE BY REF");
37786 }
37787
37788 if !e.columns.is_empty() {
37789 self.write_newline();
37790 self.write_indent();
37791 self.write_keyword("COLUMNS");
37792 for (i, col) in e.columns.iter().enumerate() {
37793 self.write_newline();
37794 self.indent_level += 1;
37795 self.write_indent();
37796 self.generate_expression(col)?;
37797 self.indent_level -= 1;
37798 if i < e.columns.len() - 1 {
37799 self.write(",");
37800 }
37801 }
37802 }
37803
37804 self.indent_level -= 1;
37805 self.write_newline();
37806 self.write_indent();
37807 self.write(")");
37808 return Ok(());
37809 }
37810
37811 if let Some(namespaces) = &e.namespaces {
37813 self.write_keyword("XMLNAMESPACES");
37814 self.write("(");
37815 if let Expression::Tuple(tuple) = namespaces.as_ref() {
37817 for (i, expr) in tuple.expressions.iter().enumerate() {
37818 if i > 0 {
37819 self.write(", ");
37820 }
37821 if !matches!(expr, Expression::Alias(_)) {
37824 self.write_keyword("DEFAULT");
37825 self.write_space();
37826 }
37827 self.generate_expression(expr)?;
37828 }
37829 } else {
37830 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
37832 self.write_keyword("DEFAULT");
37833 self.write_space();
37834 }
37835 self.generate_expression(namespaces)?;
37836 }
37837 self.write("), ");
37838 }
37839
37840 self.generate_expression(&e.this)?;
37842
37843 if let Some(passing) = &e.passing {
37845 self.write_space();
37846 self.write_keyword("PASSING");
37847 self.write_space();
37848 if let Expression::Tuple(tuple) = passing.as_ref() {
37850 for (i, expr) in tuple.expressions.iter().enumerate() {
37851 if i > 0 {
37852 self.write(", ");
37853 }
37854 self.generate_expression(expr)?;
37855 }
37856 } else {
37857 self.generate_expression(passing)?;
37858 }
37859 }
37860
37861 if e.by_ref.is_some() {
37863 self.write_space();
37864 self.write_keyword("RETURNING SEQUENCE BY REF");
37865 }
37866
37867 if !e.columns.is_empty() {
37869 self.write_space();
37870 self.write_keyword("COLUMNS");
37871 self.write_space();
37872 for (i, col) in e.columns.iter().enumerate() {
37873 if i > 0 {
37874 self.write(", ");
37875 }
37876 self.generate_expression(col)?;
37877 }
37878 }
37879
37880 self.write(")");
37881 Ok(())
37882 }
37883
37884 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
37885 if let Some(this) = &e.this {
37888 self.generate_expression(this)?;
37889 if let Some(expression) = &e.expression {
37890 self.write_space();
37891 self.write_keyword("XOR");
37892 self.write_space();
37893 self.generate_expression(expression)?;
37894 }
37895 }
37896
37897 for (i, expr) in e.expressions.iter().enumerate() {
37899 if i > 0 || e.this.is_some() {
37900 self.write_space();
37901 self.write_keyword("XOR");
37902 self.write_space();
37903 }
37904 self.generate_expression(expr)?;
37905 }
37906 Ok(())
37907 }
37908
37909 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
37910 self.write_keyword("ZIPF");
37912 self.write("(");
37913 self.generate_expression(&e.this)?;
37914 if let Some(elementcount) = &e.elementcount {
37915 self.write(", ");
37916 self.generate_expression(elementcount)?;
37917 }
37918 if let Some(gen) = &e.gen {
37919 self.write(", ");
37920 self.generate_expression(gen)?;
37921 }
37922 self.write(")");
37923 Ok(())
37924 }
37925}
37926
37927impl Default for Generator {
37928 fn default() -> Self {
37929 Self::new()
37930 }
37931}
37932
37933#[cfg(test)]
37934mod tests {
37935 use super::*;
37936 use crate::parser::Parser;
37937
37938 fn roundtrip(sql: &str) -> String {
37939 let ast = Parser::parse_sql(sql).unwrap();
37940 Generator::sql(&ast[0]).unwrap()
37941 }
37942
37943 #[test]
37944 fn test_simple_select() {
37945 let result = roundtrip("SELECT 1");
37946 assert_eq!(result, "SELECT 1");
37947 }
37948
37949 #[test]
37950 fn test_select_from() {
37951 let result = roundtrip("SELECT a, b FROM t");
37952 assert_eq!(result, "SELECT a, b FROM t");
37953 }
37954
37955 #[test]
37956 fn test_select_where() {
37957 let result = roundtrip("SELECT * FROM t WHERE x = 1");
37958 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
37959 }
37960
37961 #[test]
37962 fn test_select_join() {
37963 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
37964 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
37965 }
37966
37967 #[test]
37968 fn test_insert() {
37969 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
37970 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
37971 }
37972
37973 #[test]
37974 fn test_pretty_print() {
37975 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
37976 let result = Generator::pretty_sql(&ast[0]).unwrap();
37977 assert!(result.contains('\n'));
37978 }
37979
37980 #[test]
37981 fn test_window_function() {
37982 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
37983 assert_eq!(
37984 result,
37985 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
37986 );
37987 }
37988
37989 #[test]
37990 fn test_window_function_with_frame() {
37991 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
37992 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
37993 }
37994
37995 #[test]
37996 fn test_aggregate_with_filter() {
37997 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
37998 assert_eq!(
37999 result,
38000 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
38001 );
38002 }
38003
38004 #[test]
38005 fn test_subscript() {
38006 let result = roundtrip("SELECT arr[0]");
38007 assert_eq!(result, "SELECT arr[0]");
38008 }
38009
38010 #[test]
38012 fn test_create_table() {
38013 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
38014 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
38015 }
38016
38017 #[test]
38018 fn test_create_table_with_constraints() {
38019 let result = roundtrip(
38020 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
38021 );
38022 assert_eq!(
38023 result,
38024 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
38025 );
38026 }
38027
38028 #[test]
38029 fn test_create_table_if_not_exists() {
38030 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
38031 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
38032 }
38033
38034 #[test]
38035 fn test_drop_table() {
38036 let result = roundtrip("DROP TABLE users");
38037 assert_eq!(result, "DROP TABLE users");
38038 }
38039
38040 #[test]
38041 fn test_drop_table_if_exists_cascade() {
38042 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
38043 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
38044 }
38045
38046 #[test]
38047 fn test_alter_table_add_column() {
38048 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
38049 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
38050 }
38051
38052 #[test]
38053 fn test_alter_table_drop_column() {
38054 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
38055 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
38056 }
38057
38058 #[test]
38059 fn test_create_index() {
38060 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
38061 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
38062 }
38063
38064 #[test]
38065 fn test_create_unique_index() {
38066 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
38067 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
38068 }
38069
38070 #[test]
38071 fn test_drop_index() {
38072 let result = roundtrip("DROP INDEX idx_name");
38073 assert_eq!(result, "DROP INDEX idx_name");
38074 }
38075
38076 #[test]
38077 fn test_create_view() {
38078 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
38079 assert_eq!(
38080 result,
38081 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
38082 );
38083 }
38084
38085 #[test]
38086 fn test_drop_view() {
38087 let result = roundtrip("DROP VIEW active_users");
38088 assert_eq!(result, "DROP VIEW active_users");
38089 }
38090
38091 #[test]
38092 fn test_truncate() {
38093 let result = roundtrip("TRUNCATE TABLE users");
38094 assert_eq!(result, "TRUNCATE TABLE users");
38095 }
38096
38097 #[test]
38098 fn test_string_literal_escaping_default() {
38099 let result = roundtrip("SELECT 'hello'");
38101 assert_eq!(result, "SELECT 'hello'");
38102
38103 let result = roundtrip("SELECT 'it''s a test'");
38105 assert_eq!(result, "SELECT 'it''s a test'");
38106 }
38107
38108 #[test]
38109 fn test_not_in_style_prefix_default_generic() {
38110 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
38111 assert_eq!(
38112 result,
38113 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
38114 );
38115 }
38116
38117 #[test]
38118 fn test_not_in_style_infix_generic_override() {
38119 let ast =
38120 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
38121 .unwrap();
38122 let config = GeneratorConfig {
38123 not_in_style: NotInStyle::Infix,
38124 ..Default::default()
38125 };
38126 let mut gen = Generator::with_config(config);
38127 let result = gen.generate(&ast[0]).unwrap();
38128 assert_eq!(
38129 result,
38130 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
38131 );
38132 }
38133
38134 #[test]
38135 fn test_string_literal_escaping_mysql() {
38136 use crate::dialects::DialectType;
38137
38138 let config = GeneratorConfig {
38139 dialect: Some(DialectType::MySQL),
38140 ..Default::default()
38141 };
38142
38143 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38144 let mut gen = Generator::with_config(config.clone());
38145 let result = gen.generate(&ast[0]).unwrap();
38146 assert_eq!(result, "SELECT 'hello'");
38147
38148 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38150 let mut gen = Generator::with_config(config.clone());
38151 let result = gen.generate(&ast[0]).unwrap();
38152 assert_eq!(result, "SELECT 'it''s'");
38153 }
38154
38155 #[test]
38156 fn test_string_literal_escaping_postgres() {
38157 use crate::dialects::DialectType;
38158
38159 let config = GeneratorConfig {
38160 dialect: Some(DialectType::PostgreSQL),
38161 ..Default::default()
38162 };
38163
38164 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38165 let mut gen = Generator::with_config(config.clone());
38166 let result = gen.generate(&ast[0]).unwrap();
38167 assert_eq!(result, "SELECT 'hello'");
38168
38169 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38171 let mut gen = Generator::with_config(config.clone());
38172 let result = gen.generate(&ast[0]).unwrap();
38173 assert_eq!(result, "SELECT 'it''s'");
38174 }
38175
38176 #[test]
38177 fn test_string_literal_escaping_bigquery() {
38178 use crate::dialects::DialectType;
38179
38180 let config = GeneratorConfig {
38181 dialect: Some(DialectType::BigQuery),
38182 ..Default::default()
38183 };
38184
38185 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38186 let mut gen = Generator::with_config(config.clone());
38187 let result = gen.generate(&ast[0]).unwrap();
38188 assert_eq!(result, "SELECT 'hello'");
38189
38190 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38192 let mut gen = Generator::with_config(config.clone());
38193 let result = gen.generate(&ast[0]).unwrap();
38194 assert_eq!(result, "SELECT 'it\\'s'");
38195 }
38196
38197 #[test]
38198 fn test_generate_deep_and_chain_without_stack_growth() {
38199 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
38200 Expression::column("c0"),
38201 Expression::number(0),
38202 )));
38203
38204 for i in 1..2500 {
38205 let predicate = Expression::Eq(Box::new(BinaryOp::new(
38206 Expression::column(format!("c{i}")),
38207 Expression::number(i as i64),
38208 )));
38209 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
38210 }
38211
38212 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
38213 assert!(sql.contains("c2499 = 2499"), "{}", sql);
38214 }
38215
38216 #[test]
38217 fn test_generate_deep_or_chain_without_stack_growth() {
38218 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
38219 Expression::column("c0"),
38220 Expression::number(0),
38221 )));
38222
38223 for i in 1..2500 {
38224 let predicate = Expression::Eq(Box::new(BinaryOp::new(
38225 Expression::column(format!("c{i}")),
38226 Expression::number(i as i64),
38227 )));
38228 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
38229 }
38230
38231 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
38232 assert!(sql.contains("c2499 = 2499"), "{}", sql);
38233 }
38234}