1use crate::error::Result;
14use crate::expressions::*;
15use crate::DialectType;
16
17pub struct Generator {
42 config: GeneratorConfig,
43 output: String,
44 indent_level: usize,
45 athena_hive_context: bool,
48 sqlite_inline_pk_columns: std::collections::HashSet<String>,
50 merge_strip_qualifiers: Vec<String>,
52 clickhouse_nullable_depth: i32,
57}
58
59#[derive(Debug, Clone, Copy, PartialEq, Default)]
65pub enum NormalizeFunctions {
66 #[default]
68 Upper,
69 Lower,
71 None,
73}
74
75#[derive(Debug, Clone, Copy, PartialEq, Default)]
77pub enum LimitFetchStyle {
78 #[default]
80 Limit,
81 Top,
83 FetchFirst,
85}
86
87#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
89pub enum NotInStyle {
90 #[default]
92 Prefix,
93 Infix,
95}
96
97#[derive(Debug, Clone, Copy, PartialEq)]
99pub struct IdentifierQuoteStyle {
100 pub start: char,
102 pub end: char,
104}
105
106impl Default for IdentifierQuoteStyle {
107 fn default() -> Self {
108 Self {
109 start: '"',
110 end: '"',
111 }
112 }
113}
114
115impl IdentifierQuoteStyle {
116 pub const DOUBLE_QUOTE: Self = Self {
118 start: '"',
119 end: '"',
120 };
121 pub const BACKTICK: Self = Self {
123 start: '`',
124 end: '`',
125 };
126 pub const BRACKET: Self = Self {
128 start: '[',
129 end: ']',
130 };
131}
132
133#[derive(Debug, Clone)]
155pub struct GeneratorConfig {
156 pub pretty: bool,
159 pub indent: String,
161 pub max_text_width: usize,
163 pub identifier_quote: char,
165 pub identifier_quote_style: IdentifierQuoteStyle,
167 pub uppercase_keywords: bool,
169 pub normalize_identifiers: bool,
171 pub dialect: Option<crate::dialects::DialectType>,
173 pub source_dialect: Option<crate::dialects::DialectType>,
175 pub normalize_functions: NormalizeFunctions,
177 pub string_escape: char,
179 pub case_sensitive_identifiers: bool,
181 pub identifiers_can_start_with_digit: bool,
183 pub always_quote_identifiers: bool,
186 pub not_in_style: NotInStyle,
188
189 pub null_ordering_supported: bool,
193 pub ignore_nulls_in_func: bool,
196 pub nvl2_supported: bool,
198
199 pub limit_fetch_style: LimitFetchStyle,
202 pub limit_is_top: bool,
204 pub limit_only_literals: bool,
206
207 pub single_string_interval: bool,
210 pub interval_allows_plural_form: bool,
212
213 pub cte_recursive_keyword_required: bool,
216
217 pub values_as_table: bool,
220 pub wrap_derived_values: bool,
222
223 pub tablesample_seed_keyword: &'static str,
226 pub tablesample_requires_parens: bool,
228 pub tablesample_size_is_rows: bool,
230 pub tablesample_keywords: &'static str,
232 pub tablesample_with_method: bool,
234 pub alias_post_tablesample: bool,
236
237 pub aggregate_filter_supported: bool,
240 pub multi_arg_distinct: bool,
242 pub quantified_no_paren_space: bool,
244 pub supports_median: bool,
246
247 pub supports_select_into: bool,
250 pub locking_reads_supported: bool,
252
253 pub rename_table_with_db: bool,
256 pub semi_anti_join_with_side: bool,
258 pub supports_table_alias_columns: bool,
260 pub join_hints: bool,
262 pub table_hints: bool,
264 pub query_hints: bool,
266 pub query_hint_sep: &'static str,
268 pub supports_column_join_marks: bool,
270
271 pub index_using_no_space: bool,
275 pub supports_unlogged_tables: bool,
277 pub supports_create_table_like: bool,
279 pub like_property_inside_schema: bool,
281 pub alter_table_include_column_keyword: bool,
283 pub supports_table_copy: bool,
285 pub alter_set_type: &'static str,
287 pub alter_set_wrapped: bool,
289
290 pub tz_to_with_time_zone: bool,
293 pub supports_convert_timezone: bool,
295
296 pub json_type_required_for_extraction: bool,
299 pub json_path_bracketed_key_supported: bool,
301 pub json_path_single_quote_escape: bool,
303 pub quote_json_path: bool,
305 pub json_key_value_pair_sep: &'static str,
307
308 pub copy_params_are_wrapped: bool,
311 pub copy_params_eq_required: bool,
313 pub copy_has_into_keyword: bool,
315
316 pub supports_window_exclude: bool,
319 pub unnest_with_ordinality: bool,
321 pub lowercase_window_frame_keywords: bool,
324 pub normalize_window_frame_between: bool,
327
328 pub array_concat_is_var_len: bool,
331 pub array_size_dim_required: Option<bool>,
334 pub can_implement_array_any: bool,
336 pub array_size_name: &'static str,
338
339 pub supports_between_flags: bool,
342
343 pub is_bool_allowed: bool,
346 pub ensure_bools: bool,
348
349 pub extract_allows_quotes: bool,
352 pub normalize_extract_date_parts: bool,
354
355 pub try_supported: bool,
358 pub supports_uescape: bool,
360 pub supports_to_number: bool,
362 pub supports_single_arg_concat: bool,
364 pub last_day_supports_date_part: bool,
366 pub supports_exploding_projections: bool,
368 pub supports_unix_seconds: bool,
370 pub supports_like_quantifiers: bool,
372 pub supports_decode_case: bool,
374 pub set_op_modifiers: bool,
376 pub update_statement_supports_from: bool,
378
379 pub collate_is_func: bool,
382
383 pub duplicate_key_update_with_set: bool,
386 pub insert_overwrite: &'static str,
388
389 pub returning_end: bool,
392
393 pub matched_by_source: bool,
396
397 pub create_function_return_as: bool,
400 pub parameter_default_equals: bool,
402
403 pub computed_column_with_type: bool,
406
407 pub unpivot_aliases_are_identifiers: bool,
410
411 pub star_except: &'static str,
414
415 pub hex_func: &'static str,
418
419 pub with_properties_prefix: &'static str,
422
423 pub pad_fill_pattern_is_required: bool,
426
427 pub index_on: &'static str,
430
431 pub groupings_sep: &'static str,
434
435 pub struct_delimiter: (&'static str, &'static str),
438 pub struct_curly_brace_notation: bool,
440 pub array_bracket_only: bool,
442 pub struct_field_sep: &'static str,
444
445 pub except_intersect_support_all_clause: bool,
448
449 pub parameter_token: &'static str,
452 pub named_placeholder_token: &'static str,
454
455 pub data_type_specifiers_allowed: bool,
458
459 pub schema_comment_with_eq: bool,
463}
464
465impl Default for GeneratorConfig {
466 fn default() -> Self {
467 Self {
468 pretty: false,
470 indent: " ".to_string(),
471 max_text_width: 80,
472 identifier_quote: '"',
473 identifier_quote_style: IdentifierQuoteStyle::DOUBLE_QUOTE,
474 uppercase_keywords: true,
475 normalize_identifiers: false,
476 dialect: None,
477 source_dialect: None,
478 normalize_functions: NormalizeFunctions::Upper,
479 string_escape: '\'',
480 case_sensitive_identifiers: false,
481 identifiers_can_start_with_digit: false,
482 always_quote_identifiers: false,
483 not_in_style: NotInStyle::Prefix,
484
485 null_ordering_supported: true,
487 ignore_nulls_in_func: false,
488 nvl2_supported: true,
489
490 limit_fetch_style: LimitFetchStyle::Limit,
492 limit_is_top: false,
493 limit_only_literals: false,
494
495 single_string_interval: false,
497 interval_allows_plural_form: true,
498
499 cte_recursive_keyword_required: true,
501
502 values_as_table: true,
504 wrap_derived_values: true,
505
506 tablesample_seed_keyword: "SEED",
508 tablesample_requires_parens: true,
509 tablesample_size_is_rows: true,
510 tablesample_keywords: "TABLESAMPLE",
511 tablesample_with_method: true,
512 alias_post_tablesample: false,
513
514 aggregate_filter_supported: true,
516 multi_arg_distinct: true,
517 quantified_no_paren_space: false,
518 supports_median: true,
519
520 supports_select_into: false,
522 locking_reads_supported: true,
523
524 rename_table_with_db: true,
526 semi_anti_join_with_side: true,
527 supports_table_alias_columns: true,
528 join_hints: true,
529 table_hints: true,
530 query_hints: true,
531 query_hint_sep: ", ",
532 supports_column_join_marks: false,
533
534 index_using_no_space: false,
536 supports_unlogged_tables: false,
537 supports_create_table_like: true,
538 like_property_inside_schema: false,
539 alter_table_include_column_keyword: true,
540 supports_table_copy: true,
541 alter_set_type: "SET DATA TYPE",
542 alter_set_wrapped: false,
543
544 tz_to_with_time_zone: false,
546 supports_convert_timezone: false,
547
548 json_type_required_for_extraction: false,
550 json_path_bracketed_key_supported: true,
551 json_path_single_quote_escape: false,
552 quote_json_path: true,
553 json_key_value_pair_sep: ":",
554
555 copy_params_are_wrapped: true,
557 copy_params_eq_required: false,
558 copy_has_into_keyword: true,
559
560 supports_window_exclude: false,
562 unnest_with_ordinality: true,
563 lowercase_window_frame_keywords: false,
564 normalize_window_frame_between: false,
565
566 array_concat_is_var_len: true,
568 array_size_dim_required: None,
569 can_implement_array_any: false,
570 array_size_name: "ARRAY_LENGTH",
571
572 supports_between_flags: false,
574
575 is_bool_allowed: true,
577 ensure_bools: false,
578
579 extract_allows_quotes: true,
581 normalize_extract_date_parts: false,
582
583 try_supported: true,
585 supports_uescape: true,
586 supports_to_number: true,
587 supports_single_arg_concat: true,
588 last_day_supports_date_part: true,
589 supports_exploding_projections: true,
590 supports_unix_seconds: false,
591 supports_like_quantifiers: true,
592 supports_decode_case: true,
593 set_op_modifiers: true,
594 update_statement_supports_from: true,
595
596 collate_is_func: false,
598
599 duplicate_key_update_with_set: true,
601 insert_overwrite: " OVERWRITE TABLE",
602
603 returning_end: true,
605
606 matched_by_source: true,
608
609 create_function_return_as: true,
611 parameter_default_equals: false,
612
613 computed_column_with_type: true,
615
616 unpivot_aliases_are_identifiers: true,
618
619 star_except: "EXCEPT",
621
622 hex_func: "HEX",
624
625 with_properties_prefix: "WITH",
627
628 pad_fill_pattern_is_required: false,
630
631 index_on: "ON",
633
634 groupings_sep: ",",
636
637 struct_delimiter: ("<", ">"),
639 struct_curly_brace_notation: false,
640 array_bracket_only: false,
641 struct_field_sep: " ",
642
643 except_intersect_support_all_clause: true,
645
646 parameter_token: "@",
648 named_placeholder_token: ":",
649
650 data_type_specifiers_allowed: false,
652
653 schema_comment_with_eq: true,
655 }
656 }
657}
658
659mod reserved_keywords {
662 use std::collections::HashSet;
663 use std::sync::LazyLock;
664
665 pub static SQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
667 [
668 "all",
669 "alter",
670 "and",
671 "any",
672 "array",
673 "as",
674 "asc",
675 "at",
676 "authorization",
677 "begin",
678 "between",
679 "both",
680 "by",
681 "case",
682 "cast",
683 "check",
684 "collate",
685 "column",
686 "commit",
687 "constraint",
688 "create",
689 "cross",
690 "cube",
691 "current",
692 "current_date",
693 "current_time",
694 "current_timestamp",
695 "current_user",
696 "default",
697 "delete",
698 "desc",
699 "distinct",
700 "drop",
701 "else",
702 "end",
703 "escape",
704 "except",
705 "execute",
706 "exists",
707 "external",
708 "false",
709 "fetch",
710 "filter",
711 "for",
712 "foreign",
713 "from",
714 "full",
715 "function",
716 "grant",
717 "group",
718 "grouping",
719 "having",
720 "if",
721 "in",
722 "index",
723 "inner",
724 "insert",
725 "intersect",
726 "interval",
727 "into",
728 "is",
729 "join",
730 "key",
731 "leading",
732 "left",
733 "like",
734 "limit",
735 "local",
736 "localtime",
737 "localtimestamp",
738 "match",
739 "merge",
740 "natural",
741 "no",
742 "not",
743 "null",
744 "of",
745 "offset",
746 "on",
747 "only",
748 "or",
749 "order",
750 "outer",
751 "over",
752 "partition",
753 "primary",
754 "procedure",
755 "range",
756 "references",
757 "right",
758 "rollback",
759 "rollup",
760 "row",
761 "rows",
762 "select",
763 "session_user",
764 "set",
765 "some",
766 "table",
767 "tablesample",
768 "then",
769 "to",
770 "trailing",
771 "true",
772 "truncate",
773 "union",
774 "unique",
775 "unknown",
776 "update",
777 "user",
778 "using",
779 "values",
780 "view",
781 "when",
782 "where",
783 "window",
784 "with",
785 ]
786 .into_iter()
787 .collect()
788 });
789
790 pub static BIGQUERY_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
793 let mut set = SQL_RESERVED.clone();
794 set.extend([
795 "assert_rows_modified",
796 "at",
797 "contains",
798 "cube",
799 "current",
800 "define",
801 "enum",
802 "escape",
803 "exclude",
804 "following",
805 "for",
806 "groups",
807 "hash",
808 "ignore",
809 "lateral",
810 "lookup",
811 "new",
812 "no",
813 "nulls",
814 "of",
815 "over",
816 "preceding",
817 "proto",
818 "qualify",
819 "recursive",
820 "respect",
821 "struct",
822 "tablesample",
823 "treat",
824 "unbounded",
825 "unnest",
826 "window",
827 "within",
828 ]);
829 set.remove("grant");
831 set.remove("key");
832 set.remove("index");
833 set.remove("values");
834 set.remove("table");
835 set
836 });
837
838 pub static MYSQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
840 let mut set = SQL_RESERVED.clone();
841 set.extend([
842 "accessible",
843 "add",
844 "analyze",
845 "asensitive",
846 "before",
847 "bigint",
848 "binary",
849 "blob",
850 "call",
851 "cascade",
852 "change",
853 "char",
854 "character",
855 "condition",
856 "continue",
857 "convert",
858 "current_date",
859 "current_time",
860 "current_timestamp",
861 "current_user",
862 "cursor",
863 "database",
864 "databases",
865 "day_hour",
866 "day_microsecond",
867 "day_minute",
868 "day_second",
869 "dec",
870 "decimal",
871 "declare",
872 "delayed",
873 "describe",
874 "deterministic",
875 "distinctrow",
876 "div",
877 "double",
878 "dual",
879 "each",
880 "elseif",
881 "enclosed",
882 "escaped",
883 "exit",
884 "explain",
885 "float",
886 "float4",
887 "float8",
888 "force",
889 "get",
890 "high_priority",
891 "hour_microsecond",
892 "hour_minute",
893 "hour_second",
894 "ignore",
895 "infile",
896 "inout",
897 "insensitive",
898 "int",
899 "int1",
900 "int2",
901 "int3",
902 "int4",
903 "int8",
904 "integer",
905 "iterate",
906 "keys",
907 "kill",
908 "leave",
909 "linear",
910 "lines",
911 "load",
912 "lock",
913 "long",
914 "longblob",
915 "longtext",
916 "loop",
917 "low_priority",
918 "master_ssl_verify_server_cert",
919 "maxvalue",
920 "mediumblob",
921 "mediumint",
922 "mediumtext",
923 "middleint",
924 "minute_microsecond",
925 "minute_second",
926 "mod",
927 "modifies",
928 "no_write_to_binlog",
929 "numeric",
930 "optimize",
931 "option",
932 "optionally",
933 "out",
934 "outfile",
935 "precision",
936 "purge",
937 "read",
938 "reads",
939 "real",
940 "regexp",
941 "release",
942 "rename",
943 "repeat",
944 "replace",
945 "require",
946 "resignal",
947 "restrict",
948 "return",
949 "revoke",
950 "rlike",
951 "schema",
952 "schemas",
953 "second_microsecond",
954 "sensitive",
955 "separator",
956 "show",
957 "signal",
958 "smallint",
959 "spatial",
960 "specific",
961 "sql",
962 "sql_big_result",
963 "sql_calc_found_rows",
964 "sql_small_result",
965 "sqlexception",
966 "sqlstate",
967 "sqlwarning",
968 "ssl",
969 "starting",
970 "straight_join",
971 "terminated",
972 "text",
973 "tinyblob",
974 "tinyint",
975 "tinytext",
976 "trigger",
977 "undo",
978 "unlock",
979 "unsigned",
980 "usage",
981 "utc_date",
982 "utc_time",
983 "utc_timestamp",
984 "varbinary",
985 "varchar",
986 "varcharacter",
987 "varying",
988 "while",
989 "write",
990 "xor",
991 "year_month",
992 "zerofill",
993 ]);
994 set.remove("table");
995 set
996 });
997
998 pub static DORIS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1001 let mut set = MYSQL_RESERVED.clone();
1002 set.extend([
1003 "aggregate",
1004 "anti",
1005 "array",
1006 "backend",
1007 "backup",
1008 "begin",
1009 "bitmap",
1010 "boolean",
1011 "broker",
1012 "buckets",
1013 "cached",
1014 "cancel",
1015 "cast",
1016 "catalog",
1017 "charset",
1018 "cluster",
1019 "collation",
1020 "columns",
1021 "comment",
1022 "commit",
1023 "config",
1024 "connection",
1025 "count",
1026 "current",
1027 "data",
1028 "date",
1029 "datetime",
1030 "day",
1031 "deferred",
1032 "distributed",
1033 "dynamic",
1034 "enable",
1035 "end",
1036 "events",
1037 "export",
1038 "external",
1039 "fields",
1040 "first",
1041 "follower",
1042 "format",
1043 "free",
1044 "frontend",
1045 "full",
1046 "functions",
1047 "global",
1048 "grants",
1049 "hash",
1050 "help",
1051 "hour",
1052 "install",
1053 "intermediate",
1054 "json",
1055 "label",
1056 "last",
1057 "less",
1058 "level",
1059 "link",
1060 "local",
1061 "location",
1062 "max",
1063 "merge",
1064 "min",
1065 "minute",
1066 "modify",
1067 "month",
1068 "name",
1069 "names",
1070 "negative",
1071 "nulls",
1072 "observer",
1073 "offset",
1074 "only",
1075 "open",
1076 "overwrite",
1077 "password",
1078 "path",
1079 "plan",
1080 "plugin",
1081 "plugins",
1082 "policy",
1083 "process",
1084 "properties",
1085 "property",
1086 "query",
1087 "quota",
1088 "recover",
1089 "refresh",
1090 "repair",
1091 "replica",
1092 "repository",
1093 "resource",
1094 "restore",
1095 "resume",
1096 "role",
1097 "roles",
1098 "rollback",
1099 "rollup",
1100 "routine",
1101 "sample",
1102 "second",
1103 "semi",
1104 "session",
1105 "signed",
1106 "snapshot",
1107 "start",
1108 "stats",
1109 "status",
1110 "stop",
1111 "stream",
1112 "string",
1113 "sum",
1114 "tables",
1115 "tablet",
1116 "temporary",
1117 "text",
1118 "timestamp",
1119 "transaction",
1120 "trash",
1121 "trim",
1122 "truncate",
1123 "type",
1124 "user",
1125 "value",
1126 "variables",
1127 "verbose",
1128 "version",
1129 "view",
1130 "warnings",
1131 "week",
1132 "work",
1133 "year",
1134 ]);
1135 set
1136 });
1137
1138 pub static POSTGRES_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1140 let mut set = SQL_RESERVED.clone();
1141 set.extend([
1142 "analyse",
1143 "analyze",
1144 "asymmetric",
1145 "binary",
1146 "collation",
1147 "concurrently",
1148 "current_catalog",
1149 "current_role",
1150 "current_schema",
1151 "deferrable",
1152 "do",
1153 "freeze",
1154 "ilike",
1155 "initially",
1156 "isnull",
1157 "lateral",
1158 "notnull",
1159 "placing",
1160 "returning",
1161 "similar",
1162 "symmetric",
1163 "variadic",
1164 "verbose",
1165 ]);
1166 set.remove("default");
1168 set.remove("interval");
1169 set.remove("match");
1170 set.remove("offset");
1171 set.remove("table");
1172 set
1173 });
1174
1175 pub static REDSHIFT_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1179 [
1180 "aes128",
1181 "aes256",
1182 "all",
1183 "allowoverwrite",
1184 "analyse",
1185 "analyze",
1186 "and",
1187 "any",
1188 "array",
1189 "as",
1190 "asc",
1191 "authorization",
1192 "az64",
1193 "backup",
1194 "between",
1195 "binary",
1196 "blanksasnull",
1197 "both",
1198 "bytedict",
1199 "bzip2",
1200 "case",
1201 "cast",
1202 "check",
1203 "collate",
1204 "column",
1205 "constraint",
1206 "create",
1207 "credentials",
1208 "cross",
1209 "current_date",
1210 "current_time",
1211 "current_timestamp",
1212 "current_user",
1213 "current_user_id",
1214 "default",
1215 "deferrable",
1216 "deflate",
1217 "defrag",
1218 "delta",
1219 "delta32k",
1220 "desc",
1221 "disable",
1222 "distinct",
1223 "do",
1224 "else",
1225 "emptyasnull",
1226 "enable",
1227 "encode",
1228 "encrypt",
1229 "encryption",
1230 "end",
1231 "except",
1232 "explicit",
1233 "false",
1234 "for",
1235 "foreign",
1236 "freeze",
1237 "from",
1238 "full",
1239 "globaldict256",
1240 "globaldict64k",
1241 "grant",
1242 "group",
1243 "gzip",
1244 "having",
1245 "identity",
1246 "ignore",
1247 "ilike",
1248 "in",
1249 "initially",
1250 "inner",
1251 "intersect",
1252 "interval",
1253 "into",
1254 "is",
1255 "isnull",
1256 "join",
1257 "leading",
1258 "left",
1259 "like",
1260 "limit",
1261 "localtime",
1262 "localtimestamp",
1263 "lun",
1264 "luns",
1265 "lzo",
1266 "lzop",
1267 "minus",
1268 "mostly16",
1269 "mostly32",
1270 "mostly8",
1271 "natural",
1272 "new",
1273 "not",
1274 "notnull",
1275 "null",
1276 "nulls",
1277 "off",
1278 "offline",
1279 "offset",
1280 "oid",
1281 "old",
1282 "on",
1283 "only",
1284 "open",
1285 "or",
1286 "order",
1287 "outer",
1288 "overlaps",
1289 "parallel",
1290 "partition",
1291 "percent",
1292 "permissions",
1293 "pivot",
1294 "placing",
1295 "primary",
1296 "raw",
1297 "readratio",
1298 "recover",
1299 "references",
1300 "rejectlog",
1301 "resort",
1302 "respect",
1303 "restore",
1304 "right",
1305 "select",
1306 "session_user",
1307 "similar",
1308 "snapshot",
1309 "some",
1310 "sysdate",
1311 "system",
1312 "table",
1313 "tag",
1314 "tdes",
1315 "text255",
1316 "text32k",
1317 "then",
1318 "timestamp",
1319 "to",
1320 "top",
1321 "trailing",
1322 "true",
1323 "truncatecolumns",
1324 "type",
1325 "union",
1326 "unique",
1327 "unnest",
1328 "unpivot",
1329 "user",
1330 "using",
1331 "verbose",
1332 "wallet",
1333 "when",
1334 "where",
1335 "with",
1336 "without",
1337 ]
1338 .into_iter()
1339 .collect()
1340 });
1341
1342 pub static DUCKDB_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1344 let mut set = POSTGRES_RESERVED.clone();
1345 set.extend([
1346 "anti",
1347 "asof",
1348 "columns",
1349 "describe",
1350 "groups",
1351 "macro",
1352 "pivot",
1353 "pivot_longer",
1354 "pivot_wider",
1355 "qualify",
1356 "replace",
1357 "respect",
1358 "semi",
1359 "show",
1360 "table",
1361 "unpivot",
1362 ]);
1363 set.remove("at");
1364 set.remove("key");
1365 set.remove("row");
1366 set
1367 });
1368
1369 pub static PRESTO_TRINO_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1371 let mut set = SQL_RESERVED.clone();
1372 set.extend([
1373 "alter",
1374 "and",
1375 "as",
1376 "between",
1377 "by",
1378 "case",
1379 "cast",
1380 "constraint",
1381 "create",
1382 "cross",
1383 "cube",
1384 "current_catalog",
1385 "current_date",
1386 "current_path",
1387 "current_role",
1388 "current_schema",
1389 "current_time",
1390 "current_timestamp",
1391 "current_user",
1392 "deallocate",
1393 "delete",
1394 "describe",
1395 "distinct",
1396 "drop",
1397 "else",
1398 "end",
1399 "escape",
1400 "except",
1401 "execute",
1402 "exists",
1403 "extract",
1404 "false",
1405 "for",
1406 "from",
1407 "full",
1408 "group",
1409 "grouping",
1410 "having",
1411 "in",
1412 "inner",
1413 "insert",
1414 "intersect",
1415 "into",
1416 "is",
1417 "join",
1418 "json_array",
1419 "json_exists",
1420 "json_object",
1421 "json_query",
1422 "json_table",
1423 "json_value",
1424 "left",
1425 "like",
1426 "listagg",
1427 "localtime",
1428 "localtimestamp",
1429 "natural",
1430 "normalize",
1431 "not",
1432 "null",
1433 "on",
1434 "or",
1435 "order",
1436 "outer",
1437 "prepare",
1438 "recursive",
1439 "right",
1440 "rollup",
1441 "select",
1442 "skip",
1443 "table",
1444 "then",
1445 "trim",
1446 "true",
1447 "uescape",
1448 "union",
1449 "unnest",
1450 "using",
1451 "values",
1452 "when",
1453 "where",
1454 "with",
1455 ]);
1456 set.remove("key");
1458 set
1459 });
1460
1461 pub static STARROCKS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1464 [
1465 "add",
1466 "all",
1467 "alter",
1468 "analyze",
1469 "and",
1470 "array",
1471 "as",
1472 "asc",
1473 "between",
1474 "bigint",
1475 "bitmap",
1476 "both",
1477 "by",
1478 "case",
1479 "char",
1480 "character",
1481 "check",
1482 "collate",
1483 "column",
1484 "compaction",
1485 "convert",
1486 "create",
1487 "cross",
1488 "cube",
1489 "current_date",
1490 "current_role",
1491 "current_time",
1492 "current_timestamp",
1493 "current_user",
1494 "database",
1495 "databases",
1496 "decimal",
1497 "decimalv2",
1498 "decimal32",
1499 "decimal64",
1500 "decimal128",
1501 "default",
1502 "deferred",
1503 "delete",
1504 "dense_rank",
1505 "desc",
1506 "describe",
1507 "distinct",
1508 "double",
1509 "drop",
1510 "dual",
1511 "else",
1512 "except",
1513 "exists",
1514 "explain",
1515 "false",
1516 "first_value",
1517 "float",
1518 "for",
1519 "force",
1520 "from",
1521 "full",
1522 "function",
1523 "grant",
1524 "group",
1525 "grouping",
1526 "grouping_id",
1527 "groups",
1528 "having",
1529 "hll",
1530 "host",
1531 "if",
1532 "ignore",
1533 "immediate",
1534 "in",
1535 "index",
1536 "infile",
1537 "inner",
1538 "insert",
1539 "int",
1540 "integer",
1541 "intersect",
1542 "into",
1543 "is",
1544 "join",
1545 "json",
1546 "key",
1547 "keys",
1548 "kill",
1549 "lag",
1550 "largeint",
1551 "last_value",
1552 "lateral",
1553 "lead",
1554 "left",
1555 "like",
1556 "limit",
1557 "load",
1558 "localtime",
1559 "localtimestamp",
1560 "maxvalue",
1561 "minus",
1562 "mod",
1563 "not",
1564 "ntile",
1565 "null",
1566 "on",
1567 "or",
1568 "order",
1569 "outer",
1570 "outfile",
1571 "over",
1572 "partition",
1573 "percentile",
1574 "primary",
1575 "procedure",
1576 "qualify",
1577 "range",
1578 "rank",
1579 "read",
1580 "regexp",
1581 "release",
1582 "rename",
1583 "replace",
1584 "revoke",
1585 "right",
1586 "rlike",
1587 "row",
1588 "row_number",
1589 "rows",
1590 "schema",
1591 "schemas",
1592 "select",
1593 "set",
1594 "set_var",
1595 "show",
1596 "smallint",
1597 "system",
1598 "table",
1599 "terminated",
1600 "text",
1601 "then",
1602 "tinyint",
1603 "to",
1604 "true",
1605 "union",
1606 "unique",
1607 "unsigned",
1608 "update",
1609 "use",
1610 "using",
1611 "values",
1612 "varchar",
1613 "when",
1614 "where",
1615 "with",
1616 ]
1617 .into_iter()
1618 .collect()
1619 });
1620
1621 pub static SINGLESTORE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1624 let mut set = MYSQL_RESERVED.clone();
1625 set.extend([
1626 "abs",
1629 "account",
1630 "acos",
1631 "adddate",
1632 "addtime",
1633 "admin",
1634 "aes_decrypt",
1635 "aes_encrypt",
1636 "aggregate",
1637 "aggregates",
1638 "aggregator",
1639 "anti_join",
1640 "any_value",
1641 "approx_count_distinct",
1642 "approx_percentile",
1643 "arrange",
1644 "arrangement",
1645 "asin",
1646 "atan",
1647 "atan2",
1648 "attach",
1649 "autostats",
1650 "avro",
1651 "background",
1652 "backup",
1653 "batch",
1654 "batches",
1655 "boot_strapping",
1656 "ceil",
1657 "ceiling",
1658 "coercibility",
1659 "columnar",
1660 "columnstore",
1661 "compile",
1662 "concurrent",
1663 "connection_id",
1664 "cos",
1665 "cot",
1666 "current_security_groups",
1667 "current_security_roles",
1668 "dayname",
1669 "dayofmonth",
1670 "dayofweek",
1671 "dayofyear",
1672 "degrees",
1673 "dot_product",
1674 "dump",
1675 "durability",
1676 "earliest",
1677 "echo",
1678 "election",
1679 "euclidean_distance",
1680 "exp",
1681 "extractor",
1682 "extractors",
1683 "floor",
1684 "foreground",
1685 "found_rows",
1686 "from_base64",
1687 "from_days",
1688 "from_unixtime",
1689 "fs",
1690 "fulltext",
1691 "gc",
1692 "gcs",
1693 "geography",
1694 "geography_area",
1695 "geography_contains",
1696 "geography_distance",
1697 "geography_intersects",
1698 "geography_latitude",
1699 "geography_length",
1700 "geography_longitude",
1701 "geographypoint",
1702 "geography_point",
1703 "geography_within_distance",
1704 "geometry",
1705 "geometry_area",
1706 "geometry_contains",
1707 "geometry_distance",
1708 "geometry_filter",
1709 "geometry_intersects",
1710 "geometry_length",
1711 "geometrypoint",
1712 "geometry_point",
1713 "geometry_within_distance",
1714 "geometry_x",
1715 "geometry_y",
1716 "greatest",
1717 "groups",
1718 "group_concat",
1719 "gzip",
1720 "hdfs",
1721 "hex",
1722 "highlight",
1723 "ifnull",
1724 "ilike",
1725 "inet_aton",
1726 "inet_ntoa",
1727 "inet6_aton",
1728 "inet6_ntoa",
1729 "initcap",
1730 "instr",
1731 "interpreter_mode",
1732 "isnull",
1733 "json",
1734 "json_agg",
1735 "json_array_contains_double",
1736 "json_array_contains_json",
1737 "json_array_contains_string",
1738 "json_delete_key",
1739 "json_extract_double",
1740 "json_extract_json",
1741 "json_extract_string",
1742 "json_extract_bigint",
1743 "json_get_type",
1744 "json_length",
1745 "json_set_double",
1746 "json_set_json",
1747 "json_set_string",
1748 "kafka",
1749 "lag",
1750 "last_day",
1751 "last_insert_id",
1752 "latest",
1753 "lcase",
1754 "lead",
1755 "leaf",
1756 "least",
1757 "leaves",
1758 "length",
1759 "license",
1760 "links",
1761 "llvm",
1762 "ln",
1763 "load",
1764 "locate",
1765 "log",
1766 "log10",
1767 "log2",
1768 "lpad",
1769 "lz4",
1770 "management",
1771 "match",
1772 "mbc",
1773 "md5",
1774 "median",
1775 "memsql",
1776 "memsql_deserialize",
1777 "memsql_serialize",
1778 "metadata",
1779 "microsecond",
1780 "minute",
1781 "model",
1782 "monthname",
1783 "months_between",
1784 "mpl",
1785 "namespace",
1786 "node",
1787 "noparam",
1788 "now",
1789 "nth_value",
1790 "ntile",
1791 "nullcols",
1792 "nullif",
1793 "object",
1794 "octet_length",
1795 "offsets",
1796 "online",
1797 "optimizer",
1798 "orphan",
1799 "parquet",
1800 "partitions",
1801 "pause",
1802 "percentile_cont",
1803 "percentile_disc",
1804 "periodic",
1805 "persisted",
1806 "pi",
1807 "pipeline",
1808 "pipelines",
1809 "plancache",
1810 "plugins",
1811 "pool",
1812 "pools",
1813 "pow",
1814 "power",
1815 "process",
1816 "processlist",
1817 "profile",
1818 "profiles",
1819 "quarter",
1820 "queries",
1821 "query",
1822 "radians",
1823 "rand",
1824 "record",
1825 "reduce",
1826 "redundancy",
1827 "regexp_match",
1828 "regexp_substr",
1829 "remote",
1830 "replication",
1831 "resource",
1832 "resource_pool",
1833 "restore",
1834 "retry",
1835 "role",
1836 "roles",
1837 "round",
1838 "rpad",
1839 "rtrim",
1840 "running",
1841 "s3",
1842 "scalar",
1843 "sec_to_time",
1844 "second",
1845 "security_lists_intersect",
1846 "semi_join",
1847 "sha",
1848 "sha1",
1849 "sha2",
1850 "shard",
1851 "sharded",
1852 "sharded_id",
1853 "sigmoid",
1854 "sign",
1855 "sin",
1856 "skip",
1857 "sleep",
1858 "snapshot",
1859 "soname",
1860 "sparse",
1861 "spatial_check_index",
1862 "split",
1863 "sqrt",
1864 "standalone",
1865 "std",
1866 "stddev",
1867 "stddev_pop",
1868 "stddev_samp",
1869 "stop",
1870 "str_to_date",
1871 "subdate",
1872 "substr",
1873 "substring_index",
1874 "success",
1875 "synchronize",
1876 "table_checksum",
1877 "tan",
1878 "task",
1879 "timediff",
1880 "time_bucket",
1881 "time_format",
1882 "time_to_sec",
1883 "timestampadd",
1884 "timestampdiff",
1885 "to_base64",
1886 "to_char",
1887 "to_date",
1888 "to_days",
1889 "to_json",
1890 "to_number",
1891 "to_seconds",
1892 "to_timestamp",
1893 "tracelogs",
1894 "transform",
1895 "trim",
1896 "trunc",
1897 "truncate",
1898 "ucase",
1899 "unhex",
1900 "unix_timestamp",
1901 "utc_date",
1902 "utc_time",
1903 "utc_timestamp",
1904 "vacuum",
1905 "variance",
1906 "var_pop",
1907 "var_samp",
1908 "vector_sub",
1909 "voting",
1910 "week",
1911 "weekday",
1912 "weekofyear",
1913 "workload",
1914 "year",
1915 ]);
1916 set.remove("all");
1918 set
1919 });
1920
1921 pub static SQLITE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1925 [
1927 "abort",
1928 "action",
1929 "add",
1930 "after",
1931 "all",
1932 "alter",
1933 "always",
1934 "analyze",
1935 "and",
1936 "as",
1937 "asc",
1938 "attach",
1939 "autoincrement",
1940 "before",
1941 "begin",
1942 "between",
1943 "by",
1944 "cascade",
1945 "case",
1946 "cast",
1947 "check",
1948 "collate",
1949 "column",
1950 "commit",
1951 "conflict",
1952 "constraint",
1953 "create",
1954 "cross",
1955 "current",
1956 "current_date",
1957 "current_time",
1958 "current_timestamp",
1959 "database",
1960 "default",
1961 "deferrable",
1962 "deferred",
1963 "delete",
1964 "desc",
1965 "detach",
1966 "distinct",
1967 "do",
1968 "drop",
1969 "each",
1970 "else",
1971 "end",
1972 "escape",
1973 "except",
1974 "exclude",
1975 "exclusive",
1976 "exists",
1977 "explain",
1978 "fail",
1979 "filter",
1980 "first",
1981 "following",
1982 "for",
1983 "foreign",
1984 "from",
1985 "full",
1986 "generated",
1987 "glob",
1988 "group",
1989 "groups",
1990 "having",
1991 "if",
1992 "ignore",
1993 "immediate",
1994 "in",
1995 "index",
1996 "indexed",
1997 "initially",
1998 "inner",
1999 "insert",
2000 "instead",
2001 "intersect",
2002 "into",
2003 "is",
2004 "isnull",
2005 "join",
2006 "key",
2007 "last",
2008 "left",
2009 "like",
2010 "limit",
2011 "natural",
2012 "no",
2013 "not",
2014 "nothing",
2015 "notnull",
2016 "null",
2017 "nulls",
2018 "of",
2019 "offset",
2020 "on",
2021 "or",
2022 "order",
2023 "others",
2024 "outer",
2025 "partition",
2026 "plan",
2027 "pragma",
2028 "preceding",
2029 "primary",
2030 "query",
2031 "raise",
2032 "range",
2033 "recursive",
2034 "references",
2035 "regexp",
2036 "reindex",
2037 "release",
2038 "rename",
2039 "replace",
2040 "restrict",
2041 "returning",
2042 "right",
2043 "rollback",
2044 "row",
2045 "rows",
2046 "savepoint",
2047 "select",
2048 "set",
2049 "table",
2050 "temp",
2051 "temporary",
2052 "then",
2053 "ties",
2054 "to",
2055 "transaction",
2056 "trigger",
2057 "unbounded",
2058 "union",
2059 "unique",
2060 "update",
2061 "using",
2062 "vacuum",
2063 "values",
2064 "view",
2065 "virtual",
2066 "when",
2067 "where",
2068 "window",
2069 "with",
2070 "without",
2071 ]
2072 .into_iter()
2073 .collect()
2074 });
2075}
2076
2077impl Generator {
2078 pub fn new() -> Self {
2084 Self::with_config(GeneratorConfig::default())
2085 }
2086
2087 pub fn with_config(config: GeneratorConfig) -> Self {
2092 Self {
2093 config,
2094 output: String::new(),
2095 indent_level: 0,
2096 athena_hive_context: false,
2097 sqlite_inline_pk_columns: std::collections::HashSet::new(),
2098 merge_strip_qualifiers: Vec::new(),
2099 clickhouse_nullable_depth: 0,
2100 }
2101 }
2102
2103 fn add_column_aliases_to_query(expr: Expression) -> Expression {
2107 match expr {
2108 Expression::Select(mut select) => {
2109 select.expressions = select
2111 .expressions
2112 .into_iter()
2113 .map(|e| Self::add_alias_to_expression(e))
2114 .collect();
2115
2116 if let Some(ref mut from) = select.from {
2118 from.expressions = from
2119 .expressions
2120 .iter()
2121 .cloned()
2122 .map(|e| Self::add_column_aliases_to_query(e))
2123 .collect();
2124 }
2125
2126 Expression::Select(select)
2127 }
2128 Expression::Subquery(mut sq) => {
2129 sq.this = Self::add_column_aliases_to_query(sq.this);
2130 Expression::Subquery(sq)
2131 }
2132 Expression::Paren(mut p) => {
2133 p.this = Self::add_column_aliases_to_query(p.this);
2134 Expression::Paren(p)
2135 }
2136 other => other,
2138 }
2139 }
2140
2141 fn add_alias_to_expression(expr: Expression) -> Expression {
2144 use crate::expressions::Alias;
2145
2146 match &expr {
2147 Expression::Alias(_) => expr,
2149
2150 Expression::Column(col) => Expression::Alias(Box::new(Alias {
2152 this: expr.clone(),
2153 alias: col.name.clone(),
2154 column_aliases: Vec::new(),
2155 pre_alias_comments: Vec::new(),
2156 trailing_comments: Vec::new(),
2157 })),
2158
2159 Expression::Identifier(ident) => Expression::Alias(Box::new(Alias {
2161 this: expr.clone(),
2162 alias: ident.clone(),
2163 column_aliases: Vec::new(),
2164 pre_alias_comments: Vec::new(),
2165 trailing_comments: Vec::new(),
2166 })),
2167
2168 Expression::Subquery(sq) => {
2170 let processed = Self::add_column_aliases_to_query(Expression::Subquery(sq.clone()));
2171 if sq.alias.is_some() {
2173 processed
2174 } else {
2175 processed
2177 }
2178 }
2179
2180 Expression::Star(_) => expr,
2182
2183 _ => expr,
2186 }
2187 }
2188
2189 fn try_evaluate_constant(expr: &Expression) -> Option<i64> {
2193 match expr {
2194 Expression::Literal(Literal::Number(n)) => n.parse::<i64>().ok(),
2195 Expression::Add(op) => {
2196 let left = Self::try_evaluate_constant(&op.left)?;
2197 let right = Self::try_evaluate_constant(&op.right)?;
2198 Some(left + right)
2199 }
2200 Expression::Sub(op) => {
2201 let left = Self::try_evaluate_constant(&op.left)?;
2202 let right = Self::try_evaluate_constant(&op.right)?;
2203 Some(left - right)
2204 }
2205 Expression::Mul(op) => {
2206 let left = Self::try_evaluate_constant(&op.left)?;
2207 let right = Self::try_evaluate_constant(&op.right)?;
2208 Some(left * right)
2209 }
2210 Expression::Div(op) => {
2211 let left = Self::try_evaluate_constant(&op.left)?;
2212 let right = Self::try_evaluate_constant(&op.right)?;
2213 if right != 0 {
2214 Some(left / right)
2215 } else {
2216 None
2217 }
2218 }
2219 Expression::Paren(p) => Self::try_evaluate_constant(&p.this),
2220 _ => None,
2221 }
2222 }
2223
2224 fn is_reserved_keyword(&self, name: &str) -> bool {
2226 use crate::dialects::DialectType;
2227 let lower = name.to_lowercase();
2228 let lower_ref = lower.as_str();
2229
2230 match self.config.dialect {
2231 Some(DialectType::BigQuery) => reserved_keywords::BIGQUERY_RESERVED.contains(lower_ref),
2232 Some(DialectType::MySQL) | Some(DialectType::TiDB) => {
2233 reserved_keywords::MYSQL_RESERVED.contains(lower_ref)
2234 }
2235 Some(DialectType::Doris) => reserved_keywords::DORIS_RESERVED.contains(lower_ref),
2236 Some(DialectType::SingleStore) => {
2237 reserved_keywords::SINGLESTORE_RESERVED.contains(lower_ref)
2238 }
2239 Some(DialectType::StarRocks) => {
2240 reserved_keywords::STARROCKS_RESERVED.contains(lower_ref)
2241 }
2242 Some(DialectType::PostgreSQL)
2243 | Some(DialectType::CockroachDB)
2244 | Some(DialectType::Materialize)
2245 | Some(DialectType::RisingWave) => {
2246 reserved_keywords::POSTGRES_RESERVED.contains(lower_ref)
2247 }
2248 Some(DialectType::Redshift) => reserved_keywords::REDSHIFT_RESERVED.contains(lower_ref),
2249 Some(DialectType::Snowflake) => false,
2252 Some(DialectType::ClickHouse) => false,
2254 Some(DialectType::DuckDB) => reserved_keywords::DUCKDB_RESERVED.contains(lower_ref),
2255 Some(DialectType::Teradata) => false,
2257 Some(DialectType::TSQL)
2259 | Some(DialectType::Fabric)
2260 | Some(DialectType::Oracle)
2261 | Some(DialectType::Spark)
2262 | Some(DialectType::Databricks)
2263 | Some(DialectType::Hive)
2264 | Some(DialectType::Solr) => false,
2265 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
2266 reserved_keywords::PRESTO_TRINO_RESERVED.contains(lower_ref)
2267 }
2268 Some(DialectType::SQLite) => reserved_keywords::SQLITE_RESERVED.contains(lower_ref),
2269 Some(DialectType::Generic) | None => false,
2271 _ => reserved_keywords::SQL_RESERVED.contains(lower_ref),
2273 }
2274 }
2275
2276 fn normalize_func_name(&self, name: &str) -> String {
2278 match self.config.normalize_functions {
2279 NormalizeFunctions::Upper => name.to_uppercase(),
2280 NormalizeFunctions::Lower => name.to_lowercase(),
2281 NormalizeFunctions::None => name.to_string(),
2282 }
2283 }
2284
2285 pub fn generate(&mut self, expr: &Expression) -> Result<String> {
2294 self.output.clear();
2295 self.generate_expression(expr)?;
2296 Ok(std::mem::take(&mut self.output))
2297 }
2298
2299 pub fn sql(expr: &Expression) -> Result<String> {
2305 let mut gen = Generator::new();
2306 gen.generate(expr)
2307 }
2308
2309 pub fn pretty_sql(expr: &Expression) -> Result<String> {
2314 let config = GeneratorConfig {
2315 pretty: true,
2316 ..Default::default()
2317 };
2318 let mut gen = Generator::with_config(config);
2319 let mut sql = gen.generate(expr)?;
2320 if !sql.ends_with(';') {
2322 sql.push(';');
2323 }
2324 Ok(sql)
2325 }
2326
2327 fn generate_expression(&mut self, expr: &Expression) -> Result<()> {
2328 match expr {
2329 Expression::Select(select) => self.generate_select(select),
2330 Expression::Union(union) => self.generate_union(union),
2331 Expression::Intersect(intersect) => self.generate_intersect(intersect),
2332 Expression::Except(except) => self.generate_except(except),
2333 Expression::Insert(insert) => self.generate_insert(insert),
2334 Expression::Update(update) => self.generate_update(update),
2335 Expression::Delete(delete) => self.generate_delete(delete),
2336 Expression::Literal(lit) => self.generate_literal(lit),
2337 Expression::Boolean(b) => self.generate_boolean(b),
2338 Expression::Null(_) => {
2339 self.write_keyword("NULL");
2340 Ok(())
2341 }
2342 Expression::Identifier(id) => self.generate_identifier(id),
2343 Expression::Column(col) => self.generate_column(col),
2344 Expression::Pseudocolumn(pc) => self.generate_pseudocolumn(pc),
2345 Expression::Connect(c) => self.generate_connect_expr(c),
2346 Expression::Prior(p) => self.generate_prior(p),
2347 Expression::ConnectByRoot(cbr) => self.generate_connect_by_root(cbr),
2348 Expression::MatchRecognize(mr) => self.generate_match_recognize(mr),
2349 Expression::Table(table) => self.generate_table(table),
2350 Expression::StageReference(sr) => self.generate_stage_reference(sr),
2351 Expression::HistoricalData(hd) => self.generate_historical_data(hd),
2352 Expression::JoinedTable(jt) => self.generate_joined_table(jt),
2353 Expression::Star(star) => self.generate_star(star),
2354 Expression::BracedWildcard(expr) => self.generate_braced_wildcard(expr),
2355 Expression::Alias(alias) => self.generate_alias(alias),
2356 Expression::Cast(cast) => self.generate_cast(cast),
2357 Expression::Collation(coll) => self.generate_collation(coll),
2358 Expression::Case(case) => self.generate_case(case),
2359 Expression::Function(func) => self.generate_function(func),
2360 Expression::AggregateFunction(func) => self.generate_aggregate_function(func),
2361 Expression::WindowFunction(wf) => self.generate_window_function(wf),
2362 Expression::WithinGroup(wg) => self.generate_within_group(wg),
2363 Expression::Interval(interval) => self.generate_interval(interval),
2364
2365 Expression::ConcatWs(f) => self.generate_concat_ws(f),
2367 Expression::Substring(f) => self.generate_substring(f),
2368 Expression::Upper(f) => self.generate_unary_func("UPPER", f),
2369 Expression::Lower(f) => self.generate_unary_func("LOWER", f),
2370 Expression::Length(f) => self.generate_unary_func("LENGTH", f),
2371 Expression::Trim(f) => self.generate_trim(f),
2372 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
2373 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
2374 Expression::Replace(f) => self.generate_replace(f),
2375 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
2376 Expression::Left(f) => self.generate_left_right("LEFT", f),
2377 Expression::Right(f) => self.generate_left_right("RIGHT", f),
2378 Expression::Repeat(f) => self.generate_repeat(f),
2379 Expression::Lpad(f) => self.generate_pad("LPAD", f),
2380 Expression::Rpad(f) => self.generate_pad("RPAD", f),
2381 Expression::Split(f) => self.generate_split(f),
2382 Expression::RegexpLike(f) => self.generate_regexp_like(f),
2383 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
2384 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
2385 Expression::Overlay(f) => self.generate_overlay(f),
2386
2387 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
2389 Expression::Round(f) => self.generate_round(f),
2390 Expression::Floor(f) => self.generate_floor(f),
2391 Expression::Ceil(f) => self.generate_ceil(f),
2392 Expression::Power(f) => self.generate_power(f),
2393 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
2394 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
2395 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
2396 Expression::Log(f) => self.generate_log(f),
2397 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
2398 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
2399 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
2400 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
2401
2402 Expression::CurrentDate(_) => {
2404 self.write_keyword("CURRENT_DATE");
2405 Ok(())
2406 }
2407 Expression::CurrentTime(f) => self.generate_current_time(f),
2408 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
2409 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
2410 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
2411 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
2412 Expression::DateDiff(f) => self.generate_datediff(f),
2413 Expression::DateTrunc(f) => self.generate_date_trunc(f),
2414 Expression::Extract(f) => self.generate_extract(f),
2415 Expression::ToDate(f) => self.generate_to_date(f),
2416 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
2417
2418 Expression::Coalesce(f) => {
2420 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
2422 self.generate_vararg_func(func_name, &f.expressions)
2423 }
2424 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
2425 Expression::IfFunc(f) => self.generate_if_func(f),
2426 Expression::IfNull(f) => self.generate_ifnull(f),
2427 Expression::Nvl(f) => self.generate_nvl(f),
2428 Expression::Nvl2(f) => self.generate_nvl2(f),
2429
2430 Expression::TryCast(cast) => self.generate_try_cast(cast),
2432 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
2433
2434 Expression::Count(f) => self.generate_count(f),
2436 Expression::Sum(f) => self.generate_agg_func("SUM", f),
2437 Expression::Avg(f) => self.generate_agg_func("AVG", f),
2438 Expression::Min(f) => self.generate_agg_func("MIN", f),
2439 Expression::Max(f) => self.generate_agg_func("MAX", f),
2440 Expression::GroupConcat(f) => self.generate_group_concat(f),
2441 Expression::StringAgg(f) => self.generate_string_agg(f),
2442 Expression::ListAgg(f) => self.generate_listagg(f),
2443 Expression::ArrayAgg(f) => {
2444 let override_name = f
2447 .name
2448 .as_ref()
2449 .filter(|n| n.to_uppercase() != "ARRAY_AGG")
2450 .map(|n| n.to_uppercase());
2451 match override_name {
2452 Some(name) => self.generate_agg_func(&name, f),
2453 None => self.generate_agg_func("ARRAY_AGG", f),
2454 }
2455 }
2456 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
2457 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
2458 Expression::SumIf(f) => self.generate_sum_if(f),
2459 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
2460 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
2461 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
2462 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
2463 Expression::VarPop(f) => {
2464 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
2465 "VARIANCE_POP"
2466 } else {
2467 "VAR_POP"
2468 };
2469 self.generate_agg_func(name, f)
2470 }
2471 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
2472 Expression::Skewness(f) => {
2473 let name = match self.config.dialect {
2474 Some(DialectType::Snowflake) => "SKEW",
2475 _ => "SKEWNESS",
2476 };
2477 self.generate_agg_func(name, f)
2478 }
2479 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
2480 Expression::Mode(f) => self.generate_agg_func("MODE", f),
2481 Expression::First(f) => self.generate_agg_func("FIRST", f),
2482 Expression::Last(f) => self.generate_agg_func("LAST", f),
2483 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
2484 Expression::ApproxDistinct(f) => {
2485 match self.config.dialect {
2486 Some(DialectType::Hive)
2487 | Some(DialectType::Spark)
2488 | Some(DialectType::Databricks)
2489 | Some(DialectType::BigQuery) => {
2490 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2492 }
2493 Some(DialectType::Redshift) => {
2494 self.write_keyword("APPROXIMATE COUNT");
2496 self.write("(");
2497 self.write_keyword("DISTINCT");
2498 self.write(" ");
2499 self.generate_expression(&f.this)?;
2500 self.write(")");
2501 Ok(())
2502 }
2503 _ => self.generate_agg_func("APPROX_DISTINCT", f),
2504 }
2505 }
2506 Expression::ApproxCountDistinct(f) => {
2507 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2508 }
2509 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
2510 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
2511 Expression::LogicalAnd(f) => {
2512 let name = match self.config.dialect {
2513 Some(DialectType::Snowflake) => "BOOLAND_AGG",
2514 Some(DialectType::Spark)
2515 | Some(DialectType::Databricks)
2516 | Some(DialectType::PostgreSQL)
2517 | Some(DialectType::DuckDB)
2518 | Some(DialectType::Redshift) => "BOOL_AND",
2519 Some(DialectType::Oracle)
2520 | Some(DialectType::SQLite)
2521 | Some(DialectType::MySQL) => "MIN",
2522 _ => "BOOL_AND",
2523 };
2524 self.generate_agg_func(name, f)
2525 }
2526 Expression::LogicalOr(f) => {
2527 let name = match self.config.dialect {
2528 Some(DialectType::Snowflake) => "BOOLOR_AGG",
2529 Some(DialectType::Spark)
2530 | Some(DialectType::Databricks)
2531 | Some(DialectType::PostgreSQL)
2532 | Some(DialectType::DuckDB)
2533 | Some(DialectType::Redshift) => "BOOL_OR",
2534 Some(DialectType::Oracle)
2535 | Some(DialectType::SQLite)
2536 | Some(DialectType::MySQL) => "MAX",
2537 _ => "BOOL_OR",
2538 };
2539 self.generate_agg_func(name, f)
2540 }
2541
2542 Expression::RowNumber(_) => {
2544 if self.config.dialect == Some(DialectType::ClickHouse) {
2545 self.write("row_number");
2546 } else {
2547 self.write_keyword("ROW_NUMBER");
2548 }
2549 self.write("()");
2550 Ok(())
2551 }
2552 Expression::Rank(r) => {
2553 self.write_keyword("RANK");
2554 self.write("(");
2555 if !r.args.is_empty() {
2557 for (i, arg) in r.args.iter().enumerate() {
2558 if i > 0 {
2559 self.write(", ");
2560 }
2561 self.generate_expression(arg)?;
2562 }
2563 } else if let Some(order_by) = &r.order_by {
2564 self.write_keyword(" ORDER BY ");
2566 for (i, ob) in order_by.iter().enumerate() {
2567 if i > 0 {
2568 self.write(", ");
2569 }
2570 self.generate_ordered(ob)?;
2571 }
2572 }
2573 self.write(")");
2574 Ok(())
2575 }
2576 Expression::DenseRank(dr) => {
2577 self.write_keyword("DENSE_RANK");
2578 self.write("(");
2579 for (i, arg) in dr.args.iter().enumerate() {
2581 if i > 0 {
2582 self.write(", ");
2583 }
2584 self.generate_expression(arg)?;
2585 }
2586 self.write(")");
2587 Ok(())
2588 }
2589 Expression::NTile(f) => self.generate_ntile(f),
2590 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
2591 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
2592 Expression::FirstValue(f) => self.generate_value_func("FIRST_VALUE", f),
2593 Expression::LastValue(f) => self.generate_value_func("LAST_VALUE", f),
2594 Expression::NthValue(f) => self.generate_nth_value(f),
2595 Expression::PercentRank(pr) => {
2596 self.write_keyword("PERCENT_RANK");
2597 self.write("(");
2598 if !pr.args.is_empty() {
2600 for (i, arg) in pr.args.iter().enumerate() {
2601 if i > 0 {
2602 self.write(", ");
2603 }
2604 self.generate_expression(arg)?;
2605 }
2606 } else if let Some(order_by) = &pr.order_by {
2607 self.write_keyword(" ORDER BY ");
2609 for (i, ob) in order_by.iter().enumerate() {
2610 if i > 0 {
2611 self.write(", ");
2612 }
2613 self.generate_ordered(ob)?;
2614 }
2615 }
2616 self.write(")");
2617 Ok(())
2618 }
2619 Expression::CumeDist(cd) => {
2620 self.write_keyword("CUME_DIST");
2621 self.write("(");
2622 if !cd.args.is_empty() {
2624 for (i, arg) in cd.args.iter().enumerate() {
2625 if i > 0 {
2626 self.write(", ");
2627 }
2628 self.generate_expression(arg)?;
2629 }
2630 } else if let Some(order_by) = &cd.order_by {
2631 self.write_keyword(" ORDER BY ");
2633 for (i, ob) in order_by.iter().enumerate() {
2634 if i > 0 {
2635 self.write(", ");
2636 }
2637 self.generate_ordered(ob)?;
2638 }
2639 }
2640 self.write(")");
2641 Ok(())
2642 }
2643 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
2644 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
2645
2646 Expression::Contains(f) => {
2648 self.generate_binary_func("CONTAINS", &f.this, &f.expression)
2649 }
2650 Expression::StartsWith(f) => {
2651 let name = match self.config.dialect {
2652 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
2653 _ => "STARTS_WITH",
2654 };
2655 self.generate_binary_func(name, &f.this, &f.expression)
2656 }
2657 Expression::EndsWith(f) => {
2658 let name = match self.config.dialect {
2659 Some(DialectType::Snowflake) => "ENDSWITH",
2660 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
2661 Some(DialectType::ClickHouse) => "endsWith",
2662 _ => "ENDS_WITH",
2663 };
2664 self.generate_binary_func(name, &f.this, &f.expression)
2665 }
2666 Expression::Position(f) => self.generate_position(f),
2667 Expression::Initcap(f) => match self.config.dialect {
2668 Some(DialectType::Presto)
2669 | Some(DialectType::Trino)
2670 | Some(DialectType::Athena) => {
2671 self.write_keyword("REGEXP_REPLACE");
2672 self.write("(");
2673 self.generate_expression(&f.this)?;
2674 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
2675 Ok(())
2676 }
2677 _ => self.generate_simple_func("INITCAP", &f.this),
2678 },
2679 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
2680 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
2681 Expression::CharFunc(f) => self.generate_char_func(f),
2682 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
2683 Expression::Levenshtein(f) => {
2684 self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression)
2685 }
2686
2687 Expression::ModFunc(f) => self.generate_mod_func(f),
2689 Expression::Random(_) => {
2690 self.write_keyword("RANDOM");
2691 self.write("()");
2692 Ok(())
2693 }
2694 Expression::Rand(f) => self.generate_rand(f),
2695 Expression::TruncFunc(f) => self.generate_truncate_func(f),
2696 Expression::Pi(_) => {
2697 self.write_keyword("PI");
2698 self.write("()");
2699 Ok(())
2700 }
2701 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
2702 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
2703 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
2704 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
2705 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
2706 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
2707 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
2708 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
2709 Expression::Atan2(f) => {
2710 let name = f.original_name.as_deref().unwrap_or("ATAN2");
2711 self.generate_binary_func(name, &f.this, &f.expression)
2712 }
2713
2714 Expression::Decode(f) => self.generate_decode(f),
2716
2717 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
2719 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
2720 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
2721 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
2722 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
2723 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
2724 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
2725 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
2726 Expression::DayOfWeek(f) => {
2727 let name = match self.config.dialect {
2728 Some(DialectType::Presto)
2729 | Some(DialectType::Trino)
2730 | Some(DialectType::Athena) => "DAY_OF_WEEK",
2731 Some(DialectType::DuckDB) => "ISODOW",
2732 _ => "DAYOFWEEK",
2733 };
2734 self.generate_simple_func(name, &f.this)
2735 }
2736 Expression::DayOfMonth(f) => {
2737 let name = match self.config.dialect {
2738 Some(DialectType::Presto)
2739 | Some(DialectType::Trino)
2740 | Some(DialectType::Athena) => "DAY_OF_MONTH",
2741 _ => "DAYOFMONTH",
2742 };
2743 self.generate_simple_func(name, &f.this)
2744 }
2745 Expression::DayOfYear(f) => {
2746 let name = match self.config.dialect {
2747 Some(DialectType::Presto)
2748 | Some(DialectType::Trino)
2749 | Some(DialectType::Athena) => "DAY_OF_YEAR",
2750 _ => "DAYOFYEAR",
2751 };
2752 self.generate_simple_func(name, &f.this)
2753 }
2754 Expression::WeekOfYear(f) => {
2755 let name = match self.config.dialect {
2757 Some(DialectType::Hive)
2758 | Some(DialectType::DuckDB)
2759 | Some(DialectType::Spark)
2760 | Some(DialectType::Databricks)
2761 | Some(DialectType::MySQL) => "WEEKOFYEAR",
2762 _ => "WEEK_OF_YEAR",
2763 };
2764 self.generate_simple_func(name, &f.this)
2765 }
2766 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
2767 Expression::AddMonths(f) => {
2768 self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression)
2769 }
2770 Expression::MonthsBetween(f) => {
2771 self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression)
2772 }
2773 Expression::LastDay(f) => self.generate_last_day(f),
2774 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
2775 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
2776 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
2777 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
2778 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
2779 Expression::MakeDate(f) => self.generate_make_date(f),
2780 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
2781 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
2782
2783 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
2785 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
2786 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
2787 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
2788 Expression::ArrayContains(f) => {
2789 self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression)
2790 }
2791 Expression::ArrayPosition(f) => {
2792 self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression)
2793 }
2794 Expression::ArrayAppend(f) => {
2795 self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression)
2796 }
2797 Expression::ArrayPrepend(f) => {
2798 self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression)
2799 }
2800 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
2801 Expression::ArraySort(f) => self.generate_array_sort(f),
2802 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
2803 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
2804 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
2805 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
2806 Expression::Unnest(f) => self.generate_unnest(f),
2807 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
2808 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
2809 Expression::ArrayFilter(f) => self.generate_array_filter(f),
2810 Expression::ArrayTransform(f) => self.generate_array_transform(f),
2811 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
2812 Expression::ArrayCompact(f) => {
2813 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
2814 self.write("LIST_FILTER(");
2816 self.generate_expression(&f.this)?;
2817 self.write(", _u -> NOT _u IS NULL)");
2818 Ok(())
2819 } else {
2820 self.generate_simple_func("ARRAY_COMPACT", &f.this)
2821 }
2822 }
2823 Expression::ArrayIntersect(f) => {
2824 let func_name = f.original_name.as_deref().unwrap_or("ARRAY_INTERSECT");
2825 self.generate_vararg_func(func_name, &f.expressions)
2826 }
2827 Expression::ArrayUnion(f) => {
2828 self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression)
2829 }
2830 Expression::ArrayExcept(f) => {
2831 self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression)
2832 }
2833 Expression::ArrayRemove(f) => {
2834 self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression)
2835 }
2836 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
2837 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
2838 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
2839
2840 Expression::StructFunc(f) => self.generate_struct_constructor(f),
2842 Expression::StructExtract(f) => self.generate_struct_extract(f),
2843 Expression::NamedStruct(f) => self.generate_named_struct(f),
2844
2845 Expression::MapFunc(f) => self.generate_map_constructor(f),
2847 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
2848 Expression::MapFromArrays(f) => {
2849 self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression)
2850 }
2851 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
2852 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
2853 Expression::MapContainsKey(f) => {
2854 self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression)
2855 }
2856 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
2857 Expression::ElementAt(f) => {
2858 self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression)
2859 }
2860 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
2861 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
2862
2863 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
2865 Expression::JsonExtractScalar(f) => {
2866 self.generate_json_extract("JSON_EXTRACT_SCALAR", f)
2867 }
2868 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
2869 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
2870 Expression::JsonObject(f) => self.generate_json_object(f),
2871 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
2872 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
2873 Expression::JsonArrayLength(f) => {
2874 self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this)
2875 }
2876 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
2877 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
2878 Expression::ParseJson(f) => {
2879 let name = match self.config.dialect {
2880 Some(DialectType::Presto)
2881 | Some(DialectType::Trino)
2882 | Some(DialectType::Athena) => "JSON_PARSE",
2883 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
2884 self.write_keyword("CAST");
2886 self.write("(");
2887 self.generate_expression(&f.this)?;
2888 self.write_keyword(" AS ");
2889 self.write_keyword("JSON");
2890 self.write(")");
2891 return Ok(());
2892 }
2893 Some(DialectType::Hive)
2894 | Some(DialectType::Spark)
2895 | Some(DialectType::MySQL)
2896 | Some(DialectType::SingleStore)
2897 | Some(DialectType::TiDB)
2898 | Some(DialectType::TSQL) => {
2899 self.generate_expression(&f.this)?;
2901 return Ok(());
2902 }
2903 Some(DialectType::DuckDB) => "JSON",
2904 _ => "PARSE_JSON",
2905 };
2906 self.generate_simple_func(name, &f.this)
2907 }
2908 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
2909 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
2910 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
2911 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
2912 Expression::JsonMergePatch(f) => {
2913 self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression)
2914 }
2915 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
2916 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
2917
2918 Expression::Convert(f) => self.generate_convert(f),
2920 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
2921
2922 Expression::Lambda(f) => self.generate_lambda(f),
2924 Expression::Parameter(f) => self.generate_parameter(f),
2925 Expression::Placeholder(f) => self.generate_placeholder(f),
2926 Expression::NamedArgument(f) => self.generate_named_argument(f),
2927 Expression::TableArgument(f) => self.generate_table_argument(f),
2928 Expression::SqlComment(f) => self.generate_sql_comment(f),
2929
2930 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
2932 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
2933 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
2934 Expression::SimilarTo(f) => self.generate_similar_to(f),
2935 Expression::Any(f) => self.generate_quantified("ANY", f),
2936 Expression::All(f) => self.generate_quantified("ALL", f),
2937 Expression::Overlaps(f) => self.generate_overlaps(f),
2938
2939 Expression::BitwiseLeftShift(op) => {
2941 if matches!(
2942 self.config.dialect,
2943 Some(DialectType::Presto) | Some(DialectType::Trino)
2944 ) {
2945 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_LEFT");
2946 self.write("(");
2947 self.generate_expression(&op.left)?;
2948 self.write(", ");
2949 self.generate_expression(&op.right)?;
2950 self.write(")");
2951 Ok(())
2952 } else if matches!(
2953 self.config.dialect,
2954 Some(DialectType::Spark) | Some(DialectType::Databricks)
2955 ) {
2956 self.write_keyword("SHIFTLEFT");
2957 self.write("(");
2958 self.generate_expression(&op.left)?;
2959 self.write(", ");
2960 self.generate_expression(&op.right)?;
2961 self.write(")");
2962 Ok(())
2963 } else {
2964 self.generate_binary_op(op, "<<")
2965 }
2966 }
2967 Expression::BitwiseRightShift(op) => {
2968 if matches!(
2969 self.config.dialect,
2970 Some(DialectType::Presto) | Some(DialectType::Trino)
2971 ) {
2972 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_RIGHT");
2973 self.write("(");
2974 self.generate_expression(&op.left)?;
2975 self.write(", ");
2976 self.generate_expression(&op.right)?;
2977 self.write(")");
2978 Ok(())
2979 } else if matches!(
2980 self.config.dialect,
2981 Some(DialectType::Spark) | Some(DialectType::Databricks)
2982 ) {
2983 self.write_keyword("SHIFTRIGHT");
2984 self.write("(");
2985 self.generate_expression(&op.left)?;
2986 self.write(", ");
2987 self.generate_expression(&op.right)?;
2988 self.write(")");
2989 Ok(())
2990 } else {
2991 self.generate_binary_op(op, ">>")
2992 }
2993 }
2994 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
2995 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
2996 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
2997
2998 Expression::Subscript(s) => self.generate_subscript(s),
3000 Expression::Dot(d) => self.generate_dot_access(d),
3001 Expression::MethodCall(m) => self.generate_method_call(m),
3002 Expression::ArraySlice(s) => self.generate_array_slice(s),
3003
3004 Expression::And(op) => self.generate_binary_op(op, "AND"),
3005 Expression::Or(op) => self.generate_binary_op(op, "OR"),
3006 Expression::Add(op) => self.generate_binary_op(op, "+"),
3007 Expression::Sub(op) => self.generate_binary_op(op, "-"),
3008 Expression::Mul(op) => self.generate_binary_op(op, "*"),
3009 Expression::Div(op) => self.generate_binary_op(op, "/"),
3010 Expression::IntDiv(f) => {
3011 use crate::dialects::DialectType;
3012 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
3013 self.generate_expression(&f.this)?;
3015 self.write(" // ");
3016 self.generate_expression(&f.expression)?;
3017 Ok(())
3018 } else if matches!(
3019 self.config.dialect,
3020 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
3021 ) {
3022 self.generate_expression(&f.this)?;
3024 self.write(" ");
3025 self.write_keyword("DIV");
3026 self.write(" ");
3027 self.generate_expression(&f.expression)?;
3028 Ok(())
3029 } else {
3030 self.write_keyword("DIV");
3032 self.write("(");
3033 self.generate_expression(&f.this)?;
3034 self.write(", ");
3035 self.generate_expression(&f.expression)?;
3036 self.write(")");
3037 Ok(())
3038 }
3039 }
3040 Expression::Mod(op) => {
3041 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
3042 self.generate_binary_op(op, "MOD")
3043 } else {
3044 self.generate_binary_op(op, "%")
3045 }
3046 }
3047 Expression::Eq(op) => self.generate_binary_op(op, "="),
3048 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
3049 Expression::Lt(op) => self.generate_binary_op(op, "<"),
3050 Expression::Lte(op) => self.generate_binary_op(op, "<="),
3051 Expression::Gt(op) => self.generate_binary_op(op, ">"),
3052 Expression::Gte(op) => self.generate_binary_op(op, ">="),
3053 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
3054 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
3055 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
3056 Expression::Concat(op) => {
3057 if self.config.dialect == Some(DialectType::Solr) {
3059 self.generate_binary_op(op, "OR")
3060 } else {
3061 self.generate_binary_op(op, "||")
3062 }
3063 }
3064 Expression::BitwiseAnd(op) => {
3065 if matches!(
3067 self.config.dialect,
3068 Some(DialectType::Presto) | Some(DialectType::Trino)
3069 ) {
3070 self.write_keyword("BITWISE_AND");
3071 self.write("(");
3072 self.generate_expression(&op.left)?;
3073 self.write(", ");
3074 self.generate_expression(&op.right)?;
3075 self.write(")");
3076 Ok(())
3077 } else {
3078 self.generate_binary_op(op, "&")
3079 }
3080 }
3081 Expression::BitwiseOr(op) => {
3082 if matches!(
3084 self.config.dialect,
3085 Some(DialectType::Presto) | Some(DialectType::Trino)
3086 ) {
3087 self.write_keyword("BITWISE_OR");
3088 self.write("(");
3089 self.generate_expression(&op.left)?;
3090 self.write(", ");
3091 self.generate_expression(&op.right)?;
3092 self.write(")");
3093 Ok(())
3094 } else {
3095 self.generate_binary_op(op, "|")
3096 }
3097 }
3098 Expression::BitwiseXor(op) => {
3099 if matches!(
3101 self.config.dialect,
3102 Some(DialectType::Presto) | Some(DialectType::Trino)
3103 ) {
3104 self.write_keyword("BITWISE_XOR");
3105 self.write("(");
3106 self.generate_expression(&op.left)?;
3107 self.write(", ");
3108 self.generate_expression(&op.right)?;
3109 self.write(")");
3110 Ok(())
3111 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
3112 self.generate_binary_op(op, "#")
3113 } else {
3114 self.generate_binary_op(op, "^")
3115 }
3116 }
3117 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
3118 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
3119 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
3120 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
3121 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
3122 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
3123 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
3124 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
3125 Expression::JSONBContains(f) => {
3126 self.generate_expression(&f.this)?;
3128 self.write_space();
3129 self.write("?");
3130 self.write_space();
3131 self.generate_expression(&f.expression)
3132 }
3133 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
3134 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
3135 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
3136 Expression::Not(op) => self.generate_unary_op(op, "NOT"),
3137 Expression::Neg(op) => self.generate_unary_op(op, "-"),
3138 Expression::BitwiseNot(op) => {
3139 if matches!(
3141 self.config.dialect,
3142 Some(DialectType::Presto) | Some(DialectType::Trino)
3143 ) {
3144 self.write_keyword("BITWISE_NOT");
3145 self.write("(");
3146 self.generate_expression(&op.this)?;
3147 self.write(")");
3148 Ok(())
3149 } else {
3150 self.generate_unary_op(op, "~")
3151 }
3152 }
3153 Expression::In(in_expr) => self.generate_in(in_expr),
3154 Expression::Between(between) => self.generate_between(between),
3155 Expression::IsNull(is_null) => self.generate_is_null(is_null),
3156 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
3157 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
3158 Expression::IsJson(is_json) => self.generate_is_json(is_json),
3159 Expression::Is(is_expr) => self.generate_is(is_expr),
3160 Expression::Exists(exists) => self.generate_exists(exists),
3161 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
3162 Expression::Subquery(subquery) => self.generate_subquery(subquery),
3163 Expression::Paren(paren) => {
3164 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
3166
3167 if !skip_parens {
3168 self.write("(");
3169 if self.config.pretty {
3170 self.write_newline();
3171 self.indent_level += 1;
3172 self.write_indent();
3173 }
3174 }
3175 self.generate_expression(&paren.this)?;
3176 if !skip_parens {
3177 if self.config.pretty {
3178 self.write_newline();
3179 self.indent_level -= 1;
3180 self.write_indent();
3181 }
3182 self.write(")");
3183 }
3184 for comment in &paren.trailing_comments {
3186 self.write(" ");
3187 self.write_formatted_comment(comment);
3188 }
3189 Ok(())
3190 }
3191 Expression::Array(arr) => self.generate_array(arr),
3192 Expression::Tuple(tuple) => self.generate_tuple(tuple),
3193 Expression::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
3194 Expression::Ordered(ordered) => self.generate_ordered(ordered),
3195 Expression::DataType(dt) => self.generate_data_type(dt),
3196 Expression::Raw(raw) => {
3197 self.write(&raw.sql);
3198 Ok(())
3199 }
3200 Expression::Command(cmd) => {
3201 self.write(&cmd.this);
3202 Ok(())
3203 }
3204 Expression::Kill(kill) => {
3205 self.write_keyword("KILL");
3206 if let Some(kind) = &kill.kind {
3207 self.write_space();
3208 self.write_keyword(kind);
3209 }
3210 self.write_space();
3211 self.generate_expression(&kill.this)?;
3212 Ok(())
3213 }
3214 Expression::Execute(exec) => {
3215 self.write_keyword("EXEC");
3216 self.write_space();
3217 self.generate_expression(&exec.this)?;
3218 for (i, param) in exec.parameters.iter().enumerate() {
3219 if i == 0 {
3220 self.write_space();
3221 } else {
3222 self.write(", ");
3223 }
3224 self.write(¶m.name);
3225 self.write("=");
3226 self.generate_expression(¶m.value)?;
3227 }
3228 Ok(())
3229 }
3230 Expression::Annotated(annotated) => {
3231 self.generate_expression(&annotated.this)?;
3232 for comment in &annotated.trailing_comments {
3233 self.write(" ");
3234 self.write_formatted_comment(comment);
3235 }
3236 Ok(())
3237 }
3238
3239 Expression::CreateTable(ct) => self.generate_create_table(ct),
3241 Expression::DropTable(dt) => self.generate_drop_table(dt),
3242 Expression::AlterTable(at) => self.generate_alter_table(at),
3243 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3244 Expression::DropIndex(di) => self.generate_drop_index(di),
3245 Expression::CreateView(cv) => self.generate_create_view(cv),
3246 Expression::DropView(dv) => self.generate_drop_view(dv),
3247 Expression::AlterView(av) => self.generate_alter_view(av),
3248 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3249 Expression::Truncate(tr) => self.generate_truncate(tr),
3250 Expression::Use(u) => self.generate_use(u),
3251 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3253 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3254 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3255 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3256 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3257 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3258 Expression::DropFunction(df) => self.generate_drop_function(df),
3259 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3260 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3261 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3262 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3263 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3264 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3265 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3266 Expression::CreateType(ct) => self.generate_create_type(ct),
3267 Expression::DropType(dt) => self.generate_drop_type(dt),
3268 Expression::Describe(d) => self.generate_describe(d),
3269 Expression::Show(s) => self.generate_show(s),
3270
3271 Expression::Cache(c) => self.generate_cache(c),
3273 Expression::Uncache(u) => self.generate_uncache(u),
3274 Expression::LoadData(l) => self.generate_load_data(l),
3275 Expression::Pragma(p) => self.generate_pragma(p),
3276 Expression::Grant(g) => self.generate_grant(g),
3277 Expression::Revoke(r) => self.generate_revoke(r),
3278 Expression::Comment(c) => self.generate_comment(c),
3279 Expression::SetStatement(s) => self.generate_set_statement(s),
3280
3281 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3283 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3284
3285 Expression::Values(values) => self.generate_values(values),
3287
3288 Expression::AIAgg(e) => self.generate_ai_agg(e),
3290 Expression::AIClassify(e) => self.generate_ai_classify(e),
3291 Expression::AddPartition(e) => self.generate_add_partition(e),
3292 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3293 Expression::Aliases(e) => self.generate_aliases(e),
3294 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3295 Expression::AlterColumn(e) => self.generate_alter_column(e),
3296 Expression::AlterSession(e) => self.generate_alter_session(e),
3297 Expression::AlterSet(e) => self.generate_alter_set(e),
3298 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3299 Expression::Analyze(e) => self.generate_analyze(e),
3300 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3301 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3302 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3303 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3304 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3305 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3306 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3307 Expression::Anonymous(e) => self.generate_anonymous(e),
3308 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3309 Expression::Apply(e) => self.generate_apply(e),
3310 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3311 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3312 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3313 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3314 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3315 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3316 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3317 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3318 Expression::ArgMax(e) => self.generate_arg_max(e),
3319 Expression::ArgMin(e) => self.generate_arg_min(e),
3320 Expression::ArrayAll(e) => self.generate_array_all(e),
3321 Expression::ArrayAny(e) => self.generate_array_any(e),
3322 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3323 Expression::ArraySum(e) => self.generate_array_sum(e),
3324 Expression::AtIndex(e) => self.generate_at_index(e),
3325 Expression::Attach(e) => self.generate_attach(e),
3326 Expression::AttachOption(e) => self.generate_attach_option(e),
3327 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3328 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3329 Expression::BackupProperty(e) => self.generate_backup_property(e),
3330 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3331 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3332 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3333 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3334 Expression::Booland(e) => self.generate_booland(e),
3335 Expression::Boolor(e) => self.generate_boolor(e),
3336 Expression::BuildProperty(e) => self.generate_build_property(e),
3337 Expression::ByteString(e) => self.generate_byte_string(e),
3338 Expression::CaseSpecificColumnConstraint(e) => {
3339 self.generate_case_specific_column_constraint(e)
3340 }
3341 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3342 Expression::Changes(e) => self.generate_changes(e),
3343 Expression::CharacterSetColumnConstraint(e) => {
3344 self.generate_character_set_column_constraint(e)
3345 }
3346 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3347 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3348 Expression::CheckJson(e) => self.generate_check_json(e),
3349 Expression::CheckXml(e) => self.generate_check_xml(e),
3350 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3351 Expression::Clone(e) => self.generate_clone(e),
3352 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3353 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3354 Expression::CollateProperty(e) => self.generate_collate_property(e),
3355 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3356 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3357 Expression::ColumnPosition(e) => self.generate_column_position(e),
3358 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3359 Expression::Columns(e) => self.generate_columns(e),
3360 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3361 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3362 Expression::Commit(e) => self.generate_commit(e),
3363 Expression::Comprehension(e) => self.generate_comprehension(e),
3364 Expression::Compress(e) => self.generate_compress(e),
3365 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3366 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3367 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3368 Expression::Constraint(e) => self.generate_constraint(e),
3369 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3370 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3371 Expression::Copy(e) => self.generate_copy(e),
3372 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3373 Expression::Corr(e) => self.generate_corr(e),
3374 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3375 Expression::CovarPop(e) => self.generate_covar_pop(e),
3376 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3377 Expression::Credentials(e) => self.generate_credentials(e),
3378 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3379 Expression::Cte(e) => self.generate_cte(e),
3380 Expression::Cube(e) => self.generate_cube(e),
3381 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3382 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3383 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3384 Expression::CurrentUser(e) => self.generate_current_user(e),
3385 Expression::DPipe(e) => self.generate_d_pipe(e),
3386 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3387 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3388 Expression::Date(e) => self.generate_date_func(e),
3389 Expression::DateBin(e) => self.generate_date_bin(e),
3390 Expression::DateFormatColumnConstraint(e) => {
3391 self.generate_date_format_column_constraint(e)
3392 }
3393 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3394 Expression::Datetime(e) => self.generate_datetime(e),
3395 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3396 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3397 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3398 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3399 Expression::Dayname(e) => self.generate_dayname(e),
3400 Expression::Declare(e) => self.generate_declare(e),
3401 Expression::DeclareItem(e) => self.generate_declare_item(e),
3402 Expression::DecodeCase(e) => self.generate_decode_case(e),
3403 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3404 Expression::DecompressString(e) => self.generate_decompress_string(e),
3405 Expression::Decrypt(e) => self.generate_decrypt(e),
3406 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3407 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3408 Expression::Detach(e) => self.generate_detach(e),
3409 Expression::DictProperty(e) => self.generate_dict_property(e),
3410 Expression::DictRange(e) => self.generate_dict_range(e),
3411 Expression::Directory(e) => self.generate_directory(e),
3412 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3413 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3414 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3415 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3416 Expression::DotProduct(e) => self.generate_dot_product(e),
3417 Expression::DropPartition(e) => self.generate_drop_partition(e),
3418 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3419 Expression::Elt(e) => self.generate_elt(e),
3420 Expression::Encode(e) => self.generate_encode(e),
3421 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3422 Expression::Encrypt(e) => self.generate_encrypt(e),
3423 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3424 Expression::EngineProperty(e) => self.generate_engine_property(e),
3425 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3426 Expression::EphemeralColumnConstraint(e) => {
3427 self.generate_ephemeral_column_constraint(e)
3428 }
3429 Expression::EqualNull(e) => self.generate_equal_null(e),
3430 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3431 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3432 Expression::Export(e) => self.generate_export(e),
3433 Expression::ExternalProperty(e) => self.generate_external_property(e),
3434 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3435 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3436 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3437 Expression::Fetch(e) => self.generate_fetch(e),
3438 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3439 Expression::Filter(e) => self.generate_filter(e),
3440 Expression::Float64(e) => self.generate_float64(e),
3441 Expression::ForIn(e) => self.generate_for_in(e),
3442 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3443 Expression::Format(e) => self.generate_format(e),
3444 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3445 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3446 Expression::From(e) => self.generate_from(e),
3447 Expression::FromBase(e) => self.generate_from_base(e),
3448 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3449 Expression::GapFill(e) => self.generate_gap_fill(e),
3450 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3451 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3452 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3453 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3454 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3455 self.generate_generated_as_identity_column_constraint(e)
3456 }
3457 Expression::GeneratedAsRowColumnConstraint(e) => {
3458 self.generate_generated_as_row_column_constraint(e)
3459 }
3460 Expression::Get(e) => self.generate_get(e),
3461 Expression::GetExtract(e) => self.generate_get_extract(e),
3462 Expression::Getbit(e) => self.generate_getbit(e),
3463 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3464 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3465 Expression::Group(e) => self.generate_group(e),
3466 Expression::GroupBy(e) => self.generate_group_by(e),
3467 Expression::Grouping(e) => self.generate_grouping(e),
3468 Expression::GroupingId(e) => self.generate_grouping_id(e),
3469 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3470 Expression::HashAgg(e) => self.generate_hash_agg(e),
3471 Expression::Having(e) => self.generate_having(e),
3472 Expression::HavingMax(e) => self.generate_having_max(e),
3473 Expression::Heredoc(e) => self.generate_heredoc(e),
3474 Expression::HexEncode(e) => self.generate_hex_encode(e),
3475 Expression::Hll(e) => self.generate_hll(e),
3476 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3477 Expression::IncludeProperty(e) => self.generate_include_property(e),
3478 Expression::Index(e) => self.generate_index(e),
3479 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3480 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3481 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3482 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3483 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3484 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3485 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3486 Expression::Install(e) => self.generate_install(e),
3487 Expression::IntervalOp(e) => self.generate_interval_op(e),
3488 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3489 Expression::IntoClause(e) => self.generate_into_clause(e),
3490 Expression::Introducer(e) => self.generate_introducer(e),
3491 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3492 Expression::JSON(e) => self.generate_json(e),
3493 Expression::JSONArray(e) => self.generate_json_array(e),
3494 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3495 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3496 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3497 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3498 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3499 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3500 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3501 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3502 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3503 Expression::JSONExists(e) => self.generate_json_exists(e),
3504 Expression::JSONCast(e) => self.generate_json_cast(e),
3505 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3506 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3507 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3508 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3509 Expression::JSONFormat(e) => self.generate_json_format(e),
3510 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3511 Expression::JSONKeys(e) => self.generate_json_keys(e),
3512 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3513 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3514 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3515 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3516 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3517 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3518 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3519 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3520 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3521 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3522 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3523 Expression::JSONRemove(e) => self.generate_json_remove(e),
3524 Expression::JSONSchema(e) => self.generate_json_schema(e),
3525 Expression::JSONSet(e) => self.generate_json_set(e),
3526 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3527 Expression::JSONTable(e) => self.generate_json_table(e),
3528 Expression::JSONType(e) => self.generate_json_type(e),
3529 Expression::JSONValue(e) => self.generate_json_value(e),
3530 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3531 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3532 Expression::JoinHint(e) => self.generate_join_hint(e),
3533 Expression::JournalProperty(e) => self.generate_journal_property(e),
3534 Expression::LanguageProperty(e) => self.generate_language_property(e),
3535 Expression::Lateral(e) => self.generate_lateral(e),
3536 Expression::LikeProperty(e) => self.generate_like_property(e),
3537 Expression::Limit(e) => self.generate_limit(e),
3538 Expression::LimitOptions(e) => self.generate_limit_options(e),
3539 Expression::List(e) => self.generate_list(e),
3540 Expression::ToMap(e) => self.generate_tomap(e),
3541 Expression::Localtime(e) => self.generate_localtime(e),
3542 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3543 Expression::LocationProperty(e) => self.generate_location_property(e),
3544 Expression::Lock(e) => self.generate_lock(e),
3545 Expression::LockProperty(e) => self.generate_lock_property(e),
3546 Expression::LockingProperty(e) => self.generate_locking_property(e),
3547 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3548 Expression::LogProperty(e) => self.generate_log_property(e),
3549 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3550 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3551 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3552 Expression::MakeInterval(e) => self.generate_make_interval(e),
3553 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3554 Expression::Map(e) => self.generate_map(e),
3555 Expression::MapCat(e) => self.generate_map_cat(e),
3556 Expression::MapDelete(e) => self.generate_map_delete(e),
3557 Expression::MapInsert(e) => self.generate_map_insert(e),
3558 Expression::MapPick(e) => self.generate_map_pick(e),
3559 Expression::MaskingPolicyColumnConstraint(e) => {
3560 self.generate_masking_policy_column_constraint(e)
3561 }
3562 Expression::MatchAgainst(e) => self.generate_match_against(e),
3563 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3564 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3565 Expression::Merge(e) => self.generate_merge(e),
3566 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3567 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3568 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3569 Expression::Minhash(e) => self.generate_minhash(e),
3570 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3571 Expression::Monthname(e) => self.generate_monthname(e),
3572 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3573 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3574 Expression::Normal(e) => self.generate_normal(e),
3575 Expression::Normalize(e) => self.generate_normalize(e),
3576 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3577 Expression::Nullif(e) => self.generate_nullif(e),
3578 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3579 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3580 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3581 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3582 Expression::Offset(e) => self.generate_offset(e),
3583 Expression::Qualify(e) => self.generate_qualify(e),
3584 Expression::OnCluster(e) => self.generate_on_cluster(e),
3585 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3586 Expression::OnCondition(e) => self.generate_on_condition(e),
3587 Expression::OnConflict(e) => self.generate_on_conflict(e),
3588 Expression::OnProperty(e) => self.generate_on_property(e),
3589 Expression::Opclass(e) => self.generate_opclass(e),
3590 Expression::OpenJSON(e) => self.generate_open_json(e),
3591 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3592 Expression::Operator(e) => self.generate_operator(e),
3593 Expression::OrderBy(e) => self.generate_order_by(e),
3594 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3595 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3596 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3597 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3598 Expression::ParseIp(e) => self.generate_parse_ip(e),
3599 Expression::ParseJSON(e) => self.generate_parse_json(e),
3600 Expression::ParseTime(e) => self.generate_parse_time(e),
3601 Expression::ParseUrl(e) => self.generate_parse_url(e),
3602 Expression::Partition(e) => self.generate_partition_expr(e),
3603 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3604 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3605 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3606 Expression::PartitionByRangePropertyDynamic(e) => {
3607 self.generate_partition_by_range_property_dynamic(e)
3608 }
3609 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3610 Expression::PartitionList(e) => self.generate_partition_list(e),
3611 Expression::PartitionRange(e) => self.generate_partition_range(e),
3612 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3613 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3614 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3615 Expression::PeriodForSystemTimeConstraint(e) => {
3616 self.generate_period_for_system_time_constraint(e)
3617 }
3618 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3619 Expression::PivotAny(e) => self.generate_pivot_any(e),
3620 Expression::Predict(e) => self.generate_predict(e),
3621 Expression::PreviousDay(e) => self.generate_previous_day(e),
3622 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3623 Expression::PrimaryKeyColumnConstraint(e) => {
3624 self.generate_primary_key_column_constraint(e)
3625 }
3626 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3627 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3628 Expression::Properties(e) => self.generate_properties(e),
3629 Expression::Property(e) => self.generate_property(e),
3630 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3631 Expression::Put(e) => self.generate_put(e),
3632 Expression::Quantile(e) => self.generate_quantile(e),
3633 Expression::QueryBand(e) => self.generate_query_band(e),
3634 Expression::QueryOption(e) => self.generate_query_option(e),
3635 Expression::QueryTransform(e) => self.generate_query_transform(e),
3636 Expression::Randn(e) => self.generate_randn(e),
3637 Expression::Randstr(e) => self.generate_randstr(e),
3638 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3639 Expression::RangeN(e) => self.generate_range_n(e),
3640 Expression::ReadCSV(e) => self.generate_read_csv(e),
3641 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3642 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3643 Expression::Reduce(e) => self.generate_reduce(e),
3644 Expression::Reference(e) => self.generate_reference(e),
3645 Expression::Refresh(e) => self.generate_refresh(e),
3646 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3647 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3648 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3649 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3650 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3651 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3652 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3653 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3654 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3655 Expression::RegrCount(e) => self.generate_regr_count(e),
3656 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3657 Expression::RegrR2(e) => self.generate_regr_r2(e),
3658 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3659 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3660 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3661 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3662 Expression::RegrValx(e) => self.generate_regr_valx(e),
3663 Expression::RegrValy(e) => self.generate_regr_valy(e),
3664 Expression::RemoteWithConnectionModelProperty(e) => {
3665 self.generate_remote_with_connection_model_property(e)
3666 }
3667 Expression::RenameColumn(e) => self.generate_rename_column(e),
3668 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3669 Expression::Returning(e) => self.generate_returning(e),
3670 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3671 Expression::Rollback(e) => self.generate_rollback(e),
3672 Expression::Rollup(e) => self.generate_rollup(e),
3673 Expression::RowFormatDelimitedProperty(e) => {
3674 self.generate_row_format_delimited_property(e)
3675 }
3676 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3677 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3678 Expression::SHA2(e) => self.generate_sha2(e),
3679 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3680 Expression::SafeAdd(e) => self.generate_safe_add(e),
3681 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3682 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3683 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3684 Expression::SampleProperty(e) => self.generate_sample_property(e),
3685 Expression::Schema(e) => self.generate_schema(e),
3686 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3687 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3688 Expression::Search(e) => self.generate_search(e),
3689 Expression::SearchIp(e) => self.generate_search_ip(e),
3690 Expression::SecurityProperty(e) => self.generate_security_property(e),
3691 Expression::SemanticView(e) => self.generate_semantic_view(e),
3692 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3693 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3694 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3695 Expression::Set(e) => self.generate_set(e),
3696 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3697 Expression::SetItem(e) => self.generate_set_item(e),
3698 Expression::SetOperation(e) => self.generate_set_operation(e),
3699 Expression::SetProperty(e) => self.generate_set_property(e),
3700 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3701 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3702 Expression::Slice(e) => self.generate_slice(e),
3703 Expression::SortArray(e) => self.generate_sort_array(e),
3704 Expression::SortBy(e) => self.generate_sort_by(e),
3705 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3706 Expression::SplitPart(e) => self.generate_split_part(e),
3707 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3708 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3709 Expression::StDistance(e) => self.generate_st_distance(e),
3710 Expression::StPoint(e) => self.generate_st_point(e),
3711 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3712 Expression::StandardHash(e) => self.generate_standard_hash(e),
3713 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3714 Expression::StrPosition(e) => self.generate_str_position(e),
3715 Expression::StrToDate(e) => self.generate_str_to_date(e),
3716 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3717 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3718 Expression::StrToMap(e) => self.generate_str_to_map(e),
3719 Expression::StrToTime(e) => self.generate_str_to_time(e),
3720 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3721 Expression::StringToArray(e) => self.generate_string_to_array(e),
3722 Expression::Struct(e) => self.generate_struct(e),
3723 Expression::Stuff(e) => self.generate_stuff(e),
3724 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3725 Expression::Summarize(e) => self.generate_summarize(e),
3726 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3727 Expression::TableAlias(e) => self.generate_table_alias(e),
3728 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3729 Expression::RowsFrom(e) => self.generate_rows_from(e),
3730 Expression::TableSample(e) => self.generate_table_sample(e),
3731 Expression::Tag(e) => self.generate_tag(e),
3732 Expression::Tags(e) => self.generate_tags(e),
3733 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3734 Expression::Time(e) => self.generate_time_func(e),
3735 Expression::TimeAdd(e) => self.generate_time_add(e),
3736 Expression::TimeDiff(e) => self.generate_time_diff(e),
3737 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3738 Expression::TimeSlice(e) => self.generate_time_slice(e),
3739 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3740 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3741 Expression::TimeSub(e) => self.generate_time_sub(e),
3742 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3743 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3744 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3745 Expression::TimeUnit(e) => self.generate_time_unit(e),
3746 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3747 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3748 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3749 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3750 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3751 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3752 Expression::ToBinary(e) => self.generate_to_binary(e),
3753 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3754 Expression::ToChar(e) => self.generate_to_char(e),
3755 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3756 Expression::ToDouble(e) => self.generate_to_double(e),
3757 Expression::ToFile(e) => self.generate_to_file(e),
3758 Expression::ToNumber(e) => self.generate_to_number(e),
3759 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3760 Expression::Transaction(e) => self.generate_transaction(e),
3761 Expression::Transform(e) => self.generate_transform(e),
3762 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3763 Expression::TransientProperty(e) => self.generate_transient_property(e),
3764 Expression::Translate(e) => self.generate_translate(e),
3765 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
3766 Expression::TruncateTable(e) => self.generate_truncate_table(e),
3767 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
3768 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
3769 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
3770 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
3771 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
3772 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
3773 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
3774 Expression::Unhex(e) => self.generate_unhex(e),
3775 Expression::UnicodeString(e) => self.generate_unicode_string(e),
3776 Expression::Uniform(e) => self.generate_uniform(e),
3777 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
3778 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
3779 Expression::RollupProperty(e) => self.generate_rollup_property(e),
3780 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
3781 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
3782 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
3783 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
3784 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
3785 Expression::UtcTime(e) => self.generate_utc_time(e),
3786 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
3787 Expression::Uuid(e) => self.generate_uuid(e),
3788 Expression::Var(v) => {
3789 if matches!(self.config.dialect, Some(DialectType::MySQL))
3790 && v.this.len() > 2
3791 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
3792 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
3793 {
3794 return self.generate_identifier(&Identifier {
3795 name: v.this.clone(),
3796 quoted: true,
3797 trailing_comments: Vec::new(),
3798 });
3799 }
3800 self.write(&v.this);
3801 Ok(())
3802 }
3803 Expression::Variadic(e) => {
3804 self.write_keyword("VARIADIC");
3805 self.write_space();
3806 self.generate_expression(&e.this)?;
3807 Ok(())
3808 }
3809 Expression::VarMap(e) => self.generate_var_map(e),
3810 Expression::VectorSearch(e) => self.generate_vector_search(e),
3811 Expression::Version(e) => self.generate_version(e),
3812 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
3813 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
3814 Expression::WatermarkColumnConstraint(e) => {
3815 self.generate_watermark_column_constraint(e)
3816 }
3817 Expression::Week(e) => self.generate_week(e),
3818 Expression::When(e) => self.generate_when(e),
3819 Expression::Whens(e) => self.generate_whens(e),
3820 Expression::Where(e) => self.generate_where(e),
3821 Expression::WidthBucket(e) => self.generate_width_bucket(e),
3822 Expression::Window(e) => self.generate_window(e),
3823 Expression::WindowSpec(e) => self.generate_window_spec(e),
3824 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
3825 Expression::WithFill(e) => self.generate_with_fill(e),
3826 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
3827 Expression::WithOperator(e) => self.generate_with_operator(e),
3828 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
3829 Expression::WithSchemaBindingProperty(e) => {
3830 self.generate_with_schema_binding_property(e)
3831 }
3832 Expression::WithSystemVersioningProperty(e) => {
3833 self.generate_with_system_versioning_property(e)
3834 }
3835 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
3836 Expression::XMLElement(e) => self.generate_xml_element(e),
3837 Expression::XMLGet(e) => self.generate_xml_get(e),
3838 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
3839 Expression::XMLTable(e) => self.generate_xml_table(e),
3840 Expression::Xor(e) => self.generate_xor(e),
3841 Expression::Zipf(e) => self.generate_zipf(e),
3842 _ => {
3843 self.write(&format!("/* unimplemented: {:?} */", expr));
3845 Ok(())
3846 }
3847 }
3848 }
3849
3850 fn generate_select(&mut self, select: &Select) -> Result<()> {
3851 use crate::dialects::DialectType;
3852
3853 for comment in &select.leading_comments {
3855 self.write_formatted_comment(comment);
3856 self.write(" ");
3857 }
3858
3859 if let Some(with) = &select.with {
3861 self.generate_with(with)?;
3862 if self.config.pretty {
3863 self.write_newline();
3864 self.write_indent();
3865 } else {
3866 self.write_space();
3867 }
3868 }
3869
3870 for comment in &select.post_select_comments {
3873 self.write_formatted_comment(comment);
3874 self.write(" ");
3875 }
3876
3877 self.write_keyword("SELECT");
3878
3879 if let Some(hint) = &select.hint {
3881 self.generate_hint(hint)?;
3882 }
3883
3884 let use_top_from_limit = matches!(self.config.dialect, Some(DialectType::TSQL))
3888 && select.top.is_none()
3889 && select.limit.is_some()
3890 && select.offset.is_none(); let is_top_dialect = matches!(
3895 self.config.dialect,
3896 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
3897 );
3898 let keep_top_verbatim = !is_top_dialect
3899 && select.limit.is_none()
3900 && select
3901 .top
3902 .as_ref()
3903 .map_or(false, |top| top.percent || top.with_ties);
3904
3905 if select.distinct && (is_top_dialect || select.top.is_some()) {
3906 self.write_space();
3907 self.write_keyword("DISTINCT");
3908 }
3909
3910 if is_top_dialect || keep_top_verbatim {
3911 if let Some(top) = &select.top {
3912 self.write_space();
3913 self.write_keyword("TOP");
3914 if top.parenthesized {
3915 self.write(" (");
3916 self.generate_expression(&top.this)?;
3917 self.write(")");
3918 } else {
3919 self.write_space();
3920 self.generate_expression(&top.this)?;
3921 }
3922 if top.percent {
3923 self.write_space();
3924 self.write_keyword("PERCENT");
3925 }
3926 if top.with_ties {
3927 self.write_space();
3928 self.write_keyword("WITH TIES");
3929 }
3930 } else if use_top_from_limit {
3931 if let Some(limit) = &select.limit {
3933 self.write_space();
3934 self.write_keyword("TOP");
3935 let is_simple_literal =
3937 matches!(&limit.this, Expression::Literal(Literal::Number(_)));
3938 if is_simple_literal {
3939 self.write_space();
3940 self.generate_expression(&limit.this)?;
3941 } else {
3942 self.write(" (");
3943 self.generate_expression(&limit.this)?;
3944 self.write(")");
3945 }
3946 }
3947 }
3948 }
3949
3950 if select.distinct && !is_top_dialect && select.top.is_none() {
3951 self.write_space();
3952 self.write_keyword("DISTINCT");
3953 }
3954
3955 if let Some(distinct_on) = &select.distinct_on {
3957 self.write_space();
3958 self.write_keyword("ON");
3959 self.write(" (");
3960 for (i, expr) in distinct_on.iter().enumerate() {
3961 if i > 0 {
3962 self.write(", ");
3963 }
3964 self.generate_expression(expr)?;
3965 }
3966 self.write(")");
3967 }
3968
3969 for modifier in &select.operation_modifiers {
3971 self.write_space();
3972 self.write_keyword(modifier);
3973 }
3974
3975 if let Some(kind) = &select.kind {
3977 self.write_space();
3978 self.write_keyword("AS");
3979 self.write_space();
3980 self.write_keyword(kind);
3981 }
3982
3983 if !select.expressions.is_empty() {
3985 if self.config.pretty {
3986 self.write_newline();
3987 self.indent_level += 1;
3988 } else {
3989 self.write_space();
3990 }
3991 }
3992
3993 for (i, expr) in select.expressions.iter().enumerate() {
3994 if i > 0 {
3995 self.write(",");
3996 if self.config.pretty {
3997 self.write_newline();
3998 } else {
3999 self.write_space();
4000 }
4001 }
4002 if self.config.pretty {
4003 self.write_indent();
4004 }
4005 self.generate_expression(expr)?;
4006 }
4007
4008 if self.config.pretty && !select.expressions.is_empty() {
4009 self.indent_level -= 1;
4010 }
4011
4012 if let Some(into) = &select.into {
4015 if self.config.pretty {
4016 self.write_newline();
4017 self.write_indent();
4018 } else {
4019 self.write_space();
4020 }
4021 if into.bulk_collect {
4022 self.write_keyword("BULK COLLECT INTO");
4023 } else {
4024 self.write_keyword("INTO");
4025 }
4026 if into.temporary {
4027 self.write_space();
4028 self.write_keyword("TEMPORARY");
4029 }
4030 if into.unlogged {
4031 self.write_space();
4032 self.write_keyword("UNLOGGED");
4033 }
4034 self.write_space();
4035 if !into.expressions.is_empty() {
4037 for (i, expr) in into.expressions.iter().enumerate() {
4038 if i > 0 {
4039 self.write(", ");
4040 }
4041 self.generate_expression(expr)?;
4042 }
4043 } else {
4044 self.generate_expression(&into.this)?;
4045 }
4046 }
4047
4048 if let Some(from) = &select.from {
4050 if self.config.pretty {
4051 self.write_newline();
4052 self.write_indent();
4053 } else {
4054 self.write_space();
4055 }
4056 self.write_keyword("FROM");
4057 self.write_space();
4058
4059 let has_tablesample = from
4064 .expressions
4065 .iter()
4066 .any(|e| matches!(e, Expression::TableSample(_)));
4067 let is_cross_join_dialect = matches!(
4068 self.config.dialect,
4069 Some(DialectType::BigQuery)
4070 | Some(DialectType::Hive)
4071 | Some(DialectType::Spark)
4072 | Some(DialectType::Databricks)
4073 | Some(DialectType::SQLite)
4074 | Some(DialectType::ClickHouse)
4075 );
4076 let source_is_same_as_target = self.config.source_dialect.is_some()
4079 && self.config.source_dialect == self.config.dialect;
4080 let source_is_cross_join_dialect = matches!(
4081 self.config.source_dialect,
4082 Some(DialectType::BigQuery)
4083 | Some(DialectType::Hive)
4084 | Some(DialectType::Spark)
4085 | Some(DialectType::Databricks)
4086 | Some(DialectType::SQLite)
4087 | Some(DialectType::ClickHouse)
4088 );
4089 let use_cross_join = !has_tablesample
4090 && is_cross_join_dialect
4091 && (source_is_same_as_target
4092 || source_is_cross_join_dialect
4093 || self.config.source_dialect.is_none());
4094
4095 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4097
4098 for (i, expr) in from.expressions.iter().enumerate() {
4099 if i > 0 {
4100 if use_cross_join {
4101 self.write(" CROSS JOIN ");
4102 } else {
4103 self.write(", ");
4104 }
4105 }
4106 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4107 self.write("(");
4108 self.generate_expression(expr)?;
4109 self.write(")");
4110 } else {
4111 self.generate_expression(expr)?;
4112 }
4113 }
4114 }
4115
4116 if self.config.pretty {
4120 self.generate_joins_with_nesting(&select.joins)?;
4121 } else {
4122 for join in &select.joins {
4123 self.generate_join(join)?;
4124 }
4125 for join in select.joins.iter().rev() {
4127 if join.deferred_condition {
4128 self.generate_join_condition(join)?;
4129 }
4130 }
4131 }
4132
4133 for lateral_view in &select.lateral_views {
4135 self.generate_lateral_view(lateral_view)?;
4136 }
4137
4138 if let Some(prewhere) = &select.prewhere {
4140 self.write_clause_condition("PREWHERE", prewhere)?;
4141 }
4142
4143 if let Some(where_clause) = &select.where_clause {
4145 self.write_clause_condition("WHERE", &where_clause.this)?;
4146 }
4147
4148 if let Some(connect) = &select.connect {
4150 self.generate_connect(connect)?;
4151 }
4152
4153 if let Some(group_by) = &select.group_by {
4155 if self.config.pretty {
4156 for comment in &group_by.comments {
4158 self.write_newline();
4159 self.write_indent();
4160 self.write_formatted_comment(comment);
4161 }
4162 self.write_newline();
4163 self.write_indent();
4164 } else {
4165 self.write_space();
4166 for comment in &group_by.comments {
4168 self.write_formatted_comment(comment);
4169 self.write_space();
4170 }
4171 }
4172 self.write_keyword("GROUP BY");
4173 match group_by.all {
4175 Some(true) => {
4176 self.write_space();
4177 self.write_keyword("ALL");
4178 }
4179 Some(false) => {
4180 self.write_space();
4181 self.write_keyword("DISTINCT");
4182 }
4183 None => {}
4184 }
4185 if !group_by.expressions.is_empty() {
4186 let mut trailing_cube = false;
4189 let mut trailing_rollup = false;
4190 let mut plain_expressions: Vec<&Expression> = Vec::new();
4191 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4192 let mut cube_expressions: Vec<&Expression> = Vec::new();
4193 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4194
4195 for expr in &group_by.expressions {
4196 match expr {
4197 Expression::Cube(c) if c.expressions.is_empty() => {
4198 trailing_cube = true;
4199 }
4200 Expression::Rollup(r) if r.expressions.is_empty() => {
4201 trailing_rollup = true;
4202 }
4203 Expression::Function(f) if f.name == "CUBE" => {
4204 cube_expressions.push(expr);
4205 }
4206 Expression::Function(f) if f.name == "ROLLUP" => {
4207 rollup_expressions.push(expr);
4208 }
4209 Expression::Function(f) if f.name == "GROUPING SETS" => {
4210 grouping_sets_expressions.push(expr);
4211 }
4212 _ => {
4213 plain_expressions.push(expr);
4214 }
4215 }
4216 }
4217
4218 let mut regular_expressions: Vec<&Expression> = Vec::new();
4220 regular_expressions.extend(plain_expressions);
4221 regular_expressions.extend(grouping_sets_expressions);
4222 regular_expressions.extend(cube_expressions);
4223 regular_expressions.extend(rollup_expressions);
4224
4225 if self.config.pretty {
4226 self.write_newline();
4227 self.indent_level += 1;
4228 self.write_indent();
4229 } else {
4230 self.write_space();
4231 }
4232
4233 for (i, expr) in regular_expressions.iter().enumerate() {
4234 if i > 0 {
4235 if self.config.pretty {
4236 self.write(",");
4237 self.write_newline();
4238 self.write_indent();
4239 } else {
4240 self.write(", ");
4241 }
4242 }
4243 self.generate_expression(expr)?;
4244 }
4245
4246 if self.config.pretty {
4247 self.indent_level -= 1;
4248 }
4249
4250 if trailing_cube {
4252 self.write_space();
4253 self.write_keyword("WITH CUBE");
4254 } else if trailing_rollup {
4255 self.write_space();
4256 self.write_keyword("WITH ROLLUP");
4257 }
4258 }
4259
4260 if group_by.totals {
4262 self.write_space();
4263 self.write_keyword("WITH TOTALS");
4264 }
4265 }
4266
4267 if let Some(having) = &select.having {
4269 if self.config.pretty {
4270 for comment in &having.comments {
4272 self.write_newline();
4273 self.write_indent();
4274 self.write_formatted_comment(comment);
4275 }
4276 } else {
4277 for comment in &having.comments {
4278 self.write_space();
4279 self.write_formatted_comment(comment);
4280 }
4281 }
4282 self.write_clause_condition("HAVING", &having.this)?;
4283 }
4284
4285 if select.qualify_after_window {
4287 if let Some(windows) = &select.windows {
4289 self.write_window_clause(windows)?;
4290 }
4291 if let Some(qualify) = &select.qualify {
4292 self.write_clause_condition("QUALIFY", &qualify.this)?;
4293 }
4294 } else {
4295 if let Some(qualify) = &select.qualify {
4297 self.write_clause_condition("QUALIFY", &qualify.this)?;
4298 }
4299 if let Some(windows) = &select.windows {
4300 self.write_window_clause(windows)?;
4301 }
4302 }
4303
4304 if let Some(distribute_by) = &select.distribute_by {
4306 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4307 }
4308
4309 if let Some(cluster_by) = &select.cluster_by {
4311 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4312 }
4313
4314 if let Some(sort_by) = &select.sort_by {
4316 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4317 }
4318
4319 if let Some(order_by) = &select.order_by {
4321 if self.config.pretty {
4322 for comment in &order_by.comments {
4324 self.write_newline();
4325 self.write_indent();
4326 self.write_formatted_comment(comment);
4327 }
4328 } else {
4329 for comment in &order_by.comments {
4330 self.write_space();
4331 self.write_formatted_comment(comment);
4332 }
4333 }
4334 let keyword = if order_by.siblings {
4335 "ORDER SIBLINGS BY"
4336 } else {
4337 "ORDER BY"
4338 };
4339 self.write_order_clause(keyword, &order_by.expressions)?;
4340 }
4341
4342 if select.order_by.is_none()
4344 && select.fetch.is_some()
4345 && matches!(
4346 self.config.dialect,
4347 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4348 )
4349 {
4350 if self.config.pretty {
4351 self.write_newline();
4352 self.write_indent();
4353 } else {
4354 self.write_space();
4355 }
4356 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4357 }
4358
4359 let is_presto_like = matches!(
4364 self.config.dialect,
4365 Some(DialectType::Presto) | Some(DialectType::Trino)
4366 );
4367
4368 if is_presto_like && select.offset.is_some() {
4369 if let Some(offset) = &select.offset {
4371 if self.config.pretty {
4372 self.write_newline();
4373 self.write_indent();
4374 } else {
4375 self.write_space();
4376 }
4377 self.write_keyword("OFFSET");
4378 self.write_space();
4379 self.write_limit_expr(&offset.this)?;
4380 if offset.rows == Some(true) {
4381 self.write_space();
4382 self.write_keyword("ROWS");
4383 }
4384 }
4385 if let Some(limit) = &select.limit {
4386 if self.config.pretty {
4387 self.write_newline();
4388 self.write_indent();
4389 } else {
4390 self.write_space();
4391 }
4392 self.write_keyword("LIMIT");
4393 self.write_space();
4394 self.write_limit_expr(&limit.this)?;
4395 if limit.percent {
4396 self.write_space();
4397 self.write_keyword("PERCENT");
4398 }
4399 for comment in &limit.comments {
4401 self.write(" ");
4402 self.write_formatted_comment(comment);
4403 }
4404 }
4405 } else {
4406 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
4408 !fetch.percent
4409 && !fetch.with_ties
4410 && fetch.count.is_some()
4411 && matches!(
4412 self.config.dialect,
4413 Some(DialectType::Spark)
4414 | Some(DialectType::Hive)
4415 | Some(DialectType::DuckDB)
4416 | Some(DialectType::SQLite)
4417 | Some(DialectType::MySQL)
4418 | Some(DialectType::BigQuery)
4419 | Some(DialectType::Databricks)
4420 | Some(DialectType::StarRocks)
4421 | Some(DialectType::Doris)
4422 | Some(DialectType::Athena)
4423 | Some(DialectType::ClickHouse)
4424 | Some(DialectType::Redshift)
4425 )
4426 });
4427
4428 if let Some(limit) = &select.limit {
4430 if !matches!(self.config.dialect, Some(DialectType::TSQL)) {
4432 if self.config.pretty {
4433 self.write_newline();
4434 self.write_indent();
4435 } else {
4436 self.write_space();
4437 }
4438 self.write_keyword("LIMIT");
4439 self.write_space();
4440 self.write_limit_expr(&limit.this)?;
4441 if limit.percent {
4442 self.write_space();
4443 self.write_keyword("PERCENT");
4444 }
4445 for comment in &limit.comments {
4447 self.write(" ");
4448 self.write_formatted_comment(comment);
4449 }
4450 }
4451 }
4452
4453 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
4455 if let Some(top) = &select.top {
4456 if !top.percent && !top.with_ties {
4457 if self.config.pretty {
4458 self.write_newline();
4459 self.write_indent();
4460 } else {
4461 self.write_space();
4462 }
4463 self.write_keyword("LIMIT");
4464 self.write_space();
4465 self.generate_expression(&top.this)?;
4466 }
4467 }
4468 }
4469
4470 if fetch_as_limit && select.offset.is_some() {
4473 if let Some(fetch) = &select.fetch {
4474 if self.config.pretty {
4475 self.write_newline();
4476 self.write_indent();
4477 } else {
4478 self.write_space();
4479 }
4480 self.write_keyword("LIMIT");
4481 self.write_space();
4482 self.generate_expression(fetch.count.as_ref().unwrap())?;
4483 }
4484 }
4485
4486 if let Some(offset) = &select.offset {
4490 if self.config.pretty {
4491 self.write_newline();
4492 self.write_indent();
4493 } else {
4494 self.write_space();
4495 }
4496 if matches!(self.config.dialect, Some(DialectType::TSQL)) {
4497 self.write_keyword("OFFSET");
4499 self.write_space();
4500 self.write_limit_expr(&offset.this)?;
4501 self.write_space();
4502 self.write_keyword("ROWS");
4503 if let Some(limit) = &select.limit {
4505 self.write_space();
4506 self.write_keyword("FETCH NEXT");
4507 self.write_space();
4508 self.write_limit_expr(&limit.this)?;
4509 self.write_space();
4510 self.write_keyword("ROWS ONLY");
4511 }
4512 } else {
4513 self.write_keyword("OFFSET");
4514 self.write_space();
4515 self.write_limit_expr(&offset.this)?;
4516 if offset.rows == Some(true) {
4518 self.write_space();
4519 self.write_keyword("ROWS");
4520 }
4521 }
4522 }
4523 }
4524
4525 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4527 if let Some(limit_by) = &select.limit_by {
4528 if !limit_by.is_empty() {
4529 self.write_space();
4530 self.write_keyword("BY");
4531 self.write_space();
4532 for (i, expr) in limit_by.iter().enumerate() {
4533 if i > 0 {
4534 self.write(", ");
4535 }
4536 self.generate_expression(expr)?;
4537 }
4538 }
4539 }
4540 }
4541
4542 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4544 if let Some(settings) = &select.settings {
4545 if self.config.pretty {
4546 self.write_newline();
4547 self.write_indent();
4548 } else {
4549 self.write_space();
4550 }
4551 self.write_keyword("SETTINGS");
4552 self.write_space();
4553 for (i, expr) in settings.iter().enumerate() {
4554 if i > 0 {
4555 self.write(", ");
4556 }
4557 self.generate_expression(expr)?;
4558 }
4559 }
4560
4561 if let Some(format_expr) = &select.format {
4562 if self.config.pretty {
4563 self.write_newline();
4564 self.write_indent();
4565 } else {
4566 self.write_space();
4567 }
4568 self.write_keyword("FORMAT");
4569 self.write_space();
4570 self.generate_expression(format_expr)?;
4571 }
4572 }
4573
4574 if let Some(fetch) = &select.fetch {
4576 let fetch_already_as_limit = select.offset.is_some()
4578 && !fetch.percent
4579 && !fetch.with_ties
4580 && fetch.count.is_some()
4581 && matches!(
4582 self.config.dialect,
4583 Some(DialectType::Spark)
4584 | Some(DialectType::Hive)
4585 | Some(DialectType::DuckDB)
4586 | Some(DialectType::SQLite)
4587 | Some(DialectType::MySQL)
4588 | Some(DialectType::BigQuery)
4589 | Some(DialectType::Databricks)
4590 | Some(DialectType::StarRocks)
4591 | Some(DialectType::Doris)
4592 | Some(DialectType::Athena)
4593 | Some(DialectType::ClickHouse)
4594 | Some(DialectType::Redshift)
4595 );
4596
4597 if fetch_already_as_limit {
4598 } else {
4600 if self.config.pretty {
4601 self.write_newline();
4602 self.write_indent();
4603 } else {
4604 self.write_space();
4605 }
4606
4607 let use_limit = !fetch.percent
4609 && !fetch.with_ties
4610 && fetch.count.is_some()
4611 && matches!(
4612 self.config.dialect,
4613 Some(DialectType::Spark)
4614 | Some(DialectType::Hive)
4615 | Some(DialectType::DuckDB)
4616 | Some(DialectType::SQLite)
4617 | Some(DialectType::MySQL)
4618 | Some(DialectType::BigQuery)
4619 | Some(DialectType::Databricks)
4620 | Some(DialectType::StarRocks)
4621 | Some(DialectType::Doris)
4622 | Some(DialectType::Athena)
4623 | Some(DialectType::ClickHouse)
4624 | Some(DialectType::Redshift)
4625 );
4626
4627 if use_limit {
4628 self.write_keyword("LIMIT");
4629 self.write_space();
4630 self.generate_expression(fetch.count.as_ref().unwrap())?;
4631 } else {
4632 self.write_keyword("FETCH");
4633 self.write_space();
4634 self.write_keyword(&fetch.direction);
4635 if let Some(ref count) = fetch.count {
4636 self.write_space();
4637 self.generate_expression(count)?;
4638 }
4639 if fetch.percent {
4640 self.write_space();
4641 self.write_keyword("PERCENT");
4642 }
4643 if fetch.rows {
4644 self.write_space();
4645 self.write_keyword("ROWS");
4646 }
4647 if fetch.with_ties {
4648 self.write_space();
4649 self.write_keyword("WITH TIES");
4650 } else {
4651 self.write_space();
4652 self.write_keyword("ONLY");
4653 }
4654 }
4655 } }
4657
4658 if let Some(sample) = &select.sample {
4660 use crate::dialects::DialectType;
4661 if self.config.pretty {
4662 self.write_newline();
4663 } else {
4664 self.write_space();
4665 }
4666
4667 if sample.is_using_sample {
4668 self.write_keyword("USING SAMPLE");
4670 self.generate_sample_body(sample)?;
4671 } else {
4672 self.write_keyword("TABLESAMPLE");
4673
4674 let snowflake_bernoulli =
4676 matches!(self.config.dialect, Some(DialectType::Snowflake))
4677 && !sample.explicit_method;
4678 if snowflake_bernoulli {
4679 self.write_space();
4680 self.write_keyword("BERNOULLI");
4681 }
4682
4683 if matches!(sample.method, SampleMethod::Bucket) {
4685 self.write_space();
4686 self.write("(");
4687 self.write_keyword("BUCKET");
4688 self.write_space();
4689 if let Some(ref num) = sample.bucket_numerator {
4690 self.generate_expression(num)?;
4691 }
4692 self.write_space();
4693 self.write_keyword("OUT OF");
4694 self.write_space();
4695 if let Some(ref denom) = sample.bucket_denominator {
4696 self.generate_expression(denom)?;
4697 }
4698 if let Some(ref field) = sample.bucket_field {
4699 self.write_space();
4700 self.write_keyword("ON");
4701 self.write_space();
4702 self.generate_expression(field)?;
4703 }
4704 self.write(")");
4705 } else if sample.unit_after_size {
4706 if sample.explicit_method && sample.method_before_size {
4708 self.write_space();
4709 match sample.method {
4710 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4711 SampleMethod::System => self.write_keyword("SYSTEM"),
4712 SampleMethod::Block => self.write_keyword("BLOCK"),
4713 SampleMethod::Row => self.write_keyword("ROW"),
4714 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4715 _ => {}
4716 }
4717 }
4718 self.write(" (");
4719 self.generate_expression(&sample.size)?;
4720 self.write_space();
4721 match sample.method {
4722 SampleMethod::Percent => self.write_keyword("PERCENT"),
4723 SampleMethod::Row => self.write_keyword("ROWS"),
4724 SampleMethod::Reservoir => self.write_keyword("ROWS"),
4725 _ => {
4726 self.write_keyword("PERCENT");
4727 }
4728 }
4729 self.write(")");
4730 } else {
4731 self.write_space();
4733 match sample.method {
4734 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4735 SampleMethod::System => self.write_keyword("SYSTEM"),
4736 SampleMethod::Block => self.write_keyword("BLOCK"),
4737 SampleMethod::Row => self.write_keyword("ROW"),
4738 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
4739 SampleMethod::Bucket => {}
4740 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4741 }
4742 self.write(" (");
4743 self.generate_expression(&sample.size)?;
4744 if matches!(sample.method, SampleMethod::Percent) {
4745 self.write_space();
4746 self.write_keyword("PERCENT");
4747 }
4748 self.write(")");
4749 }
4750 }
4751
4752 if let Some(seed) = &sample.seed {
4753 self.write_space();
4754 let use_seed = sample.use_seed_keyword
4756 && !matches!(
4757 self.config.dialect,
4758 Some(crate::dialects::DialectType::Databricks)
4759 | Some(crate::dialects::DialectType::Spark)
4760 );
4761 if use_seed {
4762 self.write_keyword("SEED");
4763 } else {
4764 self.write_keyword("REPEATABLE");
4765 }
4766 self.write(" (");
4767 self.generate_expression(seed)?;
4768 self.write(")");
4769 }
4770 }
4771
4772 if self.config.locking_reads_supported {
4775 for lock in &select.locks {
4776 if self.config.pretty {
4777 self.write_newline();
4778 self.write_indent();
4779 } else {
4780 self.write_space();
4781 }
4782 self.generate_lock(lock)?;
4783 }
4784 }
4785
4786 if !select.for_xml.is_empty() {
4788 if self.config.pretty {
4789 self.write_newline();
4790 self.write_indent();
4791 } else {
4792 self.write_space();
4793 }
4794 self.write_keyword("FOR XML");
4795 for (i, opt) in select.for_xml.iter().enumerate() {
4796 if self.config.pretty {
4797 if i > 0 {
4798 self.write(",");
4799 }
4800 self.write_newline();
4801 self.write_indent();
4802 self.write(" "); } else {
4804 if i > 0 {
4805 self.write(",");
4806 }
4807 self.write_space();
4808 }
4809 self.generate_for_xml_option(opt)?;
4810 }
4811 }
4812
4813 if let Some(ref option) = select.option {
4815 if matches!(
4816 self.config.dialect,
4817 Some(crate::dialects::DialectType::TSQL)
4818 | Some(crate::dialects::DialectType::Fabric)
4819 ) {
4820 self.write_space();
4821 self.write(option);
4822 }
4823 }
4824
4825 Ok(())
4826 }
4827
4828 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
4830 match opt {
4831 Expression::QueryOption(qo) => {
4832 if let Expression::Var(var) = &*qo.this {
4834 self.write(&var.this);
4835 } else {
4836 self.generate_expression(&qo.this)?;
4837 }
4838 if let Some(expr) = &qo.expression {
4840 self.write("(");
4841 self.generate_expression(expr)?;
4842 self.write(")");
4843 }
4844 }
4845 _ => {
4846 self.generate_expression(opt)?;
4847 }
4848 }
4849 Ok(())
4850 }
4851
4852 fn generate_with(&mut self, with: &With) -> Result<()> {
4853 use crate::dialects::DialectType;
4854
4855 for comment in &with.leading_comments {
4857 self.write_formatted_comment(comment);
4858 self.write(" ");
4859 }
4860 self.write_keyword("WITH");
4861 if with.recursive && self.config.cte_recursive_keyword_required {
4862 self.write_space();
4863 self.write_keyword("RECURSIVE");
4864 }
4865 self.write_space();
4866
4867 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
4869
4870 for (i, cte) in with.ctes.iter().enumerate() {
4871 if i > 0 {
4872 self.write(",");
4873 if self.config.pretty {
4874 self.write_space();
4875 } else {
4876 self.write(" ");
4877 }
4878 }
4879 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
4880 self.generate_expression(&cte.this)?;
4881 self.write_space();
4882 self.write_keyword("AS");
4883 self.write_space();
4884 self.generate_identifier(&cte.alias)?;
4885 continue;
4886 }
4887 self.generate_identifier(&cte.alias)?;
4888 for comment in &cte.comments {
4890 self.write_space();
4891 self.write_formatted_comment(comment);
4892 }
4893 if !cte.columns.is_empty() && !skip_cte_columns {
4894 self.write("(");
4895 for (j, col) in cte.columns.iter().enumerate() {
4896 if j > 0 {
4897 self.write(", ");
4898 }
4899 self.generate_identifier(col)?;
4900 }
4901 self.write(")");
4902 }
4903 if !cte.key_expressions.is_empty() {
4905 self.write_space();
4906 self.write_keyword("USING KEY");
4907 self.write(" (");
4908 for (i, key) in cte.key_expressions.iter().enumerate() {
4909 if i > 0 {
4910 self.write(", ");
4911 }
4912 self.generate_identifier(key)?;
4913 }
4914 self.write(")");
4915 }
4916 self.write_space();
4917 self.write_keyword("AS");
4918 if let Some(materialized) = cte.materialized {
4920 self.write_space();
4921 if materialized {
4922 self.write_keyword("MATERIALIZED");
4923 } else {
4924 self.write_keyword("NOT MATERIALIZED");
4925 }
4926 }
4927 self.write(" (");
4928 if self.config.pretty {
4929 self.write_newline();
4930 self.indent_level += 1;
4931 self.write_indent();
4932 }
4933 let wrap_values_in_select = matches!(
4936 self.config.dialect,
4937 Some(DialectType::Spark) | Some(DialectType::Databricks)
4938 ) && matches!(&cte.this, Expression::Values(_));
4939
4940 if wrap_values_in_select {
4941 self.write_keyword("SELECT");
4942 self.write(" * ");
4943 self.write_keyword("FROM");
4944 self.write_space();
4945 }
4946 self.generate_expression(&cte.this)?;
4947 if self.config.pretty {
4948 self.write_newline();
4949 self.indent_level -= 1;
4950 self.write_indent();
4951 }
4952 self.write(")");
4953 }
4954
4955 if let Some(search) = &with.search {
4957 self.write_space();
4958 self.generate_expression(search)?;
4959 }
4960
4961 Ok(())
4962 }
4963
4964 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
4968 let mut i = 0;
4969 while i < joins.len() {
4970 if joins[i].deferred_condition {
4971 let parent_group = joins[i].nesting_group;
4972
4973 self.generate_join_without_condition(&joins[i])?;
4976
4977 let child_start = i + 1;
4979 let mut child_end = child_start;
4980 while child_end < joins.len()
4981 && !joins[child_end].deferred_condition
4982 && joins[child_end].nesting_group == parent_group
4983 {
4984 child_end += 1;
4985 }
4986
4987 if child_start < child_end {
4989 self.indent_level += 1;
4990 for j in child_start..child_end {
4991 self.generate_join(&joins[j])?;
4992 }
4993 self.indent_level -= 1;
4994 }
4995
4996 self.generate_join_condition(&joins[i])?;
4998
4999 i = child_end;
5000 } else {
5001 self.generate_join(&joins[i])?;
5003 i += 1;
5004 }
5005 }
5006 Ok(())
5007 }
5008
5009 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5012 let mut join_copy = join.clone();
5015 join_copy.on = None;
5016 join_copy.using = Vec::new();
5017 join_copy.deferred_condition = false;
5018 self.generate_join(&join_copy)
5019 }
5020
5021 fn generate_join(&mut self, join: &Join) -> Result<()> {
5022 if join.kind == JoinKind::Implicit {
5024 self.write(",");
5025 if self.config.pretty {
5026 self.write_newline();
5027 self.write_indent();
5028 } else {
5029 self.write_space();
5030 }
5031 self.generate_expression(&join.this)?;
5032 return Ok(());
5033 }
5034
5035 if self.config.pretty {
5036 self.write_newline();
5037 self.write_indent();
5038 } else {
5039 self.write_space();
5040 }
5041
5042 let hint_str = if self.config.join_hints {
5045 join.join_hint
5046 .as_ref()
5047 .map(|h| format!(" {}", h))
5048 .unwrap_or_default()
5049 } else {
5050 String::new()
5051 };
5052
5053 let clickhouse_join_keyword =
5054 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5055 if let Some(hint) = &join.join_hint {
5056 let mut global = false;
5057 let mut strictness: Option<&'static str> = None;
5058 for part in hint.split_whitespace() {
5059 match part.to_uppercase().as_str() {
5060 "GLOBAL" => global = true,
5061 "ANY" => strictness = Some("ANY"),
5062 "ASOF" => strictness = Some("ASOF"),
5063 "SEMI" => strictness = Some("SEMI"),
5064 "ANTI" => strictness = Some("ANTI"),
5065 _ => {}
5066 }
5067 }
5068
5069 if global || strictness.is_some() {
5070 let join_type = match join.kind {
5071 JoinKind::Left => {
5072 if join.use_outer_keyword {
5073 "LEFT OUTER"
5074 } else if join.use_inner_keyword {
5075 "LEFT INNER"
5076 } else {
5077 "LEFT"
5078 }
5079 }
5080 JoinKind::Right => {
5081 if join.use_outer_keyword {
5082 "RIGHT OUTER"
5083 } else if join.use_inner_keyword {
5084 "RIGHT INNER"
5085 } else {
5086 "RIGHT"
5087 }
5088 }
5089 JoinKind::Full => {
5090 if join.use_outer_keyword {
5091 "FULL OUTER"
5092 } else {
5093 "FULL"
5094 }
5095 }
5096 JoinKind::Inner => {
5097 if join.use_inner_keyword {
5098 "INNER"
5099 } else {
5100 ""
5101 }
5102 }
5103 _ => "",
5104 };
5105
5106 let mut parts = Vec::new();
5107 if global {
5108 parts.push("GLOBAL");
5109 }
5110 if !join_type.is_empty() {
5111 parts.push(join_type);
5112 }
5113 if let Some(strict) = strictness {
5114 parts.push(strict);
5115 }
5116 parts.push("JOIN");
5117 Some(parts.join(" "))
5118 } else {
5119 None
5120 }
5121 } else {
5122 None
5123 }
5124 } else {
5125 None
5126 };
5127
5128 if !join.comments.is_empty() {
5132 if self.config.pretty {
5133 let trimmed = self.output.trim_end().len();
5138 self.output.truncate(trimmed);
5139 for comment in &join.comments {
5140 self.write_newline();
5141 self.write_indent();
5142 self.write_formatted_comment(comment);
5143 }
5144 self.write_newline();
5145 self.write_indent();
5146 } else {
5147 for comment in &join.comments {
5148 self.write_formatted_comment(comment);
5149 self.write_space();
5150 }
5151 }
5152 }
5153
5154 let directed_str = if join.directed { " DIRECTED" } else { "" };
5155
5156 if let Some(keyword) = clickhouse_join_keyword {
5157 self.write_keyword(&keyword);
5158 } else {
5159 match join.kind {
5160 JoinKind::Inner => {
5161 if join.use_inner_keyword {
5162 self.write_keyword(&format!("INNER{}{} JOIN", hint_str, directed_str));
5163 } else {
5164 self.write_keyword(&format!(
5165 "{}{}JOIN",
5166 if hint_str.is_empty() {
5167 String::new()
5168 } else {
5169 format!("{} ", hint_str.trim())
5170 },
5171 if directed_str.is_empty() {
5172 ""
5173 } else {
5174 "DIRECTED "
5175 }
5176 ));
5177 }
5178 }
5179 JoinKind::Left => {
5180 if join.use_outer_keyword {
5181 self.write_keyword(&format!("LEFT OUTER{}{} JOIN", hint_str, directed_str));
5182 } else if join.use_inner_keyword {
5183 self.write_keyword(&format!("LEFT INNER{}{} JOIN", hint_str, directed_str));
5184 } else {
5185 self.write_keyword(&format!("LEFT{}{} JOIN", hint_str, directed_str));
5186 }
5187 }
5188 JoinKind::Right => {
5189 if join.use_outer_keyword {
5190 self.write_keyword(&format!(
5191 "RIGHT OUTER{}{} JOIN",
5192 hint_str, directed_str
5193 ));
5194 } else if join.use_inner_keyword {
5195 self.write_keyword(&format!(
5196 "RIGHT INNER{}{} JOIN",
5197 hint_str, directed_str
5198 ));
5199 } else {
5200 self.write_keyword(&format!("RIGHT{}{} JOIN", hint_str, directed_str));
5201 }
5202 }
5203 JoinKind::Full => {
5204 if join.use_outer_keyword {
5205 self.write_keyword(&format!("FULL OUTER{}{} JOIN", hint_str, directed_str));
5206 } else {
5207 self.write_keyword(&format!("FULL{}{} JOIN", hint_str, directed_str));
5208 }
5209 }
5210 JoinKind::Outer => self.write_keyword(&format!("OUTER{} JOIN", directed_str)),
5211 JoinKind::Cross => self.write_keyword(&format!("CROSS{} JOIN", directed_str)),
5212 JoinKind::Natural => {
5213 if join.use_inner_keyword {
5214 self.write_keyword(&format!("NATURAL INNER{} JOIN", directed_str));
5215 } else {
5216 self.write_keyword(&format!("NATURAL{} JOIN", directed_str));
5217 }
5218 }
5219 JoinKind::NaturalLeft => {
5220 if join.use_outer_keyword {
5221 self.write_keyword(&format!("NATURAL LEFT OUTER{} JOIN", directed_str));
5222 } else {
5223 self.write_keyword(&format!("NATURAL LEFT{} JOIN", directed_str));
5224 }
5225 }
5226 JoinKind::NaturalRight => {
5227 if join.use_outer_keyword {
5228 self.write_keyword(&format!("NATURAL RIGHT OUTER{} JOIN", directed_str));
5229 } else {
5230 self.write_keyword(&format!("NATURAL RIGHT{} JOIN", directed_str));
5231 }
5232 }
5233 JoinKind::NaturalFull => {
5234 if join.use_outer_keyword {
5235 self.write_keyword(&format!("NATURAL FULL OUTER{} JOIN", directed_str));
5236 } else {
5237 self.write_keyword(&format!("NATURAL FULL{} JOIN", directed_str));
5238 }
5239 }
5240 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
5241 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
5242 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
5243 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
5244 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
5245 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
5246 JoinKind::CrossApply => {
5247 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5249 self.write_keyword("CROSS APPLY");
5250 } else {
5251 self.write_keyword("INNER JOIN LATERAL");
5252 }
5253 }
5254 JoinKind::OuterApply => {
5255 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5257 self.write_keyword("OUTER APPLY");
5258 } else {
5259 self.write_keyword("LEFT JOIN LATERAL");
5260 }
5261 }
5262 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
5263 JoinKind::AsOfLeft => {
5264 if join.use_outer_keyword {
5265 self.write_keyword("ASOF LEFT OUTER JOIN");
5266 } else {
5267 self.write_keyword("ASOF LEFT JOIN");
5268 }
5269 }
5270 JoinKind::AsOfRight => {
5271 if join.use_outer_keyword {
5272 self.write_keyword("ASOF RIGHT OUTER JOIN");
5273 } else {
5274 self.write_keyword("ASOF RIGHT JOIN");
5275 }
5276 }
5277 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
5278 JoinKind::LeftLateral => {
5279 if join.use_outer_keyword {
5280 self.write_keyword("LEFT OUTER LATERAL JOIN");
5281 } else {
5282 self.write_keyword("LEFT LATERAL JOIN");
5283 }
5284 }
5285 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
5286 JoinKind::Implicit => {
5287 use crate::dialects::DialectType;
5291 let is_cj_dialect = matches!(
5292 self.config.dialect,
5293 Some(DialectType::BigQuery)
5294 | Some(DialectType::Hive)
5295 | Some(DialectType::Spark)
5296 | Some(DialectType::Databricks)
5297 );
5298 let source_is_same = self.config.source_dialect.is_some()
5299 && self.config.source_dialect == self.config.dialect;
5300 let source_is_cj = matches!(
5301 self.config.source_dialect,
5302 Some(DialectType::BigQuery)
5303 | Some(DialectType::Hive)
5304 | Some(DialectType::Spark)
5305 | Some(DialectType::Databricks)
5306 );
5307 if is_cj_dialect
5308 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
5309 {
5310 self.write_keyword("CROSS JOIN");
5311 } else {
5312 self.output.truncate(self.output.trim_end().len());
5316 self.write(",");
5317 }
5318 }
5319 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
5320 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
5321 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
5322 }
5323 }
5324
5325 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
5327 self.write_space();
5328 match &join.this {
5329 Expression::Tuple(t) => {
5330 for (i, item) in t.expressions.iter().enumerate() {
5331 if i > 0 {
5332 self.write(", ");
5333 }
5334 self.generate_expression(item)?;
5335 }
5336 }
5337 other => {
5338 self.generate_expression(other)?;
5339 }
5340 }
5341 } else {
5342 self.write_space();
5343 self.generate_expression(&join.this)?;
5344 }
5345
5346 if !join.deferred_condition {
5348 if let Some(match_cond) = &join.match_condition {
5350 self.write_space();
5351 self.write_keyword("MATCH_CONDITION");
5352 self.write(" (");
5353 self.generate_expression(match_cond)?;
5354 self.write(")");
5355 }
5356
5357 if let Some(on) = &join.on {
5358 if self.config.pretty {
5359 self.write_newline();
5360 self.indent_level += 1;
5361 self.write_indent();
5362 self.write_keyword("ON");
5363 self.write_space();
5364 self.generate_join_on_condition(on)?;
5365 self.indent_level -= 1;
5366 } else {
5367 self.write_space();
5368 self.write_keyword("ON");
5369 self.write_space();
5370 self.generate_expression(on)?;
5371 }
5372 }
5373
5374 if !join.using.is_empty() {
5375 if self.config.pretty {
5376 self.write_newline();
5377 self.indent_level += 1;
5378 self.write_indent();
5379 self.write_keyword("USING");
5380 self.write(" (");
5381 for (i, col) in join.using.iter().enumerate() {
5382 if i > 0 {
5383 self.write(", ");
5384 }
5385 self.generate_identifier(col)?;
5386 }
5387 self.write(")");
5388 self.indent_level -= 1;
5389 } else {
5390 self.write_space();
5391 self.write_keyword("USING");
5392 self.write(" (");
5393 for (i, col) in join.using.iter().enumerate() {
5394 if i > 0 {
5395 self.write(", ");
5396 }
5397 self.generate_identifier(col)?;
5398 }
5399 self.write(")");
5400 }
5401 }
5402 }
5403
5404 for pivot in &join.pivots {
5406 self.write_space();
5407 self.generate_expression(pivot)?;
5408 }
5409
5410 Ok(())
5411 }
5412
5413 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
5415 if let Some(match_cond) = &join.match_condition {
5417 self.write_space();
5418 self.write_keyword("MATCH_CONDITION");
5419 self.write(" (");
5420 self.generate_expression(match_cond)?;
5421 self.write(")");
5422 }
5423
5424 if let Some(on) = &join.on {
5425 if self.config.pretty {
5426 self.write_newline();
5427 self.indent_level += 1;
5428 self.write_indent();
5429 self.write_keyword("ON");
5430 self.write_space();
5431 self.generate_join_on_condition(on)?;
5433 self.indent_level -= 1;
5434 } else {
5435 self.write_space();
5436 self.write_keyword("ON");
5437 self.write_space();
5438 self.generate_expression(on)?;
5439 }
5440 }
5441
5442 if !join.using.is_empty() {
5443 if self.config.pretty {
5444 self.write_newline();
5445 self.indent_level += 1;
5446 self.write_indent();
5447 self.write_keyword("USING");
5448 self.write(" (");
5449 for (i, col) in join.using.iter().enumerate() {
5450 if i > 0 {
5451 self.write(", ");
5452 }
5453 self.generate_identifier(col)?;
5454 }
5455 self.write(")");
5456 self.indent_level -= 1;
5457 } else {
5458 self.write_space();
5459 self.write_keyword("USING");
5460 self.write(" (");
5461 for (i, col) in join.using.iter().enumerate() {
5462 if i > 0 {
5463 self.write(", ");
5464 }
5465 self.generate_identifier(col)?;
5466 }
5467 self.write(")");
5468 }
5469 }
5470
5471 for pivot in &join.pivots {
5473 self.write_space();
5474 self.generate_expression(pivot)?;
5475 }
5476
5477 Ok(())
5478 }
5479
5480 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
5482 if let Expression::And(and_op) = expr {
5484 self.generate_join_on_condition(&and_op.left)?;
5486 self.write_newline();
5488 self.write_indent();
5489 self.write_keyword("AND");
5490 self.write_space();
5491 self.generate_expression(&and_op.right)?;
5493 } else {
5494 self.generate_expression(expr)?;
5496 }
5497 Ok(())
5498 }
5499
5500 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
5501 self.write("(");
5503 self.generate_expression(&jt.left)?;
5504
5505 for join in &jt.joins {
5507 self.generate_join(join)?;
5508 }
5509
5510 for lv in &jt.lateral_views {
5512 self.generate_lateral_view(lv)?;
5513 }
5514
5515 self.write(")");
5516
5517 if let Some(alias) = &jt.alias {
5519 self.write_space();
5520 self.write_keyword("AS");
5521 self.write_space();
5522 self.generate_identifier(alias)?;
5523 }
5524
5525 Ok(())
5526 }
5527
5528 fn generate_lateral_view(&mut self, lv: &LateralView) -> Result<()> {
5529 use crate::dialects::DialectType;
5530
5531 if self.config.pretty {
5532 self.write_newline();
5533 self.write_indent();
5534 } else {
5535 self.write_space();
5536 }
5537
5538 let use_lateral_join = matches!(
5541 self.config.dialect,
5542 Some(DialectType::PostgreSQL)
5543 | Some(DialectType::DuckDB)
5544 | Some(DialectType::Snowflake)
5545 | Some(DialectType::TSQL)
5546 | Some(DialectType::Presto)
5547 | Some(DialectType::Trino)
5548 | Some(DialectType::Athena)
5549 );
5550
5551 let use_unnest = matches!(
5553 self.config.dialect,
5554 Some(DialectType::DuckDB)
5555 | Some(DialectType::Presto)
5556 | Some(DialectType::Trino)
5557 | Some(DialectType::Athena)
5558 );
5559
5560 let (is_posexplode, func_args) = match &lv.this {
5562 Expression::Explode(uf) => {
5563 (false, vec![uf.this.clone()])
5565 }
5566 Expression::Unnest(uf) => {
5567 let mut args = vec![uf.this.clone()];
5568 args.extend(uf.expressions.clone());
5569 (false, args)
5570 }
5571 Expression::Function(func) => {
5572 let name = func.name.to_uppercase();
5573 if name == "POSEXPLODE" || name == "POSEXPLODE_OUTER" {
5574 (true, func.args.clone())
5575 } else if name == "EXPLODE" || name == "EXPLODE_OUTER" || name == "INLINE" {
5576 (false, func.args.clone())
5577 } else {
5578 (false, vec![])
5579 }
5580 }
5581 _ => (false, vec![]),
5582 };
5583
5584 if use_lateral_join {
5585 if lv.outer {
5587 self.write_keyword("LEFT JOIN LATERAL");
5588 } else {
5589 self.write_keyword("CROSS JOIN");
5590 }
5591 self.write_space();
5592
5593 if use_unnest && !func_args.is_empty() {
5594 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
5597 func_args
5599 .iter()
5600 .map(|a| {
5601 if let Expression::Function(ref f) = a {
5602 if f.name.to_uppercase() == "ARRAY" && f.args.len() == 1 {
5603 return Expression::ArrayFunc(Box::new(
5604 crate::expressions::ArrayConstructor {
5605 expressions: f.args.clone(),
5606 bracket_notation: true,
5607 use_list_keyword: false,
5608 },
5609 ));
5610 }
5611 }
5612 a.clone()
5613 })
5614 .collect::<Vec<_>>()
5615 } else if matches!(
5616 self.config.dialect,
5617 Some(DialectType::Presto)
5618 | Some(DialectType::Trino)
5619 | Some(DialectType::Athena)
5620 ) {
5621 func_args
5623 .iter()
5624 .map(|a| {
5625 if let Expression::Function(ref f) = a {
5626 if f.name.to_uppercase() == "ARRAY" && f.args.len() >= 1 {
5627 return Expression::ArrayFunc(Box::new(
5628 crate::expressions::ArrayConstructor {
5629 expressions: f.args.clone(),
5630 bracket_notation: true,
5631 use_list_keyword: false,
5632 },
5633 ));
5634 }
5635 }
5636 a.clone()
5637 })
5638 .collect::<Vec<_>>()
5639 } else {
5640 func_args
5641 };
5642
5643 if is_posexplode {
5645 self.write_keyword("LATERAL");
5646 self.write(" (");
5647 self.write_keyword("SELECT");
5648 self.write_space();
5649
5650 let pos_alias = if !lv.column_aliases.is_empty() {
5653 lv.column_aliases[0].clone()
5654 } else {
5655 Identifier::new("pos")
5656 };
5657 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
5658 lv.column_aliases[1..].to_vec()
5659 } else {
5660 vec![Identifier::new("col")]
5661 };
5662
5663 self.generate_identifier(&pos_alias)?;
5665 self.write(" - 1");
5666 self.write_space();
5667 self.write_keyword("AS");
5668 self.write_space();
5669 self.generate_identifier(&pos_alias)?;
5670
5671 for data_col in &data_aliases {
5673 self.write(", ");
5674 self.generate_identifier(data_col)?;
5675 }
5676
5677 self.write_space();
5678 self.write_keyword("FROM");
5679 self.write_space();
5680 self.write_keyword("UNNEST");
5681 self.write("(");
5682 for (i, arg) in unnest_args.iter().enumerate() {
5683 if i > 0 {
5684 self.write(", ");
5685 }
5686 self.generate_expression(arg)?;
5687 }
5688 self.write(")");
5689 self.write_space();
5690 self.write_keyword("WITH ORDINALITY");
5691 self.write_space();
5692 self.write_keyword("AS");
5693 self.write_space();
5694
5695 let table_alias_ident = lv
5697 .table_alias
5698 .clone()
5699 .unwrap_or_else(|| Identifier::new("t"));
5700 self.generate_identifier(&table_alias_ident)?;
5701 self.write("(");
5702 for (i, data_col) in data_aliases.iter().enumerate() {
5703 if i > 0 {
5704 self.write(", ");
5705 }
5706 self.generate_identifier(data_col)?;
5707 }
5708 self.write(", ");
5709 self.generate_identifier(&pos_alias)?;
5710 self.write("))");
5711 } else {
5712 self.write_keyword("UNNEST");
5713 self.write("(");
5714 for (i, arg) in unnest_args.iter().enumerate() {
5715 if i > 0 {
5716 self.write(", ");
5717 }
5718 self.generate_expression(arg)?;
5719 }
5720 self.write(")");
5721
5722 if let Some(alias) = &lv.table_alias {
5724 self.write_space();
5725 self.write_keyword("AS");
5726 self.write_space();
5727 self.generate_identifier(alias)?;
5728 if !lv.column_aliases.is_empty() {
5729 self.write("(");
5730 for (i, col) in lv.column_aliases.iter().enumerate() {
5731 if i > 0 {
5732 self.write(", ");
5733 }
5734 self.generate_identifier(col)?;
5735 }
5736 self.write(")");
5737 }
5738 } else if !lv.column_aliases.is_empty() {
5739 self.write_space();
5740 self.write_keyword("AS");
5741 self.write(" t(");
5742 for (i, col) in lv.column_aliases.iter().enumerate() {
5743 if i > 0 {
5744 self.write(", ");
5745 }
5746 self.generate_identifier(col)?;
5747 }
5748 self.write(")");
5749 }
5750 }
5751 } else {
5752 if !lv.outer {
5754 self.write_keyword("LATERAL");
5755 self.write_space();
5756 }
5757 self.generate_expression(&lv.this)?;
5758
5759 if let Some(alias) = &lv.table_alias {
5761 self.write_space();
5762 self.write_keyword("AS");
5763 self.write_space();
5764 self.generate_identifier(alias)?;
5765 if !lv.column_aliases.is_empty() {
5766 self.write("(");
5767 for (i, col) in lv.column_aliases.iter().enumerate() {
5768 if i > 0 {
5769 self.write(", ");
5770 }
5771 self.generate_identifier(col)?;
5772 }
5773 self.write(")");
5774 }
5775 } else if !lv.column_aliases.is_empty() {
5776 self.write_space();
5777 self.write_keyword("AS");
5778 self.write(" t(");
5779 for (i, col) in lv.column_aliases.iter().enumerate() {
5780 if i > 0 {
5781 self.write(", ");
5782 }
5783 self.generate_identifier(col)?;
5784 }
5785 self.write(")");
5786 }
5787 }
5788
5789 if lv.outer {
5791 self.write_space();
5792 self.write_keyword("ON TRUE");
5793 }
5794 } else {
5795 self.write_keyword("LATERAL VIEW");
5797 if lv.outer {
5798 self.write_space();
5799 self.write_keyword("OUTER");
5800 }
5801 if self.config.pretty {
5802 self.write_newline();
5803 self.write_indent();
5804 } else {
5805 self.write_space();
5806 }
5807 self.generate_expression(&lv.this)?;
5808
5809 if let Some(alias) = &lv.table_alias {
5811 self.write_space();
5812 self.generate_identifier(alias)?;
5813 }
5814
5815 if !lv.column_aliases.is_empty() {
5817 self.write_space();
5818 self.write_keyword("AS");
5819 self.write_space();
5820 for (i, col) in lv.column_aliases.iter().enumerate() {
5821 if i > 0 {
5822 self.write(", ");
5823 }
5824 self.generate_identifier(col)?;
5825 }
5826 }
5827 }
5828
5829 Ok(())
5830 }
5831
5832 fn generate_union(&mut self, union: &Union) -> Result<()> {
5833 if let Some(with) = &union.with {
5835 self.generate_with(with)?;
5836 self.write_space();
5837 }
5838 self.generate_expression(&union.left)?;
5839 if self.config.pretty {
5840 self.write_newline();
5841 self.write_indent();
5842 } else {
5843 self.write_space();
5844 }
5845
5846 if let Some(side) = &union.side {
5848 self.write_keyword(side);
5849 self.write_space();
5850 }
5851 if let Some(kind) = &union.kind {
5852 self.write_keyword(kind);
5853 self.write_space();
5854 }
5855
5856 self.write_keyword("UNION");
5857 if union.all {
5858 self.write_space();
5859 self.write_keyword("ALL");
5860 } else if union.distinct {
5861 self.write_space();
5862 self.write_keyword("DISTINCT");
5863 }
5864
5865 if union.corresponding || union.by_name {
5868 self.write_space();
5869 self.write_keyword("BY NAME");
5870 }
5871 if !union.on_columns.is_empty() {
5872 self.write_space();
5873 self.write_keyword("ON");
5874 self.write(" (");
5875 for (i, col) in union.on_columns.iter().enumerate() {
5876 if i > 0 {
5877 self.write(", ");
5878 }
5879 self.generate_expression(col)?;
5880 }
5881 self.write(")");
5882 }
5883
5884 if self.config.pretty {
5885 self.write_newline();
5886 self.write_indent();
5887 } else {
5888 self.write_space();
5889 }
5890 self.generate_expression(&union.right)?;
5891 if let Some(order_by) = &union.order_by {
5893 if self.config.pretty {
5894 self.write_newline();
5895 } else {
5896 self.write_space();
5897 }
5898 self.write_keyword("ORDER BY");
5899 self.write_space();
5900 for (i, ordered) in order_by.expressions.iter().enumerate() {
5901 if i > 0 {
5902 self.write(", ");
5903 }
5904 self.generate_ordered(ordered)?;
5905 }
5906 }
5907 if let Some(limit) = &union.limit {
5908 if self.config.pretty {
5909 self.write_newline();
5910 } else {
5911 self.write_space();
5912 }
5913 self.write_keyword("LIMIT");
5914 self.write_space();
5915 self.generate_expression(limit)?;
5916 }
5917 if let Some(offset) = &union.offset {
5918 if self.config.pretty {
5919 self.write_newline();
5920 } else {
5921 self.write_space();
5922 }
5923 self.write_keyword("OFFSET");
5924 self.write_space();
5925 self.generate_expression(offset)?;
5926 }
5927 if let Some(distribute_by) = &union.distribute_by {
5929 self.write_space();
5930 self.write_keyword("DISTRIBUTE BY");
5931 self.write_space();
5932 for (i, expr) in distribute_by.expressions.iter().enumerate() {
5933 if i > 0 {
5934 self.write(", ");
5935 }
5936 self.generate_expression(expr)?;
5937 }
5938 }
5939 if let Some(sort_by) = &union.sort_by {
5941 self.write_space();
5942 self.write_keyword("SORT BY");
5943 self.write_space();
5944 for (i, ord) in sort_by.expressions.iter().enumerate() {
5945 if i > 0 {
5946 self.write(", ");
5947 }
5948 self.generate_ordered(ord)?;
5949 }
5950 }
5951 if let Some(cluster_by) = &union.cluster_by {
5953 self.write_space();
5954 self.write_keyword("CLUSTER BY");
5955 self.write_space();
5956 for (i, ord) in cluster_by.expressions.iter().enumerate() {
5957 if i > 0 {
5958 self.write(", ");
5959 }
5960 self.generate_ordered(ord)?;
5961 }
5962 }
5963 Ok(())
5964 }
5965
5966 fn generate_intersect(&mut self, intersect: &Intersect) -> Result<()> {
5967 if let Some(with) = &intersect.with {
5969 self.generate_with(with)?;
5970 self.write_space();
5971 }
5972 self.generate_expression(&intersect.left)?;
5973 if self.config.pretty {
5974 self.write_newline();
5975 self.write_indent();
5976 } else {
5977 self.write_space();
5978 }
5979
5980 if let Some(side) = &intersect.side {
5982 self.write_keyword(side);
5983 self.write_space();
5984 }
5985 if let Some(kind) = &intersect.kind {
5986 self.write_keyword(kind);
5987 self.write_space();
5988 }
5989
5990 self.write_keyword("INTERSECT");
5991 if intersect.all {
5992 self.write_space();
5993 self.write_keyword("ALL");
5994 } else if intersect.distinct {
5995 self.write_space();
5996 self.write_keyword("DISTINCT");
5997 }
5998
5999 if intersect.corresponding || intersect.by_name {
6002 self.write_space();
6003 self.write_keyword("BY NAME");
6004 }
6005 if !intersect.on_columns.is_empty() {
6006 self.write_space();
6007 self.write_keyword("ON");
6008 self.write(" (");
6009 for (i, col) in intersect.on_columns.iter().enumerate() {
6010 if i > 0 {
6011 self.write(", ");
6012 }
6013 self.generate_expression(col)?;
6014 }
6015 self.write(")");
6016 }
6017
6018 if self.config.pretty {
6019 self.write_newline();
6020 self.write_indent();
6021 } else {
6022 self.write_space();
6023 }
6024 self.generate_expression(&intersect.right)?;
6025 if let Some(order_by) = &intersect.order_by {
6027 if self.config.pretty {
6028 self.write_newline();
6029 } else {
6030 self.write_space();
6031 }
6032 self.write_keyword("ORDER BY");
6033 self.write_space();
6034 for (i, ordered) in order_by.expressions.iter().enumerate() {
6035 if i > 0 {
6036 self.write(", ");
6037 }
6038 self.generate_ordered(ordered)?;
6039 }
6040 }
6041 if let Some(limit) = &intersect.limit {
6042 if self.config.pretty {
6043 self.write_newline();
6044 } else {
6045 self.write_space();
6046 }
6047 self.write_keyword("LIMIT");
6048 self.write_space();
6049 self.generate_expression(limit)?;
6050 }
6051 if let Some(offset) = &intersect.offset {
6052 if self.config.pretty {
6053 self.write_newline();
6054 } else {
6055 self.write_space();
6056 }
6057 self.write_keyword("OFFSET");
6058 self.write_space();
6059 self.generate_expression(offset)?;
6060 }
6061 if let Some(distribute_by) = &intersect.distribute_by {
6063 self.write_space();
6064 self.write_keyword("DISTRIBUTE BY");
6065 self.write_space();
6066 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6067 if i > 0 {
6068 self.write(", ");
6069 }
6070 self.generate_expression(expr)?;
6071 }
6072 }
6073 if let Some(sort_by) = &intersect.sort_by {
6075 self.write_space();
6076 self.write_keyword("SORT BY");
6077 self.write_space();
6078 for (i, ord) in sort_by.expressions.iter().enumerate() {
6079 if i > 0 {
6080 self.write(", ");
6081 }
6082 self.generate_ordered(ord)?;
6083 }
6084 }
6085 if let Some(cluster_by) = &intersect.cluster_by {
6087 self.write_space();
6088 self.write_keyword("CLUSTER BY");
6089 self.write_space();
6090 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6091 if i > 0 {
6092 self.write(", ");
6093 }
6094 self.generate_ordered(ord)?;
6095 }
6096 }
6097 Ok(())
6098 }
6099
6100 fn generate_except(&mut self, except: &Except) -> Result<()> {
6101 use crate::dialects::DialectType;
6102
6103 if let Some(with) = &except.with {
6105 self.generate_with(with)?;
6106 self.write_space();
6107 }
6108
6109 self.generate_expression(&except.left)?;
6110 if self.config.pretty {
6111 self.write_newline();
6112 self.write_indent();
6113 } else {
6114 self.write_space();
6115 }
6116
6117 if let Some(side) = &except.side {
6119 self.write_keyword(side);
6120 self.write_space();
6121 }
6122 if let Some(kind) = &except.kind {
6123 self.write_keyword(kind);
6124 self.write_space();
6125 }
6126
6127 match self.config.dialect {
6129 Some(DialectType::Oracle) if !except.all => {
6130 self.write_keyword("MINUS");
6131 }
6132 Some(DialectType::ClickHouse) => {
6133 self.write_keyword("EXCEPT");
6135 if except.distinct {
6136 self.write_space();
6137 self.write_keyword("DISTINCT");
6138 }
6139 }
6140 Some(DialectType::BigQuery) => {
6141 self.write_keyword("EXCEPT");
6143 if except.all {
6144 self.write_space();
6145 self.write_keyword("ALL");
6146 } else {
6147 self.write_space();
6148 self.write_keyword("DISTINCT");
6149 }
6150 }
6151 _ => {
6152 self.write_keyword("EXCEPT");
6153 if except.all {
6154 self.write_space();
6155 self.write_keyword("ALL");
6156 } else if except.distinct {
6157 self.write_space();
6158 self.write_keyword("DISTINCT");
6159 }
6160 }
6161 }
6162
6163 if except.corresponding || except.by_name {
6166 self.write_space();
6167 self.write_keyword("BY NAME");
6168 }
6169 if !except.on_columns.is_empty() {
6170 self.write_space();
6171 self.write_keyword("ON");
6172 self.write(" (");
6173 for (i, col) in except.on_columns.iter().enumerate() {
6174 if i > 0 {
6175 self.write(", ");
6176 }
6177 self.generate_expression(col)?;
6178 }
6179 self.write(")");
6180 }
6181
6182 if self.config.pretty {
6183 self.write_newline();
6184 self.write_indent();
6185 } else {
6186 self.write_space();
6187 }
6188 self.generate_expression(&except.right)?;
6189 if let Some(order_by) = &except.order_by {
6191 if self.config.pretty {
6192 self.write_newline();
6193 } else {
6194 self.write_space();
6195 }
6196 self.write_keyword("ORDER BY");
6197 self.write_space();
6198 for (i, ordered) in order_by.expressions.iter().enumerate() {
6199 if i > 0 {
6200 self.write(", ");
6201 }
6202 self.generate_ordered(ordered)?;
6203 }
6204 }
6205 if let Some(limit) = &except.limit {
6206 if self.config.pretty {
6207 self.write_newline();
6208 } else {
6209 self.write_space();
6210 }
6211 self.write_keyword("LIMIT");
6212 self.write_space();
6213 self.generate_expression(limit)?;
6214 }
6215 if let Some(offset) = &except.offset {
6216 if self.config.pretty {
6217 self.write_newline();
6218 } else {
6219 self.write_space();
6220 }
6221 self.write_keyword("OFFSET");
6222 self.write_space();
6223 self.generate_expression(offset)?;
6224 }
6225 if let Some(distribute_by) = &except.distribute_by {
6227 self.write_space();
6228 self.write_keyword("DISTRIBUTE BY");
6229 self.write_space();
6230 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6231 if i > 0 {
6232 self.write(", ");
6233 }
6234 self.generate_expression(expr)?;
6235 }
6236 }
6237 if let Some(sort_by) = &except.sort_by {
6239 self.write_space();
6240 self.write_keyword("SORT BY");
6241 self.write_space();
6242 for (i, ord) in sort_by.expressions.iter().enumerate() {
6243 if i > 0 {
6244 self.write(", ");
6245 }
6246 self.generate_ordered(ord)?;
6247 }
6248 }
6249 if let Some(cluster_by) = &except.cluster_by {
6251 self.write_space();
6252 self.write_keyword("CLUSTER BY");
6253 self.write_space();
6254 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6255 if i > 0 {
6256 self.write(", ");
6257 }
6258 self.generate_ordered(ord)?;
6259 }
6260 }
6261 Ok(())
6262 }
6263
6264 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
6265 let prepend_query_cte = if insert.with.is_none() {
6267 use crate::dialects::DialectType;
6268 let should_prepend = matches!(
6269 self.config.dialect,
6270 Some(DialectType::TSQL)
6271 | Some(DialectType::Fabric)
6272 | Some(DialectType::Spark)
6273 | Some(DialectType::Databricks)
6274 | Some(DialectType::Hive)
6275 );
6276 if should_prepend {
6277 if let Some(Expression::Select(select)) = &insert.query {
6278 select.with.clone()
6279 } else {
6280 None
6281 }
6282 } else {
6283 None
6284 }
6285 } else {
6286 None
6287 };
6288
6289 if let Some(with) = &insert.with {
6291 self.generate_with(with)?;
6292 self.write_space();
6293 } else if let Some(with) = &prepend_query_cte {
6294 self.generate_with(with)?;
6295 self.write_space();
6296 }
6297
6298 for comment in &insert.leading_comments {
6300 self.write_formatted_comment(comment);
6301 self.write(" ");
6302 }
6303
6304 if let Some(dir) = &insert.directory {
6306 self.write_keyword("INSERT OVERWRITE");
6307 if dir.local {
6308 self.write_space();
6309 self.write_keyword("LOCAL");
6310 }
6311 self.write_space();
6312 self.write_keyword("DIRECTORY");
6313 self.write_space();
6314 self.write("'");
6315 self.write(&dir.path);
6316 self.write("'");
6317
6318 if let Some(row_format) = &dir.row_format {
6320 self.write_space();
6321 self.write_keyword("ROW FORMAT");
6322 if row_format.delimited {
6323 self.write_space();
6324 self.write_keyword("DELIMITED");
6325 }
6326 if let Some(val) = &row_format.fields_terminated_by {
6327 self.write_space();
6328 self.write_keyword("FIELDS TERMINATED BY");
6329 self.write_space();
6330 self.write("'");
6331 self.write(val);
6332 self.write("'");
6333 }
6334 if let Some(val) = &row_format.collection_items_terminated_by {
6335 self.write_space();
6336 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
6337 self.write_space();
6338 self.write("'");
6339 self.write(val);
6340 self.write("'");
6341 }
6342 if let Some(val) = &row_format.map_keys_terminated_by {
6343 self.write_space();
6344 self.write_keyword("MAP KEYS TERMINATED BY");
6345 self.write_space();
6346 self.write("'");
6347 self.write(val);
6348 self.write("'");
6349 }
6350 if let Some(val) = &row_format.lines_terminated_by {
6351 self.write_space();
6352 self.write_keyword("LINES TERMINATED BY");
6353 self.write_space();
6354 self.write("'");
6355 self.write(val);
6356 self.write("'");
6357 }
6358 if let Some(val) = &row_format.null_defined_as {
6359 self.write_space();
6360 self.write_keyword("NULL DEFINED AS");
6361 self.write_space();
6362 self.write("'");
6363 self.write(val);
6364 self.write("'");
6365 }
6366 }
6367
6368 if let Some(format) = &dir.stored_as {
6370 self.write_space();
6371 self.write_keyword("STORED AS");
6372 self.write_space();
6373 self.write_keyword(format);
6374 }
6375
6376 if let Some(query) = &insert.query {
6378 self.write_space();
6379 self.generate_expression(query)?;
6380 }
6381
6382 return Ok(());
6383 }
6384
6385 if insert.is_replace {
6386 self.write_keyword("REPLACE INTO");
6388 } else if insert.overwrite {
6389 self.write_keyword("INSERT");
6391 if let Some(ref hint) = insert.hint {
6393 self.generate_hint(hint)?;
6394 }
6395 self.write(&self.config.insert_overwrite.to_uppercase());
6396 } else if let Some(ref action) = insert.conflict_action {
6397 self.write_keyword("INSERT OR");
6399 self.write_space();
6400 self.write_keyword(action);
6401 self.write_space();
6402 self.write_keyword("INTO");
6403 } else if insert.ignore {
6404 self.write_keyword("INSERT IGNORE INTO");
6406 } else {
6407 self.write_keyword("INSERT");
6408 if let Some(ref hint) = insert.hint {
6410 self.generate_hint(hint)?;
6411 }
6412 self.write_space();
6413 self.write_keyword("INTO");
6414 }
6415 if let Some(ref func) = insert.function_target {
6417 self.write_space();
6418 self.write_keyword("FUNCTION");
6419 self.write_space();
6420 self.generate_expression(func)?;
6421 } else {
6422 self.write_space();
6423 self.generate_table(&insert.table)?;
6424 }
6425
6426 if let Some(ref alias) = insert.alias {
6428 self.write_space();
6429 if insert.alias_explicit_as {
6430 self.write_keyword("AS");
6431 self.write_space();
6432 }
6433 self.generate_identifier(alias)?;
6434 }
6435
6436 if insert.if_exists {
6438 self.write_space();
6439 self.write_keyword("IF EXISTS");
6440 }
6441
6442 if let Some(ref replace_where) = insert.replace_where {
6444 if self.config.pretty {
6445 self.write_newline();
6446 self.write_indent();
6447 } else {
6448 self.write_space();
6449 }
6450 self.write_keyword("REPLACE WHERE");
6451 self.write_space();
6452 self.generate_expression(replace_where)?;
6453 }
6454
6455 if !insert.partition.is_empty() {
6457 self.write_space();
6458 self.write_keyword("PARTITION");
6459 self.write("(");
6460 for (i, (col, val)) in insert.partition.iter().enumerate() {
6461 if i > 0 {
6462 self.write(", ");
6463 }
6464 self.generate_identifier(col)?;
6465 if let Some(v) = val {
6466 self.write(" = ");
6467 self.generate_expression(v)?;
6468 }
6469 }
6470 self.write(")");
6471 }
6472
6473 if let Some(ref partition_by) = insert.partition_by {
6475 self.write_space();
6476 self.write_keyword("PARTITION BY");
6477 self.write_space();
6478 self.generate_expression(partition_by)?;
6479 }
6480
6481 if !insert.settings.is_empty() {
6483 self.write_space();
6484 self.write_keyword("SETTINGS");
6485 self.write_space();
6486 for (i, setting) in insert.settings.iter().enumerate() {
6487 if i > 0 {
6488 self.write(", ");
6489 }
6490 self.generate_expression(setting)?;
6491 }
6492 }
6493
6494 if !insert.columns.is_empty() {
6495 if insert.alias.is_some() && insert.alias_explicit_as {
6496 self.write("(");
6498 } else {
6499 self.write(" (");
6501 }
6502 for (i, col) in insert.columns.iter().enumerate() {
6503 if i > 0 {
6504 self.write(", ");
6505 }
6506 self.generate_identifier(col)?;
6507 }
6508 self.write(")");
6509 }
6510
6511 if let Some(ref output) = insert.output {
6513 self.generate_output_clause(output)?;
6514 }
6515
6516 if insert.by_name {
6518 self.write_space();
6519 self.write_keyword("BY NAME");
6520 }
6521
6522 if insert.default_values {
6523 self.write_space();
6524 self.write_keyword("DEFAULT VALUES");
6525 } else if let Some(query) = &insert.query {
6526 if self.config.pretty {
6527 self.write_newline();
6528 } else {
6529 self.write_space();
6530 }
6531 if prepend_query_cte.is_some() {
6533 if let Expression::Select(select) = query {
6534 let mut select_no_with = select.clone();
6535 select_no_with.with = None;
6536 self.generate_select(&select_no_with)?;
6537 } else {
6538 self.generate_expression(query)?;
6539 }
6540 } else {
6541 self.generate_expression(query)?;
6542 }
6543 } else if !insert.values.is_empty() {
6544 if self.config.pretty {
6545 self.write_newline();
6547 self.write_keyword("VALUES");
6548 self.write_newline();
6549 self.indent_level += 1;
6550 for (i, row) in insert.values.iter().enumerate() {
6551 if i > 0 {
6552 self.write(",");
6553 self.write_newline();
6554 }
6555 self.write_indent();
6556 self.write("(");
6557 for (j, val) in row.iter().enumerate() {
6558 if j > 0 {
6559 self.write(", ");
6560 }
6561 self.generate_expression(val)?;
6562 }
6563 self.write(")");
6564 }
6565 self.indent_level -= 1;
6566 } else {
6567 self.write_space();
6569 self.write_keyword("VALUES");
6570 for (i, row) in insert.values.iter().enumerate() {
6571 if i > 0 {
6572 self.write(",");
6573 }
6574 self.write(" (");
6575 for (j, val) in row.iter().enumerate() {
6576 if j > 0 {
6577 self.write(", ");
6578 }
6579 self.generate_expression(val)?;
6580 }
6581 self.write(")");
6582 }
6583 }
6584 }
6585
6586 if let Some(ref source) = insert.source {
6588 self.write_space();
6589 self.write_keyword("TABLE");
6590 self.write_space();
6591 self.generate_expression(source)?;
6592 }
6593
6594 if let Some(alias) = &insert.source_alias {
6596 self.write_space();
6597 self.write_keyword("AS");
6598 self.write_space();
6599 self.generate_identifier(alias)?;
6600 }
6601
6602 if let Some(on_conflict) = &insert.on_conflict {
6604 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
6605 self.write_space();
6606 self.generate_expression(on_conflict)?;
6607 }
6608 }
6609
6610 if !insert.returning.is_empty() {
6612 self.write_space();
6613 self.write_keyword("RETURNING");
6614 self.write_space();
6615 for (i, expr) in insert.returning.iter().enumerate() {
6616 if i > 0 {
6617 self.write(", ");
6618 }
6619 self.generate_expression(expr)?;
6620 }
6621 }
6622
6623 Ok(())
6624 }
6625
6626 fn generate_update(&mut self, update: &Update) -> Result<()> {
6627 for comment in &update.leading_comments {
6629 self.write_formatted_comment(comment);
6630 self.write(" ");
6631 }
6632
6633 if let Some(ref with) = update.with {
6635 self.generate_with(with)?;
6636 self.write_space();
6637 }
6638
6639 self.write_keyword("UPDATE");
6640 self.write_space();
6641 self.generate_table(&update.table)?;
6642
6643 let mysql_like_update_from = matches!(
6644 self.config.dialect,
6645 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
6646 ) && update.from_clause.is_some();
6647
6648 let mut set_pairs = update.set.clone();
6649
6650 let mut pre_set_joins = update.table_joins.clone();
6652 if mysql_like_update_from {
6653 let target_name = update
6654 .table
6655 .alias
6656 .as_ref()
6657 .map(|a| a.name.clone())
6658 .unwrap_or_else(|| update.table.name.name.clone());
6659
6660 for (col, _) in &mut set_pairs {
6661 if !col.name.contains('.') {
6662 col.name = format!("{}.{}", target_name, col.name);
6663 }
6664 }
6665
6666 if let Some(from_clause) = &update.from_clause {
6667 for table_expr in &from_clause.expressions {
6668 pre_set_joins.push(crate::expressions::Join {
6669 this: table_expr.clone(),
6670 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
6671 value: true,
6672 })),
6673 using: Vec::new(),
6674 kind: crate::expressions::JoinKind::Inner,
6675 use_inner_keyword: false,
6676 use_outer_keyword: false,
6677 deferred_condition: false,
6678 join_hint: None,
6679 match_condition: None,
6680 pivots: Vec::new(),
6681 comments: Vec::new(),
6682 nesting_group: 0,
6683 directed: false,
6684 });
6685 }
6686 }
6687 for join in &update.from_joins {
6688 let mut join = join.clone();
6689 if join.on.is_none() && join.using.is_empty() {
6690 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
6691 value: true,
6692 }));
6693 }
6694 pre_set_joins.push(join);
6695 }
6696 }
6697
6698 for extra_table in &update.extra_tables {
6700 self.write(", ");
6701 self.generate_table(extra_table)?;
6702 }
6703
6704 for join in &pre_set_joins {
6706 self.generate_join(join)?;
6708 }
6709
6710 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
6712 if teradata_from_before_set && !mysql_like_update_from {
6713 if let Some(ref from_clause) = update.from_clause {
6714 self.write_space();
6715 self.write_keyword("FROM");
6716 self.write_space();
6717 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
6718 if i > 0 {
6719 self.write(", ");
6720 }
6721 self.generate_expression(table_expr)?;
6722 }
6723 }
6724 for join in &update.from_joins {
6725 self.generate_join(join)?;
6726 }
6727 }
6728
6729 self.write_space();
6730 self.write_keyword("SET");
6731 self.write_space();
6732
6733 for (i, (col, val)) in set_pairs.iter().enumerate() {
6734 if i > 0 {
6735 self.write(", ");
6736 }
6737 self.generate_identifier(col)?;
6738 self.write(" = ");
6739 self.generate_expression(val)?;
6740 }
6741
6742 if let Some(ref output) = update.output {
6744 self.generate_output_clause(output)?;
6745 }
6746
6747 if !mysql_like_update_from && !teradata_from_before_set {
6749 if let Some(ref from_clause) = update.from_clause {
6750 self.write_space();
6751 self.write_keyword("FROM");
6752 self.write_space();
6753 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
6755 if i > 0 {
6756 self.write(", ");
6757 }
6758 self.generate_expression(table_expr)?;
6759 }
6760 }
6761 }
6762
6763 if !mysql_like_update_from && !teradata_from_before_set {
6764 for join in &update.from_joins {
6766 self.generate_join(join)?;
6767 }
6768 }
6769
6770 if let Some(where_clause) = &update.where_clause {
6771 self.write_space();
6772 self.write_keyword("WHERE");
6773 self.write_space();
6774 self.generate_expression(&where_clause.this)?;
6775 }
6776
6777 if !update.returning.is_empty() {
6779 self.write_space();
6780 self.write_keyword("RETURNING");
6781 self.write_space();
6782 for (i, expr) in update.returning.iter().enumerate() {
6783 if i > 0 {
6784 self.write(", ");
6785 }
6786 self.generate_expression(expr)?;
6787 }
6788 }
6789
6790 if let Some(ref order_by) = update.order_by {
6792 self.write_space();
6793 self.generate_order_by(order_by)?;
6794 }
6795
6796 if let Some(ref limit) = update.limit {
6798 self.write_space();
6799 self.write_keyword("LIMIT");
6800 self.write_space();
6801 self.generate_expression(limit)?;
6802 }
6803
6804 Ok(())
6805 }
6806
6807 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
6808 if let Some(with) = &delete.with {
6810 self.generate_with(with)?;
6811 self.write_space();
6812 }
6813
6814 for comment in &delete.leading_comments {
6816 self.write_formatted_comment(comment);
6817 self.write(" ");
6818 }
6819
6820 if !delete.tables.is_empty() && !delete.tables_from_using {
6822 self.write_keyword("DELETE");
6824 self.write_space();
6825 for (i, tbl) in delete.tables.iter().enumerate() {
6826 if i > 0 {
6827 self.write(", ");
6828 }
6829 self.generate_table(tbl)?;
6830 }
6831 if let Some(ref output) = delete.output {
6833 self.generate_output_clause(output)?;
6834 }
6835 self.write_space();
6836 self.write_keyword("FROM");
6837 self.write_space();
6838 self.generate_table(&delete.table)?;
6839 } else if !delete.tables.is_empty() && delete.tables_from_using {
6840 self.write_keyword("DELETE FROM");
6842 self.write_space();
6843 for (i, tbl) in delete.tables.iter().enumerate() {
6844 if i > 0 {
6845 self.write(", ");
6846 }
6847 self.generate_table(tbl)?;
6848 }
6849 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
6850 self.write_keyword("DELETE");
6852 self.write_space();
6853 self.generate_table(&delete.table)?;
6854 } else {
6855 self.write_keyword("DELETE FROM");
6856 self.write_space();
6857 self.generate_table(&delete.table)?;
6858 }
6859
6860 if let Some(ref on_cluster) = delete.on_cluster {
6862 self.write_space();
6863 self.generate_on_cluster(on_cluster)?;
6864 }
6865
6866 if let Some(ref idx) = delete.force_index {
6868 self.write_space();
6869 self.write_keyword("FORCE INDEX");
6870 self.write(" (");
6871 self.write(idx);
6872 self.write(")");
6873 }
6874
6875 if let Some(ref alias) = delete.alias {
6877 self.write_space();
6878 if delete.alias_explicit_as
6879 || matches!(self.config.dialect, Some(DialectType::BigQuery))
6880 {
6881 self.write_keyword("AS");
6882 self.write_space();
6883 }
6884 self.generate_identifier(alias)?;
6885 }
6886
6887 if !delete.tables_from_using {
6889 for join in &delete.joins {
6890 self.generate_join(join)?;
6891 }
6892 }
6893
6894 if !delete.using.is_empty() {
6896 self.write_space();
6897 self.write_keyword("USING");
6898 for (i, table) in delete.using.iter().enumerate() {
6899 if i > 0 {
6900 self.write(",");
6901 }
6902 self.write_space();
6903 if !table.hints.is_empty() && table.name.is_empty() {
6905 self.generate_expression(&table.hints[0])?;
6907 if let Some(ref alias) = table.alias {
6908 self.write_space();
6909 if table.alias_explicit_as {
6910 self.write_keyword("AS");
6911 self.write_space();
6912 }
6913 self.generate_identifier(alias)?;
6914 if !table.column_aliases.is_empty() {
6915 self.write("(");
6916 for (j, col_alias) in table.column_aliases.iter().enumerate() {
6917 if j > 0 {
6918 self.write(", ");
6919 }
6920 self.generate_identifier(col_alias)?;
6921 }
6922 self.write(")");
6923 }
6924 }
6925 } else {
6926 self.generate_table(table)?;
6927 }
6928 }
6929 }
6930
6931 if delete.tables_from_using {
6933 for join in &delete.joins {
6934 self.generate_join(join)?;
6935 }
6936 }
6937
6938 let output_already_emitted =
6940 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
6941 if !output_already_emitted {
6942 if let Some(ref output) = delete.output {
6943 self.generate_output_clause(output)?;
6944 }
6945 }
6946
6947 if let Some(where_clause) = &delete.where_clause {
6948 self.write_space();
6949 self.write_keyword("WHERE");
6950 self.write_space();
6951 self.generate_expression(&where_clause.this)?;
6952 }
6953
6954 if let Some(ref order_by) = delete.order_by {
6956 self.write_space();
6957 self.generate_order_by(order_by)?;
6958 }
6959
6960 if let Some(ref limit) = delete.limit {
6962 self.write_space();
6963 self.write_keyword("LIMIT");
6964 self.write_space();
6965 self.generate_expression(limit)?;
6966 }
6967
6968 if !delete.returning.is_empty() {
6970 self.write_space();
6971 self.write_keyword("RETURNING");
6972 self.write_space();
6973 for (i, expr) in delete.returning.iter().enumerate() {
6974 if i > 0 {
6975 self.write(", ");
6976 }
6977 self.generate_expression(expr)?;
6978 }
6979 }
6980
6981 Ok(())
6982 }
6983
6984 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
6987 let saved_athena_hive_context = self.athena_hive_context;
6991 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
6992 if matches!(
6993 self.config.dialect,
6994 Some(crate::dialects::DialectType::Athena)
6995 ) {
6996 let is_external = ct
7000 .table_modifier
7001 .as_ref()
7002 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
7003 .unwrap_or(false);
7004 let has_as_select = ct.as_select.is_some();
7005 self.athena_hive_context = is_external || !has_as_select;
7006 }
7007
7008 if matches!(
7010 self.config.dialect,
7011 Some(crate::dialects::DialectType::TSQL)
7012 ) {
7013 if let Some(ref query) = ct.as_select {
7014 if let Some(with_cte) = &ct.with_cte {
7016 self.generate_with(with_cte)?;
7017 self.write_space();
7018 }
7019
7020 self.write_keyword("SELECT");
7022 self.write(" * ");
7023 self.write_keyword("INTO");
7024 self.write_space();
7025
7026 if ct.temporary {
7028 self.write("#");
7029 }
7030 self.generate_table(&ct.name)?;
7031
7032 self.write_space();
7033 self.write_keyword("FROM");
7034 self.write(" (");
7035 let aliased_query = Self::add_column_aliases_to_query(query.clone());
7037 self.generate_expression(&aliased_query)?;
7038 self.write(") ");
7039 self.write_keyword("AS");
7040 self.write(" temp");
7041 return Ok(());
7042 }
7043 }
7044
7045 if let Some(with_cte) = &ct.with_cte {
7047 self.generate_with(with_cte)?;
7048 self.write_space();
7049 }
7050
7051 for comment in &ct.leading_comments {
7053 self.write_formatted_comment(comment);
7054 self.write(" ");
7055 }
7056 self.write_keyword("CREATE");
7057
7058 if ct.or_replace {
7059 self.write_space();
7060 self.write_keyword("OR REPLACE");
7061 }
7062
7063 if ct.temporary {
7064 self.write_space();
7065 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
7067 self.write_keyword("GLOBAL TEMPORARY");
7068 } else {
7069 self.write_keyword("TEMPORARY");
7070 }
7071 }
7072
7073 let is_dictionary = ct
7075 .table_modifier
7076 .as_ref()
7077 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
7078 .unwrap_or(false);
7079 if let Some(ref modifier) = ct.table_modifier {
7080 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
7082 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
7083 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
7085 || modifier.eq_ignore_ascii_case("SET")
7086 || modifier.eq_ignore_ascii_case("MULTISET")
7087 || modifier.to_uppercase().contains("VOLATILE")
7088 || modifier.to_uppercase().starts_with("SET ")
7089 || modifier.to_uppercase().starts_with("MULTISET ");
7090 let skip_teradata =
7091 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
7092 if !skip_transient && !skip_teradata {
7093 self.write_space();
7094 self.write_keyword(modifier);
7095 }
7096 }
7097
7098 if !is_dictionary {
7099 self.write_space();
7100 self.write_keyword("TABLE");
7101 }
7102
7103 if ct.if_not_exists {
7104 self.write_space();
7105 self.write_keyword("IF NOT EXISTS");
7106 }
7107
7108 self.write_space();
7109 self.generate_table(&ct.name)?;
7110
7111 if let Some(ref on_cluster) = ct.on_cluster {
7113 self.write_space();
7114 self.generate_on_cluster(on_cluster)?;
7115 }
7116
7117 if matches!(
7119 self.config.dialect,
7120 Some(crate::dialects::DialectType::Teradata)
7121 ) && !ct.teradata_post_name_options.is_empty()
7122 {
7123 for opt in &ct.teradata_post_name_options {
7124 self.write(", ");
7125 self.write(opt);
7126 }
7127 }
7128
7129 if ct.copy_grants {
7131 self.write_space();
7132 self.write_keyword("COPY GRANTS");
7133 }
7134
7135 if let Some(ref using_template) = ct.using_template {
7137 self.write_space();
7138 self.write_keyword("USING TEMPLATE");
7139 self.write_space();
7140 self.generate_expression(using_template)?;
7141 return Ok(());
7142 }
7143
7144 if let Some(ref clone_source) = ct.clone_source {
7146 self.write_space();
7147 if ct.is_copy && self.config.supports_table_copy {
7148 self.write_keyword("COPY");
7150 } else if ct.shallow_clone {
7151 self.write_keyword("SHALLOW CLONE");
7152 } else {
7153 self.write_keyword("CLONE");
7154 }
7155 self.write_space();
7156 self.generate_table(clone_source)?;
7157 if let Some(ref at_clause) = ct.clone_at_clause {
7159 self.write_space();
7160 self.generate_expression(at_clause)?;
7161 }
7162 return Ok(());
7163 }
7164
7165 if let Some(ref partition_of) = ct.partition_of {
7169 self.write_space();
7170
7171 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
7173 self.write_keyword("PARTITION OF");
7175 self.write_space();
7176 self.generate_expression(&pop.this)?;
7177
7178 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7180 self.write(" (");
7181 let mut first = true;
7182 for col in &ct.columns {
7183 if !first {
7184 self.write(", ");
7185 }
7186 first = false;
7187 self.generate_column_def(col)?;
7188 }
7189 for constraint in &ct.constraints {
7190 if !first {
7191 self.write(", ");
7192 }
7193 first = false;
7194 self.generate_table_constraint(constraint)?;
7195 }
7196 self.write(")");
7197 }
7198
7199 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
7201 self.write_space();
7202 self.write_keyword("FOR VALUES");
7203 self.write_space();
7204 self.generate_expression(&pop.expression)?;
7205 } else {
7206 self.write_space();
7207 self.write_keyword("DEFAULT");
7208 }
7209 } else {
7210 self.generate_expression(partition_of)?;
7212
7213 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7215 self.write(" (");
7216 let mut first = true;
7217 for col in &ct.columns {
7218 if !first {
7219 self.write(", ");
7220 }
7221 first = false;
7222 self.generate_column_def(col)?;
7223 }
7224 for constraint in &ct.constraints {
7225 if !first {
7226 self.write(", ");
7227 }
7228 first = false;
7229 self.generate_table_constraint(constraint)?;
7230 }
7231 self.write(")");
7232 }
7233 }
7234
7235 for prop in &ct.properties {
7237 self.write_space();
7238 self.generate_expression(prop)?;
7239 }
7240
7241 return Ok(());
7242 }
7243
7244 self.sqlite_inline_pk_columns.clear();
7247 if matches!(
7248 self.config.dialect,
7249 Some(crate::dialects::DialectType::SQLite)
7250 ) {
7251 for constraint in &ct.constraints {
7252 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7253 if columns.len() == 1 && name.is_none() {
7255 let pk_col_name = columns[0].name.to_lowercase();
7256 if ct
7258 .columns
7259 .iter()
7260 .any(|c| c.name.name.to_lowercase() == pk_col_name)
7261 {
7262 self.sqlite_inline_pk_columns.insert(pk_col_name);
7263 }
7264 }
7265 }
7266 }
7267 }
7268
7269 if !ct.columns.is_empty() {
7271 if self.config.pretty {
7272 self.write(" (");
7274 self.write_newline();
7275 self.indent_level += 1;
7276 for (i, col) in ct.columns.iter().enumerate() {
7277 if i > 0 {
7278 self.write(",");
7279 self.write_newline();
7280 }
7281 self.write_indent();
7282 self.generate_column_def(col)?;
7283 }
7284 for constraint in &ct.constraints {
7286 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7288 if columns.len() == 1
7289 && name.is_none()
7290 && self
7291 .sqlite_inline_pk_columns
7292 .contains(&columns[0].name.to_lowercase())
7293 {
7294 continue;
7295 }
7296 }
7297 self.write(",");
7298 self.write_newline();
7299 self.write_indent();
7300 self.generate_table_constraint(constraint)?;
7301 }
7302 self.indent_level -= 1;
7303 self.write_newline();
7304 self.write(")");
7305 } else {
7306 self.write(" (");
7307 for (i, col) in ct.columns.iter().enumerate() {
7308 if i > 0 {
7309 self.write(", ");
7310 }
7311 self.generate_column_def(col)?;
7312 }
7313 let mut first_constraint = true;
7315 for constraint in &ct.constraints {
7316 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7318 if columns.len() == 1
7319 && name.is_none()
7320 && self
7321 .sqlite_inline_pk_columns
7322 .contains(&columns[0].name.to_lowercase())
7323 {
7324 continue;
7325 }
7326 }
7327 if first_constraint {
7328 self.write(", ");
7329 first_constraint = false;
7330 } else {
7331 self.write(", ");
7332 }
7333 self.generate_table_constraint(constraint)?;
7334 }
7335 self.write(")");
7336 }
7337 } else if !ct.constraints.is_empty() {
7338 let has_like_only = ct
7340 .constraints
7341 .iter()
7342 .all(|c| matches!(c, TableConstraint::Like { .. }));
7343 let has_tags_only = ct
7344 .constraints
7345 .iter()
7346 .all(|c| matches!(c, TableConstraint::Tags(_)));
7347 let is_pg_like = matches!(
7351 self.config.dialect,
7352 Some(crate::dialects::DialectType::PostgreSQL)
7353 | Some(crate::dialects::DialectType::CockroachDB)
7354 | Some(crate::dialects::DialectType::Materialize)
7355 | Some(crate::dialects::DialectType::RisingWave)
7356 | Some(crate::dialects::DialectType::Redshift)
7357 | Some(crate::dialects::DialectType::Presto)
7358 | Some(crate::dialects::DialectType::Trino)
7359 | Some(crate::dialects::DialectType::Athena)
7360 );
7361 let use_parens = if has_like_only {
7362 is_pg_like
7363 } else {
7364 !has_tags_only
7365 };
7366 if self.config.pretty && use_parens {
7367 self.write(" (");
7368 self.write_newline();
7369 self.indent_level += 1;
7370 for (i, constraint) in ct.constraints.iter().enumerate() {
7371 if i > 0 {
7372 self.write(",");
7373 self.write_newline();
7374 }
7375 self.write_indent();
7376 self.generate_table_constraint(constraint)?;
7377 }
7378 self.indent_level -= 1;
7379 self.write_newline();
7380 self.write(")");
7381 } else {
7382 if use_parens {
7383 self.write(" (");
7384 } else {
7385 self.write_space();
7386 }
7387 for (i, constraint) in ct.constraints.iter().enumerate() {
7388 if i > 0 {
7389 self.write(", ");
7390 }
7391 self.generate_table_constraint(constraint)?;
7392 }
7393 if use_parens {
7394 self.write(")");
7395 }
7396 }
7397 }
7398
7399 if let Some(ref on_prop) = ct.on_property {
7401 self.write(" ");
7402 self.write_keyword("ON");
7403 self.write(" ");
7404 self.generate_expression(&on_prop.this)?;
7405 }
7406
7407 if !is_clickhouse {
7410 for prop in &ct.properties {
7411 if let Expression::SchemaCommentProperty(_) = prop {
7412 if self.config.pretty {
7413 self.write_newline();
7414 } else {
7415 self.write_space();
7416 }
7417 self.generate_expression(prop)?;
7418 }
7419 }
7420 }
7421
7422 if !ct.with_properties.is_empty() {
7424 let is_snowflake_special_table = matches!(
7426 self.config.dialect,
7427 Some(crate::dialects::DialectType::Snowflake)
7428 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
7429 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
7430 if is_snowflake_special_table {
7431 for (key, value) in &ct.with_properties {
7432 self.write_space();
7433 self.write(key);
7434 self.write("=");
7435 self.write(value);
7436 }
7437 } else if self.config.pretty {
7438 self.write_newline();
7439 self.write_keyword("WITH");
7440 self.write(" (");
7441 self.write_newline();
7442 self.indent_level += 1;
7443 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7444 if i > 0 {
7445 self.write(",");
7446 self.write_newline();
7447 }
7448 self.write_indent();
7449 self.write(key);
7450 self.write("=");
7451 self.write(value);
7452 }
7453 self.indent_level -= 1;
7454 self.write_newline();
7455 self.write(")");
7456 } else {
7457 self.write_space();
7458 self.write_keyword("WITH");
7459 self.write(" (");
7460 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7461 if i > 0 {
7462 self.write(", ");
7463 }
7464 self.write(key);
7465 self.write("=");
7466 self.write(value);
7467 }
7468 self.write(")");
7469 }
7470 }
7471
7472 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
7473 if is_clickhouse && ct.as_select.is_some() {
7474 let mut pre = Vec::new();
7475 let mut post = Vec::new();
7476 for prop in &ct.properties {
7477 if matches!(prop, Expression::SchemaCommentProperty(_)) {
7478 post.push(prop);
7479 } else {
7480 pre.push(prop);
7481 }
7482 }
7483 (pre, post)
7484 } else {
7485 (ct.properties.iter().collect(), Vec::new())
7486 };
7487
7488 for prop in pre_as_properties {
7490 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
7492 continue;
7493 }
7494 if self.config.pretty {
7495 self.write_newline();
7496 } else {
7497 self.write_space();
7498 }
7499 if let Expression::Properties(props) = prop {
7503 let is_hive_dialect = matches!(
7504 self.config.dialect,
7505 Some(crate::dialects::DialectType::Hive)
7506 | Some(crate::dialects::DialectType::Spark)
7507 | Some(crate::dialects::DialectType::Databricks)
7508 | Some(crate::dialects::DialectType::Athena)
7509 );
7510 let is_doris_starrocks = matches!(
7511 self.config.dialect,
7512 Some(crate::dialects::DialectType::Doris)
7513 | Some(crate::dialects::DialectType::StarRocks)
7514 );
7515 if is_hive_dialect {
7516 self.generate_tblproperties_clause(&props.expressions)?;
7517 } else if is_doris_starrocks {
7518 self.generate_properties_clause(&props.expressions)?;
7519 } else {
7520 self.generate_options_clause(&props.expressions)?;
7521 }
7522 } else {
7523 self.generate_expression(prop)?;
7524 }
7525 }
7526
7527 for prop in &ct.post_table_properties {
7529 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
7530 self.write(" WITH(");
7531 self.generate_system_versioning_content(svp)?;
7532 self.write(")");
7533 } else if let Expression::Properties(props) = prop {
7534 let is_doris_starrocks = matches!(
7536 self.config.dialect,
7537 Some(crate::dialects::DialectType::Doris)
7538 | Some(crate::dialects::DialectType::StarRocks)
7539 );
7540 self.write_space();
7541 if is_doris_starrocks {
7542 self.generate_properties_clause(&props.expressions)?;
7543 } else {
7544 self.generate_options_clause(&props.expressions)?;
7545 }
7546 } else {
7547 self.write_space();
7548 self.generate_expression(prop)?;
7549 }
7550 }
7551
7552 if let Some(ref rollup) = ct.rollup {
7555 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
7556 self.write_space();
7557 self.generate_rollup_property(rollup)?;
7558 }
7559 }
7560
7561 let is_mysql_compatible = matches!(
7565 self.config.dialect,
7566 Some(DialectType::MySQL)
7567 | Some(DialectType::SingleStore)
7568 | Some(DialectType::Doris)
7569 | Some(DialectType::StarRocks)
7570 | None
7571 );
7572 let is_hive_compatible = matches!(
7573 self.config.dialect,
7574 Some(DialectType::Hive)
7575 | Some(DialectType::Spark)
7576 | Some(DialectType::Databricks)
7577 | Some(DialectType::Athena)
7578 );
7579 let mysql_pretty_options =
7580 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
7581 for (key, value) in &ct.mysql_table_options {
7582 let should_output = if is_mysql_compatible {
7584 true
7585 } else if is_hive_compatible && key == "COMMENT" {
7586 true } else {
7588 false
7589 };
7590 if should_output {
7591 if mysql_pretty_options {
7592 self.write_newline();
7593 self.write_indent();
7594 } else {
7595 self.write_space();
7596 }
7597 self.write_keyword(key);
7598 if key == "COMMENT" && !self.config.schema_comment_with_eq {
7600 self.write_space();
7601 } else {
7602 self.write("=");
7603 }
7604 self.write(value);
7605 }
7606 }
7607
7608 if ct.temporary
7610 && matches!(
7611 self.config.dialect,
7612 Some(DialectType::Spark) | Some(DialectType::Databricks)
7613 )
7614 && ct.as_select.is_none()
7615 {
7616 self.write_space();
7617 self.write_keyword("USING PARQUET");
7618 }
7619
7620 if !ct.inherits.is_empty() {
7622 self.write_space();
7623 self.write_keyword("INHERITS");
7624 self.write(" (");
7625 for (i, parent) in ct.inherits.iter().enumerate() {
7626 if i > 0 {
7627 self.write(", ");
7628 }
7629 self.generate_table(parent)?;
7630 }
7631 self.write(")");
7632 }
7633
7634 if let Some(ref query) = ct.as_select {
7636 self.write_space();
7637 self.write_keyword("AS");
7638 self.write_space();
7639 if ct.as_select_parenthesized {
7640 self.write("(");
7641 }
7642 self.generate_expression(query)?;
7643 if ct.as_select_parenthesized {
7644 self.write(")");
7645 }
7646
7647 if let Some(with_data) = ct.with_data {
7649 self.write_space();
7650 self.write_keyword("WITH");
7651 if !with_data {
7652 self.write_space();
7653 self.write_keyword("NO");
7654 }
7655 self.write_space();
7656 self.write_keyword("DATA");
7657 }
7658
7659 if let Some(with_statistics) = ct.with_statistics {
7661 self.write_space();
7662 self.write_keyword("AND");
7663 if !with_statistics {
7664 self.write_space();
7665 self.write_keyword("NO");
7666 }
7667 self.write_space();
7668 self.write_keyword("STATISTICS");
7669 }
7670
7671 for index in &ct.teradata_indexes {
7673 self.write_space();
7674 match index.kind {
7675 TeradataIndexKind::NoPrimary => {
7676 self.write_keyword("NO PRIMARY INDEX");
7677 }
7678 TeradataIndexKind::Primary => {
7679 self.write_keyword("PRIMARY INDEX");
7680 }
7681 TeradataIndexKind::PrimaryAmp => {
7682 self.write_keyword("PRIMARY AMP INDEX");
7683 }
7684 TeradataIndexKind::Unique => {
7685 self.write_keyword("UNIQUE INDEX");
7686 }
7687 TeradataIndexKind::UniquePrimary => {
7688 self.write_keyword("UNIQUE PRIMARY INDEX");
7689 }
7690 TeradataIndexKind::Secondary => {
7691 self.write_keyword("INDEX");
7692 }
7693 }
7694 if let Some(ref name) = index.name {
7696 self.write_space();
7697 self.write(name);
7698 }
7699 if !index.columns.is_empty() {
7701 self.write(" (");
7702 for (i, col) in index.columns.iter().enumerate() {
7703 if i > 0 {
7704 self.write(", ");
7705 }
7706 self.write(col);
7707 }
7708 self.write(")");
7709 }
7710 }
7711
7712 if let Some(ref on_commit) = ct.on_commit {
7714 self.write_space();
7715 self.write_keyword("ON COMMIT");
7716 self.write_space();
7717 match on_commit {
7718 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
7719 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
7720 }
7721 }
7722
7723 if !post_as_properties.is_empty() {
7724 for prop in post_as_properties {
7725 self.write_space();
7726 self.generate_expression(prop)?;
7727 }
7728 }
7729
7730 self.athena_hive_context = saved_athena_hive_context;
7732 return Ok(());
7733 }
7734
7735 if let Some(ref on_commit) = ct.on_commit {
7737 self.write_space();
7738 self.write_keyword("ON COMMIT");
7739 self.write_space();
7740 match on_commit {
7741 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
7742 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
7743 }
7744 }
7745
7746 self.athena_hive_context = saved_athena_hive_context;
7748
7749 Ok(())
7750 }
7751
7752 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
7755 self.generate_identifier(&col.name)?;
7757 if !matches!(col.data_type, DataType::Unknown) {
7759 self.write_space();
7760 self.generate_data_type(&col.data_type)?;
7761 }
7762 for constraint in &col.constraints {
7764 if let ColumnConstraint::Path(path_expr) = constraint {
7765 self.write_space();
7766 self.write_keyword("PATH");
7767 self.write_space();
7768 self.generate_expression(path_expr)?;
7769 }
7770 }
7771 Ok(())
7772 }
7773
7774 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
7775 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
7777 && col
7778 .constraints
7779 .iter()
7780 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
7781 let omit_computed_type = !self.config.computed_column_with_type
7783 && col
7784 .constraints
7785 .iter()
7786 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
7787
7788 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
7791
7792 let has_no_type = col.no_type
7795 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
7796 && col.constraints.is_empty());
7797
7798 self.generate_identifier(&col.name)?;
7799
7800 let serial_expansion = if matches!(
7802 self.config.dialect,
7803 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
7804 ) {
7805 if let DataType::Custom { ref name } = col.data_type {
7806 match name.to_uppercase().as_str() {
7807 "SERIAL" => Some("INT"),
7808 "BIGSERIAL" => Some("BIGINT"),
7809 "SMALLSERIAL" => Some("SMALLINT"),
7810 _ => None,
7811 }
7812 } else {
7813 None
7814 }
7815 } else {
7816 None
7817 };
7818
7819 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
7820 {
7821 self.write_space();
7822 let saved_nullable_depth = self.clickhouse_nullable_depth;
7825 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
7826 self.clickhouse_nullable_depth = -1;
7827 }
7828 if let Some(int_type) = serial_expansion {
7829 self.write_keyword(int_type);
7831 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
7832 let unsigned_type = match &col.data_type {
7834 DataType::Int { .. } => Some("UINTEGER"),
7835 DataType::BigInt { .. } => Some("UBIGINT"),
7836 DataType::SmallInt { .. } => Some("USMALLINT"),
7837 DataType::TinyInt { .. } => Some("UTINYINT"),
7838 _ => None,
7839 };
7840 if let Some(utype) = unsigned_type {
7841 self.write_keyword(utype);
7842 } else {
7843 self.generate_data_type(&col.data_type)?;
7844 }
7845 } else {
7846 self.generate_data_type(&col.data_type)?;
7847 }
7848 self.clickhouse_nullable_depth = saved_nullable_depth;
7849 }
7850
7851 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
7854 self.write_space();
7855 self.write_keyword("UNSIGNED");
7856 }
7857 if col.zerofill {
7858 self.write_space();
7859 self.write_keyword("ZEROFILL");
7860 }
7861
7862 if let Some(ref charset) = col.character_set {
7866 self.write_space();
7867 self.write_keyword("CHARACTER SET");
7868 self.write_space();
7869 self.write(charset);
7870 }
7871
7872 if col.uppercase {
7873 self.write_space();
7874 self.write_keyword("UPPERCASE");
7875 }
7876
7877 if let Some(casespecific) = col.casespecific {
7878 self.write_space();
7879 if casespecific {
7880 self.write_keyword("CASESPECIFIC");
7881 } else {
7882 self.write_keyword("NOT CASESPECIFIC");
7883 }
7884 }
7885
7886 if let Some(ref format) = col.format {
7887 self.write_space();
7888 self.write_keyword("FORMAT");
7889 self.write(" '");
7890 self.write(format);
7891 self.write("'");
7892 }
7893
7894 if let Some(ref title) = col.title {
7895 self.write_space();
7896 self.write_keyword("TITLE");
7897 self.write(" '");
7898 self.write(title);
7899 self.write("'");
7900 }
7901
7902 if let Some(length) = col.inline_length {
7903 self.write_space();
7904 self.write_keyword("INLINE LENGTH");
7905 self.write(" ");
7906 self.write(&length.to_string());
7907 }
7908
7909 if let Some(ref compress) = col.compress {
7910 self.write_space();
7911 self.write_keyword("COMPRESS");
7912 if !compress.is_empty() {
7913 if compress.len() == 1 {
7915 if let Expression::Literal(Literal::String(_)) = &compress[0] {
7916 self.write_space();
7917 self.generate_expression(&compress[0])?;
7918 } else {
7919 self.write(" (");
7920 self.generate_expression(&compress[0])?;
7921 self.write(")");
7922 }
7923 } else {
7924 self.write(" (");
7925 for (i, val) in compress.iter().enumerate() {
7926 if i > 0 {
7927 self.write(", ");
7928 }
7929 self.generate_expression(val)?;
7930 }
7931 self.write(")");
7932 }
7933 }
7934 }
7935
7936 if !col.constraint_order.is_empty() {
7939 let mut references_idx = 0;
7942 let mut check_idx = 0;
7943 let mut generated_idx = 0;
7944 let mut collate_idx = 0;
7945 let mut comment_idx = 0;
7946 let defer_not_null_after_identity = false;
7949 let mut pending_not_null_after_identity = false;
7950
7951 for constraint_type in &col.constraint_order {
7952 match constraint_type {
7953 ConstraintType::PrimaryKey => {
7954 if col.primary_key
7956 && !matches!(self.config.dialect, Some(DialectType::Materialize))
7957 {
7958 if let Some(ref cname) = col.primary_key_constraint_name {
7959 self.write_space();
7960 self.write_keyword("CONSTRAINT");
7961 self.write_space();
7962 self.write(cname);
7963 }
7964 self.write_space();
7965 self.write_keyword("PRIMARY KEY");
7966 if let Some(ref order) = col.primary_key_order {
7967 self.write_space();
7968 match order {
7969 SortOrder::Asc => self.write_keyword("ASC"),
7970 SortOrder::Desc => self.write_keyword("DESC"),
7971 }
7972 }
7973 }
7974 }
7975 ConstraintType::Unique => {
7976 if col.unique {
7977 if let Some(ref cname) = col.unique_constraint_name {
7978 self.write_space();
7979 self.write_keyword("CONSTRAINT");
7980 self.write_space();
7981 self.write(cname);
7982 }
7983 self.write_space();
7984 self.write_keyword("UNIQUE");
7985 if col.unique_nulls_not_distinct {
7987 self.write(" NULLS NOT DISTINCT");
7988 }
7989 }
7990 }
7991 ConstraintType::NotNull => {
7992 if col.nullable == Some(false) {
7993 if defer_not_null_after_identity {
7994 pending_not_null_after_identity = true;
7995 continue;
7996 }
7997 if let Some(ref cname) = col.not_null_constraint_name {
7998 self.write_space();
7999 self.write_keyword("CONSTRAINT");
8000 self.write_space();
8001 self.write(cname);
8002 }
8003 self.write_space();
8004 self.write_keyword("NOT NULL");
8005 }
8006 }
8007 ConstraintType::Null => {
8008 if col.nullable == Some(true) {
8009 self.write_space();
8010 self.write_keyword("NULL");
8011 }
8012 }
8013 ConstraintType::Default => {
8014 if let Some(ref default) = col.default {
8015 self.write_space();
8016 self.write_keyword("DEFAULT");
8017 self.write_space();
8018 self.generate_expression(default)?;
8019 }
8020 }
8021 ConstraintType::AutoIncrement => {
8022 if col.auto_increment {
8023 if matches!(
8025 self.config.dialect,
8026 Some(crate::dialects::DialectType::DuckDB)
8027 ) {
8028 } else if matches!(
8030 self.config.dialect,
8031 Some(crate::dialects::DialectType::Materialize)
8032 ) {
8033 if !matches!(col.nullable, Some(false)) {
8035 self.write_space();
8036 self.write_keyword("NOT NULL");
8037 }
8038 } else if matches!(
8039 self.config.dialect,
8040 Some(crate::dialects::DialectType::PostgreSQL)
8041 ) {
8042 self.write_space();
8044 self.generate_auto_increment_keyword(col)?;
8045 } else {
8046 self.write_space();
8047 self.generate_auto_increment_keyword(col)?;
8048 if pending_not_null_after_identity {
8049 self.write_space();
8050 self.write_keyword("NOT NULL");
8051 pending_not_null_after_identity = false;
8052 }
8053 }
8054 } }
8056 ConstraintType::References => {
8057 while references_idx < col.constraints.len() {
8059 if let ColumnConstraint::References(fk_ref) =
8060 &col.constraints[references_idx]
8061 {
8062 if let Some(ref name) = fk_ref.constraint_name {
8064 self.write_space();
8065 self.write_keyword("CONSTRAINT");
8066 self.write_space();
8067 self.write(name);
8068 }
8069 self.write_space();
8070 if fk_ref.has_foreign_key_keywords {
8071 self.write_keyword("FOREIGN KEY");
8072 self.write_space();
8073 }
8074 self.write_keyword("REFERENCES");
8075 self.write_space();
8076 self.generate_table(&fk_ref.table)?;
8077 if !fk_ref.columns.is_empty() {
8078 self.write(" (");
8079 for (i, c) in fk_ref.columns.iter().enumerate() {
8080 if i > 0 {
8081 self.write(", ");
8082 }
8083 self.generate_identifier(c)?;
8084 }
8085 self.write(")");
8086 }
8087 self.generate_referential_actions(fk_ref)?;
8088 references_idx += 1;
8089 break;
8090 }
8091 references_idx += 1;
8092 }
8093 }
8094 ConstraintType::Check => {
8095 while check_idx < col.constraints.len() {
8097 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
8098 if check_idx == 0 {
8100 if let Some(ref cname) = col.check_constraint_name {
8101 self.write_space();
8102 self.write_keyword("CONSTRAINT");
8103 self.write_space();
8104 self.write(cname);
8105 }
8106 }
8107 self.write_space();
8108 self.write_keyword("CHECK");
8109 self.write(" (");
8110 self.generate_expression(expr)?;
8111 self.write(")");
8112 check_idx += 1;
8113 break;
8114 }
8115 check_idx += 1;
8116 }
8117 }
8118 ConstraintType::GeneratedAsIdentity => {
8119 while generated_idx < col.constraints.len() {
8121 if let ColumnConstraint::GeneratedAsIdentity(gen) =
8122 &col.constraints[generated_idx]
8123 {
8124 self.write_space();
8125 if matches!(
8127 self.config.dialect,
8128 Some(crate::dialects::DialectType::Redshift)
8129 ) {
8130 self.write_keyword("IDENTITY");
8131 self.write("(");
8132 if let Some(ref start) = gen.start {
8133 self.generate_expression(start)?;
8134 } else {
8135 self.write("0");
8136 }
8137 self.write(", ");
8138 if let Some(ref incr) = gen.increment {
8139 self.generate_expression(incr)?;
8140 } else {
8141 self.write("1");
8142 }
8143 self.write(")");
8144 } else {
8145 self.write_keyword("GENERATED");
8146 if gen.always {
8147 self.write_space();
8148 self.write_keyword("ALWAYS");
8149 } else {
8150 self.write_space();
8151 self.write_keyword("BY DEFAULT");
8152 if gen.on_null {
8153 self.write_space();
8154 self.write_keyword("ON NULL");
8155 }
8156 }
8157 self.write_space();
8158 self.write_keyword("AS IDENTITY");
8159
8160 let has_options = gen.start.is_some()
8161 || gen.increment.is_some()
8162 || gen.minvalue.is_some()
8163 || gen.maxvalue.is_some()
8164 || gen.cycle.is_some();
8165 if has_options {
8166 self.write(" (");
8167 let mut first = true;
8168 if let Some(ref start) = gen.start {
8169 if !first {
8170 self.write(" ");
8171 }
8172 first = false;
8173 self.write_keyword("START WITH");
8174 self.write_space();
8175 self.generate_expression(start)?;
8176 }
8177 if let Some(ref incr) = gen.increment {
8178 if !first {
8179 self.write(" ");
8180 }
8181 first = false;
8182 self.write_keyword("INCREMENT BY");
8183 self.write_space();
8184 self.generate_expression(incr)?;
8185 }
8186 if let Some(ref minv) = gen.minvalue {
8187 if !first {
8188 self.write(" ");
8189 }
8190 first = false;
8191 self.write_keyword("MINVALUE");
8192 self.write_space();
8193 self.generate_expression(minv)?;
8194 }
8195 if let Some(ref maxv) = gen.maxvalue {
8196 if !first {
8197 self.write(" ");
8198 }
8199 first = false;
8200 self.write_keyword("MAXVALUE");
8201 self.write_space();
8202 self.generate_expression(maxv)?;
8203 }
8204 if let Some(cycle) = gen.cycle {
8205 if !first {
8206 self.write(" ");
8207 }
8208 if cycle {
8209 self.write_keyword("CYCLE");
8210 } else {
8211 self.write_keyword("NO CYCLE");
8212 }
8213 }
8214 self.write(")");
8215 }
8216 }
8217 generated_idx += 1;
8218 break;
8219 }
8220 generated_idx += 1;
8221 }
8222 }
8223 ConstraintType::Collate => {
8224 while collate_idx < col.constraints.len() {
8226 if let ColumnConstraint::Collate(collation) =
8227 &col.constraints[collate_idx]
8228 {
8229 self.write_space();
8230 self.write_keyword("COLLATE");
8231 self.write_space();
8232 self.generate_identifier(collation)?;
8233 collate_idx += 1;
8234 break;
8235 }
8236 collate_idx += 1;
8237 }
8238 }
8239 ConstraintType::Comment => {
8240 while comment_idx < col.constraints.len() {
8242 if let ColumnConstraint::Comment(comment) =
8243 &col.constraints[comment_idx]
8244 {
8245 self.write_space();
8246 self.write_keyword("COMMENT");
8247 self.write_space();
8248 self.generate_string_literal(comment)?;
8249 comment_idx += 1;
8250 break;
8251 }
8252 comment_idx += 1;
8253 }
8254 }
8255 ConstraintType::Tags => {
8256 for constraint in &col.constraints {
8258 if let ColumnConstraint::Tags(tags) = constraint {
8259 self.write_space();
8260 self.write_keyword("TAG");
8261 self.write(" (");
8262 for (i, expr) in tags.expressions.iter().enumerate() {
8263 if i > 0 {
8264 self.write(", ");
8265 }
8266 self.generate_expression(expr)?;
8267 }
8268 self.write(")");
8269 break;
8270 }
8271 }
8272 }
8273 ConstraintType::ComputedColumn => {
8274 for constraint in &col.constraints {
8276 if let ColumnConstraint::ComputedColumn(cc) = constraint {
8277 self.write_space();
8278 self.generate_computed_column_inline(cc)?;
8279 break;
8280 }
8281 }
8282 }
8283 ConstraintType::GeneratedAsRow => {
8284 for constraint in &col.constraints {
8286 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
8287 self.write_space();
8288 self.generate_generated_as_row_inline(gar)?;
8289 break;
8290 }
8291 }
8292 }
8293 ConstraintType::OnUpdate => {
8294 if let Some(ref expr) = col.on_update {
8295 self.write_space();
8296 self.write_keyword("ON UPDATE");
8297 self.write_space();
8298 self.generate_expression(expr)?;
8299 }
8300 }
8301 ConstraintType::Encode => {
8302 if let Some(ref encoding) = col.encoding {
8303 self.write_space();
8304 self.write_keyword("ENCODE");
8305 self.write_space();
8306 self.write(encoding);
8307 }
8308 }
8309 ConstraintType::Path => {
8310 for constraint in &col.constraints {
8312 if let ColumnConstraint::Path(path_expr) = constraint {
8313 self.write_space();
8314 self.write_keyword("PATH");
8315 self.write_space();
8316 self.generate_expression(path_expr)?;
8317 break;
8318 }
8319 }
8320 }
8321 }
8322 }
8323 if pending_not_null_after_identity {
8324 self.write_space();
8325 self.write_keyword("NOT NULL");
8326 }
8327 } else {
8328 if col.primary_key {
8330 self.write_space();
8331 self.write_keyword("PRIMARY KEY");
8332 if let Some(ref order) = col.primary_key_order {
8333 self.write_space();
8334 match order {
8335 SortOrder::Asc => self.write_keyword("ASC"),
8336 SortOrder::Desc => self.write_keyword("DESC"),
8337 }
8338 }
8339 }
8340
8341 if col.unique {
8342 self.write_space();
8343 self.write_keyword("UNIQUE");
8344 if col.unique_nulls_not_distinct {
8346 self.write(" NULLS NOT DISTINCT");
8347 }
8348 }
8349
8350 match col.nullable {
8351 Some(false) => {
8352 self.write_space();
8353 self.write_keyword("NOT NULL");
8354 }
8355 Some(true) => {
8356 self.write_space();
8357 self.write_keyword("NULL");
8358 }
8359 None => {}
8360 }
8361
8362 if let Some(ref default) = col.default {
8363 self.write_space();
8364 self.write_keyword("DEFAULT");
8365 self.write_space();
8366 self.generate_expression(default)?;
8367 }
8368
8369 if col.auto_increment {
8370 self.write_space();
8371 self.generate_auto_increment_keyword(col)?;
8372 }
8373
8374 for constraint in &col.constraints {
8376 match constraint {
8377 ColumnConstraint::References(fk_ref) => {
8378 self.write_space();
8379 if fk_ref.has_foreign_key_keywords {
8380 self.write_keyword("FOREIGN KEY");
8381 self.write_space();
8382 }
8383 self.write_keyword("REFERENCES");
8384 self.write_space();
8385 self.generate_table(&fk_ref.table)?;
8386 if !fk_ref.columns.is_empty() {
8387 self.write(" (");
8388 for (i, c) in fk_ref.columns.iter().enumerate() {
8389 if i > 0 {
8390 self.write(", ");
8391 }
8392 self.generate_identifier(c)?;
8393 }
8394 self.write(")");
8395 }
8396 self.generate_referential_actions(fk_ref)?;
8397 }
8398 ColumnConstraint::Check(expr) => {
8399 self.write_space();
8400 self.write_keyword("CHECK");
8401 self.write(" (");
8402 self.generate_expression(expr)?;
8403 self.write(")");
8404 }
8405 ColumnConstraint::GeneratedAsIdentity(gen) => {
8406 self.write_space();
8407 if matches!(
8409 self.config.dialect,
8410 Some(crate::dialects::DialectType::Redshift)
8411 ) {
8412 self.write_keyword("IDENTITY");
8413 self.write("(");
8414 if let Some(ref start) = gen.start {
8415 self.generate_expression(start)?;
8416 } else {
8417 self.write("0");
8418 }
8419 self.write(", ");
8420 if let Some(ref incr) = gen.increment {
8421 self.generate_expression(incr)?;
8422 } else {
8423 self.write("1");
8424 }
8425 self.write(")");
8426 } else {
8427 self.write_keyword("GENERATED");
8428 if gen.always {
8429 self.write_space();
8430 self.write_keyword("ALWAYS");
8431 } else {
8432 self.write_space();
8433 self.write_keyword("BY DEFAULT");
8434 if gen.on_null {
8435 self.write_space();
8436 self.write_keyword("ON NULL");
8437 }
8438 }
8439 self.write_space();
8440 self.write_keyword("AS IDENTITY");
8441
8442 let has_options = gen.start.is_some()
8443 || gen.increment.is_some()
8444 || gen.minvalue.is_some()
8445 || gen.maxvalue.is_some()
8446 || gen.cycle.is_some();
8447 if has_options {
8448 self.write(" (");
8449 let mut first = true;
8450 if let Some(ref start) = gen.start {
8451 if !first {
8452 self.write(" ");
8453 }
8454 first = false;
8455 self.write_keyword("START WITH");
8456 self.write_space();
8457 self.generate_expression(start)?;
8458 }
8459 if let Some(ref incr) = gen.increment {
8460 if !first {
8461 self.write(" ");
8462 }
8463 first = false;
8464 self.write_keyword("INCREMENT BY");
8465 self.write_space();
8466 self.generate_expression(incr)?;
8467 }
8468 if let Some(ref minv) = gen.minvalue {
8469 if !first {
8470 self.write(" ");
8471 }
8472 first = false;
8473 self.write_keyword("MINVALUE");
8474 self.write_space();
8475 self.generate_expression(minv)?;
8476 }
8477 if let Some(ref maxv) = gen.maxvalue {
8478 if !first {
8479 self.write(" ");
8480 }
8481 first = false;
8482 self.write_keyword("MAXVALUE");
8483 self.write_space();
8484 self.generate_expression(maxv)?;
8485 }
8486 if let Some(cycle) = gen.cycle {
8487 if !first {
8488 self.write(" ");
8489 }
8490 if cycle {
8491 self.write_keyword("CYCLE");
8492 } else {
8493 self.write_keyword("NO CYCLE");
8494 }
8495 }
8496 self.write(")");
8497 }
8498 }
8499 }
8500 ColumnConstraint::Collate(collation) => {
8501 self.write_space();
8502 self.write_keyword("COLLATE");
8503 self.write_space();
8504 self.generate_identifier(collation)?;
8505 }
8506 ColumnConstraint::Comment(comment) => {
8507 self.write_space();
8508 self.write_keyword("COMMENT");
8509 self.write_space();
8510 self.generate_string_literal(comment)?;
8511 }
8512 ColumnConstraint::Path(path_expr) => {
8513 self.write_space();
8514 self.write_keyword("PATH");
8515 self.write_space();
8516 self.generate_expression(path_expr)?;
8517 }
8518 _ => {} }
8520 }
8521
8522 if let Some(ref encoding) = col.encoding {
8524 self.write_space();
8525 self.write_keyword("ENCODE");
8526 self.write_space();
8527 self.write(encoding);
8528 }
8529 }
8530
8531 if let Some(ref codec) = col.codec {
8533 self.write_space();
8534 self.write_keyword("CODEC");
8535 self.write("(");
8536 self.write(codec);
8537 self.write(")");
8538 }
8539
8540 if let Some(ref ephemeral) = col.ephemeral {
8542 self.write_space();
8543 self.write_keyword("EPHEMERAL");
8544 if let Some(ref expr) = ephemeral {
8545 self.write_space();
8546 self.generate_expression(expr)?;
8547 }
8548 }
8549
8550 if let Some(ref mat_expr) = col.materialized_expr {
8552 self.write_space();
8553 self.write_keyword("MATERIALIZED");
8554 self.write_space();
8555 self.generate_expression(mat_expr)?;
8556 }
8557
8558 if let Some(ref alias_expr) = col.alias_expr {
8560 self.write_space();
8561 self.write_keyword("ALIAS");
8562 self.write_space();
8563 self.generate_expression(alias_expr)?;
8564 }
8565
8566 if let Some(ref ttl_expr) = col.ttl_expr {
8568 self.write_space();
8569 self.write_keyword("TTL");
8570 self.write_space();
8571 self.generate_expression(ttl_expr)?;
8572 }
8573
8574 if col.not_for_replication
8576 && matches!(
8577 self.config.dialect,
8578 Some(crate::dialects::DialectType::TSQL)
8579 | Some(crate::dialects::DialectType::Fabric)
8580 )
8581 {
8582 self.write_space();
8583 self.write_keyword("NOT FOR REPLICATION");
8584 }
8585
8586 if !col.options.is_empty() {
8588 self.write_space();
8589 self.generate_options_clause(&col.options)?;
8590 }
8591
8592 if !col.primary_key
8595 && self
8596 .sqlite_inline_pk_columns
8597 .contains(&col.name.name.to_lowercase())
8598 {
8599 self.write_space();
8600 self.write_keyword("PRIMARY KEY");
8601 }
8602
8603 if serial_expansion.is_some() {
8606 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
8607 self.write_space();
8608 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
8609 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
8610 self.write_space();
8611 self.write_keyword("NOT NULL");
8612 }
8613 }
8614
8615 Ok(())
8616 }
8617
8618 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
8619 match constraint {
8620 TableConstraint::PrimaryKey {
8621 name,
8622 columns,
8623 include_columns,
8624 modifiers,
8625 has_constraint_keyword,
8626 } => {
8627 if let Some(ref n) = name {
8628 if *has_constraint_keyword {
8629 self.write_keyword("CONSTRAINT");
8630 self.write_space();
8631 self.generate_identifier(n)?;
8632 self.write_space();
8633 }
8634 }
8635 self.write_keyword("PRIMARY KEY");
8636 if let Some(ref clustered) = modifiers.clustered {
8638 self.write_space();
8639 self.write_keyword(clustered);
8640 }
8641 if let Some(ref n) = name {
8643 if !*has_constraint_keyword {
8644 self.write_space();
8645 self.generate_identifier(n)?;
8646 }
8647 }
8648 self.write(" (");
8649 for (i, col) in columns.iter().enumerate() {
8650 if i > 0 {
8651 self.write(", ");
8652 }
8653 self.generate_identifier(col)?;
8654 }
8655 self.write(")");
8656 if !include_columns.is_empty() {
8657 self.write_space();
8658 self.write_keyword("INCLUDE");
8659 self.write(" (");
8660 for (i, col) in include_columns.iter().enumerate() {
8661 if i > 0 {
8662 self.write(", ");
8663 }
8664 self.generate_identifier(col)?;
8665 }
8666 self.write(")");
8667 }
8668 self.generate_constraint_modifiers(modifiers);
8669 }
8670 TableConstraint::Unique {
8671 name,
8672 columns,
8673 columns_parenthesized,
8674 modifiers,
8675 has_constraint_keyword,
8676 nulls_not_distinct,
8677 } => {
8678 if let Some(ref n) = name {
8679 if *has_constraint_keyword {
8680 self.write_keyword("CONSTRAINT");
8681 self.write_space();
8682 self.generate_identifier(n)?;
8683 self.write_space();
8684 }
8685 }
8686 self.write_keyword("UNIQUE");
8687 if let Some(ref clustered) = modifiers.clustered {
8689 self.write_space();
8690 self.write_keyword(clustered);
8691 }
8692 if *nulls_not_distinct {
8694 self.write(" NULLS NOT DISTINCT");
8695 }
8696 if let Some(ref n) = name {
8698 if !*has_constraint_keyword {
8699 self.write_space();
8700 self.generate_identifier(n)?;
8701 }
8702 }
8703 if *columns_parenthesized {
8704 self.write(" (");
8705 for (i, col) in columns.iter().enumerate() {
8706 if i > 0 {
8707 self.write(", ");
8708 }
8709 self.generate_identifier(col)?;
8710 }
8711 self.write(")");
8712 } else {
8713 for col in columns.iter() {
8715 self.write_space();
8716 self.generate_identifier(col)?;
8717 }
8718 }
8719 self.generate_constraint_modifiers(modifiers);
8720 }
8721 TableConstraint::ForeignKey {
8722 name,
8723 columns,
8724 references,
8725 on_delete,
8726 on_update,
8727 modifiers,
8728 } => {
8729 if let Some(ref n) = name {
8730 self.write_keyword("CONSTRAINT");
8731 self.write_space();
8732 self.generate_identifier(n)?;
8733 self.write_space();
8734 }
8735 self.write_keyword("FOREIGN KEY");
8736 self.write(" (");
8737 for (i, col) in columns.iter().enumerate() {
8738 if i > 0 {
8739 self.write(", ");
8740 }
8741 self.generate_identifier(col)?;
8742 }
8743 self.write(")");
8744 if let Some(ref refs) = references {
8745 self.write(" ");
8746 self.write_keyword("REFERENCES");
8747 self.write_space();
8748 self.generate_table(&refs.table)?;
8749 if !refs.columns.is_empty() {
8750 if self.config.pretty {
8751 self.write(" (");
8752 self.write_newline();
8753 self.indent_level += 1;
8754 for (i, col) in refs.columns.iter().enumerate() {
8755 if i > 0 {
8756 self.write(",");
8757 self.write_newline();
8758 }
8759 self.write_indent();
8760 self.generate_identifier(col)?;
8761 }
8762 self.indent_level -= 1;
8763 self.write_newline();
8764 self.write_indent();
8765 self.write(")");
8766 } else {
8767 self.write(" (");
8768 for (i, col) in refs.columns.iter().enumerate() {
8769 if i > 0 {
8770 self.write(", ");
8771 }
8772 self.generate_identifier(col)?;
8773 }
8774 self.write(")");
8775 }
8776 }
8777 self.generate_referential_actions(refs)?;
8778 } else {
8779 if let Some(ref action) = on_delete {
8781 self.write_space();
8782 self.write_keyword("ON DELETE");
8783 self.write_space();
8784 self.generate_referential_action(action);
8785 }
8786 if let Some(ref action) = on_update {
8787 self.write_space();
8788 self.write_keyword("ON UPDATE");
8789 self.write_space();
8790 self.generate_referential_action(action);
8791 }
8792 }
8793 self.generate_constraint_modifiers(modifiers);
8794 }
8795 TableConstraint::Check {
8796 name,
8797 expression,
8798 modifiers,
8799 } => {
8800 if let Some(ref n) = name {
8801 self.write_keyword("CONSTRAINT");
8802 self.write_space();
8803 self.generate_identifier(n)?;
8804 self.write_space();
8805 }
8806 self.write_keyword("CHECK");
8807 self.write(" (");
8808 self.generate_expression(expression)?;
8809 self.write(")");
8810 self.generate_constraint_modifiers(modifiers);
8811 }
8812 TableConstraint::Index {
8813 name,
8814 columns,
8815 kind,
8816 modifiers,
8817 use_key_keyword,
8818 expression,
8819 index_type,
8820 granularity,
8821 } => {
8822 if expression.is_some() {
8824 self.write_keyword("INDEX");
8825 if let Some(ref n) = name {
8826 self.write_space();
8827 self.generate_identifier(n)?;
8828 }
8829 if let Some(ref expr) = expression {
8830 self.write_space();
8831 self.generate_expression(expr)?;
8832 }
8833 if let Some(ref idx_type) = index_type {
8834 self.write_space();
8835 self.write_keyword("TYPE");
8836 self.write_space();
8837 self.generate_expression(idx_type)?;
8838 }
8839 if let Some(ref gran) = granularity {
8840 self.write_space();
8841 self.write_keyword("GRANULARITY");
8842 self.write_space();
8843 self.generate_expression(gran)?;
8844 }
8845 } else {
8846 use crate::dialects::DialectType;
8850 let index_keyword = if *use_key_keyword
8851 && !matches!(self.config.dialect, Some(DialectType::MySQL))
8852 {
8853 "KEY"
8854 } else {
8855 "INDEX"
8856 };
8857
8858 if let Some(ref k) = kind {
8860 self.write_keyword(k);
8861 if k != "UNIQUE" {
8863 self.write_space();
8864 self.write_keyword(index_keyword);
8865 }
8866 } else {
8867 self.write_keyword(index_keyword);
8868 }
8869
8870 if modifiers.using_before_columns && name.is_none() {
8872 if let Some(ref using) = modifiers.using {
8873 self.write_space();
8874 self.write_keyword("USING");
8875 self.write_space();
8876 self.write_keyword(using);
8877 }
8878 }
8879
8880 if let Some(ref n) = name {
8882 self.write_space();
8883 self.generate_identifier(n)?;
8884 }
8885
8886 if modifiers.using_before_columns && name.is_some() {
8888 if let Some(ref using) = modifiers.using {
8889 self.write_space();
8890 self.write_keyword("USING");
8891 self.write_space();
8892 self.write_keyword(using);
8893 }
8894 }
8895
8896 self.write(" (");
8898 for (i, col) in columns.iter().enumerate() {
8899 if i > 0 {
8900 self.write(", ");
8901 }
8902 self.generate_identifier(col)?;
8903 }
8904 self.write(")");
8905
8906 if !modifiers.using_before_columns {
8908 if let Some(ref using) = modifiers.using {
8909 self.write_space();
8910 self.write_keyword("USING");
8911 self.write_space();
8912 self.write_keyword(using);
8913 }
8914 }
8915
8916 self.generate_constraint_modifiers_without_using(modifiers);
8918 }
8919 }
8920 TableConstraint::Projection { name, expression } => {
8921 self.write_keyword("PROJECTION");
8923 self.write_space();
8924 self.generate_identifier(name)?;
8925 self.write(" (");
8926 self.generate_expression(expression)?;
8927 self.write(")");
8928 }
8929 TableConstraint::Like { source, options } => {
8930 self.write_keyword("LIKE");
8931 self.write_space();
8932 self.generate_table(source)?;
8933 for (action, prop) in options {
8934 self.write_space();
8935 match action {
8936 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
8937 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
8938 }
8939 self.write_space();
8940 self.write_keyword(prop);
8941 }
8942 }
8943 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
8944 self.write_keyword("PERIOD FOR SYSTEM_TIME");
8945 self.write(" (");
8946 self.generate_identifier(start_col)?;
8947 self.write(", ");
8948 self.generate_identifier(end_col)?;
8949 self.write(")");
8950 }
8951 TableConstraint::Exclude {
8952 name,
8953 using,
8954 elements,
8955 include_columns,
8956 where_clause,
8957 with_params,
8958 using_index_tablespace,
8959 modifiers: _,
8960 } => {
8961 if let Some(ref n) = name {
8962 self.write_keyword("CONSTRAINT");
8963 self.write_space();
8964 self.generate_identifier(n)?;
8965 self.write_space();
8966 }
8967 self.write_keyword("EXCLUDE");
8968 if let Some(ref method) = using {
8969 self.write_space();
8970 self.write_keyword("USING");
8971 self.write_space();
8972 self.write(method);
8973 self.write("(");
8974 } else {
8975 self.write(" (");
8976 }
8977 for (i, elem) in elements.iter().enumerate() {
8978 if i > 0 {
8979 self.write(", ");
8980 }
8981 self.write(&elem.expression);
8982 self.write_space();
8983 self.write_keyword("WITH");
8984 self.write_space();
8985 self.write(&elem.operator);
8986 }
8987 self.write(")");
8988 if !include_columns.is_empty() {
8989 self.write_space();
8990 self.write_keyword("INCLUDE");
8991 self.write(" (");
8992 for (i, col) in include_columns.iter().enumerate() {
8993 if i > 0 {
8994 self.write(", ");
8995 }
8996 self.generate_identifier(col)?;
8997 }
8998 self.write(")");
8999 }
9000 if !with_params.is_empty() {
9001 self.write_space();
9002 self.write_keyword("WITH");
9003 self.write(" (");
9004 for (i, (key, val)) in with_params.iter().enumerate() {
9005 if i > 0 {
9006 self.write(", ");
9007 }
9008 self.write(key);
9009 self.write("=");
9010 self.write(val);
9011 }
9012 self.write(")");
9013 }
9014 if let Some(ref tablespace) = using_index_tablespace {
9015 self.write_space();
9016 self.write_keyword("USING INDEX TABLESPACE");
9017 self.write_space();
9018 self.write(tablespace);
9019 }
9020 if let Some(ref where_expr) = where_clause {
9021 self.write_space();
9022 self.write_keyword("WHERE");
9023 self.write(" (");
9024 self.generate_expression(where_expr)?;
9025 self.write(")");
9026 }
9027 }
9028 TableConstraint::Tags(tags) => {
9029 self.write_keyword("TAG");
9030 self.write(" (");
9031 for (i, expr) in tags.expressions.iter().enumerate() {
9032 if i > 0 {
9033 self.write(", ");
9034 }
9035 self.generate_expression(expr)?;
9036 }
9037 self.write(")");
9038 }
9039 TableConstraint::InitiallyDeferred { deferred } => {
9040 self.write_keyword("INITIALLY");
9041 self.write_space();
9042 if *deferred {
9043 self.write_keyword("DEFERRED");
9044 } else {
9045 self.write_keyword("IMMEDIATE");
9046 }
9047 }
9048 }
9049 Ok(())
9050 }
9051
9052 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9053 if let Some(using) = &modifiers.using {
9055 self.write_space();
9056 self.write_keyword("USING");
9057 self.write_space();
9058 self.write_keyword(using);
9059 }
9060 if let Some(enforced) = modifiers.enforced {
9062 self.write_space();
9063 if enforced {
9064 self.write_keyword("ENFORCED");
9065 } else {
9066 self.write_keyword("NOT ENFORCED");
9067 }
9068 }
9069 if let Some(deferrable) = modifiers.deferrable {
9071 self.write_space();
9072 if deferrable {
9073 self.write_keyword("DEFERRABLE");
9074 } else {
9075 self.write_keyword("NOT DEFERRABLE");
9076 }
9077 }
9078 if let Some(initially_deferred) = modifiers.initially_deferred {
9080 self.write_space();
9081 if initially_deferred {
9082 self.write_keyword("INITIALLY DEFERRED");
9083 } else {
9084 self.write_keyword("INITIALLY IMMEDIATE");
9085 }
9086 }
9087 if modifiers.norely {
9089 self.write_space();
9090 self.write_keyword("NORELY");
9091 }
9092 if modifiers.rely {
9094 self.write_space();
9095 self.write_keyword("RELY");
9096 }
9097 if modifiers.not_valid {
9099 self.write_space();
9100 self.write_keyword("NOT VALID");
9101 }
9102 if let Some(on_conflict) = &modifiers.on_conflict {
9104 self.write_space();
9105 self.write_keyword("ON CONFLICT");
9106 self.write_space();
9107 self.write_keyword(on_conflict);
9108 }
9109 if !modifiers.with_options.is_empty() {
9111 self.write_space();
9112 self.write_keyword("WITH");
9113 self.write(" (");
9114 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
9115 if i > 0 {
9116 self.write(", ");
9117 }
9118 self.write(key);
9119 self.write("=");
9120 self.write(value);
9121 }
9122 self.write(")");
9123 }
9124 if let Some(ref fg) = modifiers.on_filegroup {
9126 self.write_space();
9127 self.write_keyword("ON");
9128 self.write_space();
9129 let _ = self.generate_identifier(fg);
9130 }
9131 }
9132
9133 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
9135 if let Some(enforced) = modifiers.enforced {
9137 self.write_space();
9138 if enforced {
9139 self.write_keyword("ENFORCED");
9140 } else {
9141 self.write_keyword("NOT ENFORCED");
9142 }
9143 }
9144 if let Some(deferrable) = modifiers.deferrable {
9146 self.write_space();
9147 if deferrable {
9148 self.write_keyword("DEFERRABLE");
9149 } else {
9150 self.write_keyword("NOT DEFERRABLE");
9151 }
9152 }
9153 if let Some(initially_deferred) = modifiers.initially_deferred {
9155 self.write_space();
9156 if initially_deferred {
9157 self.write_keyword("INITIALLY DEFERRED");
9158 } else {
9159 self.write_keyword("INITIALLY IMMEDIATE");
9160 }
9161 }
9162 if modifiers.norely {
9164 self.write_space();
9165 self.write_keyword("NORELY");
9166 }
9167 if modifiers.rely {
9169 self.write_space();
9170 self.write_keyword("RELY");
9171 }
9172 if modifiers.not_valid {
9174 self.write_space();
9175 self.write_keyword("NOT VALID");
9176 }
9177 if let Some(on_conflict) = &modifiers.on_conflict {
9179 self.write_space();
9180 self.write_keyword("ON CONFLICT");
9181 self.write_space();
9182 self.write_keyword(on_conflict);
9183 }
9184 self.generate_index_specific_modifiers(modifiers);
9186 }
9187
9188 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9190 if let Some(ref comment) = modifiers.comment {
9191 self.write_space();
9192 self.write_keyword("COMMENT");
9193 self.write(" '");
9194 self.write(comment);
9195 self.write("'");
9196 }
9197 if let Some(visible) = modifiers.visible {
9198 self.write_space();
9199 if visible {
9200 self.write_keyword("VISIBLE");
9201 } else {
9202 self.write_keyword("INVISIBLE");
9203 }
9204 }
9205 if let Some(ref attr) = modifiers.engine_attribute {
9206 self.write_space();
9207 self.write_keyword("ENGINE_ATTRIBUTE");
9208 self.write(" = '");
9209 self.write(attr);
9210 self.write("'");
9211 }
9212 if let Some(ref parser) = modifiers.with_parser {
9213 self.write_space();
9214 self.write_keyword("WITH PARSER");
9215 self.write_space();
9216 self.write(parser);
9217 }
9218 }
9219
9220 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
9221 if !fk_ref.match_after_actions {
9223 if let Some(ref match_type) = fk_ref.match_type {
9224 self.write_space();
9225 self.write_keyword("MATCH");
9226 self.write_space();
9227 match match_type {
9228 MatchType::Full => self.write_keyword("FULL"),
9229 MatchType::Partial => self.write_keyword("PARTIAL"),
9230 MatchType::Simple => self.write_keyword("SIMPLE"),
9231 }
9232 }
9233 }
9234
9235 if fk_ref.on_update_first {
9237 if let Some(ref action) = fk_ref.on_update {
9238 self.write_space();
9239 self.write_keyword("ON UPDATE");
9240 self.write_space();
9241 self.generate_referential_action(action);
9242 }
9243 if let Some(ref action) = fk_ref.on_delete {
9244 self.write_space();
9245 self.write_keyword("ON DELETE");
9246 self.write_space();
9247 self.generate_referential_action(action);
9248 }
9249 } else {
9250 if let Some(ref action) = fk_ref.on_delete {
9251 self.write_space();
9252 self.write_keyword("ON DELETE");
9253 self.write_space();
9254 self.generate_referential_action(action);
9255 }
9256 if let Some(ref action) = fk_ref.on_update {
9257 self.write_space();
9258 self.write_keyword("ON UPDATE");
9259 self.write_space();
9260 self.generate_referential_action(action);
9261 }
9262 }
9263
9264 if fk_ref.match_after_actions {
9266 if let Some(ref match_type) = fk_ref.match_type {
9267 self.write_space();
9268 self.write_keyword("MATCH");
9269 self.write_space();
9270 match match_type {
9271 MatchType::Full => self.write_keyword("FULL"),
9272 MatchType::Partial => self.write_keyword("PARTIAL"),
9273 MatchType::Simple => self.write_keyword("SIMPLE"),
9274 }
9275 }
9276 }
9277
9278 if let Some(deferrable) = fk_ref.deferrable {
9280 self.write_space();
9281 if deferrable {
9282 self.write_keyword("DEFERRABLE");
9283 } else {
9284 self.write_keyword("NOT DEFERRABLE");
9285 }
9286 }
9287
9288 Ok(())
9289 }
9290
9291 fn generate_referential_action(&mut self, action: &ReferentialAction) {
9292 match action {
9293 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
9294 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
9295 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
9296 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
9297 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
9298 }
9299 }
9300
9301 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
9302 let saved_athena_hive_context = self.athena_hive_context;
9304 if matches!(
9305 self.config.dialect,
9306 Some(crate::dialects::DialectType::Athena)
9307 ) {
9308 self.athena_hive_context = true;
9309 }
9310
9311 for comment in &dt.leading_comments {
9313 self.write_formatted_comment(comment);
9314 self.write_space();
9315 }
9316 self.write_keyword("DROP TABLE");
9317
9318 if dt.if_exists {
9319 self.write_space();
9320 self.write_keyword("IF EXISTS");
9321 }
9322
9323 self.write_space();
9324 for (i, table) in dt.names.iter().enumerate() {
9325 if i > 0 {
9326 self.write(", ");
9327 }
9328 self.generate_table(table)?;
9329 }
9330
9331 if dt.cascade_constraints {
9332 self.write_space();
9333 self.write_keyword("CASCADE CONSTRAINTS");
9334 } else if dt.cascade {
9335 self.write_space();
9336 self.write_keyword("CASCADE");
9337 }
9338
9339 if dt.purge {
9340 self.write_space();
9341 self.write_keyword("PURGE");
9342 }
9343
9344 self.athena_hive_context = saved_athena_hive_context;
9346
9347 Ok(())
9348 }
9349
9350 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
9351 let saved_athena_hive_context = self.athena_hive_context;
9353 if matches!(
9354 self.config.dialect,
9355 Some(crate::dialects::DialectType::Athena)
9356 ) {
9357 self.athena_hive_context = true;
9358 }
9359
9360 self.write_keyword("ALTER TABLE");
9361 if at.if_exists {
9362 self.write_space();
9363 self.write_keyword("IF EXISTS");
9364 }
9365 self.write_space();
9366 self.generate_table(&at.name)?;
9367
9368 if let Some(ref on_cluster) = at.on_cluster {
9370 self.write_space();
9371 self.generate_on_cluster(on_cluster)?;
9372 }
9373
9374 if let Some(ref partition) = at.partition {
9376 self.write_space();
9377 self.write_keyword("PARTITION");
9378 self.write("(");
9379 for (i, (key, value)) in partition.iter().enumerate() {
9380 if i > 0 {
9381 self.write(", ");
9382 }
9383 self.generate_identifier(key)?;
9384 self.write(" = ");
9385 self.generate_expression(value)?;
9386 }
9387 self.write(")");
9388 }
9389
9390 if let Some(ref with_check) = at.with_check {
9392 self.write_space();
9393 self.write_keyword(with_check);
9394 }
9395
9396 if self.config.pretty {
9397 self.write_newline();
9399 self.indent_level += 1;
9400 for (i, action) in at.actions.iter().enumerate() {
9401 let is_continuation = i > 0
9403 && matches!(
9404 (&at.actions[i - 1], action),
9405 (
9406 AlterTableAction::AddColumn { .. },
9407 AlterTableAction::AddColumn { .. }
9408 ) | (
9409 AlterTableAction::AddConstraint(_),
9410 AlterTableAction::AddConstraint(_)
9411 )
9412 );
9413 if i > 0 {
9414 self.write(",");
9415 self.write_newline();
9416 }
9417 self.write_indent();
9418 self.generate_alter_action_with_continuation(action, is_continuation)?;
9419 }
9420 self.indent_level -= 1;
9421 } else {
9422 for (i, action) in at.actions.iter().enumerate() {
9423 let is_continuation = i > 0
9425 && matches!(
9426 (&at.actions[i - 1], action),
9427 (
9428 AlterTableAction::AddColumn { .. },
9429 AlterTableAction::AddColumn { .. }
9430 ) | (
9431 AlterTableAction::AddConstraint(_),
9432 AlterTableAction::AddConstraint(_)
9433 )
9434 );
9435 if i > 0 {
9436 self.write(",");
9437 }
9438 self.write_space();
9439 self.generate_alter_action_with_continuation(action, is_continuation)?;
9440 }
9441 }
9442
9443 if let Some(ref algorithm) = at.algorithm {
9445 self.write(", ");
9446 self.write_keyword("ALGORITHM");
9447 self.write("=");
9448 self.write_keyword(algorithm);
9449 }
9450 if let Some(ref lock) = at.lock {
9451 self.write(", ");
9452 self.write_keyword("LOCK");
9453 self.write("=");
9454 self.write_keyword(lock);
9455 }
9456
9457 self.athena_hive_context = saved_athena_hive_context;
9459
9460 Ok(())
9461 }
9462
9463 fn generate_alter_action_with_continuation(
9464 &mut self,
9465 action: &AlterTableAction,
9466 is_continuation: bool,
9467 ) -> Result<()> {
9468 match action {
9469 AlterTableAction::AddColumn {
9470 column,
9471 if_not_exists,
9472 position,
9473 } => {
9474 use crate::dialects::DialectType;
9475 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
9479 let is_tsql_like = matches!(
9480 self.config.dialect,
9481 Some(DialectType::TSQL) | Some(DialectType::Fabric)
9482 );
9483 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
9485
9486 if is_continuation && (is_snowflake || is_tsql_like) {
9487 } else if is_snowflake {
9489 self.write_keyword("ADD");
9490 self.write_space();
9491 } else if is_athena {
9492 self.write_keyword("ADD COLUMNS");
9494 self.write(" (");
9495 } else if self.config.alter_table_include_column_keyword {
9496 self.write_keyword("ADD COLUMN");
9497 self.write_space();
9498 } else {
9499 self.write_keyword("ADD");
9501 self.write_space();
9502 }
9503
9504 if *if_not_exists {
9505 self.write_keyword("IF NOT EXISTS");
9506 self.write_space();
9507 }
9508 self.generate_column_def(column)?;
9509
9510 if is_athena {
9512 self.write(")");
9513 }
9514
9515 if let Some(pos) = position {
9517 self.write_space();
9518 match pos {
9519 ColumnPosition::First => self.write_keyword("FIRST"),
9520 ColumnPosition::After(col_name) => {
9521 self.write_keyword("AFTER");
9522 self.write_space();
9523 self.generate_identifier(col_name)?;
9524 }
9525 }
9526 }
9527 }
9528 AlterTableAction::DropColumn {
9529 name,
9530 if_exists,
9531 cascade,
9532 } => {
9533 self.write_keyword("DROP COLUMN");
9534 if *if_exists {
9535 self.write_space();
9536 self.write_keyword("IF EXISTS");
9537 }
9538 self.write_space();
9539 self.generate_identifier(name)?;
9540 if *cascade {
9541 self.write_space();
9542 self.write_keyword("CASCADE");
9543 }
9544 }
9545 AlterTableAction::DropColumns { names } => {
9546 self.write_keyword("DROP COLUMNS");
9547 self.write(" (");
9548 for (i, name) in names.iter().enumerate() {
9549 if i > 0 {
9550 self.write(", ");
9551 }
9552 self.generate_identifier(name)?;
9553 }
9554 self.write(")");
9555 }
9556 AlterTableAction::RenameColumn {
9557 old_name,
9558 new_name,
9559 if_exists,
9560 } => {
9561 self.write_keyword("RENAME COLUMN");
9562 if *if_exists {
9563 self.write_space();
9564 self.write_keyword("IF EXISTS");
9565 }
9566 self.write_space();
9567 self.generate_identifier(old_name)?;
9568 self.write_space();
9569 self.write_keyword("TO");
9570 self.write_space();
9571 self.generate_identifier(new_name)?;
9572 }
9573 AlterTableAction::AlterColumn {
9574 name,
9575 action,
9576 use_modify_keyword,
9577 } => {
9578 use crate::dialects::DialectType;
9579 let use_modify = *use_modify_keyword
9582 || (matches!(self.config.dialect, Some(DialectType::MySQL))
9583 && matches!(action, AlterColumnAction::SetDataType { .. }));
9584 if use_modify {
9585 self.write_keyword("MODIFY COLUMN");
9586 self.write_space();
9587 self.generate_identifier(name)?;
9588 if let AlterColumnAction::SetDataType {
9590 data_type,
9591 using: _,
9592 collate,
9593 } = action
9594 {
9595 self.write_space();
9596 self.generate_data_type(data_type)?;
9597 if let Some(collate_name) = collate {
9599 self.write_space();
9600 self.write_keyword("COLLATE");
9601 self.write_space();
9602 self.write(&format!("'{}'", collate_name));
9604 }
9605 } else {
9606 self.write_space();
9607 self.generate_alter_column_action(action)?;
9608 }
9609 } else if matches!(self.config.dialect, Some(DialectType::Hive))
9610 && matches!(action, AlterColumnAction::SetDataType { .. })
9611 {
9612 self.write_keyword("CHANGE COLUMN");
9614 self.write_space();
9615 self.generate_identifier(name)?;
9616 self.write_space();
9617 self.generate_identifier(name)?;
9618 if let AlterColumnAction::SetDataType { data_type, .. } = action {
9619 self.write_space();
9620 self.generate_data_type(data_type)?;
9621 }
9622 } else {
9623 self.write_keyword("ALTER COLUMN");
9624 self.write_space();
9625 self.generate_identifier(name)?;
9626 self.write_space();
9627 self.generate_alter_column_action(action)?;
9628 }
9629 }
9630 AlterTableAction::RenameTable(new_name) => {
9631 let mysql_like = matches!(
9633 self.config.dialect,
9634 Some(DialectType::MySQL)
9635 | Some(DialectType::Doris)
9636 | Some(DialectType::StarRocks)
9637 | Some(DialectType::SingleStore)
9638 );
9639 if mysql_like {
9640 self.write_keyword("RENAME");
9641 } else {
9642 self.write_keyword("RENAME TO");
9643 }
9644 self.write_space();
9645 let rename_table_with_db = !matches!(
9647 self.config.dialect,
9648 Some(DialectType::Doris)
9649 | Some(DialectType::DuckDB)
9650 | Some(DialectType::BigQuery)
9651 | Some(DialectType::PostgreSQL)
9652 );
9653 if !rename_table_with_db {
9654 let mut stripped = new_name.clone();
9655 stripped.schema = None;
9656 stripped.catalog = None;
9657 self.generate_table(&stripped)?;
9658 } else {
9659 self.generate_table(new_name)?;
9660 }
9661 }
9662 AlterTableAction::AddConstraint(constraint) => {
9663 if !is_continuation {
9666 self.write_keyword("ADD");
9667 self.write_space();
9668 }
9669 self.generate_table_constraint(constraint)?;
9670 }
9671 AlterTableAction::DropConstraint { name, if_exists } => {
9672 self.write_keyword("DROP CONSTRAINT");
9673 if *if_exists {
9674 self.write_space();
9675 self.write_keyword("IF EXISTS");
9676 }
9677 self.write_space();
9678 self.generate_identifier(name)?;
9679 }
9680 AlterTableAction::DropForeignKey { name } => {
9681 self.write_keyword("DROP FOREIGN KEY");
9682 self.write_space();
9683 self.generate_identifier(name)?;
9684 }
9685 AlterTableAction::DropPartition {
9686 partitions,
9687 if_exists,
9688 } => {
9689 self.write_keyword("DROP");
9690 if *if_exists {
9691 self.write_space();
9692 self.write_keyword("IF EXISTS");
9693 }
9694 for (i, partition) in partitions.iter().enumerate() {
9695 if i > 0 {
9696 self.write(",");
9697 }
9698 self.write_space();
9699 self.write_keyword("PARTITION");
9700 if partition.len() == 1 && partition[0].0.name == "__expr__" {
9702 self.write_space();
9704 self.generate_expression(&partition[0].1)?;
9705 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
9706 self.write_space();
9708 self.write_keyword("ALL");
9709 } else if partition.len() == 1 && partition[0].0.name == "ID" {
9710 self.write_space();
9712 self.write_keyword("ID");
9713 self.write_space();
9714 self.generate_expression(&partition[0].1)?;
9715 } else {
9716 self.write("(");
9718 for (j, (key, value)) in partition.iter().enumerate() {
9719 if j > 0 {
9720 self.write(", ");
9721 }
9722 self.generate_identifier(key)?;
9723 self.write(" = ");
9724 self.generate_expression(value)?;
9725 }
9726 self.write(")");
9727 }
9728 }
9729 }
9730 AlterTableAction::Delete { where_clause } => {
9731 self.write_keyword("DELETE");
9732 self.write_space();
9733 self.write_keyword("WHERE");
9734 self.write_space();
9735 self.generate_expression(where_clause)?;
9736 }
9737 AlterTableAction::SwapWith(target) => {
9738 self.write_keyword("SWAP WITH");
9739 self.write_space();
9740 self.generate_table(target)?;
9741 }
9742 AlterTableAction::SetProperty { properties } => {
9743 use crate::dialects::DialectType;
9744 self.write_keyword("SET");
9745 let is_trino_presto = matches!(
9747 self.config.dialect,
9748 Some(DialectType::Trino) | Some(DialectType::Presto)
9749 );
9750 if is_trino_presto {
9751 self.write_space();
9752 self.write_keyword("PROPERTIES");
9753 }
9754 let eq = if is_trino_presto { " = " } else { "=" };
9755 for (i, (key, value)) in properties.iter().enumerate() {
9756 if i > 0 {
9757 self.write(",");
9758 }
9759 self.write_space();
9760 if key.contains(' ') {
9762 self.generate_string_literal(key)?;
9763 } else {
9764 self.write(key);
9765 }
9766 self.write(eq);
9767 self.generate_expression(value)?;
9768 }
9769 }
9770 AlterTableAction::UnsetProperty { properties } => {
9771 self.write_keyword("UNSET");
9772 for (i, name) in properties.iter().enumerate() {
9773 if i > 0 {
9774 self.write(",");
9775 }
9776 self.write_space();
9777 self.write(name);
9778 }
9779 }
9780 AlterTableAction::ClusterBy { expressions } => {
9781 self.write_keyword("CLUSTER BY");
9782 self.write(" (");
9783 for (i, expr) in expressions.iter().enumerate() {
9784 if i > 0 {
9785 self.write(", ");
9786 }
9787 self.generate_expression(expr)?;
9788 }
9789 self.write(")");
9790 }
9791 AlterTableAction::SetTag { expressions } => {
9792 self.write_keyword("SET TAG");
9793 for (i, (key, value)) in expressions.iter().enumerate() {
9794 if i > 0 {
9795 self.write(",");
9796 }
9797 self.write_space();
9798 self.write(key);
9799 self.write(" = ");
9800 self.generate_expression(value)?;
9801 }
9802 }
9803 AlterTableAction::UnsetTag { names } => {
9804 self.write_keyword("UNSET TAG");
9805 for (i, name) in names.iter().enumerate() {
9806 if i > 0 {
9807 self.write(",");
9808 }
9809 self.write_space();
9810 self.write(name);
9811 }
9812 }
9813 AlterTableAction::SetOptions { expressions } => {
9814 self.write_keyword("SET");
9815 self.write(" (");
9816 for (i, expr) in expressions.iter().enumerate() {
9817 if i > 0 {
9818 self.write(", ");
9819 }
9820 self.generate_expression(expr)?;
9821 }
9822 self.write(")");
9823 }
9824 AlterTableAction::AlterIndex { name, visible } => {
9825 self.write_keyword("ALTER INDEX");
9826 self.write_space();
9827 self.generate_identifier(name)?;
9828 self.write_space();
9829 if *visible {
9830 self.write_keyword("VISIBLE");
9831 } else {
9832 self.write_keyword("INVISIBLE");
9833 }
9834 }
9835 AlterTableAction::SetAttribute { attribute } => {
9836 self.write_keyword("SET");
9837 self.write_space();
9838 self.write_keyword(attribute);
9839 }
9840 AlterTableAction::SetStageFileFormat { options } => {
9841 self.write_keyword("SET");
9842 self.write_space();
9843 self.write_keyword("STAGE_FILE_FORMAT");
9844 self.write(" = (");
9845 if let Some(opts) = options {
9846 self.generate_space_separated_properties(opts)?;
9847 }
9848 self.write(")");
9849 }
9850 AlterTableAction::SetStageCopyOptions { options } => {
9851 self.write_keyword("SET");
9852 self.write_space();
9853 self.write_keyword("STAGE_COPY_OPTIONS");
9854 self.write(" = (");
9855 if let Some(opts) = options {
9856 self.generate_space_separated_properties(opts)?;
9857 }
9858 self.write(")");
9859 }
9860 AlterTableAction::AddColumns { columns, cascade } => {
9861 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
9864 if is_oracle {
9865 self.write_keyword("ADD");
9866 } else {
9867 self.write_keyword("ADD COLUMNS");
9868 }
9869 self.write(" (");
9870 for (i, col) in columns.iter().enumerate() {
9871 if i > 0 {
9872 self.write(", ");
9873 }
9874 self.generate_column_def(col)?;
9875 }
9876 self.write(")");
9877 if *cascade {
9878 self.write_space();
9879 self.write_keyword("CASCADE");
9880 }
9881 }
9882 AlterTableAction::ChangeColumn {
9883 old_name,
9884 new_name,
9885 data_type,
9886 comment,
9887 cascade,
9888 } => {
9889 use crate::dialects::DialectType;
9890 let is_spark = matches!(
9891 self.config.dialect,
9892 Some(DialectType::Spark) | Some(DialectType::Databricks)
9893 );
9894 let is_rename = old_name.name != new_name.name;
9895
9896 if is_spark {
9897 if is_rename {
9898 self.write_keyword("RENAME COLUMN");
9900 self.write_space();
9901 self.generate_identifier(old_name)?;
9902 self.write_space();
9903 self.write_keyword("TO");
9904 self.write_space();
9905 self.generate_identifier(new_name)?;
9906 } else if comment.is_some() {
9907 self.write_keyword("ALTER COLUMN");
9909 self.write_space();
9910 self.generate_identifier(old_name)?;
9911 self.write_space();
9912 self.write_keyword("COMMENT");
9913 self.write_space();
9914 self.write("'");
9915 self.write(comment.as_ref().unwrap());
9916 self.write("'");
9917 } else if data_type.is_some() {
9918 self.write_keyword("ALTER COLUMN");
9920 self.write_space();
9921 self.generate_identifier(old_name)?;
9922 self.write_space();
9923 self.write_keyword("TYPE");
9924 self.write_space();
9925 self.generate_data_type(data_type.as_ref().unwrap())?;
9926 } else {
9927 self.write_keyword("CHANGE COLUMN");
9929 self.write_space();
9930 self.generate_identifier(old_name)?;
9931 self.write_space();
9932 self.generate_identifier(new_name)?;
9933 }
9934 } else {
9935 if data_type.is_some() {
9937 self.write_keyword("CHANGE COLUMN");
9938 } else {
9939 self.write_keyword("CHANGE");
9940 }
9941 self.write_space();
9942 self.generate_identifier(old_name)?;
9943 self.write_space();
9944 self.generate_identifier(new_name)?;
9945 if let Some(ref dt) = data_type {
9946 self.write_space();
9947 self.generate_data_type(dt)?;
9948 }
9949 if let Some(ref c) = comment {
9950 self.write_space();
9951 self.write_keyword("COMMENT");
9952 self.write_space();
9953 self.write("'");
9954 self.write(c);
9955 self.write("'");
9956 }
9957 if *cascade {
9958 self.write_space();
9959 self.write_keyword("CASCADE");
9960 }
9961 }
9962 }
9963 AlterTableAction::AddPartition {
9964 partition,
9965 if_not_exists,
9966 location,
9967 } => {
9968 self.write_keyword("ADD");
9969 self.write_space();
9970 if *if_not_exists {
9971 self.write_keyword("IF NOT EXISTS");
9972 self.write_space();
9973 }
9974 self.generate_expression(partition)?;
9975 if let Some(ref loc) = location {
9976 self.write_space();
9977 self.write_keyword("LOCATION");
9978 self.write_space();
9979 self.generate_expression(loc)?;
9980 }
9981 }
9982 AlterTableAction::AlterSortKey {
9983 this,
9984 expressions,
9985 compound,
9986 } => {
9987 self.write_keyword("ALTER");
9989 if *compound {
9990 self.write_space();
9991 self.write_keyword("COMPOUND");
9992 }
9993 self.write_space();
9994 self.write_keyword("SORTKEY");
9995 self.write_space();
9996 if let Some(style) = this {
9997 self.write_keyword(style);
9998 } else if !expressions.is_empty() {
9999 self.write("(");
10000 for (i, expr) in expressions.iter().enumerate() {
10001 if i > 0 {
10002 self.write(", ");
10003 }
10004 self.generate_expression(expr)?;
10005 }
10006 self.write(")");
10007 }
10008 }
10009 AlterTableAction::AlterDistStyle { style, distkey } => {
10010 self.write_keyword("ALTER");
10012 self.write_space();
10013 self.write_keyword("DISTSTYLE");
10014 self.write_space();
10015 self.write_keyword(style);
10016 if let Some(col) = distkey {
10017 self.write_space();
10018 self.write_keyword("DISTKEY");
10019 self.write_space();
10020 self.generate_identifier(col)?;
10021 }
10022 }
10023 AlterTableAction::SetTableProperties { properties } => {
10024 self.write_keyword("SET TABLE PROPERTIES");
10026 self.write(" (");
10027 for (i, (key, value)) in properties.iter().enumerate() {
10028 if i > 0 {
10029 self.write(", ");
10030 }
10031 self.generate_expression(key)?;
10032 self.write(" = ");
10033 self.generate_expression(value)?;
10034 }
10035 self.write(")");
10036 }
10037 AlterTableAction::SetLocation { location } => {
10038 self.write_keyword("SET LOCATION");
10040 self.write_space();
10041 self.write("'");
10042 self.write(location);
10043 self.write("'");
10044 }
10045 AlterTableAction::SetFileFormat { format } => {
10046 self.write_keyword("SET FILE FORMAT");
10048 self.write_space();
10049 self.write_keyword(format);
10050 }
10051 AlterTableAction::ReplacePartition { partition, source } => {
10052 self.write_keyword("REPLACE PARTITION");
10054 self.write_space();
10055 self.generate_expression(partition)?;
10056 if let Some(src) = source {
10057 self.write_space();
10058 self.write_keyword("FROM");
10059 self.write_space();
10060 self.generate_expression(src)?;
10061 }
10062 }
10063 AlterTableAction::Raw { sql } => {
10064 self.write(sql);
10065 }
10066 }
10067 Ok(())
10068 }
10069
10070 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
10071 match action {
10072 AlterColumnAction::SetDataType {
10073 data_type,
10074 using,
10075 collate,
10076 } => {
10077 use crate::dialects::DialectType;
10078 let is_no_prefix = matches!(
10083 self.config.dialect,
10084 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
10085 );
10086 let is_type_only = matches!(
10087 self.config.dialect,
10088 Some(DialectType::Redshift)
10089 | Some(DialectType::Spark)
10090 | Some(DialectType::Databricks)
10091 );
10092 if is_type_only {
10093 self.write_keyword("TYPE");
10094 self.write_space();
10095 } else if !is_no_prefix {
10096 self.write_keyword("SET DATA TYPE");
10097 self.write_space();
10098 }
10099 self.generate_data_type(data_type)?;
10100 if let Some(ref collation) = collate {
10101 self.write_space();
10102 self.write_keyword("COLLATE");
10103 self.write_space();
10104 self.write(collation);
10105 }
10106 if let Some(ref using_expr) = using {
10107 self.write_space();
10108 self.write_keyword("USING");
10109 self.write_space();
10110 self.generate_expression(using_expr)?;
10111 }
10112 }
10113 AlterColumnAction::SetDefault(expr) => {
10114 self.write_keyword("SET DEFAULT");
10115 self.write_space();
10116 self.generate_expression(expr)?;
10117 }
10118 AlterColumnAction::DropDefault => {
10119 self.write_keyword("DROP DEFAULT");
10120 }
10121 AlterColumnAction::SetNotNull => {
10122 self.write_keyword("SET NOT NULL");
10123 }
10124 AlterColumnAction::DropNotNull => {
10125 self.write_keyword("DROP NOT NULL");
10126 }
10127 AlterColumnAction::Comment(comment) => {
10128 self.write_keyword("COMMENT");
10129 self.write_space();
10130 self.generate_string_literal(comment)?;
10131 }
10132 AlterColumnAction::SetVisible => {
10133 self.write_keyword("SET VISIBLE");
10134 }
10135 AlterColumnAction::SetInvisible => {
10136 self.write_keyword("SET INVISIBLE");
10137 }
10138 }
10139 Ok(())
10140 }
10141
10142 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
10143 self.write_keyword("CREATE");
10144
10145 if ci.unique {
10146 self.write_space();
10147 self.write_keyword("UNIQUE");
10148 }
10149
10150 if let Some(ref clustered) = ci.clustered {
10152 self.write_space();
10153 self.write_keyword(clustered);
10154 }
10155
10156 self.write_space();
10157 self.write_keyword("INDEX");
10158
10159 if ci.concurrently {
10161 self.write_space();
10162 self.write_keyword("CONCURRENTLY");
10163 }
10164
10165 if ci.if_not_exists {
10166 self.write_space();
10167 self.write_keyword("IF NOT EXISTS");
10168 }
10169
10170 if !ci.name.name.is_empty() {
10172 self.write_space();
10173 self.generate_identifier(&ci.name)?;
10174 }
10175 self.write_space();
10176 self.write_keyword("ON");
10177 if matches!(self.config.dialect, Some(DialectType::Hive)) {
10179 self.write_space();
10180 self.write_keyword("TABLE");
10181 }
10182 self.write_space();
10183 self.generate_table(&ci.table)?;
10184
10185 if !ci.columns.is_empty() || ci.using.is_some() {
10188 let space_before_paren = false;
10189
10190 if let Some(ref using) = ci.using {
10191 self.write_space();
10192 self.write_keyword("USING");
10193 self.write_space();
10194 self.write(using);
10195 if space_before_paren {
10196 self.write(" (");
10197 } else {
10198 self.write("(");
10199 }
10200 } else {
10201 if space_before_paren {
10202 self.write(" (");
10203 } else {
10204 self.write("(");
10205 }
10206 }
10207 for (i, col) in ci.columns.iter().enumerate() {
10208 if i > 0 {
10209 self.write(", ");
10210 }
10211 self.generate_identifier(&col.column)?;
10212 if let Some(ref opclass) = col.opclass {
10213 self.write_space();
10214 self.write(opclass);
10215 }
10216 if col.desc {
10217 self.write_space();
10218 self.write_keyword("DESC");
10219 } else if col.asc {
10220 self.write_space();
10221 self.write_keyword("ASC");
10222 }
10223 if let Some(nulls_first) = col.nulls_first {
10224 self.write_space();
10225 self.write_keyword("NULLS");
10226 self.write_space();
10227 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
10228 }
10229 }
10230 self.write(")");
10231 }
10232
10233 if !ci.include_columns.is_empty() {
10235 self.write_space();
10236 self.write_keyword("INCLUDE");
10237 self.write(" (");
10238 for (i, col) in ci.include_columns.iter().enumerate() {
10239 if i > 0 {
10240 self.write(", ");
10241 }
10242 self.generate_identifier(col)?;
10243 }
10244 self.write(")");
10245 }
10246
10247 if !ci.with_options.is_empty() {
10249 self.write_space();
10250 self.write_keyword("WITH");
10251 self.write(" (");
10252 for (i, (key, value)) in ci.with_options.iter().enumerate() {
10253 if i > 0 {
10254 self.write(", ");
10255 }
10256 self.write(key);
10257 self.write("=");
10258 self.write(value);
10259 }
10260 self.write(")");
10261 }
10262
10263 if let Some(ref where_clause) = ci.where_clause {
10265 self.write_space();
10266 self.write_keyword("WHERE");
10267 self.write_space();
10268 self.generate_expression(where_clause)?;
10269 }
10270
10271 if let Some(ref on_fg) = ci.on_filegroup {
10273 self.write_space();
10274 self.write_keyword("ON");
10275 self.write_space();
10276 self.write(on_fg);
10277 }
10278
10279 Ok(())
10280 }
10281
10282 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
10283 self.write_keyword("DROP INDEX");
10284
10285 if di.concurrently {
10286 self.write_space();
10287 self.write_keyword("CONCURRENTLY");
10288 }
10289
10290 if di.if_exists {
10291 self.write_space();
10292 self.write_keyword("IF EXISTS");
10293 }
10294
10295 self.write_space();
10296 self.generate_identifier(&di.name)?;
10297
10298 if let Some(ref table) = di.table {
10299 self.write_space();
10300 self.write_keyword("ON");
10301 self.write_space();
10302 self.generate_table(table)?;
10303 }
10304
10305 Ok(())
10306 }
10307
10308 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
10309 self.write_keyword("CREATE");
10310
10311 if let Some(ref algorithm) = cv.algorithm {
10313 self.write_space();
10314 self.write_keyword("ALGORITHM");
10315 self.write("=");
10316 self.write_keyword(algorithm);
10317 }
10318
10319 if let Some(ref definer) = cv.definer {
10321 self.write_space();
10322 self.write_keyword("DEFINER");
10323 self.write("=");
10324 self.write(definer);
10325 }
10326
10327 if cv.security_sql_style {
10329 if let Some(ref security) = cv.security {
10330 self.write_space();
10331 self.write_keyword("SQL SECURITY");
10332 self.write_space();
10333 match security {
10334 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10335 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10336 FunctionSecurity::None => self.write_keyword("NONE"),
10337 }
10338 }
10339 }
10340
10341 if cv.or_replace {
10342 self.write_space();
10343 self.write_keyword("OR REPLACE");
10344 }
10345
10346 if cv.temporary {
10347 self.write_space();
10348 self.write_keyword("TEMPORARY");
10349 }
10350
10351 if cv.materialized {
10352 self.write_space();
10353 self.write_keyword("MATERIALIZED");
10354 }
10355
10356 if cv.secure {
10358 self.write_space();
10359 self.write_keyword("SECURE");
10360 }
10361
10362 self.write_space();
10363 self.write_keyword("VIEW");
10364
10365 if cv.if_not_exists {
10366 self.write_space();
10367 self.write_keyword("IF NOT EXISTS");
10368 }
10369
10370 self.write_space();
10371 self.generate_table(&cv.name)?;
10372
10373 if let Some(ref on_cluster) = cv.on_cluster {
10375 self.write_space();
10376 self.generate_on_cluster(on_cluster)?;
10377 }
10378
10379 if let Some(ref to_table) = cv.to_table {
10381 self.write_space();
10382 self.write_keyword("TO");
10383 self.write_space();
10384 self.generate_table(to_table)?;
10385 }
10386
10387 if !cv.materialized {
10390 if !cv.columns.is_empty() {
10392 self.write(" (");
10393 for (i, col) in cv.columns.iter().enumerate() {
10394 if i > 0 {
10395 self.write(", ");
10396 }
10397 self.generate_identifier(&col.name)?;
10398 if !col.options.is_empty() {
10400 self.write_space();
10401 self.generate_options_clause(&col.options)?;
10402 }
10403 if let Some(ref comment) = col.comment {
10404 self.write_space();
10405 self.write_keyword("COMMENT");
10406 self.write_space();
10407 self.generate_string_literal(comment)?;
10408 }
10409 }
10410 self.write(")");
10411 }
10412
10413 if !cv.security_sql_style {
10415 if let Some(ref security) = cv.security {
10416 self.write_space();
10417 self.write_keyword("SECURITY");
10418 self.write_space();
10419 match security {
10420 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10421 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10422 FunctionSecurity::None => self.write_keyword("NONE"),
10423 }
10424 }
10425 }
10426
10427 if cv.copy_grants {
10429 self.write_space();
10430 self.write_keyword("COPY GRANTS");
10431 }
10432 } else {
10433 if cv.copy_grants {
10435 self.write_space();
10436 self.write_keyword("COPY GRANTS");
10437 }
10438
10439 if let Some(ref schema) = cv.schema {
10441 self.write(" (");
10442 for (i, expr) in schema.expressions.iter().enumerate() {
10443 if i > 0 {
10444 self.write(", ");
10445 }
10446 self.generate_expression(expr)?;
10447 }
10448 self.write(")");
10449 } else if !cv.columns.is_empty() {
10450 self.write(" (");
10452 for (i, col) in cv.columns.iter().enumerate() {
10453 if i > 0 {
10454 self.write(", ");
10455 }
10456 self.generate_identifier(&col.name)?;
10457 if !col.options.is_empty() {
10459 self.write_space();
10460 self.generate_options_clause(&col.options)?;
10461 }
10462 if let Some(ref comment) = col.comment {
10463 self.write_space();
10464 self.write_keyword("COMMENT");
10465 self.write_space();
10466 self.generate_string_literal(comment)?;
10467 }
10468 }
10469 self.write(")");
10470 }
10471
10472 if let Some(ref unique_key) = cv.unique_key {
10474 self.write_space();
10475 self.write_keyword("KEY");
10476 self.write(" (");
10477 for (i, expr) in unique_key.expressions.iter().enumerate() {
10478 if i > 0 {
10479 self.write(", ");
10480 }
10481 self.generate_expression(expr)?;
10482 }
10483 self.write(")");
10484 }
10485 }
10486
10487 if let Some(ref comment) = cv.comment {
10489 self.write_space();
10490 self.write_keyword("COMMENT");
10491 self.write("=");
10492 self.generate_string_literal(comment)?;
10493 }
10494
10495 if !cv.tags.is_empty() {
10497 self.write_space();
10498 self.write_keyword("TAG");
10499 self.write(" (");
10500 for (i, (name, value)) in cv.tags.iter().enumerate() {
10501 if i > 0 {
10502 self.write(", ");
10503 }
10504 self.write(name);
10505 self.write("='");
10506 self.write(value);
10507 self.write("'");
10508 }
10509 self.write(")");
10510 }
10511
10512 if !cv.options.is_empty() {
10514 self.write_space();
10515 self.generate_options_clause(&cv.options)?;
10516 }
10517
10518 if let Some(ref build) = cv.build {
10520 self.write_space();
10521 self.write_keyword("BUILD");
10522 self.write_space();
10523 self.write_keyword(build);
10524 }
10525
10526 if let Some(ref refresh) = cv.refresh {
10528 self.write_space();
10529 self.generate_refresh_trigger_property(refresh)?;
10530 }
10531
10532 if let Some(auto_refresh) = cv.auto_refresh {
10534 self.write_space();
10535 self.write_keyword("AUTO REFRESH");
10536 self.write_space();
10537 if auto_refresh {
10538 self.write_keyword("YES");
10539 } else {
10540 self.write_keyword("NO");
10541 }
10542 }
10543
10544 for prop in &cv.table_properties {
10546 self.write_space();
10547 self.generate_expression(prop)?;
10548 }
10549
10550 if !matches!(&cv.query, Expression::Null(_)) {
10552 self.write_space();
10553 self.write_keyword("AS");
10554 self.write_space();
10555
10556 if let Some(ref mode) = cv.locking_mode {
10558 self.write_keyword("LOCKING");
10559 self.write_space();
10560 self.write_keyword(mode);
10561 if let Some(ref access) = cv.locking_access {
10562 self.write_space();
10563 self.write_keyword("FOR");
10564 self.write_space();
10565 self.write_keyword(access);
10566 }
10567 self.write_space();
10568 }
10569
10570 if cv.query_parenthesized {
10571 self.write("(");
10572 }
10573 self.generate_expression(&cv.query)?;
10574 if cv.query_parenthesized {
10575 self.write(")");
10576 }
10577 }
10578
10579 if cv.no_schema_binding {
10581 self.write_space();
10582 self.write_keyword("WITH NO SCHEMA BINDING");
10583 }
10584
10585 Ok(())
10586 }
10587
10588 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
10589 self.write_keyword("DROP");
10590
10591 if dv.materialized {
10592 self.write_space();
10593 self.write_keyword("MATERIALIZED");
10594 }
10595
10596 self.write_space();
10597 self.write_keyword("VIEW");
10598
10599 if dv.if_exists {
10600 self.write_space();
10601 self.write_keyword("IF EXISTS");
10602 }
10603
10604 self.write_space();
10605 self.generate_table(&dv.name)?;
10606
10607 Ok(())
10608 }
10609
10610 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
10611 match tr.target {
10612 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
10613 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
10614 }
10615 if tr.if_exists {
10616 self.write_space();
10617 self.write_keyword("IF EXISTS");
10618 }
10619 self.write_space();
10620 self.generate_table(&tr.table)?;
10621
10622 if let Some(ref on_cluster) = tr.on_cluster {
10624 self.write_space();
10625 self.generate_on_cluster(on_cluster)?;
10626 }
10627
10628 if !tr.extra_tables.is_empty() {
10630 let skip_first = if let Some(first) = tr.extra_tables.first() {
10632 first.table.name == tr.table.name && first.star
10633 } else {
10634 false
10635 };
10636
10637 let strip_star = matches!(
10639 self.config.dialect,
10640 Some(crate::dialects::DialectType::PostgreSQL)
10641 | Some(crate::dialects::DialectType::Redshift)
10642 );
10643 if skip_first && !strip_star {
10644 self.write("*");
10645 }
10646
10647 for (i, entry) in tr.extra_tables.iter().enumerate() {
10649 if i == 0 && skip_first {
10650 continue; }
10652 self.write(", ");
10653 self.generate_table(&entry.table)?;
10654 if entry.star && !strip_star {
10655 self.write("*");
10656 }
10657 }
10658 }
10659
10660 if let Some(identity) = &tr.identity {
10662 self.write_space();
10663 match identity {
10664 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
10665 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
10666 }
10667 }
10668
10669 if tr.cascade {
10670 self.write_space();
10671 self.write_keyword("CASCADE");
10672 }
10673
10674 if tr.restrict {
10675 self.write_space();
10676 self.write_keyword("RESTRICT");
10677 }
10678
10679 if let Some(ref partition) = tr.partition {
10681 self.write_space();
10682 self.generate_expression(partition)?;
10683 }
10684
10685 Ok(())
10686 }
10687
10688 fn generate_use(&mut self, u: &Use) -> Result<()> {
10689 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
10691 self.write_keyword("DATABASE");
10692 self.write_space();
10693 self.generate_identifier(&u.this)?;
10694 return Ok(());
10695 }
10696
10697 self.write_keyword("USE");
10698
10699 if let Some(kind) = &u.kind {
10700 self.write_space();
10701 match kind {
10702 UseKind::Database => self.write_keyword("DATABASE"),
10703 UseKind::Schema => self.write_keyword("SCHEMA"),
10704 UseKind::Role => self.write_keyword("ROLE"),
10705 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
10706 UseKind::Catalog => self.write_keyword("CATALOG"),
10707 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
10708 }
10709 }
10710
10711 self.write_space();
10712 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
10715 self.write(&u.this.name);
10716 } else {
10717 self.generate_identifier(&u.this)?;
10718 }
10719 Ok(())
10720 }
10721
10722 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
10723 self.write_keyword("CACHE");
10724 if c.lazy {
10725 self.write_space();
10726 self.write_keyword("LAZY");
10727 }
10728 self.write_space();
10729 self.write_keyword("TABLE");
10730 self.write_space();
10731 self.generate_identifier(&c.table)?;
10732
10733 if !c.options.is_empty() {
10735 self.write_space();
10736 self.write_keyword("OPTIONS");
10737 self.write("(");
10738 for (i, (key, value)) in c.options.iter().enumerate() {
10739 if i > 0 {
10740 self.write(", ");
10741 }
10742 self.generate_expression(key)?;
10743 self.write(" = ");
10744 self.generate_expression(value)?;
10745 }
10746 self.write(")");
10747 }
10748
10749 if let Some(query) = &c.query {
10751 self.write_space();
10752 self.write_keyword("AS");
10753 self.write_space();
10754 self.generate_expression(query)?;
10755 }
10756
10757 Ok(())
10758 }
10759
10760 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
10761 self.write_keyword("UNCACHE TABLE");
10762 if u.if_exists {
10763 self.write_space();
10764 self.write_keyword("IF EXISTS");
10765 }
10766 self.write_space();
10767 self.generate_identifier(&u.table)?;
10768 Ok(())
10769 }
10770
10771 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
10772 self.write_keyword("LOAD DATA");
10773 if l.local {
10774 self.write_space();
10775 self.write_keyword("LOCAL");
10776 }
10777 self.write_space();
10778 self.write_keyword("INPATH");
10779 self.write_space();
10780 self.write("'");
10781 self.write(&l.inpath);
10782 self.write("'");
10783
10784 if l.overwrite {
10785 self.write_space();
10786 self.write_keyword("OVERWRITE");
10787 }
10788
10789 self.write_space();
10790 self.write_keyword("INTO TABLE");
10791 self.write_space();
10792 self.generate_expression(&l.table)?;
10793
10794 if !l.partition.is_empty() {
10796 self.write_space();
10797 self.write_keyword("PARTITION");
10798 self.write("(");
10799 for (i, (col, val)) in l.partition.iter().enumerate() {
10800 if i > 0 {
10801 self.write(", ");
10802 }
10803 self.generate_identifier(col)?;
10804 self.write(" = ");
10805 self.generate_expression(val)?;
10806 }
10807 self.write(")");
10808 }
10809
10810 if let Some(fmt) = &l.input_format {
10812 self.write_space();
10813 self.write_keyword("INPUTFORMAT");
10814 self.write_space();
10815 self.write("'");
10816 self.write(fmt);
10817 self.write("'");
10818 }
10819
10820 if let Some(serde) = &l.serde {
10822 self.write_space();
10823 self.write_keyword("SERDE");
10824 self.write_space();
10825 self.write("'");
10826 self.write(serde);
10827 self.write("'");
10828 }
10829
10830 Ok(())
10831 }
10832
10833 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
10834 self.write_keyword("PRAGMA");
10835 self.write_space();
10836
10837 if let Some(schema) = &p.schema {
10839 self.generate_identifier(schema)?;
10840 self.write(".");
10841 }
10842
10843 self.generate_identifier(&p.name)?;
10845
10846 if let Some(value) = &p.value {
10848 self.write(" = ");
10849 self.generate_expression(value)?;
10850 } else if !p.args.is_empty() {
10851 self.write("(");
10852 for (i, arg) in p.args.iter().enumerate() {
10853 if i > 0 {
10854 self.write(", ");
10855 }
10856 self.generate_expression(arg)?;
10857 }
10858 self.write(")");
10859 }
10860
10861 Ok(())
10862 }
10863
10864 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
10865 self.write_keyword("GRANT");
10866 self.write_space();
10867
10868 for (i, privilege) in g.privileges.iter().enumerate() {
10870 if i > 0 {
10871 self.write(", ");
10872 }
10873 self.write_keyword(&privilege.name);
10874 if !privilege.columns.is_empty() {
10876 self.write("(");
10877 for (j, col) in privilege.columns.iter().enumerate() {
10878 if j > 0 {
10879 self.write(", ");
10880 }
10881 self.write(col);
10882 }
10883 self.write(")");
10884 }
10885 }
10886
10887 self.write_space();
10888 self.write_keyword("ON");
10889 self.write_space();
10890
10891 if let Some(kind) = &g.kind {
10893 self.write_keyword(kind);
10894 self.write_space();
10895 }
10896
10897 {
10899 use crate::dialects::DialectType;
10900 let should_upper = matches!(
10901 self.config.dialect,
10902 Some(DialectType::PostgreSQL)
10903 | Some(DialectType::CockroachDB)
10904 | Some(DialectType::Materialize)
10905 | Some(DialectType::RisingWave)
10906 ) && (g.kind.as_deref() == Some("FUNCTION")
10907 || g.kind.as_deref() == Some("PROCEDURE"));
10908 if should_upper {
10909 use crate::expressions::Identifier;
10910 let upper_id = Identifier {
10911 name: g.securable.name.to_uppercase(),
10912 quoted: g.securable.quoted,
10913 ..g.securable.clone()
10914 };
10915 self.generate_identifier(&upper_id)?;
10916 } else {
10917 self.generate_identifier(&g.securable)?;
10918 }
10919 }
10920
10921 if !g.function_params.is_empty() {
10923 self.write("(");
10924 for (i, param) in g.function_params.iter().enumerate() {
10925 if i > 0 {
10926 self.write(", ");
10927 }
10928 self.write(param);
10929 }
10930 self.write(")");
10931 }
10932
10933 self.write_space();
10934 self.write_keyword("TO");
10935 self.write_space();
10936
10937 for (i, principal) in g.principals.iter().enumerate() {
10939 if i > 0 {
10940 self.write(", ");
10941 }
10942 if principal.is_role {
10943 self.write_keyword("ROLE");
10944 self.write_space();
10945 } else if principal.is_group {
10946 self.write_keyword("GROUP");
10947 self.write_space();
10948 }
10949 self.generate_identifier(&principal.name)?;
10950 }
10951
10952 if g.grant_option {
10954 self.write_space();
10955 self.write_keyword("WITH GRANT OPTION");
10956 }
10957
10958 if let Some(ref principal) = g.as_principal {
10960 self.write_space();
10961 self.write_keyword("AS");
10962 self.write_space();
10963 self.generate_identifier(principal)?;
10964 }
10965
10966 Ok(())
10967 }
10968
10969 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
10970 self.write_keyword("REVOKE");
10971 self.write_space();
10972
10973 if r.grant_option {
10975 self.write_keyword("GRANT OPTION FOR");
10976 self.write_space();
10977 }
10978
10979 for (i, privilege) in r.privileges.iter().enumerate() {
10981 if i > 0 {
10982 self.write(", ");
10983 }
10984 self.write_keyword(&privilege.name);
10985 if !privilege.columns.is_empty() {
10987 self.write("(");
10988 for (j, col) in privilege.columns.iter().enumerate() {
10989 if j > 0 {
10990 self.write(", ");
10991 }
10992 self.write(col);
10993 }
10994 self.write(")");
10995 }
10996 }
10997
10998 self.write_space();
10999 self.write_keyword("ON");
11000 self.write_space();
11001
11002 if let Some(kind) = &r.kind {
11004 self.write_keyword(kind);
11005 self.write_space();
11006 }
11007
11008 {
11010 use crate::dialects::DialectType;
11011 let should_upper = matches!(
11012 self.config.dialect,
11013 Some(DialectType::PostgreSQL)
11014 | Some(DialectType::CockroachDB)
11015 | Some(DialectType::Materialize)
11016 | Some(DialectType::RisingWave)
11017 ) && (r.kind.as_deref() == Some("FUNCTION")
11018 || r.kind.as_deref() == Some("PROCEDURE"));
11019 if should_upper {
11020 use crate::expressions::Identifier;
11021 let upper_id = Identifier {
11022 name: r.securable.name.to_uppercase(),
11023 quoted: r.securable.quoted,
11024 ..r.securable.clone()
11025 };
11026 self.generate_identifier(&upper_id)?;
11027 } else {
11028 self.generate_identifier(&r.securable)?;
11029 }
11030 }
11031
11032 if !r.function_params.is_empty() {
11034 self.write("(");
11035 for (i, param) in r.function_params.iter().enumerate() {
11036 if i > 0 {
11037 self.write(", ");
11038 }
11039 self.write(param);
11040 }
11041 self.write(")");
11042 }
11043
11044 self.write_space();
11045 self.write_keyword("FROM");
11046 self.write_space();
11047
11048 for (i, principal) in r.principals.iter().enumerate() {
11050 if i > 0 {
11051 self.write(", ");
11052 }
11053 if principal.is_role {
11054 self.write_keyword("ROLE");
11055 self.write_space();
11056 } else if principal.is_group {
11057 self.write_keyword("GROUP");
11058 self.write_space();
11059 }
11060 self.generate_identifier(&principal.name)?;
11061 }
11062
11063 if r.cascade {
11065 self.write_space();
11066 self.write_keyword("CASCADE");
11067 } else if r.restrict {
11068 self.write_space();
11069 self.write_keyword("RESTRICT");
11070 }
11071
11072 Ok(())
11073 }
11074
11075 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
11076 self.write_keyword("COMMENT");
11077
11078 if c.exists {
11080 self.write_space();
11081 self.write_keyword("IF EXISTS");
11082 }
11083
11084 self.write_space();
11085 self.write_keyword("ON");
11086
11087 if c.materialized {
11089 self.write_space();
11090 self.write_keyword("MATERIALIZED");
11091 }
11092
11093 self.write_space();
11094 self.write_keyword(&c.kind);
11095 self.write_space();
11096
11097 self.generate_expression(&c.this)?;
11099
11100 self.write_space();
11101 self.write_keyword("IS");
11102 self.write_space();
11103
11104 self.generate_expression(&c.expression)?;
11106
11107 Ok(())
11108 }
11109
11110 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
11111 self.write_keyword("SET");
11112
11113 for (i, item) in s.items.iter().enumerate() {
11114 if i > 0 {
11115 self.write(",");
11116 }
11117 self.write_space();
11118
11119 if let Some(ref kind) = item.kind {
11121 self.write_keyword(kind);
11122 self.write_space();
11123 }
11124
11125 let name_str = match &item.name {
11127 Expression::Identifier(id) => Some(id.name.as_str()),
11128 _ => None,
11129 };
11130
11131 let is_transaction = name_str == Some("TRANSACTION");
11132 let is_character_set = name_str == Some("CHARACTER SET");
11133 let is_names = name_str == Some("NAMES");
11134 let is_collate = name_str == Some("COLLATE");
11135 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
11136 let name_has_variable_prefix = name_str.map_or(false, |n| n.starts_with("VARIABLE "));
11137 let is_variable = has_variable_kind || name_has_variable_prefix;
11138 let is_value_only =
11139 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
11140
11141 if is_transaction {
11142 self.write_keyword("TRANSACTION");
11144 if let Expression::Identifier(id) = &item.value {
11145 if !id.name.is_empty() {
11146 self.write_space();
11147 self.write(&id.name);
11148 }
11149 }
11150 } else if is_character_set {
11151 self.write_keyword("CHARACTER SET");
11153 self.write_space();
11154 self.generate_set_value(&item.value)?;
11155 } else if is_names {
11156 self.write_keyword("NAMES");
11158 self.write_space();
11159 self.generate_set_value(&item.value)?;
11160 } else if is_collate {
11161 self.write_keyword("COLLATE");
11163 self.write_space();
11164 self.generate_set_value(&item.value)?;
11165 } else if is_variable {
11166 if name_has_variable_prefix && !has_variable_kind {
11170 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
11171 self.write_keyword("VARIABLE");
11172 self.write_space();
11173 }
11174 }
11175 if let Some(ns) = name_str {
11177 let var_name = if name_has_variable_prefix {
11178 &ns["VARIABLE ".len()..]
11179 } else {
11180 ns
11181 };
11182 self.write(var_name);
11183 } else {
11184 self.generate_expression(&item.name)?;
11185 }
11186 self.write(" = ");
11187 self.generate_set_value(&item.value)?;
11188 } else if is_value_only {
11189 self.generate_expression(&item.name)?;
11191 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
11192 self.generate_expression(&item.name)?;
11194 self.write_space();
11195 self.generate_set_value(&item.value)?;
11196 } else {
11197 match &item.name {
11200 Expression::Identifier(id) => {
11201 self.write(&id.name);
11202 }
11203 _ => {
11204 self.generate_expression(&item.name)?;
11205 }
11206 }
11207 self.write(" = ");
11208 self.generate_set_value(&item.value)?;
11209 }
11210 }
11211
11212 Ok(())
11213 }
11214
11215 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
11218 if let Expression::Identifier(id) = value {
11219 match id.name.as_str() {
11220 "DEFAULT" | "ON" | "OFF" => {
11221 self.write_keyword(&id.name);
11222 return Ok(());
11223 }
11224 _ => {}
11225 }
11226 }
11227 self.generate_expression(value)
11228 }
11229
11230 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
11233 self.write_keyword("ALTER");
11234 if let Some(ref algorithm) = av.algorithm {
11236 self.write_space();
11237 self.write_keyword("ALGORITHM");
11238 self.write(" = ");
11239 self.write_keyword(algorithm);
11240 }
11241 if let Some(ref definer) = av.definer {
11242 self.write_space();
11243 self.write_keyword("DEFINER");
11244 self.write(" = ");
11245 self.write(definer);
11246 }
11247 if let Some(ref sql_security) = av.sql_security {
11248 self.write_space();
11249 self.write_keyword("SQL SECURITY");
11250 self.write(" = ");
11251 self.write_keyword(sql_security);
11252 }
11253 self.write_space();
11254 self.write_keyword("VIEW");
11255 self.write_space();
11256 self.generate_table(&av.name)?;
11257
11258 if !av.columns.is_empty() {
11260 self.write(" (");
11261 for (i, col) in av.columns.iter().enumerate() {
11262 if i > 0 {
11263 self.write(", ");
11264 }
11265 self.generate_identifier(&col.name)?;
11266 if let Some(ref comment) = col.comment {
11267 self.write_space();
11268 self.write_keyword("COMMENT");
11269 self.write(" ");
11270 self.generate_string_literal(comment)?;
11271 }
11272 }
11273 self.write(")");
11274 }
11275
11276 if let Some(ref opt) = av.with_option {
11278 self.write_space();
11279 self.write_keyword("WITH");
11280 self.write_space();
11281 self.write_keyword(opt);
11282 }
11283
11284 for action in &av.actions {
11285 self.write_space();
11286 match action {
11287 AlterViewAction::Rename(new_name) => {
11288 self.write_keyword("RENAME TO");
11289 self.write_space();
11290 self.generate_table(new_name)?;
11291 }
11292 AlterViewAction::OwnerTo(owner) => {
11293 self.write_keyword("OWNER TO");
11294 self.write_space();
11295 self.generate_identifier(owner)?;
11296 }
11297 AlterViewAction::SetSchema(schema) => {
11298 self.write_keyword("SET SCHEMA");
11299 self.write_space();
11300 self.generate_identifier(schema)?;
11301 }
11302 AlterViewAction::SetAuthorization(auth) => {
11303 self.write_keyword("SET AUTHORIZATION");
11304 self.write_space();
11305 self.write(auth);
11306 }
11307 AlterViewAction::AlterColumn { name, action } => {
11308 self.write_keyword("ALTER COLUMN");
11309 self.write_space();
11310 self.generate_identifier(name)?;
11311 self.write_space();
11312 self.generate_alter_column_action(action)?;
11313 }
11314 AlterViewAction::AsSelect(query) => {
11315 self.write_keyword("AS");
11316 self.write_space();
11317 self.generate_expression(query)?;
11318 }
11319 AlterViewAction::SetTblproperties(props) => {
11320 self.write_keyword("SET TBLPROPERTIES");
11321 self.write(" (");
11322 for (i, (key, value)) in props.iter().enumerate() {
11323 if i > 0 {
11324 self.write(", ");
11325 }
11326 self.generate_string_literal(key)?;
11327 self.write("=");
11328 self.generate_string_literal(value)?;
11329 }
11330 self.write(")");
11331 }
11332 AlterViewAction::UnsetTblproperties(keys) => {
11333 self.write_keyword("UNSET TBLPROPERTIES");
11334 self.write(" (");
11335 for (i, key) in keys.iter().enumerate() {
11336 if i > 0 {
11337 self.write(", ");
11338 }
11339 self.generate_string_literal(key)?;
11340 }
11341 self.write(")");
11342 }
11343 }
11344 }
11345
11346 Ok(())
11347 }
11348
11349 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
11350 self.write_keyword("ALTER INDEX");
11351 self.write_space();
11352 self.generate_identifier(&ai.name)?;
11353
11354 if let Some(table) = &ai.table {
11355 self.write_space();
11356 self.write_keyword("ON");
11357 self.write_space();
11358 self.generate_table(table)?;
11359 }
11360
11361 for action in &ai.actions {
11362 self.write_space();
11363 match action {
11364 AlterIndexAction::Rename(new_name) => {
11365 self.write_keyword("RENAME TO");
11366 self.write_space();
11367 self.generate_identifier(new_name)?;
11368 }
11369 AlterIndexAction::SetTablespace(tablespace) => {
11370 self.write_keyword("SET TABLESPACE");
11371 self.write_space();
11372 self.generate_identifier(tablespace)?;
11373 }
11374 AlterIndexAction::Visible(visible) => {
11375 if *visible {
11376 self.write_keyword("VISIBLE");
11377 } else {
11378 self.write_keyword("INVISIBLE");
11379 }
11380 }
11381 }
11382 }
11383
11384 Ok(())
11385 }
11386
11387 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
11388 for comment in &cs.leading_comments {
11390 self.write_formatted_comment(comment);
11391 self.write_space();
11392 }
11393
11394 let saved_athena_hive_context = self.athena_hive_context;
11396 if matches!(
11397 self.config.dialect,
11398 Some(crate::dialects::DialectType::Athena)
11399 ) {
11400 self.athena_hive_context = true;
11401 }
11402
11403 self.write_keyword("CREATE SCHEMA");
11404
11405 if cs.if_not_exists {
11406 self.write_space();
11407 self.write_keyword("IF NOT EXISTS");
11408 }
11409
11410 self.write_space();
11411 self.generate_identifier(&cs.name)?;
11412
11413 if let Some(ref clone_src) = cs.clone_from {
11414 self.write_keyword(" CLONE ");
11415 self.generate_identifier(clone_src)?;
11416 }
11417
11418 if let Some(ref at_clause) = cs.at_clause {
11419 self.write_space();
11420 self.generate_expression(at_clause)?;
11421 }
11422
11423 if let Some(auth) = &cs.authorization {
11424 self.write_space();
11425 self.write_keyword("AUTHORIZATION");
11426 self.write_space();
11427 self.generate_identifier(auth)?;
11428 }
11429
11430 let with_properties: Vec<_> = cs
11433 .properties
11434 .iter()
11435 .filter(|p| matches!(p, Expression::Property(_)))
11436 .collect();
11437 let other_properties: Vec<_> = cs
11438 .properties
11439 .iter()
11440 .filter(|p| !matches!(p, Expression::Property(_)))
11441 .collect();
11442
11443 if !with_properties.is_empty() {
11445 self.write_space();
11446 self.write_keyword("WITH");
11447 self.write(" (");
11448 for (i, prop) in with_properties.iter().enumerate() {
11449 if i > 0 {
11450 self.write(", ");
11451 }
11452 self.generate_expression(prop)?;
11453 }
11454 self.write(")");
11455 }
11456
11457 for prop in other_properties {
11459 self.write_space();
11460 self.generate_expression(prop)?;
11461 }
11462
11463 self.athena_hive_context = saved_athena_hive_context;
11465
11466 Ok(())
11467 }
11468
11469 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
11470 self.write_keyword("DROP SCHEMA");
11471
11472 if ds.if_exists {
11473 self.write_space();
11474 self.write_keyword("IF EXISTS");
11475 }
11476
11477 self.write_space();
11478 self.generate_identifier(&ds.name)?;
11479
11480 if ds.cascade {
11481 self.write_space();
11482 self.write_keyword("CASCADE");
11483 }
11484
11485 Ok(())
11486 }
11487
11488 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
11489 self.write_keyword("DROP NAMESPACE");
11490
11491 if dn.if_exists {
11492 self.write_space();
11493 self.write_keyword("IF EXISTS");
11494 }
11495
11496 self.write_space();
11497 self.generate_identifier(&dn.name)?;
11498
11499 if dn.cascade {
11500 self.write_space();
11501 self.write_keyword("CASCADE");
11502 }
11503
11504 Ok(())
11505 }
11506
11507 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
11508 self.write_keyword("CREATE DATABASE");
11509
11510 if cd.if_not_exists {
11511 self.write_space();
11512 self.write_keyword("IF NOT EXISTS");
11513 }
11514
11515 self.write_space();
11516 self.generate_identifier(&cd.name)?;
11517
11518 if let Some(ref clone_src) = cd.clone_from {
11519 self.write_keyword(" CLONE ");
11520 self.generate_identifier(clone_src)?;
11521 }
11522
11523 if let Some(ref at_clause) = cd.at_clause {
11525 self.write_space();
11526 self.generate_expression(at_clause)?;
11527 }
11528
11529 for option in &cd.options {
11530 self.write_space();
11531 match option {
11532 DatabaseOption::CharacterSet(charset) => {
11533 self.write_keyword("CHARACTER SET");
11534 self.write(" = ");
11535 self.write(&format!("'{}'", charset));
11536 }
11537 DatabaseOption::Collate(collate) => {
11538 self.write_keyword("COLLATE");
11539 self.write(" = ");
11540 self.write(&format!("'{}'", collate));
11541 }
11542 DatabaseOption::Owner(owner) => {
11543 self.write_keyword("OWNER");
11544 self.write(" = ");
11545 self.generate_identifier(owner)?;
11546 }
11547 DatabaseOption::Template(template) => {
11548 self.write_keyword("TEMPLATE");
11549 self.write(" = ");
11550 self.generate_identifier(template)?;
11551 }
11552 DatabaseOption::Encoding(encoding) => {
11553 self.write_keyword("ENCODING");
11554 self.write(" = ");
11555 self.write(&format!("'{}'", encoding));
11556 }
11557 DatabaseOption::Location(location) => {
11558 self.write_keyword("LOCATION");
11559 self.write(" = ");
11560 self.write(&format!("'{}'", location));
11561 }
11562 }
11563 }
11564
11565 Ok(())
11566 }
11567
11568 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
11569 self.write_keyword("DROP DATABASE");
11570
11571 if dd.if_exists {
11572 self.write_space();
11573 self.write_keyword("IF EXISTS");
11574 }
11575
11576 self.write_space();
11577 self.generate_identifier(&dd.name)?;
11578
11579 Ok(())
11580 }
11581
11582 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
11583 self.write_keyword("CREATE");
11584
11585 if cf.or_replace {
11586 self.write_space();
11587 self.write_keyword("OR REPLACE");
11588 }
11589
11590 if cf.temporary {
11591 self.write_space();
11592 self.write_keyword("TEMPORARY");
11593 }
11594
11595 self.write_space();
11596 if cf.is_table_function {
11597 self.write_keyword("TABLE FUNCTION");
11598 } else {
11599 self.write_keyword("FUNCTION");
11600 }
11601
11602 if cf.if_not_exists {
11603 self.write_space();
11604 self.write_keyword("IF NOT EXISTS");
11605 }
11606
11607 self.write_space();
11608 self.generate_table(&cf.name)?;
11609 if cf.has_parens {
11610 let func_multiline = self.config.pretty
11611 && matches!(
11612 self.config.dialect,
11613 Some(crate::dialects::DialectType::TSQL)
11614 | Some(crate::dialects::DialectType::Fabric)
11615 )
11616 && !cf.parameters.is_empty();
11617 if func_multiline {
11618 self.write("(\n");
11619 self.indent_level += 2;
11620 self.write_indent();
11621 self.generate_function_parameters(&cf.parameters)?;
11622 self.write("\n");
11623 self.indent_level -= 2;
11624 self.write(")");
11625 } else {
11626 self.write("(");
11627 self.generate_function_parameters(&cf.parameters)?;
11628 self.write(")");
11629 }
11630 }
11631
11632 let use_multiline = self.config.pretty
11635 && matches!(
11636 self.config.dialect,
11637 Some(crate::dialects::DialectType::BigQuery)
11638 | Some(crate::dialects::DialectType::TSQL)
11639 | Some(crate::dialects::DialectType::Fabric)
11640 );
11641
11642 if cf.language_first {
11643 if let Some(lang) = &cf.language {
11645 if use_multiline {
11646 self.write_newline();
11647 } else {
11648 self.write_space();
11649 }
11650 self.write_keyword("LANGUAGE");
11651 self.write_space();
11652 self.write(lang);
11653 }
11654
11655 if let Some(sql_data) = &cf.sql_data_access {
11657 self.write_space();
11658 match sql_data {
11659 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
11660 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
11661 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
11662 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
11663 }
11664 }
11665
11666 if let Some(ref rtb) = cf.returns_table_body {
11667 if use_multiline {
11668 self.write_newline();
11669 } else {
11670 self.write_space();
11671 }
11672 self.write_keyword("RETURNS");
11673 self.write_space();
11674 self.write(rtb);
11675 } else if let Some(return_type) = &cf.return_type {
11676 if use_multiline {
11677 self.write_newline();
11678 } else {
11679 self.write_space();
11680 }
11681 self.write_keyword("RETURNS");
11682 self.write_space();
11683 self.generate_data_type(return_type)?;
11684 }
11685 } else {
11686 let is_duckdb = matches!(
11689 self.config.dialect,
11690 Some(crate::dialects::DialectType::DuckDB)
11691 );
11692 if let Some(ref rtb) = cf.returns_table_body {
11693 if !(is_duckdb && rtb.is_empty()) {
11694 if use_multiline {
11695 self.write_newline();
11696 } else {
11697 self.write_space();
11698 }
11699 self.write_keyword("RETURNS");
11700 self.write_space();
11701 self.write(rtb);
11702 }
11703 } else if let Some(return_type) = &cf.return_type {
11704 if use_multiline {
11705 self.write_newline();
11706 } else {
11707 self.write_space();
11708 }
11709 self.write_keyword("RETURNS");
11710 self.write_space();
11711 self.generate_data_type(return_type)?;
11712 }
11713 }
11714
11715 if !cf.property_order.is_empty() {
11717 let is_bigquery = matches!(
11719 self.config.dialect,
11720 Some(crate::dialects::DialectType::BigQuery)
11721 );
11722 let property_order = if is_bigquery {
11723 let mut reordered = Vec::new();
11725 let mut has_as = false;
11726 let mut has_options = false;
11727 for prop in &cf.property_order {
11728 match prop {
11729 FunctionPropertyKind::As => has_as = true,
11730 FunctionPropertyKind::Options => has_options = true,
11731 _ => {}
11732 }
11733 }
11734 if has_as && has_options {
11735 for prop in &cf.property_order {
11737 if *prop != FunctionPropertyKind::As
11738 && *prop != FunctionPropertyKind::Options
11739 {
11740 reordered.push(*prop);
11741 }
11742 }
11743 reordered.push(FunctionPropertyKind::Options);
11744 reordered.push(FunctionPropertyKind::As);
11745 reordered
11746 } else {
11747 cf.property_order.clone()
11748 }
11749 } else {
11750 cf.property_order.clone()
11751 };
11752
11753 for prop in &property_order {
11754 match prop {
11755 FunctionPropertyKind::Set => {
11756 self.generate_function_set_options(cf)?;
11757 }
11758 FunctionPropertyKind::As => {
11759 self.generate_function_body(cf)?;
11760 }
11761 FunctionPropertyKind::Language => {
11762 if !cf.language_first {
11763 if let Some(lang) = &cf.language {
11765 let use_multiline = self.config.pretty
11767 && matches!(
11768 self.config.dialect,
11769 Some(crate::dialects::DialectType::BigQuery)
11770 );
11771 if use_multiline {
11772 self.write_newline();
11773 } else {
11774 self.write_space();
11775 }
11776 self.write_keyword("LANGUAGE");
11777 self.write_space();
11778 self.write(lang);
11779 }
11780 }
11781 }
11782 FunctionPropertyKind::Determinism => {
11783 self.generate_function_determinism(cf)?;
11784 }
11785 FunctionPropertyKind::NullInput => {
11786 self.generate_function_null_input(cf)?;
11787 }
11788 FunctionPropertyKind::Security => {
11789 self.generate_function_security(cf)?;
11790 }
11791 FunctionPropertyKind::SqlDataAccess => {
11792 if !cf.language_first {
11793 self.generate_function_sql_data_access(cf)?;
11795 }
11796 }
11797 FunctionPropertyKind::Options => {
11798 if !cf.options.is_empty() {
11799 self.write_space();
11800 self.generate_options_clause(&cf.options)?;
11801 }
11802 }
11803 FunctionPropertyKind::Environment => {
11804 if !cf.environment.is_empty() {
11805 self.write_space();
11806 self.generate_environment_clause(&cf.environment)?;
11807 }
11808 }
11809 }
11810 }
11811
11812 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
11814 {
11815 self.write_space();
11816 self.generate_options_clause(&cf.options)?;
11817 }
11818
11819 if !cf.environment.is_empty()
11821 && !cf
11822 .property_order
11823 .contains(&FunctionPropertyKind::Environment)
11824 {
11825 self.write_space();
11826 self.generate_environment_clause(&cf.environment)?;
11827 }
11828 } else {
11829 if matches!(
11832 self.config.dialect,
11833 Some(crate::dialects::DialectType::BigQuery)
11834 ) {
11835 self.generate_function_determinism(cf)?;
11836 }
11837
11838 let use_multiline = self.config.pretty
11840 && matches!(
11841 self.config.dialect,
11842 Some(crate::dialects::DialectType::BigQuery)
11843 );
11844
11845 if !cf.language_first {
11846 if let Some(lang) = &cf.language {
11847 if use_multiline {
11848 self.write_newline();
11849 } else {
11850 self.write_space();
11851 }
11852 self.write_keyword("LANGUAGE");
11853 self.write_space();
11854 self.write(lang);
11855 }
11856
11857 self.generate_function_sql_data_access(cf)?;
11859 }
11860
11861 if !matches!(
11863 self.config.dialect,
11864 Some(crate::dialects::DialectType::BigQuery)
11865 ) {
11866 self.generate_function_determinism(cf)?;
11867 }
11868
11869 self.generate_function_null_input(cf)?;
11870 self.generate_function_security(cf)?;
11871 self.generate_function_set_options(cf)?;
11872
11873 if !cf.options.is_empty() {
11875 self.write_space();
11876 self.generate_options_clause(&cf.options)?;
11877 }
11878
11879 if !cf.environment.is_empty() {
11881 self.write_space();
11882 self.generate_environment_clause(&cf.environment)?;
11883 }
11884
11885 self.generate_function_body(cf)?;
11886 }
11887
11888 Ok(())
11889 }
11890
11891 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
11893 for opt in &cf.set_options {
11894 self.write_space();
11895 self.write_keyword("SET");
11896 self.write_space();
11897 self.write(&opt.name);
11898 match &opt.value {
11899 FunctionSetValue::Value { value, use_to } => {
11900 if *use_to {
11901 self.write(" TO ");
11902 } else {
11903 self.write(" = ");
11904 }
11905 self.write(value);
11906 }
11907 FunctionSetValue::FromCurrent => {
11908 self.write_space();
11909 self.write_keyword("FROM CURRENT");
11910 }
11911 }
11912 }
11913 Ok(())
11914 }
11915
11916 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
11918 if let Some(body) = &cf.body {
11919 self.write_space();
11921 let use_multiline = self.config.pretty
11923 && matches!(
11924 self.config.dialect,
11925 Some(crate::dialects::DialectType::BigQuery)
11926 );
11927 match body {
11928 FunctionBody::Block(block) => {
11929 self.write_keyword("AS");
11930 if matches!(
11931 self.config.dialect,
11932 Some(crate::dialects::DialectType::TSQL)
11933 ) {
11934 self.write(" BEGIN ");
11935 self.write(block);
11936 self.write(" END");
11937 } else if matches!(
11938 self.config.dialect,
11939 Some(crate::dialects::DialectType::PostgreSQL)
11940 ) {
11941 self.write(" $$");
11942 self.write(block);
11943 self.write("$$");
11944 } else {
11945 let escaped = self.escape_block_for_single_quote(block);
11947 if use_multiline {
11949 self.write_newline();
11950 } else {
11951 self.write(" ");
11952 }
11953 self.write("'");
11954 self.write(&escaped);
11955 self.write("'");
11956 }
11957 }
11958 FunctionBody::StringLiteral(s) => {
11959 self.write_keyword("AS");
11960 if use_multiline {
11962 self.write_newline();
11963 } else {
11964 self.write(" ");
11965 }
11966 self.write("'");
11967 self.write(s);
11968 self.write("'");
11969 }
11970 FunctionBody::Expression(expr) => {
11971 self.write_keyword("AS");
11972 self.write_space();
11973 self.generate_expression(expr)?;
11974 }
11975 FunctionBody::External(name) => {
11976 self.write_keyword("EXTERNAL NAME");
11977 self.write(" '");
11978 self.write(name);
11979 self.write("'");
11980 }
11981 FunctionBody::Return(expr) => {
11982 if matches!(
11983 self.config.dialect,
11984 Some(crate::dialects::DialectType::DuckDB)
11985 ) {
11986 self.write_keyword("AS");
11988 self.write_space();
11989 if cf.returns_table_body.is_some() {
11991 self.write_keyword("TABLE");
11992 self.write_space();
11993 }
11994 self.generate_expression(expr)?;
11995 } else {
11996 if self.config.create_function_return_as {
11997 self.write_keyword("AS");
11998 if self.config.pretty
12000 && matches!(
12001 self.config.dialect,
12002 Some(crate::dialects::DialectType::TSQL)
12003 | Some(crate::dialects::DialectType::Fabric)
12004 )
12005 {
12006 self.write_newline();
12007 } else {
12008 self.write_space();
12009 }
12010 }
12011 self.write_keyword("RETURN");
12012 self.write_space();
12013 self.generate_expression(expr)?;
12014 }
12015 }
12016 FunctionBody::Statements(stmts) => {
12017 self.write_keyword("AS");
12018 self.write(" BEGIN ");
12019 for (i, stmt) in stmts.iter().enumerate() {
12020 if i > 0 {
12021 self.write(" ");
12022 }
12023 self.generate_expression(stmt)?;
12024 }
12025 self.write(" END");
12026 }
12027 FunctionBody::DollarQuoted { content, tag } => {
12028 self.write_keyword("AS");
12029 self.write(" ");
12030 let supports_dollar_quoting = matches!(
12032 self.config.dialect,
12033 Some(crate::dialects::DialectType::PostgreSQL)
12034 | Some(crate::dialects::DialectType::Databricks)
12035 | Some(crate::dialects::DialectType::Redshift)
12036 | Some(crate::dialects::DialectType::DuckDB)
12037 );
12038 if supports_dollar_quoting {
12039 self.write("$");
12041 if let Some(t) = tag {
12042 self.write(t);
12043 }
12044 self.write("$");
12045 self.write(content);
12046 self.write("$");
12047 if let Some(t) = tag {
12048 self.write(t);
12049 }
12050 self.write("$");
12051 } else {
12052 let escaped = self.escape_block_for_single_quote(content);
12054 self.write("'");
12055 self.write(&escaped);
12056 self.write("'");
12057 }
12058 }
12059 }
12060 }
12061 Ok(())
12062 }
12063
12064 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
12066 if let Some(det) = cf.deterministic {
12067 self.write_space();
12068 if matches!(
12069 self.config.dialect,
12070 Some(crate::dialects::DialectType::BigQuery)
12071 ) {
12072 if det {
12074 self.write_keyword("DETERMINISTIC");
12075 } else {
12076 self.write_keyword("NOT DETERMINISTIC");
12077 }
12078 } else {
12079 if det {
12081 self.write_keyword("IMMUTABLE");
12082 } else {
12083 self.write_keyword("VOLATILE");
12084 }
12085 }
12086 }
12087 Ok(())
12088 }
12089
12090 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
12092 if let Some(returns_null) = cf.returns_null_on_null_input {
12093 self.write_space();
12094 if returns_null {
12095 if cf.strict {
12096 self.write_keyword("STRICT");
12097 } else {
12098 self.write_keyword("RETURNS NULL ON NULL INPUT");
12099 }
12100 } else {
12101 self.write_keyword("CALLED ON NULL INPUT");
12102 }
12103 }
12104 Ok(())
12105 }
12106
12107 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
12109 if let Some(security) = &cf.security {
12110 self.write_space();
12111 self.write_keyword("SECURITY");
12112 self.write_space();
12113 match security {
12114 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12115 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12116 FunctionSecurity::None => self.write_keyword("NONE"),
12117 }
12118 }
12119 Ok(())
12120 }
12121
12122 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
12124 if let Some(sql_data) = &cf.sql_data_access {
12125 self.write_space();
12126 match sql_data {
12127 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12128 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12129 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12130 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12131 }
12132 }
12133 Ok(())
12134 }
12135
12136 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
12137 for (i, param) in params.iter().enumerate() {
12138 if i > 0 {
12139 self.write(", ");
12140 }
12141
12142 if let Some(mode) = ¶m.mode {
12143 if let Some(text) = ¶m.mode_text {
12144 self.write(text);
12145 } else {
12146 match mode {
12147 ParameterMode::In => self.write_keyword("IN"),
12148 ParameterMode::Out => self.write_keyword("OUT"),
12149 ParameterMode::InOut => self.write_keyword("INOUT"),
12150 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
12151 }
12152 }
12153 self.write_space();
12154 }
12155
12156 if let Some(name) = ¶m.name {
12157 self.generate_identifier(name)?;
12158 let skip_type =
12160 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
12161 if !skip_type {
12162 self.write_space();
12163 self.generate_data_type(¶m.data_type)?;
12164 }
12165 } else {
12166 self.generate_data_type(¶m.data_type)?;
12167 }
12168
12169 if let Some(default) = ¶m.default {
12170 if self.config.parameter_default_equals {
12171 self.write(" = ");
12172 } else {
12173 self.write(" DEFAULT ");
12174 }
12175 self.generate_expression(default)?;
12176 }
12177 }
12178
12179 Ok(())
12180 }
12181
12182 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
12183 self.write_keyword("DROP FUNCTION");
12184
12185 if df.if_exists {
12186 self.write_space();
12187 self.write_keyword("IF EXISTS");
12188 }
12189
12190 self.write_space();
12191 self.generate_table(&df.name)?;
12192
12193 if let Some(params) = &df.parameters {
12194 self.write(" (");
12195 for (i, dt) in params.iter().enumerate() {
12196 if i > 0 {
12197 self.write(", ");
12198 }
12199 self.generate_data_type(dt)?;
12200 }
12201 self.write(")");
12202 }
12203
12204 if df.cascade {
12205 self.write_space();
12206 self.write_keyword("CASCADE");
12207 }
12208
12209 Ok(())
12210 }
12211
12212 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
12213 self.write_keyword("CREATE");
12214
12215 if cp.or_replace {
12216 self.write_space();
12217 self.write_keyword("OR REPLACE");
12218 }
12219
12220 self.write_space();
12221 if cp.use_proc_keyword {
12222 self.write_keyword("PROC");
12223 } else {
12224 self.write_keyword("PROCEDURE");
12225 }
12226
12227 if cp.if_not_exists {
12228 self.write_space();
12229 self.write_keyword("IF NOT EXISTS");
12230 }
12231
12232 self.write_space();
12233 self.generate_table(&cp.name)?;
12234 if cp.has_parens {
12235 self.write("(");
12236 self.generate_function_parameters(&cp.parameters)?;
12237 self.write(")");
12238 } else if !cp.parameters.is_empty() {
12239 self.write_space();
12241 self.generate_function_parameters(&cp.parameters)?;
12242 }
12243
12244 if let Some(return_type) = &cp.return_type {
12246 self.write_space();
12247 self.write_keyword("RETURNS");
12248 self.write_space();
12249 self.generate_data_type(return_type)?;
12250 }
12251
12252 if let Some(execute_as) = &cp.execute_as {
12254 self.write_space();
12255 self.write_keyword("EXECUTE AS");
12256 self.write_space();
12257 self.write_keyword(execute_as);
12258 }
12259
12260 if let Some(lang) = &cp.language {
12261 self.write_space();
12262 self.write_keyword("LANGUAGE");
12263 self.write_space();
12264 self.write(lang);
12265 }
12266
12267 if let Some(security) = &cp.security {
12268 self.write_space();
12269 self.write_keyword("SECURITY");
12270 self.write_space();
12271 match security {
12272 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12273 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12274 FunctionSecurity::None => self.write_keyword("NONE"),
12275 }
12276 }
12277
12278 if !cp.with_options.is_empty() {
12280 self.write_space();
12281 self.write_keyword("WITH");
12282 self.write_space();
12283 for (i, opt) in cp.with_options.iter().enumerate() {
12284 if i > 0 {
12285 self.write(", ");
12286 }
12287 self.write(opt);
12288 }
12289 }
12290
12291 if let Some(body) = &cp.body {
12292 self.write_space();
12293 match body {
12294 FunctionBody::Block(block) => {
12295 self.write_keyword("AS");
12296 if matches!(
12297 self.config.dialect,
12298 Some(crate::dialects::DialectType::TSQL)
12299 ) {
12300 self.write(" BEGIN ");
12301 self.write(block);
12302 self.write(" END");
12303 } else if matches!(
12304 self.config.dialect,
12305 Some(crate::dialects::DialectType::PostgreSQL)
12306 ) {
12307 self.write(" $$");
12308 self.write(block);
12309 self.write("$$");
12310 } else {
12311 let escaped = self.escape_block_for_single_quote(block);
12313 self.write(" '");
12314 self.write(&escaped);
12315 self.write("'");
12316 }
12317 }
12318 FunctionBody::StringLiteral(s) => {
12319 self.write_keyword("AS");
12320 self.write(" '");
12321 self.write(s);
12322 self.write("'");
12323 }
12324 FunctionBody::Expression(expr) => {
12325 self.write_keyword("AS");
12326 self.write_space();
12327 self.generate_expression(expr)?;
12328 }
12329 FunctionBody::External(name) => {
12330 self.write_keyword("EXTERNAL NAME");
12331 self.write(" '");
12332 self.write(name);
12333 self.write("'");
12334 }
12335 FunctionBody::Return(expr) => {
12336 self.write_keyword("RETURN");
12337 self.write_space();
12338 self.generate_expression(expr)?;
12339 }
12340 FunctionBody::Statements(stmts) => {
12341 self.write_keyword("AS");
12342 self.write(" BEGIN ");
12343 for (i, stmt) in stmts.iter().enumerate() {
12344 if i > 0 {
12345 self.write(" ");
12346 }
12347 self.generate_expression(stmt)?;
12348 }
12349 self.write(" END");
12350 }
12351 FunctionBody::DollarQuoted { content, tag } => {
12352 self.write_keyword("AS");
12353 self.write(" ");
12354 let supports_dollar_quoting = matches!(
12356 self.config.dialect,
12357 Some(crate::dialects::DialectType::PostgreSQL)
12358 | Some(crate::dialects::DialectType::Databricks)
12359 | Some(crate::dialects::DialectType::Redshift)
12360 | Some(crate::dialects::DialectType::DuckDB)
12361 );
12362 if supports_dollar_quoting {
12363 self.write("$");
12365 if let Some(t) = tag {
12366 self.write(t);
12367 }
12368 self.write("$");
12369 self.write(content);
12370 self.write("$");
12371 if let Some(t) = tag {
12372 self.write(t);
12373 }
12374 self.write("$");
12375 } else {
12376 let escaped = self.escape_block_for_single_quote(content);
12378 self.write("'");
12379 self.write(&escaped);
12380 self.write("'");
12381 }
12382 }
12383 }
12384 }
12385
12386 Ok(())
12387 }
12388
12389 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
12390 self.write_keyword("DROP PROCEDURE");
12391
12392 if dp.if_exists {
12393 self.write_space();
12394 self.write_keyword("IF EXISTS");
12395 }
12396
12397 self.write_space();
12398 self.generate_table(&dp.name)?;
12399
12400 if let Some(params) = &dp.parameters {
12401 self.write(" (");
12402 for (i, dt) in params.iter().enumerate() {
12403 if i > 0 {
12404 self.write(", ");
12405 }
12406 self.generate_data_type(dt)?;
12407 }
12408 self.write(")");
12409 }
12410
12411 if dp.cascade {
12412 self.write_space();
12413 self.write_keyword("CASCADE");
12414 }
12415
12416 Ok(())
12417 }
12418
12419 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
12420 self.write_keyword("CREATE");
12421
12422 if cs.or_replace {
12423 self.write_space();
12424 self.write_keyword("OR REPLACE");
12425 }
12426
12427 if cs.temporary {
12428 self.write_space();
12429 self.write_keyword("TEMPORARY");
12430 }
12431
12432 self.write_space();
12433 self.write_keyword("SEQUENCE");
12434
12435 if cs.if_not_exists {
12436 self.write_space();
12437 self.write_keyword("IF NOT EXISTS");
12438 }
12439
12440 self.write_space();
12441 self.generate_table(&cs.name)?;
12442
12443 if let Some(as_type) = &cs.as_type {
12445 self.write_space();
12446 self.write_keyword("AS");
12447 self.write_space();
12448 self.generate_data_type(as_type)?;
12449 }
12450
12451 if let Some(comment) = &cs.comment {
12453 self.write_space();
12454 self.write_keyword("COMMENT");
12455 self.write("=");
12456 self.generate_string_literal(comment)?;
12457 }
12458
12459 if !cs.property_order.is_empty() {
12461 for prop in &cs.property_order {
12462 match prop {
12463 SeqPropKind::Start => {
12464 if let Some(start) = cs.start {
12465 self.write_space();
12466 self.write_keyword("START WITH");
12467 self.write(&format!(" {}", start));
12468 }
12469 }
12470 SeqPropKind::Increment => {
12471 if let Some(inc) = cs.increment {
12472 self.write_space();
12473 self.write_keyword("INCREMENT BY");
12474 self.write(&format!(" {}", inc));
12475 }
12476 }
12477 SeqPropKind::Minvalue => {
12478 if let Some(min) = &cs.minvalue {
12479 self.write_space();
12480 match min {
12481 SequenceBound::Value(v) => {
12482 self.write_keyword("MINVALUE");
12483 self.write(&format!(" {}", v));
12484 }
12485 SequenceBound::None => {
12486 self.write_keyword("NO MINVALUE");
12487 }
12488 }
12489 }
12490 }
12491 SeqPropKind::Maxvalue => {
12492 if let Some(max) = &cs.maxvalue {
12493 self.write_space();
12494 match max {
12495 SequenceBound::Value(v) => {
12496 self.write_keyword("MAXVALUE");
12497 self.write(&format!(" {}", v));
12498 }
12499 SequenceBound::None => {
12500 self.write_keyword("NO MAXVALUE");
12501 }
12502 }
12503 }
12504 }
12505 SeqPropKind::Cache => {
12506 if let Some(cache) = cs.cache {
12507 self.write_space();
12508 self.write_keyword("CACHE");
12509 self.write(&format!(" {}", cache));
12510 }
12511 }
12512 SeqPropKind::NoCache => {
12513 self.write_space();
12514 self.write_keyword("NO CACHE");
12515 }
12516 SeqPropKind::NoCacheWord => {
12517 self.write_space();
12518 self.write_keyword("NOCACHE");
12519 }
12520 SeqPropKind::Cycle => {
12521 self.write_space();
12522 self.write_keyword("CYCLE");
12523 }
12524 SeqPropKind::NoCycle => {
12525 self.write_space();
12526 self.write_keyword("NO CYCLE");
12527 }
12528 SeqPropKind::NoCycleWord => {
12529 self.write_space();
12530 self.write_keyword("NOCYCLE");
12531 }
12532 SeqPropKind::OwnedBy => {
12533 if !cs.owned_by_none {
12535 if let Some(owned) = &cs.owned_by {
12536 self.write_space();
12537 self.write_keyword("OWNED BY");
12538 self.write_space();
12539 self.generate_table(owned)?;
12540 }
12541 }
12542 }
12543 SeqPropKind::Order => {
12544 self.write_space();
12545 self.write_keyword("ORDER");
12546 }
12547 SeqPropKind::NoOrder => {
12548 self.write_space();
12549 self.write_keyword("NOORDER");
12550 }
12551 SeqPropKind::Comment => {
12552 }
12554 SeqPropKind::Sharing => {
12555 if let Some(val) = &cs.sharing {
12556 self.write_space();
12557 self.write(&format!("SHARING={}", val));
12558 }
12559 }
12560 SeqPropKind::Keep => {
12561 self.write_space();
12562 self.write_keyword("KEEP");
12563 }
12564 SeqPropKind::NoKeep => {
12565 self.write_space();
12566 self.write_keyword("NOKEEP");
12567 }
12568 SeqPropKind::Scale => {
12569 self.write_space();
12570 self.write_keyword("SCALE");
12571 if let Some(modifier) = &cs.scale_modifier {
12572 if !modifier.is_empty() {
12573 self.write_space();
12574 self.write_keyword(modifier);
12575 }
12576 }
12577 }
12578 SeqPropKind::NoScale => {
12579 self.write_space();
12580 self.write_keyword("NOSCALE");
12581 }
12582 SeqPropKind::Shard => {
12583 self.write_space();
12584 self.write_keyword("SHARD");
12585 if let Some(modifier) = &cs.shard_modifier {
12586 if !modifier.is_empty() {
12587 self.write_space();
12588 self.write_keyword(modifier);
12589 }
12590 }
12591 }
12592 SeqPropKind::NoShard => {
12593 self.write_space();
12594 self.write_keyword("NOSHARD");
12595 }
12596 SeqPropKind::Session => {
12597 self.write_space();
12598 self.write_keyword("SESSION");
12599 }
12600 SeqPropKind::Global => {
12601 self.write_space();
12602 self.write_keyword("GLOBAL");
12603 }
12604 SeqPropKind::NoMinvalueWord => {
12605 self.write_space();
12606 self.write_keyword("NOMINVALUE");
12607 }
12608 SeqPropKind::NoMaxvalueWord => {
12609 self.write_space();
12610 self.write_keyword("NOMAXVALUE");
12611 }
12612 }
12613 }
12614 } else {
12615 if let Some(inc) = cs.increment {
12617 self.write_space();
12618 self.write_keyword("INCREMENT BY");
12619 self.write(&format!(" {}", inc));
12620 }
12621
12622 if let Some(min) = &cs.minvalue {
12623 self.write_space();
12624 match min {
12625 SequenceBound::Value(v) => {
12626 self.write_keyword("MINVALUE");
12627 self.write(&format!(" {}", v));
12628 }
12629 SequenceBound::None => {
12630 self.write_keyword("NO MINVALUE");
12631 }
12632 }
12633 }
12634
12635 if let Some(max) = &cs.maxvalue {
12636 self.write_space();
12637 match max {
12638 SequenceBound::Value(v) => {
12639 self.write_keyword("MAXVALUE");
12640 self.write(&format!(" {}", v));
12641 }
12642 SequenceBound::None => {
12643 self.write_keyword("NO MAXVALUE");
12644 }
12645 }
12646 }
12647
12648 if let Some(start) = cs.start {
12649 self.write_space();
12650 self.write_keyword("START WITH");
12651 self.write(&format!(" {}", start));
12652 }
12653
12654 if let Some(cache) = cs.cache {
12655 self.write_space();
12656 self.write_keyword("CACHE");
12657 self.write(&format!(" {}", cache));
12658 }
12659
12660 if cs.cycle {
12661 self.write_space();
12662 self.write_keyword("CYCLE");
12663 }
12664
12665 if let Some(owned) = &cs.owned_by {
12666 self.write_space();
12667 self.write_keyword("OWNED BY");
12668 self.write_space();
12669 self.generate_table(owned)?;
12670 }
12671 }
12672
12673 Ok(())
12674 }
12675
12676 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
12677 self.write_keyword("DROP SEQUENCE");
12678
12679 if ds.if_exists {
12680 self.write_space();
12681 self.write_keyword("IF EXISTS");
12682 }
12683
12684 self.write_space();
12685 self.generate_table(&ds.name)?;
12686
12687 if ds.cascade {
12688 self.write_space();
12689 self.write_keyword("CASCADE");
12690 }
12691
12692 Ok(())
12693 }
12694
12695 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
12696 self.write_keyword("ALTER SEQUENCE");
12697
12698 if als.if_exists {
12699 self.write_space();
12700 self.write_keyword("IF EXISTS");
12701 }
12702
12703 self.write_space();
12704 self.generate_table(&als.name)?;
12705
12706 if let Some(inc) = als.increment {
12707 self.write_space();
12708 self.write_keyword("INCREMENT BY");
12709 self.write(&format!(" {}", inc));
12710 }
12711
12712 if let Some(min) = &als.minvalue {
12713 self.write_space();
12714 match min {
12715 SequenceBound::Value(v) => {
12716 self.write_keyword("MINVALUE");
12717 self.write(&format!(" {}", v));
12718 }
12719 SequenceBound::None => {
12720 self.write_keyword("NO MINVALUE");
12721 }
12722 }
12723 }
12724
12725 if let Some(max) = &als.maxvalue {
12726 self.write_space();
12727 match max {
12728 SequenceBound::Value(v) => {
12729 self.write_keyword("MAXVALUE");
12730 self.write(&format!(" {}", v));
12731 }
12732 SequenceBound::None => {
12733 self.write_keyword("NO MAXVALUE");
12734 }
12735 }
12736 }
12737
12738 if let Some(start) = als.start {
12739 self.write_space();
12740 self.write_keyword("START WITH");
12741 self.write(&format!(" {}", start));
12742 }
12743
12744 if let Some(restart) = &als.restart {
12745 self.write_space();
12746 self.write_keyword("RESTART");
12747 if let Some(val) = restart {
12748 self.write_keyword(" WITH");
12749 self.write(&format!(" {}", val));
12750 }
12751 }
12752
12753 if let Some(cache) = als.cache {
12754 self.write_space();
12755 self.write_keyword("CACHE");
12756 self.write(&format!(" {}", cache));
12757 }
12758
12759 if let Some(cycle) = als.cycle {
12760 self.write_space();
12761 if cycle {
12762 self.write_keyword("CYCLE");
12763 } else {
12764 self.write_keyword("NO CYCLE");
12765 }
12766 }
12767
12768 if let Some(owned) = &als.owned_by {
12769 self.write_space();
12770 self.write_keyword("OWNED BY");
12771 self.write_space();
12772 if let Some(table) = owned {
12773 self.generate_table(table)?;
12774 } else {
12775 self.write_keyword("NONE");
12776 }
12777 }
12778
12779 Ok(())
12780 }
12781
12782 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
12783 self.write_keyword("CREATE");
12784
12785 if ct.or_replace {
12786 self.write_space();
12787 self.write_keyword("OR REPLACE");
12788 }
12789
12790 if ct.constraint {
12791 self.write_space();
12792 self.write_keyword("CONSTRAINT");
12793 }
12794
12795 self.write_space();
12796 self.write_keyword("TRIGGER");
12797 self.write_space();
12798 self.generate_identifier(&ct.name)?;
12799
12800 self.write_space();
12801 match ct.timing {
12802 TriggerTiming::Before => self.write_keyword("BEFORE"),
12803 TriggerTiming::After => self.write_keyword("AFTER"),
12804 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
12805 }
12806
12807 for (i, event) in ct.events.iter().enumerate() {
12809 if i > 0 {
12810 self.write_keyword(" OR");
12811 }
12812 self.write_space();
12813 match event {
12814 TriggerEvent::Insert => self.write_keyword("INSERT"),
12815 TriggerEvent::Update(cols) => {
12816 self.write_keyword("UPDATE");
12817 if let Some(cols) = cols {
12818 self.write_space();
12819 self.write_keyword("OF");
12820 for (j, col) in cols.iter().enumerate() {
12821 if j > 0 {
12822 self.write(",");
12823 }
12824 self.write_space();
12825 self.generate_identifier(col)?;
12826 }
12827 }
12828 }
12829 TriggerEvent::Delete => self.write_keyword("DELETE"),
12830 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
12831 }
12832 }
12833
12834 self.write_space();
12835 self.write_keyword("ON");
12836 self.write_space();
12837 self.generate_table(&ct.table)?;
12838
12839 if let Some(ref_clause) = &ct.referencing {
12841 self.write_space();
12842 self.write_keyword("REFERENCING");
12843 if let Some(old_table) = &ref_clause.old_table {
12844 self.write_space();
12845 self.write_keyword("OLD TABLE AS");
12846 self.write_space();
12847 self.generate_identifier(old_table)?;
12848 }
12849 if let Some(new_table) = &ref_clause.new_table {
12850 self.write_space();
12851 self.write_keyword("NEW TABLE AS");
12852 self.write_space();
12853 self.generate_identifier(new_table)?;
12854 }
12855 if let Some(old_row) = &ref_clause.old_row {
12856 self.write_space();
12857 self.write_keyword("OLD ROW AS");
12858 self.write_space();
12859 self.generate_identifier(old_row)?;
12860 }
12861 if let Some(new_row) = &ref_clause.new_row {
12862 self.write_space();
12863 self.write_keyword("NEW ROW AS");
12864 self.write_space();
12865 self.generate_identifier(new_row)?;
12866 }
12867 }
12868
12869 if let Some(deferrable) = ct.deferrable {
12871 self.write_space();
12872 if deferrable {
12873 self.write_keyword("DEFERRABLE");
12874 } else {
12875 self.write_keyword("NOT DEFERRABLE");
12876 }
12877 }
12878
12879 if let Some(initially) = ct.initially_deferred {
12880 self.write_space();
12881 self.write_keyword("INITIALLY");
12882 self.write_space();
12883 if initially {
12884 self.write_keyword("DEFERRED");
12885 } else {
12886 self.write_keyword("IMMEDIATE");
12887 }
12888 }
12889
12890 self.write_space();
12891 self.write_keyword("FOR EACH");
12892 self.write_space();
12893 match ct.for_each {
12894 TriggerForEach::Row => self.write_keyword("ROW"),
12895 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
12896 }
12897
12898 if let Some(when) = &ct.when {
12900 self.write_space();
12901 self.write_keyword("WHEN");
12902 self.write(" (");
12903 self.generate_expression(when)?;
12904 self.write(")");
12905 }
12906
12907 self.write_space();
12909 match &ct.body {
12910 TriggerBody::Execute { function, args } => {
12911 self.write_keyword("EXECUTE FUNCTION");
12912 self.write_space();
12913 self.generate_table(function)?;
12914 self.write("(");
12915 for (i, arg) in args.iter().enumerate() {
12916 if i > 0 {
12917 self.write(", ");
12918 }
12919 self.generate_expression(arg)?;
12920 }
12921 self.write(")");
12922 }
12923 TriggerBody::Block(block) => {
12924 self.write_keyword("BEGIN");
12925 self.write_space();
12926 self.write(block);
12927 self.write_space();
12928 self.write_keyword("END");
12929 }
12930 }
12931
12932 Ok(())
12933 }
12934
12935 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
12936 self.write_keyword("DROP TRIGGER");
12937
12938 if dt.if_exists {
12939 self.write_space();
12940 self.write_keyword("IF EXISTS");
12941 }
12942
12943 self.write_space();
12944 self.generate_identifier(&dt.name)?;
12945
12946 if let Some(table) = &dt.table {
12947 self.write_space();
12948 self.write_keyword("ON");
12949 self.write_space();
12950 self.generate_table(table)?;
12951 }
12952
12953 if dt.cascade {
12954 self.write_space();
12955 self.write_keyword("CASCADE");
12956 }
12957
12958 Ok(())
12959 }
12960
12961 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
12962 self.write_keyword("CREATE TYPE");
12963
12964 if ct.if_not_exists {
12965 self.write_space();
12966 self.write_keyword("IF NOT EXISTS");
12967 }
12968
12969 self.write_space();
12970 self.generate_table(&ct.name)?;
12971
12972 self.write_space();
12973 self.write_keyword("AS");
12974 self.write_space();
12975
12976 match &ct.definition {
12977 TypeDefinition::Enum(values) => {
12978 self.write_keyword("ENUM");
12979 self.write(" (");
12980 for (i, val) in values.iter().enumerate() {
12981 if i > 0 {
12982 self.write(", ");
12983 }
12984 self.write(&format!("'{}'", val));
12985 }
12986 self.write(")");
12987 }
12988 TypeDefinition::Composite(attrs) => {
12989 self.write("(");
12990 for (i, attr) in attrs.iter().enumerate() {
12991 if i > 0 {
12992 self.write(", ");
12993 }
12994 self.generate_identifier(&attr.name)?;
12995 self.write_space();
12996 self.generate_data_type(&attr.data_type)?;
12997 if let Some(collate) = &attr.collate {
12998 self.write_space();
12999 self.write_keyword("COLLATE");
13000 self.write_space();
13001 self.generate_identifier(collate)?;
13002 }
13003 }
13004 self.write(")");
13005 }
13006 TypeDefinition::Range {
13007 subtype,
13008 subtype_diff,
13009 canonical,
13010 } => {
13011 self.write_keyword("RANGE");
13012 self.write(" (");
13013 self.write_keyword("SUBTYPE");
13014 self.write(" = ");
13015 self.generate_data_type(subtype)?;
13016 if let Some(diff) = subtype_diff {
13017 self.write(", ");
13018 self.write_keyword("SUBTYPE_DIFF");
13019 self.write(" = ");
13020 self.write(diff);
13021 }
13022 if let Some(canon) = canonical {
13023 self.write(", ");
13024 self.write_keyword("CANONICAL");
13025 self.write(" = ");
13026 self.write(canon);
13027 }
13028 self.write(")");
13029 }
13030 TypeDefinition::Base {
13031 input,
13032 output,
13033 internallength,
13034 } => {
13035 self.write("(");
13036 self.write_keyword("INPUT");
13037 self.write(" = ");
13038 self.write(input);
13039 self.write(", ");
13040 self.write_keyword("OUTPUT");
13041 self.write(" = ");
13042 self.write(output);
13043 if let Some(len) = internallength {
13044 self.write(", ");
13045 self.write_keyword("INTERNALLENGTH");
13046 self.write(" = ");
13047 self.write(&len.to_string());
13048 }
13049 self.write(")");
13050 }
13051 TypeDefinition::Domain {
13052 base_type,
13053 default,
13054 constraints,
13055 } => {
13056 self.generate_data_type(base_type)?;
13057 if let Some(def) = default {
13058 self.write_space();
13059 self.write_keyword("DEFAULT");
13060 self.write_space();
13061 self.generate_expression(def)?;
13062 }
13063 for constr in constraints {
13064 self.write_space();
13065 if let Some(name) = &constr.name {
13066 self.write_keyword("CONSTRAINT");
13067 self.write_space();
13068 self.generate_identifier(name)?;
13069 self.write_space();
13070 }
13071 self.write_keyword("CHECK");
13072 self.write(" (");
13073 self.generate_expression(&constr.check)?;
13074 self.write(")");
13075 }
13076 }
13077 }
13078
13079 Ok(())
13080 }
13081
13082 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
13083 self.write_keyword("DROP TYPE");
13084
13085 if dt.if_exists {
13086 self.write_space();
13087 self.write_keyword("IF EXISTS");
13088 }
13089
13090 self.write_space();
13091 self.generate_table(&dt.name)?;
13092
13093 if dt.cascade {
13094 self.write_space();
13095 self.write_keyword("CASCADE");
13096 }
13097
13098 Ok(())
13099 }
13100
13101 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
13102 let saved_athena_hive_context = self.athena_hive_context;
13104 if matches!(
13105 self.config.dialect,
13106 Some(crate::dialects::DialectType::Athena)
13107 ) {
13108 self.athena_hive_context = true;
13109 }
13110
13111 for comment in &d.leading_comments {
13113 self.write_formatted_comment(comment);
13114 self.write(" ");
13115 }
13116
13117 self.write_keyword("DESCRIBE");
13118
13119 if d.extended {
13120 self.write_space();
13121 self.write_keyword("EXTENDED");
13122 } else if d.formatted {
13123 self.write_space();
13124 self.write_keyword("FORMATTED");
13125 }
13126
13127 if let Some(ref style) = d.style {
13129 self.write_space();
13130 self.write_keyword(style);
13131 }
13132
13133 let should_output_kind = match self.config.dialect {
13135 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
13137 false
13138 }
13139 Some(DialectType::Snowflake) => true,
13141 _ => d.kind.is_some(),
13142 };
13143 if should_output_kind {
13144 if let Some(ref kind) = d.kind {
13145 self.write_space();
13146 self.write_keyword(kind);
13147 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
13148 self.write_space();
13149 self.write_keyword("TABLE");
13150 }
13151 }
13152
13153 self.write_space();
13154 self.generate_expression(&d.target)?;
13155
13156 if let Some(ref partition) = d.partition {
13158 self.write_space();
13159 self.generate_expression(partition)?;
13160 }
13161
13162 if d.as_json {
13164 self.write_space();
13165 self.write_keyword("AS JSON");
13166 }
13167
13168 for (name, value) in &d.properties {
13170 self.write_space();
13171 self.write(name);
13172 self.write("=");
13173 self.write(value);
13174 }
13175
13176 self.athena_hive_context = saved_athena_hive_context;
13178
13179 Ok(())
13180 }
13181
13182 fn generate_show(&mut self, s: &Show) -> Result<()> {
13185 self.write_keyword("SHOW");
13186 self.write_space();
13187
13188 let show_terse = s.terse
13191 && !matches!(
13192 s.this.as_str(),
13193 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
13194 );
13195 if show_terse {
13196 self.write_keyword("TERSE");
13197 self.write_space();
13198 }
13199
13200 self.write_keyword(&s.this);
13202
13203 if let Some(ref target_expr) = s.target {
13205 self.write_space();
13206 self.generate_expression(target_expr)?;
13207 }
13208
13209 if s.history {
13211 self.write_space();
13212 self.write_keyword("HISTORY");
13213 }
13214
13215 if let Some(ref for_target) = s.for_target {
13217 self.write_space();
13218 self.write_keyword("FOR");
13219 self.write_space();
13220 self.generate_expression(for_target)?;
13221 }
13222
13223 use crate::dialects::DialectType;
13227 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
13228
13229 if !is_snowflake && s.from.is_some() {
13230 if let Some(ref scope_kind) = s.scope_kind {
13234 self.write_space();
13235 self.write_keyword("IN");
13236 self.write_space();
13237 self.write_keyword(scope_kind);
13238 if let Some(ref scope) = s.scope {
13239 self.write_space();
13240 self.generate_expression(scope)?;
13241 }
13242 } else if let Some(ref scope) = s.scope {
13243 self.write_space();
13244 self.write_keyword("IN");
13245 self.write_space();
13246 self.generate_expression(scope)?;
13247 }
13248
13249 if let Some(ref from) = s.from {
13251 self.write_space();
13252 self.write_keyword("FROM");
13253 self.write_space();
13254 self.generate_expression(from)?;
13255 }
13256
13257 if let Some(ref db) = s.db {
13259 self.write_space();
13260 self.write_keyword("FROM");
13261 self.write_space();
13262 self.generate_expression(db)?;
13263 }
13264
13265 if let Some(ref like) = s.like {
13267 self.write_space();
13268 self.write_keyword("LIKE");
13269 self.write_space();
13270 self.generate_expression(like)?;
13271 }
13272 } else {
13273 if let Some(ref like) = s.like {
13277 self.write_space();
13278 self.write_keyword("LIKE");
13279 self.write_space();
13280 self.generate_expression(like)?;
13281 }
13282
13283 if let Some(ref scope_kind) = s.scope_kind {
13285 self.write_space();
13286 self.write_keyword("IN");
13287 self.write_space();
13288 self.write_keyword(scope_kind);
13289 if let Some(ref scope) = s.scope {
13290 self.write_space();
13291 self.generate_expression(scope)?;
13292 }
13293 } else if let Some(ref scope) = s.scope {
13294 self.write_space();
13295 self.write_keyword("IN");
13296 self.write_space();
13297 self.generate_expression(scope)?;
13298 }
13299 }
13300
13301 if let Some(ref starts_with) = s.starts_with {
13303 self.write_space();
13304 self.write_keyword("STARTS WITH");
13305 self.write_space();
13306 self.generate_expression(starts_with)?;
13307 }
13308
13309 if let Some(ref limit) = s.limit {
13311 self.write_space();
13312 self.generate_limit(limit)?;
13313 }
13314
13315 if is_snowflake {
13317 if let Some(ref from) = s.from {
13318 self.write_space();
13319 self.write_keyword("FROM");
13320 self.write_space();
13321 self.generate_expression(from)?;
13322 }
13323 }
13324
13325 if let Some(ref where_clause) = s.where_clause {
13327 self.write_space();
13328 self.write_keyword("WHERE");
13329 self.write_space();
13330 self.generate_expression(where_clause)?;
13331 }
13332
13333 if let Some(is_mutex) = s.mutex {
13335 self.write_space();
13336 if is_mutex {
13337 self.write_keyword("MUTEX");
13338 } else {
13339 self.write_keyword("STATUS");
13340 }
13341 }
13342
13343 if !s.privileges.is_empty() {
13345 self.write_space();
13346 self.write_keyword("WITH PRIVILEGES");
13347 self.write_space();
13348 for (i, priv_name) in s.privileges.iter().enumerate() {
13349 if i > 0 {
13350 self.write(", ");
13351 }
13352 self.write_keyword(priv_name);
13353 }
13354 }
13355
13356 Ok(())
13357 }
13358
13359 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
13362 use crate::dialects::DialectType;
13363 match lit {
13364 Literal::String(s) => {
13365 self.generate_string_literal(s)?;
13366 }
13367 Literal::Number(n) => {
13368 if matches!(self.config.dialect, Some(DialectType::MySQL))
13369 && n.len() > 2
13370 && (n.starts_with("0x") || n.starts_with("0X"))
13371 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
13372 {
13373 return self.generate_identifier(&Identifier {
13374 name: n.clone(),
13375 quoted: true,
13376 trailing_comments: Vec::new(),
13377 });
13378 }
13379 let n = if n.contains('_')
13383 && !matches!(
13384 self.config.dialect,
13385 Some(DialectType::ClickHouse)
13386 | Some(DialectType::DuckDB)
13387 | Some(DialectType::PostgreSQL)
13388 | Some(DialectType::Hive)
13389 | Some(DialectType::Spark)
13390 | Some(DialectType::Databricks)
13391 ) {
13392 std::borrow::Cow::Owned(n.replace('_', ""))
13393 } else {
13394 std::borrow::Cow::Borrowed(n.as_str())
13395 };
13396 if n.starts_with('.') {
13399 self.write("0");
13400 self.write(&n);
13401 } else if n.starts_with("-.") {
13402 self.write("-0");
13404 self.write(&n[1..]);
13405 } else {
13406 self.write(&n);
13407 }
13408 }
13409 Literal::HexString(h) => {
13410 match self.config.dialect {
13412 Some(DialectType::Spark)
13413 | Some(DialectType::Databricks)
13414 | Some(DialectType::Teradata) => self.write("X'"),
13415 _ => self.write("x'"),
13416 }
13417 self.write(h);
13418 self.write("'");
13419 }
13420 Literal::HexNumber(h) => {
13421 match self.config.dialect {
13425 Some(DialectType::BigQuery)
13426 | Some(DialectType::TSQL)
13427 | Some(DialectType::Fabric) => {
13428 self.write("0x");
13429 self.write(h);
13430 }
13431 _ => {
13432 if let Ok(val) = u64::from_str_radix(h, 16) {
13434 self.write(&val.to_string());
13435 } else {
13436 self.write("0x");
13438 self.write(h);
13439 }
13440 }
13441 }
13442 }
13443 Literal::BitString(b) => {
13444 self.write("B'");
13446 self.write(b);
13447 self.write("'");
13448 }
13449 Literal::ByteString(b) => {
13450 self.write("b'");
13452 self.write_escaped_byte_string(b);
13454 self.write("'");
13455 }
13456 Literal::NationalString(s) => {
13457 let keep_n_prefix = matches!(
13460 self.config.dialect,
13461 Some(DialectType::TSQL)
13462 | Some(DialectType::Oracle)
13463 | Some(DialectType::MySQL)
13464 | None
13465 );
13466 if keep_n_prefix {
13467 self.write("N'");
13468 } else {
13469 self.write("'");
13470 }
13471 self.write(s);
13472 self.write("'");
13473 }
13474 Literal::Date(d) => {
13475 self.generate_date_literal(d)?;
13476 }
13477 Literal::Time(t) => {
13478 self.generate_time_literal(t)?;
13479 }
13480 Literal::Timestamp(ts) => {
13481 self.generate_timestamp_literal(ts)?;
13482 }
13483 Literal::Datetime(dt) => {
13484 self.generate_datetime_literal(dt)?;
13485 }
13486 Literal::TripleQuotedString(s, _quote_char) => {
13487 if matches!(
13489 self.config.dialect,
13490 Some(crate::dialects::DialectType::BigQuery)
13491 | Some(crate::dialects::DialectType::DuckDB)
13492 | Some(crate::dialects::DialectType::Snowflake)
13493 | Some(crate::dialects::DialectType::Spark)
13494 | Some(crate::dialects::DialectType::Hive)
13495 | Some(crate::dialects::DialectType::Presto)
13496 | Some(crate::dialects::DialectType::Trino)
13497 | Some(crate::dialects::DialectType::PostgreSQL)
13498 | Some(crate::dialects::DialectType::MySQL)
13499 | Some(crate::dialects::DialectType::Redshift)
13500 | Some(crate::dialects::DialectType::TSQL)
13501 | Some(crate::dialects::DialectType::Oracle)
13502 | Some(crate::dialects::DialectType::ClickHouse)
13503 | Some(crate::dialects::DialectType::Databricks)
13504 | Some(crate::dialects::DialectType::SQLite)
13505 ) {
13506 self.generate_string_literal(s)?;
13507 } else {
13508 let quotes = format!("{0}{0}{0}", _quote_char);
13510 self.write("es);
13511 self.write(s);
13512 self.write("es);
13513 }
13514 }
13515 Literal::EscapeString(s) => {
13516 use crate::dialects::DialectType;
13520 let content = if let Some(c) = s.strip_prefix("e:") {
13521 c
13522 } else if let Some(c) = s.strip_prefix("E:") {
13523 c
13524 } else {
13525 s.as_str()
13526 };
13527
13528 if matches!(
13530 self.config.dialect,
13531 Some(DialectType::MySQL) | Some(DialectType::TiDB)
13532 ) {
13533 self.write(content);
13534 } else {
13535 let prefix = if matches!(
13537 self.config.dialect,
13538 Some(DialectType::SingleStore)
13539 | Some(DialectType::DuckDB)
13540 | Some(DialectType::PostgreSQL)
13541 | Some(DialectType::CockroachDB)
13542 | Some(DialectType::Materialize)
13543 | Some(DialectType::RisingWave)
13544 ) {
13545 "e'"
13546 } else {
13547 "E'"
13548 };
13549
13550 let normalized = content.replace("\\'", "''");
13552 self.write(prefix);
13553 self.write(&normalized);
13554 self.write("'");
13555 }
13556 }
13557 Literal::DollarString(s) => {
13558 use crate::dialects::DialectType;
13561 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
13563 let escape_backslash = matches!(self.config.dialect, Some(DialectType::Snowflake));
13565 let use_backslash_quote =
13569 matches!(self.config.dialect, Some(DialectType::Snowflake));
13570
13571 let mut escaped = String::with_capacity(content.len() + 4);
13572 for ch in content.chars() {
13573 if escape_backslash && ch == '\\' {
13574 escaped.push('\\');
13576 escaped.push('\\');
13577 } else if ch == '\'' {
13578 if use_backslash_quote {
13579 escaped.push('\\');
13580 escaped.push('\'');
13581 } else {
13582 escaped.push('\'');
13583 escaped.push('\'');
13584 }
13585 } else {
13586 escaped.push(ch);
13587 }
13588 }
13589 self.write("'");
13590 self.write(&escaped);
13591 self.write("'");
13592 }
13593 Literal::RawString(s) => {
13594 use crate::dialects::DialectType;
13600
13601 let escape_backslash = matches!(
13603 self.config.dialect,
13604 Some(DialectType::BigQuery)
13605 | Some(DialectType::MySQL)
13606 | Some(DialectType::SingleStore)
13607 | Some(DialectType::TiDB)
13608 | Some(DialectType::Hive)
13609 | Some(DialectType::Spark)
13610 | Some(DialectType::Databricks)
13611 | Some(DialectType::Drill)
13612 | Some(DialectType::Snowflake)
13613 | Some(DialectType::Redshift)
13614 | Some(DialectType::ClickHouse)
13615 );
13616
13617 let backslash_escapes_quote = matches!(
13620 self.config.dialect,
13621 Some(DialectType::BigQuery)
13622 | Some(DialectType::Hive)
13623 | Some(DialectType::Spark)
13624 | Some(DialectType::Databricks)
13625 | Some(DialectType::Drill)
13626 | Some(DialectType::Snowflake)
13627 | Some(DialectType::Redshift)
13628 );
13629
13630 let supports_escape_sequences = escape_backslash;
13633
13634 let mut escaped = String::with_capacity(s.len() + 4);
13635 for ch in s.chars() {
13636 if escape_backslash && ch == '\\' {
13637 escaped.push('\\');
13639 escaped.push('\\');
13640 } else if ch == '\'' {
13641 if backslash_escapes_quote {
13642 escaped.push('\\');
13644 escaped.push('\'');
13645 } else {
13646 escaped.push('\'');
13648 escaped.push('\'');
13649 }
13650 } else if supports_escape_sequences {
13651 match ch {
13654 '\n' => {
13655 escaped.push('\\');
13656 escaped.push('n');
13657 }
13658 '\r' => {
13659 escaped.push('\\');
13660 escaped.push('r');
13661 }
13662 '\t' => {
13663 escaped.push('\\');
13664 escaped.push('t');
13665 }
13666 '\x07' => {
13667 escaped.push('\\');
13668 escaped.push('a');
13669 }
13670 '\x08' => {
13671 escaped.push('\\');
13672 escaped.push('b');
13673 }
13674 '\x0C' => {
13675 escaped.push('\\');
13676 escaped.push('f');
13677 }
13678 '\x0B' => {
13679 escaped.push('\\');
13680 escaped.push('v');
13681 }
13682 _ => escaped.push(ch),
13683 }
13684 } else {
13685 escaped.push(ch);
13686 }
13687 }
13688 self.write("'");
13689 self.write(&escaped);
13690 self.write("'");
13691 }
13692 }
13693 Ok(())
13694 }
13695
13696 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
13698 use crate::dialects::DialectType;
13699
13700 match self.config.dialect {
13701 Some(DialectType::TSQL) => {
13703 self.write("CAST('");
13704 self.write(d);
13705 self.write("' AS DATE)");
13706 }
13707 Some(DialectType::BigQuery) => {
13710 self.write("CAST('");
13711 self.write(d);
13712 self.write("' AS DATE)");
13713 }
13714 Some(DialectType::Exasol) => {
13717 self.write("CAST('");
13718 self.write(d);
13719 self.write("' AS DATE)");
13720 }
13721 Some(DialectType::Snowflake) => {
13724 self.write("CAST('");
13725 self.write(d);
13726 self.write("' AS DATE)");
13727 }
13728 Some(DialectType::PostgreSQL)
13730 | Some(DialectType::MySQL)
13731 | Some(DialectType::SingleStore)
13732 | Some(DialectType::TiDB)
13733 | Some(DialectType::Redshift) => {
13734 self.write("CAST('");
13735 self.write(d);
13736 self.write("' AS DATE)");
13737 }
13738 Some(DialectType::DuckDB)
13740 | Some(DialectType::Presto)
13741 | Some(DialectType::Trino)
13742 | Some(DialectType::Athena)
13743 | Some(DialectType::Spark)
13744 | Some(DialectType::Databricks)
13745 | Some(DialectType::Hive) => {
13746 self.write("CAST('");
13747 self.write(d);
13748 self.write("' AS DATE)");
13749 }
13750 Some(DialectType::Oracle) => {
13752 self.write("TO_DATE('");
13753 self.write(d);
13754 self.write("', 'YYYY-MM-DD')");
13755 }
13756 _ => {
13758 self.write_keyword("DATE");
13759 self.write(" '");
13760 self.write(d);
13761 self.write("'");
13762 }
13763 }
13764 Ok(())
13765 }
13766
13767 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
13769 use crate::dialects::DialectType;
13770
13771 match self.config.dialect {
13772 Some(DialectType::TSQL) => {
13774 self.write("CAST('");
13775 self.write(t);
13776 self.write("' AS TIME)");
13777 }
13778 _ => {
13780 self.write_keyword("TIME");
13781 self.write(" '");
13782 self.write(t);
13783 self.write("'");
13784 }
13785 }
13786 Ok(())
13787 }
13788
13789 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
13791 use crate::expressions::Literal;
13792
13793 match expr {
13794 Expression::Literal(Literal::Date(d)) => {
13795 self.write("CAST('");
13797 self.write(d);
13798 self.write("' AS DATE)");
13799 }
13800 _ => {
13801 self.generate_expression(expr)?;
13803 }
13804 }
13805 Ok(())
13806 }
13807
13808 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
13810 use crate::dialects::DialectType;
13811
13812 match self.config.dialect {
13813 Some(DialectType::TSQL) => {
13815 self.write("CAST('");
13816 self.write(ts);
13817 self.write("' AS DATETIME2)");
13818 }
13819 Some(DialectType::BigQuery) => {
13822 self.write("CAST('");
13823 self.write(ts);
13824 self.write("' AS TIMESTAMP)");
13825 }
13826 Some(DialectType::Snowflake) => {
13829 self.write("CAST('");
13830 self.write(ts);
13831 self.write("' AS TIMESTAMP)");
13832 }
13833 Some(DialectType::Dremio) => {
13836 self.write("CAST('");
13837 self.write(ts);
13838 self.write("' AS TIMESTAMP)");
13839 }
13840 Some(DialectType::Exasol) => {
13843 self.write("CAST('");
13844 self.write(ts);
13845 self.write("' AS TIMESTAMP)");
13846 }
13847 Some(DialectType::Oracle) => {
13850 self.write("TO_TIMESTAMP('");
13851 self.write(ts);
13852 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
13853 }
13854 Some(DialectType::Presto) | Some(DialectType::Trino) => {
13856 if Self::timestamp_has_timezone(ts) {
13857 self.write("CAST('");
13858 self.write(ts);
13859 self.write("' AS TIMESTAMP WITH TIME ZONE)");
13860 } else {
13861 self.write("CAST('");
13862 self.write(ts);
13863 self.write("' AS TIMESTAMP)");
13864 }
13865 }
13866 Some(DialectType::ClickHouse) => {
13868 self.write("CAST('");
13869 self.write(ts);
13870 self.write("' AS Nullable(DateTime))");
13871 }
13872 Some(DialectType::Spark) => {
13874 self.write("CAST('");
13875 self.write(ts);
13876 self.write("' AS TIMESTAMP)");
13877 }
13878 Some(DialectType::Redshift) => {
13881 if ts == "epoch" {
13882 self.write_keyword("TIMESTAMP");
13883 self.write(" '");
13884 self.write(ts);
13885 self.write("'");
13886 } else {
13887 self.write("CAST('");
13888 self.write(ts);
13889 self.write("' AS TIMESTAMP)");
13890 }
13891 }
13892 Some(DialectType::PostgreSQL)
13894 | Some(DialectType::Hive)
13895 | Some(DialectType::SQLite)
13896 | Some(DialectType::DuckDB)
13897 | Some(DialectType::Athena)
13898 | Some(DialectType::Drill)
13899 | Some(DialectType::Teradata) => {
13900 self.write("CAST('");
13901 self.write(ts);
13902 self.write("' AS TIMESTAMP)");
13903 }
13904 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
13906 self.write("CAST('");
13907 self.write(ts);
13908 self.write("' AS DATETIME)");
13909 }
13910 Some(DialectType::Databricks) => {
13912 self.write("CAST('");
13913 self.write(ts);
13914 self.write("' AS TIMESTAMP_NTZ)");
13915 }
13916 _ => {
13918 self.write_keyword("TIMESTAMP");
13919 self.write(" '");
13920 self.write(ts);
13921 self.write("'");
13922 }
13923 }
13924 Ok(())
13925 }
13926
13927 fn timestamp_has_timezone(ts: &str) -> bool {
13930 let ts_lower = ts.to_lowercase();
13934
13935 let continent_prefixes = [
13937 "africa/",
13938 "america/",
13939 "antarctica/",
13940 "arctic/",
13941 "asia/",
13942 "atlantic/",
13943 "australia/",
13944 "europe/",
13945 "indian/",
13946 "pacific/",
13947 "etc/",
13948 "brazil/",
13949 "canada/",
13950 "chile/",
13951 "mexico/",
13952 "us/",
13953 ];
13954
13955 for prefix in &continent_prefixes {
13956 if ts_lower.contains(prefix) {
13957 return true;
13958 }
13959 }
13960
13961 let tz_abbrevs = [
13964 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
13965 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
13966 " sgt", " aest", " aedt", " acst", " acdt", " awst",
13967 ];
13968
13969 for abbrev in &tz_abbrevs {
13970 if ts_lower.ends_with(abbrev) {
13971 return true;
13972 }
13973 }
13974
13975 let trimmed = ts.trim();
13979 if let Some(last_space) = trimmed.rfind(' ') {
13980 let suffix = &trimmed[last_space + 1..];
13981 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
13982 let rest = &suffix[1..];
13984 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
13985 return true;
13986 }
13987 }
13988 }
13989
13990 false
13991 }
13992
13993 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
13995 use crate::dialects::DialectType;
13996
13997 match self.config.dialect {
13998 Some(DialectType::BigQuery) => {
14001 self.write("CAST('");
14002 self.write(dt);
14003 self.write("' AS DATETIME)");
14004 }
14005 Some(DialectType::DuckDB) => {
14007 self.write("CAST('");
14008 self.write(dt);
14009 self.write("' AS TIMESTAMP)");
14010 }
14011 _ => {
14014 self.write_keyword("DATETIME");
14015 self.write(" '");
14016 self.write(dt);
14017 self.write("'");
14018 }
14019 }
14020 Ok(())
14021 }
14022
14023 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
14025 use crate::dialects::DialectType;
14026
14027 match self.config.dialect {
14028 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
14032 self.write("'");
14034 for c in s.chars() {
14035 match c {
14036 '\'' => self.write("\\'"),
14037 '\\' => self.write("\\\\"),
14038 '\n' => self.write("\\n"),
14039 '\r' => self.write("\\r"),
14040 '\t' => self.write("\\t"),
14041 '\0' => self.write("\\0"),
14042 _ => self.output.push(c),
14043 }
14044 }
14045 self.write("'");
14046 }
14047 Some(DialectType::Drill) => {
14048 self.write("'");
14051 for c in s.chars() {
14052 match c {
14053 '\'' => self.write("''"),
14054 '\\' => self.write("\\\\"),
14055 '\n' => self.write("\\n"),
14056 '\r' => self.write("\\r"),
14057 '\t' => self.write("\\t"),
14058 '\0' => self.write("\\0"),
14059 _ => self.output.push(c),
14060 }
14061 }
14062 self.write("'");
14063 }
14064 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
14065 self.write("'");
14066 for c in s.chars() {
14067 match c {
14068 '\'' => self.write("''"),
14070 '\\' => self.write("\\\\"),
14071 '\n' => self.write("\\n"),
14072 '\r' => self.write("\\r"),
14073 '\t' => self.write("\\t"),
14074 '\0' => self.output.push('\0'),
14076 _ => self.output.push(c),
14077 }
14078 }
14079 self.write("'");
14080 }
14081 Some(DialectType::BigQuery) => {
14083 self.write("'");
14084 for c in s.chars() {
14085 match c {
14086 '\'' => self.write("\\'"),
14087 '\\' => self.write("\\\\"),
14088 '\n' => self.write("\\n"),
14089 '\r' => self.write("\\r"),
14090 '\t' => self.write("\\t"),
14091 '\0' => self.write("\\0"),
14092 '\x07' => self.write("\\a"),
14093 '\x08' => self.write("\\b"),
14094 '\x0C' => self.write("\\f"),
14095 '\x0B' => self.write("\\v"),
14096 _ => self.output.push(c),
14097 }
14098 }
14099 self.write("'");
14100 }
14101 Some(DialectType::Athena) => {
14105 if self.athena_hive_context {
14106 self.write("'");
14108 for c in s.chars() {
14109 match c {
14110 '\'' => self.write("\\'"),
14111 '\\' => self.write("\\\\"),
14112 '\n' => self.write("\\n"),
14113 '\r' => self.write("\\r"),
14114 '\t' => self.write("\\t"),
14115 '\0' => self.write("\\0"),
14116 _ => self.output.push(c),
14117 }
14118 }
14119 self.write("'");
14120 } else {
14121 self.write("'");
14123 for c in s.chars() {
14124 match c {
14125 '\'' => self.write("''"),
14126 _ => self.output.push(c),
14128 }
14129 }
14130 self.write("'");
14131 }
14132 }
14133 Some(DialectType::Snowflake) => {
14138 self.write("'");
14139 for c in s.chars() {
14140 match c {
14141 '\'' => self.write("\\'"),
14142 '\n' => self.write("\\n"),
14145 '\r' => self.write("\\r"),
14146 '\t' => self.write("\\t"),
14147 _ => self.output.push(c),
14148 }
14149 }
14150 self.write("'");
14151 }
14152 Some(DialectType::PostgreSQL) => {
14154 self.write("'");
14155 for c in s.chars() {
14156 match c {
14157 '\'' => self.write("''"),
14158 _ => self.output.push(c),
14159 }
14160 }
14161 self.write("'");
14162 }
14163 Some(DialectType::Redshift) => {
14165 self.write("'");
14166 for c in s.chars() {
14167 match c {
14168 '\'' => self.write("\\'"),
14169 _ => self.output.push(c),
14170 }
14171 }
14172 self.write("'");
14173 }
14174 Some(DialectType::Oracle) => {
14176 self.write("'");
14177 self.write(&s.replace('\'', "''"));
14178 self.write("'");
14179 }
14180 Some(DialectType::ClickHouse) => {
14183 self.write("'");
14184 for c in s.chars() {
14185 match c {
14186 '\'' => self.write("''"),
14187 '\\' => self.write("\\\\"),
14188 '\n' => self.write("\\n"),
14189 '\r' => self.write("\\r"),
14190 '\t' => self.write("\\t"),
14191 '\0' => self.write("\\0"),
14192 '\x07' => self.write("\\a"),
14193 '\x08' => self.write("\\b"),
14194 '\x0C' => self.write("\\f"),
14195 '\x0B' => self.write("\\v"),
14196 c if c.is_control() || (c as u32) < 0x20 => {
14198 let byte = c as u32;
14199 if byte < 256 {
14200 self.write(&format!("\\x{:02X}", byte));
14201 } else {
14202 self.output.push(c);
14203 }
14204 }
14205 _ => self.output.push(c),
14206 }
14207 }
14208 self.write("'");
14209 }
14210 _ => {
14213 self.write("'");
14214 self.write(&s.replace('\'', "''"));
14215 self.write("'");
14216 }
14217 }
14218 Ok(())
14219 }
14220
14221 fn write_escaped_byte_string(&mut self, s: &str) {
14224 for c in s.chars() {
14225 match c {
14226 '\'' => self.write("\\'"),
14228 '\\' => self.write("\\\\"),
14230 _ if !c.is_control() => self.output.push(c),
14232 _ => {
14234 let byte = c as u32;
14235 if byte < 256 {
14236 self.write(&format!("\\x{:02x}", byte));
14237 } else {
14238 for b in c.to_string().as_bytes() {
14240 self.write(&format!("\\x{:02x}", b));
14241 }
14242 }
14243 }
14244 }
14245 }
14246 }
14247
14248 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
14249 use crate::dialects::DialectType;
14250
14251 match self.config.dialect {
14253 Some(DialectType::TSQL) => {
14256 self.write(if b.value { "1" } else { "0" });
14257 }
14258 Some(DialectType::Oracle) => {
14260 self.write(if b.value { "1" } else { "0" });
14261 }
14262 Some(DialectType::MySQL) => {
14264 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14265 }
14266 _ => {
14268 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14269 }
14270 }
14271 Ok(())
14272 }
14273
14274 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
14277 let name = &id.name;
14278 let quote_style = &self.config.identifier_quote_style;
14279
14280 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
14284
14285 let output_name = if self.config.normalize_identifiers && !id.quoted {
14287 name.to_lowercase()
14288 } else {
14289 name.to_string()
14290 };
14291
14292 if needs_quoting {
14293 let escaped_name = if quote_style.start == quote_style.end {
14295 output_name.replace(
14296 quote_style.end,
14297 &format!("{}{}", quote_style.end, quote_style.end),
14298 )
14299 } else {
14300 output_name.replace(
14301 quote_style.end,
14302 &format!("{}{}", quote_style.end, quote_style.end),
14303 )
14304 };
14305 self.write(&format!(
14306 "{}{}{}",
14307 quote_style.start, escaped_name, quote_style.end
14308 ));
14309 } else {
14310 self.write(&output_name);
14311 }
14312
14313 for comment in &id.trailing_comments {
14315 self.write(" ");
14316 self.write_formatted_comment(comment);
14317 }
14318 Ok(())
14319 }
14320
14321 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
14322 use crate::dialects::DialectType;
14323
14324 let name = &id.name;
14325
14326 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
14328 && self.athena_hive_context
14329 {
14330 &IdentifierQuoteStyle::BACKTICK
14331 } else {
14332 &self.config.identifier_quote_style
14333 };
14334
14335 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
14342 let needs_digit_quoting = starts_with_digit
14343 && !self.config.identifiers_can_start_with_digit
14344 && self.config.dialect.is_some();
14345 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
14346 && name.len() > 2
14347 && (name.starts_with("0x") || name.starts_with("0X"))
14348 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
14349 let needs_quoting = id.quoted
14350 || self.is_reserved_keyword(name)
14351 || self.config.always_quote_identifiers
14352 || needs_digit_quoting
14353 || mysql_invalid_hex_identifier;
14354
14355 let (base_name, suffix) = if needs_quoting {
14358 if let Some(paren_pos) = name.find('(') {
14360 let base = &name[..paren_pos];
14361 let rest = &name[paren_pos..];
14362 if rest.starts_with('(')
14364 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
14365 {
14366 let close_paren = rest.find(')').unwrap_or(rest.len());
14368 let inside = &rest[1..close_paren];
14369 if inside.chars().all(|c| c.is_ascii_digit()) {
14370 (base.to_string(), rest.to_string())
14371 } else {
14372 (name.to_string(), String::new())
14373 }
14374 } else {
14375 (name.to_string(), String::new())
14376 }
14377 } else if name.ends_with(" ASC") {
14378 let base = &name[..name.len() - 4];
14379 (base.to_string(), " ASC".to_string())
14380 } else if name.ends_with(" DESC") {
14381 let base = &name[..name.len() - 5];
14382 (base.to_string(), " DESC".to_string())
14383 } else {
14384 (name.to_string(), String::new())
14385 }
14386 } else {
14387 (name.to_string(), String::new())
14388 };
14389
14390 let output_name = if self.config.normalize_identifiers && !id.quoted {
14394 base_name.to_lowercase()
14395 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
14396 && !id.quoted
14397 && self.is_reserved_keyword(name)
14398 {
14399 base_name.to_uppercase()
14402 } else {
14403 base_name
14404 };
14405
14406 if needs_quoting {
14407 let escaped_name = if quote_style.start == quote_style.end {
14409 output_name.replace(
14411 quote_style.end,
14412 &format!("{}{}", quote_style.end, quote_style.end),
14413 )
14414 } else {
14415 output_name.replace(
14417 quote_style.end,
14418 &format!("{}{}", quote_style.end, quote_style.end),
14419 )
14420 };
14421 self.write(&format!(
14422 "{}{}{}{}",
14423 quote_style.start, escaped_name, quote_style.end, suffix
14424 ));
14425 } else {
14426 self.write(&output_name);
14427 }
14428
14429 for comment in &id.trailing_comments {
14431 self.write(" ");
14432 self.write_formatted_comment(comment);
14433 }
14434 Ok(())
14435 }
14436
14437 fn generate_column(&mut self, col: &Column) -> Result<()> {
14438 use crate::dialects::DialectType;
14439
14440 if let Some(table) = &col.table {
14441 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
14445 && !table.quoted
14446 && table.name.eq_ignore_ascii_case("LOCAL");
14447
14448 if is_exasol_local_prefix {
14449 self.write("LOCAL");
14451 } else {
14452 self.generate_identifier(table)?;
14453 }
14454 self.write(".");
14455 }
14456 self.generate_identifier(&col.name)?;
14457 if col.join_mark && self.config.supports_column_join_marks {
14460 self.write(" (+)");
14461 }
14462 for comment in &col.trailing_comments {
14464 self.write_space();
14465 self.write_formatted_comment(comment);
14466 }
14467 Ok(())
14468 }
14469
14470 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
14473 use crate::dialects::DialectType;
14474 use crate::expressions::PseudocolumnType;
14475
14476 if pc.kind == PseudocolumnType::Sysdate
14478 && !matches!(
14479 self.config.dialect,
14480 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
14481 )
14482 {
14483 self.write_keyword("CURRENT_TIMESTAMP");
14484 if matches!(
14486 self.config.dialect,
14487 Some(DialectType::MySQL)
14488 | Some(DialectType::ClickHouse)
14489 | Some(DialectType::Spark)
14490 | Some(DialectType::Databricks)
14491 | Some(DialectType::Hive)
14492 ) {
14493 self.write("()");
14494 }
14495 } else {
14496 self.write(pc.kind.as_str());
14497 }
14498 Ok(())
14499 }
14500
14501 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
14503 use crate::dialects::DialectType;
14504
14505 let supports_connect_by = matches!(
14508 self.config.dialect,
14509 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
14510 );
14511
14512 if !supports_connect_by && self.config.dialect.is_some() {
14513 if self.config.pretty {
14515 self.write_newline();
14516 } else {
14517 self.write_space();
14518 }
14519 self.write("/* CONNECT BY requires manual conversion to recursive CTE */");
14520 }
14521
14522 if let Some(start) = &connect.start {
14524 if self.config.pretty {
14525 self.write_newline();
14526 } else {
14527 self.write_space();
14528 }
14529 self.write_keyword("START WITH");
14530 self.write_space();
14531 self.generate_expression(start)?;
14532 }
14533
14534 if self.config.pretty {
14536 self.write_newline();
14537 } else {
14538 self.write_space();
14539 }
14540 self.write_keyword("CONNECT BY");
14541 if connect.nocycle {
14542 self.write_space();
14543 self.write_keyword("NOCYCLE");
14544 }
14545 self.write_space();
14546 self.generate_expression(&connect.connect)?;
14547
14548 Ok(())
14549 }
14550
14551 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
14553 self.generate_connect(connect)
14554 }
14555
14556 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
14558 self.write_keyword("PRIOR");
14559 self.write_space();
14560 self.generate_expression(&prior.this)?;
14561 Ok(())
14562 }
14563
14564 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
14567 self.write_keyword("CONNECT_BY_ROOT");
14568 self.write_space();
14569 self.generate_expression(&cbr.this)?;
14570 Ok(())
14571 }
14572
14573 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
14575 use crate::dialects::DialectType;
14576
14577 let supports_match_recognize = matches!(
14579 self.config.dialect,
14580 Some(DialectType::Oracle)
14581 | Some(DialectType::Snowflake)
14582 | Some(DialectType::Presto)
14583 | Some(DialectType::Trino)
14584 );
14585
14586 if let Some(source) = &mr.this {
14588 self.generate_expression(source)?;
14589 }
14590
14591 if !supports_match_recognize {
14592 self.write("/* MATCH_RECOGNIZE not supported in this dialect */");
14593 return Ok(());
14594 }
14595
14596 if self.config.pretty {
14598 self.write_newline();
14599 } else {
14600 self.write_space();
14601 }
14602
14603 self.write_keyword("MATCH_RECOGNIZE");
14604 self.write(" (");
14605
14606 if self.config.pretty {
14607 self.indent_level += 1;
14608 }
14609
14610 let mut needs_separator = false;
14611
14612 if let Some(partition_by) = &mr.partition_by {
14614 if !partition_by.is_empty() {
14615 if self.config.pretty {
14616 self.write_newline();
14617 self.write_indent();
14618 }
14619 self.write_keyword("PARTITION BY");
14620 self.write_space();
14621 for (i, expr) in partition_by.iter().enumerate() {
14622 if i > 0 {
14623 self.write(", ");
14624 }
14625 self.generate_expression(expr)?;
14626 }
14627 needs_separator = true;
14628 }
14629 }
14630
14631 if let Some(order_by) = &mr.order_by {
14633 if !order_by.is_empty() {
14634 if needs_separator {
14635 if self.config.pretty {
14636 self.write_newline();
14637 self.write_indent();
14638 } else {
14639 self.write_space();
14640 }
14641 } else if self.config.pretty {
14642 self.write_newline();
14643 self.write_indent();
14644 }
14645 self.write_keyword("ORDER BY");
14646 if self.config.pretty {
14648 self.indent_level += 1;
14649 for (i, ordered) in order_by.iter().enumerate() {
14650 if i > 0 {
14651 self.write(",");
14652 }
14653 self.write_newline();
14654 self.write_indent();
14655 self.generate_ordered(ordered)?;
14656 }
14657 self.indent_level -= 1;
14658 } else {
14659 self.write_space();
14660 for (i, ordered) in order_by.iter().enumerate() {
14661 if i > 0 {
14662 self.write(", ");
14663 }
14664 self.generate_ordered(ordered)?;
14665 }
14666 }
14667 needs_separator = true;
14668 }
14669 }
14670
14671 if let Some(measures) = &mr.measures {
14673 if !measures.is_empty() {
14674 if needs_separator {
14675 if self.config.pretty {
14676 self.write_newline();
14677 self.write_indent();
14678 } else {
14679 self.write_space();
14680 }
14681 } else if self.config.pretty {
14682 self.write_newline();
14683 self.write_indent();
14684 }
14685 self.write_keyword("MEASURES");
14686 if self.config.pretty {
14688 self.indent_level += 1;
14689 for (i, measure) in measures.iter().enumerate() {
14690 if i > 0 {
14691 self.write(",");
14692 }
14693 self.write_newline();
14694 self.write_indent();
14695 if let Some(semantics) = &measure.window_frame {
14697 match semantics {
14698 MatchRecognizeSemantics::Running => {
14699 self.write_keyword("RUNNING");
14700 self.write_space();
14701 }
14702 MatchRecognizeSemantics::Final => {
14703 self.write_keyword("FINAL");
14704 self.write_space();
14705 }
14706 }
14707 }
14708 self.generate_expression(&measure.this)?;
14709 }
14710 self.indent_level -= 1;
14711 } else {
14712 self.write_space();
14713 for (i, measure) in measures.iter().enumerate() {
14714 if i > 0 {
14715 self.write(", ");
14716 }
14717 if let Some(semantics) = &measure.window_frame {
14719 match semantics {
14720 MatchRecognizeSemantics::Running => {
14721 self.write_keyword("RUNNING");
14722 self.write_space();
14723 }
14724 MatchRecognizeSemantics::Final => {
14725 self.write_keyword("FINAL");
14726 self.write_space();
14727 }
14728 }
14729 }
14730 self.generate_expression(&measure.this)?;
14731 }
14732 }
14733 needs_separator = true;
14734 }
14735 }
14736
14737 if let Some(rows) = &mr.rows {
14739 if needs_separator {
14740 if self.config.pretty {
14741 self.write_newline();
14742 self.write_indent();
14743 } else {
14744 self.write_space();
14745 }
14746 } else if self.config.pretty {
14747 self.write_newline();
14748 self.write_indent();
14749 }
14750 match rows {
14751 MatchRecognizeRows::OneRowPerMatch => {
14752 self.write_keyword("ONE ROW PER MATCH");
14753 }
14754 MatchRecognizeRows::AllRowsPerMatch => {
14755 self.write_keyword("ALL ROWS PER MATCH");
14756 }
14757 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
14758 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
14759 }
14760 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
14761 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
14762 }
14763 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
14764 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
14765 }
14766 }
14767 needs_separator = true;
14768 }
14769
14770 if let Some(after) = &mr.after {
14772 if needs_separator {
14773 if self.config.pretty {
14774 self.write_newline();
14775 self.write_indent();
14776 } else {
14777 self.write_space();
14778 }
14779 } else if self.config.pretty {
14780 self.write_newline();
14781 self.write_indent();
14782 }
14783 match after {
14784 MatchRecognizeAfter::PastLastRow => {
14785 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
14786 }
14787 MatchRecognizeAfter::ToNextRow => {
14788 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
14789 }
14790 MatchRecognizeAfter::ToFirst(ident) => {
14791 self.write_keyword("AFTER MATCH SKIP TO FIRST");
14792 self.write_space();
14793 self.generate_identifier(ident)?;
14794 }
14795 MatchRecognizeAfter::ToLast(ident) => {
14796 self.write_keyword("AFTER MATCH SKIP TO LAST");
14797 self.write_space();
14798 self.generate_identifier(ident)?;
14799 }
14800 }
14801 needs_separator = true;
14802 }
14803
14804 if let Some(pattern) = &mr.pattern {
14806 if needs_separator {
14807 if self.config.pretty {
14808 self.write_newline();
14809 self.write_indent();
14810 } else {
14811 self.write_space();
14812 }
14813 } else if self.config.pretty {
14814 self.write_newline();
14815 self.write_indent();
14816 }
14817 self.write_keyword("PATTERN");
14818 self.write_space();
14819 self.write("(");
14820 self.write(pattern);
14821 self.write(")");
14822 needs_separator = true;
14823 }
14824
14825 if let Some(define) = &mr.define {
14827 if !define.is_empty() {
14828 if needs_separator {
14829 if self.config.pretty {
14830 self.write_newline();
14831 self.write_indent();
14832 } else {
14833 self.write_space();
14834 }
14835 } else if self.config.pretty {
14836 self.write_newline();
14837 self.write_indent();
14838 }
14839 self.write_keyword("DEFINE");
14840 if self.config.pretty {
14842 self.indent_level += 1;
14843 for (i, (name, expr)) in define.iter().enumerate() {
14844 if i > 0 {
14845 self.write(",");
14846 }
14847 self.write_newline();
14848 self.write_indent();
14849 self.generate_identifier(name)?;
14850 self.write(" AS ");
14851 self.generate_expression(expr)?;
14852 }
14853 self.indent_level -= 1;
14854 } else {
14855 self.write_space();
14856 for (i, (name, expr)) in define.iter().enumerate() {
14857 if i > 0 {
14858 self.write(", ");
14859 }
14860 self.generate_identifier(name)?;
14861 self.write(" AS ");
14862 self.generate_expression(expr)?;
14863 }
14864 }
14865 }
14866 }
14867
14868 if self.config.pretty {
14869 self.indent_level -= 1;
14870 self.write_newline();
14871 }
14872 self.write(")");
14873
14874 if let Some(alias) = &mr.alias {
14876 self.write(" ");
14877 if mr.alias_explicit_as {
14878 self.write_keyword("AS");
14879 self.write(" ");
14880 }
14881 self.generate_identifier(alias)?;
14882 }
14883
14884 Ok(())
14885 }
14886
14887 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
14889 use crate::dialects::DialectType;
14890
14891 let supports_hints = matches!(
14893 self.config.dialect,
14894 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
14896 Some(DialectType::Spark) | Some(DialectType::Hive) |
14897 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
14898 );
14899
14900 if !supports_hints || hint.expressions.is_empty() {
14901 return Ok(());
14902 }
14903
14904 let mut hint_strings: Vec<String> = Vec::new();
14907 for expr in &hint.expressions {
14908 match expr {
14909 HintExpression::Raw(text) => {
14910 let parsed = self.parse_raw_hint_text(text);
14912 hint_strings.extend(parsed);
14913 }
14914 _ => {
14915 hint_strings.push(self.hint_expression_to_string(expr)?);
14916 }
14917 }
14918 }
14919
14920 let use_multiline = self.config.pretty && hint_strings.len() > 1;
14924
14925 if use_multiline {
14926 self.write(" /*+ ");
14928 for (i, hint_str) in hint_strings.iter().enumerate() {
14929 if i > 0 {
14930 self.write_newline();
14931 self.write(" "); }
14933 self.write(hint_str);
14934 }
14935 self.write(" */");
14936 } else {
14937 self.write(" /*+ ");
14939 let sep = match self.config.dialect {
14940 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
14941 _ => " ",
14942 };
14943 for (i, hint_str) in hint_strings.iter().enumerate() {
14944 if i > 0 {
14945 self.write(sep);
14946 }
14947 self.write(hint_str);
14948 }
14949 self.write(" */");
14950 }
14951
14952 Ok(())
14953 }
14954
14955 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
14959 let mut results = Vec::new();
14960 let mut chars = text.chars().peekable();
14961 let mut current = String::new();
14962 let mut paren_depth = 0;
14963 let mut has_unparseable_content = false;
14964 let mut position_after_last_function = 0;
14965 let mut char_position = 0;
14966
14967 while let Some(c) = chars.next() {
14968 char_position += c.len_utf8();
14969 match c {
14970 '(' => {
14971 paren_depth += 1;
14972 current.push(c);
14973 }
14974 ')' => {
14975 paren_depth -= 1;
14976 current.push(c);
14977 if paren_depth == 0 {
14979 let trimmed = current.trim().to_string();
14980 if !trimmed.is_empty() {
14981 let formatted = self.format_hint_function(&trimmed);
14983 results.push(formatted);
14984 }
14985 current.clear();
14986 position_after_last_function = char_position;
14987 }
14988 }
14989 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
14990 }
14992 _ if paren_depth == 0 => {
14993 current.push(c);
14995 }
14996 _ => {
14997 current.push(c);
14998 }
14999 }
15000 }
15001
15002 let remaining_text = text[position_after_last_function..].trim();
15004 if !remaining_text.is_empty() {
15005 let words: Vec<&str> = remaining_text.split_whitespace().collect();
15009 let looks_like_hint_functions = words.iter().all(|word| {
15010 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
15012 });
15013
15014 if !looks_like_hint_functions && words.len() > 1 {
15015 has_unparseable_content = true;
15016 }
15017 }
15018
15019 if has_unparseable_content {
15021 return vec![text.trim().to_string()];
15022 }
15023
15024 if results.is_empty() {
15026 results.push(text.trim().to_string());
15027 }
15028
15029 results
15030 }
15031
15032 fn format_hint_function(&self, hint: &str) -> String {
15035 if !self.config.pretty {
15036 return hint.to_string();
15037 }
15038
15039 if let Some(paren_pos) = hint.find('(') {
15041 if hint.ends_with(')') {
15042 let name = &hint[..paren_pos];
15043 let args_str = &hint[paren_pos + 1..hint.len() - 1];
15044
15045 let args: Vec<&str> = args_str.split_whitespace().collect();
15047
15048 let total_args_width: usize =
15050 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() {
15054 let mut result = format!("{}(\n", name);
15055 for arg in &args {
15056 result.push_str(" "); result.push_str(arg);
15058 result.push('\n');
15059 }
15060 result.push_str(" )"); return result;
15062 }
15063 }
15064 }
15065
15066 hint.to_string()
15067 }
15068
15069 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
15071 match expr {
15072 HintExpression::Function { name, args } => {
15073 let arg_strings: Vec<String> = args
15075 .iter()
15076 .map(|arg| {
15077 let mut gen = Generator::with_config(self.config.clone());
15078 gen.generate_expression(arg)?;
15079 Ok(gen.output)
15080 })
15081 .collect::<Result<Vec<_>>>()?;
15082
15083 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
15085 + arg_strings.len().saturating_sub(1); let args_multiline =
15090 self.config.pretty && total_args_width > self.config.max_text_width;
15091
15092 if args_multiline && !arg_strings.is_empty() {
15093 let mut result = format!("{}(\n", name);
15095 for arg_str in &arg_strings {
15096 result.push_str(" "); result.push_str(arg_str);
15098 result.push('\n');
15099 }
15100 result.push_str(" )"); Ok(result)
15102 } else {
15103 let args_str = arg_strings.join(" ");
15105 Ok(format!("{}({})", name, args_str))
15106 }
15107 }
15108 HintExpression::Identifier(name) => Ok(name.clone()),
15109 HintExpression::Raw(text) => {
15110 if self.config.pretty {
15112 Ok(self.format_hint_function(text))
15113 } else {
15114 Ok(text.clone())
15115 }
15116 }
15117 }
15118 }
15119
15120 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
15121 if table.only {
15123 self.write_keyword("ONLY");
15124 self.write_space();
15125 }
15126
15127 if let Some(ref identifier_func) = table.identifier_func {
15129 self.generate_expression(identifier_func)?;
15130 } else {
15131 if let Some(catalog) = &table.catalog {
15132 self.generate_identifier(catalog)?;
15133 self.write(".");
15134 }
15135 if let Some(schema) = &table.schema {
15136 self.generate_identifier(schema)?;
15137 self.write(".");
15138 }
15139 self.generate_identifier(&table.name)?;
15140 }
15141
15142 if let Some(changes) = &table.changes {
15144 self.write(" ");
15145 self.generate_changes(changes)?;
15146 }
15147
15148 if !table.partitions.is_empty() {
15150 self.write_space();
15151 self.write_keyword("PARTITION");
15152 self.write("(");
15153 for (i, partition) in table.partitions.iter().enumerate() {
15154 if i > 0 {
15155 self.write(", ");
15156 }
15157 self.generate_identifier(partition)?;
15158 }
15159 self.write(")");
15160 }
15161
15162 if table.changes.is_none() {
15165 if let Some(when) = &table.when {
15166 self.write_space();
15167 self.generate_historical_data(when)?;
15168 }
15169 }
15170
15171 if let Some(ref system_time) = table.system_time {
15173 self.write_space();
15174 self.write(system_time);
15175 }
15176
15177 if let Some(ref version) = table.version {
15179 self.write_space();
15180 self.generate_version(version)?;
15181 }
15182
15183 let alias_post_tablesample = self.config.alias_post_tablesample;
15187
15188 if alias_post_tablesample {
15189 self.generate_table_sample_clause(table)?;
15191 }
15192
15193 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
15196 && table.hints.iter().any(|h| {
15197 if let Expression::Identifier(id) = h {
15198 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
15199 } else {
15200 false
15201 }
15202 });
15203 if !table.hints.is_empty() && !is_sqlite_hint {
15204 for hint in &table.hints {
15205 self.write_space();
15206 self.generate_expression(hint)?;
15207 }
15208 }
15209
15210 if let Some(alias) = &table.alias {
15211 self.write_space();
15212 let always_use_as = self.config.dialect.is_none()
15215 || matches!(
15216 self.config.dialect,
15217 Some(DialectType::Generic)
15218 | Some(DialectType::PostgreSQL)
15219 | Some(DialectType::Redshift)
15220 | Some(DialectType::Snowflake)
15221 | Some(DialectType::BigQuery)
15222 | Some(DialectType::Presto)
15223 | Some(DialectType::Trino)
15224 | Some(DialectType::TSQL)
15225 | Some(DialectType::Fabric)
15226 | Some(DialectType::MySQL)
15227 | Some(DialectType::Spark)
15228 | Some(DialectType::Hive)
15229 | Some(DialectType::SQLite)
15230 | Some(DialectType::Drill)
15231 );
15232 let is_stage_ref = table.name.name.starts_with('@');
15233 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
15235 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
15236 self.write_keyword("AS");
15237 self.write_space();
15238 }
15239 self.generate_identifier(alias)?;
15240
15241 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
15244 self.write("(");
15245 for (i, col_alias) in table.column_aliases.iter().enumerate() {
15246 if i > 0 {
15247 self.write(", ");
15248 }
15249 self.generate_identifier(col_alias)?;
15250 }
15251 self.write(")");
15252 }
15253 }
15254
15255 if !alias_post_tablesample {
15257 self.generate_table_sample_clause(table)?;
15258 }
15259
15260 if is_sqlite_hint {
15262 for hint in &table.hints {
15263 self.write_space();
15264 self.generate_expression(hint)?;
15265 }
15266 }
15267
15268 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
15270 self.write_space();
15271 self.write_keyword("FINAL");
15272 }
15273
15274 for comment in &table.trailing_comments {
15276 self.write_space();
15277 self.write_formatted_comment(comment);
15278 }
15279
15280 Ok(())
15281 }
15282
15283 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
15285 if let Some(ref ts) = table.table_sample {
15286 self.write_space();
15287 if ts.is_using_sample {
15288 self.write_keyword("USING SAMPLE");
15289 } else {
15290 self.write_keyword(self.config.tablesample_keywords);
15292 }
15293 self.generate_sample_body(ts)?;
15294 if let Some(ref seed) = ts.seed {
15296 self.write_space();
15297 self.write_keyword(self.config.tablesample_seed_keyword);
15298 self.write(" (");
15299 self.generate_expression(seed)?;
15300 self.write(")");
15301 }
15302 }
15303 Ok(())
15304 }
15305
15306 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
15307 if sr.quoted {
15311 self.write("'");
15312 }
15313
15314 self.write(&sr.name);
15315 if let Some(path) = &sr.path {
15316 self.write(path);
15317 }
15318
15319 if sr.quoted {
15320 self.write("'");
15321 }
15322
15323 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
15325 if has_options {
15326 self.write(" (");
15327 let mut first = true;
15328
15329 if let Some(file_format) = &sr.file_format {
15330 if !first {
15331 self.write(", ");
15332 }
15333 self.write_keyword("FILE_FORMAT");
15334 self.write(" => ");
15335 self.generate_expression(file_format)?;
15336 first = false;
15337 }
15338
15339 if let Some(pattern) = &sr.pattern {
15340 if !first {
15341 self.write(", ");
15342 }
15343 self.write_keyword("PATTERN");
15344 self.write(" => '");
15345 self.write(pattern);
15346 self.write("'");
15347 }
15348
15349 self.write(")");
15350 }
15351 Ok(())
15352 }
15353
15354 fn generate_star(&mut self, star: &Star) -> Result<()> {
15355 use crate::dialects::DialectType;
15356
15357 if let Some(table) = &star.table {
15358 self.generate_identifier(table)?;
15359 self.write(".");
15360 }
15361 self.write("*");
15362
15363 if let Some(except) = &star.except {
15365 if !except.is_empty() {
15366 self.write_space();
15367 match self.config.dialect {
15369 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
15370 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
15371 self.write_keyword("EXCLUDE")
15372 }
15373 _ => self.write_keyword("EXCEPT"), }
15375 self.write(" (");
15376 for (i, col) in except.iter().enumerate() {
15377 if i > 0 {
15378 self.write(", ");
15379 }
15380 self.generate_identifier(col)?;
15381 }
15382 self.write(")");
15383 }
15384 }
15385
15386 if let Some(replace) = &star.replace {
15388 if !replace.is_empty() {
15389 self.write_space();
15390 self.write_keyword("REPLACE");
15391 self.write(" (");
15392 for (i, alias) in replace.iter().enumerate() {
15393 if i > 0 {
15394 self.write(", ");
15395 }
15396 self.generate_expression(&alias.this)?;
15397 self.write_space();
15398 self.write_keyword("AS");
15399 self.write_space();
15400 self.generate_identifier(&alias.alias)?;
15401 }
15402 self.write(")");
15403 }
15404 }
15405
15406 if let Some(rename) = &star.rename {
15408 if !rename.is_empty() {
15409 self.write_space();
15410 self.write_keyword("RENAME");
15411 self.write(" (");
15412 for (i, (old_name, new_name)) in rename.iter().enumerate() {
15413 if i > 0 {
15414 self.write(", ");
15415 }
15416 self.generate_identifier(old_name)?;
15417 self.write_space();
15418 self.write_keyword("AS");
15419 self.write_space();
15420 self.generate_identifier(new_name)?;
15421 }
15422 self.write(")");
15423 }
15424 }
15425
15426 for comment in &star.trailing_comments {
15428 self.write_space();
15429 self.write_formatted_comment(comment);
15430 }
15431
15432 Ok(())
15433 }
15434
15435 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
15437 self.write("{");
15438 match expr {
15439 Expression::Star(star) => {
15440 self.generate_star(star)?;
15442 }
15443 Expression::ILike(ilike) => {
15444 self.generate_expression(&ilike.left)?;
15446 self.write_space();
15447 self.write_keyword("ILIKE");
15448 self.write_space();
15449 self.generate_expression(&ilike.right)?;
15450 }
15451 _ => {
15452 self.generate_expression(expr)?;
15453 }
15454 }
15455 self.write("}");
15456 Ok(())
15457 }
15458
15459 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
15460 match &alias.this {
15464 Expression::Column(col) => {
15465 if let Some(table) = &col.table {
15467 self.generate_identifier(table)?;
15468 self.write(".");
15469 }
15470 self.generate_identifier(&col.name)?;
15471 }
15472 _ => {
15473 self.generate_expression(&alias.this)?;
15474 }
15475 }
15476
15477 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
15481 for comment in &alias.pre_alias_comments {
15482 self.write_space();
15483 self.write_formatted_comment(comment);
15484 }
15485 }
15486
15487 use crate::dialects::DialectType;
15488
15489 let is_table_source = matches!(
15495 &alias.this,
15496 Expression::JSONTable(_)
15497 | Expression::XMLTable(_)
15498 | Expression::TableFromRows(_)
15499 | Expression::Unnest(_)
15500 | Expression::MatchRecognize(_)
15501 | Expression::Select(_)
15502 | Expression::Subquery(_)
15503 | Expression::Paren(_)
15504 );
15505 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
15506 let skip_as = is_table_source && dialect_skips_table_alias_as;
15507
15508 self.write_space();
15509 if !skip_as {
15510 self.write_keyword("AS");
15511 self.write_space();
15512 }
15513
15514 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
15516
15517 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
15519 self.write("(");
15521 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
15522 if i > 0 {
15523 self.write(", ");
15524 }
15525 self.generate_alias_identifier(col_alias)?;
15526 }
15527 self.write(")");
15528 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
15529 self.generate_alias_identifier(&alias.alias)?;
15531 self.write("(");
15532 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
15533 if i > 0 {
15534 self.write(", ");
15535 }
15536 self.generate_alias_identifier(col_alias)?;
15537 }
15538 self.write(")");
15539 } else {
15540 self.generate_alias_identifier(&alias.alias)?;
15542 }
15543
15544 for comment in &alias.trailing_comments {
15546 self.write_space();
15547 self.write_formatted_comment(comment);
15548 }
15549
15550 if alias.trailing_comments.is_empty() {
15555 for comment in &alias.pre_alias_comments {
15556 self.write_space();
15557 self.write_formatted_comment(comment);
15558 }
15559 }
15560
15561 Ok(())
15562 }
15563
15564 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
15565 use crate::dialects::DialectType;
15566
15567 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
15569 self.generate_expression(&cast.this)?;
15570 self.write(" :> ");
15571 self.generate_data_type(&cast.to)?;
15572 return Ok(());
15573 }
15574
15575 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
15577 let is_unknown_type = matches!(cast.to, DataType::Unknown)
15578 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
15579 if is_unknown_type {
15580 if let Some(format) = &cast.format {
15581 self.write_keyword("CAST");
15582 self.write("(");
15583 self.generate_expression(&cast.this)?;
15584 self.write_space();
15585 self.write_keyword("AS");
15586 self.write_space();
15587 self.write_keyword("FORMAT");
15588 self.write_space();
15589 self.generate_expression(format)?;
15590 self.write(")");
15591 return Ok(());
15592 }
15593 }
15594 }
15595
15596 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
15599 if let Some(format) = &cast.format {
15600 let is_date = matches!(cast.to, DataType::Date);
15602 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
15603
15604 if is_date || is_timestamp {
15605 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
15606 self.write_keyword(func_name);
15607 self.write("(");
15608 self.generate_expression(&cast.this)?;
15609 self.write(", ");
15610
15611 if let Expression::Literal(Literal::String(fmt_str)) = format.as_ref() {
15614 let normalized = self.normalize_oracle_format(fmt_str);
15615 self.write("'");
15616 self.write(&normalized);
15617 self.write("'");
15618 } else {
15619 self.generate_expression(format)?;
15620 }
15621
15622 self.write(")");
15623 return Ok(());
15624 }
15625 }
15626 }
15627
15628 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
15631 if let Expression::Array(arr) = &cast.this {
15632 self.generate_data_type(&cast.to)?;
15633 self.write("[");
15635 for (i, expr) in arr.expressions.iter().enumerate() {
15636 if i > 0 {
15637 self.write(", ");
15638 }
15639 self.generate_expression(expr)?;
15640 }
15641 self.write("]");
15642 return Ok(());
15643 }
15644 if matches!(&cast.this, Expression::ArrayFunc(_)) {
15645 self.generate_data_type(&cast.to)?;
15646 self.generate_expression(&cast.this)?;
15647 return Ok(());
15648 }
15649 }
15650
15651 if matches!(
15654 self.config.dialect,
15655 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
15656 ) {
15657 if let Expression::Struct(ref s) = cast.this {
15658 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
15659 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
15660 self.write_keyword("CAST");
15661 self.write("(");
15662 self.generate_struct_as_row(s)?;
15663 self.write_space();
15664 self.write_keyword("AS");
15665 self.write_space();
15666 self.generate_data_type(&cast.to)?;
15667 self.write(")");
15668 return Ok(());
15669 }
15670 }
15671 }
15672
15673 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
15676
15677 if use_double_colon {
15678 self.generate_expression(&cast.this)?;
15680 self.write("::");
15681 self.generate_data_type(&cast.to)?;
15682 } else {
15683 self.write_keyword("CAST");
15685 self.write("(");
15686 self.generate_expression(&cast.this)?;
15687 self.write_space();
15688 self.write_keyword("AS");
15689 self.write_space();
15690 if matches!(
15693 self.config.dialect,
15694 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
15695 ) {
15696 match &cast.to {
15697 DataType::Custom { ref name } => {
15698 let upper = name.to_uppercase();
15699 match upper.as_str() {
15700 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" | "LONGBLOB" | "MEDIUMBLOB"
15701 | "TINYBLOB" => {
15702 self.write_keyword("CHAR");
15703 }
15704 _ => {
15705 self.generate_data_type(&cast.to)?;
15706 }
15707 }
15708 }
15709 DataType::VarChar { length, .. } => {
15710 self.write_keyword("CHAR");
15712 if let Some(n) = length {
15713 self.write(&format!("({})", n));
15714 }
15715 }
15716 DataType::Text => {
15717 self.write_keyword("CHAR");
15719 }
15720 DataType::Timestamp {
15721 precision,
15722 timezone: false,
15723 } => {
15724 self.write_keyword("DATETIME");
15726 if let Some(p) = precision {
15727 self.write(&format!("({})", p));
15728 }
15729 }
15730 _ => {
15731 self.generate_data_type(&cast.to)?;
15732 }
15733 }
15734 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
15735 match &cast.to {
15737 DataType::String { length } => {
15738 self.write_keyword("VARCHAR");
15739 if let Some(n) = length {
15740 self.write(&format!("({})", n));
15741 }
15742 }
15743 _ => {
15744 self.generate_data_type(&cast.to)?;
15745 }
15746 }
15747 } else {
15748 self.generate_data_type(&cast.to)?;
15749 }
15750
15751 if let Some(default) = &cast.default {
15753 self.write_space();
15754 self.write_keyword("DEFAULT");
15755 self.write_space();
15756 self.generate_expression(default)?;
15757 self.write_space();
15758 self.write_keyword("ON");
15759 self.write_space();
15760 self.write_keyword("CONVERSION");
15761 self.write_space();
15762 self.write_keyword("ERROR");
15763 }
15764
15765 if let Some(format) = &cast.format {
15768 if matches!(
15770 self.config.dialect,
15771 Some(crate::dialects::DialectType::Oracle)
15772 ) {
15773 self.write(", ");
15774 } else {
15775 self.write_space();
15776 self.write_keyword("FORMAT");
15777 self.write_space();
15778 }
15779 self.generate_expression(format)?;
15780 }
15781
15782 self.write(")");
15783 for comment in &cast.trailing_comments {
15785 self.write_space();
15786 self.write_formatted_comment(comment);
15787 }
15788 }
15789 Ok(())
15790 }
15791
15792 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
15795 self.write_keyword("ROW");
15796 self.write("(");
15797 for (i, (_, expr)) in s.fields.iter().enumerate() {
15798 if i > 0 {
15799 self.write(", ");
15800 }
15801 if let Expression::Struct(ref inner_s) = expr {
15803 self.generate_struct_as_row(inner_s)?;
15804 } else {
15805 self.generate_expression(expr)?;
15806 }
15807 }
15808 self.write(")");
15809 Ok(())
15810 }
15811
15812 fn normalize_oracle_format(&self, format: &str) -> String {
15815 let mut result = String::new();
15818 let chars: Vec<char> = format.chars().collect();
15819 let mut i = 0;
15820
15821 while i < chars.len() {
15822 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
15823 if i + 2 < chars.len() {
15825 let next = chars[i + 2];
15826 if next == '1' || next == '2' {
15827 result.push('H');
15829 result.push('H');
15830 i += 2;
15831 continue;
15832 }
15833 }
15834 result.push_str("HH12");
15836 i += 2;
15837 } else {
15838 result.push(chars[i]);
15839 i += 1;
15840 }
15841 }
15842
15843 result
15844 }
15845
15846 fn dialect_prefers_double_colon(&self) -> bool {
15850 false
15853 }
15854
15855 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15857 use crate::dialects::DialectType;
15858
15859 let use_percent_operator = matches!(
15861 self.config.dialect,
15862 Some(DialectType::Snowflake)
15863 | Some(DialectType::MySQL)
15864 | Some(DialectType::Presto)
15865 | Some(DialectType::Trino)
15866 | Some(DialectType::PostgreSQL)
15867 | Some(DialectType::DuckDB)
15868 | Some(DialectType::Hive)
15869 | Some(DialectType::Spark)
15870 | Some(DialectType::Databricks)
15871 | Some(DialectType::Athena)
15872 );
15873
15874 if use_percent_operator {
15875 let needs_paren = |e: &Expression| matches!(e, Expression::Add(_) | Expression::Sub(_));
15878 if needs_paren(&f.this) {
15879 self.write("(");
15880 self.generate_expression(&f.this)?;
15881 self.write(")");
15882 } else {
15883 self.generate_expression(&f.this)?;
15884 }
15885 self.write(" % ");
15886 if needs_paren(&f.expression) {
15887 self.write("(");
15888 self.generate_expression(&f.expression)?;
15889 self.write(")");
15890 } else {
15891 self.generate_expression(&f.expression)?;
15892 }
15893 Ok(())
15894 } else {
15895 self.generate_binary_func("MOD", &f.this, &f.expression)
15896 }
15897 }
15898
15899 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15901 use crate::dialects::DialectType;
15902
15903 let func_name = match self.config.dialect {
15905 Some(DialectType::Snowflake) => "COALESCE",
15906 _ => "IFNULL",
15907 };
15908
15909 self.generate_binary_func(func_name, &f.this, &f.expression)
15910 }
15911
15912 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15914 if let Some(ref original_name) = f.original_name {
15916 return self.generate_binary_func(original_name, &f.this, &f.expression);
15917 }
15918
15919 use crate::dialects::DialectType;
15921 let func_name = match self.config.dialect {
15922 Some(DialectType::Snowflake)
15923 | Some(DialectType::ClickHouse)
15924 | Some(DialectType::PostgreSQL)
15925 | Some(DialectType::Presto)
15926 | Some(DialectType::Trino)
15927 | Some(DialectType::Athena)
15928 | Some(DialectType::DuckDB)
15929 | Some(DialectType::BigQuery)
15930 | Some(DialectType::Spark)
15931 | Some(DialectType::Databricks)
15932 | Some(DialectType::Hive) => "COALESCE",
15933 Some(DialectType::MySQL)
15934 | Some(DialectType::Doris)
15935 | Some(DialectType::StarRocks)
15936 | Some(DialectType::SingleStore)
15937 | Some(DialectType::TiDB) => "IFNULL",
15938 _ => "NVL",
15939 };
15940
15941 self.generate_binary_func(func_name, &f.this, &f.expression)
15942 }
15943
15944 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
15946 use crate::dialects::DialectType;
15947
15948 let func_name = match self.config.dialect {
15950 Some(DialectType::Snowflake) => "STDDEV",
15951 _ => "STDDEV_SAMP",
15952 };
15953
15954 self.generate_agg_func(func_name, f)
15955 }
15956
15957 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
15958 self.generate_expression(&coll.this)?;
15959 self.write_space();
15960 self.write_keyword("COLLATE");
15961 self.write_space();
15962 if coll.quoted {
15963 self.write("'");
15965 self.write(&coll.collation);
15966 self.write("'");
15967 } else if coll.double_quoted {
15968 self.write("\"");
15970 self.write(&coll.collation);
15971 self.write("\"");
15972 } else {
15973 self.write(&coll.collation);
15975 }
15976 Ok(())
15977 }
15978
15979 fn generate_case(&mut self, case: &Case) -> Result<()> {
15980 let multiline_case = if self.config.pretty {
15982 let mut statements: Vec<String> = Vec::new();
15984 let operand_str = if let Some(operand) = &case.operand {
15985 let s = self.generate_to_string(operand)?;
15986 statements.push(format!("CASE {}", s));
15987 s
15988 } else {
15989 statements.push("CASE".to_string());
15990 String::new()
15991 };
15992 let _ = operand_str;
15993 for (condition, result) in &case.whens {
15994 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
15995 statements.push(format!("THEN {}", self.generate_to_string(result)?));
15996 }
15997 if let Some(else_) = &case.else_ {
15998 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
15999 }
16000 statements.push("END".to_string());
16001 self.too_wide(&statements)
16002 } else {
16003 false
16004 };
16005
16006 self.write_keyword("CASE");
16007 if let Some(operand) = &case.operand {
16008 self.write_space();
16009 self.generate_expression(operand)?;
16010 }
16011 if multiline_case {
16012 self.indent_level += 1;
16013 }
16014 for (condition, result) in &case.whens {
16015 if multiline_case {
16016 self.write_newline();
16017 self.write_indent();
16018 } else {
16019 self.write_space();
16020 }
16021 self.write_keyword("WHEN");
16022 self.write_space();
16023 self.generate_expression(condition)?;
16024 if multiline_case {
16025 self.write_newline();
16026 self.write_indent();
16027 } else {
16028 self.write_space();
16029 }
16030 self.write_keyword("THEN");
16031 self.write_space();
16032 self.generate_expression(result)?;
16033 }
16034 if let Some(else_) = &case.else_ {
16035 if multiline_case {
16036 self.write_newline();
16037 self.write_indent();
16038 } else {
16039 self.write_space();
16040 }
16041 self.write_keyword("ELSE");
16042 self.write_space();
16043 self.generate_expression(else_)?;
16044 }
16045 if multiline_case {
16046 self.indent_level -= 1;
16047 self.write_newline();
16048 self.write_indent();
16049 } else {
16050 self.write_space();
16051 }
16052 self.write_keyword("END");
16053 for comment in &case.comments {
16055 self.write(" ");
16056 self.write_formatted_comment(comment);
16057 }
16058 Ok(())
16059 }
16060
16061 fn generate_function(&mut self, func: &Function) -> Result<()> {
16062 let normalized_name = self.normalize_func_name(&func.name);
16064 let upper_name = func.name.to_uppercase();
16065
16066 if matches!(self.config.dialect, Some(DialectType::DuckDB))
16068 && upper_name == "ARRAY_CONSTRUCT_COMPACT"
16069 {
16070 self.write("LIST_FILTER(");
16071 self.write("[");
16072 for (i, arg) in func.args.iter().enumerate() {
16073 if i > 0 {
16074 self.write(", ");
16075 }
16076 self.generate_expression(arg)?;
16077 }
16078 self.write("], _u -> NOT _u IS NULL)");
16079 return Ok(());
16080 }
16081
16082 if upper_name == "STRUCT"
16084 && !matches!(
16085 self.config.dialect,
16086 Some(DialectType::BigQuery)
16087 | Some(DialectType::Spark)
16088 | Some(DialectType::Databricks)
16089 | Some(DialectType::Hive)
16090 | None
16091 )
16092 {
16093 return self.generate_struct_function_cross_dialect(func);
16094 }
16095
16096 if upper_name == "__SS_JSON_PATH_QMARK__" && func.args.len() == 2 {
16099 self.generate_expression(&func.args[0])?;
16100 self.write("::?");
16101 if let Expression::Literal(crate::expressions::Literal::String(key)) = &func.args[1] {
16103 self.write(key);
16104 } else {
16105 self.generate_expression(&func.args[1])?;
16106 }
16107 return Ok(());
16108 }
16109
16110 if upper_name == "__PG_BITWISE_XOR__" && func.args.len() == 2 {
16112 self.generate_expression(&func.args[0])?;
16113 self.write(" # ");
16114 self.generate_expression(&func.args[1])?;
16115 return Ok(());
16116 }
16117
16118 if matches!(
16120 self.config.dialect,
16121 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
16122 ) && upper_name == "TRY"
16123 && func.args.len() == 1
16124 {
16125 self.generate_expression(&func.args[0])?;
16126 return Ok(());
16127 }
16128
16129 if self.config.dialect == Some(DialectType::ClickHouse)
16131 && upper_name == "TOSTARTOFDAY"
16132 && func.args.len() == 1
16133 {
16134 self.write("dateTrunc('DAY', ");
16135 self.generate_expression(&func.args[0])?;
16136 self.write(")");
16137 return Ok(());
16138 }
16139
16140 if self.config.dialect == Some(DialectType::Redshift)
16142 && upper_name == "CONCAT"
16143 && func.args.len() >= 2
16144 {
16145 for (i, arg) in func.args.iter().enumerate() {
16146 if i > 0 {
16147 self.write(" || ");
16148 }
16149 self.generate_expression(arg)?;
16150 }
16151 return Ok(());
16152 }
16153
16154 if self.config.dialect == Some(DialectType::Redshift)
16156 && upper_name == "CONCAT_WS"
16157 && func.args.len() >= 2
16158 {
16159 let sep = &func.args[0];
16160 for (i, arg) in func.args.iter().skip(1).enumerate() {
16161 if i > 0 {
16162 self.write(" || ");
16163 self.generate_expression(sep)?;
16164 self.write(" || ");
16165 }
16166 self.generate_expression(arg)?;
16167 }
16168 return Ok(());
16169 }
16170
16171 if self.config.dialect == Some(DialectType::Redshift)
16174 && (upper_name == "DATEDIFF" || upper_name == "DATE_DIFF")
16175 && func.args.len() == 3
16176 {
16177 self.write_keyword("DATEDIFF");
16178 self.write("(");
16179 self.write_redshift_date_part(&func.args[0]);
16181 self.write(", ");
16182 self.generate_expression(&func.args[1])?;
16183 self.write(", ");
16184 self.generate_expression(&func.args[2])?;
16185 self.write(")");
16186 return Ok(());
16187 }
16188
16189 if self.config.dialect == Some(DialectType::Redshift)
16192 && (upper_name == "DATEADD" || upper_name == "DATE_ADD")
16193 && func.args.len() == 3
16194 {
16195 self.write_keyword("DATEADD");
16196 self.write("(");
16197 self.write_redshift_date_part(&func.args[0]);
16199 self.write(", ");
16200 self.generate_expression(&func.args[1])?;
16201 self.write(", ");
16202 self.generate_expression(&func.args[2])?;
16203 self.write(")");
16204 return Ok(());
16205 }
16206
16207 if upper_name == "UUID_STRING"
16209 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
16210 {
16211 let func_name = match self.config.dialect {
16212 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
16213 Some(DialectType::BigQuery) => "GENERATE_UUID",
16214 _ => "UUID",
16215 };
16216 self.write_keyword(func_name);
16217 self.write("()");
16218 return Ok(());
16219 }
16220
16221 if self.config.dialect == Some(DialectType::Redshift)
16224 && upper_name == "DATE_TRUNC"
16225 && func.args.len() == 2
16226 {
16227 self.write_keyword("DATE_TRUNC");
16228 self.write("(");
16229 self.write_redshift_date_part_quoted(&func.args[0]);
16231 self.write(", ");
16232 self.generate_expression(&func.args[1])?;
16233 self.write(")");
16234 return Ok(());
16235 }
16236
16237 if matches!(
16239 self.config.dialect,
16240 Some(DialectType::TSQL) | Some(DialectType::Fabric)
16241 ) && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16242 && func.args.len() == 2
16243 {
16244 self.write_keyword("DATEPART");
16245 self.write("(");
16246 self.generate_expression(&func.args[0])?;
16247 self.write(", ");
16248 self.generate_expression(&func.args[1])?;
16249 self.write(")");
16250 return Ok(());
16251 }
16252
16253 if matches!(
16255 self.config.dialect,
16256 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
16257 ) && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16258 && func.args.len() == 2
16259 {
16260 self.write_keyword("EXTRACT");
16261 self.write("(");
16262 match &func.args[0] {
16264 Expression::Literal(crate::expressions::Literal::String(s)) => {
16265 self.write(&s.to_lowercase());
16266 }
16267 _ => self.generate_expression(&func.args[0])?,
16268 }
16269 self.write_space();
16270 self.write_keyword("FROM");
16271 self.write_space();
16272 self.generate_expression(&func.args[1])?;
16273 self.write(")");
16274 return Ok(());
16275 }
16276
16277 if self.config.dialect == Some(DialectType::Dremio)
16280 && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16281 && func.args.len() == 2
16282 {
16283 self.write_keyword("EXTRACT");
16284 self.write("(");
16285 self.generate_expression(&func.args[0])?;
16286 self.write_space();
16287 self.write_keyword("FROM");
16288 self.write_space();
16289 self.generate_dremio_date_expression(&func.args[1])?;
16291 self.write(")");
16292 return Ok(());
16293 }
16294
16295 if self.config.dialect == Some(DialectType::Dremio)
16297 && upper_name == "CURRENT_DATE_UTC"
16298 && func.args.is_empty()
16299 {
16300 self.write_keyword("CURRENT_DATE_UTC");
16301 return Ok(());
16302 }
16303
16304 if self.config.dialect == Some(DialectType::Dremio)
16308 && upper_name == "DATETYPE"
16309 && func.args.len() == 3
16310 {
16311 fn get_int_literal(expr: &Expression) -> Option<i64> {
16313 if let Expression::Literal(crate::expressions::Literal::Number(s)) = expr {
16314 s.parse::<i64>().ok()
16315 } else {
16316 None
16317 }
16318 }
16319
16320 if let (Some(year), Some(month), Some(day)) = (
16322 get_int_literal(&func.args[0]),
16323 get_int_literal(&func.args[1]),
16324 get_int_literal(&func.args[2]),
16325 ) {
16326 self.write_keyword("DATE");
16328 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
16329 return Ok(());
16330 }
16331
16332 self.write_keyword("CAST");
16334 self.write("(");
16335 self.write_keyword("CONCAT");
16336 self.write("(");
16337 self.generate_expression(&func.args[0])?;
16338 self.write(", '-', ");
16339 self.generate_expression(&func.args[1])?;
16340 self.write(", '-', ");
16341 self.generate_expression(&func.args[2])?;
16342 self.write(")");
16343 self.write_space();
16344 self.write_keyword("AS");
16345 self.write_space();
16346 self.write_keyword("DATE");
16347 self.write(")");
16348 return Ok(());
16349 }
16350
16351 let is_presto_like = matches!(
16354 self.config.dialect,
16355 Some(DialectType::Presto) | Some(DialectType::Trino)
16356 );
16357 if is_presto_like && upper_name == "DATE_ADD" && func.args.len() == 3 {
16358 self.write_keyword("DATE_ADD");
16359 self.write("(");
16360 self.generate_expression(&func.args[0])?;
16362 self.write(", ");
16363 let interval = &func.args[1];
16365 let needs_cast = !self.returns_integer_type(interval);
16366 if needs_cast {
16367 self.write_keyword("CAST");
16368 self.write("(");
16369 }
16370 self.generate_expression(interval)?;
16371 if needs_cast {
16372 self.write_space();
16373 self.write_keyword("AS");
16374 self.write_space();
16375 self.write_keyword("BIGINT");
16376 self.write(")");
16377 }
16378 self.write(", ");
16379 self.generate_expression(&func.args[2])?;
16381 self.write(")");
16382 return Ok(());
16383 }
16384
16385 let use_brackets = func.use_bracket_syntax;
16387
16388 let has_ordinality = upper_name.ends_with(" WITH ORDINALITY");
16393 let output_name = if has_ordinality {
16394 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
16395 self.normalize_func_name(base_name)
16396 } else {
16397 normalized_name.clone()
16398 };
16399
16400 if func.name.contains('.') && !has_ordinality {
16403 if func.quoted {
16406 self.write("`");
16407 self.write(&func.name);
16408 self.write("`");
16409 } else {
16410 self.write(&func.name);
16411 }
16412 } else {
16413 self.write(&output_name);
16414 }
16415
16416 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
16419 let needs_parens = match upper_name.as_str() {
16420 "CURRENT_USER" | "SESSION_USER" | "SYSTEM_USER" => matches!(
16421 self.config.dialect,
16422 Some(DialectType::Snowflake)
16423 | Some(DialectType::Spark)
16424 | Some(DialectType::Databricks)
16425 | Some(DialectType::Hive)
16426 ),
16427 _ => false,
16428 };
16429 !needs_parens
16430 };
16431 if force_parens {
16432 for comment in &func.trailing_comments {
16434 self.write_space();
16435 self.write_formatted_comment(comment);
16436 }
16437 return Ok(());
16438 }
16439
16440 if upper_name == "CUBE" || upper_name == "ROLLUP" || upper_name == "GROUPING SETS" {
16442 self.write(" (");
16443 } else if use_brackets {
16444 self.write("[");
16445 } else {
16446 self.write("(");
16447 }
16448 if func.distinct {
16449 self.write_keyword("DISTINCT");
16450 self.write_space();
16451 }
16452
16453 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
16455 && (upper_name == "TABLE" || upper_name == "FLATTEN");
16456 let is_grouping_func =
16458 upper_name == "GROUPING SETS" || upper_name == "CUBE" || upper_name == "ROLLUP";
16459 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
16460 if is_grouping_func {
16461 true
16462 } else {
16463 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
16465 for arg in &func.args {
16466 let mut temp_gen = Generator::with_config(self.config.clone());
16467 temp_gen.config.pretty = false; temp_gen.generate_expression(arg)?;
16469 expr_strings.push(temp_gen.output);
16470 }
16471 self.too_wide(&expr_strings)
16472 }
16473 } else {
16474 false
16475 };
16476
16477 if should_split {
16478 self.write_newline();
16480 self.indent_level += 1;
16481 for (i, arg) in func.args.iter().enumerate() {
16482 self.write_indent();
16483 self.generate_expression(arg)?;
16484 if i + 1 < func.args.len() {
16485 self.write(",");
16486 }
16487 self.write_newline();
16488 }
16489 self.indent_level -= 1;
16490 self.write_indent();
16491 } else {
16492 for (i, arg) in func.args.iter().enumerate() {
16494 if i > 0 {
16495 self.write(", ");
16496 }
16497 self.generate_expression(arg)?;
16498 }
16499 }
16500
16501 if use_brackets {
16502 self.write("]");
16503 } else {
16504 self.write(")");
16505 }
16506 if has_ordinality {
16508 self.write_space();
16509 self.write_keyword("WITH ORDINALITY");
16510 }
16511 for comment in &func.trailing_comments {
16513 self.write_space();
16514 self.write_formatted_comment(comment);
16515 }
16516 Ok(())
16517 }
16518
16519 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
16520 let mut normalized_name = self.normalize_func_name(&func.name);
16522
16523 let upper = normalized_name.to_uppercase();
16525 if upper == "MAX_BY" || upper == "MIN_BY" {
16526 let is_max = upper == "MAX_BY";
16527 match self.config.dialect {
16528 Some(DialectType::ClickHouse) => {
16529 normalized_name = if is_max {
16530 "argMax".to_string()
16531 } else {
16532 "argMin".to_string()
16533 };
16534 }
16535 Some(DialectType::DuckDB) => {
16536 normalized_name = if is_max {
16537 "ARG_MAX".to_string()
16538 } else {
16539 "ARG_MIN".to_string()
16540 };
16541 }
16542 _ => {}
16543 }
16544 }
16545 self.write(&normalized_name);
16546 self.write("(");
16547 if func.distinct {
16548 self.write_keyword("DISTINCT");
16549 self.write_space();
16550 }
16551
16552 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
16556 let needs_multi_arg_transform =
16557 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
16558
16559 if needs_multi_arg_transform {
16560 self.write_keyword("CASE");
16562 for arg in &func.args {
16563 self.write_space();
16564 self.write_keyword("WHEN");
16565 self.write_space();
16566 self.generate_expression(arg)?;
16567 self.write_space();
16568 self.write_keyword("IS NULL THEN NULL");
16569 }
16570 self.write_space();
16571 self.write_keyword("ELSE");
16572 self.write(" (");
16573 for (i, arg) in func.args.iter().enumerate() {
16574 if i > 0 {
16575 self.write(", ");
16576 }
16577 self.generate_expression(arg)?;
16578 }
16579 self.write(")");
16580 self.write_space();
16581 self.write_keyword("END");
16582 } else {
16583 for (i, arg) in func.args.iter().enumerate() {
16584 if i > 0 {
16585 self.write(", ");
16586 }
16587 self.generate_expression(arg)?;
16588 }
16589 }
16590
16591 if self.config.ignore_nulls_in_func
16593 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
16594 {
16595 if let Some(ignore) = func.ignore_nulls {
16596 self.write_space();
16597 if ignore {
16598 self.write_keyword("IGNORE NULLS");
16599 } else {
16600 self.write_keyword("RESPECT NULLS");
16601 }
16602 }
16603 }
16604
16605 if !func.order_by.is_empty() {
16607 self.write_space();
16608 self.write_keyword("ORDER BY");
16609 self.write_space();
16610 for (i, ord) in func.order_by.iter().enumerate() {
16611 if i > 0 {
16612 self.write(", ");
16613 }
16614 self.generate_ordered(ord)?;
16615 }
16616 }
16617
16618 if let Some(limit) = &func.limit {
16620 self.write_space();
16621 self.write_keyword("LIMIT");
16622 self.write_space();
16623 if let Expression::Tuple(t) = limit.as_ref() {
16625 if t.expressions.len() == 2 {
16626 self.generate_expression(&t.expressions[0])?;
16627 self.write(", ");
16628 self.generate_expression(&t.expressions[1])?;
16629 } else {
16630 self.generate_expression(limit)?;
16631 }
16632 } else {
16633 self.generate_expression(limit)?;
16634 }
16635 }
16636
16637 self.write(")");
16638
16639 if !self.config.ignore_nulls_in_func
16641 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
16642 {
16643 if let Some(ignore) = func.ignore_nulls {
16644 self.write_space();
16645 if ignore {
16646 self.write_keyword("IGNORE NULLS");
16647 } else {
16648 self.write_keyword("RESPECT NULLS");
16649 }
16650 }
16651 }
16652
16653 if let Some(filter) = &func.filter {
16654 self.write_space();
16655 self.write_keyword("FILTER");
16656 self.write("(");
16657 self.write_keyword("WHERE");
16658 self.write_space();
16659 self.generate_expression(filter)?;
16660 self.write(")");
16661 }
16662
16663 Ok(())
16664 }
16665
16666 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
16667 self.generate_expression(&wf.this)?;
16668
16669 if let Some(keep) = &wf.keep {
16671 self.write_space();
16672 self.write_keyword("KEEP");
16673 self.write(" (");
16674 self.write_keyword("DENSE_RANK");
16675 self.write_space();
16676 if keep.first {
16677 self.write_keyword("FIRST");
16678 } else {
16679 self.write_keyword("LAST");
16680 }
16681 self.write_space();
16682 self.write_keyword("ORDER BY");
16683 self.write_space();
16684 for (i, ord) in keep.order_by.iter().enumerate() {
16685 if i > 0 {
16686 self.write(", ");
16687 }
16688 self.generate_ordered(ord)?;
16689 }
16690 self.write(")");
16691 }
16692
16693 let has_over = !wf.over.partition_by.is_empty()
16695 || !wf.over.order_by.is_empty()
16696 || wf.over.frame.is_some()
16697 || wf.over.window_name.is_some();
16698
16699 if has_over {
16701 self.write_space();
16702 self.write_keyword("OVER");
16703
16704 let has_specs = !wf.over.partition_by.is_empty()
16706 || !wf.over.order_by.is_empty()
16707 || wf.over.frame.is_some();
16708
16709 if wf.over.window_name.is_some() && !has_specs {
16710 self.write_space();
16712 self.write(&wf.over.window_name.as_ref().unwrap().name);
16713 } else {
16714 self.write(" (");
16716 self.generate_over(&wf.over)?;
16717 self.write(")");
16718 }
16719 } else if wf.keep.is_none() {
16720 self.write_space();
16722 self.write_keyword("OVER");
16723 self.write(" ()");
16724 }
16725
16726 Ok(())
16727 }
16728
16729 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
16731 self.generate_expression(&wg.this)?;
16732 self.write_space();
16733 self.write_keyword("WITHIN GROUP");
16734 self.write(" (");
16735 self.write_keyword("ORDER BY");
16736 self.write_space();
16737 for (i, ord) in wg.order_by.iter().enumerate() {
16738 if i > 0 {
16739 self.write(", ");
16740 }
16741 self.generate_ordered(ord)?;
16742 }
16743 self.write(")");
16744 Ok(())
16745 }
16746
16747 fn generate_over(&mut self, over: &Over) -> Result<()> {
16749 let mut has_content = false;
16750
16751 if let Some(name) = &over.window_name {
16753 self.write(&name.name);
16754 has_content = true;
16755 }
16756
16757 if !over.partition_by.is_empty() {
16759 if has_content {
16760 self.write_space();
16761 }
16762 self.write_keyword("PARTITION BY");
16763 self.write_space();
16764 for (i, expr) in over.partition_by.iter().enumerate() {
16765 if i > 0 {
16766 self.write(", ");
16767 }
16768 self.generate_expression(expr)?;
16769 }
16770 has_content = true;
16771 }
16772
16773 if !over.order_by.is_empty() {
16775 if has_content {
16776 self.write_space();
16777 }
16778 self.write_keyword("ORDER BY");
16779 self.write_space();
16780 for (i, ordered) in over.order_by.iter().enumerate() {
16781 if i > 0 {
16782 self.write(", ");
16783 }
16784 self.generate_ordered(ordered)?;
16785 }
16786 has_content = true;
16787 }
16788
16789 if let Some(frame) = &over.frame {
16791 if has_content {
16792 self.write_space();
16793 }
16794 self.generate_window_frame(frame)?;
16795 }
16796
16797 Ok(())
16798 }
16799
16800 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
16801 let lowercase_frame = self.config.lowercase_window_frame_keywords;
16803
16804 if !lowercase_frame {
16806 if let Some(kind_text) = &frame.kind_text {
16807 self.write(kind_text);
16808 } else {
16809 match frame.kind {
16810 WindowFrameKind::Rows => self.write_keyword("ROWS"),
16811 WindowFrameKind::Range => self.write_keyword("RANGE"),
16812 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
16813 }
16814 }
16815 } else {
16816 match frame.kind {
16817 WindowFrameKind::Rows => self.write("rows"),
16818 WindowFrameKind::Range => self.write("range"),
16819 WindowFrameKind::Groups => self.write("groups"),
16820 }
16821 }
16822
16823 self.write_space();
16826 let should_normalize = self.config.normalize_window_frame_between
16827 && frame.end.is_none()
16828 && matches!(
16829 frame.start,
16830 WindowFrameBound::Preceding(_)
16831 | WindowFrameBound::Following(_)
16832 | WindowFrameBound::UnboundedPreceding
16833 | WindowFrameBound::UnboundedFollowing
16834 );
16835
16836 if let Some(end) = &frame.end {
16837 self.write_keyword("BETWEEN");
16839 self.write_space();
16840 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16841 self.write_space();
16842 self.write_keyword("AND");
16843 self.write_space();
16844 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
16845 } else if should_normalize {
16846 self.write_keyword("BETWEEN");
16848 self.write_space();
16849 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16850 self.write_space();
16851 self.write_keyword("AND");
16852 self.write_space();
16853 self.write_keyword("CURRENT ROW");
16854 } else {
16855 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16857 }
16858
16859 if let Some(exclude) = &frame.exclude {
16861 self.write_space();
16862 self.write_keyword("EXCLUDE");
16863 self.write_space();
16864 match exclude {
16865 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
16866 WindowFrameExclude::Group => self.write_keyword("GROUP"),
16867 WindowFrameExclude::Ties => self.write_keyword("TIES"),
16868 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
16869 }
16870 }
16871
16872 Ok(())
16873 }
16874
16875 fn generate_window_frame_bound(
16876 &mut self,
16877 bound: &WindowFrameBound,
16878 side_text: Option<&str>,
16879 ) -> Result<()> {
16880 let lowercase_frame = self.config.lowercase_window_frame_keywords;
16882
16883 match bound {
16884 WindowFrameBound::CurrentRow => {
16885 self.write_keyword("CURRENT ROW");
16886 }
16887 WindowFrameBound::UnboundedPreceding => {
16888 self.write_keyword("UNBOUNDED");
16889 self.write_space();
16890 if lowercase_frame {
16891 self.write("preceding");
16892 } else if let Some(text) = side_text {
16893 self.write(text);
16894 } else {
16895 self.write_keyword("PRECEDING");
16896 }
16897 }
16898 WindowFrameBound::UnboundedFollowing => {
16899 self.write_keyword("UNBOUNDED");
16900 self.write_space();
16901 if lowercase_frame {
16902 self.write("following");
16903 } else if let Some(text) = side_text {
16904 self.write(text);
16905 } else {
16906 self.write_keyword("FOLLOWING");
16907 }
16908 }
16909 WindowFrameBound::Preceding(expr) => {
16910 self.generate_expression(expr)?;
16911 self.write_space();
16912 if lowercase_frame {
16913 self.write("preceding");
16914 } else if let Some(text) = side_text {
16915 self.write(text);
16916 } else {
16917 self.write_keyword("PRECEDING");
16918 }
16919 }
16920 WindowFrameBound::Following(expr) => {
16921 self.generate_expression(expr)?;
16922 self.write_space();
16923 if lowercase_frame {
16924 self.write("following");
16925 } else if let Some(text) = side_text {
16926 self.write(text);
16927 } else {
16928 self.write_keyword("FOLLOWING");
16929 }
16930 }
16931 WindowFrameBound::BarePreceding => {
16932 if lowercase_frame {
16933 self.write("preceding");
16934 } else if let Some(text) = side_text {
16935 self.write(text);
16936 } else {
16937 self.write_keyword("PRECEDING");
16938 }
16939 }
16940 WindowFrameBound::BareFollowing => {
16941 if lowercase_frame {
16942 self.write("following");
16943 } else if let Some(text) = side_text {
16944 self.write(text);
16945 } else {
16946 self.write_keyword("FOLLOWING");
16947 }
16948 }
16949 WindowFrameBound::Value(expr) => {
16950 self.generate_expression(expr)?;
16952 }
16953 }
16954 Ok(())
16955 }
16956
16957 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
16958 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
16961 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
16962 && !matches!(&interval.this, Some(Expression::Literal(_)));
16963
16964 if self.config.single_string_interval {
16967 if let (
16968 Some(Expression::Literal(Literal::String(ref val))),
16969 Some(IntervalUnitSpec::Simple {
16970 ref unit,
16971 ref use_plural,
16972 }),
16973 ) = (&interval.this, &interval.unit)
16974 {
16975 self.write_keyword("INTERVAL");
16976 self.write_space();
16977 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
16978 let unit_str = self.interval_unit_str(unit, effective_plural);
16979 self.write("'");
16980 self.write(val);
16981 self.write(" ");
16982 self.write(&unit_str);
16983 self.write("'");
16984 return Ok(());
16985 }
16986 }
16987
16988 if !skip_interval_keyword {
16989 self.write_keyword("INTERVAL");
16990 }
16991
16992 if let Some(ref value) = interval.this {
16994 if !skip_interval_keyword {
16995 self.write_space();
16996 }
16997 let needs_parens = interval.unit.is_some()
17001 && matches!(
17002 value,
17003 Expression::Add(_)
17004 | Expression::Sub(_)
17005 | Expression::Mul(_)
17006 | Expression::Div(_)
17007 | Expression::Mod(_)
17008 | Expression::BitwiseAnd(_)
17009 | Expression::BitwiseOr(_)
17010 | Expression::BitwiseXor(_)
17011 );
17012 if needs_parens {
17013 self.write("(");
17014 }
17015 self.generate_expression(value)?;
17016 if needs_parens {
17017 self.write(")");
17018 }
17019 }
17020
17021 if let Some(ref unit_spec) = interval.unit {
17023 self.write_space();
17024 self.write_interval_unit_spec(unit_spec)?;
17025 }
17026
17027 Ok(())
17028 }
17029
17030 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
17032 match (unit, use_plural) {
17033 (IntervalUnit::Year, false) => "YEAR",
17034 (IntervalUnit::Year, true) => "YEARS",
17035 (IntervalUnit::Quarter, false) => "QUARTER",
17036 (IntervalUnit::Quarter, true) => "QUARTERS",
17037 (IntervalUnit::Month, false) => "MONTH",
17038 (IntervalUnit::Month, true) => "MONTHS",
17039 (IntervalUnit::Week, false) => "WEEK",
17040 (IntervalUnit::Week, true) => "WEEKS",
17041 (IntervalUnit::Day, false) => "DAY",
17042 (IntervalUnit::Day, true) => "DAYS",
17043 (IntervalUnit::Hour, false) => "HOUR",
17044 (IntervalUnit::Hour, true) => "HOURS",
17045 (IntervalUnit::Minute, false) => "MINUTE",
17046 (IntervalUnit::Minute, true) => "MINUTES",
17047 (IntervalUnit::Second, false) => "SECOND",
17048 (IntervalUnit::Second, true) => "SECONDS",
17049 (IntervalUnit::Millisecond, false) => "MILLISECOND",
17050 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
17051 (IntervalUnit::Microsecond, false) => "MICROSECOND",
17052 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
17053 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
17054 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
17055 }
17056 }
17057
17058 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
17059 match unit_spec {
17060 IntervalUnitSpec::Simple { unit, use_plural } => {
17061 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
17063 self.write_simple_interval_unit(unit, effective_plural);
17064 }
17065 IntervalUnitSpec::Span(span) => {
17066 self.write_simple_interval_unit(&span.this, false);
17067 self.write_space();
17068 self.write_keyword("TO");
17069 self.write_space();
17070 self.write_simple_interval_unit(&span.expression, false);
17071 }
17072 IntervalUnitSpec::ExprSpan(span) => {
17073 self.generate_expression(&span.this)?;
17075 self.write_space();
17076 self.write_keyword("TO");
17077 self.write_space();
17078 self.generate_expression(&span.expression)?;
17079 }
17080 IntervalUnitSpec::Expr(expr) => {
17081 self.generate_expression(expr)?;
17082 }
17083 }
17084 Ok(())
17085 }
17086
17087 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
17088 match (unit, use_plural) {
17090 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
17091 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
17092 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
17093 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
17094 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
17095 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
17096 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
17097 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
17098 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
17099 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
17100 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
17101 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
17102 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
17103 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
17104 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
17105 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
17106 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
17107 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
17108 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
17109 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
17110 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
17111 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
17112 }
17113 }
17114
17115 fn write_redshift_date_part(&mut self, expr: &Expression) {
17118 let part_str = self.extract_date_part_string(expr);
17119 if let Some(part) = part_str {
17120 let normalized = self.normalize_date_part(&part);
17121 self.write_keyword(&normalized);
17122 } else {
17123 let _ = self.generate_expression(expr);
17125 }
17126 }
17127
17128 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
17131 let part_str = self.extract_date_part_string(expr);
17132 if let Some(part) = part_str {
17133 let normalized = self.normalize_date_part(&part);
17134 self.write("'");
17135 self.write(&normalized);
17136 self.write("'");
17137 } else {
17138 let _ = self.generate_expression(expr);
17140 }
17141 }
17142
17143 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
17145 match expr {
17146 Expression::Literal(crate::expressions::Literal::String(s)) => Some(s.clone()),
17147 Expression::Identifier(id) => Some(id.name.clone()),
17148 Expression::Column(col) if col.table.is_none() => {
17149 Some(col.name.name.clone())
17151 }
17152 _ => None,
17153 }
17154 }
17155
17156 fn normalize_date_part(&self, part: &str) -> String {
17159 let lower = part.to_lowercase();
17160 match lower.as_str() {
17161 "day" | "days" | "d" => "DAY".to_string(),
17162 "month" | "months" | "mon" | "mm" => "MONTH".to_string(),
17163 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
17164 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
17165 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
17166 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
17167 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
17168 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
17169 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
17170 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
17171 _ => part.to_uppercase(),
17172 }
17173 }
17174
17175 fn write_datetime_field(&mut self, field: &DateTimeField) {
17176 match field {
17177 DateTimeField::Year => self.write_keyword("YEAR"),
17178 DateTimeField::Month => self.write_keyword("MONTH"),
17179 DateTimeField::Day => self.write_keyword("DAY"),
17180 DateTimeField::Hour => self.write_keyword("HOUR"),
17181 DateTimeField::Minute => self.write_keyword("MINUTE"),
17182 DateTimeField::Second => self.write_keyword("SECOND"),
17183 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
17184 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
17185 DateTimeField::DayOfWeek => {
17186 let name = match self.config.dialect {
17187 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
17188 _ => "DOW",
17189 };
17190 self.write_keyword(name);
17191 }
17192 DateTimeField::DayOfYear => {
17193 let name = match self.config.dialect {
17194 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
17195 _ => "DOY",
17196 };
17197 self.write_keyword(name);
17198 }
17199 DateTimeField::Week => self.write_keyword("WEEK"),
17200 DateTimeField::WeekWithModifier(modifier) => {
17201 self.write_keyword("WEEK");
17202 self.write("(");
17203 self.write(modifier);
17204 self.write(")");
17205 }
17206 DateTimeField::Quarter => self.write_keyword("QUARTER"),
17207 DateTimeField::Epoch => self.write_keyword("EPOCH"),
17208 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
17209 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
17210 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
17211 DateTimeField::Date => self.write_keyword("DATE"),
17212 DateTimeField::Time => self.write_keyword("TIME"),
17213 DateTimeField::Custom(name) => self.write(name),
17214 }
17215 }
17216
17217 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
17219 match field {
17220 DateTimeField::Year => self.write("year"),
17221 DateTimeField::Month => self.write("month"),
17222 DateTimeField::Day => self.write("day"),
17223 DateTimeField::Hour => self.write("hour"),
17224 DateTimeField::Minute => self.write("minute"),
17225 DateTimeField::Second => self.write("second"),
17226 DateTimeField::Millisecond => self.write("millisecond"),
17227 DateTimeField::Microsecond => self.write("microsecond"),
17228 DateTimeField::DayOfWeek => self.write("dow"),
17229 DateTimeField::DayOfYear => self.write("doy"),
17230 DateTimeField::Week => self.write("week"),
17231 DateTimeField::WeekWithModifier(modifier) => {
17232 self.write("week(");
17233 self.write(modifier);
17234 self.write(")");
17235 }
17236 DateTimeField::Quarter => self.write("quarter"),
17237 DateTimeField::Epoch => self.write("epoch"),
17238 DateTimeField::Timezone => self.write("timezone"),
17239 DateTimeField::TimezoneHour => self.write("timezone_hour"),
17240 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
17241 DateTimeField::Date => self.write("date"),
17242 DateTimeField::Time => self.write("time"),
17243 DateTimeField::Custom(name) => self.write(name),
17244 }
17245 }
17246
17247 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
17250 self.write_keyword(name);
17251 self.write("(");
17252 self.generate_expression(arg)?;
17253 self.write(")");
17254 Ok(())
17255 }
17256
17257 fn generate_unary_func(
17259 &mut self,
17260 default_name: &str,
17261 f: &crate::expressions::UnaryFunc,
17262 ) -> Result<()> {
17263 let name = f.original_name.as_deref().unwrap_or(default_name);
17264 self.write_keyword(name);
17265 self.write("(");
17266 self.generate_expression(&f.this)?;
17267 self.write(")");
17268 Ok(())
17269 }
17270
17271 fn generate_sqrt_cbrt(
17273 &mut self,
17274 f: &crate::expressions::UnaryFunc,
17275 func_name: &str,
17276 _op: &str,
17277 ) -> Result<()> {
17278 self.write_keyword(func_name);
17281 self.write("(");
17282 self.generate_expression(&f.this)?;
17283 self.write(")");
17284 Ok(())
17285 }
17286
17287 fn generate_binary_func(
17288 &mut self,
17289 name: &str,
17290 arg1: &Expression,
17291 arg2: &Expression,
17292 ) -> Result<()> {
17293 self.write_keyword(name);
17294 self.write("(");
17295 self.generate_expression(arg1)?;
17296 self.write(", ");
17297 self.generate_expression(arg2)?;
17298 self.write(")");
17299 Ok(())
17300 }
17301
17302 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
17306 let func_name = f.name.as_deref().unwrap_or("CHAR");
17308 self.write_keyword(func_name);
17309 self.write("(");
17310 for (i, arg) in f.args.iter().enumerate() {
17311 if i > 0 {
17312 self.write(", ");
17313 }
17314 self.generate_expression(arg)?;
17315 }
17316 if let Some(ref charset) = f.charset {
17317 self.write(" ");
17318 self.write_keyword("USING");
17319 self.write(" ");
17320 self.write(charset);
17321 }
17322 self.write(")");
17323 Ok(())
17324 }
17325
17326 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
17327 use crate::dialects::DialectType;
17328
17329 match self.config.dialect {
17330 Some(DialectType::Teradata) => {
17331 self.generate_expression(&f.this)?;
17333 self.write(" ** ");
17334 self.generate_expression(&f.expression)?;
17335 Ok(())
17336 }
17337 _ => {
17338 self.generate_binary_func("POWER", &f.this, &f.expression)
17340 }
17341 }
17342 }
17343
17344 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
17345 self.write_func_name(name);
17346 self.write("(");
17347 for (i, arg) in args.iter().enumerate() {
17348 if i > 0 {
17349 self.write(", ");
17350 }
17351 self.generate_expression(arg)?;
17352 }
17353 self.write(")");
17354 Ok(())
17355 }
17356
17357 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
17360 self.write_keyword("CONCAT_WS");
17361 self.write("(");
17362 self.generate_expression(&f.separator)?;
17363 for expr in &f.expressions {
17364 self.write(", ");
17365 self.generate_expression(expr)?;
17366 }
17367 self.write(")");
17368 Ok(())
17369 }
17370
17371 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
17372 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
17374 if is_oracle {
17375 self.write_keyword("SUBSTR");
17376 } else {
17377 self.write_keyword("SUBSTRING");
17378 }
17379 self.write("(");
17380 self.generate_expression(&f.this)?;
17381 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
17383 let use_comma_syntax = matches!(
17385 self.config.dialect,
17386 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
17387 );
17388 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
17389 self.write_space();
17391 self.write_keyword("FROM");
17392 self.write_space();
17393 self.generate_expression(&f.start)?;
17394 if let Some(length) = &f.length {
17395 self.write_space();
17396 self.write_keyword("FOR");
17397 self.write_space();
17398 self.generate_expression(length)?;
17399 }
17400 } else {
17401 self.write(", ");
17403 self.generate_expression(&f.start)?;
17404 if let Some(length) = &f.length {
17405 self.write(", ");
17406 self.generate_expression(length)?;
17407 }
17408 }
17409 self.write(")");
17410 Ok(())
17411 }
17412
17413 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
17414 self.write_keyword("OVERLAY");
17415 self.write("(");
17416 self.generate_expression(&f.this)?;
17417 self.write_space();
17418 self.write_keyword("PLACING");
17419 self.write_space();
17420 self.generate_expression(&f.replacement)?;
17421 self.write_space();
17422 self.write_keyword("FROM");
17423 self.write_space();
17424 self.generate_expression(&f.from)?;
17425 if let Some(length) = &f.length {
17426 self.write_space();
17427 self.write_keyword("FOR");
17428 self.write_space();
17429 self.generate_expression(length)?;
17430 }
17431 self.write(")");
17432 Ok(())
17433 }
17434
17435 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
17436 if f.position_explicit && f.characters.is_none() {
17439 match f.position {
17440 TrimPosition::Leading => {
17441 self.write_keyword("LTRIM");
17442 self.write("(");
17443 self.generate_expression(&f.this)?;
17444 self.write(")");
17445 return Ok(());
17446 }
17447 TrimPosition::Trailing => {
17448 self.write_keyword("RTRIM");
17449 self.write("(");
17450 self.generate_expression(&f.this)?;
17451 self.write(")");
17452 return Ok(());
17453 }
17454 TrimPosition::Both => {
17455 }
17458 }
17459 }
17460
17461 self.write_keyword("TRIM");
17462 self.write("(");
17463 let force_standard = f.characters.is_some()
17466 && !f.sql_standard_syntax
17467 && matches!(
17468 self.config.dialect,
17469 Some(DialectType::Hive)
17470 | Some(DialectType::Spark)
17471 | Some(DialectType::Databricks)
17472 | Some(DialectType::ClickHouse)
17473 );
17474 let use_standard = (f.sql_standard_syntax || force_standard)
17475 && !(f.position_explicit
17476 && f.characters.is_none()
17477 && matches!(f.position, TrimPosition::Both));
17478 if use_standard {
17479 if f.position_explicit {
17482 match f.position {
17483 TrimPosition::Both => self.write_keyword("BOTH"),
17484 TrimPosition::Leading => self.write_keyword("LEADING"),
17485 TrimPosition::Trailing => self.write_keyword("TRAILING"),
17486 }
17487 self.write_space();
17488 }
17489 if let Some(chars) = &f.characters {
17490 self.generate_expression(chars)?;
17491 self.write_space();
17492 }
17493 self.write_keyword("FROM");
17494 self.write_space();
17495 self.generate_expression(&f.this)?;
17496 } else {
17497 self.generate_expression(&f.this)?;
17499 if let Some(chars) = &f.characters {
17500 self.write(", ");
17501 self.generate_expression(chars)?;
17502 }
17503 }
17504 self.write(")");
17505 Ok(())
17506 }
17507
17508 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
17509 self.write_keyword("REPLACE");
17510 self.write("(");
17511 self.generate_expression(&f.this)?;
17512 self.write(", ");
17513 self.generate_expression(&f.old)?;
17514 self.write(", ");
17515 self.generate_expression(&f.new)?;
17516 self.write(")");
17517 Ok(())
17518 }
17519
17520 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
17521 self.write_keyword(name);
17522 self.write("(");
17523 self.generate_expression(&f.this)?;
17524 self.write(", ");
17525 self.generate_expression(&f.length)?;
17526 self.write(")");
17527 Ok(())
17528 }
17529
17530 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
17531 self.write_keyword("REPEAT");
17532 self.write("(");
17533 self.generate_expression(&f.this)?;
17534 self.write(", ");
17535 self.generate_expression(&f.times)?;
17536 self.write(")");
17537 Ok(())
17538 }
17539
17540 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
17541 self.write_keyword(name);
17542 self.write("(");
17543 self.generate_expression(&f.this)?;
17544 self.write(", ");
17545 self.generate_expression(&f.length)?;
17546 if let Some(fill) = &f.fill {
17547 self.write(", ");
17548 self.generate_expression(fill)?;
17549 }
17550 self.write(")");
17551 Ok(())
17552 }
17553
17554 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
17555 self.write_keyword("SPLIT");
17556 self.write("(");
17557 self.generate_expression(&f.this)?;
17558 self.write(", ");
17559 self.generate_expression(&f.delimiter)?;
17560 self.write(")");
17561 Ok(())
17562 }
17563
17564 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
17565 use crate::dialects::DialectType;
17566 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
17568 self.generate_expression(&f.this)?;
17569 self.write(" ~ ");
17570 self.generate_expression(&f.pattern)?;
17571 } else if matches!(
17572 self.config.dialect,
17573 Some(DialectType::SingleStore)
17574 | Some(DialectType::Spark)
17575 | Some(DialectType::Hive)
17576 | Some(DialectType::Databricks)
17577 ) && f.flags.is_none()
17578 {
17579 self.generate_expression(&f.this)?;
17581 self.write_keyword(" RLIKE ");
17582 self.generate_expression(&f.pattern)?;
17583 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
17584 self.write_keyword("REGEXP");
17586 self.write("(");
17587 self.generate_expression(&f.this)?;
17588 self.write(", ");
17589 self.generate_expression(&f.pattern)?;
17590 if let Some(flags) = &f.flags {
17591 self.write(", ");
17592 self.generate_expression(flags)?;
17593 }
17594 self.write(")");
17595 } else {
17596 self.write_keyword("REGEXP_LIKE");
17597 self.write("(");
17598 self.generate_expression(&f.this)?;
17599 self.write(", ");
17600 self.generate_expression(&f.pattern)?;
17601 if let Some(flags) = &f.flags {
17602 self.write(", ");
17603 self.generate_expression(flags)?;
17604 }
17605 self.write(")");
17606 }
17607 Ok(())
17608 }
17609
17610 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
17611 self.write_keyword("REGEXP_REPLACE");
17612 self.write("(");
17613 self.generate_expression(&f.this)?;
17614 self.write(", ");
17615 self.generate_expression(&f.pattern)?;
17616 self.write(", ");
17617 self.generate_expression(&f.replacement)?;
17618 if let Some(flags) = &f.flags {
17619 self.write(", ");
17620 self.generate_expression(flags)?;
17621 }
17622 self.write(")");
17623 Ok(())
17624 }
17625
17626 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
17627 self.write_keyword("REGEXP_EXTRACT");
17628 self.write("(");
17629 self.generate_expression(&f.this)?;
17630 self.write(", ");
17631 self.generate_expression(&f.pattern)?;
17632 if let Some(group) = &f.group {
17633 self.write(", ");
17634 self.generate_expression(group)?;
17635 }
17636 self.write(")");
17637 Ok(())
17638 }
17639
17640 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
17643 self.write_keyword("ROUND");
17644 self.write("(");
17645 self.generate_expression(&f.this)?;
17646 if let Some(decimals) = &f.decimals {
17647 self.write(", ");
17648 self.generate_expression(decimals)?;
17649 }
17650 self.write(")");
17651 Ok(())
17652 }
17653
17654 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
17655 self.write_keyword("FLOOR");
17656 self.write("(");
17657 self.generate_expression(&f.this)?;
17658 if let Some(to) = &f.to {
17660 self.write(" ");
17661 self.write_keyword("TO");
17662 self.write(" ");
17663 self.generate_expression(to)?;
17664 } else if let Some(scale) = &f.scale {
17665 self.write(", ");
17666 self.generate_expression(scale)?;
17667 }
17668 self.write(")");
17669 Ok(())
17670 }
17671
17672 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
17673 self.write_keyword("CEIL");
17674 self.write("(");
17675 self.generate_expression(&f.this)?;
17676 if let Some(to) = &f.to {
17678 self.write(" ");
17679 self.write_keyword("TO");
17680 self.write(" ");
17681 self.generate_expression(to)?;
17682 } else if let Some(decimals) = &f.decimals {
17683 self.write(", ");
17684 self.generate_expression(decimals)?;
17685 }
17686 self.write(")");
17687 Ok(())
17688 }
17689
17690 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
17691 use crate::expressions::Literal;
17692
17693 if let Some(base) = &f.base {
17694 if self.is_log_base_none() {
17697 if matches!(base, Expression::Literal(Literal::Number(s)) if s == "2") {
17698 self.write_func_name("LOG2");
17699 self.write("(");
17700 self.generate_expression(&f.this)?;
17701 self.write(")");
17702 return Ok(());
17703 } else if matches!(base, Expression::Literal(Literal::Number(s)) if s == "10") {
17704 self.write_func_name("LOG10");
17705 self.write("(");
17706 self.generate_expression(&f.this)?;
17707 self.write(")");
17708 return Ok(());
17709 }
17710 }
17712
17713 self.write_func_name("LOG");
17714 self.write("(");
17715 if self.is_log_value_first() {
17716 self.generate_expression(&f.this)?;
17718 self.write(", ");
17719 self.generate_expression(base)?;
17720 } else {
17721 self.generate_expression(base)?;
17723 self.write(", ");
17724 self.generate_expression(&f.this)?;
17725 }
17726 self.write(")");
17727 } else {
17728 self.write_func_name("LOG");
17730 self.write("(");
17731 self.generate_expression(&f.this)?;
17732 self.write(")");
17733 }
17734 Ok(())
17735 }
17736
17737 fn is_log_value_first(&self) -> bool {
17740 use crate::dialects::DialectType;
17741 matches!(
17742 self.config.dialect,
17743 Some(DialectType::BigQuery)
17744 | Some(DialectType::TSQL)
17745 | Some(DialectType::Tableau)
17746 | Some(DialectType::Fabric)
17747 )
17748 }
17749
17750 fn is_log_base_none(&self) -> bool {
17753 use crate::dialects::DialectType;
17754 matches!(
17755 self.config.dialect,
17756 Some(DialectType::Presto)
17757 | Some(DialectType::Trino)
17758 | Some(DialectType::ClickHouse)
17759 | Some(DialectType::Athena)
17760 )
17761 }
17762
17763 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
17766 self.write_keyword("CURRENT_TIME");
17767 if let Some(precision) = f.precision {
17768 self.write(&format!("({})", precision));
17769 }
17770 Ok(())
17771 }
17772
17773 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
17774 use crate::dialects::DialectType;
17775
17776 if f.sysdate {
17778 match self.config.dialect {
17779 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
17780 self.write_keyword("SYSDATE");
17781 return Ok(());
17782 }
17783 Some(DialectType::Snowflake) => {
17784 self.write_keyword("SYSDATE");
17786 self.write("()");
17787 return Ok(());
17788 }
17789 _ => {
17790 }
17792 }
17793 }
17794
17795 self.write_keyword("CURRENT_TIMESTAMP");
17796 if let Some(precision) = f.precision {
17798 self.write(&format!("({})", precision));
17799 } else if matches!(
17800 self.config.dialect,
17801 Some(crate::dialects::DialectType::MySQL)
17802 | Some(crate::dialects::DialectType::SingleStore)
17803 | Some(crate::dialects::DialectType::TiDB)
17804 | Some(crate::dialects::DialectType::Spark)
17805 | Some(crate::dialects::DialectType::Hive)
17806 | Some(crate::dialects::DialectType::Databricks)
17807 | Some(crate::dialects::DialectType::ClickHouse)
17808 | Some(crate::dialects::DialectType::BigQuery)
17809 | Some(crate::dialects::DialectType::Snowflake)
17810 ) {
17811 self.write("()");
17812 }
17813 Ok(())
17814 }
17815
17816 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
17817 if self.config.dialect == Some(DialectType::Exasol) {
17819 self.write_keyword("CONVERT_TZ");
17820 self.write("(");
17821 self.generate_expression(&f.this)?;
17822 self.write(", 'UTC', ");
17823 self.generate_expression(&f.zone)?;
17824 self.write(")");
17825 return Ok(());
17826 }
17827
17828 self.generate_expression(&f.this)?;
17829 self.write_space();
17830 self.write_keyword("AT TIME ZONE");
17831 self.write_space();
17832 self.generate_expression(&f.zone)?;
17833 Ok(())
17834 }
17835
17836 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
17837 use crate::dialects::DialectType;
17838
17839 let is_presto_like = matches!(
17842 self.config.dialect,
17843 Some(DialectType::Presto) | Some(DialectType::Trino)
17844 );
17845
17846 if is_presto_like {
17847 self.write_keyword(name);
17848 self.write("(");
17849 self.write("'");
17851 self.write_simple_interval_unit(&f.unit, false);
17852 self.write("'");
17853 self.write(", ");
17854 let needs_cast = !self.returns_integer_type(&f.interval);
17856 if needs_cast {
17857 self.write_keyword("CAST");
17858 self.write("(");
17859 }
17860 self.generate_expression(&f.interval)?;
17861 if needs_cast {
17862 self.write_space();
17863 self.write_keyword("AS");
17864 self.write_space();
17865 self.write_keyword("BIGINT");
17866 self.write(")");
17867 }
17868 self.write(", ");
17869 self.generate_expression(&f.this)?;
17870 self.write(")");
17871 } else {
17872 self.write_keyword(name);
17873 self.write("(");
17874 self.generate_expression(&f.this)?;
17875 self.write(", ");
17876 self.write_keyword("INTERVAL");
17877 self.write_space();
17878 self.generate_expression(&f.interval)?;
17879 self.write_space();
17880 self.write_simple_interval_unit(&f.unit, false); self.write(")");
17882 }
17883 Ok(())
17884 }
17885
17886 fn returns_integer_type(&self, expr: &Expression) -> bool {
17889 use crate::expressions::{DataType, Literal};
17890 match expr {
17891 Expression::Literal(Literal::Number(n)) => !n.contains('.'),
17893
17894 Expression::Floor(f) => self.returns_integer_type(&f.this),
17896
17897 Expression::Round(f) => {
17899 f.decimals.is_none() && self.returns_integer_type(&f.this)
17901 }
17902
17903 Expression::Sign(f) => self.returns_integer_type(&f.this),
17905
17906 Expression::Abs(f) => self.returns_integer_type(&f.this),
17908
17909 Expression::Mul(op) => {
17911 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17912 }
17913 Expression::Add(op) => {
17914 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17915 }
17916 Expression::Sub(op) => {
17917 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17918 }
17919 Expression::Mod(op) => self.returns_integer_type(&op.left),
17920
17921 Expression::Cast(c) => matches!(
17923 &c.to,
17924 DataType::BigInt { .. }
17925 | DataType::Int { .. }
17926 | DataType::SmallInt { .. }
17927 | DataType::TinyInt { .. }
17928 ),
17929
17930 Expression::Neg(op) => self.returns_integer_type(&op.this),
17932
17933 Expression::Paren(p) => self.returns_integer_type(&p.this),
17935
17936 _ => false,
17939 }
17940 }
17941
17942 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
17943 self.write_keyword("DATEDIFF");
17944 self.write("(");
17945 if let Some(unit) = &f.unit {
17946 self.write_simple_interval_unit(unit, false); self.write(", ");
17948 }
17949 self.generate_expression(&f.this)?;
17950 self.write(", ");
17951 self.generate_expression(&f.expression)?;
17952 self.write(")");
17953 Ok(())
17954 }
17955
17956 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
17957 self.write_keyword("DATE_TRUNC");
17958 self.write("('");
17959 self.write_datetime_field(&f.unit);
17960 self.write("', ");
17961 self.generate_expression(&f.this)?;
17962 self.write(")");
17963 Ok(())
17964 }
17965
17966 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
17967 use crate::dialects::DialectType;
17968 use crate::expressions::DateTimeField;
17969
17970 self.write_keyword("LAST_DAY");
17971 self.write("(");
17972 self.generate_expression(&f.this)?;
17973 if let Some(unit) = &f.unit {
17974 self.write(", ");
17975 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
17978 if let DateTimeField::WeekWithModifier(_) = unit {
17979 self.write_keyword("WEEK");
17980 } else {
17981 self.write_datetime_field(unit);
17982 }
17983 } else {
17984 self.write_datetime_field(unit);
17985 }
17986 }
17987 self.write(")");
17988 Ok(())
17989 }
17990
17991 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
17992 if matches!(
17994 self.config.dialect,
17995 Some(DialectType::TSQL) | Some(DialectType::Fabric)
17996 ) {
17997 self.write_keyword("DATEPART");
17998 self.write("(");
17999 self.write_datetime_field(&f.field);
18000 self.write(", ");
18001 self.generate_expression(&f.this)?;
18002 self.write(")");
18003 return Ok(());
18004 }
18005 self.write_keyword("EXTRACT");
18006 self.write("(");
18007 if matches!(
18009 self.config.dialect,
18010 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
18011 ) {
18012 self.write_datetime_field_lower(&f.field);
18013 } else {
18014 self.write_datetime_field(&f.field);
18015 }
18016 self.write_space();
18017 self.write_keyword("FROM");
18018 self.write_space();
18019 self.generate_expression(&f.this)?;
18020 self.write(")");
18021 Ok(())
18022 }
18023
18024 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
18025 self.write_keyword("TO_DATE");
18026 self.write("(");
18027 self.generate_expression(&f.this)?;
18028 if let Some(format) = &f.format {
18029 self.write(", ");
18030 self.generate_expression(format)?;
18031 }
18032 self.write(")");
18033 Ok(())
18034 }
18035
18036 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
18037 self.write_keyword("TO_TIMESTAMP");
18038 self.write("(");
18039 self.generate_expression(&f.this)?;
18040 if let Some(format) = &f.format {
18041 self.write(", ");
18042 self.generate_expression(format)?;
18043 }
18044 self.write(")");
18045 Ok(())
18046 }
18047
18048 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
18051 use crate::dialects::DialectType;
18052
18053 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
18055 self.write_keyword("CASE WHEN");
18056 self.write_space();
18057 self.generate_expression(&f.condition)?;
18058 self.write_space();
18059 self.write_keyword("THEN");
18060 self.write_space();
18061 self.generate_expression(&f.true_value)?;
18062 if let Some(false_val) = &f.false_value {
18063 self.write_space();
18064 self.write_keyword("ELSE");
18065 self.write_space();
18066 self.generate_expression(false_val)?;
18067 }
18068 self.write_space();
18069 self.write_keyword("END");
18070 return Ok(());
18071 }
18072
18073 if self.config.dialect == Some(DialectType::Exasol) {
18075 self.write_keyword("IF");
18076 self.write_space();
18077 self.generate_expression(&f.condition)?;
18078 self.write_space();
18079 self.write_keyword("THEN");
18080 self.write_space();
18081 self.generate_expression(&f.true_value)?;
18082 if let Some(false_val) = &f.false_value {
18083 self.write_space();
18084 self.write_keyword("ELSE");
18085 self.write_space();
18086 self.generate_expression(false_val)?;
18087 }
18088 self.write_space();
18089 self.write_keyword("ENDIF");
18090 return Ok(());
18091 }
18092
18093 let func_name = match self.config.dialect {
18095 Some(DialectType::Snowflake) => "IFF",
18096 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
18097 Some(DialectType::Drill) => "`IF`",
18098 _ => "IF",
18099 };
18100 self.write(func_name);
18101 self.write("(");
18102 self.generate_expression(&f.condition)?;
18103 self.write(", ");
18104 self.generate_expression(&f.true_value)?;
18105 if let Some(false_val) = &f.false_value {
18106 self.write(", ");
18107 self.generate_expression(false_val)?;
18108 }
18109 self.write(")");
18110 Ok(())
18111 }
18112
18113 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
18114 self.write_keyword("NVL2");
18115 self.write("(");
18116 self.generate_expression(&f.this)?;
18117 self.write(", ");
18118 self.generate_expression(&f.true_value)?;
18119 self.write(", ");
18120 self.generate_expression(&f.false_value)?;
18121 self.write(")");
18122 Ok(())
18123 }
18124
18125 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
18128 let count_name = match self.config.normalize_functions {
18130 NormalizeFunctions::Upper => "COUNT".to_string(),
18131 NormalizeFunctions::Lower => "count".to_string(),
18132 NormalizeFunctions::None => f
18133 .original_name
18134 .clone()
18135 .unwrap_or_else(|| "COUNT".to_string()),
18136 };
18137 self.write(&count_name);
18138 self.write("(");
18139 if f.distinct {
18140 self.write_keyword("DISTINCT");
18141 self.write_space();
18142 }
18143 if f.star {
18144 self.write("*");
18145 } else if let Some(ref expr) = f.this {
18146 if let Expression::Tuple(tuple) = expr {
18148 let needs_transform =
18152 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
18153
18154 if needs_transform {
18155 self.write_keyword("CASE");
18157 for e in &tuple.expressions {
18158 self.write_space();
18159 self.write_keyword("WHEN");
18160 self.write_space();
18161 self.generate_expression(e)?;
18162 self.write_space();
18163 self.write_keyword("IS NULL THEN NULL");
18164 }
18165 self.write_space();
18166 self.write_keyword("ELSE");
18167 self.write(" (");
18168 for (i, e) in tuple.expressions.iter().enumerate() {
18169 if i > 0 {
18170 self.write(", ");
18171 }
18172 self.generate_expression(e)?;
18173 }
18174 self.write(")");
18175 self.write_space();
18176 self.write_keyword("END");
18177 } else {
18178 for (i, e) in tuple.expressions.iter().enumerate() {
18179 if i > 0 {
18180 self.write(", ");
18181 }
18182 self.generate_expression(e)?;
18183 }
18184 }
18185 } else {
18186 self.generate_expression(expr)?;
18187 }
18188 }
18189 if let Some(ignore) = f.ignore_nulls {
18191 self.write_space();
18192 if ignore {
18193 self.write_keyword("IGNORE NULLS");
18194 } else {
18195 self.write_keyword("RESPECT NULLS");
18196 }
18197 }
18198 self.write(")");
18199 if let Some(ref filter) = f.filter {
18200 self.write_space();
18201 self.write_keyword("FILTER");
18202 self.write("(");
18203 self.write_keyword("WHERE");
18204 self.write_space();
18205 self.generate_expression(filter)?;
18206 self.write(")");
18207 }
18208 Ok(())
18209 }
18210
18211 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
18212 let func_name = match self.config.normalize_functions {
18214 NormalizeFunctions::Upper => name.to_uppercase(),
18215 NormalizeFunctions::Lower => name.to_lowercase(),
18216 NormalizeFunctions::None => {
18217 if let Some(ref original) = f.name {
18220 original.clone()
18221 } else {
18222 name.to_lowercase()
18223 }
18224 }
18225 };
18226 self.write(&func_name);
18227 self.write("(");
18228 if f.distinct {
18229 self.write_keyword("DISTINCT");
18230 self.write_space();
18231 }
18232 if !matches!(f.this, Expression::Null(_)) {
18234 self.generate_expression(&f.this)?;
18235 }
18236 if self.config.ignore_nulls_in_func
18239 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18240 {
18241 match f.ignore_nulls {
18242 Some(true) => {
18243 self.write_space();
18244 self.write_keyword("IGNORE NULLS");
18245 }
18246 Some(false) => {
18247 self.write_space();
18248 self.write_keyword("RESPECT NULLS");
18249 }
18250 None => {}
18251 }
18252 }
18253 if let Some((ref expr, is_max)) = f.having_max {
18256 self.write_space();
18257 self.write_keyword("HAVING");
18258 self.write_space();
18259 if is_max {
18260 self.write_keyword("MAX");
18261 } else {
18262 self.write_keyword("MIN");
18263 }
18264 self.write_space();
18265 self.generate_expression(expr)?;
18266 }
18267 if !f.order_by.is_empty() {
18269 self.write_space();
18270 self.write_keyword("ORDER BY");
18271 self.write_space();
18272 for (i, ord) in f.order_by.iter().enumerate() {
18273 if i > 0 {
18274 self.write(", ");
18275 }
18276 self.generate_ordered(ord)?;
18277 }
18278 }
18279 if let Some(ref limit) = f.limit {
18281 self.write_space();
18282 self.write_keyword("LIMIT");
18283 self.write_space();
18284 if let Expression::Tuple(t) = limit.as_ref() {
18286 if t.expressions.len() == 2 {
18287 self.generate_expression(&t.expressions[0])?;
18288 self.write(", ");
18289 self.generate_expression(&t.expressions[1])?;
18290 } else {
18291 self.generate_expression(limit)?;
18292 }
18293 } else {
18294 self.generate_expression(limit)?;
18295 }
18296 }
18297 self.write(")");
18298 if !self.config.ignore_nulls_in_func
18301 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18302 {
18303 match f.ignore_nulls {
18304 Some(true) => {
18305 self.write_space();
18306 self.write_keyword("IGNORE NULLS");
18307 }
18308 Some(false) => {
18309 self.write_space();
18310 self.write_keyword("RESPECT NULLS");
18311 }
18312 None => {}
18313 }
18314 }
18315 if let Some(ref filter) = f.filter {
18316 self.write_space();
18317 self.write_keyword("FILTER");
18318 self.write("(");
18319 self.write_keyword("WHERE");
18320 self.write_space();
18321 self.generate_expression(filter)?;
18322 self.write(")");
18323 }
18324 Ok(())
18325 }
18326
18327 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
18328 self.write_keyword("GROUP_CONCAT");
18329 self.write("(");
18330 if f.distinct {
18331 self.write_keyword("DISTINCT");
18332 self.write_space();
18333 }
18334 self.generate_expression(&f.this)?;
18335 if let Some(ref order_by) = f.order_by {
18336 self.write_space();
18337 self.write_keyword("ORDER BY");
18338 self.write_space();
18339 for (i, ord) in order_by.iter().enumerate() {
18340 if i > 0 {
18341 self.write(", ");
18342 }
18343 self.generate_ordered(ord)?;
18344 }
18345 }
18346 if let Some(ref sep) = f.separator {
18347 if matches!(
18350 self.config.dialect,
18351 Some(crate::dialects::DialectType::SQLite)
18352 ) {
18353 self.write(", ");
18354 self.generate_expression(sep)?;
18355 } else {
18356 self.write_space();
18357 self.write_keyword("SEPARATOR");
18358 self.write_space();
18359 self.generate_expression(sep)?;
18360 }
18361 }
18362 self.write(")");
18363 if let Some(ref filter) = f.filter {
18364 self.write_space();
18365 self.write_keyword("FILTER");
18366 self.write("(");
18367 self.write_keyword("WHERE");
18368 self.write_space();
18369 self.generate_expression(filter)?;
18370 self.write(")");
18371 }
18372 Ok(())
18373 }
18374
18375 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
18376 let is_tsql = matches!(
18377 self.config.dialect,
18378 Some(crate::dialects::DialectType::TSQL)
18379 );
18380 self.write_keyword("STRING_AGG");
18381 self.write("(");
18382 if f.distinct {
18383 self.write_keyword("DISTINCT");
18384 self.write_space();
18385 }
18386 self.generate_expression(&f.this)?;
18387 if let Some(ref separator) = f.separator {
18388 self.write(", ");
18389 self.generate_expression(separator)?;
18390 }
18391 if !is_tsql {
18393 if let Some(ref order_by) = f.order_by {
18394 self.write_space();
18395 self.write_keyword("ORDER BY");
18396 self.write_space();
18397 for (i, ord) in order_by.iter().enumerate() {
18398 if i > 0 {
18399 self.write(", ");
18400 }
18401 self.generate_ordered(ord)?;
18402 }
18403 }
18404 }
18405 if let Some(ref limit) = f.limit {
18406 self.write_space();
18407 self.write_keyword("LIMIT");
18408 self.write_space();
18409 self.generate_expression(limit)?;
18410 }
18411 self.write(")");
18412 if is_tsql {
18414 if let Some(ref order_by) = f.order_by {
18415 self.write_space();
18416 self.write_keyword("WITHIN GROUP");
18417 self.write(" (");
18418 self.write_keyword("ORDER BY");
18419 self.write_space();
18420 for (i, ord) in order_by.iter().enumerate() {
18421 if i > 0 {
18422 self.write(", ");
18423 }
18424 self.generate_ordered(ord)?;
18425 }
18426 self.write(")");
18427 }
18428 }
18429 if let Some(ref filter) = f.filter {
18430 self.write_space();
18431 self.write_keyword("FILTER");
18432 self.write("(");
18433 self.write_keyword("WHERE");
18434 self.write_space();
18435 self.generate_expression(filter)?;
18436 self.write(")");
18437 }
18438 Ok(())
18439 }
18440
18441 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
18442 use crate::dialects::DialectType;
18443 self.write_keyword("LISTAGG");
18444 self.write("(");
18445 if f.distinct {
18446 self.write_keyword("DISTINCT");
18447 self.write_space();
18448 }
18449 self.generate_expression(&f.this)?;
18450 if let Some(ref sep) = f.separator {
18451 self.write(", ");
18452 self.generate_expression(sep)?;
18453 } else if matches!(
18454 self.config.dialect,
18455 Some(DialectType::Trino) | Some(DialectType::Presto)
18456 ) {
18457 self.write(", ','");
18459 }
18460 if let Some(ref overflow) = f.on_overflow {
18461 self.write_space();
18462 self.write_keyword("ON OVERFLOW");
18463 self.write_space();
18464 match overflow {
18465 ListAggOverflow::Error => self.write_keyword("ERROR"),
18466 ListAggOverflow::Truncate { filler, with_count } => {
18467 self.write_keyword("TRUNCATE");
18468 if let Some(ref fill) = filler {
18469 self.write_space();
18470 self.generate_expression(fill)?;
18471 }
18472 if *with_count {
18473 self.write_space();
18474 self.write_keyword("WITH COUNT");
18475 } else {
18476 self.write_space();
18477 self.write_keyword("WITHOUT COUNT");
18478 }
18479 }
18480 }
18481 }
18482 self.write(")");
18483 if let Some(ref order_by) = f.order_by {
18484 self.write_space();
18485 self.write_keyword("WITHIN GROUP");
18486 self.write(" (");
18487 self.write_keyword("ORDER BY");
18488 self.write_space();
18489 for (i, ord) in order_by.iter().enumerate() {
18490 if i > 0 {
18491 self.write(", ");
18492 }
18493 self.generate_ordered(ord)?;
18494 }
18495 self.write(")");
18496 }
18497 if let Some(ref filter) = f.filter {
18498 self.write_space();
18499 self.write_keyword("FILTER");
18500 self.write("(");
18501 self.write_keyword("WHERE");
18502 self.write_space();
18503 self.generate_expression(filter)?;
18504 self.write(")");
18505 }
18506 Ok(())
18507 }
18508
18509 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
18510 self.write_keyword("SUM_IF");
18511 self.write("(");
18512 self.generate_expression(&f.this)?;
18513 self.write(", ");
18514 self.generate_expression(&f.condition)?;
18515 self.write(")");
18516 if let Some(ref filter) = f.filter {
18517 self.write_space();
18518 self.write_keyword("FILTER");
18519 self.write("(");
18520 self.write_keyword("WHERE");
18521 self.write_space();
18522 self.generate_expression(filter)?;
18523 self.write(")");
18524 }
18525 Ok(())
18526 }
18527
18528 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
18529 self.write_keyword("APPROX_PERCENTILE");
18530 self.write("(");
18531 self.generate_expression(&f.this)?;
18532 self.write(", ");
18533 self.generate_expression(&f.percentile)?;
18534 if let Some(ref acc) = f.accuracy {
18535 self.write(", ");
18536 self.generate_expression(acc)?;
18537 }
18538 self.write(")");
18539 if let Some(ref filter) = f.filter {
18540 self.write_space();
18541 self.write_keyword("FILTER");
18542 self.write("(");
18543 self.write_keyword("WHERE");
18544 self.write_space();
18545 self.generate_expression(filter)?;
18546 self.write(")");
18547 }
18548 Ok(())
18549 }
18550
18551 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
18552 self.write_keyword(name);
18553 self.write("(");
18554 self.generate_expression(&f.percentile)?;
18555 self.write(")");
18556 if let Some(ref order_by) = f.order_by {
18557 self.write_space();
18558 self.write_keyword("WITHIN GROUP");
18559 self.write(" (");
18560 self.write_keyword("ORDER BY");
18561 self.write_space();
18562 self.generate_expression(&f.this)?;
18563 for ord in order_by.iter() {
18564 if ord.desc {
18565 self.write_space();
18566 self.write_keyword("DESC");
18567 }
18568 }
18569 self.write(")");
18570 }
18571 if let Some(ref filter) = f.filter {
18572 self.write_space();
18573 self.write_keyword("FILTER");
18574 self.write("(");
18575 self.write_keyword("WHERE");
18576 self.write_space();
18577 self.generate_expression(filter)?;
18578 self.write(")");
18579 }
18580 Ok(())
18581 }
18582
18583 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
18586 self.write_keyword("NTILE");
18587 self.write("(");
18588 if let Some(num_buckets) = &f.num_buckets {
18589 self.generate_expression(num_buckets)?;
18590 }
18591 if let Some(order_by) = &f.order_by {
18592 self.write_keyword(" ORDER BY ");
18593 for (i, ob) in order_by.iter().enumerate() {
18594 if i > 0 {
18595 self.write(", ");
18596 }
18597 self.generate_ordered(ob)?;
18598 }
18599 }
18600 self.write(")");
18601 Ok(())
18602 }
18603
18604 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
18605 self.write_keyword(name);
18606 self.write("(");
18607 self.generate_expression(&f.this)?;
18608 if let Some(ref offset) = f.offset {
18609 self.write(", ");
18610 self.generate_expression(offset)?;
18611 if let Some(ref default) = f.default {
18612 self.write(", ");
18613 self.generate_expression(default)?;
18614 }
18615 }
18616 if f.ignore_nulls && self.config.ignore_nulls_in_func {
18618 self.write_space();
18619 self.write_keyword("IGNORE NULLS");
18620 }
18621 self.write(")");
18622 if f.ignore_nulls && !self.config.ignore_nulls_in_func {
18624 self.write_space();
18625 self.write_keyword("IGNORE NULLS");
18626 }
18627 Ok(())
18628 }
18629
18630 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
18631 self.write_keyword(name);
18632 self.write("(");
18633 self.generate_expression(&f.this)?;
18634 if self.config.ignore_nulls_in_func {
18636 match f.ignore_nulls {
18637 Some(true) => {
18638 self.write_space();
18639 self.write_keyword("IGNORE NULLS");
18640 }
18641 Some(false) => {
18642 self.write_space();
18643 self.write_keyword("RESPECT NULLS");
18644 }
18645 None => {}
18646 }
18647 }
18648 self.write(")");
18649 if !self.config.ignore_nulls_in_func {
18651 match f.ignore_nulls {
18652 Some(true) => {
18653 self.write_space();
18654 self.write_keyword("IGNORE NULLS");
18655 }
18656 Some(false) => {
18657 self.write_space();
18658 self.write_keyword("RESPECT NULLS");
18659 }
18660 None => {}
18661 }
18662 }
18663 Ok(())
18664 }
18665
18666 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
18667 self.write_keyword("NTH_VALUE");
18668 self.write("(");
18669 self.generate_expression(&f.this)?;
18670 self.write(", ");
18671 self.generate_expression(&f.offset)?;
18672 if self.config.ignore_nulls_in_func {
18674 match f.ignore_nulls {
18675 Some(true) => {
18676 self.write_space();
18677 self.write_keyword("IGNORE NULLS");
18678 }
18679 Some(false) => {
18680 self.write_space();
18681 self.write_keyword("RESPECT NULLS");
18682 }
18683 None => {}
18684 }
18685 }
18686 self.write(")");
18687 if matches!(
18689 self.config.dialect,
18690 Some(crate::dialects::DialectType::Snowflake)
18691 ) {
18692 match f.from_first {
18693 Some(true) => {
18694 self.write_space();
18695 self.write_keyword("FROM FIRST");
18696 }
18697 Some(false) => {
18698 self.write_space();
18699 self.write_keyword("FROM LAST");
18700 }
18701 None => {}
18702 }
18703 }
18704 if !self.config.ignore_nulls_in_func {
18706 match f.ignore_nulls {
18707 Some(true) => {
18708 self.write_space();
18709 self.write_keyword("IGNORE NULLS");
18710 }
18711 Some(false) => {
18712 self.write_space();
18713 self.write_keyword("RESPECT NULLS");
18714 }
18715 None => {}
18716 }
18717 }
18718 Ok(())
18719 }
18720
18721 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
18724 if matches!(
18727 self.config.dialect,
18728 Some(crate::dialects::DialectType::ClickHouse)
18729 ) {
18730 self.write_keyword("POSITION");
18731 self.write("(");
18732 self.generate_expression(&f.string)?;
18733 self.write(", ");
18734 self.generate_expression(&f.substring)?;
18735 if let Some(ref start) = f.start {
18736 self.write(", ");
18737 self.generate_expression(start)?;
18738 }
18739 self.write(")");
18740 return Ok(());
18741 }
18742
18743 self.write_keyword("POSITION");
18744 self.write("(");
18745 self.generate_expression(&f.substring)?;
18746 self.write_space();
18747 self.write_keyword("IN");
18748 self.write_space();
18749 self.generate_expression(&f.string)?;
18750 if let Some(ref start) = f.start {
18751 self.write(", ");
18752 self.generate_expression(start)?;
18753 }
18754 self.write(")");
18755 Ok(())
18756 }
18757
18758 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
18761 if f.lower.is_some() || f.upper.is_some() {
18763 self.write_keyword("RANDOM");
18764 self.write("(");
18765 if let Some(ref lower) = f.lower {
18766 self.generate_expression(lower)?;
18767 }
18768 if let Some(ref upper) = f.upper {
18769 self.write(", ");
18770 self.generate_expression(upper)?;
18771 }
18772 self.write(")");
18773 return Ok(());
18774 }
18775 let func_name = match self.config.dialect {
18777 Some(crate::dialects::DialectType::Snowflake)
18778 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
18779 _ => "RAND",
18780 };
18781 self.write_keyword(func_name);
18782 self.write("(");
18783 if !matches!(
18785 self.config.dialect,
18786 Some(crate::dialects::DialectType::DuckDB)
18787 ) {
18788 if let Some(ref seed) = f.seed {
18789 self.generate_expression(seed)?;
18790 }
18791 }
18792 self.write(")");
18793 Ok(())
18794 }
18795
18796 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
18797 self.write_keyword("TRUNCATE");
18798 self.write("(");
18799 self.generate_expression(&f.this)?;
18800 if let Some(ref decimals) = f.decimals {
18801 self.write(", ");
18802 self.generate_expression(decimals)?;
18803 }
18804 self.write(")");
18805 Ok(())
18806 }
18807
18808 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
18811 self.write_keyword("DECODE");
18812 self.write("(");
18813 self.generate_expression(&f.this)?;
18814 for (search, result) in &f.search_results {
18815 self.write(", ");
18816 self.generate_expression(search)?;
18817 self.write(", ");
18818 self.generate_expression(result)?;
18819 }
18820 if let Some(ref default) = f.default {
18821 self.write(", ");
18822 self.generate_expression(default)?;
18823 }
18824 self.write(")");
18825 Ok(())
18826 }
18827
18828 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
18831 self.write_keyword(name);
18832 self.write("(");
18833 self.generate_expression(&f.this)?;
18834 self.write(", ");
18835 self.generate_expression(&f.format)?;
18836 self.write(")");
18837 Ok(())
18838 }
18839
18840 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
18841 self.write_keyword("FROM_UNIXTIME");
18842 self.write("(");
18843 self.generate_expression(&f.this)?;
18844 if let Some(ref format) = f.format {
18845 self.write(", ");
18846 self.generate_expression(format)?;
18847 }
18848 self.write(")");
18849 Ok(())
18850 }
18851
18852 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
18853 self.write_keyword("UNIX_TIMESTAMP");
18854 self.write("(");
18855 if let Some(ref expr) = f.this {
18856 self.generate_expression(expr)?;
18857 if let Some(ref format) = f.format {
18858 self.write(", ");
18859 self.generate_expression(format)?;
18860 }
18861 } else if matches!(
18862 self.config.dialect,
18863 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
18864 ) {
18865 self.write_keyword("CURRENT_TIMESTAMP");
18867 self.write("()");
18868 }
18869 self.write(")");
18870 Ok(())
18871 }
18872
18873 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
18874 self.write_keyword("MAKE_DATE");
18875 self.write("(");
18876 self.generate_expression(&f.year)?;
18877 self.write(", ");
18878 self.generate_expression(&f.month)?;
18879 self.write(", ");
18880 self.generate_expression(&f.day)?;
18881 self.write(")");
18882 Ok(())
18883 }
18884
18885 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
18886 self.write_keyword("MAKE_TIMESTAMP");
18887 self.write("(");
18888 self.generate_expression(&f.year)?;
18889 self.write(", ");
18890 self.generate_expression(&f.month)?;
18891 self.write(", ");
18892 self.generate_expression(&f.day)?;
18893 self.write(", ");
18894 self.generate_expression(&f.hour)?;
18895 self.write(", ");
18896 self.generate_expression(&f.minute)?;
18897 self.write(", ");
18898 self.generate_expression(&f.second)?;
18899 if let Some(ref tz) = f.timezone {
18900 self.write(", ");
18901 self.generate_expression(tz)?;
18902 }
18903 self.write(")");
18904 Ok(())
18905 }
18906
18907 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
18909 match expr {
18910 Expression::Struct(s) => {
18911 if s.fields.iter().all(|(name, _)| name.is_some()) {
18912 Some(
18913 s.fields
18914 .iter()
18915 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
18916 .collect(),
18917 )
18918 } else {
18919 None
18920 }
18921 }
18922 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
18923 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
18925 Some(
18926 f.args
18927 .iter()
18928 .filter_map(|a| {
18929 if let Expression::Alias(alias) = a {
18930 Some(alias.alias.name.clone())
18931 } else {
18932 None
18933 }
18934 })
18935 .collect(),
18936 )
18937 } else {
18938 None
18939 }
18940 }
18941 _ => None,
18942 }
18943 }
18944
18945 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
18947 match expr {
18948 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
18949 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
18950 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
18951 }
18952 _ => false,
18953 }
18954 }
18955
18956 fn struct_field_count(expr: &Expression) -> usize {
18958 match expr {
18959 Expression::Struct(s) => s.fields.len(),
18960 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => f.args.len(),
18961 _ => 0,
18962 }
18963 }
18964
18965 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
18967 match expr {
18968 Expression::Struct(s) => {
18969 let mut new_fields = Vec::with_capacity(s.fields.len());
18970 for (i, (name, value)) in s.fields.iter().enumerate() {
18971 if name.is_none() && i < field_names.len() {
18972 new_fields.push((Some(field_names[i].clone()), value.clone()));
18973 } else {
18974 new_fields.push((name.clone(), value.clone()));
18975 }
18976 }
18977 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
18978 }
18979 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
18980 let mut new_args = Vec::with_capacity(f.args.len());
18981 for (i, arg) in f.args.iter().enumerate() {
18982 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
18983 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
18985 this: arg.clone(),
18986 alias: crate::expressions::Identifier::new(field_names[i].clone()),
18987 column_aliases: Vec::new(),
18988 pre_alias_comments: Vec::new(),
18989 trailing_comments: Vec::new(),
18990 })));
18991 } else {
18992 new_args.push(arg.clone());
18993 }
18994 }
18995 Expression::Function(Box::new(crate::expressions::Function {
18996 name: f.name.clone(),
18997 args: new_args,
18998 distinct: f.distinct,
18999 trailing_comments: f.trailing_comments.clone(),
19000 use_bracket_syntax: f.use_bracket_syntax,
19001 no_parens: f.no_parens,
19002 quoted: f.quoted,
19003 }))
19004 }
19005 _ => expr.clone(),
19006 }
19007 }
19008
19009 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
19013 let first = match expressions.first() {
19014 Some(e) => e,
19015 None => return expressions.to_vec(),
19016 };
19017
19018 let field_names = match Self::extract_struct_field_names(first) {
19019 Some(names) if !names.is_empty() => names,
19020 _ => return expressions.to_vec(),
19021 };
19022
19023 let mut result = Vec::with_capacity(expressions.len());
19024 for (idx, expr) in expressions.iter().enumerate() {
19025 if idx == 0 {
19026 result.push(expr.clone());
19027 continue;
19028 }
19029 if Self::struct_field_count(expr) == field_names.len()
19031 && Self::struct_has_unnamed_fields(expr)
19032 {
19033 result.push(Self::apply_struct_field_names(expr, &field_names));
19034 } else {
19035 result.push(expr.clone());
19036 }
19037 }
19038 result
19039 }
19040
19041 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
19044 let needs_inheritance = matches!(
19047 self.config.dialect,
19048 Some(DialectType::DuckDB)
19049 | Some(DialectType::Spark)
19050 | Some(DialectType::Databricks)
19051 | Some(DialectType::Hive)
19052 | Some(DialectType::Snowflake)
19053 | Some(DialectType::Presto)
19054 | Some(DialectType::Trino)
19055 );
19056 let propagated: Vec<Expression>;
19057 let expressions = if needs_inheritance && f.expressions.len() > 1 {
19058 propagated = Self::inherit_struct_field_names(&f.expressions);
19059 &propagated
19060 } else {
19061 &f.expressions
19062 };
19063
19064 let should_split = if self.config.pretty && !expressions.is_empty() {
19066 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
19067 for expr in expressions {
19068 let mut temp_gen = Generator::with_config(self.config.clone());
19069 temp_gen.config.pretty = false;
19070 temp_gen.generate_expression(expr)?;
19071 expr_strings.push(temp_gen.output);
19072 }
19073 self.too_wide(&expr_strings)
19074 } else {
19075 false
19076 };
19077
19078 if f.bracket_notation {
19079 let (open, close) = match self.config.dialect {
19083 None
19084 | Some(DialectType::Generic)
19085 | Some(DialectType::Spark)
19086 | Some(DialectType::Databricks)
19087 | Some(DialectType::Hive) => {
19088 self.write_keyword("ARRAY");
19089 ("(", ")")
19090 }
19091 Some(DialectType::Presto)
19092 | Some(DialectType::Trino)
19093 | Some(DialectType::PostgreSQL)
19094 | Some(DialectType::Redshift)
19095 | Some(DialectType::Materialize)
19096 | Some(DialectType::RisingWave)
19097 | Some(DialectType::CockroachDB) => {
19098 self.write_keyword("ARRAY");
19099 ("[", "]")
19100 }
19101 _ => ("[", "]"),
19102 };
19103 self.write(open);
19104 if should_split {
19105 self.write_newline();
19106 self.indent_level += 1;
19107 for (i, expr) in expressions.iter().enumerate() {
19108 self.write_indent();
19109 self.generate_expression(expr)?;
19110 if i + 1 < expressions.len() {
19111 self.write(",");
19112 }
19113 self.write_newline();
19114 }
19115 self.indent_level -= 1;
19116 self.write_indent();
19117 } else {
19118 for (i, expr) in expressions.iter().enumerate() {
19119 if i > 0 {
19120 self.write(", ");
19121 }
19122 self.generate_expression(expr)?;
19123 }
19124 }
19125 self.write(close);
19126 } else {
19127 if f.use_list_keyword {
19129 self.write_keyword("LIST");
19130 } else {
19131 self.write_keyword("ARRAY");
19132 }
19133 let has_subquery = expressions
19136 .iter()
19137 .any(|e| matches!(e, Expression::Select(_)));
19138 let (open, close) = if matches!(
19139 self.config.dialect,
19140 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
19141 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
19142 && has_subquery)
19143 {
19144 ("(", ")")
19145 } else {
19146 ("[", "]")
19147 };
19148 self.write(open);
19149 if should_split {
19150 self.write_newline();
19151 self.indent_level += 1;
19152 for (i, expr) in expressions.iter().enumerate() {
19153 self.write_indent();
19154 self.generate_expression(expr)?;
19155 if i + 1 < expressions.len() {
19156 self.write(",");
19157 }
19158 self.write_newline();
19159 }
19160 self.indent_level -= 1;
19161 self.write_indent();
19162 } else {
19163 for (i, expr) in expressions.iter().enumerate() {
19164 if i > 0 {
19165 self.write(", ");
19166 }
19167 self.generate_expression(expr)?;
19168 }
19169 }
19170 self.write(close);
19171 }
19172 Ok(())
19173 }
19174
19175 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
19176 self.write_keyword("ARRAY_SORT");
19177 self.write("(");
19178 self.generate_expression(&f.this)?;
19179 if let Some(ref comp) = f.comparator {
19180 self.write(", ");
19181 self.generate_expression(comp)?;
19182 }
19183 self.write(")");
19184 Ok(())
19185 }
19186
19187 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
19188 self.write_keyword(name);
19189 self.write("(");
19190 self.generate_expression(&f.this)?;
19191 self.write(", ");
19192 self.generate_expression(&f.separator)?;
19193 if let Some(ref null_rep) = f.null_replacement {
19194 self.write(", ");
19195 self.generate_expression(null_rep)?;
19196 }
19197 self.write(")");
19198 Ok(())
19199 }
19200
19201 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
19202 self.write_keyword("UNNEST");
19203 self.write("(");
19204 self.generate_expression(&f.this)?;
19205 for extra in &f.expressions {
19206 self.write(", ");
19207 self.generate_expression(extra)?;
19208 }
19209 self.write(")");
19210 if f.with_ordinality {
19211 self.write_space();
19212 if self.config.unnest_with_ordinality {
19213 self.write_keyword("WITH ORDINALITY");
19215 } else if f.offset_alias.is_some() {
19216 if let Some(ref alias) = f.alias {
19219 self.write_keyword("AS");
19220 self.write_space();
19221 self.generate_identifier(alias)?;
19222 self.write_space();
19223 }
19224 self.write_keyword("WITH OFFSET");
19225 if let Some(ref offset_alias) = f.offset_alias {
19226 self.write_space();
19227 self.write_keyword("AS");
19228 self.write_space();
19229 self.generate_identifier(offset_alias)?;
19230 }
19231 } else {
19232 self.write_keyword("WITH OFFSET");
19234 if f.alias.is_none() {
19235 self.write(" AS offset");
19236 }
19237 }
19238 }
19239 if let Some(ref alias) = f.alias {
19240 let should_add_alias = if !f.with_ordinality {
19242 true
19243 } else if self.config.unnest_with_ordinality {
19244 true
19246 } else if f.offset_alias.is_some() {
19247 false
19249 } else {
19250 true
19252 };
19253 if should_add_alias {
19254 self.write_space();
19255 self.write_keyword("AS");
19256 self.write_space();
19257 self.generate_identifier(alias)?;
19258 }
19259 }
19260 Ok(())
19261 }
19262
19263 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
19264 self.write_keyword("FILTER");
19265 self.write("(");
19266 self.generate_expression(&f.this)?;
19267 self.write(", ");
19268 self.generate_expression(&f.filter)?;
19269 self.write(")");
19270 Ok(())
19271 }
19272
19273 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
19274 self.write_keyword("TRANSFORM");
19275 self.write("(");
19276 self.generate_expression(&f.this)?;
19277 self.write(", ");
19278 self.generate_expression(&f.transform)?;
19279 self.write(")");
19280 Ok(())
19281 }
19282
19283 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
19284 self.write_keyword(name);
19285 self.write("(");
19286 self.generate_expression(&f.start)?;
19287 self.write(", ");
19288 self.generate_expression(&f.stop)?;
19289 if let Some(ref step) = f.step {
19290 self.write(", ");
19291 self.generate_expression(step)?;
19292 }
19293 self.write(")");
19294 Ok(())
19295 }
19296
19297 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
19300 self.write_keyword("STRUCT");
19301 self.write("(");
19302 for (i, (name, expr)) in f.fields.iter().enumerate() {
19303 if i > 0 {
19304 self.write(", ");
19305 }
19306 if let Some(ref id) = name {
19307 self.generate_identifier(id)?;
19308 self.write(" ");
19309 self.write_keyword("AS");
19310 self.write(" ");
19311 }
19312 self.generate_expression(expr)?;
19313 }
19314 self.write(")");
19315 Ok(())
19316 }
19317
19318 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
19320 let mut names: Vec<Option<String>> = Vec::new();
19323 let mut values: Vec<&Expression> = Vec::new();
19324 let mut all_named = true;
19325
19326 for arg in &func.args {
19327 match arg {
19328 Expression::Alias(a) => {
19329 names.push(Some(a.alias.name.clone()));
19330 values.push(&a.this);
19331 }
19332 _ => {
19333 names.push(None);
19334 values.push(arg);
19335 all_named = false;
19336 }
19337 }
19338 }
19339
19340 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
19341 self.write("{");
19343 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19344 if i > 0 {
19345 self.write(", ");
19346 }
19347 if let Some(n) = name {
19348 self.write("'");
19349 self.write(n);
19350 self.write("'");
19351 } else {
19352 self.write("'_");
19353 self.write(&i.to_string());
19354 self.write("'");
19355 }
19356 self.write(": ");
19357 self.generate_expression(value)?;
19358 }
19359 self.write("}");
19360 return Ok(());
19361 }
19362
19363 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
19364 self.write_keyword("OBJECT_CONSTRUCT");
19366 self.write("(");
19367 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19368 if i > 0 {
19369 self.write(", ");
19370 }
19371 if let Some(n) = name {
19372 self.write("'");
19373 self.write(n);
19374 self.write("'");
19375 } else {
19376 self.write("'_");
19377 self.write(&i.to_string());
19378 self.write("'");
19379 }
19380 self.write(", ");
19381 self.generate_expression(value)?;
19382 }
19383 self.write(")");
19384 return Ok(());
19385 }
19386
19387 if matches!(
19388 self.config.dialect,
19389 Some(DialectType::Presto) | Some(DialectType::Trino)
19390 ) {
19391 if all_named && !names.is_empty() {
19392 self.write_keyword("CAST");
19395 self.write("(");
19396 self.write_keyword("ROW");
19397 self.write("(");
19398 for (i, value) in values.iter().enumerate() {
19399 if i > 0 {
19400 self.write(", ");
19401 }
19402 self.generate_expression(value)?;
19403 }
19404 self.write(")");
19405 self.write(" ");
19406 self.write_keyword("AS");
19407 self.write(" ");
19408 self.write_keyword("ROW");
19409 self.write("(");
19410 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19411 if i > 0 {
19412 self.write(", ");
19413 }
19414 if let Some(n) = name {
19415 self.write(n);
19416 }
19417 self.write(" ");
19418 let type_str = Self::infer_sql_type_for_presto(value);
19419 self.write_keyword(&type_str);
19420 }
19421 self.write(")");
19422 self.write(")");
19423 } else {
19424 self.write_keyword("ROW");
19426 self.write("(");
19427 for (i, value) in values.iter().enumerate() {
19428 if i > 0 {
19429 self.write(", ");
19430 }
19431 self.generate_expression(value)?;
19432 }
19433 self.write(")");
19434 }
19435 return Ok(());
19436 }
19437
19438 self.write_keyword("ROW");
19440 self.write("(");
19441 for (i, value) in values.iter().enumerate() {
19442 if i > 0 {
19443 self.write(", ");
19444 }
19445 self.generate_expression(value)?;
19446 }
19447 self.write(")");
19448 Ok(())
19449 }
19450
19451 fn infer_sql_type_for_presto(expr: &Expression) -> String {
19453 match expr {
19454 Expression::Literal(crate::expressions::Literal::String(_)) => "VARCHAR".to_string(),
19455 Expression::Literal(crate::expressions::Literal::Number(n)) => {
19456 if n.contains('.') {
19457 "DOUBLE".to_string()
19458 } else {
19459 "INTEGER".to_string()
19460 }
19461 }
19462 Expression::Boolean(_) => "BOOLEAN".to_string(),
19463 Expression::Literal(crate::expressions::Literal::Date(_)) => "DATE".to_string(),
19464 Expression::Literal(crate::expressions::Literal::Timestamp(_)) => {
19465 "TIMESTAMP".to_string()
19466 }
19467 Expression::Literal(crate::expressions::Literal::Datetime(_)) => {
19468 "TIMESTAMP".to_string()
19469 }
19470 Expression::Array(_) | Expression::ArrayFunc(_) => {
19471 "ARRAY(VARCHAR)".to_string()
19473 }
19474 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
19476 Expression::Function(f) => {
19477 let up = f.name.to_uppercase();
19478 if up == "STRUCT" {
19479 "ROW".to_string()
19480 } else if up == "CURRENT_DATE" {
19481 "DATE".to_string()
19482 } else if up == "CURRENT_TIMESTAMP" || up == "NOW" {
19483 "TIMESTAMP".to_string()
19484 } else {
19485 "VARCHAR".to_string()
19486 }
19487 }
19488 _ => "VARCHAR".to_string(),
19489 }
19490 }
19491
19492 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
19493 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
19495 self.write_keyword("STRUCT_EXTRACT");
19496 self.write("(");
19497 self.generate_expression(&f.this)?;
19498 self.write(", ");
19499 self.write("'");
19501 self.write(&f.field.name);
19502 self.write("'");
19503 self.write(")");
19504 return Ok(());
19505 }
19506 self.generate_expression(&f.this)?;
19507 self.write(".");
19508 self.generate_identifier(&f.field)
19509 }
19510
19511 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
19512 self.write_keyword("NAMED_STRUCT");
19513 self.write("(");
19514 for (i, (name, value)) in f.pairs.iter().enumerate() {
19515 if i > 0 {
19516 self.write(", ");
19517 }
19518 self.generate_expression(name)?;
19519 self.write(", ");
19520 self.generate_expression(value)?;
19521 }
19522 self.write(")");
19523 Ok(())
19524 }
19525
19526 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
19529 if f.curly_brace_syntax {
19530 if f.with_map_keyword {
19532 self.write_keyword("MAP");
19533 self.write(" ");
19534 }
19535 self.write("{");
19536 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
19537 if i > 0 {
19538 self.write(", ");
19539 }
19540 self.generate_expression(key)?;
19541 self.write(": ");
19542 self.generate_expression(val)?;
19543 }
19544 self.write("}");
19545 } else {
19546 self.write_keyword("MAP");
19548 self.write("(");
19549 self.write_keyword("ARRAY");
19550 self.write("[");
19551 for (i, key) in f.keys.iter().enumerate() {
19552 if i > 0 {
19553 self.write(", ");
19554 }
19555 self.generate_expression(key)?;
19556 }
19557 self.write("], ");
19558 self.write_keyword("ARRAY");
19559 self.write("[");
19560 for (i, val) in f.values.iter().enumerate() {
19561 if i > 0 {
19562 self.write(", ");
19563 }
19564 self.generate_expression(val)?;
19565 }
19566 self.write("])");
19567 }
19568 Ok(())
19569 }
19570
19571 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
19572 self.write_keyword(name);
19573 self.write("(");
19574 self.generate_expression(&f.this)?;
19575 self.write(", ");
19576 self.generate_expression(&f.transform)?;
19577 self.write(")");
19578 Ok(())
19579 }
19580
19581 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
19584 use crate::dialects::DialectType;
19585
19586 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
19588
19589 if use_arrow {
19590 self.generate_expression(&f.this)?;
19592 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
19593 self.write(" ->> ");
19594 } else {
19595 self.write(" -> ");
19596 }
19597 self.generate_expression(&f.path)?;
19598 return Ok(());
19599 }
19600
19601 if f.hash_arrow_syntax
19603 && matches!(
19604 self.config.dialect,
19605 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19606 )
19607 {
19608 self.generate_expression(&f.this)?;
19609 self.write(" #>> ");
19610 self.generate_expression(&f.path)?;
19611 return Ok(());
19612 }
19613
19614 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
19617 match name {
19618 "JSON_EXTRACT_SCALAR"
19619 | "JSON_EXTRACT_PATH_TEXT"
19620 | "JSON_EXTRACT"
19621 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
19622 _ => name,
19623 }
19624 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
19625 match name {
19626 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
19627 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
19628 _ => name,
19629 }
19630 } else {
19631 name
19632 };
19633
19634 self.write_keyword(func_name);
19635 self.write("(");
19636 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
19638 if let Expression::Cast(ref cast) = f.this {
19639 if matches!(cast.to, crate::expressions::DataType::Json) {
19640 self.generate_expression(&cast.this)?;
19641 } else {
19642 self.generate_expression(&f.this)?;
19643 }
19644 } else {
19645 self.generate_expression(&f.this)?;
19646 }
19647 } else {
19648 self.generate_expression(&f.this)?;
19649 }
19650 if matches!(
19653 self.config.dialect,
19654 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19655 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
19656 {
19657 if let Expression::Literal(Literal::String(ref s)) = f.path {
19658 let parts = Self::decompose_json_path(s);
19659 for part in &parts {
19660 self.write(", '");
19661 self.write(part);
19662 self.write("'");
19663 }
19664 } else {
19665 self.write(", ");
19666 self.generate_expression(&f.path)?;
19667 }
19668 } else {
19669 self.write(", ");
19670 self.generate_expression(&f.path)?;
19671 }
19672
19673 if let Some(ref wrapper) = f.wrapper_option {
19676 self.write_space();
19677 self.write_keyword(wrapper);
19678 }
19679 if let Some(ref quotes) = f.quotes_option {
19680 self.write_space();
19681 self.write_keyword(quotes);
19682 if f.on_scalar_string {
19683 self.write_space();
19684 self.write_keyword("ON SCALAR STRING");
19685 }
19686 }
19687 if let Some(ref on_err) = f.on_error {
19688 self.write_space();
19689 self.write_keyword(on_err);
19690 }
19691 if let Some(ref ret_type) = f.returning {
19692 self.write_space();
19693 self.write_keyword("RETURNING");
19694 self.write_space();
19695 self.generate_data_type(ret_type)?;
19696 }
19697
19698 self.write(")");
19699 Ok(())
19700 }
19701
19702 fn dialect_supports_json_arrow(&self) -> bool {
19704 use crate::dialects::DialectType;
19705 match self.config.dialect {
19706 Some(DialectType::PostgreSQL) => true,
19708 Some(DialectType::MySQL) => true,
19709 Some(DialectType::DuckDB) => true,
19710 Some(DialectType::CockroachDB) => true,
19711 Some(DialectType::StarRocks) => true,
19712 Some(DialectType::SQLite) => true,
19713 _ => false,
19715 }
19716 }
19717
19718 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
19719 use crate::dialects::DialectType;
19720
19721 if matches!(
19723 self.config.dialect,
19724 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19725 ) && name == "JSON_EXTRACT_PATH"
19726 {
19727 self.generate_expression(&f.this)?;
19728 self.write(" #> ");
19729 if f.paths.len() == 1 {
19730 self.generate_expression(&f.paths[0])?;
19731 } else {
19732 self.write_keyword("ARRAY");
19734 self.write("[");
19735 for (i, path) in f.paths.iter().enumerate() {
19736 if i > 0 {
19737 self.write(", ");
19738 }
19739 self.generate_expression(path)?;
19740 }
19741 self.write("]");
19742 }
19743 return Ok(());
19744 }
19745
19746 self.write_keyword(name);
19747 self.write("(");
19748 self.generate_expression(&f.this)?;
19749 for path in &f.paths {
19750 self.write(", ");
19751 self.generate_expression(path)?;
19752 }
19753 self.write(")");
19754 Ok(())
19755 }
19756
19757 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
19758 use crate::dialects::DialectType;
19759
19760 self.write_keyword("JSON_OBJECT");
19761 self.write("(");
19762 if f.star {
19763 self.write("*");
19764 } else {
19765 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
19769 || matches!(
19770 self.config.dialect,
19771 Some(DialectType::BigQuery)
19772 | Some(DialectType::MySQL)
19773 | Some(DialectType::SQLite)
19774 );
19775
19776 for (i, (key, value)) in f.pairs.iter().enumerate() {
19777 if i > 0 {
19778 self.write(", ");
19779 }
19780 self.generate_expression(key)?;
19781 if use_comma_syntax {
19782 self.write(", ");
19783 } else {
19784 self.write(": ");
19785 }
19786 self.generate_expression(value)?;
19787 }
19788 }
19789 if let Some(null_handling) = f.null_handling {
19790 self.write_space();
19791 match null_handling {
19792 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19793 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19794 }
19795 }
19796 if f.with_unique_keys {
19797 self.write_space();
19798 self.write_keyword("WITH UNIQUE KEYS");
19799 }
19800 if let Some(ref ret_type) = f.returning_type {
19801 self.write_space();
19802 self.write_keyword("RETURNING");
19803 self.write_space();
19804 self.generate_data_type(ret_type)?;
19805 if f.format_json {
19806 self.write_space();
19807 self.write_keyword("FORMAT JSON");
19808 }
19809 if let Some(ref enc) = f.encoding {
19810 self.write_space();
19811 self.write_keyword("ENCODING");
19812 self.write_space();
19813 self.write(enc);
19814 }
19815 }
19816 self.write(")");
19817 Ok(())
19818 }
19819
19820 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
19821 self.write_keyword(name);
19822 self.write("(");
19823 self.generate_expression(&f.this)?;
19824 for (path, value) in &f.path_values {
19825 self.write(", ");
19826 self.generate_expression(path)?;
19827 self.write(", ");
19828 self.generate_expression(value)?;
19829 }
19830 self.write(")");
19831 Ok(())
19832 }
19833
19834 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
19835 self.write_keyword("JSON_ARRAYAGG");
19836 self.write("(");
19837 self.generate_expression(&f.this)?;
19838 if let Some(ref order_by) = f.order_by {
19839 self.write_space();
19840 self.write_keyword("ORDER BY");
19841 self.write_space();
19842 for (i, ord) in order_by.iter().enumerate() {
19843 if i > 0 {
19844 self.write(", ");
19845 }
19846 self.generate_ordered(ord)?;
19847 }
19848 }
19849 if let Some(null_handling) = f.null_handling {
19850 self.write_space();
19851 match null_handling {
19852 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19853 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19854 }
19855 }
19856 self.write(")");
19857 if let Some(ref filter) = f.filter {
19858 self.write_space();
19859 self.write_keyword("FILTER");
19860 self.write("(");
19861 self.write_keyword("WHERE");
19862 self.write_space();
19863 self.generate_expression(filter)?;
19864 self.write(")");
19865 }
19866 Ok(())
19867 }
19868
19869 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
19870 self.write_keyword("JSON_OBJECTAGG");
19871 self.write("(");
19872 self.generate_expression(&f.key)?;
19873 self.write(": ");
19874 self.generate_expression(&f.value)?;
19875 if let Some(null_handling) = f.null_handling {
19876 self.write_space();
19877 match null_handling {
19878 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19879 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19880 }
19881 }
19882 self.write(")");
19883 if let Some(ref filter) = f.filter {
19884 self.write_space();
19885 self.write_keyword("FILTER");
19886 self.write("(");
19887 self.write_keyword("WHERE");
19888 self.write_space();
19889 self.generate_expression(filter)?;
19890 self.write(")");
19891 }
19892 Ok(())
19893 }
19894
19895 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
19898 use crate::dialects::DialectType;
19899
19900 if self.config.dialect == Some(DialectType::Redshift) {
19902 self.write_keyword("CAST");
19903 self.write("(");
19904 self.generate_expression(&f.this)?;
19905 self.write_space();
19906 self.write_keyword("AS");
19907 self.write_space();
19908 self.generate_data_type(&f.to)?;
19909 self.write(")");
19910 return Ok(());
19911 }
19912
19913 self.write_keyword("CONVERT");
19914 self.write("(");
19915 self.generate_data_type(&f.to)?;
19916 self.write(", ");
19917 self.generate_expression(&f.this)?;
19918 if let Some(ref style) = f.style {
19919 self.write(", ");
19920 self.generate_expression(style)?;
19921 }
19922 self.write(")");
19923 Ok(())
19924 }
19925
19926 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
19929 if f.colon {
19930 self.write_keyword("LAMBDA");
19932 self.write_space();
19933 for (i, param) in f.parameters.iter().enumerate() {
19934 if i > 0 {
19935 self.write(", ");
19936 }
19937 self.generate_identifier(param)?;
19938 }
19939 self.write(" : ");
19940 } else {
19941 if f.parameters.len() == 1 {
19943 self.generate_identifier(&f.parameters[0])?;
19944 } else {
19945 self.write("(");
19946 for (i, param) in f.parameters.iter().enumerate() {
19947 if i > 0 {
19948 self.write(", ");
19949 }
19950 self.generate_identifier(param)?;
19951 }
19952 self.write(")");
19953 }
19954 self.write(" -> ");
19955 }
19956 self.generate_expression(&f.body)
19957 }
19958
19959 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
19960 self.generate_identifier(&f.name)?;
19961 match f.separator {
19962 NamedArgSeparator::DArrow => self.write(" => "),
19963 NamedArgSeparator::ColonEq => self.write(" := "),
19964 NamedArgSeparator::Eq => self.write(" = "),
19965 }
19966 self.generate_expression(&f.value)
19967 }
19968
19969 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
19970 self.write_keyword(&f.prefix);
19971 self.write(" ");
19972 self.generate_expression(&f.this)
19973 }
19974
19975 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
19976 match f.style {
19977 ParameterStyle::Question => self.write("?"),
19978 ParameterStyle::Dollar => {
19979 self.write("$");
19980 if let Some(idx) = f.index {
19981 self.write(&idx.to_string());
19982 } else if let Some(ref name) = f.name {
19983 self.write(name);
19985 }
19986 }
19987 ParameterStyle::DollarBrace => {
19988 self.write("${");
19990 if let Some(ref name) = f.name {
19991 self.write(name);
19992 }
19993 if let Some(ref expr) = f.expression {
19994 self.write(":");
19995 self.write(expr);
19996 }
19997 self.write("}");
19998 }
19999 ParameterStyle::Colon => {
20000 self.write(":");
20001 if let Some(idx) = f.index {
20002 self.write(&idx.to_string());
20003 } else if let Some(ref name) = f.name {
20004 self.write(name);
20005 }
20006 }
20007 ParameterStyle::At => {
20008 self.write("@");
20009 if let Some(ref name) = f.name {
20010 if f.string_quoted {
20011 self.write("'");
20012 self.write(name);
20013 self.write("'");
20014 } else if f.quoted {
20015 self.write("\"");
20016 self.write(name);
20017 self.write("\"");
20018 } else {
20019 self.write(name);
20020 }
20021 }
20022 }
20023 ParameterStyle::DoubleAt => {
20024 self.write("@@");
20025 if let Some(ref name) = f.name {
20026 self.write(name);
20027 }
20028 }
20029 ParameterStyle::DoubleDollar => {
20030 self.write("$$");
20031 if let Some(ref name) = f.name {
20032 self.write(name);
20033 }
20034 }
20035 ParameterStyle::Percent => {
20036 if let Some(ref name) = f.name {
20037 self.write("%(");
20039 self.write(name);
20040 self.write(")s");
20041 } else {
20042 self.write("%s");
20044 }
20045 }
20046 ParameterStyle::Brace => {
20047 self.write("{");
20050 if let Some(ref name) = f.name {
20051 self.write(name);
20052 }
20053 if let Some(ref expr) = f.expression {
20054 self.write(": ");
20055 self.write(expr);
20056 }
20057 self.write("}");
20058 }
20059 }
20060 Ok(())
20061 }
20062
20063 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
20064 self.write("?");
20065 if let Some(idx) = f.index {
20066 self.write(&idx.to_string());
20067 }
20068 Ok(())
20069 }
20070
20071 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
20072 if f.is_block {
20073 self.write("/*");
20074 self.write(&f.text);
20075 self.write("*/");
20076 } else {
20077 self.write("--");
20078 self.write(&f.text);
20079 }
20080 Ok(())
20081 }
20082
20083 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
20086 self.generate_expression(&f.this)?;
20087 if f.not {
20088 self.write_space();
20089 self.write_keyword("NOT");
20090 }
20091 self.write_space();
20092 self.write_keyword("SIMILAR TO");
20093 self.write_space();
20094 self.generate_expression(&f.pattern)?;
20095 if let Some(ref escape) = f.escape {
20096 self.write_space();
20097 self.write_keyword("ESCAPE");
20098 self.write_space();
20099 self.generate_expression(escape)?;
20100 }
20101 Ok(())
20102 }
20103
20104 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
20105 self.generate_expression(&f.this)?;
20106 self.write_space();
20107 if let Some(op) = &f.op {
20109 match op {
20110 QuantifiedOp::Eq => self.write("="),
20111 QuantifiedOp::Neq => self.write("<>"),
20112 QuantifiedOp::Lt => self.write("<"),
20113 QuantifiedOp::Lte => self.write("<="),
20114 QuantifiedOp::Gt => self.write(">"),
20115 QuantifiedOp::Gte => self.write(">="),
20116 }
20117 self.write_space();
20118 }
20119 self.write_keyword(name);
20120
20121 if matches!(&f.subquery, Expression::Subquery(_)) {
20123 self.write_space();
20124 self.generate_expression(&f.subquery)?;
20125 } else {
20126 self.write("(");
20127
20128 let is_statement = matches!(
20129 &f.subquery,
20130 Expression::Select(_)
20131 | Expression::Union(_)
20132 | Expression::Intersect(_)
20133 | Expression::Except(_)
20134 );
20135
20136 if self.config.pretty && is_statement {
20137 self.write_newline();
20138 self.indent_level += 1;
20139 self.write_indent();
20140 }
20141 self.generate_expression(&f.subquery)?;
20142 if self.config.pretty && is_statement {
20143 self.write_newline();
20144 self.indent_level -= 1;
20145 self.write_indent();
20146 }
20147 self.write(")");
20148 }
20149 Ok(())
20150 }
20151
20152 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
20153 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
20155 self.generate_expression(this)?;
20156 self.write_space();
20157 self.write_keyword("OVERLAPS");
20158 self.write_space();
20159 self.generate_expression(expr)?;
20160 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
20161 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
20162 {
20163 self.write("(");
20165 self.generate_expression(ls)?;
20166 self.write(", ");
20167 self.generate_expression(le)?;
20168 self.write(")");
20169 self.write_space();
20170 self.write_keyword("OVERLAPS");
20171 self.write_space();
20172 self.write("(");
20173 self.generate_expression(rs)?;
20174 self.write(", ");
20175 self.generate_expression(re)?;
20176 self.write(")");
20177 }
20178 Ok(())
20179 }
20180
20181 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
20184 use crate::dialects::DialectType;
20185
20186 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
20188 self.generate_expression(&cast.this)?;
20189 self.write(" !:> ");
20190 self.generate_data_type(&cast.to)?;
20191 return Ok(());
20192 }
20193
20194 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
20196 self.write_keyword("TRYCAST");
20197 self.write("(");
20198 self.generate_expression(&cast.this)?;
20199 self.write_space();
20200 self.write_keyword("AS");
20201 self.write_space();
20202 self.generate_data_type(&cast.to)?;
20203 self.write(")");
20204 return Ok(());
20205 }
20206
20207 let keyword = if matches!(
20209 self.config.dialect,
20210 Some(DialectType::Hive)
20211 | Some(DialectType::MySQL)
20212 | Some(DialectType::SQLite)
20213 | Some(DialectType::Oracle)
20214 | Some(DialectType::ClickHouse)
20215 | Some(DialectType::Redshift)
20216 | Some(DialectType::PostgreSQL)
20217 | Some(DialectType::StarRocks)
20218 | Some(DialectType::Doris)
20219 ) {
20220 "CAST"
20221 } else {
20222 "TRY_CAST"
20223 };
20224
20225 self.write_keyword(keyword);
20226 self.write("(");
20227 self.generate_expression(&cast.this)?;
20228 self.write_space();
20229 self.write_keyword("AS");
20230 self.write_space();
20231 self.generate_data_type(&cast.to)?;
20232
20233 if let Some(format) = &cast.format {
20235 self.write_space();
20236 self.write_keyword("FORMAT");
20237 self.write_space();
20238 self.generate_expression(format)?;
20239 }
20240
20241 self.write(")");
20242 Ok(())
20243 }
20244
20245 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
20246 self.write_keyword("SAFE_CAST");
20247 self.write("(");
20248 self.generate_expression(&cast.this)?;
20249 self.write_space();
20250 self.write_keyword("AS");
20251 self.write_space();
20252 self.generate_data_type(&cast.to)?;
20253
20254 if let Some(format) = &cast.format {
20256 self.write_space();
20257 self.write_keyword("FORMAT");
20258 self.write_space();
20259 self.generate_expression(format)?;
20260 }
20261
20262 self.write(")");
20263 Ok(())
20264 }
20265
20266 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
20269 self.generate_expression(&s.this)?;
20270 self.write("[");
20271 self.generate_expression(&s.index)?;
20272 self.write("]");
20273 Ok(())
20274 }
20275
20276 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
20277 self.generate_expression(&d.this)?;
20278 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
20281 && matches!(
20282 &d.this,
20283 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
20284 );
20285 if use_colon {
20286 self.write(":");
20287 } else {
20288 self.write(".");
20289 }
20290 self.generate_identifier(&d.field)
20291 }
20292
20293 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
20294 self.generate_expression(&m.this)?;
20295 self.write(".");
20296 if m.method.quoted {
20299 let q = self.config.identifier_quote;
20300 self.write(&format!("{}{}{}", q, m.method.name, q));
20301 } else {
20302 self.write(&m.method.name);
20303 }
20304 self.write("(");
20305 for (i, arg) in m.args.iter().enumerate() {
20306 if i > 0 {
20307 self.write(", ");
20308 }
20309 self.generate_expression(arg)?;
20310 }
20311 self.write(")");
20312 Ok(())
20313 }
20314
20315 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
20316 let needs_parens = matches!(
20319 &s.this,
20320 Expression::JsonExtract(f) if f.arrow_syntax
20321 ) || matches!(
20322 &s.this,
20323 Expression::JsonExtractScalar(f) if f.arrow_syntax
20324 );
20325
20326 if needs_parens {
20327 self.write("(");
20328 }
20329 self.generate_expression(&s.this)?;
20330 if needs_parens {
20331 self.write(")");
20332 }
20333 self.write("[");
20334 if let Some(start) = &s.start {
20335 self.generate_expression(start)?;
20336 }
20337 self.write(":");
20338 if let Some(end) = &s.end {
20339 self.generate_expression(end)?;
20340 }
20341 self.write("]");
20342 Ok(())
20343 }
20344
20345 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
20346 match &op.left {
20350 Expression::Column(col) => {
20351 if let Some(table) = &col.table {
20354 self.generate_identifier(table)?;
20355 self.write(".");
20356 }
20357 self.generate_identifier(&col.name)?;
20358 if col.join_mark && self.config.supports_column_join_marks {
20360 self.write(" (+)");
20361 }
20362 if op.left_comments.is_empty() {
20364 for comment in &col.trailing_comments {
20365 self.write_space();
20366 self.write_formatted_comment(comment);
20367 }
20368 }
20369 }
20370 Expression::Add(inner_op)
20371 | Expression::Sub(inner_op)
20372 | Expression::Mul(inner_op)
20373 | Expression::Div(inner_op)
20374 | Expression::Concat(inner_op) => {
20375 self.generate_binary_op_no_trailing(inner_op, match &op.left {
20377 Expression::Add(_) => "+",
20378 Expression::Sub(_) => "-",
20379 Expression::Mul(_) => "*",
20380 Expression::Div(_) => "/",
20381 Expression::Concat(_) => "||",
20382 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
20383 })?;
20384 }
20385 _ => {
20386 self.generate_expression(&op.left)?;
20387 }
20388 }
20389 for comment in &op.left_comments {
20391 self.write_space();
20392 self.write_formatted_comment(comment);
20393 }
20394 if self.config.pretty
20395 && matches!(self.config.dialect, Some(DialectType::Snowflake))
20396 && (operator == "AND" || operator == "OR")
20397 {
20398 self.write_newline();
20399 self.write_indent();
20400 self.write_keyword(operator);
20401 } else {
20402 self.write_space();
20403 if operator.chars().all(|c| c.is_alphabetic()) {
20404 self.write_keyword(operator);
20405 } else {
20406 self.write(operator);
20407 }
20408 }
20409 for comment in &op.operator_comments {
20411 self.write_space();
20412 self.write_formatted_comment(comment);
20413 }
20414 self.write_space();
20415 self.generate_expression(&op.right)?;
20416 for comment in &op.trailing_comments {
20418 self.write_space();
20419 self.write_formatted_comment(comment);
20420 }
20421 Ok(())
20422 }
20423
20424 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
20426 self.generate_expression(&op.left)?;
20427 self.write_space();
20428 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
20430 self.write("`ILIKE`");
20431 } else {
20432 self.write_keyword(operator);
20433 }
20434 if let Some(quantifier) = &op.quantifier {
20435 self.write_space();
20436 self.write_keyword(quantifier);
20437 }
20438 self.write_space();
20439 self.generate_expression(&op.right)?;
20440 if let Some(escape) = &op.escape {
20441 self.write_space();
20442 self.write_keyword("ESCAPE");
20443 self.write_space();
20444 self.generate_expression(escape)?;
20445 }
20446 Ok(())
20447 }
20448
20449 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
20452 use crate::dialects::DialectType;
20453 self.generate_expression(&op.left)?;
20454 self.write_space();
20455 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
20456 self.write("<=>");
20457 } else {
20458 self.write_keyword("IS NOT DISTINCT FROM");
20459 }
20460 self.write_space();
20461 self.generate_expression(&op.right)?;
20462 Ok(())
20463 }
20464
20465 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
20467 self.generate_expression(&op.left)?;
20468 self.write_space();
20469 self.write_keyword("IS DISTINCT FROM");
20470 self.write_space();
20471 self.generate_expression(&op.right)?;
20472 Ok(())
20473 }
20474
20475 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
20477 match &op.left {
20479 Expression::Column(col) => {
20480 if let Some(table) = &col.table {
20481 self.generate_identifier(table)?;
20482 self.write(".");
20483 }
20484 self.generate_identifier(&col.name)?;
20485 if col.join_mark && self.config.supports_column_join_marks {
20487 self.write(" (+)");
20488 }
20489 }
20490 Expression::Add(inner_op)
20491 | Expression::Sub(inner_op)
20492 | Expression::Mul(inner_op)
20493 | Expression::Div(inner_op)
20494 | Expression::Concat(inner_op) => {
20495 self.generate_binary_op_no_trailing(inner_op, match &op.left {
20496 Expression::Add(_) => "+",
20497 Expression::Sub(_) => "-",
20498 Expression::Mul(_) => "*",
20499 Expression::Div(_) => "/",
20500 Expression::Concat(_) => "||",
20501 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
20502 })?;
20503 }
20504 _ => {
20505 self.generate_expression(&op.left)?;
20506 }
20507 }
20508 for comment in &op.left_comments {
20510 self.write_space();
20511 self.write_formatted_comment(comment);
20512 }
20513 self.write_space();
20514 if operator.chars().all(|c| c.is_alphabetic()) {
20515 self.write_keyword(operator);
20516 } else {
20517 self.write(operator);
20518 }
20519 for comment in &op.operator_comments {
20521 self.write_space();
20522 self.write_formatted_comment(comment);
20523 }
20524 self.write_space();
20525 match &op.right {
20528 Expression::Column(col) => {
20529 if let Some(table) = &col.table {
20530 self.generate_identifier(table)?;
20531 self.write(".");
20532 }
20533 self.generate_identifier(&col.name)?;
20534 if col.join_mark && self.config.supports_column_join_marks {
20536 self.write(" (+)");
20537 }
20538 }
20539 _ => {
20540 self.generate_expression(&op.right)?;
20541 }
20542 }
20543 Ok(())
20545 }
20546
20547 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
20548 if operator.chars().all(|c| c.is_alphabetic()) {
20549 self.write_keyword(operator);
20550 self.write_space();
20551 } else {
20552 self.write(operator);
20553 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
20555 self.write_space();
20556 }
20557 }
20558 self.generate_expression(&op.this)
20559 }
20560
20561 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
20562 let is_generic =
20566 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
20567 let use_prefix_not =
20568 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
20569 if use_prefix_not {
20570 self.write_keyword("NOT");
20571 self.write_space();
20572 }
20573 self.generate_expression(&in_expr.this)?;
20574 if in_expr.global {
20575 self.write_space();
20576 self.write_keyword("GLOBAL");
20577 }
20578 if in_expr.not && !use_prefix_not {
20579 self.write_space();
20580 self.write_keyword("NOT");
20581 }
20582 self.write_space();
20583 self.write_keyword("IN");
20584
20585 if let Some(unnest_expr) = &in_expr.unnest {
20587 self.write_space();
20588 self.write_keyword("UNNEST");
20589 self.write("(");
20590 self.generate_expression(unnest_expr)?;
20591 self.write(")");
20592 return Ok(());
20593 }
20594
20595 if let Some(query) = &in_expr.query {
20596 let is_bare = in_expr.expressions.is_empty()
20599 && !matches!(
20600 query,
20601 Expression::Select(_)
20602 | Expression::Union(_)
20603 | Expression::Intersect(_)
20604 | Expression::Except(_)
20605 | Expression::Subquery(_)
20606 );
20607 if is_bare {
20608 self.write_space();
20610 self.generate_expression(query)?;
20611 } else {
20612 self.write(" (");
20614 let is_statement = matches!(
20615 query,
20616 Expression::Select(_)
20617 | Expression::Union(_)
20618 | Expression::Intersect(_)
20619 | Expression::Except(_)
20620 | Expression::Subquery(_)
20621 );
20622 if self.config.pretty && is_statement {
20623 self.write_newline();
20624 self.indent_level += 1;
20625 self.write_indent();
20626 }
20627 self.generate_expression(query)?;
20628 if self.config.pretty && is_statement {
20629 self.write_newline();
20630 self.indent_level -= 1;
20631 self.write_indent();
20632 }
20633 self.write(")");
20634 }
20635 } else {
20636 let is_duckdb = matches!(
20640 self.config.dialect,
20641 Some(crate::dialects::DialectType::DuckDB)
20642 );
20643 let is_clickhouse = matches!(
20644 self.config.dialect,
20645 Some(crate::dialects::DialectType::ClickHouse)
20646 );
20647 let single_expr = in_expr.expressions.len() == 1;
20648 if is_clickhouse && single_expr {
20649 if let Expression::Array(arr) = &in_expr.expressions[0] {
20650 self.write(" (");
20652 for (i, expr) in arr.expressions.iter().enumerate() {
20653 if i > 0 {
20654 self.write(", ");
20655 }
20656 self.generate_expression(expr)?;
20657 }
20658 self.write(")");
20659 } else {
20660 self.write_space();
20661 self.generate_expression(&in_expr.expressions[0])?;
20662 }
20663 } else {
20664 let is_bare_ref = single_expr
20665 && matches!(
20666 &in_expr.expressions[0],
20667 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
20668 );
20669 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
20670 self.write_space();
20673 self.generate_expression(&in_expr.expressions[0])?;
20674 } else {
20675 self.write(" (");
20677 for (i, expr) in in_expr.expressions.iter().enumerate() {
20678 if i > 0 {
20679 self.write(", ");
20680 }
20681 self.generate_expression(expr)?;
20682 }
20683 self.write(")");
20684 }
20685 }
20686 }
20687
20688 Ok(())
20689 }
20690
20691 fn generate_between(&mut self, between: &Between) -> Result<()> {
20692 let use_prefix_not = between.not
20694 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
20695 if use_prefix_not {
20696 self.write_keyword("NOT");
20697 self.write_space();
20698 }
20699 self.generate_expression(&between.this)?;
20700 if between.not && !use_prefix_not {
20701 self.write_space();
20702 self.write_keyword("NOT");
20703 }
20704 self.write_space();
20705 self.write_keyword("BETWEEN");
20706 if let Some(sym) = between.symmetric {
20708 if sym {
20709 self.write(" SYMMETRIC");
20710 } else {
20711 self.write(" ASYMMETRIC");
20712 }
20713 }
20714 self.write_space();
20715 self.generate_expression(&between.low)?;
20716 self.write_space();
20717 self.write_keyword("AND");
20718 self.write_space();
20719 self.generate_expression(&between.high)
20720 }
20721
20722 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
20723 let use_prefix_not = is_null.not
20725 && (self.config.dialect.is_none()
20726 || self.config.dialect == Some(DialectType::Generic)
20727 || is_null.postfix_form);
20728 if use_prefix_not {
20729 self.write_keyword("NOT");
20731 self.write_space();
20732 self.generate_expression(&is_null.this)?;
20733 self.write_space();
20734 self.write_keyword("IS");
20735 self.write_space();
20736 self.write_keyword("NULL");
20737 } else {
20738 self.generate_expression(&is_null.this)?;
20739 self.write_space();
20740 self.write_keyword("IS");
20741 if is_null.not {
20742 self.write_space();
20743 self.write_keyword("NOT");
20744 }
20745 self.write_space();
20746 self.write_keyword("NULL");
20747 }
20748 Ok(())
20749 }
20750
20751 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
20752 self.generate_expression(&is_true.this)?;
20753 self.write_space();
20754 self.write_keyword("IS");
20755 if is_true.not {
20756 self.write_space();
20757 self.write_keyword("NOT");
20758 }
20759 self.write_space();
20760 self.write_keyword("TRUE");
20761 Ok(())
20762 }
20763
20764 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
20765 self.generate_expression(&is_false.this)?;
20766 self.write_space();
20767 self.write_keyword("IS");
20768 if is_false.not {
20769 self.write_space();
20770 self.write_keyword("NOT");
20771 }
20772 self.write_space();
20773 self.write_keyword("FALSE");
20774 Ok(())
20775 }
20776
20777 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
20778 self.generate_expression(&is_json.this)?;
20779 self.write_space();
20780 self.write_keyword("IS");
20781 if is_json.negated {
20782 self.write_space();
20783 self.write_keyword("NOT");
20784 }
20785 self.write_space();
20786 self.write_keyword("JSON");
20787
20788 if let Some(ref json_type) = is_json.json_type {
20790 self.write_space();
20791 self.write_keyword(json_type);
20792 }
20793
20794 match &is_json.unique_keys {
20796 Some(JsonUniqueKeys::With) => {
20797 self.write_space();
20798 self.write_keyword("WITH UNIQUE KEYS");
20799 }
20800 Some(JsonUniqueKeys::Without) => {
20801 self.write_space();
20802 self.write_keyword("WITHOUT UNIQUE KEYS");
20803 }
20804 Some(JsonUniqueKeys::Shorthand) => {
20805 self.write_space();
20806 self.write_keyword("UNIQUE KEYS");
20807 }
20808 None => {}
20809 }
20810
20811 Ok(())
20812 }
20813
20814 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
20815 self.generate_expression(&is_expr.left)?;
20816 self.write_space();
20817 self.write_keyword("IS");
20818 self.write_space();
20819 self.generate_expression(&is_expr.right)
20820 }
20821
20822 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
20823 if exists.not {
20824 self.write_keyword("NOT");
20825 self.write_space();
20826 }
20827 self.write_keyword("EXISTS");
20828 self.write("(");
20829 let is_statement = matches!(
20830 &exists.this,
20831 Expression::Select(_)
20832 | Expression::Union(_)
20833 | Expression::Intersect(_)
20834 | Expression::Except(_)
20835 );
20836 if self.config.pretty && is_statement {
20837 self.write_newline();
20838 self.indent_level += 1;
20839 self.write_indent();
20840 self.generate_expression(&exists.this)?;
20841 self.write_newline();
20842 self.indent_level -= 1;
20843 self.write_indent();
20844 self.write(")");
20845 } else {
20846 self.generate_expression(&exists.this)?;
20847 self.write(")");
20848 }
20849 Ok(())
20850 }
20851
20852 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
20853 self.generate_expression(&op.left)?;
20854 self.write_space();
20855 self.write_keyword("MEMBER OF");
20856 self.write("(");
20857 self.generate_expression(&op.right)?;
20858 self.write(")");
20859 Ok(())
20860 }
20861
20862 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
20863 if subquery.lateral {
20864 self.write_keyword("LATERAL");
20865 self.write_space();
20866 }
20867
20868 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
20872 matches!(
20873 &p.this,
20874 Expression::Select(_)
20875 | Expression::Union(_)
20876 | Expression::Intersect(_)
20877 | Expression::Except(_)
20878 | Expression::Subquery(_)
20879 )
20880 } else {
20881 false
20882 };
20883
20884 let is_statement = matches!(
20886 &subquery.this,
20887 Expression::Select(_)
20888 | Expression::Union(_)
20889 | Expression::Intersect(_)
20890 | Expression::Except(_)
20891 | Expression::Merge(_)
20892 );
20893
20894 if !skip_outer_parens {
20895 self.write("(");
20896 if self.config.pretty && is_statement {
20897 self.write_newline();
20898 self.indent_level += 1;
20899 self.write_indent();
20900 }
20901 }
20902 self.generate_expression(&subquery.this)?;
20903
20904 if subquery.modifiers_inside {
20906 if let Some(order_by) = &subquery.order_by {
20908 self.write_space();
20909 self.write_keyword("ORDER BY");
20910 self.write_space();
20911 for (i, ord) in order_by.expressions.iter().enumerate() {
20912 if i > 0 {
20913 self.write(", ");
20914 }
20915 self.generate_ordered(ord)?;
20916 }
20917 }
20918
20919 if let Some(limit) = &subquery.limit {
20920 self.write_space();
20921 self.write_keyword("LIMIT");
20922 self.write_space();
20923 self.generate_expression(&limit.this)?;
20924 if limit.percent {
20925 self.write_space();
20926 self.write_keyword("PERCENT");
20927 }
20928 }
20929
20930 if let Some(offset) = &subquery.offset {
20931 self.write_space();
20932 self.write_keyword("OFFSET");
20933 self.write_space();
20934 self.generate_expression(&offset.this)?;
20935 }
20936 }
20937
20938 if !skip_outer_parens {
20939 if self.config.pretty && is_statement {
20940 self.write_newline();
20941 self.indent_level -= 1;
20942 self.write_indent();
20943 }
20944 self.write(")");
20945 }
20946
20947 if !subquery.modifiers_inside {
20949 if let Some(order_by) = &subquery.order_by {
20950 self.write_space();
20951 self.write_keyword("ORDER BY");
20952 self.write_space();
20953 for (i, ord) in order_by.expressions.iter().enumerate() {
20954 if i > 0 {
20955 self.write(", ");
20956 }
20957 self.generate_ordered(ord)?;
20958 }
20959 }
20960
20961 if let Some(limit) = &subquery.limit {
20962 self.write_space();
20963 self.write_keyword("LIMIT");
20964 self.write_space();
20965 self.generate_expression(&limit.this)?;
20966 if limit.percent {
20967 self.write_space();
20968 self.write_keyword("PERCENT");
20969 }
20970 }
20971
20972 if let Some(offset) = &subquery.offset {
20973 self.write_space();
20974 self.write_keyword("OFFSET");
20975 self.write_space();
20976 self.generate_expression(&offset.this)?;
20977 }
20978
20979 if let Some(distribute_by) = &subquery.distribute_by {
20981 self.write_space();
20982 self.write_keyword("DISTRIBUTE BY");
20983 self.write_space();
20984 for (i, expr) in distribute_by.expressions.iter().enumerate() {
20985 if i > 0 {
20986 self.write(", ");
20987 }
20988 self.generate_expression(expr)?;
20989 }
20990 }
20991
20992 if let Some(sort_by) = &subquery.sort_by {
20994 self.write_space();
20995 self.write_keyword("SORT BY");
20996 self.write_space();
20997 for (i, ord) in sort_by.expressions.iter().enumerate() {
20998 if i > 0 {
20999 self.write(", ");
21000 }
21001 self.generate_ordered(ord)?;
21002 }
21003 }
21004
21005 if let Some(cluster_by) = &subquery.cluster_by {
21007 self.write_space();
21008 self.write_keyword("CLUSTER BY");
21009 self.write_space();
21010 for (i, ord) in cluster_by.expressions.iter().enumerate() {
21011 if i > 0 {
21012 self.write(", ");
21013 }
21014 self.generate_ordered(ord)?;
21015 }
21016 }
21017 }
21018
21019 if let Some(alias) = &subquery.alias {
21020 self.write_space();
21021 let skip_as = matches!(
21023 self.config.dialect,
21024 Some(crate::dialects::DialectType::Oracle)
21025 );
21026 if !skip_as {
21027 self.write_keyword("AS");
21028 self.write_space();
21029 }
21030 self.generate_identifier(alias)?;
21031 if !subquery.column_aliases.is_empty() {
21032 self.write("(");
21033 for (i, col) in subquery.column_aliases.iter().enumerate() {
21034 if i > 0 {
21035 self.write(", ");
21036 }
21037 self.generate_identifier(col)?;
21038 }
21039 self.write(")");
21040 }
21041 }
21042 for comment in &subquery.trailing_comments {
21044 self.write(" ");
21045 self.write_formatted_comment(comment);
21046 }
21047 Ok(())
21048 }
21049
21050 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
21051 if let Some(ref with) = pivot.with {
21053 self.generate_with(with)?;
21054 self.write_space();
21055 }
21056
21057 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
21058
21059 let is_redshift_unpivot = pivot.unpivot
21063 && pivot.expressions.is_empty()
21064 && pivot.fields.is_empty()
21065 && pivot.using.is_empty()
21066 && pivot.into.is_none()
21067 && !matches!(&pivot.this, Expression::Null(_));
21068
21069 if is_redshift_unpivot {
21070 self.write_keyword("UNPIVOT");
21072 self.write_space();
21073 self.generate_expression(&pivot.this)?;
21074 if let Some(alias) = &pivot.alias {
21076 self.write_space();
21077 self.write_keyword("AS");
21078 self.write_space();
21079 self.write(&alias.name);
21081 }
21082 return Ok(());
21083 }
21084
21085 let is_simplified = !pivot.using.is_empty()
21087 || pivot.into.is_some()
21088 || (pivot.fields.is_empty()
21089 && !pivot.expressions.is_empty()
21090 && !matches!(&pivot.this, Expression::Null(_)));
21091
21092 if is_simplified {
21093 self.write_keyword(direction);
21097 self.write_space();
21098 self.generate_expression(&pivot.this)?;
21099
21100 if !pivot.expressions.is_empty() {
21101 self.write_space();
21102 self.write_keyword("ON");
21103 self.write_space();
21104 for (i, expr) in pivot.expressions.iter().enumerate() {
21105 if i > 0 {
21106 self.write(", ");
21107 }
21108 self.generate_expression(expr)?;
21109 }
21110 }
21111
21112 if let Some(into) = &pivot.into {
21114 self.write_space();
21115 self.write_keyword("INTO");
21116 self.write_space();
21117 self.generate_expression(into)?;
21118 }
21119
21120 if !pivot.using.is_empty() {
21122 self.write_space();
21123 self.write_keyword("USING");
21124 self.write_space();
21125 for (i, expr) in pivot.using.iter().enumerate() {
21126 if i > 0 {
21127 self.write(", ");
21128 }
21129 self.generate_expression(expr)?;
21130 }
21131 }
21132
21133 if let Some(group) = &pivot.group {
21135 self.write_space();
21136 self.generate_expression(group)?;
21137 }
21138 } else {
21139 if !matches!(&pivot.this, Expression::Null(_)) {
21144 self.generate_expression(&pivot.this)?;
21145 self.write_space();
21146 }
21147 self.write_keyword(direction);
21148 self.write("(");
21149
21150 for (i, expr) in pivot.expressions.iter().enumerate() {
21152 if i > 0 {
21153 self.write(", ");
21154 }
21155 self.generate_expression(expr)?;
21156 }
21157
21158 if !pivot.fields.is_empty() {
21160 if !pivot.expressions.is_empty() {
21161 self.write_space();
21162 }
21163 self.write_keyword("FOR");
21164 self.write_space();
21165 for (i, field) in pivot.fields.iter().enumerate() {
21166 if i > 0 {
21167 self.write_space();
21168 }
21169 self.generate_expression(field)?;
21171 }
21172 }
21173
21174 if let Some(default_val) = &pivot.default_on_null {
21176 self.write_space();
21177 self.write_keyword("DEFAULT ON NULL");
21178 self.write(" (");
21179 self.generate_expression(default_val)?;
21180 self.write(")");
21181 }
21182
21183 if let Some(group) = &pivot.group {
21185 self.write_space();
21186 self.generate_expression(group)?;
21187 }
21188
21189 self.write(")");
21190 }
21191
21192 if let Some(alias) = &pivot.alias {
21194 self.write_space();
21195 self.write_keyword("AS");
21196 self.write_space();
21197 self.generate_identifier(alias)?;
21198 }
21199
21200 Ok(())
21201 }
21202
21203 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
21204 self.generate_expression(&unpivot.this)?;
21205 self.write_space();
21206 self.write_keyword("UNPIVOT");
21207 if let Some(include) = unpivot.include_nulls {
21209 self.write_space();
21210 if include {
21211 self.write_keyword("INCLUDE NULLS");
21212 } else {
21213 self.write_keyword("EXCLUDE NULLS");
21214 }
21215 self.write_space();
21216 }
21217 self.write("(");
21218 if unpivot.value_column_parenthesized {
21219 self.write("(");
21220 }
21221 self.generate_identifier(&unpivot.value_column)?;
21222 for extra_col in &unpivot.extra_value_columns {
21224 self.write(", ");
21225 self.generate_identifier(extra_col)?;
21226 }
21227 if unpivot.value_column_parenthesized {
21228 self.write(")");
21229 }
21230 self.write_space();
21231 self.write_keyword("FOR");
21232 self.write_space();
21233 self.generate_identifier(&unpivot.name_column)?;
21234 self.write_space();
21235 self.write_keyword("IN");
21236 self.write(" (");
21237 for (i, col) in unpivot.columns.iter().enumerate() {
21238 if i > 0 {
21239 self.write(", ");
21240 }
21241 self.generate_expression(col)?;
21242 }
21243 self.write("))");
21244 if let Some(alias) = &unpivot.alias {
21245 self.write_space();
21246 self.write_keyword("AS");
21247 self.write_space();
21248 self.generate_identifier(alias)?;
21249 }
21250 Ok(())
21251 }
21252
21253 fn generate_values(&mut self, values: &Values) -> Result<()> {
21254 self.write_keyword("VALUES");
21255 for (i, row) in values.expressions.iter().enumerate() {
21256 if i > 0 {
21257 self.write(",");
21258 }
21259 self.write(" (");
21260 for (j, expr) in row.expressions.iter().enumerate() {
21261 if j > 0 {
21262 self.write(", ");
21263 }
21264 self.generate_expression(expr)?;
21265 }
21266 self.write(")");
21267 }
21268 if let Some(alias) = &values.alias {
21269 self.write_space();
21270 self.write_keyword("AS");
21271 self.write_space();
21272 self.generate_identifier(alias)?;
21273 if !values.column_aliases.is_empty() {
21274 self.write("(");
21275 for (i, col) in values.column_aliases.iter().enumerate() {
21276 if i > 0 {
21277 self.write(", ");
21278 }
21279 self.generate_identifier(col)?;
21280 }
21281 self.write(")");
21282 }
21283 }
21284 Ok(())
21285 }
21286
21287 fn generate_array(&mut self, arr: &Array) -> Result<()> {
21288 let needs_inheritance = matches!(
21290 self.config.dialect,
21291 Some(DialectType::DuckDB)
21292 | Some(DialectType::Spark)
21293 | Some(DialectType::Databricks)
21294 | Some(DialectType::Hive)
21295 | Some(DialectType::Snowflake)
21296 | Some(DialectType::Presto)
21297 | Some(DialectType::Trino)
21298 );
21299 let propagated: Vec<Expression>;
21300 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
21301 propagated = Self::inherit_struct_field_names(&arr.expressions);
21302 &propagated
21303 } else {
21304 &arr.expressions
21305 };
21306
21307 let use_parens =
21310 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
21311 if !self.config.array_bracket_only {
21312 self.write_keyword("ARRAY");
21313 }
21314 if use_parens {
21315 self.write("(");
21316 } else {
21317 self.write("[");
21318 }
21319 for (i, expr) in expressions.iter().enumerate() {
21320 if i > 0 {
21321 self.write(", ");
21322 }
21323 self.generate_expression(expr)?;
21324 }
21325 if use_parens {
21326 self.write(")");
21327 } else {
21328 self.write("]");
21329 }
21330 Ok(())
21331 }
21332
21333 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
21334 if tuple.expressions.len() == 2 {
21337 if let Expression::TableAlias(_) = &tuple.expressions[1] {
21338 self.generate_expression(&tuple.expressions[0])?;
21340 self.write_space();
21341 self.write_keyword("AS");
21342 self.write_space();
21343 self.generate_expression(&tuple.expressions[1])?;
21344 return Ok(());
21345 }
21346 }
21347
21348 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
21351 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
21352 for expr in &tuple.expressions {
21353 expr_strings.push(self.generate_to_string(expr)?);
21354 }
21355 self.too_wide(&expr_strings)
21356 } else {
21357 false
21358 };
21359
21360 if expand_tuple {
21361 self.write("(");
21362 self.write_newline();
21363 self.indent_level += 1;
21364 for (i, expr) in tuple.expressions.iter().enumerate() {
21365 if i > 0 {
21366 self.write(",");
21367 self.write_newline();
21368 }
21369 self.write_indent();
21370 self.generate_expression(expr)?;
21371 }
21372 self.indent_level -= 1;
21373 self.write_newline();
21374 self.write_indent();
21375 self.write(")");
21376 } else {
21377 self.write("(");
21378 for (i, expr) in tuple.expressions.iter().enumerate() {
21379 if i > 0 {
21380 self.write(", ");
21381 }
21382 self.generate_expression(expr)?;
21383 }
21384 self.write(")");
21385 }
21386 Ok(())
21387 }
21388
21389 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
21390 self.generate_expression(&pipe.this)?;
21391 self.write(" |> ");
21392 self.generate_expression(&pipe.expression)?;
21393 Ok(())
21394 }
21395
21396 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
21397 self.generate_expression(&ordered.this)?;
21398 if ordered.desc {
21399 self.write_space();
21400 self.write_keyword("DESC");
21401 } else if ordered.explicit_asc {
21402 self.write_space();
21403 self.write_keyword("ASC");
21404 }
21405 if let Some(nulls_first) = ordered.nulls_first {
21406 let is_asc = !ordered.desc;
21420 let is_nulls_are_large = matches!(
21421 self.config.dialect,
21422 Some(DialectType::Oracle)
21423 | Some(DialectType::PostgreSQL)
21424 | Some(DialectType::Redshift)
21425 | Some(DialectType::Snowflake)
21426 );
21427 let is_nulls_are_last = matches!(
21428 self.config.dialect,
21429 Some(DialectType::Dremio)
21430 | Some(DialectType::DuckDB)
21431 | Some(DialectType::Presto)
21432 | Some(DialectType::Trino)
21433 | Some(DialectType::Athena)
21434 | Some(DialectType::ClickHouse)
21435 | Some(DialectType::Drill)
21436 | Some(DialectType::Exasol)
21437 );
21438
21439 let is_default_nulls = if is_nulls_are_large {
21441 (is_asc && !nulls_first) || (!is_asc && nulls_first)
21443 } else if is_nulls_are_last {
21444 !nulls_first
21446 } else {
21447 false
21448 };
21449
21450 if !is_default_nulls {
21451 self.write_space();
21452 self.write_keyword("NULLS");
21453 self.write_space();
21454 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
21455 }
21456 }
21457 if let Some(ref with_fill) = ordered.with_fill {
21459 self.write_space();
21460 self.generate_with_fill(with_fill)?;
21461 }
21462 Ok(())
21463 }
21464
21465 fn write_clickhouse_type(&mut self, type_str: &str) {
21467 if self.clickhouse_nullable_depth < 0 {
21468 self.write(type_str);
21470 } else {
21471 self.write(&format!("Nullable({})", type_str));
21472 }
21473 }
21474
21475 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
21476 use crate::dialects::DialectType;
21477
21478 match dt {
21479 DataType::Boolean => {
21480 match self.config.dialect {
21482 Some(DialectType::TSQL) => self.write_keyword("BIT"),
21483 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
21485 self.write_keyword("NUMBER(1)")
21487 }
21488 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
21490 }
21491 }
21492 DataType::TinyInt { length } => {
21493 match self.config.dialect {
21497 Some(DialectType::PostgreSQL)
21498 | Some(DialectType::Redshift)
21499 | Some(DialectType::Oracle)
21500 | Some(DialectType::Exasol) => {
21501 self.write_keyword("SMALLINT");
21502 }
21503 Some(DialectType::Teradata) => {
21504 self.write_keyword("BYTEINT");
21506 }
21507 Some(DialectType::Dremio) => {
21508 self.write_keyword("INT");
21510 }
21511 Some(DialectType::ClickHouse) => {
21512 self.write_clickhouse_type("Int8");
21513 }
21514 _ => {
21515 self.write_keyword("TINYINT");
21516 }
21517 }
21518 if let Some(n) = length {
21519 if !matches!(
21520 self.config.dialect,
21521 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
21522 ) {
21523 self.write(&format!("({})", n));
21524 }
21525 }
21526 }
21527 DataType::SmallInt { length } => {
21528 match self.config.dialect {
21530 Some(DialectType::Dremio) => {
21531 self.write_keyword("INT");
21532 }
21533 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
21534 self.write_keyword("INTEGER");
21535 }
21536 Some(DialectType::BigQuery) => {
21537 self.write_keyword("INT64");
21538 }
21539 Some(DialectType::ClickHouse) => {
21540 self.write_clickhouse_type("Int16");
21541 }
21542 _ => {
21543 self.write_keyword("SMALLINT");
21544 if let Some(n) = length {
21545 self.write(&format!("({})", n));
21546 }
21547 }
21548 }
21549 }
21550 DataType::Int {
21551 length,
21552 integer_spelling,
21553 } => {
21554 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
21556 self.write_keyword("INT64");
21557 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21558 self.write_clickhouse_type("Int32");
21559 } else {
21560 let use_integer = match self.config.dialect {
21562 Some(DialectType::TSQL)
21563 | Some(DialectType::Fabric)
21564 | Some(DialectType::Presto)
21565 | Some(DialectType::Trino)
21566 | Some(DialectType::SQLite)
21567 | Some(DialectType::Redshift) => true,
21568 Some(DialectType::Databricks) => *integer_spelling,
21570 _ => false,
21571 };
21572 if use_integer {
21573 self.write_keyword("INTEGER");
21574 } else {
21575 self.write_keyword("INT");
21576 }
21577 if let Some(n) = length {
21578 self.write(&format!("({})", n));
21579 }
21580 }
21581 }
21582 DataType::BigInt { length } => {
21583 match self.config.dialect {
21585 Some(DialectType::Oracle) => {
21586 self.write_keyword("INT");
21588 }
21589 Some(DialectType::ClickHouse) => {
21590 self.write_clickhouse_type("Int64");
21591 }
21592 _ => {
21593 self.write_keyword("BIGINT");
21594 if let Some(n) = length {
21595 self.write(&format!("({})", n));
21596 }
21597 }
21598 }
21599 }
21600 DataType::Float {
21601 precision,
21602 scale,
21603 real_spelling,
21604 } => {
21605 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21609 self.write_clickhouse_type("Float32");
21610 } else if *real_spelling
21611 && !matches!(
21612 self.config.dialect,
21613 Some(DialectType::Spark)
21614 | Some(DialectType::Databricks)
21615 | Some(DialectType::Hive)
21616 | Some(DialectType::Snowflake)
21617 | Some(DialectType::MySQL)
21618 | Some(DialectType::BigQuery)
21619 )
21620 {
21621 self.write_keyword("REAL")
21622 } else {
21623 match self.config.dialect {
21624 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
21625 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
21626 _ => self.write_keyword("FLOAT"),
21627 }
21628 }
21629 if !matches!(
21632 self.config.dialect,
21633 Some(DialectType::Spark)
21634 | Some(DialectType::Databricks)
21635 | Some(DialectType::Hive)
21636 | Some(DialectType::Presto)
21637 | Some(DialectType::Trino)
21638 ) {
21639 if let Some(p) = precision {
21640 self.write(&format!("({}", p));
21641 if let Some(s) = scale {
21642 self.write(&format!(", {})", s));
21643 } else {
21644 self.write(")");
21645 }
21646 }
21647 }
21648 }
21649 DataType::Double { precision, scale } => {
21650 match self.config.dialect {
21652 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21653 self.write_keyword("FLOAT")
21654 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
21656 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
21657 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
21658 Some(DialectType::SQLite) => self.write_keyword("REAL"),
21659 Some(DialectType::PostgreSQL)
21660 | Some(DialectType::Redshift)
21661 | Some(DialectType::Teradata)
21662 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
21663 _ => self.write_keyword("DOUBLE"),
21664 }
21665 if let Some(p) = precision {
21667 self.write(&format!("({}", p));
21668 if let Some(s) = scale {
21669 self.write(&format!(", {})", s));
21670 } else {
21671 self.write(")");
21672 }
21673 }
21674 }
21675 DataType::Decimal { precision, scale } => {
21676 match self.config.dialect {
21678 Some(DialectType::ClickHouse) => {
21679 self.write("Decimal");
21680 if let Some(p) = precision {
21681 self.write(&format!("({}", p));
21682 if let Some(s) = scale {
21683 self.write(&format!(", {}", s));
21684 }
21685 self.write(")");
21686 }
21687 }
21688 Some(DialectType::Oracle) => {
21689 self.write_keyword("NUMBER");
21691 if let Some(p) = precision {
21692 self.write(&format!("({}", p));
21693 if let Some(s) = scale {
21694 self.write(&format!(", {}", s));
21695 }
21696 self.write(")");
21697 }
21698 }
21699 Some(DialectType::BigQuery) => {
21700 self.write_keyword("NUMERIC");
21702 if let Some(p) = precision {
21703 self.write(&format!("({}", p));
21704 if let Some(s) = scale {
21705 self.write(&format!(", {}", s));
21706 }
21707 self.write(")");
21708 }
21709 }
21710 _ => {
21711 self.write_keyword("DECIMAL");
21712 if let Some(p) = precision {
21713 self.write(&format!("({}", p));
21714 if let Some(s) = scale {
21715 self.write(&format!(", {}", s));
21716 }
21717 self.write(")");
21718 }
21719 }
21720 }
21721 }
21722 DataType::Char { length } => {
21723 match self.config.dialect {
21725 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
21726 self.write_keyword("TEXT");
21728 }
21729 Some(DialectType::Hive)
21730 | Some(DialectType::Spark)
21731 | Some(DialectType::Databricks) => {
21732 if length.is_some()
21735 && !matches!(self.config.dialect, Some(DialectType::Hive))
21736 {
21737 self.write_keyword("CHAR");
21738 if let Some(n) = length {
21739 self.write(&format!("({})", n));
21740 }
21741 } else {
21742 self.write_keyword("STRING");
21743 }
21744 }
21745 Some(DialectType::Dremio) => {
21746 self.write_keyword("VARCHAR");
21748 if let Some(n) = length {
21749 self.write(&format!("({})", n));
21750 }
21751 }
21752 _ => {
21753 self.write_keyword("CHAR");
21754 if let Some(n) = length {
21755 self.write(&format!("({})", n));
21756 }
21757 }
21758 }
21759 }
21760 DataType::VarChar {
21761 length,
21762 parenthesized_length,
21763 } => {
21764 match self.config.dialect {
21766 Some(DialectType::Oracle) => {
21767 self.write_keyword("VARCHAR2");
21768 if let Some(n) = length {
21769 self.write(&format!("({})", n));
21770 }
21771 }
21772 Some(DialectType::DuckDB) => {
21773 self.write_keyword("TEXT");
21775 if let Some(n) = length {
21776 self.write(&format!("({})", n));
21777 }
21778 }
21779 Some(DialectType::SQLite) => {
21780 self.write_keyword("TEXT");
21782 if let Some(n) = length {
21783 self.write(&format!("({})", n));
21784 }
21785 }
21786 Some(DialectType::MySQL) if length.is_none() => {
21787 self.write_keyword("TEXT");
21789 }
21790 Some(DialectType::Hive)
21791 | Some(DialectType::Spark)
21792 | Some(DialectType::Databricks)
21793 if length.is_none() =>
21794 {
21795 self.write_keyword("STRING");
21797 }
21798 _ => {
21799 self.write_keyword("VARCHAR");
21800 if let Some(n) = length {
21801 if *parenthesized_length {
21803 self.write(&format!("(({}))", n));
21804 } else {
21805 self.write(&format!("({})", n));
21806 }
21807 }
21808 }
21809 }
21810 }
21811 DataType::Text => {
21812 match self.config.dialect {
21814 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
21815 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21816 self.write_keyword("VARCHAR(MAX)")
21817 }
21818 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
21819 Some(DialectType::Snowflake)
21820 | Some(DialectType::Dremio)
21821 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
21822 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
21823 Some(DialectType::Presto)
21824 | Some(DialectType::Trino)
21825 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
21826 Some(DialectType::Spark)
21827 | Some(DialectType::Databricks)
21828 | Some(DialectType::Hive) => self.write_keyword("STRING"),
21829 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
21830 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
21831 self.write_keyword("STRING")
21832 }
21833 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
21834 _ => self.write_keyword("TEXT"),
21835 }
21836 }
21837 DataType::TextWithLength { length } => {
21838 match self.config.dialect {
21840 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
21841 Some(DialectType::Hive)
21842 | Some(DialectType::Spark)
21843 | Some(DialectType::Databricks) => {
21844 self.write(&format!("VARCHAR({})", length));
21845 }
21846 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
21847 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
21848 Some(DialectType::Snowflake)
21849 | Some(DialectType::Presto)
21850 | Some(DialectType::Trino)
21851 | Some(DialectType::Athena)
21852 | Some(DialectType::Drill)
21853 | Some(DialectType::Dremio) => {
21854 self.write(&format!("VARCHAR({})", length));
21855 }
21856 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21857 self.write(&format!("VARCHAR({})", length))
21858 }
21859 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
21860 self.write(&format!("STRING({})", length))
21861 }
21862 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
21863 _ => self.write(&format!("TEXT({})", length)),
21864 }
21865 }
21866 DataType::String { length } => {
21867 match self.config.dialect {
21869 Some(DialectType::ClickHouse) => {
21870 self.write("String");
21872 if let Some(n) = length {
21873 self.write(&format!("({})", n));
21874 }
21875 }
21876 Some(DialectType::BigQuery)
21877 | Some(DialectType::Hive)
21878 | Some(DialectType::Spark)
21879 | Some(DialectType::Databricks)
21880 | Some(DialectType::StarRocks)
21881 | Some(DialectType::Doris) => {
21882 self.write_keyword("STRING");
21883 if let Some(n) = length {
21884 self.write(&format!("({})", n));
21885 }
21886 }
21887 Some(DialectType::PostgreSQL) => {
21888 if let Some(n) = length {
21890 self.write_keyword("VARCHAR");
21891 self.write(&format!("({})", n));
21892 } else {
21893 self.write_keyword("TEXT");
21894 }
21895 }
21896 Some(DialectType::Redshift) => {
21897 if let Some(n) = length {
21899 self.write_keyword("VARCHAR");
21900 self.write(&format!("({})", n));
21901 } else {
21902 self.write_keyword("VARCHAR(MAX)");
21903 }
21904 }
21905 Some(DialectType::MySQL) => {
21906 if let Some(n) = length {
21908 self.write_keyword("VARCHAR");
21909 self.write(&format!("({})", n));
21910 } else {
21911 self.write_keyword("TEXT");
21912 }
21913 }
21914 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21915 if let Some(n) = length {
21917 self.write_keyword("VARCHAR");
21918 self.write(&format!("({})", n));
21919 } else {
21920 self.write_keyword("VARCHAR(MAX)");
21921 }
21922 }
21923 Some(DialectType::Oracle) => {
21924 self.write_keyword("CLOB");
21926 }
21927 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
21928 self.write_keyword("TEXT");
21930 if let Some(n) = length {
21931 self.write(&format!("({})", n));
21932 }
21933 }
21934 Some(DialectType::Presto)
21935 | Some(DialectType::Trino)
21936 | Some(DialectType::Drill)
21937 | Some(DialectType::Dremio) => {
21938 self.write_keyword("VARCHAR");
21940 if let Some(n) = length {
21941 self.write(&format!("({})", n));
21942 }
21943 }
21944 Some(DialectType::Snowflake) => {
21945 self.write_keyword("STRING");
21948 if let Some(n) = length {
21949 self.write(&format!("({})", n));
21950 }
21951 }
21952 _ => {
21953 self.write_keyword("STRING");
21955 if let Some(n) = length {
21956 self.write(&format!("({})", n));
21957 }
21958 }
21959 }
21960 }
21961 DataType::Binary { length } => {
21962 match self.config.dialect {
21964 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
21965 self.write_keyword("BYTEA");
21966 if let Some(n) = length {
21967 self.write(&format!("({})", n));
21968 }
21969 }
21970 Some(DialectType::Redshift) => {
21971 self.write_keyword("VARBYTE");
21972 if let Some(n) = length {
21973 self.write(&format!("({})", n));
21974 }
21975 }
21976 Some(DialectType::DuckDB)
21977 | Some(DialectType::SQLite)
21978 | Some(DialectType::Oracle) => {
21979 self.write_keyword("BLOB");
21981 if let Some(n) = length {
21982 self.write(&format!("({})", n));
21983 }
21984 }
21985 Some(DialectType::Presto)
21986 | Some(DialectType::Trino)
21987 | Some(DialectType::Athena)
21988 | Some(DialectType::Drill)
21989 | Some(DialectType::Dremio) => {
21990 self.write_keyword("VARBINARY");
21992 if let Some(n) = length {
21993 self.write(&format!("({})", n));
21994 }
21995 }
21996 Some(DialectType::ClickHouse) => {
21997 if self.clickhouse_nullable_depth < 0 {
21999 self.write("BINARY");
22000 } else {
22001 self.write("Nullable(BINARY");
22002 }
22003 if let Some(n) = length {
22004 self.write(&format!("({})", n));
22005 }
22006 if self.clickhouse_nullable_depth >= 0 {
22007 self.write(")");
22008 }
22009 }
22010 _ => {
22011 self.write_keyword("BINARY");
22012 if let Some(n) = length {
22013 self.write(&format!("({})", n));
22014 }
22015 }
22016 }
22017 }
22018 DataType::VarBinary { length } => {
22019 match self.config.dialect {
22021 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
22022 self.write_keyword("BYTEA");
22023 if let Some(n) = length {
22024 self.write(&format!("({})", n));
22025 }
22026 }
22027 Some(DialectType::Redshift) => {
22028 self.write_keyword("VARBYTE");
22029 if let Some(n) = length {
22030 self.write(&format!("({})", n));
22031 }
22032 }
22033 Some(DialectType::DuckDB)
22034 | Some(DialectType::SQLite)
22035 | Some(DialectType::Oracle) => {
22036 self.write_keyword("BLOB");
22038 if let Some(n) = length {
22039 self.write(&format!("({})", n));
22040 }
22041 }
22042 Some(DialectType::Exasol) => {
22043 self.write_keyword("VARCHAR");
22045 }
22046 Some(DialectType::Spark)
22047 | Some(DialectType::Hive)
22048 | Some(DialectType::Databricks) => {
22049 self.write_keyword("BINARY");
22051 if let Some(n) = length {
22052 self.write(&format!("({})", n));
22053 }
22054 }
22055 Some(DialectType::ClickHouse) => {
22056 self.write_clickhouse_type("String");
22058 }
22059 _ => {
22060 self.write_keyword("VARBINARY");
22061 if let Some(n) = length {
22062 self.write(&format!("({})", n));
22063 }
22064 }
22065 }
22066 }
22067 DataType::Blob => {
22068 match self.config.dialect {
22070 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
22071 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
22072 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22073 self.write_keyword("VARBINARY")
22074 }
22075 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
22076 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
22077 Some(DialectType::Presto)
22078 | Some(DialectType::Trino)
22079 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
22080 Some(DialectType::DuckDB) => {
22081 self.write_keyword("VARBINARY");
22084 }
22085 Some(DialectType::Spark)
22086 | Some(DialectType::Databricks)
22087 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
22088 Some(DialectType::ClickHouse) => {
22089 self.write("Nullable(String)");
22093 }
22094 _ => self.write_keyword("BLOB"),
22095 }
22096 }
22097 DataType::Bit { length } => {
22098 match self.config.dialect {
22100 Some(DialectType::Dremio)
22101 | Some(DialectType::Spark)
22102 | Some(DialectType::Databricks)
22103 | Some(DialectType::Hive)
22104 | Some(DialectType::Snowflake)
22105 | Some(DialectType::BigQuery)
22106 | Some(DialectType::Presto)
22107 | Some(DialectType::Trino)
22108 | Some(DialectType::ClickHouse)
22109 | Some(DialectType::Redshift) => {
22110 self.write_keyword("BOOLEAN");
22112 }
22113 _ => {
22114 self.write_keyword("BIT");
22115 if let Some(n) = length {
22116 self.write(&format!("({})", n));
22117 }
22118 }
22119 }
22120 }
22121 DataType::VarBit { length } => {
22122 self.write_keyword("VARBIT");
22123 if let Some(n) = length {
22124 self.write(&format!("({})", n));
22125 }
22126 }
22127 DataType::Date => self.write_keyword("DATE"),
22128 DataType::Time {
22129 precision,
22130 timezone,
22131 } => {
22132 if *timezone {
22133 match self.config.dialect {
22135 Some(DialectType::DuckDB) => {
22136 self.write_keyword("TIMETZ");
22138 }
22139 Some(DialectType::PostgreSQL) => {
22140 self.write_keyword("TIMETZ");
22142 if let Some(p) = precision {
22143 self.write(&format!("({})", p));
22144 }
22145 }
22146 _ => {
22147 self.write_keyword("TIME");
22149 if let Some(p) = precision {
22150 self.write(&format!("({})", p));
22151 }
22152 self.write_keyword(" WITH TIME ZONE");
22153 }
22154 }
22155 } else {
22156 if matches!(
22158 self.config.dialect,
22159 Some(DialectType::Spark)
22160 | Some(DialectType::Databricks)
22161 | Some(DialectType::Hive)
22162 ) {
22163 self.write_keyword("TIMESTAMP");
22164 } else {
22165 self.write_keyword("TIME");
22166 if let Some(p) = precision {
22167 self.write(&format!("({})", p));
22168 }
22169 }
22170 }
22171 }
22172 DataType::Timestamp {
22173 precision,
22174 timezone,
22175 } => {
22176 match self.config.dialect {
22178 Some(DialectType::ClickHouse) => {
22179 self.write("DateTime");
22180 if let Some(p) = precision {
22181 self.write(&format!("({})", p));
22182 }
22183 }
22184 Some(DialectType::TSQL) => {
22185 if *timezone {
22186 self.write_keyword("DATETIMEOFFSET");
22187 } else {
22188 self.write_keyword("DATETIME2");
22189 }
22190 if let Some(p) = precision {
22191 self.write(&format!("({})", p));
22192 }
22193 }
22194 Some(DialectType::MySQL) => {
22195 self.write_keyword("TIMESTAMP");
22197 if let Some(p) = precision {
22198 self.write(&format!("({})", p));
22199 }
22200 }
22201 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
22202 self.write_keyword("DATETIME");
22204 if let Some(p) = precision {
22205 self.write(&format!("({})", p));
22206 }
22207 }
22208 Some(DialectType::BigQuery) => {
22209 if *timezone {
22211 self.write_keyword("TIMESTAMP");
22212 } else {
22213 self.write_keyword("DATETIME");
22214 }
22215 }
22216 Some(DialectType::DuckDB) => {
22217 if *timezone {
22219 self.write_keyword("TIMESTAMPTZ");
22220 } else {
22221 self.write_keyword("TIMESTAMP");
22222 if let Some(p) = precision {
22223 self.write(&format!("({})", p));
22224 }
22225 }
22226 }
22227 _ => {
22228 if *timezone && !self.config.tz_to_with_time_zone {
22229 self.write_keyword("TIMESTAMPTZ");
22231 if let Some(p) = precision {
22232 self.write(&format!("({})", p));
22233 }
22234 } else {
22235 self.write_keyword("TIMESTAMP");
22236 if let Some(p) = precision {
22237 self.write(&format!("({})", p));
22238 }
22239 if *timezone {
22240 self.write_space();
22241 self.write_keyword("WITH TIME ZONE");
22242 }
22243 }
22244 }
22245 }
22246 }
22247 DataType::Interval { unit, to } => {
22248 self.write_keyword("INTERVAL");
22249 if let Some(u) = unit {
22250 self.write_space();
22251 self.write_keyword(u);
22252 }
22253 if let Some(t) = to {
22255 self.write_space();
22256 self.write_keyword("TO");
22257 self.write_space();
22258 self.write_keyword(t);
22259 }
22260 }
22261 DataType::Json => {
22262 match self.config.dialect {
22264 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
22267 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
22268 _ => self.write_keyword("JSON"),
22269 }
22270 }
22271 DataType::JsonB => {
22272 match self.config.dialect {
22274 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
22275 Some(DialectType::Doris) => self.write_keyword("JSONB"),
22276 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
22277 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
22278 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
22281 }
22282 DataType::Uuid => {
22283 match self.config.dialect {
22285 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
22286 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
22287 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
22288 Some(DialectType::BigQuery)
22289 | Some(DialectType::Spark)
22290 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
22291 _ => self.write_keyword("UUID"),
22292 }
22293 }
22294 DataType::Array {
22295 element_type,
22296 dimension,
22297 } => {
22298 match self.config.dialect {
22300 Some(DialectType::PostgreSQL)
22301 | Some(DialectType::Redshift)
22302 | Some(DialectType::DuckDB) => {
22303 self.generate_data_type(element_type)?;
22305 if let Some(dim) = dimension {
22306 self.write(&format!("[{}]", dim));
22307 } else {
22308 self.write("[]");
22309 }
22310 }
22311 Some(DialectType::BigQuery) => {
22312 self.write_keyword("ARRAY<");
22313 self.generate_data_type(element_type)?;
22314 self.write(">");
22315 }
22316 Some(DialectType::Snowflake)
22317 | Some(DialectType::Presto)
22318 | Some(DialectType::Trino)
22319 | Some(DialectType::ClickHouse) => {
22320 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22322 self.write("Array(");
22323 } else {
22324 self.write_keyword("ARRAY(");
22325 }
22326 self.generate_data_type(element_type)?;
22327 self.write(")");
22328 }
22329 Some(DialectType::TSQL)
22330 | Some(DialectType::MySQL)
22331 | Some(DialectType::Oracle) => {
22332 match self.config.dialect {
22335 Some(DialectType::MySQL) => self.write_keyword("JSON"),
22336 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
22337 _ => self.write_keyword("JSON"),
22338 }
22339 }
22340 _ => {
22341 self.write_keyword("ARRAY<");
22343 self.generate_data_type(element_type)?;
22344 self.write(">");
22345 }
22346 }
22347 }
22348 DataType::List { element_type } => {
22349 self.generate_data_type(element_type)?;
22351 self.write_keyword(" LIST");
22352 }
22353 DataType::Map {
22354 key_type,
22355 value_type,
22356 } => {
22357 match self.config.dialect {
22359 Some(DialectType::Materialize) => {
22360 self.write_keyword("MAP[");
22362 self.generate_data_type(key_type)?;
22363 self.write(" => ");
22364 self.generate_data_type(value_type)?;
22365 self.write("]");
22366 }
22367 Some(DialectType::Snowflake)
22368 | Some(DialectType::RisingWave)
22369 | Some(DialectType::DuckDB)
22370 | Some(DialectType::Presto)
22371 | Some(DialectType::Trino)
22372 | Some(DialectType::Athena) => {
22373 self.write_keyword("MAP(");
22374 self.generate_data_type(key_type)?;
22375 self.write(", ");
22376 self.generate_data_type(value_type)?;
22377 self.write(")");
22378 }
22379 Some(DialectType::ClickHouse) => {
22380 self.write("Map(");
22383 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
22385 self.clickhouse_nullable_depth = 0;
22386 self.write(", ");
22387 self.generate_data_type(value_type)?;
22388 self.write(")");
22389 }
22390 _ => {
22391 self.write_keyword("MAP<");
22392 self.generate_data_type(key_type)?;
22393 self.write(", ");
22394 self.generate_data_type(value_type)?;
22395 self.write(">");
22396 }
22397 }
22398 }
22399 DataType::Vector {
22400 element_type,
22401 dimension,
22402 } => {
22403 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
22404 self.write_keyword("VECTOR(");
22406 if let Some(dim) = dimension {
22407 self.write(&dim.to_string());
22408 }
22409 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
22411 DataType::TinyInt { .. } => Some("I8"),
22412 DataType::SmallInt { .. } => Some("I16"),
22413 DataType::Int { .. } => Some("I32"),
22414 DataType::BigInt { .. } => Some("I64"),
22415 DataType::Float { .. } => Some("F32"),
22416 DataType::Double { .. } => Some("F64"),
22417 _ => None,
22418 });
22419 if let Some(alias) = type_alias {
22420 if dimension.is_some() {
22421 self.write(", ");
22422 }
22423 self.write(alias);
22424 }
22425 self.write(")");
22426 } else {
22427 self.write_keyword("VECTOR(");
22429 if let Some(ref et) = element_type {
22430 self.generate_data_type(et)?;
22431 if dimension.is_some() {
22432 self.write(", ");
22433 }
22434 }
22435 if let Some(dim) = dimension {
22436 self.write(&dim.to_string());
22437 }
22438 self.write(")");
22439 }
22440 }
22441 DataType::Object { fields, modifier } => {
22442 self.write_keyword("OBJECT(");
22443 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
22444 if i > 0 {
22445 self.write(", ");
22446 }
22447 self.write(name);
22448 self.write(" ");
22449 self.generate_data_type(dt)?;
22450 if *not_null {
22451 self.write_keyword(" NOT NULL");
22452 }
22453 }
22454 self.write(")");
22455 if let Some(mod_str) = modifier {
22456 self.write(" ");
22457 self.write_keyword(mod_str);
22458 }
22459 }
22460 DataType::Struct { fields, nested } => {
22461 match self.config.dialect {
22463 Some(DialectType::Snowflake) => {
22464 self.write_keyword("OBJECT(");
22466 for (i, field) in fields.iter().enumerate() {
22467 if i > 0 {
22468 self.write(", ");
22469 }
22470 if !field.name.is_empty() {
22471 self.write(&field.name);
22472 self.write(" ");
22473 }
22474 self.generate_data_type(&field.data_type)?;
22475 }
22476 self.write(")");
22477 }
22478 Some(DialectType::Presto) | Some(DialectType::Trino) => {
22479 self.write_keyword("ROW(");
22481 for (i, field) in fields.iter().enumerate() {
22482 if i > 0 {
22483 self.write(", ");
22484 }
22485 if !field.name.is_empty() {
22486 self.write(&field.name);
22487 self.write(" ");
22488 }
22489 self.generate_data_type(&field.data_type)?;
22490 }
22491 self.write(")");
22492 }
22493 Some(DialectType::DuckDB) => {
22494 self.write_keyword("STRUCT(");
22496 for (i, field) in fields.iter().enumerate() {
22497 if i > 0 {
22498 self.write(", ");
22499 }
22500 if !field.name.is_empty() {
22501 self.write(&field.name);
22502 self.write(" ");
22503 }
22504 self.generate_data_type(&field.data_type)?;
22505 }
22506 self.write(")");
22507 }
22508 Some(DialectType::ClickHouse) => {
22509 self.write("Tuple(");
22511 for (i, field) in fields.iter().enumerate() {
22512 if i > 0 {
22513 self.write(", ");
22514 }
22515 if !field.name.is_empty() {
22516 self.write(&field.name);
22517 self.write(" ");
22518 }
22519 self.generate_data_type(&field.data_type)?;
22520 }
22521 self.write(")");
22522 }
22523 Some(DialectType::SingleStore) => {
22524 self.write_keyword("RECORD(");
22526 for (i, field) in fields.iter().enumerate() {
22527 if i > 0 {
22528 self.write(", ");
22529 }
22530 if !field.name.is_empty() {
22531 self.write(&field.name);
22532 self.write(" ");
22533 }
22534 self.generate_data_type(&field.data_type)?;
22535 }
22536 self.write(")");
22537 }
22538 _ => {
22539 let force_angle_brackets = matches!(
22541 self.config.dialect,
22542 Some(DialectType::Hive)
22543 | Some(DialectType::Spark)
22544 | Some(DialectType::Databricks)
22545 );
22546 if *nested && !force_angle_brackets {
22547 self.write_keyword("STRUCT(");
22548 for (i, field) in fields.iter().enumerate() {
22549 if i > 0 {
22550 self.write(", ");
22551 }
22552 if !field.name.is_empty() {
22553 self.write(&field.name);
22554 self.write(" ");
22555 }
22556 self.generate_data_type(&field.data_type)?;
22557 }
22558 self.write(")");
22559 } else {
22560 self.write_keyword("STRUCT<");
22561 for (i, field) in fields.iter().enumerate() {
22562 if i > 0 {
22563 self.write(", ");
22564 }
22565 if !field.name.is_empty() {
22566 self.write(&field.name);
22568 self.write(self.config.struct_field_sep);
22569 }
22570 self.generate_data_type(&field.data_type)?;
22572 if let Some(comment) = &field.comment {
22574 self.write(" COMMENT '");
22575 self.write(comment);
22576 self.write("'");
22577 }
22578 if !field.options.is_empty() {
22580 self.write(" ");
22581 self.generate_options_clause(&field.options)?;
22582 }
22583 }
22584 self.write(">");
22585 }
22586 }
22587 }
22588 }
22589 DataType::Enum {
22590 values,
22591 assignments,
22592 } => {
22593 if self.config.dialect == Some(DialectType::ClickHouse) {
22596 self.write("Enum(");
22597 } else {
22598 self.write_keyword("ENUM(");
22599 }
22600 for (i, val) in values.iter().enumerate() {
22601 if i > 0 {
22602 self.write(", ");
22603 }
22604 self.write("'");
22605 self.write(val);
22606 self.write("'");
22607 if let Some(Some(assignment)) = assignments.get(i) {
22608 self.write(" = ");
22609 self.write(assignment);
22610 }
22611 }
22612 self.write(")");
22613 }
22614 DataType::Set { values } => {
22615 self.write_keyword("SET(");
22617 for (i, val) in values.iter().enumerate() {
22618 if i > 0 {
22619 self.write(", ");
22620 }
22621 self.write("'");
22622 self.write(val);
22623 self.write("'");
22624 }
22625 self.write(")");
22626 }
22627 DataType::Union { fields } => {
22628 self.write_keyword("UNION(");
22630 for (i, (name, dt)) in fields.iter().enumerate() {
22631 if i > 0 {
22632 self.write(", ");
22633 }
22634 if !name.is_empty() {
22635 self.write(name);
22636 self.write(" ");
22637 }
22638 self.generate_data_type(dt)?;
22639 }
22640 self.write(")");
22641 }
22642 DataType::Nullable { inner } => {
22643 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22645 self.write("Nullable(");
22646 let saved_depth = self.clickhouse_nullable_depth;
22648 self.clickhouse_nullable_depth = -1;
22649 self.generate_data_type(inner)?;
22650 self.clickhouse_nullable_depth = saved_depth;
22651 self.write(")");
22652 } else {
22653 match inner.as_ref() {
22655 DataType::Custom { name } if name.to_uppercase() == "DATETIME" => {
22656 self.generate_data_type(&DataType::Timestamp {
22657 precision: None,
22658 timezone: false,
22659 })?;
22660 }
22661 _ => {
22662 self.generate_data_type(inner)?;
22663 }
22664 }
22665 }
22666 }
22667 DataType::Custom { name } => {
22668 let name_upper = name.to_uppercase();
22670 match self.config.dialect {
22671 Some(DialectType::ClickHouse) => {
22672 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
22673 (name_upper[..idx].to_string(), &name[idx..])
22674 } else {
22675 (name_upper.clone(), "")
22676 };
22677 let mapped = match base_upper.as_str() {
22678 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
22679 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
22680 "DATETIME64" => "DateTime64",
22681 "DATE32" => "Date32",
22682 "INT" => "Int32",
22683 "MEDIUMINT" => "Int32",
22684 "INT8" => "Int8",
22685 "INT16" => "Int16",
22686 "INT32" => "Int32",
22687 "INT64" => "Int64",
22688 "INT128" => "Int128",
22689 "INT256" => "Int256",
22690 "UINT8" => "UInt8",
22691 "UINT16" => "UInt16",
22692 "UINT32" => "UInt32",
22693 "UINT64" => "UInt64",
22694 "UINT128" => "UInt128",
22695 "UINT256" => "UInt256",
22696 "FLOAT32" => "Float32",
22697 "FLOAT64" => "Float64",
22698 "DECIMAL32" => "Decimal32",
22699 "DECIMAL64" => "Decimal64",
22700 "DECIMAL128" => "Decimal128",
22701 "DECIMAL256" => "Decimal256",
22702 "ENUM" => "Enum",
22703 "ENUM8" => "Enum8",
22704 "ENUM16" => "Enum16",
22705 "FIXEDSTRING" => "FixedString",
22706 "NESTED" => "Nested",
22707 "LOWCARDINALITY" => "LowCardinality",
22708 "NULLABLE" => "Nullable",
22709 "IPV4" => "IPv4",
22710 "IPV6" => "IPv6",
22711 "POINT" => "Point",
22712 "RING" => "Ring",
22713 "LINESTRING" => "LineString",
22714 "MULTILINESTRING" => "MultiLineString",
22715 "POLYGON" => "Polygon",
22716 "MULTIPOLYGON" => "MultiPolygon",
22717 "AGGREGATEFUNCTION" => "AggregateFunction",
22718 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
22719 "DYNAMIC" => "Dynamic",
22720 _ => "",
22721 };
22722 if mapped.is_empty() {
22723 self.write(name);
22724 } else {
22725 self.write(mapped);
22726 self.write(suffix);
22727 }
22728 }
22729 Some(DialectType::MySQL)
22730 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
22731 {
22732 self.write_keyword("TIMESTAMP");
22734 }
22735 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
22736 self.write_keyword("SQL_VARIANT");
22737 }
22738 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
22739 self.write_keyword("DECIMAL(38, 5)");
22740 }
22741 Some(DialectType::Exasol) => {
22742 match name_upper.as_str() {
22744 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
22746 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
22748 "MEDIUMINT" => self.write_keyword("INT"),
22750 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
22752 self.write_keyword("DECIMAL")
22753 }
22754 "DATETIME" => self.write_keyword("TIMESTAMP"),
22756 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
22757 _ => self.write(name),
22758 }
22759 }
22760 Some(DialectType::Dremio) => {
22761 match name_upper.as_str() {
22763 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
22764 "ARRAY" => self.write_keyword("LIST"),
22765 "NCHAR" => self.write_keyword("VARCHAR"),
22766 _ => self.write(name),
22767 }
22768 }
22769 _ => {
22771 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
22773 (name_upper[..idx].to_string(), Some(&name[idx..]))
22774 } else {
22775 (name_upper.clone(), None)
22776 };
22777
22778 match base_upper.as_str() {
22779 "INT64"
22780 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22781 {
22782 self.write_keyword("BIGINT");
22783 }
22784 "FLOAT64"
22785 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22786 {
22787 self.write_keyword("DOUBLE");
22788 }
22789 "BOOL"
22790 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22791 {
22792 self.write_keyword("BOOLEAN");
22793 }
22794 "BYTES"
22795 if matches!(
22796 self.config.dialect,
22797 Some(DialectType::Spark)
22798 | Some(DialectType::Hive)
22799 | Some(DialectType::Databricks)
22800 ) =>
22801 {
22802 self.write_keyword("BINARY");
22803 }
22804 "BYTES"
22805 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22806 {
22807 self.write_keyword("VARBINARY");
22808 }
22809 "DATETIME2" | "SMALLDATETIME"
22811 if !matches!(
22812 self.config.dialect,
22813 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22814 ) =>
22815 {
22816 if matches!(
22818 self.config.dialect,
22819 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22820 ) {
22821 self.write_keyword("TIMESTAMP");
22822 if let Some(args) = _args_str {
22823 self.write(args);
22824 }
22825 } else {
22826 self.write_keyword("TIMESTAMP");
22827 }
22828 }
22829 "DATETIMEOFFSET"
22831 if !matches!(
22832 self.config.dialect,
22833 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22834 ) =>
22835 {
22836 if matches!(
22837 self.config.dialect,
22838 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22839 ) {
22840 self.write_keyword("TIMESTAMPTZ");
22841 if let Some(args) = _args_str {
22842 self.write(args);
22843 }
22844 } else {
22845 self.write_keyword("TIMESTAMPTZ");
22846 }
22847 }
22848 "UNIQUEIDENTIFIER"
22850 if !matches!(
22851 self.config.dialect,
22852 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22853 ) =>
22854 {
22855 match self.config.dialect {
22856 Some(DialectType::Spark)
22857 | Some(DialectType::Databricks)
22858 | Some(DialectType::Hive) => self.write_keyword("STRING"),
22859 _ => self.write_keyword("UUID"),
22860 }
22861 }
22862 "BIT"
22864 if !matches!(
22865 self.config.dialect,
22866 Some(DialectType::TSQL)
22867 | Some(DialectType::Fabric)
22868 | Some(DialectType::PostgreSQL)
22869 | Some(DialectType::MySQL)
22870 | Some(DialectType::DuckDB)
22871 ) =>
22872 {
22873 self.write_keyword("BOOLEAN");
22874 }
22875 "NVARCHAR"
22877 if !matches!(
22878 self.config.dialect,
22879 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22880 ) =>
22881 {
22882 match self.config.dialect {
22883 Some(DialectType::Oracle) => {
22884 self.write_keyword("NVARCHAR2");
22886 if let Some(args) = _args_str {
22887 self.write(args);
22888 }
22889 }
22890 Some(DialectType::BigQuery) => {
22891 self.write_keyword("STRING");
22893 }
22894 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
22895 self.write_keyword("TEXT");
22896 if let Some(args) = _args_str {
22897 self.write(args);
22898 }
22899 }
22900 Some(DialectType::Hive) => {
22901 self.write_keyword("STRING");
22903 }
22904 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
22905 if _args_str.is_some() {
22906 self.write_keyword("VARCHAR");
22907 self.write(_args_str.unwrap());
22908 } else {
22909 self.write_keyword("STRING");
22910 }
22911 }
22912 _ => {
22913 self.write_keyword("VARCHAR");
22914 if let Some(args) = _args_str {
22915 self.write(args);
22916 }
22917 }
22918 }
22919 }
22920 "NCHAR"
22922 if !matches!(
22923 self.config.dialect,
22924 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22925 ) =>
22926 {
22927 match self.config.dialect {
22928 Some(DialectType::Oracle) => {
22929 self.write_keyword("NCHAR");
22931 if let Some(args) = _args_str {
22932 self.write(args);
22933 }
22934 }
22935 Some(DialectType::BigQuery) => {
22936 self.write_keyword("STRING");
22938 }
22939 Some(DialectType::Hive) => {
22940 self.write_keyword("STRING");
22942 }
22943 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
22944 self.write_keyword("TEXT");
22945 if let Some(args) = _args_str {
22946 self.write(args);
22947 }
22948 }
22949 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
22950 if _args_str.is_some() {
22951 self.write_keyword("CHAR");
22952 self.write(_args_str.unwrap());
22953 } else {
22954 self.write_keyword("STRING");
22955 }
22956 }
22957 _ => {
22958 self.write_keyword("CHAR");
22959 if let Some(args) = _args_str {
22960 self.write(args);
22961 }
22962 }
22963 }
22964 }
22965 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
22968 Some(DialectType::MySQL)
22969 | Some(DialectType::SingleStore)
22970 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
22971 Some(DialectType::Spark)
22972 | Some(DialectType::Databricks)
22973 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
22974 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
22975 Some(DialectType::Presto)
22976 | Some(DialectType::Trino)
22977 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
22978 Some(DialectType::Snowflake)
22979 | Some(DialectType::Redshift)
22980 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
22981 _ => self.write_keyword("TEXT"),
22982 },
22983 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
22986 Some(DialectType::MySQL)
22987 | Some(DialectType::SingleStore)
22988 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
22989 Some(DialectType::Spark)
22990 | Some(DialectType::Databricks)
22991 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
22992 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
22993 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
22994 Some(DialectType::Presto)
22995 | Some(DialectType::Trino)
22996 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
22997 Some(DialectType::Snowflake)
22998 | Some(DialectType::Redshift)
22999 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
23000 _ => self.write_keyword("BLOB"),
23001 },
23002 "LONGVARCHAR" => match self.config.dialect {
23004 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
23005 _ => self.write_keyword("VARCHAR"),
23006 },
23007 "DATETIME" => {
23009 match self.config.dialect {
23010 Some(DialectType::MySQL)
23011 | Some(DialectType::Doris)
23012 | Some(DialectType::StarRocks)
23013 | Some(DialectType::TSQL)
23014 | Some(DialectType::Fabric)
23015 | Some(DialectType::BigQuery)
23016 | Some(DialectType::SQLite)
23017 | Some(DialectType::Snowflake) => {
23018 self.write_keyword("DATETIME");
23019 if let Some(args) = _args_str {
23020 self.write(args);
23021 }
23022 }
23023 Some(_) => {
23024 self.write_keyword("TIMESTAMP");
23026 if let Some(args) = _args_str {
23027 self.write(args);
23028 }
23029 }
23030 None => {
23031 self.write(name);
23033 }
23034 }
23035 }
23036 "VARCHAR2"
23038 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
23039 {
23040 match self.config.dialect {
23041 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23042 self.write_keyword("TEXT");
23043 }
23044 Some(DialectType::Hive)
23045 | Some(DialectType::Spark)
23046 | Some(DialectType::Databricks)
23047 | Some(DialectType::BigQuery)
23048 | Some(DialectType::ClickHouse)
23049 | Some(DialectType::StarRocks)
23050 | Some(DialectType::Doris) => {
23051 self.write_keyword("STRING");
23052 }
23053 _ => {
23054 self.write_keyword("VARCHAR");
23055 if let Some(args) = _args_str {
23056 self.write(args);
23057 }
23058 }
23059 }
23060 }
23061 "NVARCHAR2"
23062 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
23063 {
23064 match self.config.dialect {
23065 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23066 self.write_keyword("TEXT");
23067 }
23068 Some(DialectType::Hive)
23069 | Some(DialectType::Spark)
23070 | Some(DialectType::Databricks)
23071 | Some(DialectType::BigQuery)
23072 | Some(DialectType::ClickHouse)
23073 | Some(DialectType::StarRocks)
23074 | Some(DialectType::Doris) => {
23075 self.write_keyword("STRING");
23076 }
23077 _ => {
23078 self.write_keyword("VARCHAR");
23079 if let Some(args) = _args_str {
23080 self.write(args);
23081 }
23082 }
23083 }
23084 }
23085 _ => self.write(name),
23086 }
23087 }
23088 }
23089 }
23090 DataType::Geometry { subtype, srid } => {
23091 match self.config.dialect {
23093 Some(DialectType::MySQL) => {
23094 if let Some(sub) = subtype {
23096 self.write_keyword(sub);
23097 if let Some(s) = srid {
23098 self.write(" SRID ");
23099 self.write(&s.to_string());
23100 }
23101 } else {
23102 self.write_keyword("GEOMETRY");
23103 }
23104 }
23105 Some(DialectType::BigQuery) => {
23106 self.write_keyword("GEOGRAPHY");
23108 }
23109 Some(DialectType::Teradata) => {
23110 self.write_keyword("ST_GEOMETRY");
23112 if subtype.is_some() || srid.is_some() {
23113 self.write("(");
23114 if let Some(sub) = subtype {
23115 self.write_keyword(sub);
23116 }
23117 if let Some(s) = srid {
23118 if subtype.is_some() {
23119 self.write(", ");
23120 }
23121 self.write(&s.to_string());
23122 }
23123 self.write(")");
23124 }
23125 }
23126 _ => {
23127 self.write_keyword("GEOMETRY");
23129 if subtype.is_some() || srid.is_some() {
23130 self.write("(");
23131 if let Some(sub) = subtype {
23132 self.write_keyword(sub);
23133 }
23134 if let Some(s) = srid {
23135 if subtype.is_some() {
23136 self.write(", ");
23137 }
23138 self.write(&s.to_string());
23139 }
23140 self.write(")");
23141 }
23142 }
23143 }
23144 }
23145 DataType::Geography { subtype, srid } => {
23146 match self.config.dialect {
23148 Some(DialectType::MySQL) => {
23149 if let Some(sub) = subtype {
23151 self.write_keyword(sub);
23152 } else {
23153 self.write_keyword("GEOMETRY");
23154 }
23155 let effective_srid = srid.unwrap_or(4326);
23157 self.write(" SRID ");
23158 self.write(&effective_srid.to_string());
23159 }
23160 Some(DialectType::BigQuery) => {
23161 self.write_keyword("GEOGRAPHY");
23163 }
23164 Some(DialectType::Snowflake) => {
23165 self.write_keyword("GEOGRAPHY");
23167 }
23168 _ => {
23169 self.write_keyword("GEOGRAPHY");
23171 if subtype.is_some() || srid.is_some() {
23172 self.write("(");
23173 if let Some(sub) = subtype {
23174 self.write_keyword(sub);
23175 }
23176 if let Some(s) = srid {
23177 if subtype.is_some() {
23178 self.write(", ");
23179 }
23180 self.write(&s.to_string());
23181 }
23182 self.write(")");
23183 }
23184 }
23185 }
23186 }
23187 DataType::CharacterSet { name } => {
23188 self.write_keyword("CHAR CHARACTER SET ");
23190 self.write(name);
23191 }
23192 _ => self.write("UNKNOWN"),
23193 }
23194 Ok(())
23195 }
23196
23197 fn write(&mut self, s: &str) {
23200 self.output.push_str(s);
23201 }
23202
23203 fn write_space(&mut self) {
23204 self.output.push(' ');
23205 }
23206
23207 fn write_keyword(&mut self, keyword: &str) {
23208 if self.config.uppercase_keywords {
23209 self.output.push_str(keyword);
23210 } else {
23211 self.output.push_str(&keyword.to_lowercase());
23212 }
23213 }
23214
23215 fn write_func_name(&mut self, name: &str) {
23217 let normalized = self.normalize_func_name(name);
23218 self.output.push_str(&normalized);
23219 }
23220
23221 fn convert_strptime_to_exasol_format(format: &str) -> String {
23225 let mut result = String::new();
23226 let chars: Vec<char> = format.chars().collect();
23227 let mut i = 0;
23228 while i < chars.len() {
23229 if chars[i] == '%' && i + 1 < chars.len() {
23230 let spec = chars[i + 1];
23231 let exasol_spec = match spec {
23232 'Y' => "YYYY",
23233 'y' => "YY",
23234 'm' => "MM",
23235 'd' => "DD",
23236 'H' => "HH",
23237 'M' => "MI",
23238 'S' => "SS",
23239 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
23251 result.push('%');
23253 result.push(spec);
23254 i += 2;
23255 continue;
23256 }
23257 };
23258 result.push_str(exasol_spec);
23259 i += 2;
23260 } else {
23261 result.push(chars[i]);
23262 i += 1;
23263 }
23264 }
23265 result
23266 }
23267
23268 fn convert_strptime_to_postgres_format(format: &str) -> String {
23272 let mut result = String::new();
23273 let chars: Vec<char> = format.chars().collect();
23274 let mut i = 0;
23275 while i < chars.len() {
23276 if chars[i] == '%' && i + 1 < chars.len() {
23277 if chars[i + 1] == '-' && i + 2 < chars.len() {
23279 let spec = chars[i + 2];
23280 let pg_spec = match spec {
23281 'd' => "FMDD",
23282 'm' => "FMMM",
23283 'H' => "FMHH24",
23284 'M' => "FMMI",
23285 'S' => "FMSS",
23286 _ => {
23287 result.push('%');
23288 result.push('-');
23289 result.push(spec);
23290 i += 3;
23291 continue;
23292 }
23293 };
23294 result.push_str(pg_spec);
23295 i += 3;
23296 continue;
23297 }
23298 let spec = chars[i + 1];
23299 let pg_spec = match spec {
23300 'Y' => "YYYY",
23301 'y' => "YY",
23302 'm' => "MM",
23303 'd' => "DD",
23304 'H' => "HH24",
23305 'I' => "HH12",
23306 'M' => "MI",
23307 'S' => "SS",
23308 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
23319 result.push('%');
23321 result.push(spec);
23322 i += 2;
23323 continue;
23324 }
23325 };
23326 result.push_str(pg_spec);
23327 i += 2;
23328 } else {
23329 result.push(chars[i]);
23330 i += 1;
23331 }
23332 }
23333 result
23334 }
23335
23336 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
23338 if self.config.limit_only_literals {
23339 if let Some(value) = Self::try_evaluate_constant(expr) {
23340 self.write(&value.to_string());
23341 return Ok(());
23342 }
23343 }
23344 self.generate_expression(expr)
23345 }
23346
23347 fn write_formatted_comment(&mut self, comment: &str) {
23351 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
23354 &comment[2..comment.len() - 2]
23357 } else if comment.starts_with("--") {
23358 &comment[2..]
23361 } else {
23362 comment
23364 };
23365 if content.trim().is_empty() {
23367 return;
23368 }
23369 self.output.push_str("/*");
23371 if !content.starts_with(' ') {
23372 self.output.push(' ');
23373 }
23374 self.output.push_str(content);
23375 if !content.ends_with(' ') {
23376 self.output.push(' ');
23377 }
23378 self.output.push_str("*/");
23379 }
23380
23381 fn escape_block_for_single_quote(&self, block: &str) -> String {
23384 let escape_backslash = matches!(
23385 self.config.dialect,
23386 Some(crate::dialects::DialectType::Snowflake)
23387 );
23388 let mut escaped = String::with_capacity(block.len() + 4);
23389 for ch in block.chars() {
23390 if ch == '\'' {
23391 escaped.push('\\');
23392 escaped.push('\'');
23393 } else if escape_backslash && ch == '\\' {
23394 escaped.push('\\');
23395 escaped.push('\\');
23396 } else {
23397 escaped.push(ch);
23398 }
23399 }
23400 escaped
23401 }
23402
23403 fn write_newline(&mut self) {
23404 self.output.push('\n');
23405 }
23406
23407 fn write_indent(&mut self) {
23408 for _ in 0..self.indent_level {
23409 self.output.push_str(&self.config.indent);
23410 }
23411 }
23412
23413 fn too_wide(&self, args: &[String]) -> bool {
23419 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
23420 }
23421
23422 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
23425 let config = GeneratorConfig {
23426 pretty: false,
23427 dialect: self.config.dialect,
23428 ..Default::default()
23429 };
23430 let mut gen = Generator::with_config(config);
23431 gen.generate_expression(expr)?;
23432 Ok(gen.output)
23433 }
23434
23435 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
23438 if self.config.pretty {
23439 self.write_newline();
23440 self.write_indent();
23441 self.write_keyword(keyword);
23442 self.write_newline();
23443 self.indent_level += 1;
23444 self.write_indent();
23445 self.generate_expression(condition)?;
23446 self.indent_level -= 1;
23447 } else {
23448 self.write_space();
23449 self.write_keyword(keyword);
23450 self.write_space();
23451 self.generate_expression(condition)?;
23452 }
23453 Ok(())
23454 }
23455
23456 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
23459 if exprs.is_empty() {
23460 return Ok(());
23461 }
23462
23463 if self.config.pretty {
23464 self.write_newline();
23465 self.write_indent();
23466 self.write_keyword(keyword);
23467 self.write_newline();
23468 self.indent_level += 1;
23469 for (i, expr) in exprs.iter().enumerate() {
23470 if i > 0 {
23471 self.write(",");
23472 self.write_newline();
23473 }
23474 self.write_indent();
23475 self.generate_expression(expr)?;
23476 }
23477 self.indent_level -= 1;
23478 } else {
23479 self.write_space();
23480 self.write_keyword(keyword);
23481 self.write_space();
23482 for (i, expr) in exprs.iter().enumerate() {
23483 if i > 0 {
23484 self.write(", ");
23485 }
23486 self.generate_expression(expr)?;
23487 }
23488 }
23489 Ok(())
23490 }
23491
23492 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
23494 if orderings.is_empty() {
23495 return Ok(());
23496 }
23497
23498 if self.config.pretty {
23499 self.write_newline();
23500 self.write_indent();
23501 self.write_keyword(keyword);
23502 self.write_newline();
23503 self.indent_level += 1;
23504 for (i, ordered) in orderings.iter().enumerate() {
23505 if i > 0 {
23506 self.write(",");
23507 self.write_newline();
23508 }
23509 self.write_indent();
23510 self.generate_ordered(ordered)?;
23511 }
23512 self.indent_level -= 1;
23513 } else {
23514 self.write_space();
23515 self.write_keyword(keyword);
23516 self.write_space();
23517 for (i, ordered) in orderings.iter().enumerate() {
23518 if i > 0 {
23519 self.write(", ");
23520 }
23521 self.generate_ordered(ordered)?;
23522 }
23523 }
23524 Ok(())
23525 }
23526
23527 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
23529 if windows.is_empty() {
23530 return Ok(());
23531 }
23532
23533 if self.config.pretty {
23534 self.write_newline();
23535 self.write_indent();
23536 self.write_keyword("WINDOW");
23537 self.write_newline();
23538 self.indent_level += 1;
23539 for (i, named_window) in windows.iter().enumerate() {
23540 if i > 0 {
23541 self.write(",");
23542 self.write_newline();
23543 }
23544 self.write_indent();
23545 self.generate_identifier(&named_window.name)?;
23546 self.write_space();
23547 self.write_keyword("AS");
23548 self.write(" (");
23549 self.generate_over(&named_window.spec)?;
23550 self.write(")");
23551 }
23552 self.indent_level -= 1;
23553 } else {
23554 self.write_space();
23555 self.write_keyword("WINDOW");
23556 self.write_space();
23557 for (i, named_window) in windows.iter().enumerate() {
23558 if i > 0 {
23559 self.write(", ");
23560 }
23561 self.generate_identifier(&named_window.name)?;
23562 self.write_space();
23563 self.write_keyword("AS");
23564 self.write(" (");
23565 self.generate_over(&named_window.spec)?;
23566 self.write(")");
23567 }
23568 }
23569 Ok(())
23570 }
23571
23572 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
23574 self.write_keyword("AI_AGG");
23576 self.write("(");
23577 self.generate_expression(&e.this)?;
23578 self.write(", ");
23579 self.generate_expression(&e.expression)?;
23580 self.write(")");
23581 Ok(())
23582 }
23583
23584 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
23585 self.write_keyword("AI_CLASSIFY");
23587 self.write("(");
23588 self.generate_expression(&e.this)?;
23589 if let Some(categories) = &e.categories {
23590 self.write(", ");
23591 self.generate_expression(categories)?;
23592 }
23593 if let Some(config) = &e.config {
23594 self.write(", ");
23595 self.generate_expression(config)?;
23596 }
23597 self.write(")");
23598 Ok(())
23599 }
23600
23601 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
23602 self.write_keyword("ADD");
23604 self.write_space();
23605 if e.exists {
23606 self.write_keyword("IF NOT EXISTS");
23607 self.write_space();
23608 }
23609 self.generate_expression(&e.this)?;
23610 if let Some(location) = &e.location {
23611 self.write_space();
23612 self.generate_expression(location)?;
23613 }
23614 Ok(())
23615 }
23616
23617 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
23618 self.write_keyword("ALGORITHM");
23620 self.write("=");
23621 self.generate_expression(&e.this)?;
23622 Ok(())
23623 }
23624
23625 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
23626 self.generate_expression(&e.this)?;
23628 self.write_space();
23629 self.write_keyword("AS");
23630 self.write(" (");
23631 for (i, expr) in e.expressions.iter().enumerate() {
23632 if i > 0 {
23633 self.write(", ");
23634 }
23635 self.generate_expression(expr)?;
23636 }
23637 self.write(")");
23638 Ok(())
23639 }
23640
23641 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
23642 self.write_keyword("ALLOWED_VALUES");
23644 self.write_space();
23645 for (i, expr) in e.expressions.iter().enumerate() {
23646 if i > 0 {
23647 self.write(", ");
23648 }
23649 self.generate_expression(expr)?;
23650 }
23651 Ok(())
23652 }
23653
23654 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
23655 self.write_keyword("ALTER COLUMN");
23657 self.write_space();
23658 self.generate_expression(&e.this)?;
23659
23660 if let Some(dtype) = &e.dtype {
23661 self.write_space();
23662 self.write_keyword("SET DATA TYPE");
23663 self.write_space();
23664 self.generate_expression(dtype)?;
23665 if let Some(collate) = &e.collate {
23666 self.write_space();
23667 self.write_keyword("COLLATE");
23668 self.write_space();
23669 self.generate_expression(collate)?;
23670 }
23671 if let Some(using) = &e.using {
23672 self.write_space();
23673 self.write_keyword("USING");
23674 self.write_space();
23675 self.generate_expression(using)?;
23676 }
23677 } else if let Some(default) = &e.default {
23678 self.write_space();
23679 self.write_keyword("SET DEFAULT");
23680 self.write_space();
23681 self.generate_expression(default)?;
23682 } else if let Some(comment) = &e.comment {
23683 self.write_space();
23684 self.write_keyword("COMMENT");
23685 self.write_space();
23686 self.generate_expression(comment)?;
23687 } else if let Some(drop) = &e.drop {
23688 self.write_space();
23689 self.write_keyword("DROP");
23690 self.write_space();
23691 self.generate_expression(drop)?;
23692 } else if let Some(visible) = &e.visible {
23693 self.write_space();
23694 self.generate_expression(visible)?;
23695 } else if let Some(rename_to) = &e.rename_to {
23696 self.write_space();
23697 self.write_keyword("RENAME TO");
23698 self.write_space();
23699 self.generate_expression(rename_to)?;
23700 } else if let Some(allow_null) = &e.allow_null {
23701 self.write_space();
23702 self.generate_expression(allow_null)?;
23703 }
23704 Ok(())
23705 }
23706
23707 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
23708 self.write_keyword("ALTER SESSION");
23710 self.write_space();
23711 if e.unset.is_some() {
23712 self.write_keyword("UNSET");
23713 } else {
23714 self.write_keyword("SET");
23715 }
23716 self.write_space();
23717 for (i, expr) in e.expressions.iter().enumerate() {
23718 if i > 0 {
23719 self.write(", ");
23720 }
23721 self.generate_expression(expr)?;
23722 }
23723 Ok(())
23724 }
23725
23726 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
23727 self.write_keyword("SET");
23729
23730 if let Some(opt) = &e.option {
23732 self.write_space();
23733 self.generate_expression(opt)?;
23734 }
23735
23736 if !e.expressions.is_empty() {
23739 let is_properties = e
23741 .expressions
23742 .iter()
23743 .any(|expr| matches!(expr, Expression::Eq(_)));
23744 if is_properties && e.option.is_none() {
23745 self.write_space();
23746 self.write_keyword("PROPERTIES");
23747 }
23748 self.write_space();
23749 for (i, expr) in e.expressions.iter().enumerate() {
23750 if i > 0 {
23751 self.write(", ");
23752 }
23753 self.generate_expression(expr)?;
23754 }
23755 }
23756
23757 if let Some(file_format) = &e.file_format {
23759 self.write(" ");
23760 self.write_keyword("STAGE_FILE_FORMAT");
23761 self.write(" = (");
23762 self.generate_space_separated_properties(file_format)?;
23763 self.write(")");
23764 }
23765
23766 if let Some(copy_options) = &e.copy_options {
23768 self.write(" ");
23769 self.write_keyword("STAGE_COPY_OPTIONS");
23770 self.write(" = (");
23771 self.generate_space_separated_properties(copy_options)?;
23772 self.write(")");
23773 }
23774
23775 if let Some(tag) = &e.tag {
23777 self.write(" ");
23778 self.write_keyword("TAG");
23779 self.write(" ");
23780 self.generate_expression(tag)?;
23781 }
23782
23783 Ok(())
23784 }
23785
23786 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
23788 match expr {
23789 Expression::Tuple(t) => {
23790 for (i, prop) in t.expressions.iter().enumerate() {
23791 if i > 0 {
23792 self.write(" ");
23793 }
23794 self.generate_expression(prop)?;
23795 }
23796 }
23797 _ => {
23798 self.generate_expression(expr)?;
23799 }
23800 }
23801 Ok(())
23802 }
23803
23804 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
23805 self.write_keyword("ALTER");
23807 if e.compound.is_some() {
23808 self.write_space();
23809 self.write_keyword("COMPOUND");
23810 }
23811 self.write_space();
23812 self.write_keyword("SORTKEY");
23813 self.write_space();
23814 if let Some(this) = &e.this {
23815 self.generate_expression(this)?;
23816 } else if !e.expressions.is_empty() {
23817 self.write("(");
23818 for (i, expr) in e.expressions.iter().enumerate() {
23819 if i > 0 {
23820 self.write(", ");
23821 }
23822 self.generate_expression(expr)?;
23823 }
23824 self.write(")");
23825 }
23826 Ok(())
23827 }
23828
23829 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
23830 self.write_keyword("ANALYZE");
23832 if !e.options.is_empty() {
23833 self.write_space();
23834 for (i, opt) in e.options.iter().enumerate() {
23835 if i > 0 {
23836 self.write_space();
23837 }
23838 if let Expression::Identifier(id) = opt {
23840 self.write_keyword(&id.name);
23841 } else {
23842 self.generate_expression(opt)?;
23843 }
23844 }
23845 }
23846 if let Some(kind) = &e.kind {
23847 self.write_space();
23848 self.write_keyword(kind);
23849 }
23850 if let Some(this) = &e.this {
23851 self.write_space();
23852 self.generate_expression(this)?;
23853 }
23854 if !e.columns.is_empty() {
23856 self.write("(");
23857 for (i, col) in e.columns.iter().enumerate() {
23858 if i > 0 {
23859 self.write(", ");
23860 }
23861 self.write(col);
23862 }
23863 self.write(")");
23864 }
23865 if let Some(partition) = &e.partition {
23866 self.write_space();
23867 self.generate_expression(partition)?;
23868 }
23869 if let Some(mode) = &e.mode {
23870 self.write_space();
23871 self.generate_expression(mode)?;
23872 }
23873 if let Some(expression) = &e.expression {
23874 self.write_space();
23875 self.generate_expression(expression)?;
23876 }
23877 if !e.properties.is_empty() {
23878 self.write_space();
23879 self.write_keyword(self.config.with_properties_prefix);
23880 self.write(" (");
23881 for (i, prop) in e.properties.iter().enumerate() {
23882 if i > 0 {
23883 self.write(", ");
23884 }
23885 self.generate_expression(prop)?;
23886 }
23887 self.write(")");
23888 }
23889 Ok(())
23890 }
23891
23892 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
23893 self.write_keyword("DELETE");
23895 if let Some(kind) = &e.kind {
23896 self.write_space();
23897 self.write_keyword(kind);
23898 }
23899 self.write_space();
23900 self.write_keyword("STATISTICS");
23901 Ok(())
23902 }
23903
23904 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
23905 if let Expression::Identifier(id) = e.this.as_ref() {
23908 self.write_keyword(&id.name);
23909 } else {
23910 self.generate_expression(&e.this)?;
23911 }
23912 self.write_space();
23913 self.write_keyword("HISTOGRAM ON");
23914 self.write_space();
23915 for (i, expr) in e.expressions.iter().enumerate() {
23916 if i > 0 {
23917 self.write(", ");
23918 }
23919 self.generate_expression(expr)?;
23920 }
23921 if let Some(expression) = &e.expression {
23922 self.write_space();
23923 self.generate_expression(expression)?;
23924 }
23925 if let Some(update_options) = &e.update_options {
23926 self.write_space();
23927 self.generate_expression(update_options)?;
23928 self.write_space();
23929 self.write_keyword("UPDATE");
23930 }
23931 Ok(())
23932 }
23933
23934 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
23935 self.write_keyword("LIST CHAINED ROWS");
23937 if let Some(expression) = &e.expression {
23938 self.write_space();
23939 self.write_keyword("INTO");
23940 self.write_space();
23941 self.generate_expression(expression)?;
23942 }
23943 Ok(())
23944 }
23945
23946 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
23947 self.write_keyword("SAMPLE");
23949 self.write_space();
23950 if let Some(sample) = &e.sample {
23951 self.generate_expression(sample)?;
23952 self.write_space();
23953 }
23954 self.write_keyword(&e.kind);
23955 Ok(())
23956 }
23957
23958 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
23959 self.write_keyword(&e.kind);
23961 if let Some(option) = &e.option {
23962 self.write_space();
23963 self.generate_expression(option)?;
23964 }
23965 self.write_space();
23966 self.write_keyword("STATISTICS");
23967 if let Some(this) = &e.this {
23968 self.write_space();
23969 self.generate_expression(this)?;
23970 }
23971 if !e.expressions.is_empty() {
23972 self.write_space();
23973 for (i, expr) in e.expressions.iter().enumerate() {
23974 if i > 0 {
23975 self.write(", ");
23976 }
23977 self.generate_expression(expr)?;
23978 }
23979 }
23980 Ok(())
23981 }
23982
23983 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
23984 self.write_keyword("VALIDATE");
23986 self.write_space();
23987 self.write_keyword(&e.kind);
23988 if let Some(this) = &e.this {
23989 self.write_space();
23990 if let Expression::Identifier(id) = this.as_ref() {
23992 self.write_keyword(&id.name);
23993 } else {
23994 self.generate_expression(this)?;
23995 }
23996 }
23997 if let Some(expression) = &e.expression {
23998 self.write_space();
23999 self.write_keyword("INTO");
24000 self.write_space();
24001 self.generate_expression(expression)?;
24002 }
24003 Ok(())
24004 }
24005
24006 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
24007 self.write_keyword("WITH");
24009 self.write_space();
24010 for (i, expr) in e.expressions.iter().enumerate() {
24011 if i > 0 {
24012 self.write(", ");
24013 }
24014 self.generate_expression(expr)?;
24015 }
24016 Ok(())
24017 }
24018
24019 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
24020 self.generate_expression(&e.this)?;
24023 self.write("(");
24024 for (i, arg) in e.expressions.iter().enumerate() {
24025 if i > 0 {
24026 self.write(", ");
24027 }
24028 self.generate_expression(arg)?;
24029 }
24030 self.write(")");
24031 Ok(())
24032 }
24033
24034 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
24035 self.generate_expression(&e.this)?;
24037 self.write("(");
24038 for (i, arg) in e.expressions.iter().enumerate() {
24039 if i > 0 {
24040 self.write(", ");
24041 }
24042 self.generate_expression(arg)?;
24043 }
24044 self.write(")");
24045 Ok(())
24046 }
24047
24048 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
24049 self.generate_expression(&e.this)?;
24051 self.write_space();
24052 self.write_keyword("APPLY");
24053 self.write("(");
24054 self.generate_expression(&e.expression)?;
24055 self.write(")");
24056 Ok(())
24057 }
24058
24059 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
24060 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
24062 self.write("(");
24063 self.generate_expression(&e.this)?;
24064 if let Some(percentile) = &e.percentile {
24065 self.write(", ");
24066 self.generate_expression(percentile)?;
24067 }
24068 self.write(")");
24069 Ok(())
24070 }
24071
24072 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
24073 self.write_keyword("APPROX_QUANTILE");
24075 self.write("(");
24076 self.generate_expression(&e.this)?;
24077 if let Some(quantile) = &e.quantile {
24078 self.write(", ");
24079 self.generate_expression(quantile)?;
24080 }
24081 if let Some(accuracy) = &e.accuracy {
24082 self.write(", ");
24083 self.generate_expression(accuracy)?;
24084 }
24085 if let Some(weight) = &e.weight {
24086 self.write(", ");
24087 self.generate_expression(weight)?;
24088 }
24089 self.write(")");
24090 Ok(())
24091 }
24092
24093 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
24094 self.write_keyword("APPROX_QUANTILES");
24096 self.write("(");
24097 self.generate_expression(&e.this)?;
24098 if let Some(expression) = &e.expression {
24099 self.write(", ");
24100 self.generate_expression(expression)?;
24101 }
24102 self.write(")");
24103 Ok(())
24104 }
24105
24106 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
24107 self.write_keyword("APPROX_TOP_K");
24109 self.write("(");
24110 self.generate_expression(&e.this)?;
24111 if let Some(expression) = &e.expression {
24112 self.write(", ");
24113 self.generate_expression(expression)?;
24114 }
24115 if let Some(counters) = &e.counters {
24116 self.write(", ");
24117 self.generate_expression(counters)?;
24118 }
24119 self.write(")");
24120 Ok(())
24121 }
24122
24123 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
24124 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
24126 self.write("(");
24127 self.generate_expression(&e.this)?;
24128 if let Some(expression) = &e.expression {
24129 self.write(", ");
24130 self.generate_expression(expression)?;
24131 }
24132 self.write(")");
24133 Ok(())
24134 }
24135
24136 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
24137 self.write_keyword("APPROX_TOP_K_COMBINE");
24139 self.write("(");
24140 self.generate_expression(&e.this)?;
24141 if let Some(expression) = &e.expression {
24142 self.write(", ");
24143 self.generate_expression(expression)?;
24144 }
24145 self.write(")");
24146 Ok(())
24147 }
24148
24149 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
24150 self.write_keyword("APPROX_TOP_K_ESTIMATE");
24152 self.write("(");
24153 self.generate_expression(&e.this)?;
24154 if let Some(expression) = &e.expression {
24155 self.write(", ");
24156 self.generate_expression(expression)?;
24157 }
24158 self.write(")");
24159 Ok(())
24160 }
24161
24162 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
24163 self.write_keyword("APPROX_TOP_SUM");
24165 self.write("(");
24166 self.generate_expression(&e.this)?;
24167 self.write(", ");
24168 self.generate_expression(&e.expression)?;
24169 if let Some(count) = &e.count {
24170 self.write(", ");
24171 self.generate_expression(count)?;
24172 }
24173 self.write(")");
24174 Ok(())
24175 }
24176
24177 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
24178 self.write_keyword("ARG_MAX");
24180 self.write("(");
24181 self.generate_expression(&e.this)?;
24182 self.write(", ");
24183 self.generate_expression(&e.expression)?;
24184 if let Some(count) = &e.count {
24185 self.write(", ");
24186 self.generate_expression(count)?;
24187 }
24188 self.write(")");
24189 Ok(())
24190 }
24191
24192 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
24193 self.write_keyword("ARG_MIN");
24195 self.write("(");
24196 self.generate_expression(&e.this)?;
24197 self.write(", ");
24198 self.generate_expression(&e.expression)?;
24199 if let Some(count) = &e.count {
24200 self.write(", ");
24201 self.generate_expression(count)?;
24202 }
24203 self.write(")");
24204 Ok(())
24205 }
24206
24207 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
24208 self.write_keyword("ARRAY_ALL");
24210 self.write("(");
24211 self.generate_expression(&e.this)?;
24212 self.write(", ");
24213 self.generate_expression(&e.expression)?;
24214 self.write(")");
24215 Ok(())
24216 }
24217
24218 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
24219 self.write_keyword("ARRAY_ANY");
24221 self.write("(");
24222 self.generate_expression(&e.this)?;
24223 self.write(", ");
24224 self.generate_expression(&e.expression)?;
24225 self.write(")");
24226 Ok(())
24227 }
24228
24229 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
24230 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
24232 self.write("(");
24233 for (i, expr) in e.expressions.iter().enumerate() {
24234 if i > 0 {
24235 self.write(", ");
24236 }
24237 self.generate_expression(expr)?;
24238 }
24239 self.write(")");
24240 Ok(())
24241 }
24242
24243 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
24244 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24246 self.write("arraySum");
24247 } else {
24248 self.write_keyword("ARRAY_SUM");
24249 }
24250 self.write("(");
24251 self.generate_expression(&e.this)?;
24252 if let Some(expression) = &e.expression {
24253 self.write(", ");
24254 self.generate_expression(expression)?;
24255 }
24256 self.write(")");
24257 Ok(())
24258 }
24259
24260 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
24261 self.generate_expression(&e.this)?;
24263 self.write_space();
24264 self.write_keyword("AT");
24265 self.write_space();
24266 self.generate_expression(&e.expression)?;
24267 Ok(())
24268 }
24269
24270 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
24271 self.write_keyword("ATTACH");
24273 if e.exists {
24274 self.write_space();
24275 self.write_keyword("IF NOT EXISTS");
24276 }
24277 self.write_space();
24278 self.generate_expression(&e.this)?;
24279 if !e.expressions.is_empty() {
24280 self.write(" (");
24281 for (i, expr) in e.expressions.iter().enumerate() {
24282 if i > 0 {
24283 self.write(", ");
24284 }
24285 self.generate_expression(expr)?;
24286 }
24287 self.write(")");
24288 }
24289 Ok(())
24290 }
24291
24292 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
24293 self.generate_expression(&e.this)?;
24296 if let Some(expression) = &e.expression {
24297 self.write_space();
24298 self.generate_expression(expression)?;
24299 }
24300 Ok(())
24301 }
24302
24303 fn generate_auto_increment_keyword(
24307 &mut self,
24308 col: &crate::expressions::ColumnDef,
24309 ) -> Result<()> {
24310 use crate::dialects::DialectType;
24311 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
24312 self.write_keyword("IDENTITY");
24313 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24314 self.write("(");
24315 if let Some(ref start) = col.auto_increment_start {
24316 self.generate_expression(start)?;
24317 } else {
24318 self.write("0");
24319 }
24320 self.write(", ");
24321 if let Some(ref inc) = col.auto_increment_increment {
24322 self.generate_expression(inc)?;
24323 } else {
24324 self.write("1");
24325 }
24326 self.write(")");
24327 }
24328 } else if matches!(
24329 self.config.dialect,
24330 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
24331 ) {
24332 self.write_keyword("AUTOINCREMENT");
24333 if let Some(ref start) = col.auto_increment_start {
24334 self.write_space();
24335 self.write_keyword("START");
24336 self.write_space();
24337 self.generate_expression(start)?;
24338 }
24339 if let Some(ref inc) = col.auto_increment_increment {
24340 self.write_space();
24341 self.write_keyword("INCREMENT");
24342 self.write_space();
24343 self.generate_expression(inc)?;
24344 }
24345 if let Some(order) = col.auto_increment_order {
24346 self.write_space();
24347 if order {
24348 self.write_keyword("ORDER");
24349 } else {
24350 self.write_keyword("NOORDER");
24351 }
24352 }
24353 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
24354 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
24355 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24356 self.write(" (");
24357 let mut first = true;
24358 if let Some(ref start) = col.auto_increment_start {
24359 self.write_keyword("START WITH");
24360 self.write_space();
24361 self.generate_expression(start)?;
24362 first = false;
24363 }
24364 if let Some(ref inc) = col.auto_increment_increment {
24365 if !first {
24366 self.write_space();
24367 }
24368 self.write_keyword("INCREMENT BY");
24369 self.write_space();
24370 self.generate_expression(inc)?;
24371 }
24372 self.write(")");
24373 }
24374 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
24375 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
24376 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24377 self.write(" (");
24378 let mut first = true;
24379 if let Some(ref start) = col.auto_increment_start {
24380 self.write_keyword("START WITH");
24381 self.write_space();
24382 self.generate_expression(start)?;
24383 first = false;
24384 }
24385 if let Some(ref inc) = col.auto_increment_increment {
24386 if !first {
24387 self.write_space();
24388 }
24389 self.write_keyword("INCREMENT BY");
24390 self.write_space();
24391 self.generate_expression(inc)?;
24392 }
24393 self.write(")");
24394 }
24395 } else if matches!(
24396 self.config.dialect,
24397 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24398 ) {
24399 self.write_keyword("IDENTITY");
24400 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24401 self.write("(");
24402 if let Some(ref start) = col.auto_increment_start {
24403 self.generate_expression(start)?;
24404 } else {
24405 self.write("0");
24406 }
24407 self.write(", ");
24408 if let Some(ref inc) = col.auto_increment_increment {
24409 self.generate_expression(inc)?;
24410 } else {
24411 self.write("1");
24412 }
24413 self.write(")");
24414 }
24415 } else {
24416 self.write_keyword("AUTO_INCREMENT");
24417 if let Some(ref start) = col.auto_increment_start {
24418 self.write_space();
24419 self.write_keyword("START");
24420 self.write_space();
24421 self.generate_expression(start)?;
24422 }
24423 if let Some(ref inc) = col.auto_increment_increment {
24424 self.write_space();
24425 self.write_keyword("INCREMENT");
24426 self.write_space();
24427 self.generate_expression(inc)?;
24428 }
24429 if let Some(order) = col.auto_increment_order {
24430 self.write_space();
24431 if order {
24432 self.write_keyword("ORDER");
24433 } else {
24434 self.write_keyword("NOORDER");
24435 }
24436 }
24437 }
24438 Ok(())
24439 }
24440
24441 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
24442 self.write_keyword("AUTO_INCREMENT");
24444 self.write("=");
24445 self.generate_expression(&e.this)?;
24446 Ok(())
24447 }
24448
24449 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
24450 self.write_keyword("AUTO_REFRESH");
24452 self.write("=");
24453 self.generate_expression(&e.this)?;
24454 Ok(())
24455 }
24456
24457 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
24458 self.write_keyword("BACKUP");
24460 self.write_space();
24461 self.generate_expression(&e.this)?;
24462 Ok(())
24463 }
24464
24465 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
24466 self.write_keyword("BASE64_DECODE_BINARY");
24468 self.write("(");
24469 self.generate_expression(&e.this)?;
24470 if let Some(alphabet) = &e.alphabet {
24471 self.write(", ");
24472 self.generate_expression(alphabet)?;
24473 }
24474 self.write(")");
24475 Ok(())
24476 }
24477
24478 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
24479 self.write_keyword("BASE64_DECODE_STRING");
24481 self.write("(");
24482 self.generate_expression(&e.this)?;
24483 if let Some(alphabet) = &e.alphabet {
24484 self.write(", ");
24485 self.generate_expression(alphabet)?;
24486 }
24487 self.write(")");
24488 Ok(())
24489 }
24490
24491 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
24492 self.write_keyword("BASE64_ENCODE");
24494 self.write("(");
24495 self.generate_expression(&e.this)?;
24496 if let Some(max_line_length) = &e.max_line_length {
24497 self.write(", ");
24498 self.generate_expression(max_line_length)?;
24499 }
24500 if let Some(alphabet) = &e.alphabet {
24501 self.write(", ");
24502 self.generate_expression(alphabet)?;
24503 }
24504 self.write(")");
24505 Ok(())
24506 }
24507
24508 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
24509 self.write_keyword("BLOCKCOMPRESSION");
24511 self.write("=");
24512 if let Some(autotemp) = &e.autotemp {
24513 self.write_keyword("AUTOTEMP");
24514 self.write("(");
24515 self.generate_expression(autotemp)?;
24516 self.write(")");
24517 }
24518 if let Some(always) = &e.always {
24519 self.generate_expression(always)?;
24520 }
24521 if let Some(default) = &e.default {
24522 self.generate_expression(default)?;
24523 }
24524 if let Some(manual) = &e.manual {
24525 self.generate_expression(manual)?;
24526 }
24527 if let Some(never) = &e.never {
24528 self.generate_expression(never)?;
24529 }
24530 Ok(())
24531 }
24532
24533 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
24534 self.write("((");
24536 self.generate_expression(&e.this)?;
24537 self.write(") ");
24538 self.write_keyword("AND");
24539 self.write(" (");
24540 self.generate_expression(&e.expression)?;
24541 self.write("))");
24542 Ok(())
24543 }
24544
24545 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
24546 self.write("((");
24548 self.generate_expression(&e.this)?;
24549 self.write(") ");
24550 self.write_keyword("OR");
24551 self.write(" (");
24552 self.generate_expression(&e.expression)?;
24553 self.write("))");
24554 Ok(())
24555 }
24556
24557 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
24558 self.write_keyword("BUILD");
24560 self.write_space();
24561 self.generate_expression(&e.this)?;
24562 Ok(())
24563 }
24564
24565 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
24566 self.generate_expression(&e.this)?;
24568 Ok(())
24569 }
24570
24571 fn generate_case_specific_column_constraint(
24572 &mut self,
24573 e: &CaseSpecificColumnConstraint,
24574 ) -> Result<()> {
24575 if e.not_.is_some() {
24577 self.write_keyword("NOT");
24578 self.write_space();
24579 }
24580 self.write_keyword("CASESPECIFIC");
24581 Ok(())
24582 }
24583
24584 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
24585 self.write_keyword("CAST");
24587 self.write("(");
24588 self.generate_expression(&e.this)?;
24589 if self.config.dialect == Some(DialectType::ClickHouse) {
24590 self.write(", ");
24592 } else {
24593 self.write_space();
24594 self.write_keyword("AS");
24595 self.write_space();
24596 }
24597 if let Some(to) = &e.to {
24598 self.generate_expression(to)?;
24599 }
24600 self.write(")");
24601 Ok(())
24602 }
24603
24604 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
24605 self.write_keyword("CHANGES");
24608 self.write(" (");
24609 if let Some(information) = &e.information {
24610 self.write_keyword("INFORMATION");
24611 self.write(" => ");
24612 self.generate_expression(information)?;
24613 }
24614 self.write(")");
24615 if let Some(at_before) = &e.at_before {
24617 self.write(" ");
24618 self.generate_expression(at_before)?;
24619 }
24620 if let Some(end) = &e.end {
24621 self.write(" ");
24622 self.generate_expression(end)?;
24623 }
24624 Ok(())
24625 }
24626
24627 fn generate_character_set_column_constraint(
24628 &mut self,
24629 e: &CharacterSetColumnConstraint,
24630 ) -> Result<()> {
24631 self.write_keyword("CHARACTER SET");
24633 self.write_space();
24634 self.generate_expression(&e.this)?;
24635 Ok(())
24636 }
24637
24638 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
24639 if e.default.is_some() {
24641 self.write_keyword("DEFAULT");
24642 self.write_space();
24643 }
24644 self.write_keyword("CHARACTER SET");
24645 self.write("=");
24646 self.generate_expression(&e.this)?;
24647 Ok(())
24648 }
24649
24650 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
24651 self.write_keyword("CHECK");
24653 self.write(" (");
24654 self.generate_expression(&e.this)?;
24655 self.write(")");
24656 if e.enforced.is_some() {
24657 self.write_space();
24658 self.write_keyword("ENFORCED");
24659 }
24660 Ok(())
24661 }
24662
24663 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
24664 self.write_keyword("CHECK_JSON");
24666 self.write("(");
24667 self.generate_expression(&e.this)?;
24668 self.write(")");
24669 Ok(())
24670 }
24671
24672 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
24673 self.write_keyword("CHECK_XML");
24675 self.write("(");
24676 self.generate_expression(&e.this)?;
24677 self.write(")");
24678 Ok(())
24679 }
24680
24681 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
24682 self.write_keyword("CHECKSUM");
24684 self.write("=");
24685 if e.on.is_some() {
24686 self.write_keyword("ON");
24687 } else if e.default.is_some() {
24688 self.write_keyword("DEFAULT");
24689 } else {
24690 self.write_keyword("OFF");
24691 }
24692 Ok(())
24693 }
24694
24695 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
24696 if e.shallow.is_some() {
24698 self.write_keyword("SHALLOW");
24699 self.write_space();
24700 }
24701 if e.copy.is_some() {
24702 self.write_keyword("COPY");
24703 } else {
24704 self.write_keyword("CLONE");
24705 }
24706 self.write_space();
24707 self.generate_expression(&e.this)?;
24708 Ok(())
24709 }
24710
24711 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
24712 self.write_keyword("CLUSTER BY");
24714 self.write(" (");
24715 for (i, ord) in e.expressions.iter().enumerate() {
24716 if i > 0 {
24717 self.write(", ");
24718 }
24719 self.generate_ordered(ord)?;
24720 }
24721 self.write(")");
24722 Ok(())
24723 }
24724
24725 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
24726 self.write_keyword("CLUSTERED BY");
24728 self.write(" (");
24729 for (i, expr) in e.expressions.iter().enumerate() {
24730 if i > 0 {
24731 self.write(", ");
24732 }
24733 self.generate_expression(expr)?;
24734 }
24735 self.write(")");
24736 if let Some(sorted_by) = &e.sorted_by {
24737 self.write_space();
24738 self.write_keyword("SORTED BY");
24739 self.write(" (");
24740 if let Expression::Tuple(t) = sorted_by.as_ref() {
24742 for (i, expr) in t.expressions.iter().enumerate() {
24743 if i > 0 {
24744 self.write(", ");
24745 }
24746 self.generate_expression(expr)?;
24747 }
24748 } else {
24749 self.generate_expression(sorted_by)?;
24750 }
24751 self.write(")");
24752 }
24753 if let Some(buckets) = &e.buckets {
24754 self.write_space();
24755 self.write_keyword("INTO");
24756 self.write_space();
24757 self.generate_expression(buckets)?;
24758 self.write_space();
24759 self.write_keyword("BUCKETS");
24760 }
24761 Ok(())
24762 }
24763
24764 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
24765 if e.default.is_some() {
24769 self.write_keyword("DEFAULT");
24770 self.write_space();
24771 }
24772 self.write_keyword("COLLATE");
24773 match self.config.dialect {
24775 Some(DialectType::BigQuery) => self.write_space(),
24776 _ => self.write("="),
24777 }
24778 self.generate_expression(&e.this)?;
24779 Ok(())
24780 }
24781
24782 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
24783 match e {
24785 ColumnConstraint::NotNull => {
24786 self.write_keyword("NOT NULL");
24787 }
24788 ColumnConstraint::Null => {
24789 self.write_keyword("NULL");
24790 }
24791 ColumnConstraint::Unique => {
24792 self.write_keyword("UNIQUE");
24793 }
24794 ColumnConstraint::PrimaryKey => {
24795 self.write_keyword("PRIMARY KEY");
24796 }
24797 ColumnConstraint::Default(expr) => {
24798 self.write_keyword("DEFAULT");
24799 self.write_space();
24800 self.generate_expression(expr)?;
24801 }
24802 ColumnConstraint::Check(expr) => {
24803 self.write_keyword("CHECK");
24804 self.write(" (");
24805 self.generate_expression(expr)?;
24806 self.write(")");
24807 }
24808 ColumnConstraint::References(fk_ref) => {
24809 if fk_ref.has_foreign_key_keywords {
24810 self.write_keyword("FOREIGN KEY");
24811 self.write_space();
24812 }
24813 self.write_keyword("REFERENCES");
24814 self.write_space();
24815 self.generate_table(&fk_ref.table)?;
24816 if !fk_ref.columns.is_empty() {
24817 self.write(" (");
24818 for (i, col) in fk_ref.columns.iter().enumerate() {
24819 if i > 0 {
24820 self.write(", ");
24821 }
24822 self.generate_identifier(col)?;
24823 }
24824 self.write(")");
24825 }
24826 }
24827 ColumnConstraint::GeneratedAsIdentity(gen) => {
24828 self.write_keyword("GENERATED");
24829 self.write_space();
24830 if gen.always {
24831 self.write_keyword("ALWAYS");
24832 } else {
24833 self.write_keyword("BY DEFAULT");
24834 if gen.on_null {
24835 self.write_space();
24836 self.write_keyword("ON NULL");
24837 }
24838 }
24839 self.write_space();
24840 self.write_keyword("AS IDENTITY");
24841 }
24842 ColumnConstraint::Collate(collation) => {
24843 self.write_keyword("COLLATE");
24844 self.write_space();
24845 self.generate_identifier(collation)?;
24846 }
24847 ColumnConstraint::Comment(comment) => {
24848 self.write_keyword("COMMENT");
24849 self.write(" '");
24850 self.write(comment);
24851 self.write("'");
24852 }
24853 ColumnConstraint::ComputedColumn(cc) => {
24854 self.generate_computed_column_inline(cc)?;
24855 }
24856 ColumnConstraint::GeneratedAsRow(gar) => {
24857 self.generate_generated_as_row_inline(gar)?;
24858 }
24859 ColumnConstraint::Tags(tags) => {
24860 self.write_keyword("TAG");
24861 self.write(" (");
24862 for (i, expr) in tags.expressions.iter().enumerate() {
24863 if i > 0 {
24864 self.write(", ");
24865 }
24866 self.generate_expression(expr)?;
24867 }
24868 self.write(")");
24869 }
24870 ColumnConstraint::Path(path_expr) => {
24871 self.write_keyword("PATH");
24872 self.write_space();
24873 self.generate_expression(path_expr)?;
24874 }
24875 }
24876 Ok(())
24877 }
24878
24879 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
24880 match e {
24882 ColumnPosition::First => {
24883 self.write_keyword("FIRST");
24884 }
24885 ColumnPosition::After(ident) => {
24886 self.write_keyword("AFTER");
24887 self.write_space();
24888 self.generate_identifier(ident)?;
24889 }
24890 }
24891 Ok(())
24892 }
24893
24894 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
24895 self.generate_expression(&e.this)?;
24897 self.write("(");
24898 self.generate_expression(&e.expression)?;
24899 self.write(")");
24900 Ok(())
24901 }
24902
24903 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
24904 if let Some(ref unpack) = e.unpack {
24907 if let Expression::Boolean(b) = unpack.as_ref() {
24908 if b.value {
24909 self.write("*");
24910 }
24911 }
24912 }
24913 self.write_keyword("COLUMNS");
24914 self.write("(");
24915 self.generate_expression(&e.this)?;
24916 self.write(")");
24917 Ok(())
24918 }
24919
24920 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
24921 self.generate_expression(&e.this)?;
24923 self.write("(");
24924 for (i, expr) in e.expressions.iter().enumerate() {
24925 if i > 0 {
24926 self.write(", ");
24927 }
24928 self.generate_expression(expr)?;
24929 }
24930 self.write(")");
24931 Ok(())
24932 }
24933
24934 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
24935 self.generate_expression(&e.this)?;
24937 self.write("(");
24938 for (i, param) in e.params.iter().enumerate() {
24939 if i > 0 {
24940 self.write(", ");
24941 }
24942 self.generate_expression(param)?;
24943 }
24944 self.write(")(");
24945 for (i, expr) in e.expressions.iter().enumerate() {
24946 if i > 0 {
24947 self.write(", ");
24948 }
24949 self.generate_expression(expr)?;
24950 }
24951 self.write(")");
24952 Ok(())
24953 }
24954
24955 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
24956 self.write_keyword("COMMIT");
24958
24959 if e.this.is_none()
24961 && matches!(
24962 self.config.dialect,
24963 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24964 )
24965 {
24966 self.write_space();
24967 self.write_keyword("TRANSACTION");
24968 }
24969
24970 if let Some(this) = &e.this {
24972 let is_transaction_marker = matches!(
24974 this.as_ref(),
24975 Expression::Identifier(id) if id.name == "TRANSACTION"
24976 );
24977
24978 self.write_space();
24979 self.write_keyword("TRANSACTION");
24980
24981 if !is_transaction_marker {
24983 self.write_space();
24984 self.generate_expression(this)?;
24985 }
24986 }
24987
24988 if let Some(durability) = &e.durability {
24990 self.write_space();
24991 self.write_keyword("WITH");
24992 self.write(" (");
24993 self.write_keyword("DELAYED_DURABILITY");
24994 self.write(" = ");
24995 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
24996 self.write_keyword("ON");
24997 } else {
24998 self.write_keyword("OFF");
24999 }
25000 self.write(")");
25001 }
25002
25003 if let Some(chain) = &e.chain {
25005 self.write_space();
25006 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
25007 self.write_keyword("AND NO CHAIN");
25008 } else {
25009 self.write_keyword("AND CHAIN");
25010 }
25011 }
25012 Ok(())
25013 }
25014
25015 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
25016 self.write("[");
25018 self.generate_expression(&e.this)?;
25019 self.write_space();
25020 self.write_keyword("FOR");
25021 self.write_space();
25022 self.generate_expression(&e.expression)?;
25023 if let Some(pos) = &e.position {
25025 self.write(", ");
25026 self.generate_expression(pos)?;
25027 }
25028 if let Some(iterator) = &e.iterator {
25029 self.write_space();
25030 self.write_keyword("IN");
25031 self.write_space();
25032 self.generate_expression(iterator)?;
25033 }
25034 if let Some(condition) = &e.condition {
25035 self.write_space();
25036 self.write_keyword("IF");
25037 self.write_space();
25038 self.generate_expression(condition)?;
25039 }
25040 self.write("]");
25041 Ok(())
25042 }
25043
25044 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
25045 self.write_keyword("COMPRESS");
25047 self.write("(");
25048 self.generate_expression(&e.this)?;
25049 if let Some(method) = &e.method {
25050 self.write(", '");
25051 self.write(method);
25052 self.write("'");
25053 }
25054 self.write(")");
25055 Ok(())
25056 }
25057
25058 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
25059 self.write_keyword("COMPRESS");
25061 if let Some(this) = &e.this {
25062 self.write_space();
25063 self.generate_expression(this)?;
25064 }
25065 Ok(())
25066 }
25067
25068 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
25069 self.write_keyword("AS");
25071 self.write_space();
25072 self.generate_expression(&e.this)?;
25073 if e.not_null.is_some() {
25074 self.write_space();
25075 self.write_keyword("PERSISTED NOT NULL");
25076 } else if e.persisted.is_some() {
25077 self.write_space();
25078 self.write_keyword("PERSISTED");
25079 }
25080 Ok(())
25081 }
25082
25083 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
25087 let computed_expr = if matches!(
25088 self.config.dialect,
25089 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25090 ) {
25091 match &*cc.expression {
25092 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
25093 {
25094 let wrapped = Expression::Cast(Box::new(Cast {
25095 this: y.this.clone(),
25096 to: DataType::Date,
25097 trailing_comments: Vec::new(),
25098 double_colon_syntax: false,
25099 format: None,
25100 default: None,
25101 }));
25102 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
25103 }
25104 Expression::Function(f)
25105 if f.name.eq_ignore_ascii_case("YEAR")
25106 && f.args.len() == 1
25107 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
25108 {
25109 let wrapped = Expression::Cast(Box::new(Cast {
25110 this: f.args[0].clone(),
25111 to: DataType::Date,
25112 trailing_comments: Vec::new(),
25113 double_colon_syntax: false,
25114 format: None,
25115 default: None,
25116 }));
25117 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
25118 }
25119 _ => *cc.expression.clone(),
25120 }
25121 } else {
25122 *cc.expression.clone()
25123 };
25124
25125 match cc.persistence_kind.as_deref() {
25126 Some("STORED") | Some("VIRTUAL") => {
25127 self.write_keyword("GENERATED ALWAYS AS");
25129 self.write(" (");
25130 self.generate_expression(&computed_expr)?;
25131 self.write(")");
25132 self.write_space();
25133 if cc.persisted {
25134 self.write_keyword("STORED");
25135 } else {
25136 self.write_keyword("VIRTUAL");
25137 }
25138 }
25139 Some("PERSISTED") => {
25140 self.write_keyword("AS");
25142 self.write(" (");
25143 self.generate_expression(&computed_expr)?;
25144 self.write(")");
25145 self.write_space();
25146 self.write_keyword("PERSISTED");
25147 if let Some(ref dt) = cc.data_type {
25149 self.write_space();
25150 self.generate_data_type(dt)?;
25151 }
25152 if cc.not_null {
25153 self.write_space();
25154 self.write_keyword("NOT NULL");
25155 }
25156 }
25157 _ => {
25158 if matches!(
25161 self.config.dialect,
25162 Some(DialectType::Spark)
25163 | Some(DialectType::Databricks)
25164 | Some(DialectType::Hive)
25165 ) {
25166 self.write_keyword("GENERATED ALWAYS AS");
25167 self.write(" (");
25168 self.generate_expression(&computed_expr)?;
25169 self.write(")");
25170 } else if matches!(
25171 self.config.dialect,
25172 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25173 ) {
25174 self.write_keyword("AS");
25175 let omit_parens = matches!(computed_expr, Expression::Year(_))
25176 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
25177 if omit_parens {
25178 self.write_space();
25179 self.generate_expression(&computed_expr)?;
25180 } else {
25181 self.write(" (");
25182 self.generate_expression(&computed_expr)?;
25183 self.write(")");
25184 }
25185 } else {
25186 self.write_keyword("AS");
25187 self.write(" (");
25188 self.generate_expression(&computed_expr)?;
25189 self.write(")");
25190 }
25191 }
25192 }
25193 Ok(())
25194 }
25195
25196 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
25199 self.write_keyword("GENERATED ALWAYS AS ROW ");
25200 if gar.start {
25201 self.write_keyword("START");
25202 } else {
25203 self.write_keyword("END");
25204 }
25205 if gar.hidden {
25206 self.write_space();
25207 self.write_keyword("HIDDEN");
25208 }
25209 Ok(())
25210 }
25211
25212 fn generate_system_versioning_content(
25214 &mut self,
25215 e: &WithSystemVersioningProperty,
25216 ) -> Result<()> {
25217 let mut parts = Vec::new();
25218
25219 if let Some(this) = &e.this {
25220 let mut s = String::from("HISTORY_TABLE=");
25221 let mut gen = Generator::new();
25222 gen.config = self.config.clone();
25223 gen.generate_expression(this)?;
25224 s.push_str(&gen.output);
25225 parts.push(s);
25226 }
25227
25228 if let Some(data_consistency) = &e.data_consistency {
25229 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
25230 let mut gen = Generator::new();
25231 gen.config = self.config.clone();
25232 gen.generate_expression(data_consistency)?;
25233 s.push_str(&gen.output);
25234 parts.push(s);
25235 }
25236
25237 if let Some(retention_period) = &e.retention_period {
25238 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
25239 let mut gen = Generator::new();
25240 gen.config = self.config.clone();
25241 gen.generate_expression(retention_period)?;
25242 s.push_str(&gen.output);
25243 parts.push(s);
25244 }
25245
25246 self.write_keyword("SYSTEM_VERSIONING");
25247 self.write("=");
25248
25249 if !parts.is_empty() {
25250 self.write_keyword("ON");
25251 self.write("(");
25252 self.write(&parts.join(", "));
25253 self.write(")");
25254 } else if e.on.is_some() {
25255 self.write_keyword("ON");
25256 } else {
25257 self.write_keyword("OFF");
25258 }
25259
25260 Ok(())
25261 }
25262
25263 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
25264 if e.else_.is_some() {
25267 self.write_keyword("ELSE");
25268 self.write_space();
25269 } else if let Some(expression) = &e.expression {
25270 self.write_keyword("WHEN");
25271 self.write_space();
25272 self.generate_expression(expression)?;
25273 self.write_space();
25274 self.write_keyword("THEN");
25275 self.write_space();
25276 }
25277
25278 if let Expression::Insert(insert) = e.this.as_ref() {
25281 self.write_keyword("INTO");
25282 self.write_space();
25283 self.generate_table(&insert.table)?;
25284
25285 if !insert.columns.is_empty() {
25287 self.write(" (");
25288 for (i, col) in insert.columns.iter().enumerate() {
25289 if i > 0 {
25290 self.write(", ");
25291 }
25292 self.generate_identifier(col)?;
25293 }
25294 self.write(")");
25295 }
25296
25297 if !insert.values.is_empty() {
25299 self.write_space();
25300 self.write_keyword("VALUES");
25301 for (row_idx, row) in insert.values.iter().enumerate() {
25302 if row_idx > 0 {
25303 self.write(", ");
25304 }
25305 self.write(" (");
25306 for (i, val) in row.iter().enumerate() {
25307 if i > 0 {
25308 self.write(", ");
25309 }
25310 self.generate_expression(val)?;
25311 }
25312 self.write(")");
25313 }
25314 }
25315 } else {
25316 self.generate_expression(&e.this)?;
25318 }
25319 Ok(())
25320 }
25321
25322 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
25323 self.write_keyword("CONSTRAINT");
25325 self.write_space();
25326 self.generate_expression(&e.this)?;
25327 if !e.expressions.is_empty() {
25328 self.write_space();
25329 for (i, expr) in e.expressions.iter().enumerate() {
25330 if i > 0 {
25331 self.write_space();
25332 }
25333 self.generate_expression(expr)?;
25334 }
25335 }
25336 Ok(())
25337 }
25338
25339 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
25340 self.write_keyword("CONVERT_TIMEZONE");
25342 self.write("(");
25343 let mut first = true;
25344 if let Some(source_tz) = &e.source_tz {
25345 self.generate_expression(source_tz)?;
25346 first = false;
25347 }
25348 if let Some(target_tz) = &e.target_tz {
25349 if !first {
25350 self.write(", ");
25351 }
25352 self.generate_expression(target_tz)?;
25353 first = false;
25354 }
25355 if let Some(timestamp) = &e.timestamp {
25356 if !first {
25357 self.write(", ");
25358 }
25359 self.generate_expression(timestamp)?;
25360 }
25361 self.write(")");
25362 Ok(())
25363 }
25364
25365 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
25366 self.write_keyword("CONVERT");
25368 self.write("(");
25369 self.generate_expression(&e.this)?;
25370 if let Some(dest) = &e.dest {
25371 self.write_space();
25372 self.write_keyword("USING");
25373 self.write_space();
25374 self.generate_expression(dest)?;
25375 }
25376 self.write(")");
25377 Ok(())
25378 }
25379
25380 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
25381 self.write_keyword("COPY");
25382 if e.is_into {
25383 self.write_space();
25384 self.write_keyword("INTO");
25385 }
25386 self.write_space();
25387
25388 if let Expression::Literal(Literal::String(s)) = &e.this {
25390 if s.starts_with('@') {
25391 self.write(s);
25392 } else {
25393 self.generate_expression(&e.this)?;
25394 }
25395 } else {
25396 self.generate_expression(&e.this)?;
25397 }
25398
25399 if e.kind {
25401 if self.config.pretty {
25403 self.write_newline();
25404 } else {
25405 self.write_space();
25406 }
25407 self.write_keyword("FROM");
25408 self.write_space();
25409 } else if !e.files.is_empty() {
25410 if self.config.pretty {
25412 self.write_newline();
25413 } else {
25414 self.write_space();
25415 }
25416 self.write_keyword("TO");
25417 self.write_space();
25418 }
25419
25420 for (i, file) in e.files.iter().enumerate() {
25422 if i > 0 {
25423 self.write_space();
25424 }
25425 if let Expression::Literal(Literal::String(s)) = file {
25427 if s.starts_with('@') {
25428 self.write(s);
25429 } else {
25430 self.generate_expression(file)?;
25431 }
25432 } else if let Expression::Identifier(id) = file {
25433 if id.quoted {
25435 self.write("`");
25436 self.write(&id.name);
25437 self.write("`");
25438 } else {
25439 self.generate_expression(file)?;
25440 }
25441 } else {
25442 self.generate_expression(file)?;
25443 }
25444 }
25445
25446 if !e.with_wrapped {
25448 if let Some(ref creds) = e.credentials {
25449 if let Some(ref storage) = creds.storage {
25450 if self.config.pretty {
25451 self.write_newline();
25452 } else {
25453 self.write_space();
25454 }
25455 self.write_keyword("STORAGE_INTEGRATION");
25456 self.write(" = ");
25457 self.write(storage);
25458 }
25459 if creds.credentials.is_empty() {
25460 if self.config.pretty {
25462 self.write_newline();
25463 } else {
25464 self.write_space();
25465 }
25466 self.write_keyword("CREDENTIALS");
25467 self.write(" = ()");
25468 } else {
25469 if self.config.pretty {
25470 self.write_newline();
25471 } else {
25472 self.write_space();
25473 }
25474 self.write_keyword("CREDENTIALS");
25475 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
25478 self.write(" '");
25480 self.write(&creds.credentials[0].1);
25481 self.write("'");
25482 } else {
25483 self.write(" = (");
25485 for (i, (k, v)) in creds.credentials.iter().enumerate() {
25486 if i > 0 {
25487 self.write_space();
25488 }
25489 self.write(k);
25490 self.write("='");
25491 self.write(v);
25492 self.write("'");
25493 }
25494 self.write(")");
25495 }
25496 }
25497 if let Some(ref encryption) = creds.encryption {
25498 self.write_space();
25499 self.write_keyword("ENCRYPTION");
25500 self.write(" = ");
25501 self.write(encryption);
25502 }
25503 }
25504 }
25505
25506 if !e.params.is_empty() {
25508 if e.with_wrapped {
25509 self.write_space();
25511 self.write_keyword("WITH");
25512 self.write(" (");
25513 for (i, param) in e.params.iter().enumerate() {
25514 if i > 0 {
25515 self.write(", ");
25516 }
25517 self.generate_copy_param_with_format(param)?;
25518 }
25519 self.write(")");
25520 } else {
25521 for param in &e.params {
25525 if self.config.pretty {
25526 self.write_newline();
25527 } else {
25528 self.write_space();
25529 }
25530 self.write(¶m.name);
25532 if let Some(ref value) = param.value {
25533 if param.eq {
25535 self.write(" = ");
25536 } else {
25537 self.write(" ");
25538 }
25539 if !param.values.is_empty() {
25540 self.write("(");
25541 for (i, v) in param.values.iter().enumerate() {
25542 if i > 0 {
25543 self.write_space();
25544 }
25545 self.generate_copy_nested_param(v)?;
25546 }
25547 self.write(")");
25548 } else {
25549 self.generate_copy_param_value(value)?;
25551 }
25552 } else if !param.values.is_empty() {
25553 if param.eq {
25555 self.write(" = (");
25556 } else {
25557 self.write(" (");
25558 }
25559 let is_key_value_pairs = param
25564 .values
25565 .first()
25566 .map_or(false, |v| matches!(v, Expression::Eq(_)));
25567 let sep = if is_key_value_pairs && param.eq {
25568 " "
25569 } else {
25570 ", "
25571 };
25572 for (i, v) in param.values.iter().enumerate() {
25573 if i > 0 {
25574 self.write(sep);
25575 }
25576 self.generate_copy_nested_param(v)?;
25577 }
25578 self.write(")");
25579 }
25580 }
25581 }
25582 }
25583
25584 Ok(())
25585 }
25586
25587 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
25590 self.write_keyword(¶m.name);
25591 if !param.values.is_empty() {
25592 self.write(" = (");
25594 for (i, v) in param.values.iter().enumerate() {
25595 if i > 0 {
25596 self.write(", ");
25597 }
25598 self.generate_copy_nested_param(v)?;
25599 }
25600 self.write(")");
25601 } else if let Some(ref value) = param.value {
25602 if param.eq {
25603 self.write(" = ");
25604 } else {
25605 self.write(" ");
25606 }
25607 self.generate_expression(value)?;
25608 }
25609 Ok(())
25610 }
25611
25612 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
25614 match expr {
25615 Expression::Eq(eq) => {
25616 match &eq.left {
25618 Expression::Column(c) => self.write(&c.name.name),
25619 _ => self.generate_expression(&eq.left)?,
25620 }
25621 self.write("=");
25622 match &eq.right {
25624 Expression::Literal(Literal::String(s)) => {
25625 self.write("'");
25626 self.write(s);
25627 self.write("'");
25628 }
25629 Expression::Tuple(t) => {
25630 self.write("(");
25632 if self.config.pretty {
25633 self.write_newline();
25634 self.indent_level += 1;
25635 for (i, item) in t.expressions.iter().enumerate() {
25636 if i > 0 {
25637 self.write(", ");
25638 }
25639 self.write_indent();
25640 self.generate_expression(item)?;
25641 }
25642 self.write_newline();
25643 self.indent_level -= 1;
25644 } else {
25645 for (i, item) in t.expressions.iter().enumerate() {
25646 if i > 0 {
25647 self.write(", ");
25648 }
25649 self.generate_expression(item)?;
25650 }
25651 }
25652 self.write(")");
25653 }
25654 _ => self.generate_expression(&eq.right)?,
25655 }
25656 Ok(())
25657 }
25658 Expression::Column(c) => {
25659 self.write(&c.name.name);
25661 Ok(())
25662 }
25663 _ => self.generate_expression(expr),
25664 }
25665 }
25666
25667 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
25670 match expr {
25671 Expression::Column(c) => {
25672 if c.name.quoted {
25674 self.write("\"");
25675 self.write(&c.name.name);
25676 self.write("\"");
25677 } else {
25678 self.write(&c.name.name);
25679 }
25680 Ok(())
25681 }
25682 Expression::Identifier(id) => {
25683 if id.quoted {
25685 self.write("\"");
25686 self.write(&id.name);
25687 self.write("\"");
25688 } else {
25689 self.write(&id.name);
25690 }
25691 Ok(())
25692 }
25693 Expression::Literal(Literal::String(s)) => {
25694 self.write("'");
25696 self.write(s);
25697 self.write("'");
25698 Ok(())
25699 }
25700 _ => self.generate_expression(expr),
25701 }
25702 }
25703
25704 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
25705 self.write_keyword(&e.name);
25706 if let Some(ref value) = e.value {
25707 if e.eq {
25708 self.write(" = ");
25709 } else {
25710 self.write(" ");
25711 }
25712 self.generate_expression(value)?;
25713 }
25714 if !e.values.is_empty() {
25715 if e.eq {
25716 self.write(" = ");
25717 } else {
25718 self.write(" ");
25719 }
25720 self.write("(");
25721 for (i, v) in e.values.iter().enumerate() {
25722 if i > 0 {
25723 self.write(", ");
25724 }
25725 self.generate_expression(v)?;
25726 }
25727 self.write(")");
25728 }
25729 Ok(())
25730 }
25731
25732 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
25733 self.write_keyword("CORR");
25735 self.write("(");
25736 self.generate_expression(&e.this)?;
25737 self.write(", ");
25738 self.generate_expression(&e.expression)?;
25739 self.write(")");
25740 Ok(())
25741 }
25742
25743 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
25744 self.write_keyword("COSINE_DISTANCE");
25746 self.write("(");
25747 self.generate_expression(&e.this)?;
25748 self.write(", ");
25749 self.generate_expression(&e.expression)?;
25750 self.write(")");
25751 Ok(())
25752 }
25753
25754 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
25755 self.write_keyword("COVAR_POP");
25757 self.write("(");
25758 self.generate_expression(&e.this)?;
25759 self.write(", ");
25760 self.generate_expression(&e.expression)?;
25761 self.write(")");
25762 Ok(())
25763 }
25764
25765 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
25766 self.write_keyword("COVAR_SAMP");
25768 self.write("(");
25769 self.generate_expression(&e.this)?;
25770 self.write(", ");
25771 self.generate_expression(&e.expression)?;
25772 self.write(")");
25773 Ok(())
25774 }
25775
25776 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
25777 self.write_keyword("CREDENTIALS");
25779 self.write(" (");
25780 for (i, (key, value)) in e.credentials.iter().enumerate() {
25781 if i > 0 {
25782 self.write(", ");
25783 }
25784 self.write(key);
25785 self.write("='");
25786 self.write(value);
25787 self.write("'");
25788 }
25789 self.write(")");
25790 Ok(())
25791 }
25792
25793 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
25794 self.write_keyword("CREDENTIALS");
25796 self.write("=(");
25797 for (i, expr) in e.expressions.iter().enumerate() {
25798 if i > 0 {
25799 self.write(", ");
25800 }
25801 self.generate_expression(expr)?;
25802 }
25803 self.write(")");
25804 Ok(())
25805 }
25806
25807 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
25808 use crate::dialects::DialectType;
25809
25810 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
25813 self.generate_expression(&e.this)?;
25814 self.write_space();
25815 self.write_keyword("AS");
25816 self.write_space();
25817 self.generate_identifier(&e.alias)?;
25818 return Ok(());
25819 }
25820 self.write(&e.alias.name);
25821
25822 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
25824
25825 if !e.columns.is_empty() && !skip_cte_columns {
25826 self.write("(");
25827 for (i, col) in e.columns.iter().enumerate() {
25828 if i > 0 {
25829 self.write(", ");
25830 }
25831 self.write(&col.name);
25832 }
25833 self.write(")");
25834 }
25835 if !e.key_expressions.is_empty() {
25837 self.write_space();
25838 self.write_keyword("USING KEY");
25839 self.write(" (");
25840 for (i, key) in e.key_expressions.iter().enumerate() {
25841 if i > 0 {
25842 self.write(", ");
25843 }
25844 self.write(&key.name);
25845 }
25846 self.write(")");
25847 }
25848 self.write_space();
25849 self.write_keyword("AS");
25850 self.write_space();
25851 if let Some(materialized) = e.materialized {
25852 if materialized {
25853 self.write_keyword("MATERIALIZED");
25854 } else {
25855 self.write_keyword("NOT MATERIALIZED");
25856 }
25857 self.write_space();
25858 }
25859 self.write("(");
25860 self.generate_expression(&e.this)?;
25861 self.write(")");
25862 Ok(())
25863 }
25864
25865 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
25866 if e.expressions.is_empty() {
25868 self.write_keyword("WITH CUBE");
25869 } else {
25870 self.write_keyword("CUBE");
25871 self.write("(");
25872 for (i, expr) in e.expressions.iter().enumerate() {
25873 if i > 0 {
25874 self.write(", ");
25875 }
25876 self.generate_expression(expr)?;
25877 }
25878 self.write(")");
25879 }
25880 Ok(())
25881 }
25882
25883 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
25884 self.write_keyword("CURRENT_DATETIME");
25886 if let Some(this) = &e.this {
25887 self.write("(");
25888 self.generate_expression(this)?;
25889 self.write(")");
25890 }
25891 Ok(())
25892 }
25893
25894 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
25895 self.write_keyword("CURRENT_SCHEMA");
25897 Ok(())
25898 }
25899
25900 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
25901 self.write_keyword("CURRENT_SCHEMAS");
25903 self.write("(");
25904 if let Some(this) = &e.this {
25905 self.generate_expression(this)?;
25906 }
25907 self.write(")");
25908 Ok(())
25909 }
25910
25911 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
25912 self.write_keyword("CURRENT_USER");
25914 let needs_parens = e.this.is_some()
25916 || matches!(
25917 self.config.dialect,
25918 Some(DialectType::Snowflake)
25919 | Some(DialectType::Spark)
25920 | Some(DialectType::Hive)
25921 | Some(DialectType::DuckDB)
25922 | Some(DialectType::BigQuery)
25923 | Some(DialectType::MySQL)
25924 | Some(DialectType::Databricks)
25925 );
25926 if needs_parens {
25927 self.write("()");
25928 }
25929 Ok(())
25930 }
25931
25932 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
25933 if self.config.dialect == Some(DialectType::Solr) {
25935 self.generate_expression(&e.this)?;
25936 self.write(" ");
25937 self.write_keyword("OR");
25938 self.write(" ");
25939 self.generate_expression(&e.expression)?;
25940 } else {
25941 self.generate_expression(&e.this)?;
25943 self.write(" || ");
25944 self.generate_expression(&e.expression)?;
25945 }
25946 Ok(())
25947 }
25948
25949 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
25950 self.write_keyword("DATABLOCKSIZE");
25952 self.write("=");
25953 if let Some(size) = e.size {
25954 self.write(&size.to_string());
25955 if let Some(units) = &e.units {
25956 self.write_space();
25957 self.generate_expression(units)?;
25958 }
25959 } else if e.minimum.is_some() {
25960 self.write_keyword("MINIMUM");
25961 } else if e.maximum.is_some() {
25962 self.write_keyword("MAXIMUM");
25963 } else if e.default.is_some() {
25964 self.write_keyword("DEFAULT");
25965 }
25966 Ok(())
25967 }
25968
25969 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
25970 self.write_keyword("DATA_DELETION");
25972 self.write("=");
25973
25974 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
25975 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
25976
25977 if is_on {
25978 self.write_keyword("ON");
25979 if has_options {
25980 self.write("(");
25981 let mut first = true;
25982 if let Some(filter_column) = &e.filter_column {
25983 self.write_keyword("FILTER_COLUMN");
25984 self.write("=");
25985 self.generate_expression(filter_column)?;
25986 first = false;
25987 }
25988 if let Some(retention_period) = &e.retention_period {
25989 if !first {
25990 self.write(", ");
25991 }
25992 self.write_keyword("RETENTION_PERIOD");
25993 self.write("=");
25994 self.generate_expression(retention_period)?;
25995 }
25996 self.write(")");
25997 }
25998 } else {
25999 self.write_keyword("OFF");
26000 }
26001 Ok(())
26002 }
26003
26004 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
26008 use crate::dialects::DialectType;
26009 use crate::expressions::Literal;
26010
26011 match self.config.dialect {
26012 Some(DialectType::Exasol) => {
26014 self.write_keyword("TO_DATE");
26015 self.write("(");
26016 match &e.this {
26018 Expression::Literal(Literal::String(s)) => {
26019 self.write("'");
26020 self.write(s);
26021 self.write("'");
26022 }
26023 _ => {
26024 self.generate_expression(&e.this)?;
26025 }
26026 }
26027 self.write(")");
26028 }
26029 _ => {
26031 self.write_keyword("DATE");
26032 self.write("(");
26033 self.generate_expression(&e.this)?;
26034 self.write(")");
26035 }
26036 }
26037 Ok(())
26038 }
26039
26040 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
26041 self.write_keyword("DATE_BIN");
26043 self.write("(");
26044 self.generate_expression(&e.this)?;
26045 self.write(", ");
26046 self.generate_expression(&e.expression)?;
26047 if let Some(origin) = &e.origin {
26048 self.write(", ");
26049 self.generate_expression(origin)?;
26050 }
26051 self.write(")");
26052 Ok(())
26053 }
26054
26055 fn generate_date_format_column_constraint(
26056 &mut self,
26057 e: &DateFormatColumnConstraint,
26058 ) -> Result<()> {
26059 self.write_keyword("FORMAT");
26061 self.write_space();
26062 self.generate_expression(&e.this)?;
26063 Ok(())
26064 }
26065
26066 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
26067 self.write_keyword("DATE_FROM_PARTS");
26069 self.write("(");
26070 let mut first = true;
26071 if let Some(year) = &e.year {
26072 self.generate_expression(year)?;
26073 first = false;
26074 }
26075 if let Some(month) = &e.month {
26076 if !first {
26077 self.write(", ");
26078 }
26079 self.generate_expression(month)?;
26080 first = false;
26081 }
26082 if let Some(day) = &e.day {
26083 if !first {
26084 self.write(", ");
26085 }
26086 self.generate_expression(day)?;
26087 }
26088 self.write(")");
26089 Ok(())
26090 }
26091
26092 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
26093 self.write_keyword("DATETIME");
26095 self.write("(");
26096 self.generate_expression(&e.this)?;
26097 if let Some(expr) = &e.expression {
26098 self.write(", ");
26099 self.generate_expression(expr)?;
26100 }
26101 self.write(")");
26102 Ok(())
26103 }
26104
26105 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
26106 self.write_keyword("DATETIME_ADD");
26108 self.write("(");
26109 self.generate_expression(&e.this)?;
26110 self.write(", ");
26111 self.generate_expression(&e.expression)?;
26112 if let Some(unit) = &e.unit {
26113 self.write(", ");
26114 self.write_keyword(unit);
26115 }
26116 self.write(")");
26117 Ok(())
26118 }
26119
26120 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
26121 self.write_keyword("DATETIME_DIFF");
26123 self.write("(");
26124 self.generate_expression(&e.this)?;
26125 self.write(", ");
26126 self.generate_expression(&e.expression)?;
26127 if let Some(unit) = &e.unit {
26128 self.write(", ");
26129 self.write_keyword(unit);
26130 }
26131 self.write(")");
26132 Ok(())
26133 }
26134
26135 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
26136 self.write_keyword("DATETIME_SUB");
26138 self.write("(");
26139 self.generate_expression(&e.this)?;
26140 self.write(", ");
26141 self.generate_expression(&e.expression)?;
26142 if let Some(unit) = &e.unit {
26143 self.write(", ");
26144 self.write_keyword(unit);
26145 }
26146 self.write(")");
26147 Ok(())
26148 }
26149
26150 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
26151 self.write_keyword("DATETIME_TRUNC");
26153 self.write("(");
26154 self.generate_expression(&e.this)?;
26155 self.write(", ");
26156 self.write_keyword(&e.unit);
26157 if let Some(zone) = &e.zone {
26158 self.write(", ");
26159 self.generate_expression(zone)?;
26160 }
26161 self.write(")");
26162 Ok(())
26163 }
26164
26165 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
26166 self.write_keyword("DAYNAME");
26168 self.write("(");
26169 self.generate_expression(&e.this)?;
26170 self.write(")");
26171 Ok(())
26172 }
26173
26174 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
26175 self.write_keyword("DECLARE");
26177 self.write_space();
26178 for (i, expr) in e.expressions.iter().enumerate() {
26179 if i > 0 {
26180 self.write(", ");
26181 }
26182 self.generate_expression(expr)?;
26183 }
26184 Ok(())
26185 }
26186
26187 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
26188 use crate::dialects::DialectType;
26189
26190 self.generate_expression(&e.this)?;
26192 for name in &e.additional_names {
26194 self.write(", ");
26195 self.generate_expression(name)?;
26196 }
26197 if let Some(kind) = &e.kind {
26198 self.write_space();
26199 match self.config.dialect {
26203 Some(DialectType::BigQuery) => {
26204 self.write(kind);
26205 }
26206 Some(DialectType::TSQL) => {
26207 let is_complex_table = kind.starts_with("TABLE")
26211 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
26212
26213 if is_complex_table {
26214 self.write(kind);
26216 } else {
26217 if !kind.starts_with("CURSOR") {
26219 self.write_keyword("AS");
26220 self.write_space();
26221 }
26222 if kind == "INT" {
26224 self.write("INTEGER");
26225 } else if kind.starts_with("TABLE") {
26226 let normalized = kind
26228 .replace(" INT ", " INTEGER ")
26229 .replace(" INT,", " INTEGER,")
26230 .replace(" INT)", " INTEGER)")
26231 .replace("(INT ", "(INTEGER ");
26232 self.write(&normalized);
26233 } else {
26234 self.write(kind);
26235 }
26236 }
26237 }
26238 _ => {
26239 if e.has_as {
26240 self.write_keyword("AS");
26241 self.write_space();
26242 }
26243 self.write(kind);
26244 }
26245 }
26246 }
26247 if let Some(default) = &e.default {
26248 match self.config.dialect {
26250 Some(DialectType::BigQuery) => {
26251 self.write_space();
26252 self.write_keyword("DEFAULT");
26253 self.write_space();
26254 }
26255 _ => {
26256 self.write(" = ");
26257 }
26258 }
26259 self.generate_expression(default)?;
26260 }
26261 Ok(())
26262 }
26263
26264 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
26265 self.write_keyword("DECODE");
26267 self.write("(");
26268 for (i, expr) in e.expressions.iter().enumerate() {
26269 if i > 0 {
26270 self.write(", ");
26271 }
26272 self.generate_expression(expr)?;
26273 }
26274 self.write(")");
26275 Ok(())
26276 }
26277
26278 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
26279 self.write_keyword("DECOMPRESS");
26281 self.write("(");
26282 self.generate_expression(&e.this)?;
26283 self.write(", '");
26284 self.write(&e.method);
26285 self.write("')");
26286 Ok(())
26287 }
26288
26289 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
26290 self.write_keyword("DECOMPRESS");
26292 self.write("(");
26293 self.generate_expression(&e.this)?;
26294 self.write(", '");
26295 self.write(&e.method);
26296 self.write("')");
26297 Ok(())
26298 }
26299
26300 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
26301 self.write_keyword("DECRYPT");
26303 self.write("(");
26304 self.generate_expression(&e.this)?;
26305 if let Some(passphrase) = &e.passphrase {
26306 self.write(", ");
26307 self.generate_expression(passphrase)?;
26308 }
26309 if let Some(aad) = &e.aad {
26310 self.write(", ");
26311 self.generate_expression(aad)?;
26312 }
26313 if let Some(method) = &e.encryption_method {
26314 self.write(", ");
26315 self.generate_expression(method)?;
26316 }
26317 self.write(")");
26318 Ok(())
26319 }
26320
26321 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
26322 self.write_keyword("DECRYPT_RAW");
26324 self.write("(");
26325 self.generate_expression(&e.this)?;
26326 if let Some(key) = &e.key {
26327 self.write(", ");
26328 self.generate_expression(key)?;
26329 }
26330 if let Some(iv) = &e.iv {
26331 self.write(", ");
26332 self.generate_expression(iv)?;
26333 }
26334 if let Some(aad) = &e.aad {
26335 self.write(", ");
26336 self.generate_expression(aad)?;
26337 }
26338 if let Some(method) = &e.encryption_method {
26339 self.write(", ");
26340 self.generate_expression(method)?;
26341 }
26342 self.write(")");
26343 Ok(())
26344 }
26345
26346 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
26347 self.write_keyword("DEFINER");
26349 self.write(" = ");
26350 self.generate_expression(&e.this)?;
26351 Ok(())
26352 }
26353
26354 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
26355 self.write_keyword("DETACH");
26357 if e.exists {
26358 self.write_keyword(" DATABASE IF EXISTS");
26359 }
26360 self.write_space();
26361 self.generate_expression(&e.this)?;
26362 Ok(())
26363 }
26364
26365 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
26366 let property_name = match e.this.as_ref() {
26367 Expression::Identifier(id) => id.name.as_str(),
26368 Expression::Var(v) => v.this.as_str(),
26369 _ => "DICTIONARY",
26370 };
26371 self.write_keyword(property_name);
26372 self.write("(");
26373 self.write(&e.kind);
26374 if let Some(settings) = &e.settings {
26375 self.write("(");
26376 if let Expression::Tuple(t) = settings.as_ref() {
26377 if self.config.pretty && !t.expressions.is_empty() {
26378 self.write_newline();
26379 self.indent_level += 1;
26380 for (i, pair) in t.expressions.iter().enumerate() {
26381 if i > 0 {
26382 self.write(",");
26383 self.write_newline();
26384 }
26385 self.write_indent();
26386 if let Expression::Tuple(pair_tuple) = pair {
26387 if let Some(k) = pair_tuple.expressions.first() {
26388 self.generate_expression(k)?;
26389 }
26390 if let Some(v) = pair_tuple.expressions.get(1) {
26391 self.write(" ");
26392 self.generate_expression(v)?;
26393 }
26394 } else {
26395 self.generate_expression(pair)?;
26396 }
26397 }
26398 self.indent_level -= 1;
26399 self.write_newline();
26400 self.write_indent();
26401 } else {
26402 for (i, pair) in t.expressions.iter().enumerate() {
26403 if i > 0 {
26404 self.write(", ");
26405 }
26406 if let Expression::Tuple(pair_tuple) = pair {
26407 if let Some(k) = pair_tuple.expressions.first() {
26408 self.generate_expression(k)?;
26409 }
26410 if let Some(v) = pair_tuple.expressions.get(1) {
26411 self.write(" ");
26412 self.generate_expression(v)?;
26413 }
26414 } else {
26415 self.generate_expression(pair)?;
26416 }
26417 }
26418 }
26419 } else {
26420 self.generate_expression(settings)?;
26421 }
26422 self.write(")");
26423 } else if property_name.eq_ignore_ascii_case("LAYOUT") {
26424 self.write("()");
26425 }
26426 self.write(")");
26427 Ok(())
26428 }
26429
26430 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
26431 let property_name = match e.this.as_ref() {
26432 Expression::Identifier(id) => id.name.as_str(),
26433 Expression::Var(v) => v.this.as_str(),
26434 _ => "RANGE",
26435 };
26436 self.write_keyword(property_name);
26437 self.write("(");
26438 if let Some(min) = &e.min {
26439 self.write_keyword("MIN");
26440 self.write_space();
26441 self.generate_expression(min)?;
26442 }
26443 if let Some(max) = &e.max {
26444 self.write_space();
26445 self.write_keyword("MAX");
26446 self.write_space();
26447 self.generate_expression(max)?;
26448 }
26449 self.write(")");
26450 Ok(())
26451 }
26452
26453 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
26454 if e.local.is_some() {
26456 self.write_keyword("LOCAL ");
26457 }
26458 self.write_keyword("DIRECTORY");
26459 self.write_space();
26460 self.generate_expression(&e.this)?;
26461 if let Some(row_format) = &e.row_format {
26462 self.write_space();
26463 self.generate_expression(row_format)?;
26464 }
26465 Ok(())
26466 }
26467
26468 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
26469 self.write_keyword("DISTKEY");
26471 self.write("(");
26472 self.generate_expression(&e.this)?;
26473 self.write(")");
26474 Ok(())
26475 }
26476
26477 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
26478 self.write_keyword("DISTSTYLE");
26480 self.write_space();
26481 self.generate_expression(&e.this)?;
26482 Ok(())
26483 }
26484
26485 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
26486 self.write_keyword("DISTRIBUTE BY");
26488 self.write_space();
26489 for (i, expr) in e.expressions.iter().enumerate() {
26490 if i > 0 {
26491 self.write(", ");
26492 }
26493 self.generate_expression(expr)?;
26494 }
26495 Ok(())
26496 }
26497
26498 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
26499 self.write_keyword("DISTRIBUTED BY");
26501 self.write_space();
26502 self.write(&e.kind);
26503 if !e.expressions.is_empty() {
26504 self.write(" (");
26505 for (i, expr) in e.expressions.iter().enumerate() {
26506 if i > 0 {
26507 self.write(", ");
26508 }
26509 self.generate_expression(expr)?;
26510 }
26511 self.write(")");
26512 }
26513 if let Some(buckets) = &e.buckets {
26514 self.write_space();
26515 self.write_keyword("BUCKETS");
26516 self.write_space();
26517 self.generate_expression(buckets)?;
26518 }
26519 if let Some(order) = &e.order {
26520 self.write_space();
26521 self.generate_expression(order)?;
26522 }
26523 Ok(())
26524 }
26525
26526 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
26527 self.write_keyword("DOT_PRODUCT");
26529 self.write("(");
26530 self.generate_expression(&e.this)?;
26531 self.write(", ");
26532 self.generate_expression(&e.expression)?;
26533 self.write(")");
26534 Ok(())
26535 }
26536
26537 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
26538 self.write_keyword("DROP");
26540 if e.exists {
26541 self.write_keyword(" IF EXISTS ");
26542 } else {
26543 self.write_space();
26544 }
26545 for (i, expr) in e.expressions.iter().enumerate() {
26546 if i > 0 {
26547 self.write(", ");
26548 }
26549 self.generate_expression(expr)?;
26550 }
26551 Ok(())
26552 }
26553
26554 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
26555 self.write_keyword("DUPLICATE KEY");
26557 self.write(" (");
26558 for (i, expr) in e.expressions.iter().enumerate() {
26559 if i > 0 {
26560 self.write(", ");
26561 }
26562 self.generate_expression(expr)?;
26563 }
26564 self.write(")");
26565 Ok(())
26566 }
26567
26568 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
26569 self.write_keyword("ELT");
26571 self.write("(");
26572 self.generate_expression(&e.this)?;
26573 for expr in &e.expressions {
26574 self.write(", ");
26575 self.generate_expression(expr)?;
26576 }
26577 self.write(")");
26578 Ok(())
26579 }
26580
26581 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
26582 self.write_keyword("ENCODE");
26584 self.write("(");
26585 self.generate_expression(&e.this)?;
26586 if let Some(charset) = &e.charset {
26587 self.write(", ");
26588 self.generate_expression(charset)?;
26589 }
26590 self.write(")");
26591 Ok(())
26592 }
26593
26594 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
26595 if e.key.is_some() {
26597 self.write_keyword("KEY ");
26598 }
26599 self.write_keyword("ENCODE");
26600 self.write_space();
26601 self.generate_expression(&e.this)?;
26602 if !e.properties.is_empty() {
26603 self.write(" (");
26604 for (i, prop) in e.properties.iter().enumerate() {
26605 if i > 0 {
26606 self.write(", ");
26607 }
26608 self.generate_expression(prop)?;
26609 }
26610 self.write(")");
26611 }
26612 Ok(())
26613 }
26614
26615 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
26616 self.write_keyword("ENCRYPT");
26618 self.write("(");
26619 self.generate_expression(&e.this)?;
26620 if let Some(passphrase) = &e.passphrase {
26621 self.write(", ");
26622 self.generate_expression(passphrase)?;
26623 }
26624 if let Some(aad) = &e.aad {
26625 self.write(", ");
26626 self.generate_expression(aad)?;
26627 }
26628 if let Some(method) = &e.encryption_method {
26629 self.write(", ");
26630 self.generate_expression(method)?;
26631 }
26632 self.write(")");
26633 Ok(())
26634 }
26635
26636 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
26637 self.write_keyword("ENCRYPT_RAW");
26639 self.write("(");
26640 self.generate_expression(&e.this)?;
26641 if let Some(key) = &e.key {
26642 self.write(", ");
26643 self.generate_expression(key)?;
26644 }
26645 if let Some(iv) = &e.iv {
26646 self.write(", ");
26647 self.generate_expression(iv)?;
26648 }
26649 if let Some(aad) = &e.aad {
26650 self.write(", ");
26651 self.generate_expression(aad)?;
26652 }
26653 if let Some(method) = &e.encryption_method {
26654 self.write(", ");
26655 self.generate_expression(method)?;
26656 }
26657 self.write(")");
26658 Ok(())
26659 }
26660
26661 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
26662 self.write_keyword("ENGINE");
26664 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
26665 self.write("=");
26666 } else {
26667 self.write(" = ");
26668 }
26669 self.generate_expression(&e.this)?;
26670 Ok(())
26671 }
26672
26673 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
26674 self.write_keyword("ENVIRONMENT");
26676 self.write(" (");
26677 for (i, expr) in e.expressions.iter().enumerate() {
26678 if i > 0 {
26679 self.write(", ");
26680 }
26681 self.generate_expression(expr)?;
26682 }
26683 self.write(")");
26684 Ok(())
26685 }
26686
26687 fn generate_ephemeral_column_constraint(
26688 &mut self,
26689 e: &EphemeralColumnConstraint,
26690 ) -> Result<()> {
26691 self.write_keyword("EPHEMERAL");
26693 if let Some(this) = &e.this {
26694 self.write_space();
26695 self.generate_expression(this)?;
26696 }
26697 Ok(())
26698 }
26699
26700 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
26701 self.write_keyword("EQUAL_NULL");
26703 self.write("(");
26704 self.generate_expression(&e.this)?;
26705 self.write(", ");
26706 self.generate_expression(&e.expression)?;
26707 self.write(")");
26708 Ok(())
26709 }
26710
26711 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
26712 use crate::dialects::DialectType;
26713
26714 match self.config.dialect {
26716 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
26717 self.generate_expression(&e.this)?;
26718 self.write(" <-> ");
26719 self.generate_expression(&e.expression)?;
26720 }
26721 _ => {
26722 self.write_keyword("EUCLIDEAN_DISTANCE");
26724 self.write("(");
26725 self.generate_expression(&e.this)?;
26726 self.write(", ");
26727 self.generate_expression(&e.expression)?;
26728 self.write(")");
26729 }
26730 }
26731 Ok(())
26732 }
26733
26734 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
26735 self.write_keyword("EXECUTE AS");
26737 self.write_space();
26738 self.generate_expression(&e.this)?;
26739 Ok(())
26740 }
26741
26742 fn generate_export(&mut self, e: &Export) -> Result<()> {
26743 self.write_keyword("EXPORT DATA");
26745 if let Some(connection) = &e.connection {
26746 self.write_space();
26747 self.write_keyword("WITH CONNECTION");
26748 self.write_space();
26749 self.generate_expression(connection)?;
26750 }
26751 if !e.options.is_empty() {
26752 self.write_space();
26753 self.generate_options_clause(&e.options)?;
26754 }
26755 self.write_space();
26756 self.write_keyword("AS");
26757 self.write_space();
26758 self.generate_expression(&e.this)?;
26759 Ok(())
26760 }
26761
26762 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
26763 self.write_keyword("EXTERNAL");
26765 if let Some(this) = &e.this {
26766 self.write_space();
26767 self.generate_expression(this)?;
26768 }
26769 Ok(())
26770 }
26771
26772 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
26773 if e.no.is_some() {
26775 self.write_keyword("NO ");
26776 }
26777 self.write_keyword("FALLBACK");
26778 if e.protection.is_some() {
26779 self.write_keyword(" PROTECTION");
26780 }
26781 Ok(())
26782 }
26783
26784 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
26785 self.write_keyword("FARM_FINGERPRINT");
26787 self.write("(");
26788 for (i, expr) in e.expressions.iter().enumerate() {
26789 if i > 0 {
26790 self.write(", ");
26791 }
26792 self.generate_expression(expr)?;
26793 }
26794 self.write(")");
26795 Ok(())
26796 }
26797
26798 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
26799 self.write_keyword("FEATURES_AT_TIME");
26801 self.write("(");
26802 self.generate_expression(&e.this)?;
26803 if let Some(time) = &e.time {
26804 self.write(", ");
26805 self.generate_expression(time)?;
26806 }
26807 if let Some(num_rows) = &e.num_rows {
26808 self.write(", ");
26809 self.generate_expression(num_rows)?;
26810 }
26811 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
26812 self.write(", ");
26813 self.generate_expression(ignore_nulls)?;
26814 }
26815 self.write(")");
26816 Ok(())
26817 }
26818
26819 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
26820 let use_limit = !e.percent
26822 && !e.with_ties
26823 && e.count.is_some()
26824 && matches!(
26825 self.config.dialect,
26826 Some(DialectType::Spark)
26827 | Some(DialectType::Hive)
26828 | Some(DialectType::DuckDB)
26829 | Some(DialectType::SQLite)
26830 | Some(DialectType::MySQL)
26831 | Some(DialectType::BigQuery)
26832 | Some(DialectType::Databricks)
26833 | Some(DialectType::StarRocks)
26834 | Some(DialectType::Doris)
26835 | Some(DialectType::Athena)
26836 | Some(DialectType::ClickHouse)
26837 );
26838
26839 if use_limit {
26840 self.write_keyword("LIMIT");
26841 self.write_space();
26842 self.generate_expression(e.count.as_ref().unwrap())?;
26843 return Ok(());
26844 }
26845
26846 self.write_keyword("FETCH");
26848 if !e.direction.is_empty() {
26849 self.write_space();
26850 self.write_keyword(&e.direction);
26851 }
26852 if let Some(count) = &e.count {
26853 self.write_space();
26854 self.generate_expression(count)?;
26855 }
26856 if e.percent {
26858 self.write_keyword(" PERCENT");
26859 }
26860 if e.rows {
26861 self.write_keyword(" ROWS");
26862 }
26863 if e.with_ties {
26864 self.write_keyword(" WITH TIES");
26865 } else if e.rows {
26866 self.write_keyword(" ONLY");
26867 } else {
26868 self.write_keyword(" ROWS ONLY");
26869 }
26870 Ok(())
26871 }
26872
26873 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
26874 if e.hive_format.is_some() {
26878 self.write_keyword("STORED AS");
26880 self.write_space();
26881 if let Some(this) = &e.this {
26882 if let Expression::Identifier(id) = this.as_ref() {
26884 self.write_keyword(&id.name.to_uppercase());
26885 } else {
26886 self.generate_expression(this)?;
26887 }
26888 }
26889 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
26890 self.write_keyword("STORED AS");
26892 self.write_space();
26893 if let Some(this) = &e.this {
26894 if let Expression::Identifier(id) = this.as_ref() {
26895 self.write_keyword(&id.name.to_uppercase());
26896 } else {
26897 self.generate_expression(this)?;
26898 }
26899 }
26900 } else if matches!(
26901 self.config.dialect,
26902 Some(DialectType::Spark) | Some(DialectType::Databricks)
26903 ) {
26904 self.write_keyword("USING");
26906 self.write_space();
26907 if let Some(this) = &e.this {
26908 self.generate_expression(this)?;
26909 }
26910 } else {
26911 self.write_keyword("FILE_FORMAT");
26913 self.write(" = ");
26914 if let Some(this) = &e.this {
26915 self.generate_expression(this)?;
26916 } else if !e.expressions.is_empty() {
26917 self.write("(");
26918 for (i, expr) in e.expressions.iter().enumerate() {
26919 if i > 0 {
26920 self.write(", ");
26921 }
26922 self.generate_expression(expr)?;
26923 }
26924 self.write(")");
26925 }
26926 }
26927 Ok(())
26928 }
26929
26930 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
26931 self.generate_expression(&e.this)?;
26933 self.write_space();
26934 self.write_keyword("FILTER");
26935 self.write("(");
26936 self.write_keyword("WHERE");
26937 self.write_space();
26938 self.generate_expression(&e.expression)?;
26939 self.write(")");
26940 Ok(())
26941 }
26942
26943 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
26944 self.write_keyword("FLOAT64");
26946 self.write("(");
26947 self.generate_expression(&e.this)?;
26948 if let Some(expr) = &e.expression {
26949 self.write(", ");
26950 self.generate_expression(expr)?;
26951 }
26952 self.write(")");
26953 Ok(())
26954 }
26955
26956 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
26957 self.write_keyword("FOR");
26959 self.write_space();
26960 self.generate_expression(&e.this)?;
26961 self.write_space();
26962 self.write_keyword("DO");
26963 self.write_space();
26964 self.generate_expression(&e.expression)?;
26965 Ok(())
26966 }
26967
26968 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
26969 self.write_keyword("FOREIGN KEY");
26971 if !e.expressions.is_empty() {
26972 self.write(" (");
26973 for (i, expr) in e.expressions.iter().enumerate() {
26974 if i > 0 {
26975 self.write(", ");
26976 }
26977 self.generate_expression(expr)?;
26978 }
26979 self.write(")");
26980 }
26981 if let Some(reference) = &e.reference {
26982 self.write_space();
26983 self.generate_expression(reference)?;
26984 }
26985 if let Some(delete) = &e.delete {
26986 self.write_space();
26987 self.write_keyword("ON DELETE");
26988 self.write_space();
26989 self.generate_expression(delete)?;
26990 }
26991 if let Some(update) = &e.update {
26992 self.write_space();
26993 self.write_keyword("ON UPDATE");
26994 self.write_space();
26995 self.generate_expression(update)?;
26996 }
26997 if !e.options.is_empty() {
26998 self.write_space();
26999 for (i, opt) in e.options.iter().enumerate() {
27000 if i > 0 {
27001 self.write_space();
27002 }
27003 self.generate_expression(opt)?;
27004 }
27005 }
27006 Ok(())
27007 }
27008
27009 fn generate_format(&mut self, e: &Format) -> Result<()> {
27010 self.write_keyword("FORMAT");
27012 self.write("(");
27013 self.generate_expression(&e.this)?;
27014 for expr in &e.expressions {
27015 self.write(", ");
27016 self.generate_expression(expr)?;
27017 }
27018 self.write(")");
27019 Ok(())
27020 }
27021
27022 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
27023 self.generate_expression(&e.this)?;
27025 self.write(" (");
27026 self.write_keyword("FORMAT");
27027 self.write(" '");
27028 self.write(&e.format);
27029 self.write("')");
27030 Ok(())
27031 }
27032
27033 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
27034 self.write_keyword("FREESPACE");
27036 self.write("=");
27037 self.generate_expression(&e.this)?;
27038 if e.percent.is_some() {
27039 self.write_keyword(" PERCENT");
27040 }
27041 Ok(())
27042 }
27043
27044 fn generate_from(&mut self, e: &From) -> Result<()> {
27045 self.write_keyword("FROM");
27047 self.write_space();
27048
27049 use crate::dialects::DialectType;
27053 let has_tablesample = e
27054 .expressions
27055 .iter()
27056 .any(|expr| matches!(expr, Expression::TableSample(_)));
27057 let is_cross_join_dialect = matches!(
27058 self.config.dialect,
27059 Some(DialectType::BigQuery)
27060 | Some(DialectType::Hive)
27061 | Some(DialectType::Spark)
27062 | Some(DialectType::Databricks)
27063 | Some(DialectType::SQLite)
27064 | Some(DialectType::ClickHouse)
27065 );
27066 let source_is_same_as_target2 = self.config.source_dialect.is_some()
27067 && self.config.source_dialect == self.config.dialect;
27068 let source_is_cross_join_dialect2 = matches!(
27069 self.config.source_dialect,
27070 Some(DialectType::BigQuery)
27071 | Some(DialectType::Hive)
27072 | Some(DialectType::Spark)
27073 | Some(DialectType::Databricks)
27074 | Some(DialectType::SQLite)
27075 | Some(DialectType::ClickHouse)
27076 );
27077 let use_cross_join = !has_tablesample
27078 && is_cross_join_dialect
27079 && (source_is_same_as_target2
27080 || source_is_cross_join_dialect2
27081 || self.config.source_dialect.is_none());
27082
27083 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
27085
27086 for (i, expr) in e.expressions.iter().enumerate() {
27087 if i > 0 {
27088 if use_cross_join {
27089 self.write(" CROSS JOIN ");
27090 } else {
27091 self.write(", ");
27092 }
27093 }
27094 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
27095 self.write("(");
27096 self.generate_expression(expr)?;
27097 self.write(")");
27098 } else {
27099 self.generate_expression(expr)?;
27100 }
27101 }
27102 Ok(())
27103 }
27104
27105 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
27106 self.write_keyword("FROM_BASE");
27108 self.write("(");
27109 self.generate_expression(&e.this)?;
27110 self.write(", ");
27111 self.generate_expression(&e.expression)?;
27112 self.write(")");
27113 Ok(())
27114 }
27115
27116 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
27117 self.generate_expression(&e.this)?;
27119 if let Some(zone) = &e.zone {
27120 self.write_space();
27121 self.write_keyword("AT TIME ZONE");
27122 self.write_space();
27123 self.generate_expression(zone)?;
27124 self.write_space();
27125 self.write_keyword("AT TIME ZONE");
27126 self.write(" 'UTC'");
27127 }
27128 Ok(())
27129 }
27130
27131 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
27132 self.write_keyword("GAP_FILL");
27134 self.write("(");
27135 self.generate_expression(&e.this)?;
27136 if let Some(ts_column) = &e.ts_column {
27137 self.write(", ");
27138 self.generate_expression(ts_column)?;
27139 }
27140 if let Some(bucket_width) = &e.bucket_width {
27141 self.write(", ");
27142 self.generate_expression(bucket_width)?;
27143 }
27144 if let Some(partitioning_columns) = &e.partitioning_columns {
27145 self.write(", ");
27146 self.generate_expression(partitioning_columns)?;
27147 }
27148 if let Some(value_columns) = &e.value_columns {
27149 self.write(", ");
27150 self.generate_expression(value_columns)?;
27151 }
27152 self.write(")");
27153 Ok(())
27154 }
27155
27156 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
27157 self.write_keyword("GENERATE_DATE_ARRAY");
27159 self.write("(");
27160 let mut first = true;
27161 if let Some(start) = &e.start {
27162 self.generate_expression(start)?;
27163 first = false;
27164 }
27165 if let Some(end) = &e.end {
27166 if !first {
27167 self.write(", ");
27168 }
27169 self.generate_expression(end)?;
27170 first = false;
27171 }
27172 if let Some(step) = &e.step {
27173 if !first {
27174 self.write(", ");
27175 }
27176 self.generate_expression(step)?;
27177 }
27178 self.write(")");
27179 Ok(())
27180 }
27181
27182 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
27183 self.write_keyword("ML.GENERATE_EMBEDDING");
27185 self.write("(");
27186 self.generate_expression(&e.this)?;
27187 self.write(", ");
27188 self.generate_expression(&e.expression)?;
27189 if let Some(params) = &e.params_struct {
27190 self.write(", ");
27191 self.generate_expression(params)?;
27192 }
27193 self.write(")");
27194 Ok(())
27195 }
27196
27197 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
27198 let fn_name = match self.config.dialect {
27200 Some(DialectType::Presto)
27201 | Some(DialectType::Trino)
27202 | Some(DialectType::Athena)
27203 | Some(DialectType::Spark)
27204 | Some(DialectType::Databricks)
27205 | Some(DialectType::Hive) => "SEQUENCE",
27206 _ => "GENERATE_SERIES",
27207 };
27208 self.write_keyword(fn_name);
27209 self.write("(");
27210 let mut first = true;
27211 if let Some(start) = &e.start {
27212 self.generate_expression(start)?;
27213 first = false;
27214 }
27215 if let Some(end) = &e.end {
27216 if !first {
27217 self.write(", ");
27218 }
27219 self.generate_expression(end)?;
27220 first = false;
27221 }
27222 if let Some(step) = &e.step {
27223 if !first {
27224 self.write(", ");
27225 }
27226 if matches!(
27229 self.config.dialect,
27230 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
27231 ) {
27232 if let Some(converted) = self.convert_week_interval_to_day(step) {
27233 self.generate_expression(&converted)?;
27234 } else {
27235 self.generate_expression(step)?;
27236 }
27237 } else {
27238 self.generate_expression(step)?;
27239 }
27240 }
27241 self.write(")");
27242 Ok(())
27243 }
27244
27245 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
27248 use crate::expressions::*;
27249 if let Expression::Interval(ref iv) = expr {
27250 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
27252 unit: IntervalUnit::Week,
27253 ..
27254 }) = &iv.unit
27255 {
27256 let count = match &iv.this {
27258 Some(Expression::Literal(Literal::String(s))) => s.clone(),
27259 Some(Expression::Literal(Literal::Number(s))) => s.clone(),
27260 _ => return None,
27261 };
27262 (true, count)
27263 } else if iv.unit.is_none() {
27264 if let Some(Expression::Literal(Literal::String(s))) = &iv.this {
27266 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
27267 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
27268 (true, parts[0].to_string())
27269 } else {
27270 (false, String::new())
27271 }
27272 } else {
27273 (false, String::new())
27274 }
27275 } else {
27276 (false, String::new())
27277 };
27278
27279 if is_week {
27280 let count_expr = Expression::Literal(Literal::Number(count_str));
27282 let day_interval = Expression::Interval(Box::new(Interval {
27283 this: Some(Expression::Literal(Literal::String("7".to_string()))),
27284 unit: Some(IntervalUnitSpec::Simple {
27285 unit: IntervalUnit::Day,
27286 use_plural: false,
27287 }),
27288 }));
27289 let mul = Expression::Mul(Box::new(BinaryOp {
27290 left: count_expr,
27291 right: day_interval,
27292 left_comments: vec![],
27293 operator_comments: vec![],
27294 trailing_comments: vec![],
27295 }));
27296 return Some(Expression::Paren(Box::new(Paren {
27297 this: mul,
27298 trailing_comments: vec![],
27299 })));
27300 }
27301 }
27302 None
27303 }
27304
27305 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
27306 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
27308 self.write("(");
27309 let mut first = true;
27310 if let Some(start) = &e.start {
27311 self.generate_expression(start)?;
27312 first = false;
27313 }
27314 if let Some(end) = &e.end {
27315 if !first {
27316 self.write(", ");
27317 }
27318 self.generate_expression(end)?;
27319 first = false;
27320 }
27321 if let Some(step) = &e.step {
27322 if !first {
27323 self.write(", ");
27324 }
27325 self.generate_expression(step)?;
27326 }
27327 self.write(")");
27328 Ok(())
27329 }
27330
27331 fn generate_generated_as_identity_column_constraint(
27332 &mut self,
27333 e: &GeneratedAsIdentityColumnConstraint,
27334 ) -> Result<()> {
27335 use crate::dialects::DialectType;
27336
27337 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
27339 self.write_keyword("AUTOINCREMENT");
27340 if let Some(start) = &e.start {
27341 self.write_keyword(" START ");
27342 self.generate_expression(start)?;
27343 }
27344 if let Some(increment) = &e.increment {
27345 self.write_keyword(" INCREMENT ");
27346 self.generate_expression(increment)?;
27347 }
27348 return Ok(());
27349 }
27350
27351 self.write_keyword("GENERATED");
27353 if let Some(this) = &e.this {
27354 if let Expression::Boolean(b) = this.as_ref() {
27356 if b.value {
27357 self.write_keyword(" ALWAYS");
27358 } else {
27359 self.write_keyword(" BY DEFAULT");
27360 if e.on_null.is_some() {
27361 self.write_keyword(" ON NULL");
27362 }
27363 }
27364 } else {
27365 self.write_keyword(" ALWAYS");
27366 }
27367 }
27368 self.write_keyword(" AS IDENTITY");
27369 let has_options = e.start.is_some()
27371 || e.increment.is_some()
27372 || e.minvalue.is_some()
27373 || e.maxvalue.is_some();
27374 if has_options {
27375 self.write(" (");
27376 let mut first = true;
27377 if let Some(start) = &e.start {
27378 self.write_keyword("START WITH ");
27379 self.generate_expression(start)?;
27380 first = false;
27381 }
27382 if let Some(increment) = &e.increment {
27383 if !first {
27384 self.write(" ");
27385 }
27386 self.write_keyword("INCREMENT BY ");
27387 self.generate_expression(increment)?;
27388 first = false;
27389 }
27390 if let Some(minvalue) = &e.minvalue {
27391 if !first {
27392 self.write(" ");
27393 }
27394 self.write_keyword("MINVALUE ");
27395 self.generate_expression(minvalue)?;
27396 first = false;
27397 }
27398 if let Some(maxvalue) = &e.maxvalue {
27399 if !first {
27400 self.write(" ");
27401 }
27402 self.write_keyword("MAXVALUE ");
27403 self.generate_expression(maxvalue)?;
27404 }
27405 self.write(")");
27406 }
27407 Ok(())
27408 }
27409
27410 fn generate_generated_as_row_column_constraint(
27411 &mut self,
27412 e: &GeneratedAsRowColumnConstraint,
27413 ) -> Result<()> {
27414 self.write_keyword("GENERATED ALWAYS AS ROW ");
27416 if e.start.is_some() {
27417 self.write_keyword("START");
27418 } else {
27419 self.write_keyword("END");
27420 }
27421 if e.hidden.is_some() {
27422 self.write_keyword(" HIDDEN");
27423 }
27424 Ok(())
27425 }
27426
27427 fn generate_get(&mut self, e: &Get) -> Result<()> {
27428 self.write_keyword("GET");
27430 self.write_space();
27431 self.generate_expression(&e.this)?;
27432 if let Some(target) = &e.target {
27433 self.write_space();
27434 self.generate_expression(target)?;
27435 }
27436 for prop in &e.properties {
27437 self.write_space();
27438 self.generate_expression(prop)?;
27439 }
27440 Ok(())
27441 }
27442
27443 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
27444 self.generate_expression(&e.this)?;
27446 self.write("[");
27447 self.generate_expression(&e.expression)?;
27448 self.write("]");
27449 Ok(())
27450 }
27451
27452 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
27453 self.write_keyword("GETBIT");
27455 self.write("(");
27456 self.generate_expression(&e.this)?;
27457 self.write(", ");
27458 self.generate_expression(&e.expression)?;
27459 self.write(")");
27460 Ok(())
27461 }
27462
27463 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
27464 if e.is_role {
27466 self.write_keyword("ROLE");
27467 self.write_space();
27468 } else if e.is_group {
27469 self.write_keyword("GROUP");
27470 self.write_space();
27471 }
27472 self.write(&e.name.name);
27473 Ok(())
27474 }
27475
27476 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
27477 self.generate_expression(&e.this)?;
27479 if !e.expressions.is_empty() {
27480 self.write("(");
27481 for (i, expr) in e.expressions.iter().enumerate() {
27482 if i > 0 {
27483 self.write(", ");
27484 }
27485 self.generate_expression(expr)?;
27486 }
27487 self.write(")");
27488 }
27489 Ok(())
27490 }
27491
27492 fn generate_group(&mut self, e: &Group) -> Result<()> {
27493 self.write_keyword("GROUP BY");
27495 match e.all {
27497 Some(true) => {
27498 self.write_space();
27499 self.write_keyword("ALL");
27500 }
27501 Some(false) => {
27502 self.write_space();
27503 self.write_keyword("DISTINCT");
27504 }
27505 None => {}
27506 }
27507 if !e.expressions.is_empty() {
27508 self.write_space();
27509 for (i, expr) in e.expressions.iter().enumerate() {
27510 if i > 0 {
27511 self.write(", ");
27512 }
27513 self.generate_expression(expr)?;
27514 }
27515 }
27516 if let Some(cube) = &e.cube {
27518 if !e.expressions.is_empty() {
27519 self.write(", ");
27520 } else {
27521 self.write_space();
27522 }
27523 self.generate_expression(cube)?;
27524 }
27525 if let Some(rollup) = &e.rollup {
27526 if !e.expressions.is_empty() || e.cube.is_some() {
27527 self.write(", ");
27528 } else {
27529 self.write_space();
27530 }
27531 self.generate_expression(rollup)?;
27532 }
27533 if let Some(grouping_sets) = &e.grouping_sets {
27534 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
27535 self.write(", ");
27536 } else {
27537 self.write_space();
27538 }
27539 self.generate_expression(grouping_sets)?;
27540 }
27541 if let Some(totals) = &e.totals {
27542 self.write_space();
27543 self.write_keyword("WITH TOTALS");
27544 self.generate_expression(totals)?;
27545 }
27546 Ok(())
27547 }
27548
27549 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
27550 self.write_keyword("GROUP BY");
27552 match e.all {
27554 Some(true) => {
27555 self.write_space();
27556 self.write_keyword("ALL");
27557 }
27558 Some(false) => {
27559 self.write_space();
27560 self.write_keyword("DISTINCT");
27561 }
27562 None => {}
27563 }
27564
27565 let mut trailing_cube = false;
27568 let mut trailing_rollup = false;
27569 let mut regular_expressions: Vec<&Expression> = Vec::new();
27570
27571 for expr in &e.expressions {
27572 match expr {
27573 Expression::Cube(c) if c.expressions.is_empty() => {
27574 trailing_cube = true;
27575 }
27576 Expression::Rollup(r) if r.expressions.is_empty() => {
27577 trailing_rollup = true;
27578 }
27579 _ => {
27580 regular_expressions.push(expr);
27581 }
27582 }
27583 }
27584
27585 if self.config.pretty {
27587 self.write_newline();
27588 self.indent_level += 1;
27589 for (i, expr) in regular_expressions.iter().enumerate() {
27590 if i > 0 {
27591 self.write(",");
27592 self.write_newline();
27593 }
27594 self.write_indent();
27595 self.generate_expression(expr)?;
27596 }
27597 self.indent_level -= 1;
27598 } else {
27599 self.write_space();
27600 for (i, expr) in regular_expressions.iter().enumerate() {
27601 if i > 0 {
27602 self.write(", ");
27603 }
27604 self.generate_expression(expr)?;
27605 }
27606 }
27607
27608 if trailing_cube {
27610 self.write_space();
27611 self.write_keyword("WITH CUBE");
27612 } else if trailing_rollup {
27613 self.write_space();
27614 self.write_keyword("WITH ROLLUP");
27615 }
27616
27617 if e.totals {
27619 self.write_space();
27620 self.write_keyword("WITH TOTALS");
27621 }
27622
27623 Ok(())
27624 }
27625
27626 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
27627 self.write_keyword("GROUPING");
27629 self.write("(");
27630 for (i, expr) in e.expressions.iter().enumerate() {
27631 if i > 0 {
27632 self.write(", ");
27633 }
27634 self.generate_expression(expr)?;
27635 }
27636 self.write(")");
27637 Ok(())
27638 }
27639
27640 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
27641 self.write_keyword("GROUPING_ID");
27643 self.write("(");
27644 for (i, expr) in e.expressions.iter().enumerate() {
27645 if i > 0 {
27646 self.write(", ");
27647 }
27648 self.generate_expression(expr)?;
27649 }
27650 self.write(")");
27651 Ok(())
27652 }
27653
27654 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
27655 self.write_keyword("GROUPING SETS");
27657 self.write(" (");
27658 for (i, expr) in e.expressions.iter().enumerate() {
27659 if i > 0 {
27660 self.write(", ");
27661 }
27662 self.generate_expression(expr)?;
27663 }
27664 self.write(")");
27665 Ok(())
27666 }
27667
27668 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
27669 self.write_keyword("HASH_AGG");
27671 self.write("(");
27672 self.generate_expression(&e.this)?;
27673 for expr in &e.expressions {
27674 self.write(", ");
27675 self.generate_expression(expr)?;
27676 }
27677 self.write(")");
27678 Ok(())
27679 }
27680
27681 fn generate_having(&mut self, e: &Having) -> Result<()> {
27682 self.write_keyword("HAVING");
27684 self.write_space();
27685 self.generate_expression(&e.this)?;
27686 Ok(())
27687 }
27688
27689 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
27690 self.generate_expression(&e.this)?;
27692 self.write_space();
27693 self.write_keyword("HAVING");
27694 self.write_space();
27695 if e.max.is_some() {
27696 self.write_keyword("MAX");
27697 } else {
27698 self.write_keyword("MIN");
27699 }
27700 self.write_space();
27701 self.generate_expression(&e.expression)?;
27702 Ok(())
27703 }
27704
27705 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
27706 use crate::dialects::DialectType;
27707 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
27709 if let Expression::Literal(Literal::String(ref s)) = *e.this {
27711 return self.generate_string_literal(s);
27712 }
27713 }
27714 if matches!(
27716 self.config.dialect,
27717 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
27718 ) {
27719 self.write("$");
27720 if let Some(tag) = &e.tag {
27721 self.generate_expression(tag)?;
27722 }
27723 self.write("$");
27724 self.generate_expression(&e.this)?;
27725 self.write("$");
27726 if let Some(tag) = &e.tag {
27727 self.generate_expression(tag)?;
27728 }
27729 self.write("$");
27730 return Ok(());
27731 }
27732 self.write("$");
27734 if let Some(tag) = &e.tag {
27735 self.generate_expression(tag)?;
27736 }
27737 self.write("$");
27738 self.generate_expression(&e.this)?;
27739 self.write("$");
27740 if let Some(tag) = &e.tag {
27741 self.generate_expression(tag)?;
27742 }
27743 self.write("$");
27744 Ok(())
27745 }
27746
27747 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
27748 self.write_keyword("HEX_ENCODE");
27750 self.write("(");
27751 self.generate_expression(&e.this)?;
27752 self.write(")");
27753 Ok(())
27754 }
27755
27756 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
27757 match e.this.as_ref() {
27760 Expression::Identifier(id) => self.write(&id.name),
27761 other => self.generate_expression(other)?,
27762 }
27763 self.write(" (");
27764 self.write(&e.kind);
27765 self.write(" => ");
27766 self.generate_expression(&e.expression)?;
27767 self.write(")");
27768 Ok(())
27769 }
27770
27771 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
27772 self.write_keyword("HLL");
27774 self.write("(");
27775 self.generate_expression(&e.this)?;
27776 for expr in &e.expressions {
27777 self.write(", ");
27778 self.generate_expression(expr)?;
27779 }
27780 self.write(")");
27781 Ok(())
27782 }
27783
27784 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
27785 if e.input_.is_some() && e.output.is_some() {
27787 self.write_keyword("IN OUT");
27788 } else if e.input_.is_some() {
27789 self.write_keyword("IN");
27790 } else if e.output.is_some() {
27791 self.write_keyword("OUT");
27792 }
27793 Ok(())
27794 }
27795
27796 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
27797 self.write_keyword("INCLUDE");
27799 self.write_space();
27800 self.generate_expression(&e.this)?;
27801 if let Some(column_def) = &e.column_def {
27802 self.write_space();
27803 self.generate_expression(column_def)?;
27804 }
27805 if let Some(alias) = &e.alias {
27806 self.write_space();
27807 self.write_keyword("AS");
27808 self.write_space();
27809 self.write(alias);
27810 }
27811 Ok(())
27812 }
27813
27814 fn generate_index(&mut self, e: &Index) -> Result<()> {
27815 if e.unique {
27817 self.write_keyword("UNIQUE");
27818 self.write_space();
27819 }
27820 if e.primary.is_some() {
27821 self.write_keyword("PRIMARY");
27822 self.write_space();
27823 }
27824 if e.amp.is_some() {
27825 self.write_keyword("AMP");
27826 self.write_space();
27827 }
27828 if e.table.is_none() {
27829 self.write_keyword("INDEX");
27830 self.write_space();
27831 }
27832 if let Some(name) = &e.this {
27833 self.generate_expression(name)?;
27834 self.write_space();
27835 }
27836 if let Some(table) = &e.table {
27837 self.write_keyword("ON");
27838 self.write_space();
27839 self.generate_expression(table)?;
27840 }
27841 if !e.params.is_empty() {
27842 self.write("(");
27843 for (i, param) in e.params.iter().enumerate() {
27844 if i > 0 {
27845 self.write(", ");
27846 }
27847 self.generate_expression(param)?;
27848 }
27849 self.write(")");
27850 }
27851 Ok(())
27852 }
27853
27854 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
27855 if let Some(kind) = &e.kind {
27857 self.write(kind);
27858 self.write_space();
27859 }
27860 self.write_keyword("INDEX");
27861 if let Some(this) = &e.this {
27862 self.write_space();
27863 self.generate_expression(this)?;
27864 }
27865 if let Some(index_type) = &e.index_type {
27866 self.write_space();
27867 self.write_keyword("USING");
27868 self.write_space();
27869 self.generate_expression(index_type)?;
27870 }
27871 if !e.expressions.is_empty() {
27872 self.write(" (");
27873 for (i, expr) in e.expressions.iter().enumerate() {
27874 if i > 0 {
27875 self.write(", ");
27876 }
27877 self.generate_expression(expr)?;
27878 }
27879 self.write(")");
27880 }
27881 for opt in &e.options {
27882 self.write_space();
27883 self.generate_expression(opt)?;
27884 }
27885 Ok(())
27886 }
27887
27888 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
27889 if let Some(key_block_size) = &e.key_block_size {
27891 self.write_keyword("KEY_BLOCK_SIZE");
27892 self.write(" = ");
27893 self.generate_expression(key_block_size)?;
27894 } else if let Some(using) = &e.using {
27895 self.write_keyword("USING");
27896 self.write_space();
27897 self.generate_expression(using)?;
27898 } else if let Some(parser) = &e.parser {
27899 self.write_keyword("WITH PARSER");
27900 self.write_space();
27901 self.generate_expression(parser)?;
27902 } else if let Some(comment) = &e.comment {
27903 self.write_keyword("COMMENT");
27904 self.write_space();
27905 self.generate_expression(comment)?;
27906 } else if let Some(visible) = &e.visible {
27907 self.generate_expression(visible)?;
27908 } else if let Some(engine_attr) = &e.engine_attr {
27909 self.write_keyword("ENGINE_ATTRIBUTE");
27910 self.write(" = ");
27911 self.generate_expression(engine_attr)?;
27912 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
27913 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
27914 self.write(" = ");
27915 self.generate_expression(secondary_engine_attr)?;
27916 }
27917 Ok(())
27918 }
27919
27920 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
27921 if let Some(using) = &e.using {
27923 self.write_keyword("USING");
27924 self.write_space();
27925 self.generate_expression(using)?;
27926 }
27927 if !e.columns.is_empty() {
27928 self.write("(");
27929 for (i, col) in e.columns.iter().enumerate() {
27930 if i > 0 {
27931 self.write(", ");
27932 }
27933 self.generate_expression(col)?;
27934 }
27935 self.write(")");
27936 }
27937 if let Some(partition_by) = &e.partition_by {
27938 self.write_space();
27939 self.write_keyword("PARTITION BY");
27940 self.write_space();
27941 self.generate_expression(partition_by)?;
27942 }
27943 if let Some(where_) = &e.where_ {
27944 self.write_space();
27945 self.generate_expression(where_)?;
27946 }
27947 if let Some(include) = &e.include {
27948 self.write_space();
27949 self.write_keyword("INCLUDE");
27950 self.write(" (");
27951 self.generate_expression(include)?;
27952 self.write(")");
27953 }
27954 if let Some(with_storage) = &e.with_storage {
27955 self.write_space();
27956 self.write_keyword("WITH");
27957 self.write(" (");
27958 self.generate_expression(with_storage)?;
27959 self.write(")");
27960 }
27961 if let Some(tablespace) = &e.tablespace {
27962 self.write_space();
27963 self.write_keyword("USING INDEX TABLESPACE");
27964 self.write_space();
27965 self.generate_expression(tablespace)?;
27966 }
27967 Ok(())
27968 }
27969
27970 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
27971 if let Expression::Identifier(id) = &*e.this {
27975 self.write_keyword(&id.name);
27976 } else {
27977 self.generate_expression(&e.this)?;
27978 }
27979 self.write_space();
27980 self.write_keyword("INDEX");
27981 if let Some(target) = &e.target {
27982 self.write_space();
27983 self.write_keyword("FOR");
27984 self.write_space();
27985 if let Expression::Identifier(id) = &**target {
27986 self.write_keyword(&id.name);
27987 } else {
27988 self.generate_expression(target)?;
27989 }
27990 }
27991 self.write(" (");
27993 for (i, expr) in e.expressions.iter().enumerate() {
27994 if i > 0 {
27995 self.write(", ");
27996 }
27997 self.generate_expression(expr)?;
27998 }
27999 self.write(")");
28000 Ok(())
28001 }
28002
28003 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
28004 self.write_keyword("INHERITS");
28006 self.write(" (");
28007 for (i, expr) in e.expressions.iter().enumerate() {
28008 if i > 0 {
28009 self.write(", ");
28010 }
28011 self.generate_expression(expr)?;
28012 }
28013 self.write(")");
28014 Ok(())
28015 }
28016
28017 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
28018 self.write_keyword("INPUT");
28020 self.write("(");
28021 self.generate_expression(&e.this)?;
28022 self.write(")");
28023 Ok(())
28024 }
28025
28026 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
28027 if let Some(input_format) = &e.input_format {
28029 self.write_keyword("INPUTFORMAT");
28030 self.write_space();
28031 self.generate_expression(input_format)?;
28032 }
28033 if let Some(output_format) = &e.output_format {
28034 if e.input_format.is_some() {
28035 self.write(" ");
28036 }
28037 self.write_keyword("OUTPUTFORMAT");
28038 self.write_space();
28039 self.generate_expression(output_format)?;
28040 }
28041 Ok(())
28042 }
28043
28044 fn generate_install(&mut self, e: &Install) -> Result<()> {
28045 if e.force.is_some() {
28047 self.write_keyword("FORCE");
28048 self.write_space();
28049 }
28050 self.write_keyword("INSTALL");
28051 self.write_space();
28052 self.generate_expression(&e.this)?;
28053 if let Some(from) = &e.from_ {
28054 self.write_space();
28055 self.write_keyword("FROM");
28056 self.write_space();
28057 self.generate_expression(from)?;
28058 }
28059 Ok(())
28060 }
28061
28062 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
28063 self.write_keyword("INTERVAL");
28065 self.write_space();
28066 self.generate_expression(&e.expression)?;
28068 if let Some(unit) = &e.unit {
28069 self.write_space();
28070 self.write(unit);
28071 }
28072 Ok(())
28073 }
28074
28075 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
28076 self.write(&format!("{:?}", e.this).to_uppercase());
28078 self.write_space();
28079 self.write_keyword("TO");
28080 self.write_space();
28081 self.write(&format!("{:?}", e.expression).to_uppercase());
28082 Ok(())
28083 }
28084
28085 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
28086 self.write_keyword("INTO");
28088 if e.temporary {
28089 self.write_keyword(" TEMPORARY");
28090 }
28091 if e.unlogged.is_some() {
28092 self.write_keyword(" UNLOGGED");
28093 }
28094 if let Some(this) = &e.this {
28095 self.write_space();
28096 self.generate_expression(this)?;
28097 }
28098 if !e.expressions.is_empty() {
28099 self.write(" (");
28100 for (i, expr) in e.expressions.iter().enumerate() {
28101 if i > 0 {
28102 self.write(", ");
28103 }
28104 self.generate_expression(expr)?;
28105 }
28106 self.write(")");
28107 }
28108 Ok(())
28109 }
28110
28111 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
28112 self.generate_expression(&e.this)?;
28114 self.write_space();
28115 self.generate_expression(&e.expression)?;
28116 Ok(())
28117 }
28118
28119 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
28120 self.write_keyword("WITH");
28122 if e.no.is_some() {
28123 self.write_keyword(" NO");
28124 }
28125 if e.concurrent.is_some() {
28126 self.write_keyword(" CONCURRENT");
28127 }
28128 self.write_keyword(" ISOLATED LOADING");
28129 if let Some(target) = &e.target {
28130 self.write_space();
28131 self.generate_expression(target)?;
28132 }
28133 Ok(())
28134 }
28135
28136 fn generate_json(&mut self, e: &JSON) -> Result<()> {
28137 self.write_keyword("JSON");
28139 if let Some(this) = &e.this {
28140 self.write_space();
28141 self.generate_expression(this)?;
28142 }
28143 if let Some(with_) = &e.with_ {
28144 if let Expression::Boolean(b) = with_.as_ref() {
28146 if b.value {
28147 self.write_keyword(" WITH");
28148 } else {
28149 self.write_keyword(" WITHOUT");
28150 }
28151 }
28152 }
28153 if e.unique {
28154 self.write_keyword(" UNIQUE KEYS");
28155 }
28156 Ok(())
28157 }
28158
28159 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
28160 self.write_keyword("JSON_ARRAY");
28162 self.write("(");
28163 for (i, expr) in e.expressions.iter().enumerate() {
28164 if i > 0 {
28165 self.write(", ");
28166 }
28167 self.generate_expression(expr)?;
28168 }
28169 if let Some(null_handling) = &e.null_handling {
28170 self.write_space();
28171 self.generate_expression(null_handling)?;
28172 }
28173 if let Some(return_type) = &e.return_type {
28174 self.write_space();
28175 self.write_keyword("RETURNING");
28176 self.write_space();
28177 self.generate_expression(return_type)?;
28178 }
28179 if e.strict.is_some() {
28180 self.write_space();
28181 self.write_keyword("STRICT");
28182 }
28183 self.write(")");
28184 Ok(())
28185 }
28186
28187 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
28188 self.write_keyword("JSON_ARRAYAGG");
28190 self.write("(");
28191 self.generate_expression(&e.this)?;
28192 if let Some(order) = &e.order {
28193 self.write_space();
28194 if let Expression::OrderBy(ob) = order.as_ref() {
28196 self.write_keyword("ORDER BY");
28197 self.write_space();
28198 for (i, ord) in ob.expressions.iter().enumerate() {
28199 if i > 0 {
28200 self.write(", ");
28201 }
28202 self.generate_ordered(ord)?;
28203 }
28204 } else {
28205 self.generate_expression(order)?;
28207 }
28208 }
28209 if let Some(null_handling) = &e.null_handling {
28210 self.write_space();
28211 self.generate_expression(null_handling)?;
28212 }
28213 if let Some(return_type) = &e.return_type {
28214 self.write_space();
28215 self.write_keyword("RETURNING");
28216 self.write_space();
28217 self.generate_expression(return_type)?;
28218 }
28219 if e.strict.is_some() {
28220 self.write_space();
28221 self.write_keyword("STRICT");
28222 }
28223 self.write(")");
28224 Ok(())
28225 }
28226
28227 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
28228 self.write_keyword("JSON_OBJECTAGG");
28230 self.write("(");
28231 for (i, expr) in e.expressions.iter().enumerate() {
28232 if i > 0 {
28233 self.write(", ");
28234 }
28235 self.generate_expression(expr)?;
28236 }
28237 if let Some(null_handling) = &e.null_handling {
28238 self.write_space();
28239 self.generate_expression(null_handling)?;
28240 }
28241 if let Some(unique_keys) = &e.unique_keys {
28242 self.write_space();
28243 if let Expression::Boolean(b) = unique_keys.as_ref() {
28244 if b.value {
28245 self.write_keyword("WITH UNIQUE KEYS");
28246 } else {
28247 self.write_keyword("WITHOUT UNIQUE KEYS");
28248 }
28249 }
28250 }
28251 if let Some(return_type) = &e.return_type {
28252 self.write_space();
28253 self.write_keyword("RETURNING");
28254 self.write_space();
28255 self.generate_expression(return_type)?;
28256 }
28257 self.write(")");
28258 Ok(())
28259 }
28260
28261 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
28262 self.write_keyword("JSON_ARRAY_APPEND");
28264 self.write("(");
28265 self.generate_expression(&e.this)?;
28266 for expr in &e.expressions {
28267 self.write(", ");
28268 self.generate_expression(expr)?;
28269 }
28270 self.write(")");
28271 Ok(())
28272 }
28273
28274 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
28275 self.write_keyword("JSON_ARRAY_CONTAINS");
28277 self.write("(");
28278 self.generate_expression(&e.this)?;
28279 self.write(", ");
28280 self.generate_expression(&e.expression)?;
28281 self.write(")");
28282 Ok(())
28283 }
28284
28285 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
28286 self.write_keyword("JSON_ARRAY_INSERT");
28288 self.write("(");
28289 self.generate_expression(&e.this)?;
28290 for expr in &e.expressions {
28291 self.write(", ");
28292 self.generate_expression(expr)?;
28293 }
28294 self.write(")");
28295 Ok(())
28296 }
28297
28298 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
28299 self.write_keyword("JSONB_EXISTS");
28301 self.write("(");
28302 self.generate_expression(&e.this)?;
28303 if let Some(path) = &e.path {
28304 self.write(", ");
28305 self.generate_expression(path)?;
28306 }
28307 self.write(")");
28308 Ok(())
28309 }
28310
28311 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
28312 self.write_keyword("JSONB_EXTRACT_SCALAR");
28314 self.write("(");
28315 self.generate_expression(&e.this)?;
28316 self.write(", ");
28317 self.generate_expression(&e.expression)?;
28318 self.write(")");
28319 Ok(())
28320 }
28321
28322 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
28323 self.write_keyword("JSONB_OBJECT_AGG");
28325 self.write("(");
28326 self.generate_expression(&e.this)?;
28327 self.write(", ");
28328 self.generate_expression(&e.expression)?;
28329 self.write(")");
28330 Ok(())
28331 }
28332
28333 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
28334 if let Some(nested_schema) = &e.nested_schema {
28336 self.write_keyword("NESTED");
28337 if let Some(path) = &e.path {
28338 self.write_space();
28339 self.write_keyword("PATH");
28340 self.write_space();
28341 self.generate_expression(path)?;
28342 }
28343 self.write_space();
28344 self.generate_expression(nested_schema)?;
28345 } else {
28346 if let Some(this) = &e.this {
28347 self.generate_expression(this)?;
28348 }
28349 if let Some(kind) = &e.kind {
28350 self.write_space();
28351 self.write(kind);
28352 }
28353 if let Some(path) = &e.path {
28354 self.write_space();
28355 self.write_keyword("PATH");
28356 self.write_space();
28357 self.generate_expression(path)?;
28358 }
28359 if e.ordinality.is_some() {
28360 self.write_keyword(" FOR ORDINALITY");
28361 }
28362 }
28363 Ok(())
28364 }
28365
28366 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
28367 self.write_keyword("JSON_EXISTS");
28369 self.write("(");
28370 self.generate_expression(&e.this)?;
28371 if let Some(path) = &e.path {
28372 self.write(", ");
28373 self.generate_expression(path)?;
28374 }
28375 if let Some(passing) = &e.passing {
28376 self.write_space();
28377 self.write_keyword("PASSING");
28378 self.write_space();
28379 self.generate_expression(passing)?;
28380 }
28381 if let Some(on_condition) = &e.on_condition {
28382 self.write_space();
28383 self.generate_expression(on_condition)?;
28384 }
28385 self.write(")");
28386 Ok(())
28387 }
28388
28389 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
28390 self.generate_expression(&e.this)?;
28391 self.write(".:");
28392 self.generate_data_type(&e.to)?;
28393 Ok(())
28394 }
28395
28396 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
28397 self.write_keyword("JSON_EXTRACT_ARRAY");
28399 self.write("(");
28400 self.generate_expression(&e.this)?;
28401 if let Some(expr) = &e.expression {
28402 self.write(", ");
28403 self.generate_expression(expr)?;
28404 }
28405 self.write(")");
28406 Ok(())
28407 }
28408
28409 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
28410 if let Some(option) = &e.option {
28412 self.generate_expression(option)?;
28413 self.write_space();
28414 }
28415 self.write_keyword("QUOTES");
28416 if e.scalar.is_some() {
28417 self.write_keyword(" SCALAR_ONLY");
28418 }
28419 Ok(())
28420 }
28421
28422 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
28423 self.write_keyword("JSON_EXTRACT_SCALAR");
28425 self.write("(");
28426 self.generate_expression(&e.this)?;
28427 self.write(", ");
28428 self.generate_expression(&e.expression)?;
28429 self.write(")");
28430 Ok(())
28431 }
28432
28433 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
28434 if e.variant_extract.is_some() {
28438 use crate::dialects::DialectType;
28439 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
28440 self.generate_expression(&e.this)?;
28442 self.write(":");
28443 match e.expression.as_ref() {
28446 Expression::Literal(Literal::String(s)) => {
28447 self.write(s);
28448 }
28449 _ => {
28450 self.generate_expression(&e.expression)?;
28452 }
28453 }
28454 } else {
28455 self.write_keyword("GET_PATH");
28457 self.write("(");
28458 self.generate_expression(&e.this)?;
28459 self.write(", ");
28460 self.generate_expression(&e.expression)?;
28461 self.write(")");
28462 }
28463 } else {
28464 self.write_keyword("JSON_EXTRACT");
28465 self.write("(");
28466 self.generate_expression(&e.this)?;
28467 self.write(", ");
28468 self.generate_expression(&e.expression)?;
28469 for expr in &e.expressions {
28470 self.write(", ");
28471 self.generate_expression(expr)?;
28472 }
28473 self.write(")");
28474 }
28475 Ok(())
28476 }
28477
28478 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
28479 if let Some(this) = &e.this {
28482 self.generate_expression(this)?;
28483 self.write_space();
28484 }
28485 self.write_keyword("FORMAT JSON");
28486 Ok(())
28487 }
28488
28489 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
28490 self.generate_expression(&e.this)?;
28492 self.write(": ");
28493 self.generate_expression(&e.expression)?;
28494 Ok(())
28495 }
28496
28497 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
28498 self.write_keyword("JSON_KEYS");
28500 self.write("(");
28501 self.generate_expression(&e.this)?;
28502 if let Some(expr) = &e.expression {
28503 self.write(", ");
28504 self.generate_expression(expr)?;
28505 }
28506 for expr in &e.expressions {
28507 self.write(", ");
28508 self.generate_expression(expr)?;
28509 }
28510 self.write(")");
28511 Ok(())
28512 }
28513
28514 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
28515 self.write_keyword("JSON_KEYS");
28517 self.write("(");
28518 self.generate_expression(&e.this)?;
28519 if let Some(expr) = &e.expression {
28520 self.write(", ");
28521 self.generate_expression(expr)?;
28522 }
28523 self.write(")");
28524 Ok(())
28525 }
28526
28527 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
28528 let mut path_str = String::new();
28531 for expr in &e.expressions {
28532 match expr {
28533 Expression::JSONPathRoot(_) => {
28534 path_str.push('$');
28535 }
28536 Expression::JSONPathKey(k) => {
28537 if let Expression::Literal(crate::expressions::Literal::String(s)) =
28539 k.this.as_ref()
28540 {
28541 path_str.push('.');
28542 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
28544 if needs_quoting {
28545 path_str.push('"');
28546 path_str.push_str(s);
28547 path_str.push('"');
28548 } else {
28549 path_str.push_str(s);
28550 }
28551 }
28552 }
28553 Expression::JSONPathSubscript(s) => {
28554 if let Expression::Literal(crate::expressions::Literal::Number(n)) =
28556 s.this.as_ref()
28557 {
28558 path_str.push('[');
28559 path_str.push_str(n);
28560 path_str.push(']');
28561 }
28562 }
28563 _ => {
28564 let mut temp_gen = Self::with_config(self.config.clone());
28566 temp_gen.generate_expression(expr)?;
28567 path_str.push_str(&temp_gen.output);
28568 }
28569 }
28570 }
28571 self.write("'");
28573 self.write(&path_str);
28574 self.write("'");
28575 Ok(())
28576 }
28577
28578 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
28579 self.write("?(");
28581 self.generate_expression(&e.this)?;
28582 self.write(")");
28583 Ok(())
28584 }
28585
28586 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
28587 self.write(".");
28589 self.generate_expression(&e.this)?;
28590 Ok(())
28591 }
28592
28593 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
28594 self.write("..");
28596 if let Some(this) = &e.this {
28597 self.generate_expression(this)?;
28598 }
28599 Ok(())
28600 }
28601
28602 fn generate_json_path_root(&mut self) -> Result<()> {
28603 self.write("$");
28605 Ok(())
28606 }
28607
28608 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
28609 self.write("(");
28611 self.generate_expression(&e.this)?;
28612 self.write(")");
28613 Ok(())
28614 }
28615
28616 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
28617 self.generate_expression(&e.this)?;
28619 Ok(())
28620 }
28621
28622 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
28623 self.write("[");
28625 if let Some(start) = &e.start {
28626 self.generate_expression(start)?;
28627 }
28628 self.write(":");
28629 if let Some(end) = &e.end {
28630 self.generate_expression(end)?;
28631 }
28632 if let Some(step) = &e.step {
28633 self.write(":");
28634 self.generate_expression(step)?;
28635 }
28636 self.write("]");
28637 Ok(())
28638 }
28639
28640 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
28641 self.write("[");
28643 self.generate_expression(&e.this)?;
28644 self.write("]");
28645 Ok(())
28646 }
28647
28648 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
28649 self.write("[");
28651 for (i, expr) in e.expressions.iter().enumerate() {
28652 if i > 0 {
28653 self.write(", ");
28654 }
28655 self.generate_expression(expr)?;
28656 }
28657 self.write("]");
28658 Ok(())
28659 }
28660
28661 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
28662 self.write_keyword("JSON_REMOVE");
28664 self.write("(");
28665 self.generate_expression(&e.this)?;
28666 for expr in &e.expressions {
28667 self.write(", ");
28668 self.generate_expression(expr)?;
28669 }
28670 self.write(")");
28671 Ok(())
28672 }
28673
28674 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
28675 self.write_keyword("COLUMNS");
28678 self.write("(");
28679
28680 if self.config.pretty && !e.expressions.is_empty() {
28681 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
28683 for expr in &e.expressions {
28684 let mut temp_gen = Generator::with_config(self.config.clone());
28685 temp_gen.generate_expression(expr)?;
28686 expr_strings.push(temp_gen.output);
28687 }
28688
28689 if self.too_wide(&expr_strings) {
28691 self.write_newline();
28693 self.indent_level += 1;
28694 for (i, expr_str) in expr_strings.iter().enumerate() {
28695 if i > 0 {
28696 self.write(",");
28697 self.write_newline();
28698 }
28699 self.write_indent();
28700 self.write(expr_str);
28701 }
28702 self.write_newline();
28703 self.indent_level -= 1;
28704 self.write_indent();
28705 } else {
28706 for (i, expr_str) in expr_strings.iter().enumerate() {
28708 if i > 0 {
28709 self.write(", ");
28710 }
28711 self.write(expr_str);
28712 }
28713 }
28714 } else {
28715 for (i, expr) in e.expressions.iter().enumerate() {
28717 if i > 0 {
28718 self.write(", ");
28719 }
28720 self.generate_expression(expr)?;
28721 }
28722 }
28723 self.write(")");
28724 Ok(())
28725 }
28726
28727 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
28728 self.write_keyword("JSON_SET");
28730 self.write("(");
28731 self.generate_expression(&e.this)?;
28732 for expr in &e.expressions {
28733 self.write(", ");
28734 self.generate_expression(expr)?;
28735 }
28736 self.write(")");
28737 Ok(())
28738 }
28739
28740 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
28741 self.write_keyword("JSON_STRIP_NULLS");
28743 self.write("(");
28744 self.generate_expression(&e.this)?;
28745 if let Some(expr) = &e.expression {
28746 self.write(", ");
28747 self.generate_expression(expr)?;
28748 }
28749 self.write(")");
28750 Ok(())
28751 }
28752
28753 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
28754 self.write_keyword("JSON_TABLE");
28756 self.write("(");
28757 self.generate_expression(&e.this)?;
28758 if let Some(path) = &e.path {
28759 self.write(", ");
28760 self.generate_expression(path)?;
28761 }
28762 if let Some(error_handling) = &e.error_handling {
28763 self.write_space();
28764 self.generate_expression(error_handling)?;
28765 }
28766 if let Some(empty_handling) = &e.empty_handling {
28767 self.write_space();
28768 self.generate_expression(empty_handling)?;
28769 }
28770 if let Some(schema) = &e.schema {
28771 self.write_space();
28772 self.generate_expression(schema)?;
28773 }
28774 self.write(")");
28775 Ok(())
28776 }
28777
28778 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
28779 self.write_keyword("JSON_TYPE");
28781 self.write("(");
28782 self.generate_expression(&e.this)?;
28783 self.write(")");
28784 Ok(())
28785 }
28786
28787 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
28788 self.write_keyword("JSON_VALUE");
28790 self.write("(");
28791 self.generate_expression(&e.this)?;
28792 if let Some(path) = &e.path {
28793 self.write(", ");
28794 self.generate_expression(path)?;
28795 }
28796 if let Some(returning) = &e.returning {
28797 self.write_space();
28798 self.write_keyword("RETURNING");
28799 self.write_space();
28800 self.generate_expression(returning)?;
28801 }
28802 if let Some(on_condition) = &e.on_condition {
28803 self.write_space();
28804 self.generate_expression(on_condition)?;
28805 }
28806 self.write(")");
28807 Ok(())
28808 }
28809
28810 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
28811 self.write_keyword("JSON_VALUE_ARRAY");
28813 self.write("(");
28814 self.generate_expression(&e.this)?;
28815 self.write(")");
28816 Ok(())
28817 }
28818
28819 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
28820 self.write_keyword("JAROWINKLER_SIMILARITY");
28822 self.write("(");
28823 self.generate_expression(&e.this)?;
28824 self.write(", ");
28825 self.generate_expression(&e.expression)?;
28826 self.write(")");
28827 Ok(())
28828 }
28829
28830 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
28831 self.generate_expression(&e.this)?;
28833 self.write("(");
28834 for (i, expr) in e.expressions.iter().enumerate() {
28835 if i > 0 {
28836 self.write(", ");
28837 }
28838 self.generate_expression(expr)?;
28839 }
28840 self.write(")");
28841 Ok(())
28842 }
28843
28844 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
28845 if e.no.is_some() {
28847 self.write_keyword("NO ");
28848 }
28849 if let Some(local) = &e.local {
28850 self.generate_expression(local)?;
28851 self.write_space();
28852 }
28853 if e.dual.is_some() {
28854 self.write_keyword("DUAL ");
28855 }
28856 if e.before.is_some() {
28857 self.write_keyword("BEFORE ");
28858 }
28859 if e.after.is_some() {
28860 self.write_keyword("AFTER ");
28861 }
28862 self.write_keyword("JOURNAL");
28863 Ok(())
28864 }
28865
28866 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
28867 self.write_keyword("LANGUAGE");
28869 self.write_space();
28870 self.generate_expression(&e.this)?;
28871 Ok(())
28872 }
28873
28874 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
28875 if e.view.is_some() {
28877 self.write_keyword("LATERAL VIEW");
28879 if e.outer.is_some() {
28880 self.write_space();
28881 self.write_keyword("OUTER");
28882 }
28883 self.write_space();
28884 self.generate_expression(&e.this)?;
28885 if let Some(alias) = &e.alias {
28886 self.write_space();
28887 self.write(alias);
28888 }
28889 } else {
28890 self.write_keyword("LATERAL");
28892 self.write_space();
28893 self.generate_expression(&e.this)?;
28894 if e.ordinality.is_some() {
28895 self.write_space();
28896 self.write_keyword("WITH ORDINALITY");
28897 }
28898 if let Some(alias) = &e.alias {
28899 self.write_space();
28900 self.write_keyword("AS");
28901 self.write_space();
28902 self.write(alias);
28903 if !e.column_aliases.is_empty() {
28904 self.write("(");
28905 for (i, col) in e.column_aliases.iter().enumerate() {
28906 if i > 0 {
28907 self.write(", ");
28908 }
28909 self.write(col);
28910 }
28911 self.write(")");
28912 }
28913 }
28914 }
28915 Ok(())
28916 }
28917
28918 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
28919 self.write_keyword("LIKE");
28921 self.write_space();
28922 self.generate_expression(&e.this)?;
28923 for expr in &e.expressions {
28924 self.write_space();
28925 self.generate_expression(expr)?;
28926 }
28927 Ok(())
28928 }
28929
28930 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
28931 self.write_keyword("LIMIT");
28932 self.write_space();
28933 self.write_limit_expr(&e.this)?;
28934 if e.percent {
28935 self.write_space();
28936 self.write_keyword("PERCENT");
28937 }
28938 for comment in &e.comments {
28940 self.write(" ");
28941 self.write_formatted_comment(comment);
28942 }
28943 Ok(())
28944 }
28945
28946 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
28947 if e.percent.is_some() {
28949 self.write_keyword(" PERCENT");
28950 }
28951 if e.rows.is_some() {
28952 self.write_keyword(" ROWS");
28953 }
28954 if e.with_ties.is_some() {
28955 self.write_keyword(" WITH TIES");
28956 } else if e.rows.is_some() {
28957 self.write_keyword(" ONLY");
28958 }
28959 Ok(())
28960 }
28961
28962 fn generate_list(&mut self, e: &List) -> Result<()> {
28963 use crate::dialects::DialectType;
28964 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
28965
28966 if e.expressions.len() == 1 {
28968 if let Expression::Select(_) = &e.expressions[0] {
28969 self.write_keyword("LIST");
28970 self.write("(");
28971 self.generate_expression(&e.expressions[0])?;
28972 self.write(")");
28973 return Ok(());
28974 }
28975 }
28976
28977 if is_materialize {
28979 self.write_keyword("LIST");
28980 self.write("[");
28981 for (i, expr) in e.expressions.iter().enumerate() {
28982 if i > 0 {
28983 self.write(", ");
28984 }
28985 self.generate_expression(expr)?;
28986 }
28987 self.write("]");
28988 } else {
28989 self.write_keyword("LIST");
28991 self.write("(");
28992 for (i, expr) in e.expressions.iter().enumerate() {
28993 if i > 0 {
28994 self.write(", ");
28995 }
28996 self.generate_expression(expr)?;
28997 }
28998 self.write(")");
28999 }
29000 Ok(())
29001 }
29002
29003 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
29004 if let Expression::Select(_) = &*e.this {
29006 self.write_keyword("MAP");
29007 self.write("(");
29008 self.generate_expression(&e.this)?;
29009 self.write(")");
29010 return Ok(());
29011 }
29012
29013 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
29014
29015 self.write_keyword("MAP");
29017 if is_duckdb {
29018 self.write(" {");
29019 } else {
29020 self.write("[");
29021 }
29022 if let Expression::Struct(s) = &*e.this {
29023 for (i, (_, expr)) in s.fields.iter().enumerate() {
29024 if i > 0 {
29025 self.write(", ");
29026 }
29027 if let Expression::PropertyEQ(op) = expr {
29028 self.generate_expression(&op.left)?;
29029 if is_duckdb {
29030 self.write(": ");
29031 } else {
29032 self.write(" => ");
29033 }
29034 self.generate_expression(&op.right)?;
29035 } else {
29036 self.generate_expression(expr)?;
29037 }
29038 }
29039 }
29040 if is_duckdb {
29041 self.write("}");
29042 } else {
29043 self.write("]");
29044 }
29045 Ok(())
29046 }
29047
29048 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
29049 self.write_keyword("LOCALTIME");
29051 if let Some(precision) = &e.this {
29052 self.write("(");
29053 self.generate_expression(precision)?;
29054 self.write(")");
29055 }
29056 Ok(())
29057 }
29058
29059 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
29060 self.write_keyword("LOCALTIMESTAMP");
29062 if let Some(precision) = &e.this {
29063 self.write("(");
29064 self.generate_expression(precision)?;
29065 self.write(")");
29066 }
29067 Ok(())
29068 }
29069
29070 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
29071 self.write_keyword("LOCATION");
29073 self.write_space();
29074 self.generate_expression(&e.this)?;
29075 Ok(())
29076 }
29077
29078 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
29079 if e.update.is_some() {
29081 if e.key.is_some() {
29082 self.write_keyword("FOR NO KEY UPDATE");
29083 } else {
29084 self.write_keyword("FOR UPDATE");
29085 }
29086 } else {
29087 if e.key.is_some() {
29088 self.write_keyword("FOR KEY SHARE");
29089 } else {
29090 self.write_keyword("FOR SHARE");
29091 }
29092 }
29093 if !e.expressions.is_empty() {
29094 self.write_keyword(" OF ");
29095 for (i, expr) in e.expressions.iter().enumerate() {
29096 if i > 0 {
29097 self.write(", ");
29098 }
29099 self.generate_expression(expr)?;
29100 }
29101 }
29102 if let Some(wait) = &e.wait {
29107 match wait.as_ref() {
29108 Expression::Boolean(b) => {
29109 if b.value {
29110 self.write_keyword(" NOWAIT");
29111 } else {
29112 self.write_keyword(" SKIP LOCKED");
29113 }
29114 }
29115 _ => {
29116 self.write_keyword(" WAIT ");
29118 self.generate_expression(wait)?;
29119 }
29120 }
29121 }
29122 Ok(())
29123 }
29124
29125 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
29126 self.write_keyword("LOCK");
29128 self.write_space();
29129 self.generate_expression(&e.this)?;
29130 Ok(())
29131 }
29132
29133 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
29134 self.write_keyword("LOCKING");
29136 self.write_space();
29137 self.write(&e.kind);
29138 if let Some(this) = &e.this {
29139 self.write_space();
29140 self.generate_expression(this)?;
29141 }
29142 if let Some(for_or_in) = &e.for_or_in {
29143 self.write_space();
29144 self.generate_expression(for_or_in)?;
29145 }
29146 if let Some(lock_type) = &e.lock_type {
29147 self.write_space();
29148 self.generate_expression(lock_type)?;
29149 }
29150 if e.override_.is_some() {
29151 self.write_keyword(" OVERRIDE");
29152 }
29153 Ok(())
29154 }
29155
29156 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
29157 self.generate_expression(&e.this)?;
29159 self.write_space();
29160 self.generate_expression(&e.expression)?;
29161 Ok(())
29162 }
29163
29164 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
29165 if e.no.is_some() {
29167 self.write_keyword("NO ");
29168 }
29169 self.write_keyword("LOG");
29170 Ok(())
29171 }
29172
29173 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
29174 self.write_keyword("MD5");
29176 self.write("(");
29177 self.generate_expression(&e.this)?;
29178 for expr in &e.expressions {
29179 self.write(", ");
29180 self.generate_expression(expr)?;
29181 }
29182 self.write(")");
29183 Ok(())
29184 }
29185
29186 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
29187 self.write_keyword("ML.FORECAST");
29189 self.write("(");
29190 self.generate_expression(&e.this)?;
29191 if let Some(expression) = &e.expression {
29192 self.write(", ");
29193 self.generate_expression(expression)?;
29194 }
29195 if let Some(params) = &e.params_struct {
29196 self.write(", ");
29197 self.generate_expression(params)?;
29198 }
29199 self.write(")");
29200 Ok(())
29201 }
29202
29203 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
29204 self.write_keyword("ML.TRANSLATE");
29206 self.write("(");
29207 self.generate_expression(&e.this)?;
29208 self.write(", ");
29209 self.generate_expression(&e.expression)?;
29210 if let Some(params) = &e.params_struct {
29211 self.write(", ");
29212 self.generate_expression(params)?;
29213 }
29214 self.write(")");
29215 Ok(())
29216 }
29217
29218 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
29219 self.write_keyword("MAKE_INTERVAL");
29221 self.write("(");
29222 let mut first = true;
29223 if let Some(year) = &e.year {
29224 self.write("years => ");
29225 self.generate_expression(year)?;
29226 first = false;
29227 }
29228 if let Some(month) = &e.month {
29229 if !first {
29230 self.write(", ");
29231 }
29232 self.write("months => ");
29233 self.generate_expression(month)?;
29234 first = false;
29235 }
29236 if let Some(week) = &e.week {
29237 if !first {
29238 self.write(", ");
29239 }
29240 self.write("weeks => ");
29241 self.generate_expression(week)?;
29242 first = false;
29243 }
29244 if let Some(day) = &e.day {
29245 if !first {
29246 self.write(", ");
29247 }
29248 self.write("days => ");
29249 self.generate_expression(day)?;
29250 first = false;
29251 }
29252 if let Some(hour) = &e.hour {
29253 if !first {
29254 self.write(", ");
29255 }
29256 self.write("hours => ");
29257 self.generate_expression(hour)?;
29258 first = false;
29259 }
29260 if let Some(minute) = &e.minute {
29261 if !first {
29262 self.write(", ");
29263 }
29264 self.write("mins => ");
29265 self.generate_expression(minute)?;
29266 first = false;
29267 }
29268 if let Some(second) = &e.second {
29269 if !first {
29270 self.write(", ");
29271 }
29272 self.write("secs => ");
29273 self.generate_expression(second)?;
29274 }
29275 self.write(")");
29276 Ok(())
29277 }
29278
29279 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
29280 self.write_keyword("MANHATTAN_DISTANCE");
29282 self.write("(");
29283 self.generate_expression(&e.this)?;
29284 self.write(", ");
29285 self.generate_expression(&e.expression)?;
29286 self.write(")");
29287 Ok(())
29288 }
29289
29290 fn generate_map(&mut self, e: &Map) -> Result<()> {
29291 self.write_keyword("MAP");
29293 self.write("(");
29294 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
29295 if i > 0 {
29296 self.write(", ");
29297 }
29298 self.generate_expression(key)?;
29299 self.write(", ");
29300 self.generate_expression(value)?;
29301 }
29302 self.write(")");
29303 Ok(())
29304 }
29305
29306 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
29307 self.write_keyword("MAP_CAT");
29309 self.write("(");
29310 self.generate_expression(&e.this)?;
29311 self.write(", ");
29312 self.generate_expression(&e.expression)?;
29313 self.write(")");
29314 Ok(())
29315 }
29316
29317 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
29318 self.write_keyword("MAP_DELETE");
29320 self.write("(");
29321 self.generate_expression(&e.this)?;
29322 for expr in &e.expressions {
29323 self.write(", ");
29324 self.generate_expression(expr)?;
29325 }
29326 self.write(")");
29327 Ok(())
29328 }
29329
29330 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
29331 self.write_keyword("MAP_INSERT");
29333 self.write("(");
29334 self.generate_expression(&e.this)?;
29335 if let Some(key) = &e.key {
29336 self.write(", ");
29337 self.generate_expression(key)?;
29338 }
29339 if let Some(value) = &e.value {
29340 self.write(", ");
29341 self.generate_expression(value)?;
29342 }
29343 if let Some(update_flag) = &e.update_flag {
29344 self.write(", ");
29345 self.generate_expression(update_flag)?;
29346 }
29347 self.write(")");
29348 Ok(())
29349 }
29350
29351 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
29352 self.write_keyword("MAP_PICK");
29354 self.write("(");
29355 self.generate_expression(&e.this)?;
29356 for expr in &e.expressions {
29357 self.write(", ");
29358 self.generate_expression(expr)?;
29359 }
29360 self.write(")");
29361 Ok(())
29362 }
29363
29364 fn generate_masking_policy_column_constraint(
29365 &mut self,
29366 e: &MaskingPolicyColumnConstraint,
29367 ) -> Result<()> {
29368 self.write_keyword("MASKING POLICY");
29370 self.write_space();
29371 self.generate_expression(&e.this)?;
29372 if !e.expressions.is_empty() {
29373 self.write_keyword(" USING");
29374 self.write(" (");
29375 for (i, expr) in e.expressions.iter().enumerate() {
29376 if i > 0 {
29377 self.write(", ");
29378 }
29379 self.generate_expression(expr)?;
29380 }
29381 self.write(")");
29382 }
29383 Ok(())
29384 }
29385
29386 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
29387 if matches!(
29388 self.config.dialect,
29389 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
29390 ) {
29391 if e.expressions.len() > 1 {
29392 self.write("(");
29393 }
29394 for (i, expr) in e.expressions.iter().enumerate() {
29395 if i > 0 {
29396 self.write_keyword(" OR ");
29397 }
29398 self.generate_expression(expr)?;
29399 self.write_space();
29400 self.write("@@");
29401 self.write_space();
29402 self.generate_expression(&e.this)?;
29403 }
29404 if e.expressions.len() > 1 {
29405 self.write(")");
29406 }
29407 return Ok(());
29408 }
29409
29410 self.write_keyword("MATCH");
29412 self.write("(");
29413 for (i, expr) in e.expressions.iter().enumerate() {
29414 if i > 0 {
29415 self.write(", ");
29416 }
29417 self.generate_expression(expr)?;
29418 }
29419 self.write(")");
29420 self.write_keyword(" AGAINST");
29421 self.write("(");
29422 self.generate_expression(&e.this)?;
29423 if let Some(modifier) = &e.modifier {
29424 self.write_space();
29425 self.generate_expression(modifier)?;
29426 }
29427 self.write(")");
29428 Ok(())
29429 }
29430
29431 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
29432 if let Some(window_frame) = &e.window_frame {
29434 self.write(&format!("{:?}", window_frame).to_uppercase());
29435 self.write_space();
29436 }
29437 self.generate_expression(&e.this)?;
29438 Ok(())
29439 }
29440
29441 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
29442 self.write_keyword("MATERIALIZED");
29444 if let Some(this) = &e.this {
29445 self.write_space();
29446 self.generate_expression(this)?;
29447 }
29448 Ok(())
29449 }
29450
29451 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
29452 if let Some(with_) = &e.with_ {
29455 self.generate_expression(with_)?;
29456 self.write_space();
29457 }
29458 self.write_keyword("MERGE INTO");
29459 self.write_space();
29460 self.generate_expression(&e.this)?;
29461
29462 if self.config.pretty {
29464 self.write_newline();
29465 self.write_indent();
29466 } else {
29467 self.write_space();
29468 }
29469 self.write_keyword("USING");
29470 self.write_space();
29471 self.generate_expression(&e.using)?;
29472
29473 if let Some(on) = &e.on {
29475 if self.config.pretty {
29476 self.write_newline();
29477 self.write_indent();
29478 } else {
29479 self.write_space();
29480 }
29481 self.write_keyword("ON");
29482 self.write_space();
29483 self.generate_expression(on)?;
29484 }
29485 if let Some(using_cond) = &e.using_cond {
29487 self.write_space();
29488 self.write_keyword("USING");
29489 self.write_space();
29490 self.write("(");
29491 if let Expression::Tuple(tuple) = using_cond.as_ref() {
29493 for (i, col) in tuple.expressions.iter().enumerate() {
29494 if i > 0 {
29495 self.write(", ");
29496 }
29497 self.generate_expression(col)?;
29498 }
29499 } else {
29500 self.generate_expression(using_cond)?;
29501 }
29502 self.write(")");
29503 }
29504 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
29506 if matches!(
29507 self.config.dialect,
29508 Some(crate::DialectType::PostgreSQL)
29509 | Some(crate::DialectType::Redshift)
29510 | Some(crate::DialectType::Trino)
29511 | Some(crate::DialectType::Presto)
29512 | Some(crate::DialectType::Athena)
29513 ) {
29514 let mut names = Vec::new();
29515 match e.this.as_ref() {
29516 Expression::Alias(a) => {
29517 if let Expression::Table(t) = &a.this {
29519 names.push(t.name.name.clone());
29520 } else if let Expression::Identifier(id) = &a.this {
29521 names.push(id.name.clone());
29522 }
29523 names.push(a.alias.name.clone());
29524 }
29525 Expression::Table(t) => {
29526 names.push(t.name.name.clone());
29527 }
29528 Expression::Identifier(id) => {
29529 names.push(id.name.clone());
29530 }
29531 _ => {}
29532 }
29533 self.merge_strip_qualifiers = names;
29534 }
29535
29536 if let Some(whens) = &e.whens {
29538 if self.config.pretty {
29539 self.write_newline();
29540 self.write_indent();
29541 } else {
29542 self.write_space();
29543 }
29544 self.generate_expression(whens)?;
29545 }
29546
29547 self.merge_strip_qualifiers = saved_merge_strip;
29549
29550 if let Some(returning) = &e.returning {
29552 if self.config.pretty {
29553 self.write_newline();
29554 self.write_indent();
29555 } else {
29556 self.write_space();
29557 }
29558 self.generate_expression(returning)?;
29559 }
29560 Ok(())
29561 }
29562
29563 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
29564 if e.no.is_some() {
29566 self.write_keyword("NO MERGEBLOCKRATIO");
29567 } else if e.default.is_some() {
29568 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
29569 } else {
29570 self.write_keyword("MERGEBLOCKRATIO");
29571 self.write("=");
29572 if let Some(this) = &e.this {
29573 self.generate_expression(this)?;
29574 }
29575 if e.percent.is_some() {
29576 self.write_keyword(" PERCENT");
29577 }
29578 }
29579 Ok(())
29580 }
29581
29582 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
29583 self.write_keyword("TTL");
29585 let pretty_clickhouse = self.config.pretty
29586 && matches!(
29587 self.config.dialect,
29588 Some(crate::dialects::DialectType::ClickHouse)
29589 );
29590
29591 if pretty_clickhouse {
29592 self.write_newline();
29593 self.indent_level += 1;
29594 for (i, expr) in e.expressions.iter().enumerate() {
29595 if i > 0 {
29596 self.write(",");
29597 self.write_newline();
29598 }
29599 self.write_indent();
29600 self.generate_expression(expr)?;
29601 }
29602 self.indent_level -= 1;
29603 } else {
29604 self.write_space();
29605 for (i, expr) in e.expressions.iter().enumerate() {
29606 if i > 0 {
29607 self.write(", ");
29608 }
29609 self.generate_expression(expr)?;
29610 }
29611 }
29612
29613 if let Some(where_) = &e.where_ {
29614 if pretty_clickhouse {
29615 self.write_newline();
29616 if let Expression::Where(w) = where_.as_ref() {
29617 self.write_indent();
29618 self.write_keyword("WHERE");
29619 self.write_newline();
29620 self.indent_level += 1;
29621 self.write_indent();
29622 self.generate_expression(&w.this)?;
29623 self.indent_level -= 1;
29624 } else {
29625 self.write_indent();
29626 self.generate_expression(where_)?;
29627 }
29628 } else {
29629 self.write_space();
29630 self.generate_expression(where_)?;
29631 }
29632 }
29633 if let Some(group) = &e.group {
29634 if pretty_clickhouse {
29635 self.write_newline();
29636 if let Expression::Group(g) = group.as_ref() {
29637 self.write_indent();
29638 self.write_keyword("GROUP BY");
29639 self.write_newline();
29640 self.indent_level += 1;
29641 for (i, expr) in g.expressions.iter().enumerate() {
29642 if i > 0 {
29643 self.write(",");
29644 self.write_newline();
29645 }
29646 self.write_indent();
29647 self.generate_expression(expr)?;
29648 }
29649 self.indent_level -= 1;
29650 } else {
29651 self.write_indent();
29652 self.generate_expression(group)?;
29653 }
29654 } else {
29655 self.write_space();
29656 self.generate_expression(group)?;
29657 }
29658 }
29659 if let Some(aggregates) = &e.aggregates {
29660 if pretty_clickhouse {
29661 self.write_newline();
29662 self.write_indent();
29663 self.write_keyword("SET");
29664 self.write_newline();
29665 self.indent_level += 1;
29666 if let Expression::Tuple(t) = aggregates.as_ref() {
29667 for (i, agg) in t.expressions.iter().enumerate() {
29668 if i > 0 {
29669 self.write(",");
29670 self.write_newline();
29671 }
29672 self.write_indent();
29673 self.generate_expression(agg)?;
29674 }
29675 } else {
29676 self.write_indent();
29677 self.generate_expression(aggregates)?;
29678 }
29679 self.indent_level -= 1;
29680 } else {
29681 self.write_space();
29682 self.write_keyword("SET");
29683 self.write_space();
29684 self.generate_expression(aggregates)?;
29685 }
29686 }
29687 Ok(())
29688 }
29689
29690 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
29691 self.generate_expression(&e.this)?;
29693 if e.delete.is_some() {
29694 self.write_keyword(" DELETE");
29695 }
29696 if let Some(recompress) = &e.recompress {
29697 self.write_keyword(" RECOMPRESS ");
29698 self.generate_expression(recompress)?;
29699 }
29700 if let Some(to_disk) = &e.to_disk {
29701 self.write_keyword(" TO DISK ");
29702 self.generate_expression(to_disk)?;
29703 }
29704 if let Some(to_volume) = &e.to_volume {
29705 self.write_keyword(" TO VOLUME ");
29706 self.generate_expression(to_volume)?;
29707 }
29708 Ok(())
29709 }
29710
29711 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
29712 self.write_keyword("MINHASH");
29714 self.write("(");
29715 self.generate_expression(&e.this)?;
29716 for expr in &e.expressions {
29717 self.write(", ");
29718 self.generate_expression(expr)?;
29719 }
29720 self.write(")");
29721 Ok(())
29722 }
29723
29724 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
29725 self.generate_expression(&e.this)?;
29727 self.write("!");
29728 self.generate_expression(&e.expression)?;
29729 Ok(())
29730 }
29731
29732 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
29733 self.write_keyword("MONTHNAME");
29735 self.write("(");
29736 self.generate_expression(&e.this)?;
29737 self.write(")");
29738 Ok(())
29739 }
29740
29741 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
29742 for comment in &e.leading_comments {
29744 self.write_formatted_comment(comment);
29745 if self.config.pretty {
29746 self.write_newline();
29747 self.write_indent();
29748 } else {
29749 self.write_space();
29750 }
29751 }
29752 self.write_keyword("INSERT");
29754 self.write_space();
29755 self.write(&e.kind);
29756 if self.config.pretty {
29757 self.indent_level += 1;
29758 for expr in &e.expressions {
29759 self.write_newline();
29760 self.write_indent();
29761 self.generate_expression(expr)?;
29762 }
29763 self.indent_level -= 1;
29764 } else {
29765 for expr in &e.expressions {
29766 self.write_space();
29767 self.generate_expression(expr)?;
29768 }
29769 }
29770 if let Some(source) = &e.source {
29771 if self.config.pretty {
29772 self.write_newline();
29773 self.write_indent();
29774 } else {
29775 self.write_space();
29776 }
29777 self.generate_expression(source)?;
29778 }
29779 Ok(())
29780 }
29781
29782 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
29783 self.write_keyword("NEXT VALUE FOR");
29785 self.write_space();
29786 self.generate_expression(&e.this)?;
29787 if let Some(order) = &e.order {
29788 self.write_space();
29789 self.write_keyword("OVER");
29790 self.write(" (");
29791 self.generate_expression(order)?;
29792 self.write(")");
29793 }
29794 Ok(())
29795 }
29796
29797 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
29798 self.write_keyword("NORMAL");
29800 self.write("(");
29801 self.generate_expression(&e.this)?;
29802 if let Some(stddev) = &e.stddev {
29803 self.write(", ");
29804 self.generate_expression(stddev)?;
29805 }
29806 if let Some(gen) = &e.gen {
29807 self.write(", ");
29808 self.generate_expression(gen)?;
29809 }
29810 self.write(")");
29811 Ok(())
29812 }
29813
29814 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
29815 if e.is_casefold.is_some() {
29817 self.write_keyword("NORMALIZE_AND_CASEFOLD");
29818 } else {
29819 self.write_keyword("NORMALIZE");
29820 }
29821 self.write("(");
29822 self.generate_expression(&e.this)?;
29823 if let Some(form) = &e.form {
29824 self.write(", ");
29825 self.generate_expression(form)?;
29826 }
29827 self.write(")");
29828 Ok(())
29829 }
29830
29831 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
29832 if e.allow_null.is_none() {
29834 self.write_keyword("NOT ");
29835 }
29836 self.write_keyword("NULL");
29837 Ok(())
29838 }
29839
29840 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
29841 self.write_keyword("NULLIF");
29843 self.write("(");
29844 self.generate_expression(&e.this)?;
29845 self.write(", ");
29846 self.generate_expression(&e.expression)?;
29847 self.write(")");
29848 Ok(())
29849 }
29850
29851 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
29852 self.write_keyword("FORMAT");
29854 self.write("(");
29855 self.generate_expression(&e.this)?;
29856 self.write(", '");
29857 self.write(&e.format);
29858 self.write("'");
29859 if let Some(culture) = &e.culture {
29860 self.write(", ");
29861 self.generate_expression(culture)?;
29862 }
29863 self.write(")");
29864 Ok(())
29865 }
29866
29867 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
29868 self.write_keyword("OBJECT_AGG");
29870 self.write("(");
29871 self.generate_expression(&e.this)?;
29872 self.write(", ");
29873 self.generate_expression(&e.expression)?;
29874 self.write(")");
29875 Ok(())
29876 }
29877
29878 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
29879 self.generate_expression(&e.this)?;
29881 Ok(())
29882 }
29883
29884 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
29885 self.write_keyword("OBJECT_INSERT");
29887 self.write("(");
29888 self.generate_expression(&e.this)?;
29889 if let Some(key) = &e.key {
29890 self.write(", ");
29891 self.generate_expression(key)?;
29892 }
29893 if let Some(value) = &e.value {
29894 self.write(", ");
29895 self.generate_expression(value)?;
29896 }
29897 if let Some(update_flag) = &e.update_flag {
29898 self.write(", ");
29899 self.generate_expression(update_flag)?;
29900 }
29901 self.write(")");
29902 Ok(())
29903 }
29904
29905 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
29906 self.write_keyword("OFFSET");
29908 self.write_space();
29909 self.generate_expression(&e.this)?;
29910 if e.rows == Some(true)
29912 && matches!(
29913 self.config.dialect,
29914 Some(crate::dialects::DialectType::TSQL)
29915 | Some(crate::dialects::DialectType::Oracle)
29916 )
29917 {
29918 self.write_space();
29919 self.write_keyword("ROWS");
29920 }
29921 Ok(())
29922 }
29923
29924 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
29925 self.write_keyword("QUALIFY");
29927 self.write_space();
29928 self.generate_expression(&e.this)?;
29929 Ok(())
29930 }
29931
29932 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
29933 self.write_keyword("ON CLUSTER");
29935 self.write_space();
29936 self.generate_expression(&e.this)?;
29937 Ok(())
29938 }
29939
29940 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
29941 self.write_keyword("ON COMMIT");
29943 if e.delete.is_some() {
29944 self.write_keyword(" DELETE ROWS");
29945 } else {
29946 self.write_keyword(" PRESERVE ROWS");
29947 }
29948 Ok(())
29949 }
29950
29951 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
29952 if let Some(empty) = &e.empty {
29954 self.generate_expression(empty)?;
29955 self.write_keyword(" ON EMPTY");
29956 }
29957 if let Some(error) = &e.error {
29958 if e.empty.is_some() {
29959 self.write_space();
29960 }
29961 self.generate_expression(error)?;
29962 self.write_keyword(" ON ERROR");
29963 }
29964 if let Some(null) = &e.null {
29965 if e.empty.is_some() || e.error.is_some() {
29966 self.write_space();
29967 }
29968 self.generate_expression(null)?;
29969 self.write_keyword(" ON NULL");
29970 }
29971 Ok(())
29972 }
29973
29974 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
29975 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
29977 return Ok(());
29978 }
29979 if e.duplicate.is_some() {
29981 self.write_keyword("ON DUPLICATE KEY UPDATE");
29983 for (i, expr) in e.expressions.iter().enumerate() {
29984 if i > 0 {
29985 self.write(",");
29986 }
29987 self.write_space();
29988 self.generate_expression(expr)?;
29989 }
29990 return Ok(());
29991 } else {
29992 self.write_keyword("ON CONFLICT");
29993 }
29994 if let Some(constraint) = &e.constraint {
29995 self.write_keyword(" ON CONSTRAINT ");
29996 self.generate_expression(constraint)?;
29997 }
29998 if let Some(conflict_keys) = &e.conflict_keys {
29999 if let Expression::Tuple(t) = conflict_keys.as_ref() {
30001 self.write("(");
30002 for (i, expr) in t.expressions.iter().enumerate() {
30003 if i > 0 {
30004 self.write(", ");
30005 }
30006 self.generate_expression(expr)?;
30007 }
30008 self.write(")");
30009 } else {
30010 self.write("(");
30011 self.generate_expression(conflict_keys)?;
30012 self.write(")");
30013 }
30014 }
30015 if let Some(index_predicate) = &e.index_predicate {
30016 self.write_keyword(" WHERE ");
30017 self.generate_expression(index_predicate)?;
30018 }
30019 if let Some(action) = &e.action {
30020 if let Expression::Identifier(id) = action.as_ref() {
30022 if id.name == "NOTHING" || id.name.to_uppercase() == "NOTHING" {
30023 self.write_keyword(" DO NOTHING");
30024 } else {
30025 self.write_keyword(" DO ");
30026 self.generate_expression(action)?;
30027 }
30028 } else if let Expression::Tuple(t) = action.as_ref() {
30029 self.write_keyword(" DO UPDATE SET ");
30031 for (i, expr) in t.expressions.iter().enumerate() {
30032 if i > 0 {
30033 self.write(", ");
30034 }
30035 self.generate_expression(expr)?;
30036 }
30037 } else {
30038 self.write_keyword(" DO ");
30039 self.generate_expression(action)?;
30040 }
30041 }
30042 if let Some(where_) = &e.where_ {
30044 self.write_keyword(" WHERE ");
30045 self.generate_expression(where_)?;
30046 }
30047 Ok(())
30048 }
30049
30050 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
30051 self.write_keyword("ON");
30053 self.write_space();
30054 self.generate_expression(&e.this)?;
30055 Ok(())
30056 }
30057
30058 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
30059 self.generate_expression(&e.this)?;
30061 self.write_space();
30062 self.generate_expression(&e.expression)?;
30063 Ok(())
30064 }
30065
30066 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
30067 self.write_keyword("OPENJSON");
30069 self.write("(");
30070 self.generate_expression(&e.this)?;
30071 if let Some(path) = &e.path {
30072 self.write(", ");
30073 self.generate_expression(path)?;
30074 }
30075 self.write(")");
30076 if !e.expressions.is_empty() {
30077 self.write_keyword(" WITH");
30078 if self.config.pretty {
30079 self.write(" (\n");
30080 self.indent_level += 2;
30081 for (i, expr) in e.expressions.iter().enumerate() {
30082 if i > 0 {
30083 self.write(",\n");
30084 }
30085 self.write_indent();
30086 self.generate_expression(expr)?;
30087 }
30088 self.write("\n");
30089 self.indent_level -= 2;
30090 self.write(")");
30091 } else {
30092 self.write(" (");
30093 for (i, expr) in e.expressions.iter().enumerate() {
30094 if i > 0 {
30095 self.write(", ");
30096 }
30097 self.generate_expression(expr)?;
30098 }
30099 self.write(")");
30100 }
30101 }
30102 Ok(())
30103 }
30104
30105 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
30106 self.generate_expression(&e.this)?;
30108 self.write_space();
30109 if let Some(ref dt) = e.data_type {
30111 self.generate_data_type(dt)?;
30112 } else if !e.kind.is_empty() {
30113 self.write(&e.kind);
30114 }
30115 if let Some(path) = &e.path {
30116 self.write_space();
30117 self.generate_expression(path)?;
30118 }
30119 if e.as_json.is_some() {
30120 self.write_keyword(" AS JSON");
30121 }
30122 Ok(())
30123 }
30124
30125 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
30126 self.generate_expression(&e.this)?;
30128 self.write_space();
30129 if let Some(op) = &e.operator {
30130 self.write_keyword("OPERATOR");
30131 self.write("(");
30132 self.generate_expression(op)?;
30133 self.write(")");
30134 }
30135 for comment in &e.comments {
30137 self.write_space();
30138 self.write_formatted_comment(comment);
30139 }
30140 self.write_space();
30141 self.generate_expression(&e.expression)?;
30142 Ok(())
30143 }
30144
30145 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
30146 self.write_keyword("ORDER BY");
30148 let pretty_clickhouse_single_paren = self.config.pretty
30149 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
30150 && e.expressions.len() == 1
30151 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
30152 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
30153 && e.expressions.len() == 1
30154 && matches!(e.expressions[0].this, Expression::Tuple(_))
30155 && !e.expressions[0].desc
30156 && e.expressions[0].nulls_first.is_none();
30157
30158 if pretty_clickhouse_single_paren {
30159 self.write_space();
30160 if let Expression::Paren(p) = &e.expressions[0].this {
30161 self.write("(");
30162 self.write_newline();
30163 self.indent_level += 1;
30164 self.write_indent();
30165 self.generate_expression(&p.this)?;
30166 self.indent_level -= 1;
30167 self.write_newline();
30168 self.write(")");
30169 }
30170 return Ok(());
30171 }
30172
30173 if clickhouse_single_tuple {
30174 self.write_space();
30175 if let Expression::Tuple(t) = &e.expressions[0].this {
30176 self.write("(");
30177 for (i, expr) in t.expressions.iter().enumerate() {
30178 if i > 0 {
30179 self.write(", ");
30180 }
30181 self.generate_expression(expr)?;
30182 }
30183 self.write(")");
30184 }
30185 return Ok(());
30186 }
30187
30188 self.write_space();
30189 for (i, ordered) in e.expressions.iter().enumerate() {
30190 if i > 0 {
30191 self.write(", ");
30192 }
30193 self.generate_expression(&ordered.this)?;
30194 if ordered.desc {
30195 self.write_space();
30196 self.write_keyword("DESC");
30197 } else if ordered.explicit_asc {
30198 self.write_space();
30199 self.write_keyword("ASC");
30200 }
30201 if let Some(nulls_first) = ordered.nulls_first {
30202 let skip_nulls_last =
30204 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
30205 if !skip_nulls_last {
30206 self.write_space();
30207 self.write_keyword("NULLS");
30208 self.write_space();
30209 if nulls_first {
30210 self.write_keyword("FIRST");
30211 } else {
30212 self.write_keyword("LAST");
30213 }
30214 }
30215 }
30216 }
30217 Ok(())
30218 }
30219
30220 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
30221 self.write_keyword("OUTPUT");
30223 self.write("(");
30224 if self.config.pretty {
30225 self.indent_level += 1;
30226 self.write_newline();
30227 self.write_indent();
30228 self.generate_expression(&e.this)?;
30229 self.indent_level -= 1;
30230 self.write_newline();
30231 } else {
30232 self.generate_expression(&e.this)?;
30233 }
30234 self.write(")");
30235 Ok(())
30236 }
30237
30238 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
30239 self.write_keyword("TRUNCATE");
30241 if let Some(this) = &e.this {
30242 self.write_space();
30243 self.generate_expression(this)?;
30244 }
30245 if e.with_count.is_some() {
30246 self.write_keyword(" WITH COUNT");
30247 } else {
30248 self.write_keyword(" WITHOUT COUNT");
30249 }
30250 Ok(())
30251 }
30252
30253 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
30254 self.generate_expression(&e.this)?;
30256 self.write("(");
30257 for (i, expr) in e.expressions.iter().enumerate() {
30258 if i > 0 {
30259 self.write(", ");
30260 }
30261 self.generate_expression(expr)?;
30262 }
30263 self.write(")(");
30264 for (i, param) in e.params.iter().enumerate() {
30265 if i > 0 {
30266 self.write(", ");
30267 }
30268 self.generate_expression(param)?;
30269 }
30270 self.write(")");
30271 Ok(())
30272 }
30273
30274 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
30275 self.write_keyword("PARSE_DATETIME");
30277 self.write("(");
30278 if let Some(format) = &e.format {
30279 self.write("'");
30280 self.write(format);
30281 self.write("', ");
30282 }
30283 self.generate_expression(&e.this)?;
30284 if let Some(zone) = &e.zone {
30285 self.write(", ");
30286 self.generate_expression(zone)?;
30287 }
30288 self.write(")");
30289 Ok(())
30290 }
30291
30292 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
30293 self.write_keyword("PARSE_IP");
30295 self.write("(");
30296 self.generate_expression(&e.this)?;
30297 if let Some(type_) = &e.type_ {
30298 self.write(", ");
30299 self.generate_expression(type_)?;
30300 }
30301 if let Some(permissive) = &e.permissive {
30302 self.write(", ");
30303 self.generate_expression(permissive)?;
30304 }
30305 self.write(")");
30306 Ok(())
30307 }
30308
30309 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
30310 self.write_keyword("PARSE_JSON");
30312 self.write("(");
30313 self.generate_expression(&e.this)?;
30314 if let Some(expression) = &e.expression {
30315 self.write(", ");
30316 self.generate_expression(expression)?;
30317 }
30318 self.write(")");
30319 Ok(())
30320 }
30321
30322 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
30323 self.write_keyword("PARSE_TIME");
30325 self.write("(");
30326 self.write(&format!("'{}'", e.format));
30327 self.write(", ");
30328 self.generate_expression(&e.this)?;
30329 self.write(")");
30330 Ok(())
30331 }
30332
30333 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
30334 self.write_keyword("PARSE_URL");
30336 self.write("(");
30337 self.generate_expression(&e.this)?;
30338 if let Some(part) = &e.part_to_extract {
30339 self.write(", ");
30340 self.generate_expression(part)?;
30341 }
30342 if let Some(key) = &e.key {
30343 self.write(", ");
30344 self.generate_expression(key)?;
30345 }
30346 if let Some(permissive) = &e.permissive {
30347 self.write(", ");
30348 self.generate_expression(permissive)?;
30349 }
30350 self.write(")");
30351 Ok(())
30352 }
30353
30354 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
30355 if e.subpartition {
30357 self.write_keyword("SUBPARTITION");
30358 } else {
30359 self.write_keyword("PARTITION");
30360 }
30361 self.write("(");
30362 for (i, expr) in e.expressions.iter().enumerate() {
30363 if i > 0 {
30364 self.write(", ");
30365 }
30366 self.generate_expression(expr)?;
30367 }
30368 self.write(")");
30369 Ok(())
30370 }
30371
30372 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
30373 if let Some(this) = &e.this {
30375 if let Some(expression) = &e.expression {
30376 self.write_keyword("WITH");
30378 self.write(" (");
30379 self.write_keyword("MODULUS");
30380 self.write_space();
30381 self.generate_expression(this)?;
30382 self.write(", ");
30383 self.write_keyword("REMAINDER");
30384 self.write_space();
30385 self.generate_expression(expression)?;
30386 self.write(")");
30387 } else {
30388 self.write_keyword("IN");
30390 self.write(" (");
30391 self.generate_partition_bound_values(this)?;
30392 self.write(")");
30393 }
30394 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
30395 self.write_keyword("FROM");
30397 self.write(" (");
30398 self.generate_partition_bound_values(from)?;
30399 self.write(") ");
30400 self.write_keyword("TO");
30401 self.write(" (");
30402 self.generate_partition_bound_values(to)?;
30403 self.write(")");
30404 }
30405 Ok(())
30406 }
30407
30408 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
30411 if let Expression::Tuple(t) = expr {
30412 for (i, e) in t.expressions.iter().enumerate() {
30413 if i > 0 {
30414 self.write(", ");
30415 }
30416 self.generate_expression(e)?;
30417 }
30418 Ok(())
30419 } else {
30420 self.generate_expression(expr)
30421 }
30422 }
30423
30424 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
30425 self.write_keyword("PARTITION BY LIST");
30427 if let Some(partition_exprs) = &e.partition_expressions {
30428 self.write(" (");
30429 self.generate_doris_partition_expressions(partition_exprs)?;
30431 self.write(")");
30432 }
30433 if let Some(create_exprs) = &e.create_expressions {
30434 self.write(" (");
30435 self.generate_doris_partition_definitions(create_exprs)?;
30437 self.write(")");
30438 }
30439 Ok(())
30440 }
30441
30442 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
30443 self.write_keyword("PARTITION BY RANGE");
30445 if let Some(partition_exprs) = &e.partition_expressions {
30446 self.write(" (");
30447 self.generate_doris_partition_expressions(partition_exprs)?;
30449 self.write(")");
30450 }
30451 if let Some(create_exprs) = &e.create_expressions {
30452 self.write(" (");
30453 self.generate_doris_partition_definitions(create_exprs)?;
30455 self.write(")");
30456 }
30457 Ok(())
30458 }
30459
30460 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
30462 if let Expression::Tuple(t) = expr {
30463 for (i, e) in t.expressions.iter().enumerate() {
30464 if i > 0 {
30465 self.write(", ");
30466 }
30467 self.generate_expression(e)?;
30468 }
30469 } else {
30470 self.generate_expression(expr)?;
30471 }
30472 Ok(())
30473 }
30474
30475 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
30477 match expr {
30478 Expression::Tuple(t) => {
30479 for (i, part) in t.expressions.iter().enumerate() {
30481 if i > 0 {
30482 self.write(", ");
30483 }
30484 if let Expression::Partition(p) = part {
30486 for (j, inner) in p.expressions.iter().enumerate() {
30487 if j > 0 {
30488 self.write(", ");
30489 }
30490 self.generate_expression(inner)?;
30491 }
30492 } else {
30493 self.generate_expression(part)?;
30494 }
30495 }
30496 }
30497 Expression::PartitionByRangePropertyDynamic(_) => {
30498 self.generate_expression(expr)?;
30500 }
30501 _ => {
30502 self.generate_expression(expr)?;
30503 }
30504 }
30505 Ok(())
30506 }
30507
30508 fn generate_partition_by_range_property_dynamic(
30509 &mut self,
30510 e: &PartitionByRangePropertyDynamic,
30511 ) -> Result<()> {
30512 if e.use_start_end {
30513 if let Some(start) = &e.start {
30515 self.write_keyword("START");
30516 self.write(" (");
30517 self.generate_expression(start)?;
30518 self.write(")");
30519 }
30520 if let Some(end) = &e.end {
30521 self.write_space();
30522 self.write_keyword("END");
30523 self.write(" (");
30524 self.generate_expression(end)?;
30525 self.write(")");
30526 }
30527 if let Some(every) = &e.every {
30528 self.write_space();
30529 self.write_keyword("EVERY");
30530 self.write(" (");
30531 self.generate_doris_interval(every)?;
30533 self.write(")");
30534 }
30535 } else {
30536 if let Some(start) = &e.start {
30538 self.write_keyword("FROM");
30539 self.write(" (");
30540 self.generate_expression(start)?;
30541 self.write(")");
30542 }
30543 if let Some(end) = &e.end {
30544 self.write_space();
30545 self.write_keyword("TO");
30546 self.write(" (");
30547 self.generate_expression(end)?;
30548 self.write(")");
30549 }
30550 if let Some(every) = &e.every {
30551 self.write_space();
30552 self.generate_doris_interval(every)?;
30554 }
30555 }
30556 Ok(())
30557 }
30558
30559 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
30561 if let Expression::Interval(interval) = expr {
30562 self.write_keyword("INTERVAL");
30563 if let Some(ref value) = interval.this {
30564 self.write_space();
30565 match value {
30569 Expression::Literal(Literal::String(s))
30570 if s.chars()
30571 .all(|c| c.is_ascii_digit() || c == '.' || c == '-')
30572 && !s.is_empty() =>
30573 {
30574 self.write(s);
30575 }
30576 _ => {
30577 self.generate_expression(value)?;
30578 }
30579 }
30580 }
30581 if let Some(ref unit_spec) = interval.unit {
30582 self.write_space();
30583 self.write_interval_unit_spec(unit_spec)?;
30584 }
30585 Ok(())
30586 } else {
30587 self.generate_expression(expr)
30588 }
30589 }
30590
30591 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
30592 self.write_keyword("TRUNCATE");
30594 self.write("(");
30595 self.generate_expression(&e.expression)?;
30596 self.write(", ");
30597 self.generate_expression(&e.this)?;
30598 self.write(")");
30599 Ok(())
30600 }
30601
30602 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
30603 self.write_keyword("PARTITION");
30605 self.write_space();
30606 self.generate_expression(&e.this)?;
30607 self.write_space();
30608 self.write_keyword("VALUES IN");
30609 self.write(" (");
30610 for (i, expr) in e.expressions.iter().enumerate() {
30611 if i > 0 {
30612 self.write(", ");
30613 }
30614 self.generate_expression(expr)?;
30615 }
30616 self.write(")");
30617 Ok(())
30618 }
30619
30620 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
30621 if e.expressions.is_empty() && e.expression.is_some() {
30624 self.generate_expression(&e.this)?;
30626 self.write_space();
30627 self.write_keyword("TO");
30628 self.write_space();
30629 self.generate_expression(e.expression.as_ref().unwrap())?;
30630 return Ok(());
30631 }
30632
30633 self.write_keyword("PARTITION");
30635 self.write_space();
30636 self.generate_expression(&e.this)?;
30637 self.write_space();
30638
30639 if e.expressions.len() == 1 {
30641 self.write_keyword("VALUES LESS THAN");
30643 self.write(" (");
30644 self.generate_expression(&e.expressions[0])?;
30645 self.write(")");
30646 } else if !e.expressions.is_empty() {
30647 self.write_keyword("VALUES");
30649 self.write(" [");
30650 for (i, expr) in e.expressions.iter().enumerate() {
30651 if i > 0 {
30652 self.write(", ");
30653 }
30654 if let Expression::Tuple(t) = expr {
30656 self.write("(");
30657 for (j, inner) in t.expressions.iter().enumerate() {
30658 if j > 0 {
30659 self.write(", ");
30660 }
30661 self.generate_expression(inner)?;
30662 }
30663 self.write(")");
30664 } else {
30665 self.write("(");
30666 self.generate_expression(expr)?;
30667 self.write(")");
30668 }
30669 }
30670 self.write(")");
30671 }
30672 Ok(())
30673 }
30674
30675 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
30676 self.write_keyword("BUCKET");
30678 self.write("(");
30679 self.generate_expression(&e.this)?;
30680 self.write(", ");
30681 self.generate_expression(&e.expression)?;
30682 self.write(")");
30683 Ok(())
30684 }
30685
30686 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
30687 if matches!(
30689 self.config.dialect,
30690 Some(crate::dialects::DialectType::Teradata)
30691 | Some(crate::dialects::DialectType::ClickHouse)
30692 ) {
30693 self.write_keyword("PARTITION BY");
30694 } else {
30695 self.write_keyword("PARTITIONED BY");
30696 }
30697 self.write_space();
30698 if self.config.pretty {
30700 if let Expression::Tuple(ref tuple) = *e.this {
30701 self.write("(");
30702 self.write_newline();
30703 self.indent_level += 1;
30704 for (i, expr) in tuple.expressions.iter().enumerate() {
30705 if i > 0 {
30706 self.write(",");
30707 self.write_newline();
30708 }
30709 self.write_indent();
30710 self.generate_expression(expr)?;
30711 }
30712 self.indent_level -= 1;
30713 self.write_newline();
30714 self.write(")");
30715 } else {
30716 self.generate_expression(&e.this)?;
30717 }
30718 } else {
30719 self.generate_expression(&e.this)?;
30720 }
30721 Ok(())
30722 }
30723
30724 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
30725 self.write_keyword("PARTITION OF");
30727 self.write_space();
30728 self.generate_expression(&e.this)?;
30729 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
30731 self.write_space();
30732 self.write_keyword("FOR VALUES");
30733 self.write_space();
30734 self.generate_expression(&e.expression)?;
30735 } else {
30736 self.write_space();
30737 self.write_keyword("DEFAULT");
30738 }
30739 Ok(())
30740 }
30741
30742 fn generate_period_for_system_time_constraint(
30743 &mut self,
30744 e: &PeriodForSystemTimeConstraint,
30745 ) -> Result<()> {
30746 self.write_keyword("PERIOD FOR SYSTEM_TIME");
30748 self.write(" (");
30749 self.generate_expression(&e.this)?;
30750 self.write(", ");
30751 self.generate_expression(&e.expression)?;
30752 self.write(")");
30753 Ok(())
30754 }
30755
30756 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
30757 self.generate_expression(&e.this)?;
30760 self.write_space();
30761 self.write_keyword("AS");
30762 self.write_space();
30763 if self.config.unpivot_aliases_are_identifiers {
30765 match &e.alias {
30766 Expression::Literal(Literal::String(s)) => {
30767 self.generate_identifier(&Identifier::new(s.clone()))?;
30769 }
30770 Expression::Literal(Literal::Number(n)) => {
30771 let mut id = Identifier::new(n.clone());
30773 id.quoted = true;
30774 self.generate_identifier(&id)?;
30775 }
30776 other => {
30777 self.generate_expression(other)?;
30778 }
30779 }
30780 } else {
30781 self.generate_expression(&e.alias)?;
30782 }
30783 Ok(())
30784 }
30785
30786 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
30787 self.write_keyword("ANY");
30789 if let Some(this) = &e.this {
30790 self.write_space();
30791 self.generate_expression(this)?;
30792 }
30793 Ok(())
30794 }
30795
30796 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
30797 self.write_keyword("ML.PREDICT");
30799 self.write("(");
30800 self.write_keyword("MODEL");
30801 self.write_space();
30802 self.generate_expression(&e.this)?;
30803 self.write(", ");
30804 self.generate_expression(&e.expression)?;
30805 if let Some(params) = &e.params_struct {
30806 self.write(", ");
30807 self.generate_expression(params)?;
30808 }
30809 self.write(")");
30810 Ok(())
30811 }
30812
30813 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
30814 self.write_keyword("PREVIOUS_DAY");
30816 self.write("(");
30817 self.generate_expression(&e.this)?;
30818 self.write(", ");
30819 self.generate_expression(&e.expression)?;
30820 self.write(")");
30821 Ok(())
30822 }
30823
30824 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
30825 self.write_keyword("PRIMARY KEY");
30827 if let Some(name) = &e.this {
30828 self.write_space();
30829 self.generate_expression(name)?;
30830 }
30831 if !e.expressions.is_empty() {
30832 self.write(" (");
30833 for (i, expr) in e.expressions.iter().enumerate() {
30834 if i > 0 {
30835 self.write(", ");
30836 }
30837 self.generate_expression(expr)?;
30838 }
30839 self.write(")");
30840 }
30841 if let Some(include) = &e.include {
30842 self.write_space();
30843 self.generate_expression(include)?;
30844 }
30845 if !e.options.is_empty() {
30846 self.write_space();
30847 for (i, opt) in e.options.iter().enumerate() {
30848 if i > 0 {
30849 self.write_space();
30850 }
30851 self.generate_expression(opt)?;
30852 }
30853 }
30854 Ok(())
30855 }
30856
30857 fn generate_primary_key_column_constraint(
30858 &mut self,
30859 _e: &PrimaryKeyColumnConstraint,
30860 ) -> Result<()> {
30861 self.write_keyword("PRIMARY KEY");
30863 Ok(())
30864 }
30865
30866 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
30867 self.write_keyword("PATH");
30869 self.write_space();
30870 self.generate_expression(&e.this)?;
30871 Ok(())
30872 }
30873
30874 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
30875 self.write_keyword("PROJECTION");
30877 self.write_space();
30878 self.generate_expression(&e.this)?;
30879 self.write(" (");
30880 self.generate_expression(&e.expression)?;
30881 self.write(")");
30882 Ok(())
30883 }
30884
30885 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
30886 for (i, prop) in e.expressions.iter().enumerate() {
30888 if i > 0 {
30889 self.write(", ");
30890 }
30891 self.generate_expression(prop)?;
30892 }
30893 Ok(())
30894 }
30895
30896 fn generate_property(&mut self, e: &Property) -> Result<()> {
30897 self.generate_expression(&e.this)?;
30899 if let Some(value) = &e.value {
30900 self.write("=");
30901 self.generate_expression(value)?;
30902 }
30903 Ok(())
30904 }
30905
30906 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
30908 self.write_keyword("OPTIONS");
30909 self.write(" (");
30910 for (i, opt) in options.iter().enumerate() {
30911 if i > 0 {
30912 self.write(", ");
30913 }
30914 self.generate_option_expression(opt)?;
30915 }
30916 self.write(")");
30917 Ok(())
30918 }
30919
30920 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
30922 self.write_keyword("PROPERTIES");
30923 self.write(" (");
30924 for (i, prop) in properties.iter().enumerate() {
30925 if i > 0 {
30926 self.write(", ");
30927 }
30928 self.generate_option_expression(prop)?;
30929 }
30930 self.write(")");
30931 Ok(())
30932 }
30933
30934 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
30936 self.write_keyword("ENVIRONMENT");
30937 self.write(" (");
30938 for (i, env_item) in environment.iter().enumerate() {
30939 if i > 0 {
30940 self.write(", ");
30941 }
30942 self.generate_environment_expression(env_item)?;
30943 }
30944 self.write(")");
30945 Ok(())
30946 }
30947
30948 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
30950 match expr {
30951 Expression::Eq(eq) => {
30952 self.generate_expression(&eq.left)?;
30954 self.write(" = ");
30955 self.generate_expression(&eq.right)?;
30956 Ok(())
30957 }
30958 _ => self.generate_expression(expr),
30959 }
30960 }
30961
30962 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
30964 self.write_keyword("TBLPROPERTIES");
30965 if self.config.pretty {
30966 self.write(" (");
30967 self.write_newline();
30968 self.indent_level += 1;
30969 for (i, opt) in options.iter().enumerate() {
30970 if i > 0 {
30971 self.write(",");
30972 self.write_newline();
30973 }
30974 self.write_indent();
30975 self.generate_option_expression(opt)?;
30976 }
30977 self.indent_level -= 1;
30978 self.write_newline();
30979 self.write(")");
30980 } else {
30981 self.write(" (");
30982 for (i, opt) in options.iter().enumerate() {
30983 if i > 0 {
30984 self.write(", ");
30985 }
30986 self.generate_option_expression(opt)?;
30987 }
30988 self.write(")");
30989 }
30990 Ok(())
30991 }
30992
30993 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
30995 match expr {
30996 Expression::Eq(eq) => {
30997 self.generate_expression(&eq.left)?;
30999 self.write("=");
31000 self.generate_expression(&eq.right)?;
31001 Ok(())
31002 }
31003 _ => self.generate_expression(expr),
31004 }
31005 }
31006
31007 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
31008 self.generate_expression(&e.this)?;
31010 Ok(())
31011 }
31012
31013 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
31014 self.write_keyword("PUT");
31016 self.write_space();
31017
31018 if e.source_quoted {
31020 self.write("'");
31021 self.write(&e.source);
31022 self.write("'");
31023 } else {
31024 self.write(&e.source);
31025 }
31026
31027 self.write_space();
31028
31029 if let Expression::Literal(Literal::String(s)) = &e.target {
31031 self.write(s);
31032 } else {
31033 self.generate_expression(&e.target)?;
31034 }
31035
31036 for param in &e.params {
31038 self.write_space();
31039 self.write(¶m.name);
31040 if let Some(ref value) = param.value {
31041 self.write("=");
31042 self.generate_expression(value)?;
31043 }
31044 }
31045
31046 Ok(())
31047 }
31048
31049 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
31050 self.write_keyword("QUANTILE");
31052 self.write("(");
31053 self.generate_expression(&e.this)?;
31054 if let Some(quantile) = &e.quantile {
31055 self.write(", ");
31056 self.generate_expression(quantile)?;
31057 }
31058 self.write(")");
31059 Ok(())
31060 }
31061
31062 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
31063 if matches!(
31065 self.config.dialect,
31066 Some(crate::dialects::DialectType::Teradata)
31067 ) {
31068 self.write_keyword("SET");
31069 self.write_space();
31070 }
31071 self.write_keyword("QUERY_BAND");
31072 self.write(" = ");
31073 self.generate_expression(&e.this)?;
31074 if e.update.is_some() {
31075 self.write_space();
31076 self.write_keyword("UPDATE");
31077 }
31078 if let Some(scope) = &e.scope {
31079 self.write_space();
31080 self.write_keyword("FOR");
31081 self.write_space();
31082 self.generate_expression(scope)?;
31083 }
31084 Ok(())
31085 }
31086
31087 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
31088 self.generate_expression(&e.this)?;
31090 if let Some(expression) = &e.expression {
31091 self.write(" = ");
31092 self.generate_expression(expression)?;
31093 }
31094 Ok(())
31095 }
31096
31097 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
31098 self.write_keyword("TRANSFORM");
31100 self.write("(");
31101 for (i, expr) in e.expressions.iter().enumerate() {
31102 if i > 0 {
31103 self.write(", ");
31104 }
31105 self.generate_expression(expr)?;
31106 }
31107 self.write(")");
31108 if let Some(row_format_before) = &e.row_format_before {
31109 self.write_space();
31110 self.generate_expression(row_format_before)?;
31111 }
31112 if let Some(record_writer) = &e.record_writer {
31113 self.write_space();
31114 self.write_keyword("RECORDWRITER");
31115 self.write_space();
31116 self.generate_expression(record_writer)?;
31117 }
31118 if let Some(command_script) = &e.command_script {
31119 self.write_space();
31120 self.write_keyword("USING");
31121 self.write_space();
31122 self.generate_expression(command_script)?;
31123 }
31124 if let Some(schema) = &e.schema {
31125 self.write_space();
31126 self.write_keyword("AS");
31127 self.write_space();
31128 self.generate_expression(schema)?;
31129 }
31130 if let Some(row_format_after) = &e.row_format_after {
31131 self.write_space();
31132 self.generate_expression(row_format_after)?;
31133 }
31134 if let Some(record_reader) = &e.record_reader {
31135 self.write_space();
31136 self.write_keyword("RECORDREADER");
31137 self.write_space();
31138 self.generate_expression(record_reader)?;
31139 }
31140 Ok(())
31141 }
31142
31143 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
31144 self.write_keyword("RANDN");
31146 self.write("(");
31147 if let Some(this) = &e.this {
31148 self.generate_expression(this)?;
31149 }
31150 self.write(")");
31151 Ok(())
31152 }
31153
31154 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
31155 self.write_keyword("RANDSTR");
31157 self.write("(");
31158 self.generate_expression(&e.this)?;
31159 if let Some(generator) = &e.generator {
31160 self.write(", ");
31161 self.generate_expression(generator)?;
31162 }
31163 self.write(")");
31164 Ok(())
31165 }
31166
31167 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
31168 self.write_keyword("RANGE_BUCKET");
31170 self.write("(");
31171 self.generate_expression(&e.this)?;
31172 self.write(", ");
31173 self.generate_expression(&e.expression)?;
31174 self.write(")");
31175 Ok(())
31176 }
31177
31178 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
31179 self.write_keyword("RANGE_N");
31181 self.write("(");
31182 self.generate_expression(&e.this)?;
31183 self.write_space();
31184 self.write_keyword("BETWEEN");
31185 self.write_space();
31186 for (i, expr) in e.expressions.iter().enumerate() {
31187 if i > 0 {
31188 self.write(", ");
31189 }
31190 self.generate_expression(expr)?;
31191 }
31192 if let Some(each) = &e.each {
31193 self.write_space();
31194 self.write_keyword("EACH");
31195 self.write_space();
31196 self.generate_expression(each)?;
31197 }
31198 self.write(")");
31199 Ok(())
31200 }
31201
31202 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
31203 self.write_keyword("READ_CSV");
31205 self.write("(");
31206 self.generate_expression(&e.this)?;
31207 for expr in &e.expressions {
31208 self.write(", ");
31209 self.generate_expression(expr)?;
31210 }
31211 self.write(")");
31212 Ok(())
31213 }
31214
31215 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
31216 self.write_keyword("READ_PARQUET");
31218 self.write("(");
31219 for (i, expr) in e.expressions.iter().enumerate() {
31220 if i > 0 {
31221 self.write(", ");
31222 }
31223 self.generate_expression(expr)?;
31224 }
31225 self.write(")");
31226 Ok(())
31227 }
31228
31229 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
31230 if e.kind == "CYCLE" {
31233 self.write_keyword("CYCLE");
31234 } else {
31235 self.write_keyword("SEARCH");
31236 self.write_space();
31237 self.write(&e.kind);
31238 self.write_space();
31239 self.write_keyword("FIRST BY");
31240 }
31241 self.write_space();
31242 self.generate_expression(&e.this)?;
31243 self.write_space();
31244 self.write_keyword("SET");
31245 self.write_space();
31246 self.generate_expression(&e.expression)?;
31247 if let Some(using) = &e.using {
31248 self.write_space();
31249 self.write_keyword("USING");
31250 self.write_space();
31251 self.generate_expression(using)?;
31252 }
31253 Ok(())
31254 }
31255
31256 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
31257 self.write_keyword("REDUCE");
31259 self.write("(");
31260 self.generate_expression(&e.this)?;
31261 if let Some(initial) = &e.initial {
31262 self.write(", ");
31263 self.generate_expression(initial)?;
31264 }
31265 if let Some(merge) = &e.merge {
31266 self.write(", ");
31267 self.generate_expression(merge)?;
31268 }
31269 if let Some(finish) = &e.finish {
31270 self.write(", ");
31271 self.generate_expression(finish)?;
31272 }
31273 self.write(")");
31274 Ok(())
31275 }
31276
31277 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
31278 self.write_keyword("REFERENCES");
31280 self.write_space();
31281 self.generate_expression(&e.this)?;
31282 if !e.expressions.is_empty() {
31283 self.write(" (");
31284 for (i, expr) in e.expressions.iter().enumerate() {
31285 if i > 0 {
31286 self.write(", ");
31287 }
31288 self.generate_expression(expr)?;
31289 }
31290 self.write(")");
31291 }
31292 for opt in &e.options {
31293 self.write_space();
31294 self.generate_expression(opt)?;
31295 }
31296 Ok(())
31297 }
31298
31299 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
31300 self.write_keyword("REFRESH");
31302 if !e.kind.is_empty() {
31303 self.write_space();
31304 self.write_keyword(&e.kind);
31305 }
31306 self.write_space();
31307 self.generate_expression(&e.this)?;
31308 Ok(())
31309 }
31310
31311 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
31312 self.write_keyword("REFRESH");
31314 self.write_space();
31315 self.write_keyword(&e.method);
31316
31317 if let Some(ref kind) = e.kind {
31318 self.write_space();
31319 self.write_keyword("ON");
31320 self.write_space();
31321 self.write_keyword(kind);
31322
31323 if let Some(ref every) = e.every {
31325 self.write_space();
31326 self.write_keyword("EVERY");
31327 self.write_space();
31328 self.generate_expression(every)?;
31329 if let Some(ref unit) = e.unit {
31330 self.write_space();
31331 self.write_keyword(unit);
31332 }
31333 }
31334
31335 if let Some(ref starts) = e.starts {
31337 self.write_space();
31338 self.write_keyword("STARTS");
31339 self.write_space();
31340 self.generate_expression(starts)?;
31341 }
31342 }
31343 Ok(())
31344 }
31345
31346 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
31347 self.write_keyword("REGEXP_COUNT");
31349 self.write("(");
31350 self.generate_expression(&e.this)?;
31351 self.write(", ");
31352 self.generate_expression(&e.expression)?;
31353 if let Some(position) = &e.position {
31354 self.write(", ");
31355 self.generate_expression(position)?;
31356 }
31357 if let Some(parameters) = &e.parameters {
31358 self.write(", ");
31359 self.generate_expression(parameters)?;
31360 }
31361 self.write(")");
31362 Ok(())
31363 }
31364
31365 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
31366 self.write_keyword("REGEXP_EXTRACT_ALL");
31368 self.write("(");
31369 self.generate_expression(&e.this)?;
31370 self.write(", ");
31371 self.generate_expression(&e.expression)?;
31372 if let Some(group) = &e.group {
31373 self.write(", ");
31374 self.generate_expression(group)?;
31375 }
31376 self.write(")");
31377 Ok(())
31378 }
31379
31380 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
31381 self.write_keyword("REGEXP_FULL_MATCH");
31383 self.write("(");
31384 self.generate_expression(&e.this)?;
31385 self.write(", ");
31386 self.generate_expression(&e.expression)?;
31387 self.write(")");
31388 Ok(())
31389 }
31390
31391 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
31392 use crate::dialects::DialectType;
31393 if matches!(
31395 self.config.dialect,
31396 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
31397 ) && e.flag.is_none()
31398 {
31399 self.generate_expression(&e.this)?;
31400 self.write(" ~* ");
31401 self.generate_expression(&e.expression)?;
31402 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
31403 self.write_keyword("REGEXP_LIKE");
31405 self.write("(");
31406 self.generate_expression(&e.this)?;
31407 self.write(", ");
31408 self.generate_expression(&e.expression)?;
31409 self.write(", ");
31410 if let Some(flag) = &e.flag {
31411 self.generate_expression(flag)?;
31412 } else {
31413 self.write("'i'");
31414 }
31415 self.write(")");
31416 } else {
31417 self.generate_expression(&e.this)?;
31419 self.write_space();
31420 self.write_keyword("REGEXP_ILIKE");
31421 self.write_space();
31422 self.generate_expression(&e.expression)?;
31423 if let Some(flag) = &e.flag {
31424 self.write(", ");
31425 self.generate_expression(flag)?;
31426 }
31427 }
31428 Ok(())
31429 }
31430
31431 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
31432 self.write_keyword("REGEXP_INSTR");
31434 self.write("(");
31435 self.generate_expression(&e.this)?;
31436 self.write(", ");
31437 self.generate_expression(&e.expression)?;
31438 if let Some(position) = &e.position {
31439 self.write(", ");
31440 self.generate_expression(position)?;
31441 }
31442 if let Some(occurrence) = &e.occurrence {
31443 self.write(", ");
31444 self.generate_expression(occurrence)?;
31445 }
31446 if let Some(option) = &e.option {
31447 self.write(", ");
31448 self.generate_expression(option)?;
31449 }
31450 if let Some(parameters) = &e.parameters {
31451 self.write(", ");
31452 self.generate_expression(parameters)?;
31453 }
31454 if let Some(group) = &e.group {
31455 self.write(", ");
31456 self.generate_expression(group)?;
31457 }
31458 self.write(")");
31459 Ok(())
31460 }
31461
31462 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
31463 self.write_keyword("REGEXP_SPLIT");
31465 self.write("(");
31466 self.generate_expression(&e.this)?;
31467 self.write(", ");
31468 self.generate_expression(&e.expression)?;
31469 if let Some(limit) = &e.limit {
31470 self.write(", ");
31471 self.generate_expression(limit)?;
31472 }
31473 self.write(")");
31474 Ok(())
31475 }
31476
31477 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
31478 self.write_keyword("REGR_AVGX");
31480 self.write("(");
31481 self.generate_expression(&e.this)?;
31482 self.write(", ");
31483 self.generate_expression(&e.expression)?;
31484 self.write(")");
31485 Ok(())
31486 }
31487
31488 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
31489 self.write_keyword("REGR_AVGY");
31491 self.write("(");
31492 self.generate_expression(&e.this)?;
31493 self.write(", ");
31494 self.generate_expression(&e.expression)?;
31495 self.write(")");
31496 Ok(())
31497 }
31498
31499 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
31500 self.write_keyword("REGR_COUNT");
31502 self.write("(");
31503 self.generate_expression(&e.this)?;
31504 self.write(", ");
31505 self.generate_expression(&e.expression)?;
31506 self.write(")");
31507 Ok(())
31508 }
31509
31510 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
31511 self.write_keyword("REGR_INTERCEPT");
31513 self.write("(");
31514 self.generate_expression(&e.this)?;
31515 self.write(", ");
31516 self.generate_expression(&e.expression)?;
31517 self.write(")");
31518 Ok(())
31519 }
31520
31521 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
31522 self.write_keyword("REGR_R2");
31524 self.write("(");
31525 self.generate_expression(&e.this)?;
31526 self.write(", ");
31527 self.generate_expression(&e.expression)?;
31528 self.write(")");
31529 Ok(())
31530 }
31531
31532 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
31533 self.write_keyword("REGR_SLOPE");
31535 self.write("(");
31536 self.generate_expression(&e.this)?;
31537 self.write(", ");
31538 self.generate_expression(&e.expression)?;
31539 self.write(")");
31540 Ok(())
31541 }
31542
31543 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
31544 self.write_keyword("REGR_SXX");
31546 self.write("(");
31547 self.generate_expression(&e.this)?;
31548 self.write(", ");
31549 self.generate_expression(&e.expression)?;
31550 self.write(")");
31551 Ok(())
31552 }
31553
31554 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
31555 self.write_keyword("REGR_SXY");
31557 self.write("(");
31558 self.generate_expression(&e.this)?;
31559 self.write(", ");
31560 self.generate_expression(&e.expression)?;
31561 self.write(")");
31562 Ok(())
31563 }
31564
31565 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
31566 self.write_keyword("REGR_SYY");
31568 self.write("(");
31569 self.generate_expression(&e.this)?;
31570 self.write(", ");
31571 self.generate_expression(&e.expression)?;
31572 self.write(")");
31573 Ok(())
31574 }
31575
31576 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
31577 self.write_keyword("REGR_VALX");
31579 self.write("(");
31580 self.generate_expression(&e.this)?;
31581 self.write(", ");
31582 self.generate_expression(&e.expression)?;
31583 self.write(")");
31584 Ok(())
31585 }
31586
31587 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
31588 self.write_keyword("REGR_VALY");
31590 self.write("(");
31591 self.generate_expression(&e.this)?;
31592 self.write(", ");
31593 self.generate_expression(&e.expression)?;
31594 self.write(")");
31595 Ok(())
31596 }
31597
31598 fn generate_remote_with_connection_model_property(
31599 &mut self,
31600 e: &RemoteWithConnectionModelProperty,
31601 ) -> Result<()> {
31602 self.write_keyword("REMOTE WITH CONNECTION");
31604 self.write_space();
31605 self.generate_expression(&e.this)?;
31606 Ok(())
31607 }
31608
31609 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
31610 self.write_keyword("RENAME COLUMN");
31612 if e.exists {
31613 self.write_space();
31614 self.write_keyword("IF EXISTS");
31615 }
31616 self.write_space();
31617 self.generate_expression(&e.this)?;
31618 if let Some(to) = &e.to {
31619 self.write_space();
31620 self.write_keyword("TO");
31621 self.write_space();
31622 self.generate_expression(to)?;
31623 }
31624 Ok(())
31625 }
31626
31627 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
31628 self.write_keyword("REPLACE PARTITION");
31630 self.write_space();
31631 self.generate_expression(&e.expression)?;
31632 if let Some(source) = &e.source {
31633 self.write_space();
31634 self.write_keyword("FROM");
31635 self.write_space();
31636 self.generate_expression(source)?;
31637 }
31638 Ok(())
31639 }
31640
31641 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
31642 let keyword = match self.config.dialect {
31645 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
31646 _ => "RETURNING",
31647 };
31648 self.write_keyword(keyword);
31649 self.write_space();
31650 for (i, expr) in e.expressions.iter().enumerate() {
31651 if i > 0 {
31652 self.write(", ");
31653 }
31654 self.generate_expression(expr)?;
31655 }
31656 if let Some(into) = &e.into {
31657 self.write_space();
31658 self.write_keyword("INTO");
31659 self.write_space();
31660 self.generate_expression(into)?;
31661 }
31662 Ok(())
31663 }
31664
31665 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
31666 self.write_space();
31668 self.write_keyword("OUTPUT");
31669 self.write_space();
31670 for (i, expr) in output.columns.iter().enumerate() {
31671 if i > 0 {
31672 self.write(", ");
31673 }
31674 self.generate_expression(expr)?;
31675 }
31676 if let Some(into_table) = &output.into_table {
31677 self.write_space();
31678 self.write_keyword("INTO");
31679 self.write_space();
31680 self.generate_expression(into_table)?;
31681 }
31682 Ok(())
31683 }
31684
31685 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
31686 self.write_keyword("RETURNS");
31688 if e.is_table.is_some() {
31689 self.write_space();
31690 self.write_keyword("TABLE");
31691 }
31692 if let Some(table) = &e.table {
31693 self.write_space();
31694 self.generate_expression(table)?;
31695 } else if let Some(this) = &e.this {
31696 self.write_space();
31697 self.generate_expression(this)?;
31698 }
31699 if e.null.is_some() {
31700 self.write_space();
31701 self.write_keyword("NULL ON NULL INPUT");
31702 }
31703 Ok(())
31704 }
31705
31706 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
31707 self.write_keyword("ROLLBACK");
31709
31710 if e.this.is_none()
31712 && matches!(
31713 self.config.dialect,
31714 Some(DialectType::TSQL) | Some(DialectType::Fabric)
31715 )
31716 {
31717 self.write_space();
31718 self.write_keyword("TRANSACTION");
31719 }
31720
31721 if let Some(this) = &e.this {
31723 let is_transaction_marker = matches!(
31725 this.as_ref(),
31726 Expression::Identifier(id) if id.name == "TRANSACTION"
31727 );
31728
31729 self.write_space();
31730 self.write_keyword("TRANSACTION");
31731
31732 if !is_transaction_marker {
31734 self.write_space();
31735 self.generate_expression(this)?;
31736 }
31737 }
31738
31739 if let Some(savepoint) = &e.savepoint {
31741 self.write_space();
31742 self.write_keyword("TO");
31743 self.write_space();
31744 self.generate_expression(savepoint)?;
31745 }
31746 Ok(())
31747 }
31748
31749 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
31750 if e.expressions.is_empty() {
31752 self.write_keyword("WITH ROLLUP");
31753 } else {
31754 self.write_keyword("ROLLUP");
31755 self.write("(");
31756 for (i, expr) in e.expressions.iter().enumerate() {
31757 if i > 0 {
31758 self.write(", ");
31759 }
31760 self.generate_expression(expr)?;
31761 }
31762 self.write(")");
31763 }
31764 Ok(())
31765 }
31766
31767 fn generate_row_format_delimited_property(
31768 &mut self,
31769 e: &RowFormatDelimitedProperty,
31770 ) -> Result<()> {
31771 self.write_keyword("ROW FORMAT DELIMITED");
31773 if let Some(fields) = &e.fields {
31774 self.write_space();
31775 self.write_keyword("FIELDS TERMINATED BY");
31776 self.write_space();
31777 self.generate_expression(fields)?;
31778 }
31779 if let Some(escaped) = &e.escaped {
31780 self.write_space();
31781 self.write_keyword("ESCAPED BY");
31782 self.write_space();
31783 self.generate_expression(escaped)?;
31784 }
31785 if let Some(items) = &e.collection_items {
31786 self.write_space();
31787 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
31788 self.write_space();
31789 self.generate_expression(items)?;
31790 }
31791 if let Some(keys) = &e.map_keys {
31792 self.write_space();
31793 self.write_keyword("MAP KEYS TERMINATED BY");
31794 self.write_space();
31795 self.generate_expression(keys)?;
31796 }
31797 if let Some(lines) = &e.lines {
31798 self.write_space();
31799 self.write_keyword("LINES TERMINATED BY");
31800 self.write_space();
31801 self.generate_expression(lines)?;
31802 }
31803 if let Some(null) = &e.null {
31804 self.write_space();
31805 self.write_keyword("NULL DEFINED AS");
31806 self.write_space();
31807 self.generate_expression(null)?;
31808 }
31809 if let Some(serde) = &e.serde {
31810 self.write_space();
31811 self.generate_expression(serde)?;
31812 }
31813 Ok(())
31814 }
31815
31816 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
31817 self.write_keyword("ROW FORMAT");
31819 self.write_space();
31820 self.generate_expression(&e.this)?;
31821 Ok(())
31822 }
31823
31824 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
31825 self.write_keyword("ROW FORMAT SERDE");
31827 self.write_space();
31828 self.generate_expression(&e.this)?;
31829 if let Some(props) = &e.serde_properties {
31830 self.write_space();
31831 self.generate_expression(props)?;
31833 }
31834 Ok(())
31835 }
31836
31837 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
31838 self.write_keyword("SHA2");
31840 self.write("(");
31841 self.generate_expression(&e.this)?;
31842 if let Some(length) = e.length {
31843 self.write(", ");
31844 self.write(&length.to_string());
31845 }
31846 self.write(")");
31847 Ok(())
31848 }
31849
31850 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
31851 self.write_keyword("SHA2_DIGEST");
31853 self.write("(");
31854 self.generate_expression(&e.this)?;
31855 if let Some(length) = e.length {
31856 self.write(", ");
31857 self.write(&length.to_string());
31858 }
31859 self.write(")");
31860 Ok(())
31861 }
31862
31863 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
31864 let name = if matches!(
31865 self.config.dialect,
31866 Some(crate::dialects::DialectType::Spark)
31867 | Some(crate::dialects::DialectType::Databricks)
31868 ) {
31869 "TRY_ADD"
31870 } else {
31871 "SAFE_ADD"
31872 };
31873 self.write_keyword(name);
31874 self.write("(");
31875 self.generate_expression(&e.this)?;
31876 self.write(", ");
31877 self.generate_expression(&e.expression)?;
31878 self.write(")");
31879 Ok(())
31880 }
31881
31882 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
31883 self.write_keyword("SAFE_DIVIDE");
31885 self.write("(");
31886 self.generate_expression(&e.this)?;
31887 self.write(", ");
31888 self.generate_expression(&e.expression)?;
31889 self.write(")");
31890 Ok(())
31891 }
31892
31893 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
31894 let name = if matches!(
31895 self.config.dialect,
31896 Some(crate::dialects::DialectType::Spark)
31897 | Some(crate::dialects::DialectType::Databricks)
31898 ) {
31899 "TRY_MULTIPLY"
31900 } else {
31901 "SAFE_MULTIPLY"
31902 };
31903 self.write_keyword(name);
31904 self.write("(");
31905 self.generate_expression(&e.this)?;
31906 self.write(", ");
31907 self.generate_expression(&e.expression)?;
31908 self.write(")");
31909 Ok(())
31910 }
31911
31912 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
31913 let name = if matches!(
31914 self.config.dialect,
31915 Some(crate::dialects::DialectType::Spark)
31916 | Some(crate::dialects::DialectType::Databricks)
31917 ) {
31918 "TRY_SUBTRACT"
31919 } else {
31920 "SAFE_SUBTRACT"
31921 };
31922 self.write_keyword(name);
31923 self.write("(");
31924 self.generate_expression(&e.this)?;
31925 self.write(", ");
31926 self.generate_expression(&e.expression)?;
31927 self.write(")");
31928 Ok(())
31929 }
31930
31931 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
31934 if matches!(sample.method, SampleMethod::Bucket) {
31936 self.write(" (");
31937 self.write_keyword("BUCKET");
31938 self.write_space();
31939 if let Some(ref num) = sample.bucket_numerator {
31940 self.generate_expression(num)?;
31941 }
31942 self.write_space();
31943 self.write_keyword("OUT OF");
31944 self.write_space();
31945 if let Some(ref denom) = sample.bucket_denominator {
31946 self.generate_expression(denom)?;
31947 }
31948 if let Some(ref field) = sample.bucket_field {
31949 self.write_space();
31950 self.write_keyword("ON");
31951 self.write_space();
31952 self.generate_expression(field)?;
31953 }
31954 self.write(")");
31955 return Ok(());
31956 }
31957
31958 let is_snowflake = matches!(
31960 self.config.dialect,
31961 Some(crate::dialects::DialectType::Snowflake)
31962 );
31963 let is_postgres = matches!(
31964 self.config.dialect,
31965 Some(crate::dialects::DialectType::PostgreSQL)
31966 | Some(crate::dialects::DialectType::Redshift)
31967 );
31968 let is_databricks = matches!(
31970 self.config.dialect,
31971 Some(crate::dialects::DialectType::Databricks)
31972 );
31973 let is_spark = matches!(
31974 self.config.dialect,
31975 Some(crate::dialects::DialectType::Spark)
31976 );
31977 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
31978 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
31980 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
31981 self.write_space();
31982 if !sample.explicit_method && (is_snowflake || force_method) {
31983 self.write_keyword("BERNOULLI");
31985 } else {
31986 match sample.method {
31987 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
31988 SampleMethod::System => self.write_keyword("SYSTEM"),
31989 SampleMethod::Block => self.write_keyword("BLOCK"),
31990 SampleMethod::Row => self.write_keyword("ROW"),
31991 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
31992 SampleMethod::Percent => self.write_keyword("SYSTEM"),
31993 SampleMethod::Bucket => {} }
31995 }
31996 }
31997
31998 let emit_size_no_parens = !self.config.tablesample_requires_parens;
32000 if emit_size_no_parens {
32001 self.write_space();
32002 match &sample.size {
32003 Expression::Tuple(tuple) => {
32004 for (i, expr) in tuple.expressions.iter().enumerate() {
32005 if i > 0 {
32006 self.write(", ");
32007 }
32008 self.generate_expression(expr)?;
32009 }
32010 }
32011 expr => self.generate_expression(expr)?,
32012 }
32013 } else {
32014 self.write(" (");
32015 self.generate_expression(&sample.size)?;
32016 }
32017
32018 let is_rows_method = matches!(
32020 sample.method,
32021 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
32022 );
32023 let is_percent = matches!(
32024 sample.method,
32025 SampleMethod::Percent
32026 | SampleMethod::System
32027 | SampleMethod::Bernoulli
32028 | SampleMethod::Block
32029 );
32030
32031 let is_presto = matches!(
32035 self.config.dialect,
32036 Some(crate::dialects::DialectType::Presto)
32037 | Some(crate::dialects::DialectType::Trino)
32038 | Some(crate::dialects::DialectType::Athena)
32039 );
32040 let should_output_unit = if is_databricks || is_spark {
32041 is_percent || is_rows_method || sample.unit_after_size
32043 } else if is_snowflake || is_postgres || is_presto {
32044 sample.unit_after_size
32045 } else {
32046 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
32047 };
32048
32049 if should_output_unit {
32050 self.write_space();
32051 if sample.is_percent {
32052 self.write_keyword("PERCENT");
32053 } else if is_rows_method && !sample.unit_after_size {
32054 self.write_keyword("ROWS");
32055 } else if sample.unit_after_size {
32056 match sample.method {
32057 SampleMethod::Percent
32058 | SampleMethod::System
32059 | SampleMethod::Bernoulli
32060 | SampleMethod::Block => {
32061 self.write_keyword("PERCENT");
32062 }
32063 SampleMethod::Row | SampleMethod::Reservoir => {
32064 self.write_keyword("ROWS");
32065 }
32066 _ => self.write_keyword("ROWS"),
32067 }
32068 } else {
32069 self.write_keyword("PERCENT");
32070 }
32071 }
32072
32073 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32074 if let Some(ref offset) = sample.offset {
32075 self.write_space();
32076 self.write_keyword("OFFSET");
32077 self.write_space();
32078 self.generate_expression(offset)?;
32079 }
32080 }
32081 if !emit_size_no_parens {
32082 self.write(")");
32083 }
32084
32085 Ok(())
32086 }
32087
32088 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
32089 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32091 self.write_keyword("SAMPLE BY");
32092 } else {
32093 self.write_keyword("SAMPLE");
32094 }
32095 self.write_space();
32096 self.generate_expression(&e.this)?;
32097 Ok(())
32098 }
32099
32100 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
32101 if let Some(this) = &e.this {
32103 self.generate_expression(this)?;
32104 }
32105 if !e.expressions.is_empty() {
32106 if e.this.is_some() {
32108 self.write_space();
32109 }
32110 self.write("(");
32111 for (i, expr) in e.expressions.iter().enumerate() {
32112 if i > 0 {
32113 self.write(", ");
32114 }
32115 self.generate_expression(expr)?;
32116 }
32117 self.write(")");
32118 }
32119 Ok(())
32120 }
32121
32122 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
32123 self.write_keyword("COMMENT");
32125 self.write_space();
32126 self.generate_expression(&e.this)?;
32127 Ok(())
32128 }
32129
32130 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
32131 if let Some(this) = &e.this {
32133 self.generate_expression(this)?;
32134 self.write("::");
32135 }
32136 self.generate_expression(&e.expression)?;
32137 Ok(())
32138 }
32139
32140 fn generate_search(&mut self, e: &Search) -> Result<()> {
32141 self.write_keyword("SEARCH");
32143 self.write("(");
32144 self.generate_expression(&e.this)?;
32145 self.write(", ");
32146 self.generate_expression(&e.expression)?;
32147 if let Some(json_scope) = &e.json_scope {
32148 self.write(", ");
32149 self.generate_expression(json_scope)?;
32150 }
32151 if let Some(analyzer) = &e.analyzer {
32152 self.write(", ");
32153 self.generate_expression(analyzer)?;
32154 }
32155 if let Some(analyzer_options) = &e.analyzer_options {
32156 self.write(", ");
32157 self.generate_expression(analyzer_options)?;
32158 }
32159 if let Some(search_mode) = &e.search_mode {
32160 self.write(", ");
32161 self.generate_expression(search_mode)?;
32162 }
32163 self.write(")");
32164 Ok(())
32165 }
32166
32167 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
32168 self.write_keyword("SEARCH_IP");
32170 self.write("(");
32171 self.generate_expression(&e.this)?;
32172 self.write(", ");
32173 self.generate_expression(&e.expression)?;
32174 self.write(")");
32175 Ok(())
32176 }
32177
32178 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
32179 self.write_keyword("SECURITY");
32181 self.write_space();
32182 self.generate_expression(&e.this)?;
32183 Ok(())
32184 }
32185
32186 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
32187 self.write("SEMANTIC_VIEW(");
32189
32190 if self.config.pretty {
32191 self.write_newline();
32193 self.indent_level += 1;
32194 self.write_indent();
32195 self.generate_expression(&e.this)?;
32196
32197 if let Some(metrics) = &e.metrics {
32198 self.write_newline();
32199 self.write_indent();
32200 self.write_keyword("METRICS");
32201 self.write_space();
32202 self.generate_semantic_view_tuple(metrics)?;
32203 }
32204 if let Some(dimensions) = &e.dimensions {
32205 self.write_newline();
32206 self.write_indent();
32207 self.write_keyword("DIMENSIONS");
32208 self.write_space();
32209 self.generate_semantic_view_tuple(dimensions)?;
32210 }
32211 if let Some(facts) = &e.facts {
32212 self.write_newline();
32213 self.write_indent();
32214 self.write_keyword("FACTS");
32215 self.write_space();
32216 self.generate_semantic_view_tuple(facts)?;
32217 }
32218 if let Some(where_) = &e.where_ {
32219 self.write_newline();
32220 self.write_indent();
32221 self.write_keyword("WHERE");
32222 self.write_space();
32223 self.generate_expression(where_)?;
32224 }
32225 self.write_newline();
32226 self.indent_level -= 1;
32227 self.write_indent();
32228 } else {
32229 self.generate_expression(&e.this)?;
32231 if let Some(metrics) = &e.metrics {
32232 self.write_space();
32233 self.write_keyword("METRICS");
32234 self.write_space();
32235 self.generate_semantic_view_tuple(metrics)?;
32236 }
32237 if let Some(dimensions) = &e.dimensions {
32238 self.write_space();
32239 self.write_keyword("DIMENSIONS");
32240 self.write_space();
32241 self.generate_semantic_view_tuple(dimensions)?;
32242 }
32243 if let Some(facts) = &e.facts {
32244 self.write_space();
32245 self.write_keyword("FACTS");
32246 self.write_space();
32247 self.generate_semantic_view_tuple(facts)?;
32248 }
32249 if let Some(where_) = &e.where_ {
32250 self.write_space();
32251 self.write_keyword("WHERE");
32252 self.write_space();
32253 self.generate_expression(where_)?;
32254 }
32255 }
32256 self.write(")");
32257 Ok(())
32258 }
32259
32260 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
32262 if let Expression::Tuple(t) = expr {
32263 for (i, e) in t.expressions.iter().enumerate() {
32264 if i > 0 {
32265 self.write(", ");
32266 }
32267 self.generate_expression(e)?;
32268 }
32269 } else {
32270 self.generate_expression(expr)?;
32271 }
32272 Ok(())
32273 }
32274
32275 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
32276 if let Some(start) = &e.start {
32278 self.write_keyword("START WITH");
32279 self.write_space();
32280 self.generate_expression(start)?;
32281 }
32282 if let Some(increment) = &e.increment {
32283 self.write_space();
32284 self.write_keyword("INCREMENT BY");
32285 self.write_space();
32286 self.generate_expression(increment)?;
32287 }
32288 if let Some(minvalue) = &e.minvalue {
32289 self.write_space();
32290 self.write_keyword("MINVALUE");
32291 self.write_space();
32292 self.generate_expression(minvalue)?;
32293 }
32294 if let Some(maxvalue) = &e.maxvalue {
32295 self.write_space();
32296 self.write_keyword("MAXVALUE");
32297 self.write_space();
32298 self.generate_expression(maxvalue)?;
32299 }
32300 if let Some(cache) = &e.cache {
32301 self.write_space();
32302 self.write_keyword("CACHE");
32303 self.write_space();
32304 self.generate_expression(cache)?;
32305 }
32306 if let Some(owned) = &e.owned {
32307 self.write_space();
32308 self.write_keyword("OWNED BY");
32309 self.write_space();
32310 self.generate_expression(owned)?;
32311 }
32312 for opt in &e.options {
32313 self.write_space();
32314 self.generate_expression(opt)?;
32315 }
32316 Ok(())
32317 }
32318
32319 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
32320 if e.with_.is_some() {
32322 self.write_keyword("WITH");
32323 self.write_space();
32324 }
32325 self.write_keyword("SERDEPROPERTIES");
32326 self.write(" (");
32327 for (i, expr) in e.expressions.iter().enumerate() {
32328 if i > 0 {
32329 self.write(", ");
32330 }
32331 match expr {
32333 Expression::Eq(eq) => {
32334 self.generate_expression(&eq.left)?;
32335 self.write("=");
32336 self.generate_expression(&eq.right)?;
32337 }
32338 _ => self.generate_expression(expr)?,
32339 }
32340 }
32341 self.write(")");
32342 Ok(())
32343 }
32344
32345 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
32346 self.write("@@");
32348 if let Some(kind) = &e.kind {
32349 self.write(kind);
32350 self.write(".");
32351 }
32352 self.generate_expression(&e.this)?;
32353 Ok(())
32354 }
32355
32356 fn generate_set(&mut self, e: &Set) -> Result<()> {
32357 if e.unset.is_some() {
32359 self.write_keyword("UNSET");
32360 } else {
32361 self.write_keyword("SET");
32362 }
32363 if e.tag.is_some() {
32364 self.write_space();
32365 self.write_keyword("TAG");
32366 }
32367 if !e.expressions.is_empty() {
32368 self.write_space();
32369 for (i, expr) in e.expressions.iter().enumerate() {
32370 if i > 0 {
32371 self.write(", ");
32372 }
32373 self.generate_expression(expr)?;
32374 }
32375 }
32376 Ok(())
32377 }
32378
32379 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
32380 self.write_keyword("SET");
32382 self.write_space();
32383 self.generate_expression(&e.this)?;
32384 Ok(())
32385 }
32386
32387 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
32388 if let Some(kind) = &e.kind {
32390 self.write_keyword(kind);
32391 self.write_space();
32392 }
32393 self.generate_expression(&e.name)?;
32394 self.write(" = ");
32395 self.generate_expression(&e.value)?;
32396 Ok(())
32397 }
32398
32399 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
32400 if let Some(with_) = &e.with_ {
32402 self.generate_expression(with_)?;
32403 self.write_space();
32404 }
32405 self.generate_expression(&e.this)?;
32406 self.write_space();
32407 if let Some(kind) = &e.kind {
32409 self.write_keyword(kind);
32410 }
32411 if e.distinct {
32412 self.write_space();
32413 self.write_keyword("DISTINCT");
32414 } else {
32415 self.write_space();
32416 self.write_keyword("ALL");
32417 }
32418 if e.by_name.is_some() {
32419 self.write_space();
32420 self.write_keyword("BY NAME");
32421 }
32422 self.write_space();
32423 self.generate_expression(&e.expression)?;
32424 Ok(())
32425 }
32426
32427 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
32428 if e.multi.is_some() {
32430 self.write_keyword("MULTISET");
32431 } else {
32432 self.write_keyword("SET");
32433 }
32434 Ok(())
32435 }
32436
32437 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
32438 self.write_keyword("SETTINGS");
32440 if self.config.pretty && e.expressions.len() > 1 {
32441 self.indent_level += 1;
32443 for (i, expr) in e.expressions.iter().enumerate() {
32444 if i > 0 {
32445 self.write(",");
32446 }
32447 self.write_newline();
32448 self.write_indent();
32449 self.generate_expression(expr)?;
32450 }
32451 self.indent_level -= 1;
32452 } else {
32453 self.write_space();
32454 for (i, expr) in e.expressions.iter().enumerate() {
32455 if i > 0 {
32456 self.write(", ");
32457 }
32458 self.generate_expression(expr)?;
32459 }
32460 }
32461 Ok(())
32462 }
32463
32464 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
32465 self.write_keyword("SHARING");
32467 if let Some(this) = &e.this {
32468 self.write(" = ");
32469 self.generate_expression(this)?;
32470 }
32471 Ok(())
32472 }
32473
32474 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
32475 if let Some(begin) = &e.this {
32477 self.generate_expression(begin)?;
32478 }
32479 self.write(":");
32480 if let Some(end) = &e.expression {
32481 self.generate_expression(end)?;
32482 }
32483 if let Some(step) = &e.step {
32484 self.write(":");
32485 self.generate_expression(step)?;
32486 }
32487 Ok(())
32488 }
32489
32490 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
32491 self.write_keyword("SORT_ARRAY");
32493 self.write("(");
32494 self.generate_expression(&e.this)?;
32495 if let Some(asc) = &e.asc {
32496 self.write(", ");
32497 self.generate_expression(asc)?;
32498 }
32499 self.write(")");
32500 Ok(())
32501 }
32502
32503 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
32504 self.write_keyword("SORT BY");
32506 self.write_space();
32507 for (i, expr) in e.expressions.iter().enumerate() {
32508 if i > 0 {
32509 self.write(", ");
32510 }
32511 self.generate_ordered(expr)?;
32512 }
32513 Ok(())
32514 }
32515
32516 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
32517 if e.compound.is_some() {
32519 self.write_keyword("COMPOUND");
32520 self.write_space();
32521 }
32522 self.write_keyword("SORTKEY");
32523 self.write("(");
32524 if let Expression::Tuple(t) = e.this.as_ref() {
32526 for (i, expr) in t.expressions.iter().enumerate() {
32527 if i > 0 {
32528 self.write(", ");
32529 }
32530 self.generate_expression(expr)?;
32531 }
32532 } else {
32533 self.generate_expression(&e.this)?;
32534 }
32535 self.write(")");
32536 Ok(())
32537 }
32538
32539 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
32540 self.write_keyword("SPLIT_PART");
32542 self.write("(");
32543 self.generate_expression(&e.this)?;
32544 if let Some(delimiter) = &e.delimiter {
32545 self.write(", ");
32546 self.generate_expression(delimiter)?;
32547 }
32548 if let Some(part_index) = &e.part_index {
32549 self.write(", ");
32550 self.generate_expression(part_index)?;
32551 }
32552 self.write(")");
32553 Ok(())
32554 }
32555
32556 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
32557 self.generate_expression(&e.this)?;
32559 Ok(())
32560 }
32561
32562 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
32563 self.write_keyword("SQL SECURITY");
32565 self.write_space();
32566 self.generate_expression(&e.this)?;
32567 Ok(())
32568 }
32569
32570 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
32571 self.write_keyword("ST_DISTANCE");
32573 self.write("(");
32574 self.generate_expression(&e.this)?;
32575 self.write(", ");
32576 self.generate_expression(&e.expression)?;
32577 if let Some(use_spheroid) = &e.use_spheroid {
32578 self.write(", ");
32579 self.generate_expression(use_spheroid)?;
32580 }
32581 self.write(")");
32582 Ok(())
32583 }
32584
32585 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
32586 self.write_keyword("ST_POINT");
32588 self.write("(");
32589 self.generate_expression(&e.this)?;
32590 self.write(", ");
32591 self.generate_expression(&e.expression)?;
32592 self.write(")");
32593 Ok(())
32594 }
32595
32596 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
32597 self.generate_expression(&e.this)?;
32599 Ok(())
32600 }
32601
32602 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
32603 self.write_keyword("STANDARD_HASH");
32605 self.write("(");
32606 self.generate_expression(&e.this)?;
32607 if let Some(expression) = &e.expression {
32608 self.write(", ");
32609 self.generate_expression(expression)?;
32610 }
32611 self.write(")");
32612 Ok(())
32613 }
32614
32615 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
32616 self.write_keyword("STORED BY");
32618 self.write_space();
32619 self.generate_expression(&e.this)?;
32620 Ok(())
32621 }
32622
32623 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
32624 use crate::dialects::DialectType;
32627 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
32628 self.write_keyword("CHARINDEX");
32630 self.write("(");
32631 if let Some(substr) = &e.substr {
32632 self.generate_expression(substr)?;
32633 self.write(", ");
32634 }
32635 self.generate_expression(&e.this)?;
32636 if let Some(position) = &e.position {
32637 self.write(", ");
32638 self.generate_expression(position)?;
32639 }
32640 self.write(")");
32641 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32642 self.write_keyword("POSITION");
32643 self.write("(");
32644 self.generate_expression(&e.this)?;
32645 if let Some(substr) = &e.substr {
32646 self.write(", ");
32647 self.generate_expression(substr)?;
32648 }
32649 if let Some(position) = &e.position {
32650 self.write(", ");
32651 self.generate_expression(position)?;
32652 }
32653 if let Some(occurrence) = &e.occurrence {
32654 self.write(", ");
32655 self.generate_expression(occurrence)?;
32656 }
32657 self.write(")");
32658 } else if matches!(
32659 self.config.dialect,
32660 Some(DialectType::SQLite)
32661 | Some(DialectType::Oracle)
32662 | Some(DialectType::BigQuery)
32663 | Some(DialectType::Teradata)
32664 ) {
32665 self.write_keyword("INSTR");
32666 self.write("(");
32667 self.generate_expression(&e.this)?;
32668 if let Some(substr) = &e.substr {
32669 self.write(", ");
32670 self.generate_expression(substr)?;
32671 }
32672 if let Some(position) = &e.position {
32673 self.write(", ");
32674 self.generate_expression(position)?;
32675 } else if e.occurrence.is_some() {
32676 self.write(", 1");
32679 }
32680 if let Some(occurrence) = &e.occurrence {
32681 self.write(", ");
32682 self.generate_expression(occurrence)?;
32683 }
32684 self.write(")");
32685 } else if matches!(
32686 self.config.dialect,
32687 Some(DialectType::MySQL)
32688 | Some(DialectType::SingleStore)
32689 | Some(DialectType::Doris)
32690 | Some(DialectType::StarRocks)
32691 | Some(DialectType::Hive)
32692 | Some(DialectType::Spark)
32693 | Some(DialectType::Databricks)
32694 ) {
32695 self.write_keyword("LOCATE");
32697 self.write("(");
32698 if let Some(substr) = &e.substr {
32699 self.generate_expression(substr)?;
32700 self.write(", ");
32701 }
32702 self.generate_expression(&e.this)?;
32703 if let Some(position) = &e.position {
32704 self.write(", ");
32705 self.generate_expression(position)?;
32706 }
32707 self.write(")");
32708 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
32709 self.write_keyword("CHARINDEX");
32711 self.write("(");
32712 if let Some(substr) = &e.substr {
32713 self.generate_expression(substr)?;
32714 self.write(", ");
32715 }
32716 self.generate_expression(&e.this)?;
32717 if let Some(position) = &e.position {
32718 self.write(", ");
32719 self.generate_expression(position)?;
32720 }
32721 self.write(")");
32722 } else if matches!(
32723 self.config.dialect,
32724 Some(DialectType::PostgreSQL)
32725 | Some(DialectType::Materialize)
32726 | Some(DialectType::RisingWave)
32727 | Some(DialectType::Redshift)
32728 ) {
32729 self.write_keyword("POSITION");
32731 self.write("(");
32732 if let Some(substr) = &e.substr {
32733 self.generate_expression(substr)?;
32734 self.write(" IN ");
32735 }
32736 self.generate_expression(&e.this)?;
32737 self.write(")");
32738 } else {
32739 self.write_keyword("STRPOS");
32740 self.write("(");
32741 self.generate_expression(&e.this)?;
32742 if let Some(substr) = &e.substr {
32743 self.write(", ");
32744 self.generate_expression(substr)?;
32745 }
32746 if let Some(position) = &e.position {
32747 self.write(", ");
32748 self.generate_expression(position)?;
32749 }
32750 if let Some(occurrence) = &e.occurrence {
32751 self.write(", ");
32752 self.generate_expression(occurrence)?;
32753 }
32754 self.write(")");
32755 }
32756 Ok(())
32757 }
32758
32759 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
32760 match self.config.dialect {
32761 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
32762 self.write_keyword("TO_DATE");
32764 self.write("(");
32765 self.generate_expression(&e.this)?;
32766 if let Some(format) = &e.format {
32767 self.write(", '");
32768 self.write(&Self::strftime_to_java_format(format));
32769 self.write("'");
32770 }
32771 self.write(")");
32772 }
32773 Some(DialectType::DuckDB) => {
32774 self.write_keyword("CAST");
32776 self.write("(");
32777 self.write_keyword("STRPTIME");
32778 self.write("(");
32779 self.generate_expression(&e.this)?;
32780 if let Some(format) = &e.format {
32781 self.write(", '");
32782 self.write(format);
32783 self.write("'");
32784 }
32785 self.write(")");
32786 self.write_keyword(" AS ");
32787 self.write_keyword("DATE");
32788 self.write(")");
32789 }
32790 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
32791 self.write_keyword("TO_DATE");
32793 self.write("(");
32794 self.generate_expression(&e.this)?;
32795 if let Some(format) = &e.format {
32796 self.write(", '");
32797 self.write(&Self::strftime_to_postgres_format(format));
32798 self.write("'");
32799 }
32800 self.write(")");
32801 }
32802 Some(DialectType::BigQuery) => {
32803 self.write_keyword("PARSE_DATE");
32805 self.write("(");
32806 if let Some(format) = &e.format {
32807 self.write("'");
32808 self.write(format);
32809 self.write("'");
32810 self.write(", ");
32811 }
32812 self.generate_expression(&e.this)?;
32813 self.write(")");
32814 }
32815 Some(DialectType::Teradata) => {
32816 self.write_keyword("CAST");
32818 self.write("(");
32819 self.generate_expression(&e.this)?;
32820 self.write_keyword(" AS ");
32821 self.write_keyword("DATE");
32822 if let Some(format) = &e.format {
32823 self.write_keyword(" FORMAT ");
32824 self.write("'");
32825 self.write(&Self::strftime_to_teradata_format(format));
32826 self.write("'");
32827 }
32828 self.write(")");
32829 }
32830 _ => {
32831 self.write_keyword("STR_TO_DATE");
32833 self.write("(");
32834 self.generate_expression(&e.this)?;
32835 if let Some(format) = &e.format {
32836 self.write(", '");
32837 self.write(format);
32838 self.write("'");
32839 }
32840 self.write(")");
32841 }
32842 }
32843 Ok(())
32844 }
32845
32846 fn strftime_to_teradata_format(fmt: &str) -> String {
32848 let mut result = fmt.to_string();
32849 result = result.replace("%Y", "YYYY");
32850 result = result.replace("%y", "YY");
32851 result = result.replace("%m", "MM");
32852 result = result.replace("%B", "MMMM");
32853 result = result.replace("%b", "MMM");
32854 result = result.replace("%d", "DD");
32855 result = result.replace("%j", "DDD");
32856 result = result.replace("%H", "HH");
32857 result = result.replace("%M", "MI");
32858 result = result.replace("%S", "SS");
32859 result = result.replace("%f", "SSSSSS");
32860 result = result.replace("%A", "EEEE");
32861 result = result.replace("%a", "EEE");
32862 result
32863 }
32864
32865 pub fn strftime_to_java_format_static(fmt: &str) -> String {
32868 Self::strftime_to_java_format(fmt)
32869 }
32870
32871 fn strftime_to_java_format(fmt: &str) -> String {
32873 let mut result = fmt.to_string();
32874 result = result.replace("%-d", "d");
32876 result = result.replace("%-m", "M");
32877 result = result.replace("%-H", "H");
32878 result = result.replace("%-M", "m");
32879 result = result.replace("%-S", "s");
32880 result = result.replace("%Y", "yyyy");
32881 result = result.replace("%y", "yy");
32882 result = result.replace("%m", "MM");
32883 result = result.replace("%B", "MMMM");
32884 result = result.replace("%b", "MMM");
32885 result = result.replace("%d", "dd");
32886 result = result.replace("%j", "DDD");
32887 result = result.replace("%H", "HH");
32888 result = result.replace("%M", "mm");
32889 result = result.replace("%S", "ss");
32890 result = result.replace("%f", "SSSSSS");
32891 result = result.replace("%A", "EEEE");
32892 result = result.replace("%a", "EEE");
32893 result
32894 }
32895
32896 fn strftime_to_tsql_format(fmt: &str) -> String {
32899 let mut result = fmt.to_string();
32900 result = result.replace("%-d", "d");
32902 result = result.replace("%-m", "M");
32903 result = result.replace("%-H", "H");
32904 result = result.replace("%-M", "m");
32905 result = result.replace("%-S", "s");
32906 result = result.replace("%Y", "yyyy");
32907 result = result.replace("%y", "yy");
32908 result = result.replace("%m", "MM");
32909 result = result.replace("%B", "MMMM");
32910 result = result.replace("%b", "MMM");
32911 result = result.replace("%d", "dd");
32912 result = result.replace("%j", "DDD");
32913 result = result.replace("%H", "HH");
32914 result = result.replace("%M", "mm");
32915 result = result.replace("%S", "ss");
32916 result = result.replace("%f", "ffffff");
32917 result = result.replace("%A", "dddd");
32918 result = result.replace("%a", "ddd");
32919 result
32920 }
32921
32922 fn decompose_json_path(path: &str) -> Vec<String> {
32925 let mut parts = Vec::new();
32926 let path = if path.starts_with("$.") {
32928 &path[2..]
32929 } else if path.starts_with('$') {
32930 &path[1..]
32931 } else {
32932 path
32933 };
32934 if path.is_empty() {
32935 return parts;
32936 }
32937 let mut current = String::new();
32938 let chars: Vec<char> = path.chars().collect();
32939 let mut i = 0;
32940 while i < chars.len() {
32941 match chars[i] {
32942 '.' => {
32943 if !current.is_empty() {
32944 parts.push(current.clone());
32945 current.clear();
32946 }
32947 i += 1;
32948 }
32949 '[' => {
32950 if !current.is_empty() {
32951 parts.push(current.clone());
32952 current.clear();
32953 }
32954 i += 1;
32955 let mut bracket_content = String::new();
32957 while i < chars.len() && chars[i] != ']' {
32958 if chars[i] == '"' || chars[i] == '\'' {
32960 let quote = chars[i];
32961 i += 1;
32962 while i < chars.len() && chars[i] != quote {
32963 bracket_content.push(chars[i]);
32964 i += 1;
32965 }
32966 if i < chars.len() {
32967 i += 1;
32968 } } else {
32970 bracket_content.push(chars[i]);
32971 i += 1;
32972 }
32973 }
32974 if i < chars.len() {
32975 i += 1;
32976 } if bracket_content != "*" {
32979 parts.push(bracket_content);
32980 }
32981 }
32982 _ => {
32983 current.push(chars[i]);
32984 i += 1;
32985 }
32986 }
32987 }
32988 if !current.is_empty() {
32989 parts.push(current);
32990 }
32991 parts
32992 }
32993
32994 fn strftime_to_postgres_format(fmt: &str) -> String {
32996 let mut result = fmt.to_string();
32997 result = result.replace("%-d", "FMDD");
32999 result = result.replace("%-m", "FMMM");
33000 result = result.replace("%-H", "FMHH24");
33001 result = result.replace("%-M", "FMMI");
33002 result = result.replace("%-S", "FMSS");
33003 result = result.replace("%Y", "YYYY");
33004 result = result.replace("%y", "YY");
33005 result = result.replace("%m", "MM");
33006 result = result.replace("%B", "Month");
33007 result = result.replace("%b", "Mon");
33008 result = result.replace("%d", "DD");
33009 result = result.replace("%j", "DDD");
33010 result = result.replace("%H", "HH24");
33011 result = result.replace("%M", "MI");
33012 result = result.replace("%S", "SS");
33013 result = result.replace("%f", "US");
33014 result = result.replace("%A", "Day");
33015 result = result.replace("%a", "Dy");
33016 result
33017 }
33018
33019 fn strftime_to_snowflake_format(fmt: &str) -> String {
33021 let mut result = fmt.to_string();
33022 result = result.replace("%-d", "dd");
33024 result = result.replace("%-m", "mm"); result = result.replace("%Y", "yyyy");
33026 result = result.replace("%y", "yy");
33027 result = result.replace("%m", "mm");
33028 result = result.replace("%d", "DD");
33029 result = result.replace("%H", "hh24");
33030 result = result.replace("%M", "mi");
33031 result = result.replace("%S", "ss");
33032 result = result.replace("%f", "ff");
33033 result
33034 }
33035
33036 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
33037 self.write_keyword("STR_TO_MAP");
33039 self.write("(");
33040 self.generate_expression(&e.this)?;
33041 let needs_defaults = matches!(
33043 self.config.dialect,
33044 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
33045 );
33046 if let Some(pair_delim) = &e.pair_delim {
33047 self.write(", ");
33048 self.generate_expression(pair_delim)?;
33049 } else if needs_defaults {
33050 self.write(", ','");
33051 }
33052 if let Some(key_value_delim) = &e.key_value_delim {
33053 self.write(", ");
33054 self.generate_expression(key_value_delim)?;
33055 } else if needs_defaults {
33056 self.write(", ':'");
33057 }
33058 self.write(")");
33059 Ok(())
33060 }
33061
33062 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
33063 let is_strftime = e.format.contains('%');
33065 let to_strftime = |f: &str| -> String {
33067 if is_strftime {
33068 f.to_string()
33069 } else {
33070 Self::snowflake_format_to_strftime(f)
33071 }
33072 };
33073 let to_java = |f: &str| -> String {
33075 if is_strftime {
33076 Self::strftime_to_java_format(f)
33077 } else {
33078 Self::snowflake_format_to_spark(f)
33079 }
33080 };
33081 let to_pg = |f: &str| -> String {
33083 if is_strftime {
33084 Self::strftime_to_postgres_format(f)
33085 } else {
33086 Self::convert_strptime_to_postgres_format(f)
33087 }
33088 };
33089
33090 match self.config.dialect {
33091 Some(DialectType::Exasol) => {
33092 self.write_keyword("TO_DATE");
33093 self.write("(");
33094 self.generate_expression(&e.this)?;
33095 self.write(", '");
33096 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
33097 self.write("'");
33098 self.write(")");
33099 }
33100 Some(DialectType::BigQuery) => {
33101 let fmt = to_strftime(&e.format);
33103 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
33105 self.write_keyword("PARSE_TIMESTAMP");
33106 self.write("('");
33107 self.write(&fmt);
33108 self.write("', ");
33109 self.generate_expression(&e.this)?;
33110 self.write(")");
33111 }
33112 Some(DialectType::Hive) => {
33113 let java_fmt = to_java(&e.format);
33116 if java_fmt == "yyyy-MM-dd HH:mm:ss"
33117 || java_fmt == "yyyy-MM-dd"
33118 || e.format == "yyyy-MM-dd HH:mm:ss"
33119 || e.format == "yyyy-MM-dd"
33120 {
33121 self.write_keyword("CAST");
33122 self.write("(");
33123 self.generate_expression(&e.this)?;
33124 self.write(" ");
33125 self.write_keyword("AS TIMESTAMP");
33126 self.write(")");
33127 } else {
33128 self.write_keyword("CAST");
33130 self.write("(");
33131 self.write_keyword("FROM_UNIXTIME");
33132 self.write("(");
33133 self.write_keyword("UNIX_TIMESTAMP");
33134 self.write("(");
33135 self.generate_expression(&e.this)?;
33136 self.write(", '");
33137 self.write(&java_fmt);
33138 self.write("')");
33139 self.write(") ");
33140 self.write_keyword("AS TIMESTAMP");
33141 self.write(")");
33142 }
33143 }
33144 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
33145 let java_fmt = to_java(&e.format);
33147 self.write_keyword("TO_TIMESTAMP");
33148 self.write("(");
33149 self.generate_expression(&e.this)?;
33150 self.write(", '");
33151 self.write(&java_fmt);
33152 self.write("')");
33153 }
33154 Some(DialectType::MySQL) => {
33155 let mut fmt = to_strftime(&e.format);
33157 fmt = fmt.replace("%-d", "%e");
33159 fmt = fmt.replace("%-m", "%c");
33160 fmt = fmt.replace("%H:%M:%S", "%T");
33161 self.write_keyword("STR_TO_DATE");
33162 self.write("(");
33163 self.generate_expression(&e.this)?;
33164 self.write(", '");
33165 self.write(&fmt);
33166 self.write("')");
33167 }
33168 Some(DialectType::Drill) => {
33169 let java_fmt = to_java(&e.format);
33171 let java_fmt = java_fmt.replace('T', "''T''");
33173 self.write_keyword("TO_TIMESTAMP");
33174 self.write("(");
33175 self.generate_expression(&e.this)?;
33176 self.write(", '");
33177 self.write(&java_fmt);
33178 self.write("')");
33179 }
33180 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
33181 let mut fmt = to_strftime(&e.format);
33183 fmt = fmt.replace("%-d", "%e");
33185 fmt = fmt.replace("%-m", "%c");
33186 fmt = fmt.replace("%H:%M:%S", "%T");
33187 self.write_keyword("DATE_PARSE");
33188 self.write("(");
33189 self.generate_expression(&e.this)?;
33190 self.write(", '");
33191 self.write(&fmt);
33192 self.write("')");
33193 }
33194 Some(DialectType::DuckDB) => {
33195 let fmt = to_strftime(&e.format);
33197 self.write_keyword("STRPTIME");
33198 self.write("(");
33199 self.generate_expression(&e.this)?;
33200 self.write(", '");
33201 self.write(&fmt);
33202 self.write("')");
33203 }
33204 Some(DialectType::PostgreSQL)
33205 | Some(DialectType::Redshift)
33206 | Some(DialectType::Materialize) => {
33207 let pg_fmt = to_pg(&e.format);
33209 self.write_keyword("TO_TIMESTAMP");
33210 self.write("(");
33211 self.generate_expression(&e.this)?;
33212 self.write(", '");
33213 self.write(&pg_fmt);
33214 self.write("')");
33215 }
33216 Some(DialectType::Oracle) => {
33217 let pg_fmt = to_pg(&e.format);
33219 self.write_keyword("TO_TIMESTAMP");
33220 self.write("(");
33221 self.generate_expression(&e.this)?;
33222 self.write(", '");
33223 self.write(&pg_fmt);
33224 self.write("')");
33225 }
33226 Some(DialectType::Snowflake) => {
33227 self.write_keyword("TO_TIMESTAMP");
33229 self.write("(");
33230 self.generate_expression(&e.this)?;
33231 self.write(", '");
33232 self.write(&e.format);
33233 self.write("')");
33234 }
33235 _ => {
33236 self.write_keyword("STR_TO_TIME");
33238 self.write("(");
33239 self.generate_expression(&e.this)?;
33240 self.write(", '");
33241 self.write(&e.format);
33242 self.write("'");
33243 self.write(")");
33244 }
33245 }
33246 Ok(())
33247 }
33248
33249 fn snowflake_format_to_strftime(format: &str) -> String {
33251 let mut result = String::new();
33252 let chars: Vec<char> = format.chars().collect();
33253 let mut i = 0;
33254 while i < chars.len() {
33255 let remaining = &format[i..];
33256 if remaining.starts_with("yyyy") {
33257 result.push_str("%Y");
33258 i += 4;
33259 } else if remaining.starts_with("yy") {
33260 result.push_str("%y");
33261 i += 2;
33262 } else if remaining.starts_with("mmmm") {
33263 result.push_str("%B"); i += 4;
33265 } else if remaining.starts_with("mon") {
33266 result.push_str("%b"); i += 3;
33268 } else if remaining.starts_with("mm") {
33269 result.push_str("%m");
33270 i += 2;
33271 } else if remaining.starts_with("DD") {
33272 result.push_str("%d");
33273 i += 2;
33274 } else if remaining.starts_with("dy") {
33275 result.push_str("%a"); i += 2;
33277 } else if remaining.starts_with("hh24") {
33278 result.push_str("%H");
33279 i += 4;
33280 } else if remaining.starts_with("hh12") {
33281 result.push_str("%I");
33282 i += 4;
33283 } else if remaining.starts_with("hh") {
33284 result.push_str("%H");
33285 i += 2;
33286 } else if remaining.starts_with("mi") {
33287 result.push_str("%M");
33288 i += 2;
33289 } else if remaining.starts_with("ss") {
33290 result.push_str("%S");
33291 i += 2;
33292 } else if remaining.starts_with("ff") {
33293 result.push_str("%f");
33295 i += 2;
33296 while i < chars.len() && chars[i].is_ascii_digit() {
33298 i += 1;
33299 }
33300 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
33301 result.push_str("%p");
33302 i += 2;
33303 } else if remaining.starts_with("tz") {
33304 result.push_str("%Z");
33305 i += 2;
33306 } else {
33307 result.push(chars[i]);
33308 i += 1;
33309 }
33310 }
33311 result
33312 }
33313
33314 fn snowflake_format_to_spark(format: &str) -> String {
33316 let mut result = String::new();
33317 let chars: Vec<char> = format.chars().collect();
33318 let mut i = 0;
33319 while i < chars.len() {
33320 let remaining = &format[i..];
33321 if remaining.starts_with("yyyy") {
33322 result.push_str("yyyy");
33323 i += 4;
33324 } else if remaining.starts_with("yy") {
33325 result.push_str("yy");
33326 i += 2;
33327 } else if remaining.starts_with("mmmm") {
33328 result.push_str("MMMM"); i += 4;
33330 } else if remaining.starts_with("mon") {
33331 result.push_str("MMM"); i += 3;
33333 } else if remaining.starts_with("mm") {
33334 result.push_str("MM");
33335 i += 2;
33336 } else if remaining.starts_with("DD") {
33337 result.push_str("dd");
33338 i += 2;
33339 } else if remaining.starts_with("dy") {
33340 result.push_str("EEE"); i += 2;
33342 } else if remaining.starts_with("hh24") {
33343 result.push_str("HH");
33344 i += 4;
33345 } else if remaining.starts_with("hh12") {
33346 result.push_str("hh");
33347 i += 4;
33348 } else if remaining.starts_with("hh") {
33349 result.push_str("HH");
33350 i += 2;
33351 } else if remaining.starts_with("mi") {
33352 result.push_str("mm");
33353 i += 2;
33354 } else if remaining.starts_with("ss") {
33355 result.push_str("ss");
33356 i += 2;
33357 } else if remaining.starts_with("ff") {
33358 result.push_str("SSS"); i += 2;
33360 while i < chars.len() && chars[i].is_ascii_digit() {
33362 i += 1;
33363 }
33364 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
33365 result.push_str("a");
33366 i += 2;
33367 } else if remaining.starts_with("tz") {
33368 result.push_str("z");
33369 i += 2;
33370 } else {
33371 result.push(chars[i]);
33372 i += 1;
33373 }
33374 }
33375 result
33376 }
33377
33378 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
33379 match self.config.dialect {
33380 Some(DialectType::DuckDB) => {
33381 self.write_keyword("EPOCH");
33383 self.write("(");
33384 self.write_keyword("STRPTIME");
33385 self.write("(");
33386 if let Some(this) = &e.this {
33387 self.generate_expression(this)?;
33388 }
33389 if let Some(format) = &e.format {
33390 self.write(", '");
33391 self.write(format);
33392 self.write("'");
33393 }
33394 self.write("))");
33395 }
33396 Some(DialectType::Hive) => {
33397 self.write_keyword("UNIX_TIMESTAMP");
33399 self.write("(");
33400 if let Some(this) = &e.this {
33401 self.generate_expression(this)?;
33402 }
33403 if let Some(format) = &e.format {
33404 let java_fmt = Self::strftime_to_java_format(format);
33405 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
33406 self.write(", '");
33407 self.write(&java_fmt);
33408 self.write("'");
33409 }
33410 }
33411 self.write(")");
33412 }
33413 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
33414 self.write_keyword("UNIX_TIMESTAMP");
33416 self.write("(");
33417 if let Some(this) = &e.this {
33418 self.generate_expression(this)?;
33419 }
33420 if let Some(format) = &e.format {
33421 self.write(", '");
33422 self.write(format);
33423 self.write("'");
33424 }
33425 self.write(")");
33426 }
33427 Some(DialectType::Presto) | Some(DialectType::Trino) => {
33428 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
33431 let java_fmt = Self::strftime_to_java_format(c_fmt);
33432 self.write_keyword("TO_UNIXTIME");
33433 self.write("(");
33434 self.write_keyword("COALESCE");
33435 self.write("(");
33436 self.write_keyword("TRY");
33437 self.write("(");
33438 self.write_keyword("DATE_PARSE");
33439 self.write("(");
33440 self.write_keyword("CAST");
33441 self.write("(");
33442 if let Some(this) = &e.this {
33443 self.generate_expression(this)?;
33444 }
33445 self.write(" ");
33446 self.write_keyword("AS VARCHAR");
33447 self.write("), '");
33448 self.write(c_fmt);
33449 self.write("')), ");
33450 self.write_keyword("PARSE_DATETIME");
33451 self.write("(");
33452 self.write_keyword("DATE_FORMAT");
33453 self.write("(");
33454 self.write_keyword("CAST");
33455 self.write("(");
33456 if let Some(this) = &e.this {
33457 self.generate_expression(this)?;
33458 }
33459 self.write(" ");
33460 self.write_keyword("AS TIMESTAMP");
33461 self.write("), '");
33462 self.write(c_fmt);
33463 self.write("'), '");
33464 self.write(&java_fmt);
33465 self.write("')))");
33466 }
33467 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
33468 self.write_keyword("UNIX_TIMESTAMP");
33470 self.write("(");
33471 if let Some(this) = &e.this {
33472 self.generate_expression(this)?;
33473 }
33474 if let Some(format) = &e.format {
33475 let java_fmt = Self::strftime_to_java_format(format);
33476 self.write(", '");
33477 self.write(&java_fmt);
33478 self.write("'");
33479 }
33480 self.write(")");
33481 }
33482 _ => {
33483 self.write_keyword("STR_TO_UNIX");
33485 self.write("(");
33486 if let Some(this) = &e.this {
33487 self.generate_expression(this)?;
33488 }
33489 if let Some(format) = &e.format {
33490 self.write(", '");
33491 self.write(format);
33492 self.write("'");
33493 }
33494 self.write(")");
33495 }
33496 }
33497 Ok(())
33498 }
33499
33500 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
33501 self.write_keyword("STRING_TO_ARRAY");
33503 self.write("(");
33504 self.generate_expression(&e.this)?;
33505 if let Some(expression) = &e.expression {
33506 self.write(", ");
33507 self.generate_expression(expression)?;
33508 }
33509 if let Some(null_val) = &e.null {
33510 self.write(", ");
33511 self.generate_expression(null_val)?;
33512 }
33513 self.write(")");
33514 Ok(())
33515 }
33516
33517 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
33518 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33519 self.write_keyword("OBJECT_CONSTRUCT");
33521 self.write("(");
33522 for (i, (name, expr)) in e.fields.iter().enumerate() {
33523 if i > 0 {
33524 self.write(", ");
33525 }
33526 if let Some(name) = name {
33527 self.write("'");
33528 self.write(name);
33529 self.write("'");
33530 self.write(", ");
33531 } else {
33532 self.write("'_");
33533 self.write(&i.to_string());
33534 self.write("'");
33535 self.write(", ");
33536 }
33537 self.generate_expression(expr)?;
33538 }
33539 self.write(")");
33540 } else if self.config.struct_curly_brace_notation {
33541 self.write("{");
33543 for (i, (name, expr)) in e.fields.iter().enumerate() {
33544 if i > 0 {
33545 self.write(", ");
33546 }
33547 if let Some(name) = name {
33548 self.write("'");
33550 self.write(name);
33551 self.write("'");
33552 self.write(": ");
33553 } else {
33554 self.write("'_");
33556 self.write(&i.to_string());
33557 self.write("'");
33558 self.write(": ");
33559 }
33560 self.generate_expression(expr)?;
33561 }
33562 self.write("}");
33563 } else {
33564 let value_as_name = matches!(
33568 self.config.dialect,
33569 Some(DialectType::BigQuery)
33570 | Some(DialectType::Spark)
33571 | Some(DialectType::Databricks)
33572 | Some(DialectType::Hive)
33573 );
33574 self.write_keyword("STRUCT");
33575 self.write("(");
33576 for (i, (name, expr)) in e.fields.iter().enumerate() {
33577 if i > 0 {
33578 self.write(", ");
33579 }
33580 if let Some(name) = name {
33581 if value_as_name {
33582 self.generate_expression(expr)?;
33584 self.write_space();
33585 self.write_keyword("AS");
33586 self.write_space();
33587 let needs_quoting = name.contains(' ') || name.contains('-');
33589 if needs_quoting {
33590 if matches!(
33591 self.config.dialect,
33592 Some(DialectType::Spark)
33593 | Some(DialectType::Databricks)
33594 | Some(DialectType::Hive)
33595 ) {
33596 self.write("`");
33597 self.write(name);
33598 self.write("`");
33599 } else {
33600 self.write(name);
33601 }
33602 } else {
33603 self.write(name);
33604 }
33605 } else {
33606 self.write(name);
33608 self.write_space();
33609 self.write_keyword("AS");
33610 self.write_space();
33611 self.generate_expression(expr)?;
33612 }
33613 } else {
33614 self.generate_expression(expr)?;
33615 }
33616 }
33617 self.write(")");
33618 }
33619 Ok(())
33620 }
33621
33622 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
33623 self.write_keyword("STUFF");
33625 self.write("(");
33626 self.generate_expression(&e.this)?;
33627 if let Some(start) = &e.start {
33628 self.write(", ");
33629 self.generate_expression(start)?;
33630 }
33631 if let Some(length) = e.length {
33632 self.write(", ");
33633 self.write(&length.to_string());
33634 }
33635 self.write(", ");
33636 self.generate_expression(&e.expression)?;
33637 self.write(")");
33638 Ok(())
33639 }
33640
33641 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
33642 self.write_keyword("SUBSTRING_INDEX");
33644 self.write("(");
33645 self.generate_expression(&e.this)?;
33646 if let Some(delimiter) = &e.delimiter {
33647 self.write(", ");
33648 self.generate_expression(delimiter)?;
33649 }
33650 if let Some(count) = &e.count {
33651 self.write(", ");
33652 self.generate_expression(count)?;
33653 }
33654 self.write(")");
33655 Ok(())
33656 }
33657
33658 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
33659 self.write_keyword("SUMMARIZE");
33661 if e.table.is_some() {
33662 self.write_space();
33663 self.write_keyword("TABLE");
33664 }
33665 self.write_space();
33666 self.generate_expression(&e.this)?;
33667 Ok(())
33668 }
33669
33670 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
33671 self.write_keyword("SYSTIMESTAMP");
33673 Ok(())
33674 }
33675
33676 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
33677 if let Some(this) = &e.this {
33679 self.generate_expression(this)?;
33680 }
33681 if !e.columns.is_empty() {
33682 self.write("(");
33683 for (i, col) in e.columns.iter().enumerate() {
33684 if i > 0 {
33685 self.write(", ");
33686 }
33687 self.generate_expression(col)?;
33688 }
33689 self.write(")");
33690 }
33691 Ok(())
33692 }
33693
33694 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
33695 self.write_keyword("TABLE");
33697 self.write("(");
33698 self.generate_expression(&e.this)?;
33699 self.write(")");
33700 if let Some(alias) = &e.alias {
33701 self.write_space();
33702 self.write_keyword("AS");
33703 self.write_space();
33704 self.write(alias);
33705 }
33706 Ok(())
33707 }
33708
33709 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
33710 self.write_keyword("ROWS FROM");
33712 self.write(" (");
33713 for (i, expr) in e.expressions.iter().enumerate() {
33714 if i > 0 {
33715 self.write(", ");
33716 }
33717 match expr {
33721 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
33722 self.generate_expression(&tuple.expressions[0])?;
33724 self.write_space();
33725 self.write_keyword("AS");
33726 self.write_space();
33727 self.generate_expression(&tuple.expressions[1])?;
33728 }
33729 _ => {
33730 self.generate_expression(expr)?;
33731 }
33732 }
33733 }
33734 self.write(")");
33735 if e.ordinality {
33736 self.write_space();
33737 self.write_keyword("WITH ORDINALITY");
33738 }
33739 if let Some(alias) = &e.alias {
33740 self.write_space();
33741 self.write_keyword("AS");
33742 self.write_space();
33743 self.generate_expression(alias)?;
33744 }
33745 Ok(())
33746 }
33747
33748 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
33749 use crate::dialects::DialectType;
33750
33751 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
33753 if self.config.alias_post_tablesample {
33755 if let Expression::Subquery(ref s) = **this {
33757 if let Some(ref alias) = s.alias {
33758 let mut subquery_no_alias = (**s).clone();
33760 subquery_no_alias.alias = None;
33761 subquery_no_alias.column_aliases = Vec::new();
33762 self.generate_expression(&Expression::Subquery(Box::new(
33763 subquery_no_alias,
33764 )))?;
33765 self.write_space();
33766 self.write_keyword("TABLESAMPLE");
33767 self.generate_sample_body(sample)?;
33768 if let Some(ref seed) = sample.seed {
33769 self.write_space();
33770 let use_seed = sample.use_seed_keyword
33771 && !matches!(
33772 self.config.dialect,
33773 Some(crate::dialects::DialectType::Databricks)
33774 | Some(crate::dialects::DialectType::Spark)
33775 );
33776 if use_seed {
33777 self.write_keyword("SEED");
33778 } else {
33779 self.write_keyword("REPEATABLE");
33780 }
33781 self.write(" (");
33782 self.generate_expression(seed)?;
33783 self.write(")");
33784 }
33785 self.write_space();
33786 self.write_keyword("AS");
33787 self.write_space();
33788 self.generate_identifier(alias)?;
33789 return Ok(());
33790 }
33791 } else if let Expression::Alias(ref a) = **this {
33792 self.generate_expression(&a.this)?;
33794 self.write_space();
33795 self.write_keyword("TABLESAMPLE");
33796 self.generate_sample_body(sample)?;
33797 if let Some(ref seed) = sample.seed {
33798 self.write_space();
33799 let use_seed = sample.use_seed_keyword
33800 && !matches!(
33801 self.config.dialect,
33802 Some(crate::dialects::DialectType::Databricks)
33803 | Some(crate::dialects::DialectType::Spark)
33804 );
33805 if use_seed {
33806 self.write_keyword("SEED");
33807 } else {
33808 self.write_keyword("REPEATABLE");
33809 }
33810 self.write(" (");
33811 self.generate_expression(seed)?;
33812 self.write(")");
33813 }
33814 self.write_space();
33816 self.write_keyword("AS");
33817 self.write_space();
33818 self.generate_identifier(&a.alias)?;
33819 return Ok(());
33820 }
33821 }
33822 self.generate_expression(this)?;
33824 self.write_space();
33825 self.write_keyword("TABLESAMPLE");
33826 self.generate_sample_body(sample)?;
33827 if let Some(ref seed) = sample.seed {
33829 self.write_space();
33830 let use_seed = sample.use_seed_keyword
33832 && !matches!(
33833 self.config.dialect,
33834 Some(crate::dialects::DialectType::Databricks)
33835 | Some(crate::dialects::DialectType::Spark)
33836 );
33837 if use_seed {
33838 self.write_keyword("SEED");
33839 } else {
33840 self.write_keyword("REPEATABLE");
33841 }
33842 self.write(" (");
33843 self.generate_expression(seed)?;
33844 self.write(")");
33845 }
33846 return Ok(());
33847 }
33848
33849 self.write_keyword("TABLESAMPLE");
33851 if let Some(method) = &e.method {
33852 self.write_space();
33853 self.write_keyword(method);
33854 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33855 self.write_space();
33857 self.write_keyword("BERNOULLI");
33858 }
33859 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
33860 self.write_space();
33861 self.write_keyword("BUCKET");
33862 self.write_space();
33863 self.generate_expression(numerator)?;
33864 self.write_space();
33865 self.write_keyword("OUT OF");
33866 self.write_space();
33867 self.generate_expression(denominator)?;
33868 if let Some(field) = &e.bucket_field {
33869 self.write_space();
33870 self.write_keyword("ON");
33871 self.write_space();
33872 self.generate_expression(field)?;
33873 }
33874 } else if !e.expressions.is_empty() {
33875 self.write(" (");
33876 for (i, expr) in e.expressions.iter().enumerate() {
33877 if i > 0 {
33878 self.write(", ");
33879 }
33880 self.generate_expression(expr)?;
33881 }
33882 self.write(")");
33883 } else if let Some(percent) = &e.percent {
33884 self.write(" (");
33885 self.generate_expression(percent)?;
33886 self.write_space();
33887 self.write_keyword("PERCENT");
33888 self.write(")");
33889 }
33890 Ok(())
33891 }
33892
33893 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
33894 if let Some(prefix) = &e.prefix {
33896 self.generate_expression(prefix)?;
33897 }
33898 if let Some(this) = &e.this {
33899 self.generate_expression(this)?;
33900 }
33901 if let Some(postfix) = &e.postfix {
33902 self.generate_expression(postfix)?;
33903 }
33904 Ok(())
33905 }
33906
33907 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
33908 self.write_keyword("TAG");
33910 self.write(" (");
33911 for (i, expr) in e.expressions.iter().enumerate() {
33912 if i > 0 {
33913 self.write(", ");
33914 }
33915 self.generate_expression(expr)?;
33916 }
33917 self.write(")");
33918 Ok(())
33919 }
33920
33921 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
33922 if let Some(this) = &e.this {
33924 self.generate_expression(this)?;
33925 self.write_space();
33926 }
33927 self.write_keyword("TEMPORARY");
33928 Ok(())
33929 }
33930
33931 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
33934 self.write_keyword("TIME");
33936 self.write("(");
33937 self.generate_expression(&e.this)?;
33938 self.write(")");
33939 Ok(())
33940 }
33941
33942 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
33943 self.write_keyword("TIME_ADD");
33945 self.write("(");
33946 self.generate_expression(&e.this)?;
33947 self.write(", ");
33948 self.generate_expression(&e.expression)?;
33949 if let Some(unit) = &e.unit {
33950 self.write(", ");
33951 self.write_keyword(unit);
33952 }
33953 self.write(")");
33954 Ok(())
33955 }
33956
33957 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
33958 self.write_keyword("TIME_DIFF");
33960 self.write("(");
33961 self.generate_expression(&e.this)?;
33962 self.write(", ");
33963 self.generate_expression(&e.expression)?;
33964 if let Some(unit) = &e.unit {
33965 self.write(", ");
33966 self.write_keyword(unit);
33967 }
33968 self.write(")");
33969 Ok(())
33970 }
33971
33972 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
33973 self.write_keyword("TIME_FROM_PARTS");
33975 self.write("(");
33976 let mut first = true;
33977 if let Some(hour) = &e.hour {
33978 self.generate_expression(hour)?;
33979 first = false;
33980 }
33981 if let Some(minute) = &e.min {
33982 if !first {
33983 self.write(", ");
33984 }
33985 self.generate_expression(minute)?;
33986 first = false;
33987 }
33988 if let Some(second) = &e.sec {
33989 if !first {
33990 self.write(", ");
33991 }
33992 self.generate_expression(second)?;
33993 first = false;
33994 }
33995 if let Some(ns) = &e.nano {
33996 if !first {
33997 self.write(", ");
33998 }
33999 self.generate_expression(ns)?;
34000 }
34001 self.write(")");
34002 Ok(())
34003 }
34004
34005 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
34006 self.write_keyword("TIME_SLICE");
34008 self.write("(");
34009 self.generate_expression(&e.this)?;
34010 self.write(", ");
34011 self.generate_expression(&e.expression)?;
34012 self.write(", ");
34013 self.write_keyword(&e.unit);
34014 self.write(")");
34015 Ok(())
34016 }
34017
34018 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
34019 self.write_keyword("TIME_STR_TO_TIME");
34021 self.write("(");
34022 self.generate_expression(&e.this)?;
34023 self.write(")");
34024 Ok(())
34025 }
34026
34027 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
34028 self.write_keyword("TIME_SUB");
34030 self.write("(");
34031 self.generate_expression(&e.this)?;
34032 self.write(", ");
34033 self.generate_expression(&e.expression)?;
34034 if let Some(unit) = &e.unit {
34035 self.write(", ");
34036 self.write_keyword(unit);
34037 }
34038 self.write(")");
34039 Ok(())
34040 }
34041
34042 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
34043 match self.config.dialect {
34044 Some(DialectType::Exasol) => {
34045 self.write_keyword("TO_CHAR");
34047 self.write("(");
34048 self.generate_expression(&e.this)?;
34049 self.write(", '");
34050 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
34051 self.write("'");
34052 self.write(")");
34053 }
34054 Some(DialectType::PostgreSQL)
34055 | Some(DialectType::Redshift)
34056 | Some(DialectType::Materialize) => {
34057 self.write_keyword("TO_CHAR");
34059 self.write("(");
34060 self.generate_expression(&e.this)?;
34061 self.write(", '");
34062 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
34063 self.write("'");
34064 self.write(")");
34065 }
34066 Some(DialectType::Oracle) => {
34067 self.write_keyword("TO_CHAR");
34069 self.write("(");
34070 self.generate_expression(&e.this)?;
34071 self.write(", '");
34072 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
34073 self.write("'");
34074 self.write(")");
34075 }
34076 Some(DialectType::Drill) => {
34077 self.write_keyword("TO_CHAR");
34079 self.write("(");
34080 self.generate_expression(&e.this)?;
34081 self.write(", '");
34082 self.write(&Self::strftime_to_java_format(&e.format));
34083 self.write("'");
34084 self.write(")");
34085 }
34086 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
34087 self.write_keyword("FORMAT");
34089 self.write("(");
34090 self.generate_expression(&e.this)?;
34091 self.write(", '");
34092 self.write(&Self::strftime_to_tsql_format(&e.format));
34093 self.write("'");
34094 self.write(")");
34095 }
34096 Some(DialectType::DuckDB) => {
34097 self.write_keyword("STRFTIME");
34099 self.write("(");
34100 self.generate_expression(&e.this)?;
34101 self.write(", '");
34102 self.write(&e.format);
34103 self.write("'");
34104 self.write(")");
34105 }
34106 Some(DialectType::BigQuery) => {
34107 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
34110 self.write_keyword("FORMAT_DATE");
34111 self.write("('");
34112 self.write(&fmt);
34113 self.write("', ");
34114 self.generate_expression(&e.this)?;
34115 self.write(")");
34116 }
34117 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
34118 self.write_keyword("DATE_FORMAT");
34120 self.write("(");
34121 self.generate_expression(&e.this)?;
34122 self.write(", '");
34123 self.write(&Self::strftime_to_java_format(&e.format));
34124 self.write("'");
34125 self.write(")");
34126 }
34127 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
34128 self.write_keyword("DATE_FORMAT");
34130 self.write("(");
34131 self.generate_expression(&e.this)?;
34132 self.write(", '");
34133 self.write(&e.format);
34134 self.write("'");
34135 self.write(")");
34136 }
34137 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
34138 self.write_keyword("DATE_FORMAT");
34140 self.write("(");
34141 self.generate_expression(&e.this)?;
34142 self.write(", '");
34143 self.write(&e.format);
34144 self.write("'");
34145 self.write(")");
34146 }
34147 _ => {
34148 self.write_keyword("TIME_TO_STR");
34150 self.write("(");
34151 self.generate_expression(&e.this)?;
34152 self.write(", '");
34153 self.write(&e.format);
34154 self.write("'");
34155 self.write(")");
34156 }
34157 }
34158 Ok(())
34159 }
34160
34161 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
34162 match self.config.dialect {
34163 Some(DialectType::DuckDB) => {
34164 self.write_keyword("EPOCH");
34166 self.write("(");
34167 self.generate_expression(&e.this)?;
34168 self.write(")");
34169 }
34170 Some(DialectType::Hive)
34171 | Some(DialectType::Spark)
34172 | Some(DialectType::Databricks)
34173 | Some(DialectType::Doris)
34174 | Some(DialectType::StarRocks)
34175 | Some(DialectType::Drill) => {
34176 self.write_keyword("UNIX_TIMESTAMP");
34178 self.write("(");
34179 self.generate_expression(&e.this)?;
34180 self.write(")");
34181 }
34182 Some(DialectType::Presto) | Some(DialectType::Trino) => {
34183 self.write_keyword("TO_UNIXTIME");
34185 self.write("(");
34186 self.generate_expression(&e.this)?;
34187 self.write(")");
34188 }
34189 _ => {
34190 self.write_keyword("TIME_TO_UNIX");
34192 self.write("(");
34193 self.generate_expression(&e.this)?;
34194 self.write(")");
34195 }
34196 }
34197 Ok(())
34198 }
34199
34200 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
34201 match self.config.dialect {
34202 Some(DialectType::Hive) => {
34203 self.write_keyword("TO_DATE");
34205 self.write("(");
34206 self.generate_expression(&e.this)?;
34207 self.write(")");
34208 }
34209 _ => {
34210 self.write_keyword("TIME_STR_TO_DATE");
34212 self.write("(");
34213 self.generate_expression(&e.this)?;
34214 self.write(")");
34215 }
34216 }
34217 Ok(())
34218 }
34219
34220 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
34221 self.write_keyword("TIME_TRUNC");
34223 self.write("(");
34224 self.generate_expression(&e.this)?;
34225 self.write(", ");
34226 self.write_keyword(&e.unit);
34227 self.write(")");
34228 Ok(())
34229 }
34230
34231 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
34232 if let Some(unit) = &e.unit {
34234 self.write_keyword(unit);
34235 }
34236 Ok(())
34237 }
34238
34239 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
34243 use crate::dialects::DialectType;
34244 use crate::expressions::Literal;
34245
34246 match self.config.dialect {
34247 Some(DialectType::Exasol) => {
34249 self.write_keyword("TO_TIMESTAMP");
34250 self.write("(");
34251 if let Some(this) = &e.this {
34253 match this.as_ref() {
34254 Expression::Literal(Literal::String(s)) => {
34255 self.write("'");
34256 self.write(s);
34257 self.write("'");
34258 }
34259 _ => {
34260 self.generate_expression(this)?;
34261 }
34262 }
34263 }
34264 self.write(")");
34265 }
34266 _ => {
34268 self.write_keyword("TIMESTAMP");
34269 self.write("(");
34270 if let Some(this) = &e.this {
34271 self.generate_expression(this)?;
34272 }
34273 if let Some(zone) = &e.zone {
34274 self.write(", ");
34275 self.generate_expression(zone)?;
34276 }
34277 self.write(")");
34278 }
34279 }
34280 Ok(())
34281 }
34282
34283 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
34284 self.write_keyword("TIMESTAMP_ADD");
34286 self.write("(");
34287 self.generate_expression(&e.this)?;
34288 self.write(", ");
34289 self.generate_expression(&e.expression)?;
34290 if let Some(unit) = &e.unit {
34291 self.write(", ");
34292 self.write_keyword(unit);
34293 }
34294 self.write(")");
34295 Ok(())
34296 }
34297
34298 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
34299 self.write_keyword("TIMESTAMP_DIFF");
34301 self.write("(");
34302 self.generate_expression(&e.this)?;
34303 self.write(", ");
34304 self.generate_expression(&e.expression)?;
34305 if let Some(unit) = &e.unit {
34306 self.write(", ");
34307 self.write_keyword(unit);
34308 }
34309 self.write(")");
34310 Ok(())
34311 }
34312
34313 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
34314 self.write_keyword("TIMESTAMP_FROM_PARTS");
34316 self.write("(");
34317 if let Some(this) = &e.this {
34318 self.generate_expression(this)?;
34319 }
34320 if let Some(expression) = &e.expression {
34321 self.write(", ");
34322 self.generate_expression(expression)?;
34323 }
34324 if let Some(zone) = &e.zone {
34325 self.write(", ");
34326 self.generate_expression(zone)?;
34327 }
34328 if let Some(milli) = &e.milli {
34329 self.write(", ");
34330 self.generate_expression(milli)?;
34331 }
34332 self.write(")");
34333 Ok(())
34334 }
34335
34336 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
34337 self.write_keyword("TIMESTAMP_SUB");
34339 self.write("(");
34340 self.generate_expression(&e.this)?;
34341 self.write(", ");
34342 self.write_keyword("INTERVAL");
34343 self.write_space();
34344 self.generate_expression(&e.expression)?;
34345 if let Some(unit) = &e.unit {
34346 self.write_space();
34347 self.write_keyword(unit);
34348 }
34349 self.write(")");
34350 Ok(())
34351 }
34352
34353 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
34354 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
34356 self.write("(");
34357 if let Some(zone) = &e.zone {
34358 self.generate_expression(zone)?;
34359 }
34360 self.write(")");
34361 Ok(())
34362 }
34363
34364 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
34365 self.write_keyword("TO_BINARY");
34367 self.write("(");
34368 self.generate_expression(&e.this)?;
34369 if let Some(format) = &e.format {
34370 self.write(", '");
34371 self.write(format);
34372 self.write("'");
34373 }
34374 self.write(")");
34375 Ok(())
34376 }
34377
34378 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
34379 self.write_keyword("TO_BOOLEAN");
34381 self.write("(");
34382 self.generate_expression(&e.this)?;
34383 self.write(")");
34384 Ok(())
34385 }
34386
34387 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
34388 self.write_keyword("TO_CHAR");
34390 self.write("(");
34391 self.generate_expression(&e.this)?;
34392 if let Some(format) = &e.format {
34393 self.write(", '");
34394 self.write(format);
34395 self.write("'");
34396 }
34397 if let Some(nlsparam) = &e.nlsparam {
34398 self.write(", ");
34399 self.generate_expression(nlsparam)?;
34400 }
34401 self.write(")");
34402 Ok(())
34403 }
34404
34405 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
34406 self.write_keyword("TO_DECFLOAT");
34408 self.write("(");
34409 self.generate_expression(&e.this)?;
34410 if let Some(format) = &e.format {
34411 self.write(", '");
34412 self.write(format);
34413 self.write("'");
34414 }
34415 self.write(")");
34416 Ok(())
34417 }
34418
34419 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
34420 self.write_keyword("TO_DOUBLE");
34422 self.write("(");
34423 self.generate_expression(&e.this)?;
34424 if let Some(format) = &e.format {
34425 self.write(", '");
34426 self.write(format);
34427 self.write("'");
34428 }
34429 self.write(")");
34430 Ok(())
34431 }
34432
34433 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
34434 self.write_keyword("TO_FILE");
34436 self.write("(");
34437 self.generate_expression(&e.this)?;
34438 if let Some(path) = &e.path {
34439 self.write(", ");
34440 self.generate_expression(path)?;
34441 }
34442 self.write(")");
34443 Ok(())
34444 }
34445
34446 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
34447 let is_safe = e.safe.is_some();
34450 if is_safe {
34451 self.write_keyword("TRY_TO_NUMBER");
34452 } else {
34453 self.write_keyword("TO_NUMBER");
34454 }
34455 self.write("(");
34456 self.generate_expression(&e.this)?;
34457 if let Some(format) = &e.format {
34458 self.write(", ");
34459 self.generate_expression(format)?;
34460 }
34461 if let Some(nlsparam) = &e.nlsparam {
34462 self.write(", ");
34463 self.generate_expression(nlsparam)?;
34464 }
34465 if let Some(precision) = &e.precision {
34466 self.write(", ");
34467 self.generate_expression(precision)?;
34468 }
34469 if let Some(scale) = &e.scale {
34470 self.write(", ");
34471 self.generate_expression(scale)?;
34472 }
34473 self.write(")");
34474 Ok(())
34475 }
34476
34477 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
34478 self.write_keyword("TO_TABLE");
34480 self.write_space();
34481 self.generate_expression(&e.this)?;
34482 Ok(())
34483 }
34484
34485 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
34486 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
34488 Expression::Identifier(id) => id.name.clone(),
34489 Expression::Literal(Literal::String(s)) => s.clone(),
34490 _ => String::new(),
34491 });
34492
34493 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
34494 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
34495 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
34496 matches!(m.as_ref(), Expression::Literal(Literal::String(_)))
34497 });
34498
34499 let use_start_transaction = matches!(
34501 self.config.dialect,
34502 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
34503 );
34504 let strip_transaction = matches!(
34506 self.config.dialect,
34507 Some(DialectType::Snowflake)
34508 | Some(DialectType::PostgreSQL)
34509 | Some(DialectType::Redshift)
34510 | Some(DialectType::MySQL)
34511 | Some(DialectType::Hive)
34512 | Some(DialectType::Spark)
34513 | Some(DialectType::Databricks)
34514 | Some(DialectType::DuckDB)
34515 | Some(DialectType::Oracle)
34516 | Some(DialectType::Doris)
34517 | Some(DialectType::StarRocks)
34518 | Some(DialectType::Materialize)
34519 | Some(DialectType::ClickHouse)
34520 );
34521
34522 if is_start || use_start_transaction {
34523 self.write_keyword("START TRANSACTION");
34525 if let Some(modes) = &e.modes {
34526 self.write_space();
34527 self.generate_expression(modes)?;
34528 }
34529 } else {
34530 self.write_keyword("BEGIN");
34532
34533 let is_kind = e.this.as_ref().map_or(false, |t| {
34535 if let Expression::Identifier(id) = t.as_ref() {
34536 matches!(
34537 id.name.to_uppercase().as_str(),
34538 "DEFERRED" | "IMMEDIATE" | "EXCLUSIVE"
34539 )
34540 } else {
34541 false
34542 }
34543 });
34544
34545 if is_kind {
34547 if let Some(this) = &e.this {
34548 self.write_space();
34549 if let Expression::Identifier(id) = this.as_ref() {
34550 self.write_keyword(&id.name);
34551 }
34552 }
34553 }
34554
34555 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
34557 self.write_space();
34558 self.write_keyword("TRANSACTION");
34559 }
34560
34561 if !is_kind {
34563 if let Some(this) = &e.this {
34564 self.write_space();
34565 self.generate_expression(this)?;
34566 }
34567 }
34568
34569 if has_with_mark {
34571 self.write_space();
34572 self.write_keyword("WITH MARK");
34573 if let Some(Expression::Literal(Literal::String(desc))) = e.mark.as_deref() {
34574 if !desc.is_empty() {
34575 self.write_space();
34576 self.write(&format!("'{}'", desc));
34577 }
34578 }
34579 }
34580
34581 if let Some(modes) = &e.modes {
34583 self.write_space();
34584 self.generate_expression(modes)?;
34585 }
34586 }
34587 Ok(())
34588 }
34589
34590 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
34591 self.write_keyword("TRANSFORM");
34593 self.write("(");
34594 self.generate_expression(&e.this)?;
34595 self.write(", ");
34596 self.generate_expression(&e.expression)?;
34597 self.write(")");
34598 Ok(())
34599 }
34600
34601 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
34602 self.write_keyword("TRANSFORM");
34604 self.write("(");
34605 if self.config.pretty && !e.expressions.is_empty() {
34606 self.indent_level += 1;
34607 for (i, expr) in e.expressions.iter().enumerate() {
34608 if i > 0 {
34609 self.write(",");
34610 }
34611 self.write_newline();
34612 self.write_indent();
34613 self.generate_expression(expr)?;
34614 }
34615 self.indent_level -= 1;
34616 self.write_newline();
34617 self.write(")");
34618 } else {
34619 for (i, expr) in e.expressions.iter().enumerate() {
34620 if i > 0 {
34621 self.write(", ");
34622 }
34623 self.generate_expression(expr)?;
34624 }
34625 self.write(")");
34626 }
34627 Ok(())
34628 }
34629
34630 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
34631 use crate::dialects::DialectType;
34632 if let Some(this) = &e.this {
34634 self.generate_expression(this)?;
34635 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
34636 self.write_space();
34637 }
34638 }
34639 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
34640 self.write_keyword("TRANSIENT");
34641 }
34642 Ok(())
34643 }
34644
34645 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
34646 self.write_keyword("TRANSLATE");
34648 self.write("(");
34649 self.generate_expression(&e.this)?;
34650 if let Some(from) = &e.from_ {
34651 self.write(", ");
34652 self.generate_expression(from)?;
34653 }
34654 if let Some(to) = &e.to {
34655 self.write(", ");
34656 self.generate_expression(to)?;
34657 }
34658 self.write(")");
34659 Ok(())
34660 }
34661
34662 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
34663 self.write_keyword("TRANSLATE");
34665 self.write("(");
34666 self.generate_expression(&e.this)?;
34667 self.write_space();
34668 self.write_keyword("USING");
34669 self.write_space();
34670 self.generate_expression(&e.expression)?;
34671 if e.with_error.is_some() {
34672 self.write_space();
34673 self.write_keyword("WITH ERROR");
34674 }
34675 self.write(")");
34676 Ok(())
34677 }
34678
34679 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
34680 self.write_keyword("TRUNCATE TABLE");
34682 self.write_space();
34683 for (i, expr) in e.expressions.iter().enumerate() {
34684 if i > 0 {
34685 self.write(", ");
34686 }
34687 self.generate_expression(expr)?;
34688 }
34689 Ok(())
34690 }
34691
34692 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
34693 self.write_keyword("TRY_BASE64_DECODE_BINARY");
34695 self.write("(");
34696 self.generate_expression(&e.this)?;
34697 if let Some(alphabet) = &e.alphabet {
34698 self.write(", ");
34699 self.generate_expression(alphabet)?;
34700 }
34701 self.write(")");
34702 Ok(())
34703 }
34704
34705 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
34706 self.write_keyword("TRY_BASE64_DECODE_STRING");
34708 self.write("(");
34709 self.generate_expression(&e.this)?;
34710 if let Some(alphabet) = &e.alphabet {
34711 self.write(", ");
34712 self.generate_expression(alphabet)?;
34713 }
34714 self.write(")");
34715 Ok(())
34716 }
34717
34718 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
34719 self.write_keyword("TRY_TO_DECFLOAT");
34721 self.write("(");
34722 self.generate_expression(&e.this)?;
34723 if let Some(format) = &e.format {
34724 self.write(", '");
34725 self.write(format);
34726 self.write("'");
34727 }
34728 self.write(")");
34729 Ok(())
34730 }
34731
34732 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
34733 self.write_keyword("TS_OR_DS_ADD");
34735 self.write("(");
34736 self.generate_expression(&e.this)?;
34737 self.write(", ");
34738 self.generate_expression(&e.expression)?;
34739 if let Some(unit) = &e.unit {
34740 self.write(", ");
34741 self.write_keyword(unit);
34742 }
34743 if let Some(return_type) = &e.return_type {
34744 self.write(", ");
34745 self.generate_expression(return_type)?;
34746 }
34747 self.write(")");
34748 Ok(())
34749 }
34750
34751 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
34752 self.write_keyword("TS_OR_DS_DIFF");
34754 self.write("(");
34755 self.generate_expression(&e.this)?;
34756 self.write(", ");
34757 self.generate_expression(&e.expression)?;
34758 if let Some(unit) = &e.unit {
34759 self.write(", ");
34760 self.write_keyword(unit);
34761 }
34762 self.write(")");
34763 Ok(())
34764 }
34765
34766 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
34767 let default_time_format = "%Y-%m-%d %H:%M:%S";
34768 let default_date_format = "%Y-%m-%d";
34769 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
34770 f != default_time_format && f != default_date_format
34771 });
34772
34773 if has_non_default_format {
34774 let fmt = e.format.as_ref().unwrap();
34776 match self.config.dialect {
34777 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
34778 let str_to_time = crate::expressions::StrToTime {
34781 this: Box::new((*e.this).clone()),
34782 format: fmt.clone(),
34783 zone: None,
34784 safe: None,
34785 target_type: None,
34786 };
34787 self.generate_str_to_time(&str_to_time)?;
34788 }
34789 Some(DialectType::Hive)
34790 | Some(DialectType::Spark)
34791 | Some(DialectType::Databricks) => {
34792 self.write_keyword("TO_DATE");
34794 self.write("(");
34795 self.generate_expression(&e.this)?;
34796 self.write(", '");
34797 self.write(&Self::strftime_to_java_format(fmt));
34798 self.write("')");
34799 }
34800 Some(DialectType::Snowflake) => {
34801 self.write_keyword("TO_DATE");
34803 self.write("(");
34804 self.generate_expression(&e.this)?;
34805 self.write(", '");
34806 self.write(&Self::strftime_to_snowflake_format(fmt));
34807 self.write("')");
34808 }
34809 Some(DialectType::Doris) => {
34810 self.write_keyword("TO_DATE");
34812 self.write("(");
34813 self.generate_expression(&e.this)?;
34814 self.write(")");
34815 }
34816 _ => {
34817 self.write_keyword("CAST");
34819 self.write("(");
34820 let str_to_time = crate::expressions::StrToTime {
34821 this: Box::new((*e.this).clone()),
34822 format: fmt.clone(),
34823 zone: None,
34824 safe: None,
34825 target_type: None,
34826 };
34827 self.generate_str_to_time(&str_to_time)?;
34828 self.write_keyword(" AS ");
34829 self.write_keyword("DATE");
34830 self.write(")");
34831 }
34832 }
34833 } else {
34834 match self.config.dialect {
34836 Some(DialectType::MySQL)
34837 | Some(DialectType::SQLite)
34838 | Some(DialectType::StarRocks) => {
34839 self.write_keyword("DATE");
34841 self.write("(");
34842 self.generate_expression(&e.this)?;
34843 self.write(")");
34844 }
34845 Some(DialectType::Hive)
34846 | Some(DialectType::Spark)
34847 | Some(DialectType::Databricks)
34848 | Some(DialectType::Snowflake)
34849 | Some(DialectType::Doris) => {
34850 self.write_keyword("TO_DATE");
34852 self.write("(");
34853 self.generate_expression(&e.this)?;
34854 self.write(")");
34855 }
34856 Some(DialectType::Presto)
34857 | Some(DialectType::Trino)
34858 | Some(DialectType::Athena) => {
34859 self.write_keyword("CAST");
34861 self.write("(");
34862 self.write_keyword("CAST");
34863 self.write("(");
34864 self.generate_expression(&e.this)?;
34865 self.write_keyword(" AS ");
34866 self.write_keyword("TIMESTAMP");
34867 self.write(")");
34868 self.write_keyword(" AS ");
34869 self.write_keyword("DATE");
34870 self.write(")");
34871 }
34872 Some(DialectType::ClickHouse) => {
34873 self.write_keyword("CAST");
34875 self.write("(");
34876 self.generate_expression(&e.this)?;
34877 self.write_keyword(" AS ");
34878 self.write("Nullable(DATE)");
34879 self.write(")");
34880 }
34881 _ => {
34882 self.write_keyword("CAST");
34884 self.write("(");
34885 self.generate_expression(&e.this)?;
34886 self.write_keyword(" AS ");
34887 self.write_keyword("DATE");
34888 self.write(")");
34889 }
34890 }
34891 }
34892 Ok(())
34893 }
34894
34895 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
34896 self.write_keyword("TS_OR_DS_TO_TIME");
34898 self.write("(");
34899 self.generate_expression(&e.this)?;
34900 if let Some(format) = &e.format {
34901 self.write(", '");
34902 self.write(format);
34903 self.write("'");
34904 }
34905 self.write(")");
34906 Ok(())
34907 }
34908
34909 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
34910 self.write_keyword("UNHEX");
34912 self.write("(");
34913 self.generate_expression(&e.this)?;
34914 if let Some(expression) = &e.expression {
34915 self.write(", ");
34916 self.generate_expression(expression)?;
34917 }
34918 self.write(")");
34919 Ok(())
34920 }
34921
34922 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
34923 self.write("U&");
34925 self.generate_expression(&e.this)?;
34926 if let Some(escape) = &e.escape {
34927 self.write_space();
34928 self.write_keyword("UESCAPE");
34929 self.write_space();
34930 self.generate_expression(escape)?;
34931 }
34932 Ok(())
34933 }
34934
34935 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
34936 self.write_keyword("UNIFORM");
34938 self.write("(");
34939 self.generate_expression(&e.this)?;
34940 self.write(", ");
34941 self.generate_expression(&e.expression)?;
34942 if let Some(gen) = &e.gen {
34943 self.write(", ");
34944 self.generate_expression(gen)?;
34945 }
34946 if let Some(seed) = &e.seed {
34947 self.write(", ");
34948 self.generate_expression(seed)?;
34949 }
34950 self.write(")");
34951 Ok(())
34952 }
34953
34954 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
34955 self.write_keyword("UNIQUE");
34957 if e.nulls.is_some() {
34959 self.write(" NULLS NOT DISTINCT");
34960 }
34961 if let Some(this) = &e.this {
34962 self.write_space();
34963 self.generate_expression(this)?;
34964 }
34965 if let Some(index_type) = &e.index_type {
34966 self.write(" USING ");
34967 self.generate_expression(index_type)?;
34968 }
34969 if let Some(on_conflict) = &e.on_conflict {
34970 self.write_space();
34971 self.generate_expression(on_conflict)?;
34972 }
34973 for opt in &e.options {
34974 self.write_space();
34975 self.generate_expression(opt)?;
34976 }
34977 Ok(())
34978 }
34979
34980 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
34981 self.write_keyword("UNIQUE KEY");
34983 self.write(" (");
34984 for (i, expr) in e.expressions.iter().enumerate() {
34985 if i > 0 {
34986 self.write(", ");
34987 }
34988 self.generate_expression(expr)?;
34989 }
34990 self.write(")");
34991 Ok(())
34992 }
34993
34994 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
34995 self.write_keyword("ROLLUP");
34997 self.write(" (");
34998 for (i, index) in e.expressions.iter().enumerate() {
34999 if i > 0 {
35000 self.write(", ");
35001 }
35002 self.generate_identifier(&index.name)?;
35003 self.write("(");
35004 for (j, col) in index.expressions.iter().enumerate() {
35005 if j > 0 {
35006 self.write(", ");
35007 }
35008 self.generate_identifier(col)?;
35009 }
35010 self.write(")");
35011 }
35012 self.write(")");
35013 Ok(())
35014 }
35015
35016 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
35017 match self.config.dialect {
35018 Some(DialectType::DuckDB) => {
35019 self.write_keyword("STRFTIME");
35021 self.write("(");
35022 self.write_keyword("TO_TIMESTAMP");
35023 self.write("(");
35024 self.generate_expression(&e.this)?;
35025 self.write("), '");
35026 if let Some(format) = &e.format {
35027 self.write(format);
35028 }
35029 self.write("')");
35030 }
35031 Some(DialectType::Hive) => {
35032 self.write_keyword("FROM_UNIXTIME");
35034 self.write("(");
35035 self.generate_expression(&e.this)?;
35036 if let Some(format) = &e.format {
35037 if format != "yyyy-MM-dd HH:mm:ss" {
35038 self.write(", '");
35039 self.write(format);
35040 self.write("'");
35041 }
35042 }
35043 self.write(")");
35044 }
35045 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35046 self.write_keyword("DATE_FORMAT");
35048 self.write("(");
35049 self.write_keyword("FROM_UNIXTIME");
35050 self.write("(");
35051 self.generate_expression(&e.this)?;
35052 self.write("), '");
35053 if let Some(format) = &e.format {
35054 self.write(format);
35055 }
35056 self.write("')");
35057 }
35058 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35059 self.write_keyword("FROM_UNIXTIME");
35061 self.write("(");
35062 self.generate_expression(&e.this)?;
35063 if let Some(format) = &e.format {
35064 self.write(", '");
35065 self.write(format);
35066 self.write("'");
35067 }
35068 self.write(")");
35069 }
35070 _ => {
35071 self.write_keyword("UNIX_TO_STR");
35073 self.write("(");
35074 self.generate_expression(&e.this)?;
35075 if let Some(format) = &e.format {
35076 self.write(", '");
35077 self.write(format);
35078 self.write("'");
35079 }
35080 self.write(")");
35081 }
35082 }
35083 Ok(())
35084 }
35085
35086 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
35087 use crate::dialects::DialectType;
35088 let scale = e.scale.unwrap_or(0); match self.config.dialect {
35091 Some(DialectType::Snowflake) => {
35092 self.write_keyword("TO_TIMESTAMP");
35094 self.write("(");
35095 self.generate_expression(&e.this)?;
35096 if let Some(s) = e.scale {
35097 if s > 0 {
35098 self.write(", ");
35099 self.write(&s.to_string());
35100 }
35101 }
35102 self.write(")");
35103 }
35104 Some(DialectType::BigQuery) => {
35105 match scale {
35108 0 => {
35109 self.write_keyword("TIMESTAMP_SECONDS");
35110 self.write("(");
35111 self.generate_expression(&e.this)?;
35112 self.write(")");
35113 }
35114 3 => {
35115 self.write_keyword("TIMESTAMP_MILLIS");
35116 self.write("(");
35117 self.generate_expression(&e.this)?;
35118 self.write(")");
35119 }
35120 6 => {
35121 self.write_keyword("TIMESTAMP_MICROS");
35122 self.write("(");
35123 self.generate_expression(&e.this)?;
35124 self.write(")");
35125 }
35126 _ => {
35127 self.write_keyword("TIMESTAMP_SECONDS");
35129 self.write("(CAST(");
35130 self.generate_expression(&e.this)?;
35131 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
35132 }
35133 }
35134 }
35135 Some(DialectType::Spark) => {
35136 match scale {
35141 0 => {
35142 self.write_keyword("CAST");
35143 self.write("(");
35144 self.write_keyword("FROM_UNIXTIME");
35145 self.write("(");
35146 self.generate_expression(&e.this)?;
35147 self.write(") ");
35148 self.write_keyword("AS TIMESTAMP");
35149 self.write(")");
35150 }
35151 3 => {
35152 self.write_keyword("TIMESTAMP_MILLIS");
35153 self.write("(");
35154 self.generate_expression(&e.this)?;
35155 self.write(")");
35156 }
35157 6 => {
35158 self.write_keyword("TIMESTAMP_MICROS");
35159 self.write("(");
35160 self.generate_expression(&e.this)?;
35161 self.write(")");
35162 }
35163 _ => {
35164 self.write_keyword("TIMESTAMP_SECONDS");
35165 self.write("(");
35166 self.generate_expression(&e.this)?;
35167 self.write(&format!(" / POWER(10, {}))", scale));
35168 }
35169 }
35170 }
35171 Some(DialectType::Databricks) => {
35172 match scale {
35176 0 => {
35177 self.write_keyword("CAST");
35178 self.write("(");
35179 self.write_keyword("FROM_UNIXTIME");
35180 self.write("(");
35181 self.generate_expression(&e.this)?;
35182 self.write(") ");
35183 self.write_keyword("AS TIMESTAMP");
35184 self.write(")");
35185 }
35186 3 => {
35187 self.write_keyword("TIMESTAMP_MILLIS");
35188 self.write("(");
35189 self.generate_expression(&e.this)?;
35190 self.write(")");
35191 }
35192 6 => {
35193 self.write_keyword("TIMESTAMP_MICROS");
35194 self.write("(");
35195 self.generate_expression(&e.this)?;
35196 self.write(")");
35197 }
35198 _ => {
35199 self.write_keyword("TIMESTAMP_SECONDS");
35200 self.write("(");
35201 self.generate_expression(&e.this)?;
35202 self.write(&format!(" / POWER(10, {}))", scale));
35203 }
35204 }
35205 }
35206 Some(DialectType::Hive) => {
35207 if scale == 0 {
35209 self.write_keyword("FROM_UNIXTIME");
35210 self.write("(");
35211 self.generate_expression(&e.this)?;
35212 self.write(")");
35213 } else {
35214 self.write_keyword("FROM_UNIXTIME");
35215 self.write("(");
35216 self.generate_expression(&e.this)?;
35217 self.write(&format!(" / POWER(10, {})", scale));
35218 self.write(")");
35219 }
35220 }
35221 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35222 if scale == 0 {
35225 self.write_keyword("FROM_UNIXTIME");
35226 self.write("(");
35227 self.generate_expression(&e.this)?;
35228 self.write(")");
35229 } else {
35230 self.write_keyword("FROM_UNIXTIME");
35231 self.write("(CAST(");
35232 self.generate_expression(&e.this)?;
35233 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
35234 }
35235 }
35236 Some(DialectType::DuckDB) => {
35237 match scale {
35241 0 => {
35242 self.write_keyword("TO_TIMESTAMP");
35243 self.write("(");
35244 self.generate_expression(&e.this)?;
35245 self.write(")");
35246 }
35247 3 => {
35248 self.write_keyword("EPOCH_MS");
35249 self.write("(");
35250 self.generate_expression(&e.this)?;
35251 self.write(")");
35252 }
35253 6 => {
35254 self.write_keyword("MAKE_TIMESTAMP");
35255 self.write("(");
35256 self.generate_expression(&e.this)?;
35257 self.write(")");
35258 }
35259 _ => {
35260 self.write_keyword("TO_TIMESTAMP");
35261 self.write("(");
35262 self.generate_expression(&e.this)?;
35263 self.write(&format!(" / POWER(10, {}))", scale));
35264 self.write_keyword(" AT TIME ZONE");
35265 self.write(" 'UTC'");
35266 }
35267 }
35268 }
35269 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35270 self.write_keyword("FROM_UNIXTIME");
35272 self.write("(");
35273 self.generate_expression(&e.this)?;
35274 self.write(")");
35275 }
35276 Some(DialectType::Oracle) => {
35277 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
35279 self.generate_expression(&e.this)?;
35280 self.write(" / 86400)");
35281 }
35282 Some(DialectType::Redshift) => {
35283 self.write("(TIMESTAMP 'epoch' + ");
35286 if scale == 0 {
35287 self.generate_expression(&e.this)?;
35288 } else {
35289 self.write("(");
35290 self.generate_expression(&e.this)?;
35291 self.write(&format!(" / POWER(10, {}))", scale));
35292 }
35293 self.write(" * INTERVAL '1 SECOND')");
35294 }
35295 _ => {
35296 self.write_keyword("TO_TIMESTAMP");
35298 self.write("(");
35299 self.generate_expression(&e.this)?;
35300 if let Some(s) = e.scale {
35301 self.write(", ");
35302 self.write(&s.to_string());
35303 }
35304 self.write(")");
35305 }
35306 }
35307 Ok(())
35308 }
35309
35310 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
35311 if !matches!(&*e.this, Expression::Null(_)) {
35313 self.write_keyword("NAME");
35314 self.write_space();
35315 self.generate_expression(&e.this)?;
35316 }
35317 if !e.expressions.is_empty() {
35318 self.write_space();
35319 self.write_keyword("VALUE");
35320 self.write_space();
35321 for (i, expr) in e.expressions.iter().enumerate() {
35322 if i > 0 {
35323 self.write(", ");
35324 }
35325 self.generate_expression(expr)?;
35326 }
35327 }
35328 Ok(())
35329 }
35330
35331 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
35332 if e.wrapped.is_some() {
35334 self.write("(");
35335 }
35336 self.generate_expression(&e.this)?;
35337 if e.wrapped.is_some() {
35338 self.write(")");
35339 }
35340 self.write("(");
35341 for (i, expr) in e.expressions.iter().enumerate() {
35342 if i > 0 {
35343 self.write(", ");
35344 }
35345 self.generate_expression(expr)?;
35346 }
35347 self.write(")");
35348 Ok(())
35349 }
35350
35351 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
35352 self.write_keyword("USING TEMPLATE");
35354 self.write_space();
35355 self.generate_expression(&e.this)?;
35356 Ok(())
35357 }
35358
35359 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
35360 self.write_keyword("UTC_TIME");
35362 Ok(())
35363 }
35364
35365 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
35366 self.write_keyword("UTC_TIMESTAMP");
35368 Ok(())
35369 }
35370
35371 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
35372 use crate::dialects::DialectType;
35373 let func_name = match self.config.dialect {
35375 Some(DialectType::Snowflake) => "UUID_STRING",
35376 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
35377 Some(DialectType::BigQuery) => "GENERATE_UUID",
35378 _ => {
35379 if let Some(name) = &e.name {
35380 name.as_str()
35381 } else {
35382 "UUID"
35383 }
35384 }
35385 };
35386 self.write_keyword(func_name);
35387 self.write("(");
35388 if let Some(this) = &e.this {
35389 self.generate_expression(this)?;
35390 }
35391 self.write(")");
35392 Ok(())
35393 }
35394
35395 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
35396 self.write_keyword("MAP");
35398 self.write("(");
35399 let mut first = true;
35400 for (k, v) in e.keys.iter().zip(e.values.iter()) {
35401 if !first {
35402 self.write(", ");
35403 }
35404 self.generate_expression(k)?;
35405 self.write(", ");
35406 self.generate_expression(v)?;
35407 first = false;
35408 }
35409 self.write(")");
35410 Ok(())
35411 }
35412
35413 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
35414 self.write_keyword("VECTOR_SEARCH");
35416 self.write("(");
35417 self.generate_expression(&e.this)?;
35418 if let Some(col) = &e.column_to_search {
35419 self.write(", ");
35420 self.generate_expression(col)?;
35421 }
35422 if let Some(query_table) = &e.query_table {
35423 self.write(", ");
35424 self.generate_expression(query_table)?;
35425 }
35426 if let Some(query_col) = &e.query_column_to_search {
35427 self.write(", ");
35428 self.generate_expression(query_col)?;
35429 }
35430 if let Some(top_k) = &e.top_k {
35431 self.write(", ");
35432 self.generate_expression(top_k)?;
35433 }
35434 if let Some(dist_type) = &e.distance_type {
35435 self.write(", ");
35436 self.generate_expression(dist_type)?;
35437 }
35438 self.write(")");
35439 Ok(())
35440 }
35441
35442 fn generate_version(&mut self, e: &Version) -> Result<()> {
35443 use crate::dialects::DialectType;
35449 let skip_for = matches!(
35450 self.config.dialect,
35451 Some(DialectType::Hive) | Some(DialectType::Spark)
35452 );
35453 if !skip_for {
35454 self.write_keyword("FOR");
35455 self.write_space();
35456 }
35457 match e.this.as_ref() {
35459 Expression::Identifier(ident) => {
35460 self.write_keyword(&ident.name);
35461 }
35462 _ => {
35463 self.generate_expression(&e.this)?;
35464 }
35465 }
35466 self.write_space();
35467 self.write_keyword(&e.kind);
35468 if let Some(expression) = &e.expression {
35469 self.write_space();
35470 self.generate_expression(expression)?;
35471 }
35472 Ok(())
35473 }
35474
35475 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
35476 self.generate_expression(&e.this)?;
35478 Ok(())
35479 }
35480
35481 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
35482 if e.this.is_some() {
35484 self.write_keyword("NOT VOLATILE");
35485 } else {
35486 self.write_keyword("VOLATILE");
35487 }
35488 Ok(())
35489 }
35490
35491 fn generate_watermark_column_constraint(
35492 &mut self,
35493 e: &WatermarkColumnConstraint,
35494 ) -> Result<()> {
35495 self.write_keyword("WATERMARK FOR");
35497 self.write_space();
35498 self.generate_expression(&e.this)?;
35499 self.write_space();
35500 self.write_keyword("AS");
35501 self.write_space();
35502 self.generate_expression(&e.expression)?;
35503 Ok(())
35504 }
35505
35506 fn generate_week(&mut self, e: &Week) -> Result<()> {
35507 self.write_keyword("WEEK");
35509 self.write("(");
35510 self.generate_expression(&e.this)?;
35511 if let Some(mode) = &e.mode {
35512 self.write(", ");
35513 self.generate_expression(mode)?;
35514 }
35515 self.write(")");
35516 Ok(())
35517 }
35518
35519 fn generate_when(&mut self, e: &When) -> Result<()> {
35520 self.write_keyword("WHEN");
35524 self.write_space();
35525
35526 if let Some(matched) = &e.matched {
35528 match matched.as_ref() {
35530 Expression::Boolean(b) if b.value => {
35531 self.write_keyword("MATCHED");
35532 }
35533 _ => {
35534 self.write_keyword("NOT MATCHED");
35535 }
35536 }
35537 } else {
35538 self.write_keyword("NOT MATCHED");
35539 }
35540
35541 if self.config.matched_by_source {
35546 if let Some(source) = &e.source {
35547 if let Expression::Boolean(b) = source.as_ref() {
35548 if b.value {
35549 self.write_space();
35551 self.write_keyword("BY SOURCE");
35552 }
35553 } else {
35555 self.write_space();
35557 self.write_keyword("BY SOURCE");
35558 }
35559 }
35560 }
35561
35562 if let Some(condition) = &e.condition {
35564 self.write_space();
35565 self.write_keyword("AND");
35566 self.write_space();
35567 self.generate_expression(condition)?;
35568 }
35569
35570 self.write_space();
35571 self.write_keyword("THEN");
35572 self.write_space();
35573
35574 self.generate_merge_action(&e.then)?;
35577
35578 Ok(())
35579 }
35580
35581 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
35582 match action {
35583 Expression::Tuple(tuple) => {
35584 let elements = &tuple.expressions;
35585 if elements.is_empty() {
35586 return self.generate_expression(action);
35587 }
35588 match &elements[0] {
35590 Expression::Var(v) if v.this == "INSERT" => {
35591 self.write_keyword("INSERT");
35592 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
35594 self.write(" *");
35595 } else {
35596 let mut values_idx = 1;
35597 if elements.len() > 1 {
35599 if let Expression::Tuple(cols) = &elements[1] {
35600 if elements.len() > 2 {
35602 self.write(" (");
35604 for (i, col) in cols.expressions.iter().enumerate() {
35605 if i > 0 {
35606 self.write(", ");
35607 }
35608 if !self.merge_strip_qualifiers.is_empty() {
35610 let stripped = self.strip_merge_qualifier(col);
35611 self.generate_expression(&stripped)?;
35612 } else {
35613 self.generate_expression(col)?;
35614 }
35615 }
35616 self.write(")");
35617 values_idx = 2;
35618 } else {
35619 values_idx = 1;
35621 }
35622 }
35623 }
35624 if values_idx < elements.len() {
35626 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
35628 if !is_row {
35629 self.write_space();
35630 self.write_keyword("VALUES");
35631 }
35632 self.write(" ");
35633 if let Expression::Tuple(vals) = &elements[values_idx] {
35634 self.write("(");
35635 for (i, val) in vals.expressions.iter().enumerate() {
35636 if i > 0 {
35637 self.write(", ");
35638 }
35639 self.generate_expression(val)?;
35640 }
35641 self.write(")");
35642 } else {
35643 self.generate_expression(&elements[values_idx])?;
35644 }
35645 }
35646 } }
35648 Expression::Var(v) if v.this == "UPDATE" => {
35649 self.write_keyword("UPDATE");
35650 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
35652 self.write(" *");
35653 } else if elements.len() > 1 {
35654 self.write_space();
35655 self.write_keyword("SET");
35656 if self.config.pretty {
35658 self.write_newline();
35659 self.indent_level += 1;
35660 self.write_indent();
35661 } else {
35662 self.write_space();
35663 }
35664 if let Expression::Tuple(assignments) = &elements[1] {
35665 for (i, assignment) in assignments.expressions.iter().enumerate() {
35666 if i > 0 {
35667 if self.config.pretty {
35668 self.write(",");
35669 self.write_newline();
35670 self.write_indent();
35671 } else {
35672 self.write(", ");
35673 }
35674 }
35675 if !self.merge_strip_qualifiers.is_empty() {
35677 self.generate_merge_set_assignment(assignment)?;
35678 } else {
35679 self.generate_expression(assignment)?;
35680 }
35681 }
35682 } else {
35683 self.generate_expression(&elements[1])?;
35684 }
35685 if self.config.pretty {
35686 self.indent_level -= 1;
35687 }
35688 }
35689 }
35690 _ => {
35691 self.generate_expression(action)?;
35693 }
35694 }
35695 }
35696 Expression::Var(v)
35697 if v.this == "INSERT"
35698 || v.this == "UPDATE"
35699 || v.this == "DELETE"
35700 || v.this == "DO NOTHING" =>
35701 {
35702 self.write_keyword(&v.this);
35703 }
35704 _ => {
35705 self.generate_expression(action)?;
35706 }
35707 }
35708 Ok(())
35709 }
35710
35711 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
35713 match assignment {
35714 Expression::Eq(eq) => {
35715 let stripped_left = self.strip_merge_qualifier(&eq.left);
35717 self.generate_expression(&stripped_left)?;
35718 self.write(" = ");
35719 self.generate_expression(&eq.right)?;
35720 Ok(())
35721 }
35722 other => self.generate_expression(other),
35723 }
35724 }
35725
35726 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
35728 match expr {
35729 Expression::Column(col) => {
35730 if let Some(ref table_ident) = col.table {
35731 if self
35732 .merge_strip_qualifiers
35733 .iter()
35734 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
35735 {
35736 let mut col = col.clone();
35738 col.table = None;
35739 return Expression::Column(col);
35740 }
35741 }
35742 expr.clone()
35743 }
35744 Expression::Dot(dot) => {
35745 if let Expression::Identifier(id) = &dot.this {
35747 if self
35748 .merge_strip_qualifiers
35749 .iter()
35750 .any(|n| n.eq_ignore_ascii_case(&id.name))
35751 {
35752 return Expression::Identifier(dot.field.clone());
35753 }
35754 }
35755 expr.clone()
35756 }
35757 _ => expr.clone(),
35758 }
35759 }
35760
35761 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
35762 for (i, expr) in e.expressions.iter().enumerate() {
35764 if i > 0 {
35765 if self.config.pretty {
35767 self.write_newline();
35768 self.write_indent();
35769 } else {
35770 self.write_space();
35771 }
35772 }
35773 self.generate_expression(expr)?;
35774 }
35775 Ok(())
35776 }
35777
35778 fn generate_where(&mut self, e: &Where) -> Result<()> {
35779 self.write_keyword("WHERE");
35781 self.write_space();
35782 self.generate_expression(&e.this)?;
35783 Ok(())
35784 }
35785
35786 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
35787 self.write_keyword("WIDTH_BUCKET");
35789 self.write("(");
35790 self.generate_expression(&e.this)?;
35791 if let Some(min_value) = &e.min_value {
35792 self.write(", ");
35793 self.generate_expression(min_value)?;
35794 }
35795 if let Some(max_value) = &e.max_value {
35796 self.write(", ");
35797 self.generate_expression(max_value)?;
35798 }
35799 if let Some(num_buckets) = &e.num_buckets {
35800 self.write(", ");
35801 self.generate_expression(num_buckets)?;
35802 }
35803 self.write(")");
35804 Ok(())
35805 }
35806
35807 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
35808 self.generate_window_spec(e)
35810 }
35811
35812 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
35813 let mut has_content = false;
35815
35816 if !e.partition_by.is_empty() {
35818 self.write_keyword("PARTITION BY");
35819 self.write_space();
35820 for (i, expr) in e.partition_by.iter().enumerate() {
35821 if i > 0 {
35822 self.write(", ");
35823 }
35824 self.generate_expression(expr)?;
35825 }
35826 has_content = true;
35827 }
35828
35829 if !e.order_by.is_empty() {
35831 if has_content {
35832 self.write_space();
35833 }
35834 self.write_keyword("ORDER BY");
35835 self.write_space();
35836 for (i, ordered) in e.order_by.iter().enumerate() {
35837 if i > 0 {
35838 self.write(", ");
35839 }
35840 self.generate_expression(&ordered.this)?;
35841 if ordered.desc {
35842 self.write_space();
35843 self.write_keyword("DESC");
35844 } else if ordered.explicit_asc {
35845 self.write_space();
35846 self.write_keyword("ASC");
35847 }
35848 if let Some(nulls_first) = ordered.nulls_first {
35849 self.write_space();
35850 self.write_keyword("NULLS");
35851 self.write_space();
35852 if nulls_first {
35853 self.write_keyword("FIRST");
35854 } else {
35855 self.write_keyword("LAST");
35856 }
35857 }
35858 }
35859 has_content = true;
35860 }
35861
35862 if let Some(frame) = &e.frame {
35864 if has_content {
35865 self.write_space();
35866 }
35867 self.generate_window_frame(frame)?;
35868 }
35869
35870 Ok(())
35871 }
35872
35873 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
35874 self.write_keyword("WITH");
35876 self.write_space();
35877 if e.no.is_some() {
35878 self.write_keyword("NO");
35879 self.write_space();
35880 }
35881 self.write_keyword("DATA");
35882
35883 if let Some(statistics) = &e.statistics {
35885 self.write_space();
35886 self.write_keyword("AND");
35887 self.write_space();
35888 match statistics.as_ref() {
35890 Expression::Boolean(b) if !b.value => {
35891 self.write_keyword("NO");
35892 self.write_space();
35893 }
35894 _ => {}
35895 }
35896 self.write_keyword("STATISTICS");
35897 }
35898 Ok(())
35899 }
35900
35901 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
35902 self.write_keyword("WITH FILL");
35904
35905 if let Some(from_) = &e.from_ {
35906 self.write_space();
35907 self.write_keyword("FROM");
35908 self.write_space();
35909 self.generate_expression(from_)?;
35910 }
35911
35912 if let Some(to) = &e.to {
35913 self.write_space();
35914 self.write_keyword("TO");
35915 self.write_space();
35916 self.generate_expression(to)?;
35917 }
35918
35919 if let Some(step) = &e.step {
35920 self.write_space();
35921 self.write_keyword("STEP");
35922 self.write_space();
35923 self.generate_expression(step)?;
35924 }
35925
35926 if let Some(staleness) = &e.staleness {
35927 self.write_space();
35928 self.write_keyword("STALENESS");
35929 self.write_space();
35930 self.generate_expression(staleness)?;
35931 }
35932
35933 if let Some(interpolate) = &e.interpolate {
35934 self.write_space();
35935 self.write_keyword("INTERPOLATE");
35936 self.write(" (");
35937 self.generate_interpolate_item(interpolate)?;
35939 self.write(")");
35940 }
35941
35942 Ok(())
35943 }
35944
35945 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
35947 match expr {
35948 Expression::Alias(alias) => {
35949 self.generate_identifier(&alias.alias)?;
35951 self.write_space();
35952 self.write_keyword("AS");
35953 self.write_space();
35954 self.generate_expression(&alias.this)?;
35955 }
35956 Expression::Tuple(tuple) => {
35957 for (i, item) in tuple.expressions.iter().enumerate() {
35958 if i > 0 {
35959 self.write(", ");
35960 }
35961 self.generate_interpolate_item(item)?;
35962 }
35963 }
35964 other => {
35965 self.generate_expression(other)?;
35966 }
35967 }
35968 Ok(())
35969 }
35970
35971 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
35972 self.write_keyword("WITH JOURNAL TABLE");
35974 self.write("=");
35975 self.generate_expression(&e.this)?;
35976 Ok(())
35977 }
35978
35979 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
35980 self.generate_expression(&e.this)?;
35982 self.write_space();
35983 self.write_keyword("WITH");
35984 self.write_space();
35985 self.write_keyword(&e.op);
35986 Ok(())
35987 }
35988
35989 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
35990 self.write_keyword("WITH");
35992 self.write_space();
35993 for (i, expr) in e.expressions.iter().enumerate() {
35994 if i > 0 {
35995 self.write(", ");
35996 }
35997 self.generate_expression(expr)?;
35998 }
35999 Ok(())
36000 }
36001
36002 fn generate_with_schema_binding_property(
36003 &mut self,
36004 e: &WithSchemaBindingProperty,
36005 ) -> Result<()> {
36006 self.write_keyword("WITH");
36008 self.write_space();
36009 self.generate_expression(&e.this)?;
36010 Ok(())
36011 }
36012
36013 fn generate_with_system_versioning_property(
36014 &mut self,
36015 e: &WithSystemVersioningProperty,
36016 ) -> Result<()> {
36017 let mut parts = Vec::new();
36023
36024 if let Some(this) = &e.this {
36025 let mut s = String::from("HISTORY_TABLE=");
36027 let mut gen = Generator::new();
36028 gen.generate_expression(this)?;
36029 s.push_str(&gen.output);
36030 parts.push(s);
36031 }
36032
36033 if let Some(data_consistency) = &e.data_consistency {
36034 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
36035 let mut gen = Generator::new();
36036 gen.generate_expression(data_consistency)?;
36037 s.push_str(&gen.output);
36038 parts.push(s);
36039 }
36040
36041 if let Some(retention_period) = &e.retention_period {
36042 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
36043 let mut gen = Generator::new();
36044 gen.generate_expression(retention_period)?;
36045 s.push_str(&gen.output);
36046 parts.push(s);
36047 }
36048
36049 self.write_keyword("SYSTEM_VERSIONING");
36050 self.write("=");
36051
36052 if !parts.is_empty() {
36053 self.write_keyword("ON");
36054 self.write("(");
36055 self.write(&parts.join(", "));
36056 self.write(")");
36057 } else if e.on.is_some() {
36058 self.write_keyword("ON");
36059 } else {
36060 self.write_keyword("OFF");
36061 }
36062
36063 if e.with_.is_some() {
36065 let inner = self.output.clone();
36066 self.output.clear();
36067 self.write("WITH(");
36068 self.write(&inner);
36069 self.write(")");
36070 }
36071
36072 Ok(())
36073 }
36074
36075 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
36076 self.write_keyword("WITH");
36078 self.write(" (");
36079 for (i, expr) in e.expressions.iter().enumerate() {
36080 if i > 0 {
36081 self.write(", ");
36082 }
36083 self.generate_expression(expr)?;
36084 }
36085 self.write(")");
36086 Ok(())
36087 }
36088
36089 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
36090 self.write_keyword("XMLELEMENT");
36093 self.write("(");
36094
36095 if e.evalname.is_some() {
36096 self.write_keyword("EVALNAME");
36097 } else {
36098 self.write_keyword("NAME");
36099 }
36100 self.write_space();
36101 self.generate_expression(&e.this)?;
36102
36103 for expr in &e.expressions {
36104 self.write(", ");
36105 self.generate_expression(expr)?;
36106 }
36107 self.write(")");
36108 Ok(())
36109 }
36110
36111 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
36112 self.write_keyword("XMLGET");
36114 self.write("(");
36115 self.generate_expression(&e.this)?;
36116 self.write(", ");
36117 self.generate_expression(&e.expression)?;
36118 if let Some(instance) = &e.instance {
36119 self.write(", ");
36120 self.generate_expression(instance)?;
36121 }
36122 self.write(")");
36123 Ok(())
36124 }
36125
36126 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
36127 self.generate_expression(&e.this)?;
36129 if let Some(expression) = &e.expression {
36130 self.write("(");
36131 self.generate_expression(expression)?;
36132 self.write(")");
36133 }
36134 Ok(())
36135 }
36136
36137 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
36138 self.write_keyword("XMLTABLE");
36140 self.write("(");
36141
36142 if self.config.pretty {
36143 self.indent_level += 1;
36144 self.write_newline();
36145 self.write_indent();
36146 self.generate_expression(&e.this)?;
36147
36148 if let Some(passing) = &e.passing {
36149 self.write_newline();
36150 self.write_indent();
36151 self.write_keyword("PASSING");
36152 if let Expression::Tuple(tuple) = passing.as_ref() {
36153 for expr in &tuple.expressions {
36154 self.write_newline();
36155 self.indent_level += 1;
36156 self.write_indent();
36157 self.generate_expression(expr)?;
36158 self.indent_level -= 1;
36159 }
36160 } else {
36161 self.write_newline();
36162 self.indent_level += 1;
36163 self.write_indent();
36164 self.generate_expression(passing)?;
36165 self.indent_level -= 1;
36166 }
36167 }
36168
36169 if e.by_ref.is_some() {
36170 self.write_newline();
36171 self.write_indent();
36172 self.write_keyword("RETURNING SEQUENCE BY REF");
36173 }
36174
36175 if !e.columns.is_empty() {
36176 self.write_newline();
36177 self.write_indent();
36178 self.write_keyword("COLUMNS");
36179 for (i, col) in e.columns.iter().enumerate() {
36180 self.write_newline();
36181 self.indent_level += 1;
36182 self.write_indent();
36183 self.generate_expression(col)?;
36184 self.indent_level -= 1;
36185 if i < e.columns.len() - 1 {
36186 self.write(",");
36187 }
36188 }
36189 }
36190
36191 self.indent_level -= 1;
36192 self.write_newline();
36193 self.write_indent();
36194 self.write(")");
36195 return Ok(());
36196 }
36197
36198 if let Some(namespaces) = &e.namespaces {
36200 self.write_keyword("XMLNAMESPACES");
36201 self.write("(");
36202 if let Expression::Tuple(tuple) = namespaces.as_ref() {
36204 for (i, expr) in tuple.expressions.iter().enumerate() {
36205 if i > 0 {
36206 self.write(", ");
36207 }
36208 if !matches!(expr, Expression::Alias(_)) {
36211 self.write_keyword("DEFAULT");
36212 self.write_space();
36213 }
36214 self.generate_expression(expr)?;
36215 }
36216 } else {
36217 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
36219 self.write_keyword("DEFAULT");
36220 self.write_space();
36221 }
36222 self.generate_expression(namespaces)?;
36223 }
36224 self.write("), ");
36225 }
36226
36227 self.generate_expression(&e.this)?;
36229
36230 if let Some(passing) = &e.passing {
36232 self.write_space();
36233 self.write_keyword("PASSING");
36234 self.write_space();
36235 if let Expression::Tuple(tuple) = passing.as_ref() {
36237 for (i, expr) in tuple.expressions.iter().enumerate() {
36238 if i > 0 {
36239 self.write(", ");
36240 }
36241 self.generate_expression(expr)?;
36242 }
36243 } else {
36244 self.generate_expression(passing)?;
36245 }
36246 }
36247
36248 if e.by_ref.is_some() {
36250 self.write_space();
36251 self.write_keyword("RETURNING SEQUENCE BY REF");
36252 }
36253
36254 if !e.columns.is_empty() {
36256 self.write_space();
36257 self.write_keyword("COLUMNS");
36258 self.write_space();
36259 for (i, col) in e.columns.iter().enumerate() {
36260 if i > 0 {
36261 self.write(", ");
36262 }
36263 self.generate_expression(col)?;
36264 }
36265 }
36266
36267 self.write(")");
36268 Ok(())
36269 }
36270
36271 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
36272 if let Some(this) = &e.this {
36275 self.generate_expression(this)?;
36276 if let Some(expression) = &e.expression {
36277 self.write_space();
36278 self.write_keyword("XOR");
36279 self.write_space();
36280 self.generate_expression(expression)?;
36281 }
36282 }
36283
36284 for (i, expr) in e.expressions.iter().enumerate() {
36286 if i > 0 || e.this.is_some() {
36287 self.write_space();
36288 self.write_keyword("XOR");
36289 self.write_space();
36290 }
36291 self.generate_expression(expr)?;
36292 }
36293 Ok(())
36294 }
36295
36296 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
36297 self.write_keyword("ZIPF");
36299 self.write("(");
36300 self.generate_expression(&e.this)?;
36301 if let Some(elementcount) = &e.elementcount {
36302 self.write(", ");
36303 self.generate_expression(elementcount)?;
36304 }
36305 if let Some(gen) = &e.gen {
36306 self.write(", ");
36307 self.generate_expression(gen)?;
36308 }
36309 self.write(")");
36310 Ok(())
36311 }
36312}
36313
36314impl Default for Generator {
36315 fn default() -> Self {
36316 Self::new()
36317 }
36318}
36319
36320#[cfg(test)]
36321mod tests {
36322 use super::*;
36323 use crate::parser::Parser;
36324
36325 fn roundtrip(sql: &str) -> String {
36326 let ast = Parser::parse_sql(sql).unwrap();
36327 Generator::sql(&ast[0]).unwrap()
36328 }
36329
36330 #[test]
36331 fn test_simple_select() {
36332 let result = roundtrip("SELECT 1");
36333 assert_eq!(result, "SELECT 1");
36334 }
36335
36336 #[test]
36337 fn test_select_from() {
36338 let result = roundtrip("SELECT a, b FROM t");
36339 assert_eq!(result, "SELECT a, b FROM t");
36340 }
36341
36342 #[test]
36343 fn test_select_where() {
36344 let result = roundtrip("SELECT * FROM t WHERE x = 1");
36345 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
36346 }
36347
36348 #[test]
36349 fn test_select_join() {
36350 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
36351 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
36352 }
36353
36354 #[test]
36355 fn test_insert() {
36356 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
36357 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
36358 }
36359
36360 #[test]
36361 fn test_pretty_print() {
36362 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
36363 let result = Generator::pretty_sql(&ast[0]).unwrap();
36364 assert!(result.contains('\n'));
36365 }
36366
36367 #[test]
36368 fn test_window_function() {
36369 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
36370 assert_eq!(
36371 result,
36372 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
36373 );
36374 }
36375
36376 #[test]
36377 fn test_window_function_with_frame() {
36378 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
36379 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
36380 }
36381
36382 #[test]
36383 fn test_aggregate_with_filter() {
36384 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
36385 assert_eq!(
36386 result,
36387 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
36388 );
36389 }
36390
36391 #[test]
36392 fn test_subscript() {
36393 let result = roundtrip("SELECT arr[0]");
36394 assert_eq!(result, "SELECT arr[0]");
36395 }
36396
36397 #[test]
36399 fn test_create_table() {
36400 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
36401 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
36402 }
36403
36404 #[test]
36405 fn test_create_table_with_constraints() {
36406 let result = roundtrip(
36407 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
36408 );
36409 assert_eq!(
36410 result,
36411 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
36412 );
36413 }
36414
36415 #[test]
36416 fn test_create_table_if_not_exists() {
36417 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
36418 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
36419 }
36420
36421 #[test]
36422 fn test_drop_table() {
36423 let result = roundtrip("DROP TABLE users");
36424 assert_eq!(result, "DROP TABLE users");
36425 }
36426
36427 #[test]
36428 fn test_drop_table_if_exists_cascade() {
36429 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
36430 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
36431 }
36432
36433 #[test]
36434 fn test_alter_table_add_column() {
36435 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
36436 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
36437 }
36438
36439 #[test]
36440 fn test_alter_table_drop_column() {
36441 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
36442 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
36443 }
36444
36445 #[test]
36446 fn test_create_index() {
36447 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
36448 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
36449 }
36450
36451 #[test]
36452 fn test_create_unique_index() {
36453 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
36454 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
36455 }
36456
36457 #[test]
36458 fn test_drop_index() {
36459 let result = roundtrip("DROP INDEX idx_name");
36460 assert_eq!(result, "DROP INDEX idx_name");
36461 }
36462
36463 #[test]
36464 fn test_create_view() {
36465 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
36466 assert_eq!(
36467 result,
36468 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
36469 );
36470 }
36471
36472 #[test]
36473 fn test_drop_view() {
36474 let result = roundtrip("DROP VIEW active_users");
36475 assert_eq!(result, "DROP VIEW active_users");
36476 }
36477
36478 #[test]
36479 fn test_truncate() {
36480 let result = roundtrip("TRUNCATE TABLE users");
36481 assert_eq!(result, "TRUNCATE TABLE users");
36482 }
36483
36484 #[test]
36485 fn test_string_literal_escaping_default() {
36486 let result = roundtrip("SELECT 'hello'");
36488 assert_eq!(result, "SELECT 'hello'");
36489
36490 let result = roundtrip("SELECT 'it''s a test'");
36492 assert_eq!(result, "SELECT 'it''s a test'");
36493 }
36494
36495 #[test]
36496 fn test_not_in_style_prefix_default_generic() {
36497 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
36498 assert_eq!(
36499 result,
36500 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
36501 );
36502 }
36503
36504 #[test]
36505 fn test_not_in_style_infix_generic_override() {
36506 let ast =
36507 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
36508 .unwrap();
36509 let config = GeneratorConfig {
36510 not_in_style: NotInStyle::Infix,
36511 ..Default::default()
36512 };
36513 let mut gen = Generator::with_config(config);
36514 let result = gen.generate(&ast[0]).unwrap();
36515 assert_eq!(
36516 result,
36517 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
36518 );
36519 }
36520
36521 #[test]
36522 fn test_string_literal_escaping_mysql() {
36523 use crate::dialects::DialectType;
36524
36525 let config = GeneratorConfig {
36526 dialect: Some(DialectType::MySQL),
36527 ..Default::default()
36528 };
36529
36530 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36531 let mut gen = Generator::with_config(config.clone());
36532 let result = gen.generate(&ast[0]).unwrap();
36533 assert_eq!(result, "SELECT 'hello'");
36534
36535 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36537 let mut gen = Generator::with_config(config.clone());
36538 let result = gen.generate(&ast[0]).unwrap();
36539 assert_eq!(result, "SELECT 'it''s'");
36540 }
36541
36542 #[test]
36543 fn test_string_literal_escaping_postgres() {
36544 use crate::dialects::DialectType;
36545
36546 let config = GeneratorConfig {
36547 dialect: Some(DialectType::PostgreSQL),
36548 ..Default::default()
36549 };
36550
36551 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36552 let mut gen = Generator::with_config(config.clone());
36553 let result = gen.generate(&ast[0]).unwrap();
36554 assert_eq!(result, "SELECT 'hello'");
36555
36556 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36558 let mut gen = Generator::with_config(config.clone());
36559 let result = gen.generate(&ast[0]).unwrap();
36560 assert_eq!(result, "SELECT 'it''s'");
36561 }
36562
36563 #[test]
36564 fn test_string_literal_escaping_bigquery() {
36565 use crate::dialects::DialectType;
36566
36567 let config = GeneratorConfig {
36568 dialect: Some(DialectType::BigQuery),
36569 ..Default::default()
36570 };
36571
36572 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36573 let mut gen = Generator::with_config(config.clone());
36574 let result = gen.generate(&ast[0]).unwrap();
36575 assert_eq!(result, "SELECT 'hello'");
36576
36577 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36579 let mut gen = Generator::with_config(config.clone());
36580 let result = gen.generate(&ast[0]).unwrap();
36581 assert_eq!(result, "SELECT 'it\\'s'");
36582 }
36583}