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
3899 if select.distinct && (is_top_dialect || select.top.is_some()) {
3900 self.write_space();
3901 self.write_keyword("DISTINCT");
3902 }
3903
3904 if is_top_dialect {
3905 if let Some(top) = &select.top {
3906 self.write_space();
3907 self.write_keyword("TOP");
3908 if top.parenthesized {
3909 self.write(" (");
3910 self.generate_expression(&top.this)?;
3911 self.write(")");
3912 } else {
3913 self.write_space();
3914 self.generate_expression(&top.this)?;
3915 }
3916 if top.percent {
3917 self.write_space();
3918 self.write_keyword("PERCENT");
3919 }
3920 if top.with_ties {
3921 self.write_space();
3922 self.write_keyword("WITH TIES");
3923 }
3924 } else if use_top_from_limit {
3925 if let Some(limit) = &select.limit {
3927 self.write_space();
3928 self.write_keyword("TOP");
3929 let is_simple_literal =
3931 matches!(&limit.this, Expression::Literal(Literal::Number(_)));
3932 if is_simple_literal {
3933 self.write_space();
3934 self.generate_expression(&limit.this)?;
3935 } else {
3936 self.write(" (");
3937 self.generate_expression(&limit.this)?;
3938 self.write(")");
3939 }
3940 }
3941 }
3942 }
3943
3944 if select.distinct && !is_top_dialect && select.top.is_none() {
3945 self.write_space();
3946 self.write_keyword("DISTINCT");
3947 }
3948
3949 if let Some(distinct_on) = &select.distinct_on {
3951 self.write_space();
3952 self.write_keyword("ON");
3953 self.write(" (");
3954 for (i, expr) in distinct_on.iter().enumerate() {
3955 if i > 0 {
3956 self.write(", ");
3957 }
3958 self.generate_expression(expr)?;
3959 }
3960 self.write(")");
3961 }
3962
3963 for modifier in &select.operation_modifiers {
3965 self.write_space();
3966 self.write_keyword(modifier);
3967 }
3968
3969 if let Some(kind) = &select.kind {
3971 self.write_space();
3972 self.write_keyword("AS");
3973 self.write_space();
3974 self.write_keyword(kind);
3975 }
3976
3977 if !select.expressions.is_empty() {
3979 if self.config.pretty {
3980 self.write_newline();
3981 self.indent_level += 1;
3982 } else {
3983 self.write_space();
3984 }
3985 }
3986
3987 for (i, expr) in select.expressions.iter().enumerate() {
3988 if i > 0 {
3989 self.write(",");
3990 if self.config.pretty {
3991 self.write_newline();
3992 } else {
3993 self.write_space();
3994 }
3995 }
3996 if self.config.pretty {
3997 self.write_indent();
3998 }
3999 self.generate_expression(expr)?;
4000 }
4001
4002 if self.config.pretty && !select.expressions.is_empty() {
4003 self.indent_level -= 1;
4004 }
4005
4006 if let Some(into) = &select.into {
4009 if self.config.pretty {
4010 self.write_newline();
4011 self.write_indent();
4012 } else {
4013 self.write_space();
4014 }
4015 if into.bulk_collect {
4016 self.write_keyword("BULK COLLECT INTO");
4017 } else {
4018 self.write_keyword("INTO");
4019 }
4020 if into.temporary {
4021 self.write_space();
4022 self.write_keyword("TEMPORARY");
4023 }
4024 if into.unlogged {
4025 self.write_space();
4026 self.write_keyword("UNLOGGED");
4027 }
4028 self.write_space();
4029 if !into.expressions.is_empty() {
4031 for (i, expr) in into.expressions.iter().enumerate() {
4032 if i > 0 {
4033 self.write(", ");
4034 }
4035 self.generate_expression(expr)?;
4036 }
4037 } else {
4038 self.generate_expression(&into.this)?;
4039 }
4040 }
4041
4042 if let Some(from) = &select.from {
4044 if self.config.pretty {
4045 self.write_newline();
4046 self.write_indent();
4047 } else {
4048 self.write_space();
4049 }
4050 self.write_keyword("FROM");
4051 self.write_space();
4052
4053 let has_tablesample = from
4058 .expressions
4059 .iter()
4060 .any(|e| matches!(e, Expression::TableSample(_)));
4061 let is_cross_join_dialect = matches!(
4062 self.config.dialect,
4063 Some(DialectType::BigQuery)
4064 | Some(DialectType::Hive)
4065 | Some(DialectType::Spark)
4066 | Some(DialectType::Databricks)
4067 | Some(DialectType::SQLite)
4068 | Some(DialectType::ClickHouse)
4069 );
4070 let source_is_same_as_target = self.config.source_dialect.is_some()
4073 && self.config.source_dialect == self.config.dialect;
4074 let source_is_cross_join_dialect = matches!(
4075 self.config.source_dialect,
4076 Some(DialectType::BigQuery)
4077 | Some(DialectType::Hive)
4078 | Some(DialectType::Spark)
4079 | Some(DialectType::Databricks)
4080 | Some(DialectType::SQLite)
4081 | Some(DialectType::ClickHouse)
4082 );
4083 let use_cross_join = !has_tablesample
4084 && is_cross_join_dialect
4085 && (source_is_same_as_target
4086 || source_is_cross_join_dialect
4087 || self.config.source_dialect.is_none());
4088
4089 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4091
4092 for (i, expr) in from.expressions.iter().enumerate() {
4093 if i > 0 {
4094 if use_cross_join {
4095 self.write(" CROSS JOIN ");
4096 } else {
4097 self.write(", ");
4098 }
4099 }
4100 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4101 self.write("(");
4102 self.generate_expression(expr)?;
4103 self.write(")");
4104 } else {
4105 self.generate_expression(expr)?;
4106 }
4107 }
4108 }
4109
4110 if self.config.pretty {
4114 self.generate_joins_with_nesting(&select.joins)?;
4115 } else {
4116 for join in &select.joins {
4117 self.generate_join(join)?;
4118 }
4119 for join in select.joins.iter().rev() {
4121 if join.deferred_condition {
4122 self.generate_join_condition(join)?;
4123 }
4124 }
4125 }
4126
4127 for lateral_view in &select.lateral_views {
4129 self.generate_lateral_view(lateral_view)?;
4130 }
4131
4132 if let Some(prewhere) = &select.prewhere {
4134 self.write_clause_condition("PREWHERE", prewhere)?;
4135 }
4136
4137 if let Some(where_clause) = &select.where_clause {
4139 self.write_clause_condition("WHERE", &where_clause.this)?;
4140 }
4141
4142 if let Some(connect) = &select.connect {
4144 self.generate_connect(connect)?;
4145 }
4146
4147 if let Some(group_by) = &select.group_by {
4149 if self.config.pretty {
4150 for comment in &group_by.comments {
4152 self.write_newline();
4153 self.write_indent();
4154 self.write_formatted_comment(comment);
4155 }
4156 self.write_newline();
4157 self.write_indent();
4158 } else {
4159 self.write_space();
4160 for comment in &group_by.comments {
4162 self.write_formatted_comment(comment);
4163 self.write_space();
4164 }
4165 }
4166 self.write_keyword("GROUP BY");
4167 match group_by.all {
4169 Some(true) => {
4170 self.write_space();
4171 self.write_keyword("ALL");
4172 }
4173 Some(false) => {
4174 self.write_space();
4175 self.write_keyword("DISTINCT");
4176 }
4177 None => {}
4178 }
4179 if !group_by.expressions.is_empty() {
4180 let mut trailing_cube = false;
4183 let mut trailing_rollup = false;
4184 let mut plain_expressions: Vec<&Expression> = Vec::new();
4185 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4186 let mut cube_expressions: Vec<&Expression> = Vec::new();
4187 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4188
4189 for expr in &group_by.expressions {
4190 match expr {
4191 Expression::Cube(c) if c.expressions.is_empty() => {
4192 trailing_cube = true;
4193 }
4194 Expression::Rollup(r) if r.expressions.is_empty() => {
4195 trailing_rollup = true;
4196 }
4197 Expression::Function(f) if f.name == "CUBE" => {
4198 cube_expressions.push(expr);
4199 }
4200 Expression::Function(f) if f.name == "ROLLUP" => {
4201 rollup_expressions.push(expr);
4202 }
4203 Expression::Function(f) if f.name == "GROUPING SETS" => {
4204 grouping_sets_expressions.push(expr);
4205 }
4206 _ => {
4207 plain_expressions.push(expr);
4208 }
4209 }
4210 }
4211
4212 let mut regular_expressions: Vec<&Expression> = Vec::new();
4214 regular_expressions.extend(plain_expressions);
4215 regular_expressions.extend(grouping_sets_expressions);
4216 regular_expressions.extend(cube_expressions);
4217 regular_expressions.extend(rollup_expressions);
4218
4219 if self.config.pretty {
4220 self.write_newline();
4221 self.indent_level += 1;
4222 self.write_indent();
4223 } else {
4224 self.write_space();
4225 }
4226
4227 for (i, expr) in regular_expressions.iter().enumerate() {
4228 if i > 0 {
4229 if self.config.pretty {
4230 self.write(",");
4231 self.write_newline();
4232 self.write_indent();
4233 } else {
4234 self.write(", ");
4235 }
4236 }
4237 self.generate_expression(expr)?;
4238 }
4239
4240 if self.config.pretty {
4241 self.indent_level -= 1;
4242 }
4243
4244 if trailing_cube {
4246 self.write_space();
4247 self.write_keyword("WITH CUBE");
4248 } else if trailing_rollup {
4249 self.write_space();
4250 self.write_keyword("WITH ROLLUP");
4251 }
4252 }
4253
4254 if group_by.totals {
4256 self.write_space();
4257 self.write_keyword("WITH TOTALS");
4258 }
4259 }
4260
4261 if let Some(having) = &select.having {
4263 if self.config.pretty {
4264 for comment in &having.comments {
4266 self.write_newline();
4267 self.write_indent();
4268 self.write_formatted_comment(comment);
4269 }
4270 } else {
4271 for comment in &having.comments {
4272 self.write_space();
4273 self.write_formatted_comment(comment);
4274 }
4275 }
4276 self.write_clause_condition("HAVING", &having.this)?;
4277 }
4278
4279 if select.qualify_after_window {
4281 if let Some(windows) = &select.windows {
4283 self.write_window_clause(windows)?;
4284 }
4285 if let Some(qualify) = &select.qualify {
4286 self.write_clause_condition("QUALIFY", &qualify.this)?;
4287 }
4288 } else {
4289 if let Some(qualify) = &select.qualify {
4291 self.write_clause_condition("QUALIFY", &qualify.this)?;
4292 }
4293 if let Some(windows) = &select.windows {
4294 self.write_window_clause(windows)?;
4295 }
4296 }
4297
4298 if let Some(distribute_by) = &select.distribute_by {
4300 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4301 }
4302
4303 if let Some(cluster_by) = &select.cluster_by {
4305 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4306 }
4307
4308 if let Some(sort_by) = &select.sort_by {
4310 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4311 }
4312
4313 if let Some(order_by) = &select.order_by {
4315 if self.config.pretty {
4316 for comment in &order_by.comments {
4318 self.write_newline();
4319 self.write_indent();
4320 self.write_formatted_comment(comment);
4321 }
4322 } else {
4323 for comment in &order_by.comments {
4324 self.write_space();
4325 self.write_formatted_comment(comment);
4326 }
4327 }
4328 let keyword = if order_by.siblings {
4329 "ORDER SIBLINGS BY"
4330 } else {
4331 "ORDER BY"
4332 };
4333 self.write_order_clause(keyword, &order_by.expressions)?;
4334 }
4335
4336 if select.order_by.is_none()
4338 && select.fetch.is_some()
4339 && matches!(
4340 self.config.dialect,
4341 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4342 )
4343 {
4344 if self.config.pretty {
4345 self.write_newline();
4346 self.write_indent();
4347 } else {
4348 self.write_space();
4349 }
4350 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4351 }
4352
4353 let is_presto_like = matches!(
4358 self.config.dialect,
4359 Some(DialectType::Presto) | Some(DialectType::Trino)
4360 );
4361
4362 if is_presto_like && select.offset.is_some() {
4363 if let Some(offset) = &select.offset {
4365 if self.config.pretty {
4366 self.write_newline();
4367 self.write_indent();
4368 } else {
4369 self.write_space();
4370 }
4371 self.write_keyword("OFFSET");
4372 self.write_space();
4373 self.write_limit_expr(&offset.this)?;
4374 if offset.rows == Some(true) {
4375 self.write_space();
4376 self.write_keyword("ROWS");
4377 }
4378 }
4379 if let Some(limit) = &select.limit {
4380 if self.config.pretty {
4381 self.write_newline();
4382 self.write_indent();
4383 } else {
4384 self.write_space();
4385 }
4386 self.write_keyword("LIMIT");
4387 self.write_space();
4388 self.write_limit_expr(&limit.this)?;
4389 if limit.percent {
4390 self.write_space();
4391 self.write_keyword("PERCENT");
4392 }
4393 for comment in &limit.comments {
4395 self.write(" ");
4396 self.write_formatted_comment(comment);
4397 }
4398 }
4399 } else {
4400 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
4402 !fetch.percent
4403 && !fetch.with_ties
4404 && fetch.count.is_some()
4405 && matches!(
4406 self.config.dialect,
4407 Some(DialectType::Spark)
4408 | Some(DialectType::Hive)
4409 | Some(DialectType::DuckDB)
4410 | Some(DialectType::SQLite)
4411 | Some(DialectType::MySQL)
4412 | Some(DialectType::BigQuery)
4413 | Some(DialectType::Databricks)
4414 | Some(DialectType::StarRocks)
4415 | Some(DialectType::Doris)
4416 | Some(DialectType::Athena)
4417 | Some(DialectType::ClickHouse)
4418 | Some(DialectType::Redshift)
4419 )
4420 });
4421
4422 if let Some(limit) = &select.limit {
4424 if !matches!(self.config.dialect, Some(DialectType::TSQL)) {
4426 if self.config.pretty {
4427 self.write_newline();
4428 self.write_indent();
4429 } else {
4430 self.write_space();
4431 }
4432 self.write_keyword("LIMIT");
4433 self.write_space();
4434 self.write_limit_expr(&limit.this)?;
4435 if limit.percent {
4436 self.write_space();
4437 self.write_keyword("PERCENT");
4438 }
4439 for comment in &limit.comments {
4441 self.write(" ");
4442 self.write_formatted_comment(comment);
4443 }
4444 }
4445 }
4446
4447 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
4449 if let Some(top) = &select.top {
4450 if !top.percent && !top.with_ties {
4451 if self.config.pretty {
4452 self.write_newline();
4453 self.write_indent();
4454 } else {
4455 self.write_space();
4456 }
4457 self.write_keyword("LIMIT");
4458 self.write_space();
4459 self.generate_expression(&top.this)?;
4460 }
4461 }
4462 }
4463
4464 if fetch_as_limit && select.offset.is_some() {
4467 if let Some(fetch) = &select.fetch {
4468 if self.config.pretty {
4469 self.write_newline();
4470 self.write_indent();
4471 } else {
4472 self.write_space();
4473 }
4474 self.write_keyword("LIMIT");
4475 self.write_space();
4476 self.generate_expression(fetch.count.as_ref().unwrap())?;
4477 }
4478 }
4479
4480 if let Some(offset) = &select.offset {
4484 if self.config.pretty {
4485 self.write_newline();
4486 self.write_indent();
4487 } else {
4488 self.write_space();
4489 }
4490 if matches!(self.config.dialect, Some(DialectType::TSQL)) {
4491 self.write_keyword("OFFSET");
4493 self.write_space();
4494 self.write_limit_expr(&offset.this)?;
4495 self.write_space();
4496 self.write_keyword("ROWS");
4497 if let Some(limit) = &select.limit {
4499 self.write_space();
4500 self.write_keyword("FETCH NEXT");
4501 self.write_space();
4502 self.write_limit_expr(&limit.this)?;
4503 self.write_space();
4504 self.write_keyword("ROWS ONLY");
4505 }
4506 } else {
4507 self.write_keyword("OFFSET");
4508 self.write_space();
4509 self.write_limit_expr(&offset.this)?;
4510 if offset.rows == Some(true) {
4512 self.write_space();
4513 self.write_keyword("ROWS");
4514 }
4515 }
4516 }
4517 }
4518
4519 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4521 if let Some(limit_by) = &select.limit_by {
4522 if !limit_by.is_empty() {
4523 self.write_space();
4524 self.write_keyword("BY");
4525 self.write_space();
4526 for (i, expr) in limit_by.iter().enumerate() {
4527 if i > 0 {
4528 self.write(", ");
4529 }
4530 self.generate_expression(expr)?;
4531 }
4532 }
4533 }
4534 }
4535
4536 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4538 if let Some(settings) = &select.settings {
4539 if self.config.pretty {
4540 self.write_newline();
4541 self.write_indent();
4542 } else {
4543 self.write_space();
4544 }
4545 self.write_keyword("SETTINGS");
4546 self.write_space();
4547 for (i, expr) in settings.iter().enumerate() {
4548 if i > 0 {
4549 self.write(", ");
4550 }
4551 self.generate_expression(expr)?;
4552 }
4553 }
4554
4555 if let Some(format_expr) = &select.format {
4556 if self.config.pretty {
4557 self.write_newline();
4558 self.write_indent();
4559 } else {
4560 self.write_space();
4561 }
4562 self.write_keyword("FORMAT");
4563 self.write_space();
4564 self.generate_expression(format_expr)?;
4565 }
4566 }
4567
4568 if let Some(fetch) = &select.fetch {
4570 let fetch_already_as_limit = select.offset.is_some()
4572 && !fetch.percent
4573 && !fetch.with_ties
4574 && fetch.count.is_some()
4575 && matches!(
4576 self.config.dialect,
4577 Some(DialectType::Spark)
4578 | Some(DialectType::Hive)
4579 | Some(DialectType::DuckDB)
4580 | Some(DialectType::SQLite)
4581 | Some(DialectType::MySQL)
4582 | Some(DialectType::BigQuery)
4583 | Some(DialectType::Databricks)
4584 | Some(DialectType::StarRocks)
4585 | Some(DialectType::Doris)
4586 | Some(DialectType::Athena)
4587 | Some(DialectType::ClickHouse)
4588 | Some(DialectType::Redshift)
4589 );
4590
4591 if fetch_already_as_limit {
4592 } else {
4594 if self.config.pretty {
4595 self.write_newline();
4596 self.write_indent();
4597 } else {
4598 self.write_space();
4599 }
4600
4601 let use_limit = !fetch.percent
4603 && !fetch.with_ties
4604 && fetch.count.is_some()
4605 && matches!(
4606 self.config.dialect,
4607 Some(DialectType::Spark)
4608 | Some(DialectType::Hive)
4609 | Some(DialectType::DuckDB)
4610 | Some(DialectType::SQLite)
4611 | Some(DialectType::MySQL)
4612 | Some(DialectType::BigQuery)
4613 | Some(DialectType::Databricks)
4614 | Some(DialectType::StarRocks)
4615 | Some(DialectType::Doris)
4616 | Some(DialectType::Athena)
4617 | Some(DialectType::ClickHouse)
4618 | Some(DialectType::Redshift)
4619 );
4620
4621 if use_limit {
4622 self.write_keyword("LIMIT");
4623 self.write_space();
4624 self.generate_expression(fetch.count.as_ref().unwrap())?;
4625 } else {
4626 self.write_keyword("FETCH");
4627 self.write_space();
4628 self.write_keyword(&fetch.direction);
4629 if let Some(ref count) = fetch.count {
4630 self.write_space();
4631 self.generate_expression(count)?;
4632 }
4633 if fetch.percent {
4634 self.write_space();
4635 self.write_keyword("PERCENT");
4636 }
4637 if fetch.rows {
4638 self.write_space();
4639 self.write_keyword("ROWS");
4640 }
4641 if fetch.with_ties {
4642 self.write_space();
4643 self.write_keyword("WITH TIES");
4644 } else {
4645 self.write_space();
4646 self.write_keyword("ONLY");
4647 }
4648 }
4649 } }
4651
4652 if let Some(sample) = &select.sample {
4654 use crate::dialects::DialectType;
4655 if self.config.pretty {
4656 self.write_newline();
4657 } else {
4658 self.write_space();
4659 }
4660
4661 if sample.is_using_sample {
4662 self.write_keyword("USING SAMPLE");
4664 self.generate_sample_body(sample)?;
4665 } else {
4666 self.write_keyword("TABLESAMPLE");
4667
4668 let snowflake_bernoulli =
4670 matches!(self.config.dialect, Some(DialectType::Snowflake))
4671 && !sample.explicit_method;
4672 if snowflake_bernoulli {
4673 self.write_space();
4674 self.write_keyword("BERNOULLI");
4675 }
4676
4677 if matches!(sample.method, SampleMethod::Bucket) {
4679 self.write_space();
4680 self.write("(");
4681 self.write_keyword("BUCKET");
4682 self.write_space();
4683 if let Some(ref num) = sample.bucket_numerator {
4684 self.generate_expression(num)?;
4685 }
4686 self.write_space();
4687 self.write_keyword("OUT OF");
4688 self.write_space();
4689 if let Some(ref denom) = sample.bucket_denominator {
4690 self.generate_expression(denom)?;
4691 }
4692 if let Some(ref field) = sample.bucket_field {
4693 self.write_space();
4694 self.write_keyword("ON");
4695 self.write_space();
4696 self.generate_expression(field)?;
4697 }
4698 self.write(")");
4699 } else if sample.unit_after_size {
4700 if sample.explicit_method && sample.method_before_size {
4702 self.write_space();
4703 match sample.method {
4704 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4705 SampleMethod::System => self.write_keyword("SYSTEM"),
4706 SampleMethod::Block => self.write_keyword("BLOCK"),
4707 SampleMethod::Row => self.write_keyword("ROW"),
4708 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4709 _ => {}
4710 }
4711 }
4712 self.write(" (");
4713 self.generate_expression(&sample.size)?;
4714 self.write_space();
4715 match sample.method {
4716 SampleMethod::Percent => self.write_keyword("PERCENT"),
4717 SampleMethod::Row => self.write_keyword("ROWS"),
4718 SampleMethod::Reservoir => self.write_keyword("ROWS"),
4719 _ => {
4720 self.write_keyword("PERCENT");
4721 }
4722 }
4723 self.write(")");
4724 } else {
4725 self.write_space();
4727 match sample.method {
4728 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4729 SampleMethod::System => self.write_keyword("SYSTEM"),
4730 SampleMethod::Block => self.write_keyword("BLOCK"),
4731 SampleMethod::Row => self.write_keyword("ROW"),
4732 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
4733 SampleMethod::Bucket => {}
4734 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4735 }
4736 self.write(" (");
4737 self.generate_expression(&sample.size)?;
4738 if matches!(sample.method, SampleMethod::Percent) {
4739 self.write_space();
4740 self.write_keyword("PERCENT");
4741 }
4742 self.write(")");
4743 }
4744 }
4745
4746 if let Some(seed) = &sample.seed {
4747 self.write_space();
4748 let use_seed = sample.use_seed_keyword
4750 && !matches!(
4751 self.config.dialect,
4752 Some(crate::dialects::DialectType::Databricks)
4753 | Some(crate::dialects::DialectType::Spark)
4754 );
4755 if use_seed {
4756 self.write_keyword("SEED");
4757 } else {
4758 self.write_keyword("REPEATABLE");
4759 }
4760 self.write(" (");
4761 self.generate_expression(seed)?;
4762 self.write(")");
4763 }
4764 }
4765
4766 if self.config.locking_reads_supported {
4769 for lock in &select.locks {
4770 if self.config.pretty {
4771 self.write_newline();
4772 self.write_indent();
4773 } else {
4774 self.write_space();
4775 }
4776 self.generate_lock(lock)?;
4777 }
4778 }
4779
4780 if !select.for_xml.is_empty() {
4782 if self.config.pretty {
4783 self.write_newline();
4784 self.write_indent();
4785 } else {
4786 self.write_space();
4787 }
4788 self.write_keyword("FOR XML");
4789 for (i, opt) in select.for_xml.iter().enumerate() {
4790 if self.config.pretty {
4791 if i > 0 {
4792 self.write(",");
4793 }
4794 self.write_newline();
4795 self.write_indent();
4796 self.write(" "); } else {
4798 if i > 0 {
4799 self.write(",");
4800 }
4801 self.write_space();
4802 }
4803 self.generate_for_xml_option(opt)?;
4804 }
4805 }
4806
4807 if let Some(ref option) = select.option {
4809 if matches!(
4810 self.config.dialect,
4811 Some(crate::dialects::DialectType::TSQL)
4812 | Some(crate::dialects::DialectType::Fabric)
4813 ) {
4814 self.write_space();
4815 self.write(option);
4816 }
4817 }
4818
4819 Ok(())
4820 }
4821
4822 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
4824 match opt {
4825 Expression::QueryOption(qo) => {
4826 if let Expression::Var(var) = &*qo.this {
4828 self.write(&var.this);
4829 } else {
4830 self.generate_expression(&qo.this)?;
4831 }
4832 if let Some(expr) = &qo.expression {
4834 self.write("(");
4835 self.generate_expression(expr)?;
4836 self.write(")");
4837 }
4838 }
4839 _ => {
4840 self.generate_expression(opt)?;
4841 }
4842 }
4843 Ok(())
4844 }
4845
4846 fn generate_with(&mut self, with: &With) -> Result<()> {
4847 use crate::dialects::DialectType;
4848
4849 for comment in &with.leading_comments {
4851 self.write_formatted_comment(comment);
4852 self.write(" ");
4853 }
4854 self.write_keyword("WITH");
4855 if with.recursive && self.config.cte_recursive_keyword_required {
4856 self.write_space();
4857 self.write_keyword("RECURSIVE");
4858 }
4859 self.write_space();
4860
4861 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
4863
4864 for (i, cte) in with.ctes.iter().enumerate() {
4865 if i > 0 {
4866 self.write(",");
4867 if self.config.pretty {
4868 self.write_space();
4869 } else {
4870 self.write(" ");
4871 }
4872 }
4873 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
4874 self.generate_expression(&cte.this)?;
4875 self.write_space();
4876 self.write_keyword("AS");
4877 self.write_space();
4878 self.generate_identifier(&cte.alias)?;
4879 continue;
4880 }
4881 self.generate_identifier(&cte.alias)?;
4882 for comment in &cte.comments {
4884 self.write_space();
4885 self.write_formatted_comment(comment);
4886 }
4887 if !cte.columns.is_empty() && !skip_cte_columns {
4888 self.write("(");
4889 for (j, col) in cte.columns.iter().enumerate() {
4890 if j > 0 {
4891 self.write(", ");
4892 }
4893 self.generate_identifier(col)?;
4894 }
4895 self.write(")");
4896 }
4897 if !cte.key_expressions.is_empty() {
4899 self.write_space();
4900 self.write_keyword("USING KEY");
4901 self.write(" (");
4902 for (i, key) in cte.key_expressions.iter().enumerate() {
4903 if i > 0 {
4904 self.write(", ");
4905 }
4906 self.generate_identifier(key)?;
4907 }
4908 self.write(")");
4909 }
4910 self.write_space();
4911 self.write_keyword("AS");
4912 if let Some(materialized) = cte.materialized {
4914 self.write_space();
4915 if materialized {
4916 self.write_keyword("MATERIALIZED");
4917 } else {
4918 self.write_keyword("NOT MATERIALIZED");
4919 }
4920 }
4921 self.write(" (");
4922 if self.config.pretty {
4923 self.write_newline();
4924 self.indent_level += 1;
4925 self.write_indent();
4926 }
4927 let wrap_values_in_select = matches!(
4930 self.config.dialect,
4931 Some(DialectType::Spark) | Some(DialectType::Databricks)
4932 ) && matches!(&cte.this, Expression::Values(_));
4933
4934 if wrap_values_in_select {
4935 self.write_keyword("SELECT");
4936 self.write(" * ");
4937 self.write_keyword("FROM");
4938 self.write_space();
4939 }
4940 self.generate_expression(&cte.this)?;
4941 if self.config.pretty {
4942 self.write_newline();
4943 self.indent_level -= 1;
4944 self.write_indent();
4945 }
4946 self.write(")");
4947 }
4948
4949 if let Some(search) = &with.search {
4951 self.write_space();
4952 self.generate_expression(search)?;
4953 }
4954
4955 Ok(())
4956 }
4957
4958 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
4962 let mut i = 0;
4963 while i < joins.len() {
4964 if joins[i].deferred_condition {
4965 let parent_group = joins[i].nesting_group;
4966
4967 self.generate_join_without_condition(&joins[i])?;
4970
4971 let child_start = i + 1;
4973 let mut child_end = child_start;
4974 while child_end < joins.len()
4975 && !joins[child_end].deferred_condition
4976 && joins[child_end].nesting_group == parent_group
4977 {
4978 child_end += 1;
4979 }
4980
4981 if child_start < child_end {
4983 self.indent_level += 1;
4984 for j in child_start..child_end {
4985 self.generate_join(&joins[j])?;
4986 }
4987 self.indent_level -= 1;
4988 }
4989
4990 self.generate_join_condition(&joins[i])?;
4992
4993 i = child_end;
4994 } else {
4995 self.generate_join(&joins[i])?;
4997 i += 1;
4998 }
4999 }
5000 Ok(())
5001 }
5002
5003 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5006 let mut join_copy = join.clone();
5009 join_copy.on = None;
5010 join_copy.using = Vec::new();
5011 join_copy.deferred_condition = false;
5012 self.generate_join(&join_copy)
5013 }
5014
5015 fn generate_join(&mut self, join: &Join) -> Result<()> {
5016 if join.kind == JoinKind::Implicit {
5018 self.write(",");
5019 if self.config.pretty {
5020 self.write_newline();
5021 self.write_indent();
5022 } else {
5023 self.write_space();
5024 }
5025 self.generate_expression(&join.this)?;
5026 return Ok(());
5027 }
5028
5029 if self.config.pretty {
5030 self.write_newline();
5031 self.write_indent();
5032 } else {
5033 self.write_space();
5034 }
5035
5036 let hint_str = if self.config.join_hints {
5039 join.join_hint
5040 .as_ref()
5041 .map(|h| format!(" {}", h))
5042 .unwrap_or_default()
5043 } else {
5044 String::new()
5045 };
5046
5047 let clickhouse_join_keyword =
5048 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5049 if let Some(hint) = &join.join_hint {
5050 let mut global = false;
5051 let mut strictness: Option<&'static str> = None;
5052 for part in hint.split_whitespace() {
5053 match part.to_uppercase().as_str() {
5054 "GLOBAL" => global = true,
5055 "ANY" => strictness = Some("ANY"),
5056 "ASOF" => strictness = Some("ASOF"),
5057 "SEMI" => strictness = Some("SEMI"),
5058 "ANTI" => strictness = Some("ANTI"),
5059 _ => {}
5060 }
5061 }
5062
5063 if global || strictness.is_some() {
5064 let join_type = match join.kind {
5065 JoinKind::Left => {
5066 if join.use_outer_keyword {
5067 "LEFT OUTER"
5068 } else if join.use_inner_keyword {
5069 "LEFT INNER"
5070 } else {
5071 "LEFT"
5072 }
5073 }
5074 JoinKind::Right => {
5075 if join.use_outer_keyword {
5076 "RIGHT OUTER"
5077 } else if join.use_inner_keyword {
5078 "RIGHT INNER"
5079 } else {
5080 "RIGHT"
5081 }
5082 }
5083 JoinKind::Full => {
5084 if join.use_outer_keyword {
5085 "FULL OUTER"
5086 } else {
5087 "FULL"
5088 }
5089 }
5090 JoinKind::Inner => {
5091 if join.use_inner_keyword {
5092 "INNER"
5093 } else {
5094 ""
5095 }
5096 }
5097 _ => "",
5098 };
5099
5100 let mut parts = Vec::new();
5101 if global {
5102 parts.push("GLOBAL");
5103 }
5104 if !join_type.is_empty() {
5105 parts.push(join_type);
5106 }
5107 if let Some(strict) = strictness {
5108 parts.push(strict);
5109 }
5110 parts.push("JOIN");
5111 Some(parts.join(" "))
5112 } else {
5113 None
5114 }
5115 } else {
5116 None
5117 }
5118 } else {
5119 None
5120 };
5121
5122 if !join.comments.is_empty() {
5126 if self.config.pretty {
5127 let trimmed = self.output.trim_end().len();
5132 self.output.truncate(trimmed);
5133 for comment in &join.comments {
5134 self.write_newline();
5135 self.write_indent();
5136 self.write_formatted_comment(comment);
5137 }
5138 self.write_newline();
5139 self.write_indent();
5140 } else {
5141 for comment in &join.comments {
5142 self.write_formatted_comment(comment);
5143 self.write_space();
5144 }
5145 }
5146 }
5147
5148 let directed_str = if join.directed { " DIRECTED" } else { "" };
5149
5150 if let Some(keyword) = clickhouse_join_keyword {
5151 self.write_keyword(&keyword);
5152 } else {
5153 match join.kind {
5154 JoinKind::Inner => {
5155 if join.use_inner_keyword {
5156 self.write_keyword(&format!("INNER{}{} JOIN", hint_str, directed_str));
5157 } else {
5158 self.write_keyword(&format!(
5159 "{}{}JOIN",
5160 if hint_str.is_empty() {
5161 String::new()
5162 } else {
5163 format!("{} ", hint_str.trim())
5164 },
5165 if directed_str.is_empty() {
5166 ""
5167 } else {
5168 "DIRECTED "
5169 }
5170 ));
5171 }
5172 }
5173 JoinKind::Left => {
5174 if join.use_outer_keyword {
5175 self.write_keyword(&format!("LEFT OUTER{}{} JOIN", hint_str, directed_str));
5176 } else if join.use_inner_keyword {
5177 self.write_keyword(&format!("LEFT INNER{}{} JOIN", hint_str, directed_str));
5178 } else {
5179 self.write_keyword(&format!("LEFT{}{} JOIN", hint_str, directed_str));
5180 }
5181 }
5182 JoinKind::Right => {
5183 if join.use_outer_keyword {
5184 self.write_keyword(&format!(
5185 "RIGHT OUTER{}{} JOIN",
5186 hint_str, directed_str
5187 ));
5188 } else if join.use_inner_keyword {
5189 self.write_keyword(&format!(
5190 "RIGHT INNER{}{} JOIN",
5191 hint_str, directed_str
5192 ));
5193 } else {
5194 self.write_keyword(&format!("RIGHT{}{} JOIN", hint_str, directed_str));
5195 }
5196 }
5197 JoinKind::Full => {
5198 if join.use_outer_keyword {
5199 self.write_keyword(&format!("FULL OUTER{}{} JOIN", hint_str, directed_str));
5200 } else {
5201 self.write_keyword(&format!("FULL{}{} JOIN", hint_str, directed_str));
5202 }
5203 }
5204 JoinKind::Outer => self.write_keyword(&format!("OUTER{} JOIN", directed_str)),
5205 JoinKind::Cross => self.write_keyword(&format!("CROSS{} JOIN", directed_str)),
5206 JoinKind::Natural => {
5207 if join.use_inner_keyword {
5208 self.write_keyword(&format!("NATURAL INNER{} JOIN", directed_str));
5209 } else {
5210 self.write_keyword(&format!("NATURAL{} JOIN", directed_str));
5211 }
5212 }
5213 JoinKind::NaturalLeft => {
5214 if join.use_outer_keyword {
5215 self.write_keyword(&format!("NATURAL LEFT OUTER{} JOIN", directed_str));
5216 } else {
5217 self.write_keyword(&format!("NATURAL LEFT{} JOIN", directed_str));
5218 }
5219 }
5220 JoinKind::NaturalRight => {
5221 if join.use_outer_keyword {
5222 self.write_keyword(&format!("NATURAL RIGHT OUTER{} JOIN", directed_str));
5223 } else {
5224 self.write_keyword(&format!("NATURAL RIGHT{} JOIN", directed_str));
5225 }
5226 }
5227 JoinKind::NaturalFull => {
5228 if join.use_outer_keyword {
5229 self.write_keyword(&format!("NATURAL FULL OUTER{} JOIN", directed_str));
5230 } else {
5231 self.write_keyword(&format!("NATURAL FULL{} JOIN", directed_str));
5232 }
5233 }
5234 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
5235 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
5236 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
5237 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
5238 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
5239 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
5240 JoinKind::CrossApply => {
5241 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5243 self.write_keyword("CROSS APPLY");
5244 } else {
5245 self.write_keyword("INNER JOIN LATERAL");
5246 }
5247 }
5248 JoinKind::OuterApply => {
5249 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5251 self.write_keyword("OUTER APPLY");
5252 } else {
5253 self.write_keyword("LEFT JOIN LATERAL");
5254 }
5255 }
5256 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
5257 JoinKind::AsOfLeft => {
5258 if join.use_outer_keyword {
5259 self.write_keyword("ASOF LEFT OUTER JOIN");
5260 } else {
5261 self.write_keyword("ASOF LEFT JOIN");
5262 }
5263 }
5264 JoinKind::AsOfRight => {
5265 if join.use_outer_keyword {
5266 self.write_keyword("ASOF RIGHT OUTER JOIN");
5267 } else {
5268 self.write_keyword("ASOF RIGHT JOIN");
5269 }
5270 }
5271 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
5272 JoinKind::LeftLateral => {
5273 if join.use_outer_keyword {
5274 self.write_keyword("LEFT OUTER LATERAL JOIN");
5275 } else {
5276 self.write_keyword("LEFT LATERAL JOIN");
5277 }
5278 }
5279 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
5280 JoinKind::Implicit => {
5281 use crate::dialects::DialectType;
5285 let is_cj_dialect = matches!(
5286 self.config.dialect,
5287 Some(DialectType::BigQuery)
5288 | Some(DialectType::Hive)
5289 | Some(DialectType::Spark)
5290 | Some(DialectType::Databricks)
5291 );
5292 let source_is_same = self.config.source_dialect.is_some()
5293 && self.config.source_dialect == self.config.dialect;
5294 let source_is_cj = matches!(
5295 self.config.source_dialect,
5296 Some(DialectType::BigQuery)
5297 | Some(DialectType::Hive)
5298 | Some(DialectType::Spark)
5299 | Some(DialectType::Databricks)
5300 );
5301 if is_cj_dialect
5302 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
5303 {
5304 self.write_keyword("CROSS JOIN");
5305 } else {
5306 self.output.truncate(self.output.trim_end().len());
5310 self.write(",");
5311 }
5312 }
5313 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
5314 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
5315 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
5316 }
5317 }
5318
5319 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
5321 self.write_space();
5322 match &join.this {
5323 Expression::Tuple(t) => {
5324 for (i, item) in t.expressions.iter().enumerate() {
5325 if i > 0 {
5326 self.write(", ");
5327 }
5328 self.generate_expression(item)?;
5329 }
5330 }
5331 other => {
5332 self.generate_expression(other)?;
5333 }
5334 }
5335 } else {
5336 self.write_space();
5337 self.generate_expression(&join.this)?;
5338 }
5339
5340 if !join.deferred_condition {
5342 if let Some(match_cond) = &join.match_condition {
5344 self.write_space();
5345 self.write_keyword("MATCH_CONDITION");
5346 self.write(" (");
5347 self.generate_expression(match_cond)?;
5348 self.write(")");
5349 }
5350
5351 if let Some(on) = &join.on {
5352 if self.config.pretty {
5353 self.write_newline();
5354 self.indent_level += 1;
5355 self.write_indent();
5356 self.write_keyword("ON");
5357 self.write_space();
5358 self.generate_join_on_condition(on)?;
5359 self.indent_level -= 1;
5360 } else {
5361 self.write_space();
5362 self.write_keyword("ON");
5363 self.write_space();
5364 self.generate_expression(on)?;
5365 }
5366 }
5367
5368 if !join.using.is_empty() {
5369 if self.config.pretty {
5370 self.write_newline();
5371 self.indent_level += 1;
5372 self.write_indent();
5373 self.write_keyword("USING");
5374 self.write(" (");
5375 for (i, col) in join.using.iter().enumerate() {
5376 if i > 0 {
5377 self.write(", ");
5378 }
5379 self.generate_identifier(col)?;
5380 }
5381 self.write(")");
5382 self.indent_level -= 1;
5383 } else {
5384 self.write_space();
5385 self.write_keyword("USING");
5386 self.write(" (");
5387 for (i, col) in join.using.iter().enumerate() {
5388 if i > 0 {
5389 self.write(", ");
5390 }
5391 self.generate_identifier(col)?;
5392 }
5393 self.write(")");
5394 }
5395 }
5396 }
5397
5398 for pivot in &join.pivots {
5400 self.write_space();
5401 self.generate_expression(pivot)?;
5402 }
5403
5404 Ok(())
5405 }
5406
5407 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
5409 if let Some(match_cond) = &join.match_condition {
5411 self.write_space();
5412 self.write_keyword("MATCH_CONDITION");
5413 self.write(" (");
5414 self.generate_expression(match_cond)?;
5415 self.write(")");
5416 }
5417
5418 if let Some(on) = &join.on {
5419 if self.config.pretty {
5420 self.write_newline();
5421 self.indent_level += 1;
5422 self.write_indent();
5423 self.write_keyword("ON");
5424 self.write_space();
5425 self.generate_join_on_condition(on)?;
5427 self.indent_level -= 1;
5428 } else {
5429 self.write_space();
5430 self.write_keyword("ON");
5431 self.write_space();
5432 self.generate_expression(on)?;
5433 }
5434 }
5435
5436 if !join.using.is_empty() {
5437 if self.config.pretty {
5438 self.write_newline();
5439 self.indent_level += 1;
5440 self.write_indent();
5441 self.write_keyword("USING");
5442 self.write(" (");
5443 for (i, col) in join.using.iter().enumerate() {
5444 if i > 0 {
5445 self.write(", ");
5446 }
5447 self.generate_identifier(col)?;
5448 }
5449 self.write(")");
5450 self.indent_level -= 1;
5451 } else {
5452 self.write_space();
5453 self.write_keyword("USING");
5454 self.write(" (");
5455 for (i, col) in join.using.iter().enumerate() {
5456 if i > 0 {
5457 self.write(", ");
5458 }
5459 self.generate_identifier(col)?;
5460 }
5461 self.write(")");
5462 }
5463 }
5464
5465 for pivot in &join.pivots {
5467 self.write_space();
5468 self.generate_expression(pivot)?;
5469 }
5470
5471 Ok(())
5472 }
5473
5474 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
5476 if let Expression::And(and_op) = expr {
5478 self.generate_join_on_condition(&and_op.left)?;
5480 self.write_newline();
5482 self.write_indent();
5483 self.write_keyword("AND");
5484 self.write_space();
5485 self.generate_expression(&and_op.right)?;
5487 } else {
5488 self.generate_expression(expr)?;
5490 }
5491 Ok(())
5492 }
5493
5494 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
5495 self.write("(");
5497 self.generate_expression(&jt.left)?;
5498
5499 for join in &jt.joins {
5501 self.generate_join(join)?;
5502 }
5503
5504 for lv in &jt.lateral_views {
5506 self.generate_lateral_view(lv)?;
5507 }
5508
5509 self.write(")");
5510
5511 if let Some(alias) = &jt.alias {
5513 self.write_space();
5514 self.write_keyword("AS");
5515 self.write_space();
5516 self.generate_identifier(alias)?;
5517 }
5518
5519 Ok(())
5520 }
5521
5522 fn generate_lateral_view(&mut self, lv: &LateralView) -> Result<()> {
5523 use crate::dialects::DialectType;
5524
5525 if self.config.pretty {
5526 self.write_newline();
5527 self.write_indent();
5528 } else {
5529 self.write_space();
5530 }
5531
5532 let use_lateral_join = matches!(
5535 self.config.dialect,
5536 Some(DialectType::PostgreSQL)
5537 | Some(DialectType::DuckDB)
5538 | Some(DialectType::Snowflake)
5539 | Some(DialectType::TSQL)
5540 | Some(DialectType::Presto)
5541 | Some(DialectType::Trino)
5542 | Some(DialectType::Athena)
5543 );
5544
5545 let use_unnest = matches!(
5547 self.config.dialect,
5548 Some(DialectType::DuckDB)
5549 | Some(DialectType::Presto)
5550 | Some(DialectType::Trino)
5551 | Some(DialectType::Athena)
5552 );
5553
5554 let (is_posexplode, func_args) = match &lv.this {
5556 Expression::Explode(uf) => {
5557 (false, vec![uf.this.clone()])
5559 }
5560 Expression::Unnest(uf) => {
5561 let mut args = vec![uf.this.clone()];
5562 args.extend(uf.expressions.clone());
5563 (false, args)
5564 }
5565 Expression::Function(func) => {
5566 let name = func.name.to_uppercase();
5567 if name == "POSEXPLODE" || name == "POSEXPLODE_OUTER" {
5568 (true, func.args.clone())
5569 } else if name == "EXPLODE" || name == "EXPLODE_OUTER" || name == "INLINE" {
5570 (false, func.args.clone())
5571 } else {
5572 (false, vec![])
5573 }
5574 }
5575 _ => (false, vec![]),
5576 };
5577
5578 if use_lateral_join {
5579 if lv.outer {
5581 self.write_keyword("LEFT JOIN LATERAL");
5582 } else {
5583 self.write_keyword("CROSS JOIN");
5584 }
5585 self.write_space();
5586
5587 if use_unnest && !func_args.is_empty() {
5588 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
5591 func_args
5593 .iter()
5594 .map(|a| {
5595 if let Expression::Function(ref f) = a {
5596 if f.name.to_uppercase() == "ARRAY" && f.args.len() == 1 {
5597 return Expression::ArrayFunc(Box::new(
5598 crate::expressions::ArrayConstructor {
5599 expressions: f.args.clone(),
5600 bracket_notation: true,
5601 use_list_keyword: false,
5602 },
5603 ));
5604 }
5605 }
5606 a.clone()
5607 })
5608 .collect::<Vec<_>>()
5609 } else if matches!(
5610 self.config.dialect,
5611 Some(DialectType::Presto)
5612 | Some(DialectType::Trino)
5613 | Some(DialectType::Athena)
5614 ) {
5615 func_args
5617 .iter()
5618 .map(|a| {
5619 if let Expression::Function(ref f) = a {
5620 if f.name.to_uppercase() == "ARRAY" && f.args.len() >= 1 {
5621 return Expression::ArrayFunc(Box::new(
5622 crate::expressions::ArrayConstructor {
5623 expressions: f.args.clone(),
5624 bracket_notation: true,
5625 use_list_keyword: false,
5626 },
5627 ));
5628 }
5629 }
5630 a.clone()
5631 })
5632 .collect::<Vec<_>>()
5633 } else {
5634 func_args
5635 };
5636
5637 if is_posexplode {
5639 self.write_keyword("LATERAL");
5640 self.write(" (");
5641 self.write_keyword("SELECT");
5642 self.write_space();
5643
5644 let pos_alias = if !lv.column_aliases.is_empty() {
5647 lv.column_aliases[0].clone()
5648 } else {
5649 Identifier::new("pos")
5650 };
5651 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
5652 lv.column_aliases[1..].to_vec()
5653 } else {
5654 vec![Identifier::new("col")]
5655 };
5656
5657 self.generate_identifier(&pos_alias)?;
5659 self.write(" - 1");
5660 self.write_space();
5661 self.write_keyword("AS");
5662 self.write_space();
5663 self.generate_identifier(&pos_alias)?;
5664
5665 for data_col in &data_aliases {
5667 self.write(", ");
5668 self.generate_identifier(data_col)?;
5669 }
5670
5671 self.write_space();
5672 self.write_keyword("FROM");
5673 self.write_space();
5674 self.write_keyword("UNNEST");
5675 self.write("(");
5676 for (i, arg) in unnest_args.iter().enumerate() {
5677 if i > 0 {
5678 self.write(", ");
5679 }
5680 self.generate_expression(arg)?;
5681 }
5682 self.write(")");
5683 self.write_space();
5684 self.write_keyword("WITH ORDINALITY");
5685 self.write_space();
5686 self.write_keyword("AS");
5687 self.write_space();
5688
5689 let table_alias_ident = lv
5691 .table_alias
5692 .clone()
5693 .unwrap_or_else(|| Identifier::new("t"));
5694 self.generate_identifier(&table_alias_ident)?;
5695 self.write("(");
5696 for (i, data_col) in data_aliases.iter().enumerate() {
5697 if i > 0 {
5698 self.write(", ");
5699 }
5700 self.generate_identifier(data_col)?;
5701 }
5702 self.write(", ");
5703 self.generate_identifier(&pos_alias)?;
5704 self.write("))");
5705 } else {
5706 self.write_keyword("UNNEST");
5707 self.write("(");
5708 for (i, arg) in unnest_args.iter().enumerate() {
5709 if i > 0 {
5710 self.write(", ");
5711 }
5712 self.generate_expression(arg)?;
5713 }
5714 self.write(")");
5715
5716 if let Some(alias) = &lv.table_alias {
5718 self.write_space();
5719 self.write_keyword("AS");
5720 self.write_space();
5721 self.generate_identifier(alias)?;
5722 if !lv.column_aliases.is_empty() {
5723 self.write("(");
5724 for (i, col) in lv.column_aliases.iter().enumerate() {
5725 if i > 0 {
5726 self.write(", ");
5727 }
5728 self.generate_identifier(col)?;
5729 }
5730 self.write(")");
5731 }
5732 } else if !lv.column_aliases.is_empty() {
5733 self.write_space();
5734 self.write_keyword("AS");
5735 self.write(" t(");
5736 for (i, col) in lv.column_aliases.iter().enumerate() {
5737 if i > 0 {
5738 self.write(", ");
5739 }
5740 self.generate_identifier(col)?;
5741 }
5742 self.write(")");
5743 }
5744 }
5745 } else {
5746 if !lv.outer {
5748 self.write_keyword("LATERAL");
5749 self.write_space();
5750 }
5751 self.generate_expression(&lv.this)?;
5752
5753 if let Some(alias) = &lv.table_alias {
5755 self.write_space();
5756 self.write_keyword("AS");
5757 self.write_space();
5758 self.generate_identifier(alias)?;
5759 if !lv.column_aliases.is_empty() {
5760 self.write("(");
5761 for (i, col) in lv.column_aliases.iter().enumerate() {
5762 if i > 0 {
5763 self.write(", ");
5764 }
5765 self.generate_identifier(col)?;
5766 }
5767 self.write(")");
5768 }
5769 } else if !lv.column_aliases.is_empty() {
5770 self.write_space();
5771 self.write_keyword("AS");
5772 self.write(" t(");
5773 for (i, col) in lv.column_aliases.iter().enumerate() {
5774 if i > 0 {
5775 self.write(", ");
5776 }
5777 self.generate_identifier(col)?;
5778 }
5779 self.write(")");
5780 }
5781 }
5782
5783 if lv.outer {
5785 self.write_space();
5786 self.write_keyword("ON TRUE");
5787 }
5788 } else {
5789 self.write_keyword("LATERAL VIEW");
5791 if lv.outer {
5792 self.write_space();
5793 self.write_keyword("OUTER");
5794 }
5795 if self.config.pretty {
5796 self.write_newline();
5797 self.write_indent();
5798 } else {
5799 self.write_space();
5800 }
5801 self.generate_expression(&lv.this)?;
5802
5803 if let Some(alias) = &lv.table_alias {
5805 self.write_space();
5806 self.generate_identifier(alias)?;
5807 }
5808
5809 if !lv.column_aliases.is_empty() {
5811 self.write_space();
5812 self.write_keyword("AS");
5813 self.write_space();
5814 for (i, col) in lv.column_aliases.iter().enumerate() {
5815 if i > 0 {
5816 self.write(", ");
5817 }
5818 self.generate_identifier(col)?;
5819 }
5820 }
5821 }
5822
5823 Ok(())
5824 }
5825
5826 fn generate_union(&mut self, union: &Union) -> Result<()> {
5827 if let Some(with) = &union.with {
5829 self.generate_with(with)?;
5830 self.write_space();
5831 }
5832 self.generate_expression(&union.left)?;
5833 if self.config.pretty {
5834 self.write_newline();
5835 self.write_indent();
5836 } else {
5837 self.write_space();
5838 }
5839
5840 if let Some(side) = &union.side {
5842 self.write_keyword(side);
5843 self.write_space();
5844 }
5845 if let Some(kind) = &union.kind {
5846 self.write_keyword(kind);
5847 self.write_space();
5848 }
5849
5850 self.write_keyword("UNION");
5851 if union.all {
5852 self.write_space();
5853 self.write_keyword("ALL");
5854 } else if union.distinct {
5855 self.write_space();
5856 self.write_keyword("DISTINCT");
5857 }
5858
5859 if union.corresponding || union.by_name {
5862 self.write_space();
5863 self.write_keyword("BY NAME");
5864 }
5865 if !union.on_columns.is_empty() {
5866 self.write_space();
5867 self.write_keyword("ON");
5868 self.write(" (");
5869 for (i, col) in union.on_columns.iter().enumerate() {
5870 if i > 0 {
5871 self.write(", ");
5872 }
5873 self.generate_expression(col)?;
5874 }
5875 self.write(")");
5876 }
5877
5878 if self.config.pretty {
5879 self.write_newline();
5880 self.write_indent();
5881 } else {
5882 self.write_space();
5883 }
5884 self.generate_expression(&union.right)?;
5885 if let Some(order_by) = &union.order_by {
5887 if self.config.pretty {
5888 self.write_newline();
5889 } else {
5890 self.write_space();
5891 }
5892 self.write_keyword("ORDER BY");
5893 self.write_space();
5894 for (i, ordered) in order_by.expressions.iter().enumerate() {
5895 if i > 0 {
5896 self.write(", ");
5897 }
5898 self.generate_ordered(ordered)?;
5899 }
5900 }
5901 if let Some(limit) = &union.limit {
5902 if self.config.pretty {
5903 self.write_newline();
5904 } else {
5905 self.write_space();
5906 }
5907 self.write_keyword("LIMIT");
5908 self.write_space();
5909 self.generate_expression(limit)?;
5910 }
5911 if let Some(offset) = &union.offset {
5912 if self.config.pretty {
5913 self.write_newline();
5914 } else {
5915 self.write_space();
5916 }
5917 self.write_keyword("OFFSET");
5918 self.write_space();
5919 self.generate_expression(offset)?;
5920 }
5921 if let Some(distribute_by) = &union.distribute_by {
5923 self.write_space();
5924 self.write_keyword("DISTRIBUTE BY");
5925 self.write_space();
5926 for (i, expr) in distribute_by.expressions.iter().enumerate() {
5927 if i > 0 {
5928 self.write(", ");
5929 }
5930 self.generate_expression(expr)?;
5931 }
5932 }
5933 if let Some(sort_by) = &union.sort_by {
5935 self.write_space();
5936 self.write_keyword("SORT BY");
5937 self.write_space();
5938 for (i, ord) in sort_by.expressions.iter().enumerate() {
5939 if i > 0 {
5940 self.write(", ");
5941 }
5942 self.generate_ordered(ord)?;
5943 }
5944 }
5945 if let Some(cluster_by) = &union.cluster_by {
5947 self.write_space();
5948 self.write_keyword("CLUSTER BY");
5949 self.write_space();
5950 for (i, ord) in cluster_by.expressions.iter().enumerate() {
5951 if i > 0 {
5952 self.write(", ");
5953 }
5954 self.generate_ordered(ord)?;
5955 }
5956 }
5957 Ok(())
5958 }
5959
5960 fn generate_intersect(&mut self, intersect: &Intersect) -> Result<()> {
5961 if let Some(with) = &intersect.with {
5963 self.generate_with(with)?;
5964 self.write_space();
5965 }
5966 self.generate_expression(&intersect.left)?;
5967 if self.config.pretty {
5968 self.write_newline();
5969 self.write_indent();
5970 } else {
5971 self.write_space();
5972 }
5973
5974 if let Some(side) = &intersect.side {
5976 self.write_keyword(side);
5977 self.write_space();
5978 }
5979 if let Some(kind) = &intersect.kind {
5980 self.write_keyword(kind);
5981 self.write_space();
5982 }
5983
5984 self.write_keyword("INTERSECT");
5985 if intersect.all {
5986 self.write_space();
5987 self.write_keyword("ALL");
5988 } else if intersect.distinct {
5989 self.write_space();
5990 self.write_keyword("DISTINCT");
5991 }
5992
5993 if intersect.corresponding || intersect.by_name {
5996 self.write_space();
5997 self.write_keyword("BY NAME");
5998 }
5999 if !intersect.on_columns.is_empty() {
6000 self.write_space();
6001 self.write_keyword("ON");
6002 self.write(" (");
6003 for (i, col) in intersect.on_columns.iter().enumerate() {
6004 if i > 0 {
6005 self.write(", ");
6006 }
6007 self.generate_expression(col)?;
6008 }
6009 self.write(")");
6010 }
6011
6012 if self.config.pretty {
6013 self.write_newline();
6014 self.write_indent();
6015 } else {
6016 self.write_space();
6017 }
6018 self.generate_expression(&intersect.right)?;
6019 if let Some(order_by) = &intersect.order_by {
6021 if self.config.pretty {
6022 self.write_newline();
6023 } else {
6024 self.write_space();
6025 }
6026 self.write_keyword("ORDER BY");
6027 self.write_space();
6028 for (i, ordered) in order_by.expressions.iter().enumerate() {
6029 if i > 0 {
6030 self.write(", ");
6031 }
6032 self.generate_ordered(ordered)?;
6033 }
6034 }
6035 if let Some(limit) = &intersect.limit {
6036 if self.config.pretty {
6037 self.write_newline();
6038 } else {
6039 self.write_space();
6040 }
6041 self.write_keyword("LIMIT");
6042 self.write_space();
6043 self.generate_expression(limit)?;
6044 }
6045 if let Some(offset) = &intersect.offset {
6046 if self.config.pretty {
6047 self.write_newline();
6048 } else {
6049 self.write_space();
6050 }
6051 self.write_keyword("OFFSET");
6052 self.write_space();
6053 self.generate_expression(offset)?;
6054 }
6055 if let Some(distribute_by) = &intersect.distribute_by {
6057 self.write_space();
6058 self.write_keyword("DISTRIBUTE BY");
6059 self.write_space();
6060 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6061 if i > 0 {
6062 self.write(", ");
6063 }
6064 self.generate_expression(expr)?;
6065 }
6066 }
6067 if let Some(sort_by) = &intersect.sort_by {
6069 self.write_space();
6070 self.write_keyword("SORT BY");
6071 self.write_space();
6072 for (i, ord) in sort_by.expressions.iter().enumerate() {
6073 if i > 0 {
6074 self.write(", ");
6075 }
6076 self.generate_ordered(ord)?;
6077 }
6078 }
6079 if let Some(cluster_by) = &intersect.cluster_by {
6081 self.write_space();
6082 self.write_keyword("CLUSTER BY");
6083 self.write_space();
6084 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6085 if i > 0 {
6086 self.write(", ");
6087 }
6088 self.generate_ordered(ord)?;
6089 }
6090 }
6091 Ok(())
6092 }
6093
6094 fn generate_except(&mut self, except: &Except) -> Result<()> {
6095 use crate::dialects::DialectType;
6096
6097 if let Some(with) = &except.with {
6099 self.generate_with(with)?;
6100 self.write_space();
6101 }
6102
6103 self.generate_expression(&except.left)?;
6104 if self.config.pretty {
6105 self.write_newline();
6106 self.write_indent();
6107 } else {
6108 self.write_space();
6109 }
6110
6111 if let Some(side) = &except.side {
6113 self.write_keyword(side);
6114 self.write_space();
6115 }
6116 if let Some(kind) = &except.kind {
6117 self.write_keyword(kind);
6118 self.write_space();
6119 }
6120
6121 match self.config.dialect {
6123 Some(DialectType::Oracle) if !except.all => {
6124 self.write_keyword("MINUS");
6125 }
6126 Some(DialectType::ClickHouse) => {
6127 self.write_keyword("EXCEPT");
6129 if except.distinct {
6130 self.write_space();
6131 self.write_keyword("DISTINCT");
6132 }
6133 }
6134 Some(DialectType::BigQuery) => {
6135 self.write_keyword("EXCEPT");
6137 if except.all {
6138 self.write_space();
6139 self.write_keyword("ALL");
6140 } else {
6141 self.write_space();
6142 self.write_keyword("DISTINCT");
6143 }
6144 }
6145 _ => {
6146 self.write_keyword("EXCEPT");
6147 if except.all {
6148 self.write_space();
6149 self.write_keyword("ALL");
6150 } else if except.distinct {
6151 self.write_space();
6152 self.write_keyword("DISTINCT");
6153 }
6154 }
6155 }
6156
6157 if except.corresponding || except.by_name {
6160 self.write_space();
6161 self.write_keyword("BY NAME");
6162 }
6163 if !except.on_columns.is_empty() {
6164 self.write_space();
6165 self.write_keyword("ON");
6166 self.write(" (");
6167 for (i, col) in except.on_columns.iter().enumerate() {
6168 if i > 0 {
6169 self.write(", ");
6170 }
6171 self.generate_expression(col)?;
6172 }
6173 self.write(")");
6174 }
6175
6176 if self.config.pretty {
6177 self.write_newline();
6178 self.write_indent();
6179 } else {
6180 self.write_space();
6181 }
6182 self.generate_expression(&except.right)?;
6183 if let Some(order_by) = &except.order_by {
6185 if self.config.pretty {
6186 self.write_newline();
6187 } else {
6188 self.write_space();
6189 }
6190 self.write_keyword("ORDER BY");
6191 self.write_space();
6192 for (i, ordered) in order_by.expressions.iter().enumerate() {
6193 if i > 0 {
6194 self.write(", ");
6195 }
6196 self.generate_ordered(ordered)?;
6197 }
6198 }
6199 if let Some(limit) = &except.limit {
6200 if self.config.pretty {
6201 self.write_newline();
6202 } else {
6203 self.write_space();
6204 }
6205 self.write_keyword("LIMIT");
6206 self.write_space();
6207 self.generate_expression(limit)?;
6208 }
6209 if let Some(offset) = &except.offset {
6210 if self.config.pretty {
6211 self.write_newline();
6212 } else {
6213 self.write_space();
6214 }
6215 self.write_keyword("OFFSET");
6216 self.write_space();
6217 self.generate_expression(offset)?;
6218 }
6219 if let Some(distribute_by) = &except.distribute_by {
6221 self.write_space();
6222 self.write_keyword("DISTRIBUTE BY");
6223 self.write_space();
6224 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6225 if i > 0 {
6226 self.write(", ");
6227 }
6228 self.generate_expression(expr)?;
6229 }
6230 }
6231 if let Some(sort_by) = &except.sort_by {
6233 self.write_space();
6234 self.write_keyword("SORT BY");
6235 self.write_space();
6236 for (i, ord) in sort_by.expressions.iter().enumerate() {
6237 if i > 0 {
6238 self.write(", ");
6239 }
6240 self.generate_ordered(ord)?;
6241 }
6242 }
6243 if let Some(cluster_by) = &except.cluster_by {
6245 self.write_space();
6246 self.write_keyword("CLUSTER BY");
6247 self.write_space();
6248 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6249 if i > 0 {
6250 self.write(", ");
6251 }
6252 self.generate_ordered(ord)?;
6253 }
6254 }
6255 Ok(())
6256 }
6257
6258 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
6259 let prepend_query_cte = if insert.with.is_none() {
6261 use crate::dialects::DialectType;
6262 let should_prepend = matches!(
6263 self.config.dialect,
6264 Some(DialectType::TSQL)
6265 | Some(DialectType::Fabric)
6266 | Some(DialectType::Spark)
6267 | Some(DialectType::Databricks)
6268 | Some(DialectType::Hive)
6269 );
6270 if should_prepend {
6271 if let Some(Expression::Select(select)) = &insert.query {
6272 select.with.clone()
6273 } else {
6274 None
6275 }
6276 } else {
6277 None
6278 }
6279 } else {
6280 None
6281 };
6282
6283 if let Some(with) = &insert.with {
6285 self.generate_with(with)?;
6286 self.write_space();
6287 } else if let Some(with) = &prepend_query_cte {
6288 self.generate_with(with)?;
6289 self.write_space();
6290 }
6291
6292 for comment in &insert.leading_comments {
6294 self.write_formatted_comment(comment);
6295 self.write(" ");
6296 }
6297
6298 if let Some(dir) = &insert.directory {
6300 self.write_keyword("INSERT OVERWRITE");
6301 if dir.local {
6302 self.write_space();
6303 self.write_keyword("LOCAL");
6304 }
6305 self.write_space();
6306 self.write_keyword("DIRECTORY");
6307 self.write_space();
6308 self.write("'");
6309 self.write(&dir.path);
6310 self.write("'");
6311
6312 if let Some(row_format) = &dir.row_format {
6314 self.write_space();
6315 self.write_keyword("ROW FORMAT");
6316 if row_format.delimited {
6317 self.write_space();
6318 self.write_keyword("DELIMITED");
6319 }
6320 if let Some(val) = &row_format.fields_terminated_by {
6321 self.write_space();
6322 self.write_keyword("FIELDS TERMINATED BY");
6323 self.write_space();
6324 self.write("'");
6325 self.write(val);
6326 self.write("'");
6327 }
6328 if let Some(val) = &row_format.collection_items_terminated_by {
6329 self.write_space();
6330 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
6331 self.write_space();
6332 self.write("'");
6333 self.write(val);
6334 self.write("'");
6335 }
6336 if let Some(val) = &row_format.map_keys_terminated_by {
6337 self.write_space();
6338 self.write_keyword("MAP KEYS TERMINATED BY");
6339 self.write_space();
6340 self.write("'");
6341 self.write(val);
6342 self.write("'");
6343 }
6344 if let Some(val) = &row_format.lines_terminated_by {
6345 self.write_space();
6346 self.write_keyword("LINES TERMINATED BY");
6347 self.write_space();
6348 self.write("'");
6349 self.write(val);
6350 self.write("'");
6351 }
6352 if let Some(val) = &row_format.null_defined_as {
6353 self.write_space();
6354 self.write_keyword("NULL DEFINED AS");
6355 self.write_space();
6356 self.write("'");
6357 self.write(val);
6358 self.write("'");
6359 }
6360 }
6361
6362 if let Some(format) = &dir.stored_as {
6364 self.write_space();
6365 self.write_keyword("STORED AS");
6366 self.write_space();
6367 self.write_keyword(format);
6368 }
6369
6370 if let Some(query) = &insert.query {
6372 self.write_space();
6373 self.generate_expression(query)?;
6374 }
6375
6376 return Ok(());
6377 }
6378
6379 if insert.is_replace {
6380 self.write_keyword("REPLACE INTO");
6382 } else if insert.overwrite {
6383 self.write_keyword("INSERT");
6385 if let Some(ref hint) = insert.hint {
6387 self.generate_hint(hint)?;
6388 }
6389 self.write(&self.config.insert_overwrite.to_uppercase());
6390 } else if let Some(ref action) = insert.conflict_action {
6391 self.write_keyword("INSERT OR");
6393 self.write_space();
6394 self.write_keyword(action);
6395 self.write_space();
6396 self.write_keyword("INTO");
6397 } else if insert.ignore {
6398 self.write_keyword("INSERT IGNORE INTO");
6400 } else {
6401 self.write_keyword("INSERT");
6402 if let Some(ref hint) = insert.hint {
6404 self.generate_hint(hint)?;
6405 }
6406 self.write_space();
6407 self.write_keyword("INTO");
6408 }
6409 if let Some(ref func) = insert.function_target {
6411 self.write_space();
6412 self.write_keyword("FUNCTION");
6413 self.write_space();
6414 self.generate_expression(func)?;
6415 } else {
6416 self.write_space();
6417 self.generate_table(&insert.table)?;
6418 }
6419
6420 if let Some(ref alias) = insert.alias {
6422 self.write_space();
6423 if insert.alias_explicit_as {
6424 self.write_keyword("AS");
6425 self.write_space();
6426 }
6427 self.generate_identifier(alias)?;
6428 }
6429
6430 if insert.if_exists {
6432 self.write_space();
6433 self.write_keyword("IF EXISTS");
6434 }
6435
6436 if let Some(ref replace_where) = insert.replace_where {
6438 if self.config.pretty {
6439 self.write_newline();
6440 self.write_indent();
6441 } else {
6442 self.write_space();
6443 }
6444 self.write_keyword("REPLACE WHERE");
6445 self.write_space();
6446 self.generate_expression(replace_where)?;
6447 }
6448
6449 if !insert.partition.is_empty() {
6451 self.write_space();
6452 self.write_keyword("PARTITION");
6453 self.write("(");
6454 for (i, (col, val)) in insert.partition.iter().enumerate() {
6455 if i > 0 {
6456 self.write(", ");
6457 }
6458 self.generate_identifier(col)?;
6459 if let Some(v) = val {
6460 self.write(" = ");
6461 self.generate_expression(v)?;
6462 }
6463 }
6464 self.write(")");
6465 }
6466
6467 if let Some(ref partition_by) = insert.partition_by {
6469 self.write_space();
6470 self.write_keyword("PARTITION BY");
6471 self.write_space();
6472 self.generate_expression(partition_by)?;
6473 }
6474
6475 if !insert.settings.is_empty() {
6477 self.write_space();
6478 self.write_keyword("SETTINGS");
6479 self.write_space();
6480 for (i, setting) in insert.settings.iter().enumerate() {
6481 if i > 0 {
6482 self.write(", ");
6483 }
6484 self.generate_expression(setting)?;
6485 }
6486 }
6487
6488 if !insert.columns.is_empty() {
6489 if insert.alias.is_some() && insert.alias_explicit_as {
6490 self.write("(");
6492 } else {
6493 self.write(" (");
6495 }
6496 for (i, col) in insert.columns.iter().enumerate() {
6497 if i > 0 {
6498 self.write(", ");
6499 }
6500 self.generate_identifier(col)?;
6501 }
6502 self.write(")");
6503 }
6504
6505 if let Some(ref output) = insert.output {
6507 self.generate_output_clause(output)?;
6508 }
6509
6510 if insert.by_name {
6512 self.write_space();
6513 self.write_keyword("BY NAME");
6514 }
6515
6516 if insert.default_values {
6517 self.write_space();
6518 self.write_keyword("DEFAULT VALUES");
6519 } else if let Some(query) = &insert.query {
6520 if self.config.pretty {
6521 self.write_newline();
6522 } else {
6523 self.write_space();
6524 }
6525 if prepend_query_cte.is_some() {
6527 if let Expression::Select(select) = query {
6528 let mut select_no_with = select.clone();
6529 select_no_with.with = None;
6530 self.generate_select(&select_no_with)?;
6531 } else {
6532 self.generate_expression(query)?;
6533 }
6534 } else {
6535 self.generate_expression(query)?;
6536 }
6537 } else if !insert.values.is_empty() {
6538 if self.config.pretty {
6539 self.write_newline();
6541 self.write_keyword("VALUES");
6542 self.write_newline();
6543 self.indent_level += 1;
6544 for (i, row) in insert.values.iter().enumerate() {
6545 if i > 0 {
6546 self.write(",");
6547 self.write_newline();
6548 }
6549 self.write_indent();
6550 self.write("(");
6551 for (j, val) in row.iter().enumerate() {
6552 if j > 0 {
6553 self.write(", ");
6554 }
6555 self.generate_expression(val)?;
6556 }
6557 self.write(")");
6558 }
6559 self.indent_level -= 1;
6560 } else {
6561 self.write_space();
6563 self.write_keyword("VALUES");
6564 for (i, row) in insert.values.iter().enumerate() {
6565 if i > 0 {
6566 self.write(",");
6567 }
6568 self.write(" (");
6569 for (j, val) in row.iter().enumerate() {
6570 if j > 0 {
6571 self.write(", ");
6572 }
6573 self.generate_expression(val)?;
6574 }
6575 self.write(")");
6576 }
6577 }
6578 }
6579
6580 if let Some(ref source) = insert.source {
6582 self.write_space();
6583 self.write_keyword("TABLE");
6584 self.write_space();
6585 self.generate_expression(source)?;
6586 }
6587
6588 if let Some(alias) = &insert.source_alias {
6590 self.write_space();
6591 self.write_keyword("AS");
6592 self.write_space();
6593 self.generate_identifier(alias)?;
6594 }
6595
6596 if let Some(on_conflict) = &insert.on_conflict {
6598 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
6599 self.write_space();
6600 self.generate_expression(on_conflict)?;
6601 }
6602 }
6603
6604 if !insert.returning.is_empty() {
6606 self.write_space();
6607 self.write_keyword("RETURNING");
6608 self.write_space();
6609 for (i, expr) in insert.returning.iter().enumerate() {
6610 if i > 0 {
6611 self.write(", ");
6612 }
6613 self.generate_expression(expr)?;
6614 }
6615 }
6616
6617 Ok(())
6618 }
6619
6620 fn generate_update(&mut self, update: &Update) -> Result<()> {
6621 for comment in &update.leading_comments {
6623 self.write_formatted_comment(comment);
6624 self.write(" ");
6625 }
6626
6627 if let Some(ref with) = update.with {
6629 self.generate_with(with)?;
6630 self.write_space();
6631 }
6632
6633 self.write_keyword("UPDATE");
6634 self.write_space();
6635 self.generate_table(&update.table)?;
6636
6637 let mysql_like_update_from = matches!(
6638 self.config.dialect,
6639 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
6640 ) && update.from_clause.is_some();
6641
6642 let mut set_pairs = update.set.clone();
6643
6644 let mut pre_set_joins = update.table_joins.clone();
6646 if mysql_like_update_from {
6647 let target_name = update
6648 .table
6649 .alias
6650 .as_ref()
6651 .map(|a| a.name.clone())
6652 .unwrap_or_else(|| update.table.name.name.clone());
6653
6654 for (col, _) in &mut set_pairs {
6655 if !col.name.contains('.') {
6656 col.name = format!("{}.{}", target_name, col.name);
6657 }
6658 }
6659
6660 if let Some(from_clause) = &update.from_clause {
6661 for table_expr in &from_clause.expressions {
6662 pre_set_joins.push(crate::expressions::Join {
6663 this: table_expr.clone(),
6664 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
6665 value: true,
6666 })),
6667 using: Vec::new(),
6668 kind: crate::expressions::JoinKind::Inner,
6669 use_inner_keyword: false,
6670 use_outer_keyword: false,
6671 deferred_condition: false,
6672 join_hint: None,
6673 match_condition: None,
6674 pivots: Vec::new(),
6675 comments: Vec::new(),
6676 nesting_group: 0,
6677 directed: false,
6678 });
6679 }
6680 }
6681 for join in &update.from_joins {
6682 let mut join = join.clone();
6683 if join.on.is_none() && join.using.is_empty() {
6684 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
6685 value: true,
6686 }));
6687 }
6688 pre_set_joins.push(join);
6689 }
6690 }
6691
6692 for extra_table in &update.extra_tables {
6694 self.write(", ");
6695 self.generate_table(extra_table)?;
6696 }
6697
6698 for join in &pre_set_joins {
6700 self.generate_join(join)?;
6702 }
6703
6704 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
6706 if teradata_from_before_set && !mysql_like_update_from {
6707 if let Some(ref from_clause) = update.from_clause {
6708 self.write_space();
6709 self.write_keyword("FROM");
6710 self.write_space();
6711 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
6712 if i > 0 {
6713 self.write(", ");
6714 }
6715 self.generate_expression(table_expr)?;
6716 }
6717 }
6718 for join in &update.from_joins {
6719 self.generate_join(join)?;
6720 }
6721 }
6722
6723 self.write_space();
6724 self.write_keyword("SET");
6725 self.write_space();
6726
6727 for (i, (col, val)) in set_pairs.iter().enumerate() {
6728 if i > 0 {
6729 self.write(", ");
6730 }
6731 self.generate_identifier(col)?;
6732 self.write(" = ");
6733 self.generate_expression(val)?;
6734 }
6735
6736 if let Some(ref output) = update.output {
6738 self.generate_output_clause(output)?;
6739 }
6740
6741 if !mysql_like_update_from && !teradata_from_before_set {
6743 if let Some(ref from_clause) = update.from_clause {
6744 self.write_space();
6745 self.write_keyword("FROM");
6746 self.write_space();
6747 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
6749 if i > 0 {
6750 self.write(", ");
6751 }
6752 self.generate_expression(table_expr)?;
6753 }
6754 }
6755 }
6756
6757 if !mysql_like_update_from && !teradata_from_before_set {
6758 for join in &update.from_joins {
6760 self.generate_join(join)?;
6761 }
6762 }
6763
6764 if let Some(where_clause) = &update.where_clause {
6765 self.write_space();
6766 self.write_keyword("WHERE");
6767 self.write_space();
6768 self.generate_expression(&where_clause.this)?;
6769 }
6770
6771 if !update.returning.is_empty() {
6773 self.write_space();
6774 self.write_keyword("RETURNING");
6775 self.write_space();
6776 for (i, expr) in update.returning.iter().enumerate() {
6777 if i > 0 {
6778 self.write(", ");
6779 }
6780 self.generate_expression(expr)?;
6781 }
6782 }
6783
6784 if let Some(ref order_by) = update.order_by {
6786 self.write_space();
6787 self.generate_order_by(order_by)?;
6788 }
6789
6790 if let Some(ref limit) = update.limit {
6792 self.write_space();
6793 self.write_keyword("LIMIT");
6794 self.write_space();
6795 self.generate_expression(limit)?;
6796 }
6797
6798 Ok(())
6799 }
6800
6801 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
6802 if let Some(with) = &delete.with {
6804 self.generate_with(with)?;
6805 self.write_space();
6806 }
6807
6808 for comment in &delete.leading_comments {
6810 self.write_formatted_comment(comment);
6811 self.write(" ");
6812 }
6813
6814 if !delete.tables.is_empty() && !delete.tables_from_using {
6816 self.write_keyword("DELETE");
6818 self.write_space();
6819 for (i, tbl) in delete.tables.iter().enumerate() {
6820 if i > 0 {
6821 self.write(", ");
6822 }
6823 self.generate_table(tbl)?;
6824 }
6825 if let Some(ref output) = delete.output {
6827 self.generate_output_clause(output)?;
6828 }
6829 self.write_space();
6830 self.write_keyword("FROM");
6831 self.write_space();
6832 self.generate_table(&delete.table)?;
6833 } else if !delete.tables.is_empty() && delete.tables_from_using {
6834 self.write_keyword("DELETE FROM");
6836 self.write_space();
6837 for (i, tbl) in delete.tables.iter().enumerate() {
6838 if i > 0 {
6839 self.write(", ");
6840 }
6841 self.generate_table(tbl)?;
6842 }
6843 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
6844 self.write_keyword("DELETE");
6846 self.write_space();
6847 self.generate_table(&delete.table)?;
6848 } else {
6849 self.write_keyword("DELETE FROM");
6850 self.write_space();
6851 self.generate_table(&delete.table)?;
6852 }
6853
6854 if let Some(ref on_cluster) = delete.on_cluster {
6856 self.write_space();
6857 self.generate_on_cluster(on_cluster)?;
6858 }
6859
6860 if let Some(ref idx) = delete.force_index {
6862 self.write_space();
6863 self.write_keyword("FORCE INDEX");
6864 self.write(" (");
6865 self.write(idx);
6866 self.write(")");
6867 }
6868
6869 if let Some(ref alias) = delete.alias {
6871 self.write_space();
6872 if delete.alias_explicit_as
6873 || matches!(self.config.dialect, Some(DialectType::BigQuery))
6874 {
6875 self.write_keyword("AS");
6876 self.write_space();
6877 }
6878 self.generate_identifier(alias)?;
6879 }
6880
6881 if !delete.tables_from_using {
6883 for join in &delete.joins {
6884 self.generate_join(join)?;
6885 }
6886 }
6887
6888 if !delete.using.is_empty() {
6890 self.write_space();
6891 self.write_keyword("USING");
6892 for (i, table) in delete.using.iter().enumerate() {
6893 if i > 0 {
6894 self.write(",");
6895 }
6896 self.write_space();
6897 if !table.hints.is_empty() && table.name.is_empty() {
6899 self.generate_expression(&table.hints[0])?;
6901 if let Some(ref alias) = table.alias {
6902 self.write_space();
6903 if table.alias_explicit_as {
6904 self.write_keyword("AS");
6905 self.write_space();
6906 }
6907 self.generate_identifier(alias)?;
6908 if !table.column_aliases.is_empty() {
6909 self.write("(");
6910 for (j, col_alias) in table.column_aliases.iter().enumerate() {
6911 if j > 0 {
6912 self.write(", ");
6913 }
6914 self.generate_identifier(col_alias)?;
6915 }
6916 self.write(")");
6917 }
6918 }
6919 } else {
6920 self.generate_table(table)?;
6921 }
6922 }
6923 }
6924
6925 if delete.tables_from_using {
6927 for join in &delete.joins {
6928 self.generate_join(join)?;
6929 }
6930 }
6931
6932 let output_already_emitted =
6934 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
6935 if !output_already_emitted {
6936 if let Some(ref output) = delete.output {
6937 self.generate_output_clause(output)?;
6938 }
6939 }
6940
6941 if let Some(where_clause) = &delete.where_clause {
6942 self.write_space();
6943 self.write_keyword("WHERE");
6944 self.write_space();
6945 self.generate_expression(&where_clause.this)?;
6946 }
6947
6948 if let Some(ref order_by) = delete.order_by {
6950 self.write_space();
6951 self.generate_order_by(order_by)?;
6952 }
6953
6954 if let Some(ref limit) = delete.limit {
6956 self.write_space();
6957 self.write_keyword("LIMIT");
6958 self.write_space();
6959 self.generate_expression(limit)?;
6960 }
6961
6962 if !delete.returning.is_empty() {
6964 self.write_space();
6965 self.write_keyword("RETURNING");
6966 self.write_space();
6967 for (i, expr) in delete.returning.iter().enumerate() {
6968 if i > 0 {
6969 self.write(", ");
6970 }
6971 self.generate_expression(expr)?;
6972 }
6973 }
6974
6975 Ok(())
6976 }
6977
6978 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
6981 let saved_athena_hive_context = self.athena_hive_context;
6985 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
6986 if matches!(
6987 self.config.dialect,
6988 Some(crate::dialects::DialectType::Athena)
6989 ) {
6990 let is_external = ct
6994 .table_modifier
6995 .as_ref()
6996 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
6997 .unwrap_or(false);
6998 let has_as_select = ct.as_select.is_some();
6999 self.athena_hive_context = is_external || !has_as_select;
7000 }
7001
7002 if matches!(
7004 self.config.dialect,
7005 Some(crate::dialects::DialectType::TSQL)
7006 ) {
7007 if let Some(ref query) = ct.as_select {
7008 if let Some(with_cte) = &ct.with_cte {
7010 self.generate_with(with_cte)?;
7011 self.write_space();
7012 }
7013
7014 self.write_keyword("SELECT");
7016 self.write(" * ");
7017 self.write_keyword("INTO");
7018 self.write_space();
7019
7020 if ct.temporary {
7022 self.write("#");
7023 }
7024 self.generate_table(&ct.name)?;
7025
7026 self.write_space();
7027 self.write_keyword("FROM");
7028 self.write(" (");
7029 let aliased_query = Self::add_column_aliases_to_query(query.clone());
7031 self.generate_expression(&aliased_query)?;
7032 self.write(") ");
7033 self.write_keyword("AS");
7034 self.write(" temp");
7035 return Ok(());
7036 }
7037 }
7038
7039 if let Some(with_cte) = &ct.with_cte {
7041 self.generate_with(with_cte)?;
7042 self.write_space();
7043 }
7044
7045 for comment in &ct.leading_comments {
7047 self.write_formatted_comment(comment);
7048 self.write(" ");
7049 }
7050 self.write_keyword("CREATE");
7051
7052 if ct.or_replace {
7053 self.write_space();
7054 self.write_keyword("OR REPLACE");
7055 }
7056
7057 if ct.temporary {
7058 self.write_space();
7059 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
7061 self.write_keyword("GLOBAL TEMPORARY");
7062 } else {
7063 self.write_keyword("TEMPORARY");
7064 }
7065 }
7066
7067 let is_dictionary = ct
7069 .table_modifier
7070 .as_ref()
7071 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
7072 .unwrap_or(false);
7073 if let Some(ref modifier) = ct.table_modifier {
7074 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
7076 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
7077 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
7079 || modifier.eq_ignore_ascii_case("SET")
7080 || modifier.eq_ignore_ascii_case("MULTISET")
7081 || modifier.to_uppercase().contains("VOLATILE")
7082 || modifier.to_uppercase().starts_with("SET ")
7083 || modifier.to_uppercase().starts_with("MULTISET ");
7084 let skip_teradata =
7085 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
7086 if !skip_transient && !skip_teradata {
7087 self.write_space();
7088 self.write_keyword(modifier);
7089 }
7090 }
7091
7092 if !is_dictionary {
7093 self.write_space();
7094 self.write_keyword("TABLE");
7095 }
7096
7097 if ct.if_not_exists {
7098 self.write_space();
7099 self.write_keyword("IF NOT EXISTS");
7100 }
7101
7102 self.write_space();
7103 self.generate_table(&ct.name)?;
7104
7105 if let Some(ref on_cluster) = ct.on_cluster {
7107 self.write_space();
7108 self.generate_on_cluster(on_cluster)?;
7109 }
7110
7111 if matches!(
7113 self.config.dialect,
7114 Some(crate::dialects::DialectType::Teradata)
7115 ) && !ct.teradata_post_name_options.is_empty()
7116 {
7117 for opt in &ct.teradata_post_name_options {
7118 self.write(", ");
7119 self.write(opt);
7120 }
7121 }
7122
7123 if ct.copy_grants {
7125 self.write_space();
7126 self.write_keyword("COPY GRANTS");
7127 }
7128
7129 if let Some(ref using_template) = ct.using_template {
7131 self.write_space();
7132 self.write_keyword("USING TEMPLATE");
7133 self.write_space();
7134 self.generate_expression(using_template)?;
7135 return Ok(());
7136 }
7137
7138 if let Some(ref clone_source) = ct.clone_source {
7140 self.write_space();
7141 if ct.is_copy && self.config.supports_table_copy {
7142 self.write_keyword("COPY");
7144 } else if ct.shallow_clone {
7145 self.write_keyword("SHALLOW CLONE");
7146 } else {
7147 self.write_keyword("CLONE");
7148 }
7149 self.write_space();
7150 self.generate_table(clone_source)?;
7151 if let Some(ref at_clause) = ct.clone_at_clause {
7153 self.write_space();
7154 self.generate_expression(at_clause)?;
7155 }
7156 return Ok(());
7157 }
7158
7159 if let Some(ref partition_of) = ct.partition_of {
7163 self.write_space();
7164
7165 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
7167 self.write_keyword("PARTITION OF");
7169 self.write_space();
7170 self.generate_expression(&pop.this)?;
7171
7172 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7174 self.write(" (");
7175 let mut first = true;
7176 for col in &ct.columns {
7177 if !first {
7178 self.write(", ");
7179 }
7180 first = false;
7181 self.generate_column_def(col)?;
7182 }
7183 for constraint in &ct.constraints {
7184 if !first {
7185 self.write(", ");
7186 }
7187 first = false;
7188 self.generate_table_constraint(constraint)?;
7189 }
7190 self.write(")");
7191 }
7192
7193 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
7195 self.write_space();
7196 self.write_keyword("FOR VALUES");
7197 self.write_space();
7198 self.generate_expression(&pop.expression)?;
7199 } else {
7200 self.write_space();
7201 self.write_keyword("DEFAULT");
7202 }
7203 } else {
7204 self.generate_expression(partition_of)?;
7206
7207 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7209 self.write(" (");
7210 let mut first = true;
7211 for col in &ct.columns {
7212 if !first {
7213 self.write(", ");
7214 }
7215 first = false;
7216 self.generate_column_def(col)?;
7217 }
7218 for constraint in &ct.constraints {
7219 if !first {
7220 self.write(", ");
7221 }
7222 first = false;
7223 self.generate_table_constraint(constraint)?;
7224 }
7225 self.write(")");
7226 }
7227 }
7228
7229 for prop in &ct.properties {
7231 self.write_space();
7232 self.generate_expression(prop)?;
7233 }
7234
7235 return Ok(());
7236 }
7237
7238 self.sqlite_inline_pk_columns.clear();
7241 if matches!(
7242 self.config.dialect,
7243 Some(crate::dialects::DialectType::SQLite)
7244 ) {
7245 for constraint in &ct.constraints {
7246 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7247 if columns.len() == 1 && name.is_none() {
7249 let pk_col_name = columns[0].name.to_lowercase();
7250 if ct
7252 .columns
7253 .iter()
7254 .any(|c| c.name.name.to_lowercase() == pk_col_name)
7255 {
7256 self.sqlite_inline_pk_columns.insert(pk_col_name);
7257 }
7258 }
7259 }
7260 }
7261 }
7262
7263 if !ct.columns.is_empty() {
7265 if self.config.pretty {
7266 self.write(" (");
7268 self.write_newline();
7269 self.indent_level += 1;
7270 for (i, col) in ct.columns.iter().enumerate() {
7271 if i > 0 {
7272 self.write(",");
7273 self.write_newline();
7274 }
7275 self.write_indent();
7276 self.generate_column_def(col)?;
7277 }
7278 for constraint in &ct.constraints {
7280 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7282 if columns.len() == 1
7283 && name.is_none()
7284 && self
7285 .sqlite_inline_pk_columns
7286 .contains(&columns[0].name.to_lowercase())
7287 {
7288 continue;
7289 }
7290 }
7291 self.write(",");
7292 self.write_newline();
7293 self.write_indent();
7294 self.generate_table_constraint(constraint)?;
7295 }
7296 self.indent_level -= 1;
7297 self.write_newline();
7298 self.write(")");
7299 } else {
7300 self.write(" (");
7301 for (i, col) in ct.columns.iter().enumerate() {
7302 if i > 0 {
7303 self.write(", ");
7304 }
7305 self.generate_column_def(col)?;
7306 }
7307 let mut first_constraint = true;
7309 for constraint in &ct.constraints {
7310 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7312 if columns.len() == 1
7313 && name.is_none()
7314 && self
7315 .sqlite_inline_pk_columns
7316 .contains(&columns[0].name.to_lowercase())
7317 {
7318 continue;
7319 }
7320 }
7321 if first_constraint {
7322 self.write(", ");
7323 first_constraint = false;
7324 } else {
7325 self.write(", ");
7326 }
7327 self.generate_table_constraint(constraint)?;
7328 }
7329 self.write(")");
7330 }
7331 } else if !ct.constraints.is_empty() {
7332 let has_like_only = ct
7334 .constraints
7335 .iter()
7336 .all(|c| matches!(c, TableConstraint::Like { .. }));
7337 let has_tags_only = ct
7338 .constraints
7339 .iter()
7340 .all(|c| matches!(c, TableConstraint::Tags(_)));
7341 let is_pg_like = matches!(
7345 self.config.dialect,
7346 Some(crate::dialects::DialectType::PostgreSQL)
7347 | Some(crate::dialects::DialectType::CockroachDB)
7348 | Some(crate::dialects::DialectType::Materialize)
7349 | Some(crate::dialects::DialectType::RisingWave)
7350 | Some(crate::dialects::DialectType::Redshift)
7351 | Some(crate::dialects::DialectType::Presto)
7352 | Some(crate::dialects::DialectType::Trino)
7353 | Some(crate::dialects::DialectType::Athena)
7354 );
7355 let use_parens = if has_like_only {
7356 is_pg_like
7357 } else {
7358 !has_tags_only
7359 };
7360 if self.config.pretty && use_parens {
7361 self.write(" (");
7362 self.write_newline();
7363 self.indent_level += 1;
7364 for (i, constraint) in ct.constraints.iter().enumerate() {
7365 if i > 0 {
7366 self.write(",");
7367 self.write_newline();
7368 }
7369 self.write_indent();
7370 self.generate_table_constraint(constraint)?;
7371 }
7372 self.indent_level -= 1;
7373 self.write_newline();
7374 self.write(")");
7375 } else {
7376 if use_parens {
7377 self.write(" (");
7378 } else {
7379 self.write_space();
7380 }
7381 for (i, constraint) in ct.constraints.iter().enumerate() {
7382 if i > 0 {
7383 self.write(", ");
7384 }
7385 self.generate_table_constraint(constraint)?;
7386 }
7387 if use_parens {
7388 self.write(")");
7389 }
7390 }
7391 }
7392
7393 if let Some(ref on_prop) = ct.on_property {
7395 self.write(" ");
7396 self.write_keyword("ON");
7397 self.write(" ");
7398 self.generate_expression(&on_prop.this)?;
7399 }
7400
7401 if !is_clickhouse {
7404 for prop in &ct.properties {
7405 if let Expression::SchemaCommentProperty(_) = prop {
7406 if self.config.pretty {
7407 self.write_newline();
7408 } else {
7409 self.write_space();
7410 }
7411 self.generate_expression(prop)?;
7412 }
7413 }
7414 }
7415
7416 if !ct.with_properties.is_empty() {
7418 let is_snowflake_special_table = matches!(
7420 self.config.dialect,
7421 Some(crate::dialects::DialectType::Snowflake)
7422 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
7423 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
7424 if is_snowflake_special_table {
7425 for (key, value) in &ct.with_properties {
7426 self.write_space();
7427 self.write(key);
7428 self.write("=");
7429 self.write(value);
7430 }
7431 } else if self.config.pretty {
7432 self.write_newline();
7433 self.write_keyword("WITH");
7434 self.write(" (");
7435 self.write_newline();
7436 self.indent_level += 1;
7437 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7438 if i > 0 {
7439 self.write(",");
7440 self.write_newline();
7441 }
7442 self.write_indent();
7443 self.write(key);
7444 self.write("=");
7445 self.write(value);
7446 }
7447 self.indent_level -= 1;
7448 self.write_newline();
7449 self.write(")");
7450 } else {
7451 self.write_space();
7452 self.write_keyword("WITH");
7453 self.write(" (");
7454 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7455 if i > 0 {
7456 self.write(", ");
7457 }
7458 self.write(key);
7459 self.write("=");
7460 self.write(value);
7461 }
7462 self.write(")");
7463 }
7464 }
7465
7466 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
7467 if is_clickhouse && ct.as_select.is_some() {
7468 let mut pre = Vec::new();
7469 let mut post = Vec::new();
7470 for prop in &ct.properties {
7471 if matches!(prop, Expression::SchemaCommentProperty(_)) {
7472 post.push(prop);
7473 } else {
7474 pre.push(prop);
7475 }
7476 }
7477 (pre, post)
7478 } else {
7479 (ct.properties.iter().collect(), Vec::new())
7480 };
7481
7482 for prop in pre_as_properties {
7484 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
7486 continue;
7487 }
7488 if self.config.pretty {
7489 self.write_newline();
7490 } else {
7491 self.write_space();
7492 }
7493 if let Expression::Properties(props) = prop {
7497 let is_hive_dialect = matches!(
7498 self.config.dialect,
7499 Some(crate::dialects::DialectType::Hive)
7500 | Some(crate::dialects::DialectType::Spark)
7501 | Some(crate::dialects::DialectType::Databricks)
7502 | Some(crate::dialects::DialectType::Athena)
7503 );
7504 let is_doris_starrocks = matches!(
7505 self.config.dialect,
7506 Some(crate::dialects::DialectType::Doris)
7507 | Some(crate::dialects::DialectType::StarRocks)
7508 );
7509 if is_hive_dialect {
7510 self.generate_tblproperties_clause(&props.expressions)?;
7511 } else if is_doris_starrocks {
7512 self.generate_properties_clause(&props.expressions)?;
7513 } else {
7514 self.generate_options_clause(&props.expressions)?;
7515 }
7516 } else {
7517 self.generate_expression(prop)?;
7518 }
7519 }
7520
7521 for prop in &ct.post_table_properties {
7523 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
7524 self.write(" WITH(");
7525 self.generate_system_versioning_content(svp)?;
7526 self.write(")");
7527 } else if let Expression::Properties(props) = prop {
7528 let is_doris_starrocks = matches!(
7530 self.config.dialect,
7531 Some(crate::dialects::DialectType::Doris)
7532 | Some(crate::dialects::DialectType::StarRocks)
7533 );
7534 self.write_space();
7535 if is_doris_starrocks {
7536 self.generate_properties_clause(&props.expressions)?;
7537 } else {
7538 self.generate_options_clause(&props.expressions)?;
7539 }
7540 } else {
7541 self.write_space();
7542 self.generate_expression(prop)?;
7543 }
7544 }
7545
7546 if let Some(ref rollup) = ct.rollup {
7549 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
7550 self.write_space();
7551 self.generate_rollup_property(rollup)?;
7552 }
7553 }
7554
7555 let is_mysql_compatible = matches!(
7559 self.config.dialect,
7560 Some(DialectType::MySQL)
7561 | Some(DialectType::SingleStore)
7562 | Some(DialectType::Doris)
7563 | Some(DialectType::StarRocks)
7564 | None
7565 );
7566 let is_hive_compatible = matches!(
7567 self.config.dialect,
7568 Some(DialectType::Hive)
7569 | Some(DialectType::Spark)
7570 | Some(DialectType::Databricks)
7571 | Some(DialectType::Athena)
7572 );
7573 let mysql_pretty_options =
7574 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
7575 for (key, value) in &ct.mysql_table_options {
7576 let should_output = if is_mysql_compatible {
7578 true
7579 } else if is_hive_compatible && key == "COMMENT" {
7580 true } else {
7582 false
7583 };
7584 if should_output {
7585 if mysql_pretty_options {
7586 self.write_newline();
7587 self.write_indent();
7588 } else {
7589 self.write_space();
7590 }
7591 self.write_keyword(key);
7592 if key == "COMMENT" && !self.config.schema_comment_with_eq {
7594 self.write_space();
7595 } else {
7596 self.write("=");
7597 }
7598 self.write(value);
7599 }
7600 }
7601
7602 if ct.temporary
7604 && matches!(
7605 self.config.dialect,
7606 Some(DialectType::Spark) | Some(DialectType::Databricks)
7607 )
7608 && ct.as_select.is_none()
7609 {
7610 self.write_space();
7611 self.write_keyword("USING PARQUET");
7612 }
7613
7614 if !ct.inherits.is_empty() {
7616 self.write_space();
7617 self.write_keyword("INHERITS");
7618 self.write(" (");
7619 for (i, parent) in ct.inherits.iter().enumerate() {
7620 if i > 0 {
7621 self.write(", ");
7622 }
7623 self.generate_table(parent)?;
7624 }
7625 self.write(")");
7626 }
7627
7628 if let Some(ref query) = ct.as_select {
7630 self.write_space();
7631 self.write_keyword("AS");
7632 self.write_space();
7633 if ct.as_select_parenthesized {
7634 self.write("(");
7635 }
7636 self.generate_expression(query)?;
7637 if ct.as_select_parenthesized {
7638 self.write(")");
7639 }
7640
7641 if let Some(with_data) = ct.with_data {
7643 self.write_space();
7644 self.write_keyword("WITH");
7645 if !with_data {
7646 self.write_space();
7647 self.write_keyword("NO");
7648 }
7649 self.write_space();
7650 self.write_keyword("DATA");
7651 }
7652
7653 if let Some(with_statistics) = ct.with_statistics {
7655 self.write_space();
7656 self.write_keyword("AND");
7657 if !with_statistics {
7658 self.write_space();
7659 self.write_keyword("NO");
7660 }
7661 self.write_space();
7662 self.write_keyword("STATISTICS");
7663 }
7664
7665 for index in &ct.teradata_indexes {
7667 self.write_space();
7668 match index.kind {
7669 TeradataIndexKind::NoPrimary => {
7670 self.write_keyword("NO PRIMARY INDEX");
7671 }
7672 TeradataIndexKind::Primary => {
7673 self.write_keyword("PRIMARY INDEX");
7674 }
7675 TeradataIndexKind::PrimaryAmp => {
7676 self.write_keyword("PRIMARY AMP INDEX");
7677 }
7678 TeradataIndexKind::Unique => {
7679 self.write_keyword("UNIQUE INDEX");
7680 }
7681 TeradataIndexKind::UniquePrimary => {
7682 self.write_keyword("UNIQUE PRIMARY INDEX");
7683 }
7684 TeradataIndexKind::Secondary => {
7685 self.write_keyword("INDEX");
7686 }
7687 }
7688 if let Some(ref name) = index.name {
7690 self.write_space();
7691 self.write(name);
7692 }
7693 if !index.columns.is_empty() {
7695 self.write(" (");
7696 for (i, col) in index.columns.iter().enumerate() {
7697 if i > 0 {
7698 self.write(", ");
7699 }
7700 self.write(col);
7701 }
7702 self.write(")");
7703 }
7704 }
7705
7706 if let Some(ref on_commit) = ct.on_commit {
7708 self.write_space();
7709 self.write_keyword("ON COMMIT");
7710 self.write_space();
7711 match on_commit {
7712 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
7713 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
7714 }
7715 }
7716
7717 if !post_as_properties.is_empty() {
7718 for prop in post_as_properties {
7719 self.write_space();
7720 self.generate_expression(prop)?;
7721 }
7722 }
7723
7724 self.athena_hive_context = saved_athena_hive_context;
7726 return Ok(());
7727 }
7728
7729 if let Some(ref on_commit) = ct.on_commit {
7731 self.write_space();
7732 self.write_keyword("ON COMMIT");
7733 self.write_space();
7734 match on_commit {
7735 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
7736 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
7737 }
7738 }
7739
7740 self.athena_hive_context = saved_athena_hive_context;
7742
7743 Ok(())
7744 }
7745
7746 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
7749 self.generate_identifier(&col.name)?;
7751 if !matches!(col.data_type, DataType::Unknown) {
7753 self.write_space();
7754 self.generate_data_type(&col.data_type)?;
7755 }
7756 for constraint in &col.constraints {
7758 if let ColumnConstraint::Path(path_expr) = constraint {
7759 self.write_space();
7760 self.write_keyword("PATH");
7761 self.write_space();
7762 self.generate_expression(path_expr)?;
7763 }
7764 }
7765 Ok(())
7766 }
7767
7768 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
7769 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
7771 && col
7772 .constraints
7773 .iter()
7774 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
7775 let omit_computed_type = !self.config.computed_column_with_type
7777 && col
7778 .constraints
7779 .iter()
7780 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
7781
7782 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
7785
7786 let has_no_type = col.no_type
7789 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
7790 && col.constraints.is_empty());
7791
7792 self.generate_identifier(&col.name)?;
7793
7794 let serial_expansion = if matches!(
7796 self.config.dialect,
7797 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
7798 ) {
7799 if let DataType::Custom { ref name } = col.data_type {
7800 match name.to_uppercase().as_str() {
7801 "SERIAL" => Some("INT"),
7802 "BIGSERIAL" => Some("BIGINT"),
7803 "SMALLSERIAL" => Some("SMALLINT"),
7804 _ => None,
7805 }
7806 } else {
7807 None
7808 }
7809 } else {
7810 None
7811 };
7812
7813 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
7814 {
7815 self.write_space();
7816 let saved_nullable_depth = self.clickhouse_nullable_depth;
7819 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
7820 self.clickhouse_nullable_depth = -1;
7821 }
7822 if let Some(int_type) = serial_expansion {
7823 self.write_keyword(int_type);
7825 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
7826 let unsigned_type = match &col.data_type {
7828 DataType::Int { .. } => Some("UINTEGER"),
7829 DataType::BigInt { .. } => Some("UBIGINT"),
7830 DataType::SmallInt { .. } => Some("USMALLINT"),
7831 DataType::TinyInt { .. } => Some("UTINYINT"),
7832 _ => None,
7833 };
7834 if let Some(utype) = unsigned_type {
7835 self.write_keyword(utype);
7836 } else {
7837 self.generate_data_type(&col.data_type)?;
7838 }
7839 } else {
7840 self.generate_data_type(&col.data_type)?;
7841 }
7842 self.clickhouse_nullable_depth = saved_nullable_depth;
7843 }
7844
7845 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
7848 self.write_space();
7849 self.write_keyword("UNSIGNED");
7850 }
7851 if col.zerofill {
7852 self.write_space();
7853 self.write_keyword("ZEROFILL");
7854 }
7855
7856 if let Some(ref charset) = col.character_set {
7860 self.write_space();
7861 self.write_keyword("CHARACTER SET");
7862 self.write_space();
7863 self.write(charset);
7864 }
7865
7866 if col.uppercase {
7867 self.write_space();
7868 self.write_keyword("UPPERCASE");
7869 }
7870
7871 if let Some(casespecific) = col.casespecific {
7872 self.write_space();
7873 if casespecific {
7874 self.write_keyword("CASESPECIFIC");
7875 } else {
7876 self.write_keyword("NOT CASESPECIFIC");
7877 }
7878 }
7879
7880 if let Some(ref format) = col.format {
7881 self.write_space();
7882 self.write_keyword("FORMAT");
7883 self.write(" '");
7884 self.write(format);
7885 self.write("'");
7886 }
7887
7888 if let Some(ref title) = col.title {
7889 self.write_space();
7890 self.write_keyword("TITLE");
7891 self.write(" '");
7892 self.write(title);
7893 self.write("'");
7894 }
7895
7896 if let Some(length) = col.inline_length {
7897 self.write_space();
7898 self.write_keyword("INLINE LENGTH");
7899 self.write(" ");
7900 self.write(&length.to_string());
7901 }
7902
7903 if let Some(ref compress) = col.compress {
7904 self.write_space();
7905 self.write_keyword("COMPRESS");
7906 if !compress.is_empty() {
7907 if compress.len() == 1 {
7909 if let Expression::Literal(Literal::String(_)) = &compress[0] {
7910 self.write_space();
7911 self.generate_expression(&compress[0])?;
7912 } else {
7913 self.write(" (");
7914 self.generate_expression(&compress[0])?;
7915 self.write(")");
7916 }
7917 } else {
7918 self.write(" (");
7919 for (i, val) in compress.iter().enumerate() {
7920 if i > 0 {
7921 self.write(", ");
7922 }
7923 self.generate_expression(val)?;
7924 }
7925 self.write(")");
7926 }
7927 }
7928 }
7929
7930 if !col.constraint_order.is_empty() {
7933 let mut references_idx = 0;
7936 let mut check_idx = 0;
7937 let mut generated_idx = 0;
7938 let mut collate_idx = 0;
7939 let mut comment_idx = 0;
7940 let defer_not_null_after_identity = false;
7943 let mut pending_not_null_after_identity = false;
7944
7945 for constraint_type in &col.constraint_order {
7946 match constraint_type {
7947 ConstraintType::PrimaryKey => {
7948 if col.primary_key
7950 && !matches!(self.config.dialect, Some(DialectType::Materialize))
7951 {
7952 if let Some(ref cname) = col.primary_key_constraint_name {
7953 self.write_space();
7954 self.write_keyword("CONSTRAINT");
7955 self.write_space();
7956 self.write(cname);
7957 }
7958 self.write_space();
7959 self.write_keyword("PRIMARY KEY");
7960 if let Some(ref order) = col.primary_key_order {
7961 self.write_space();
7962 match order {
7963 SortOrder::Asc => self.write_keyword("ASC"),
7964 SortOrder::Desc => self.write_keyword("DESC"),
7965 }
7966 }
7967 }
7968 }
7969 ConstraintType::Unique => {
7970 if col.unique {
7971 if let Some(ref cname) = col.unique_constraint_name {
7972 self.write_space();
7973 self.write_keyword("CONSTRAINT");
7974 self.write_space();
7975 self.write(cname);
7976 }
7977 self.write_space();
7978 self.write_keyword("UNIQUE");
7979 if col.unique_nulls_not_distinct {
7981 self.write(" NULLS NOT DISTINCT");
7982 }
7983 }
7984 }
7985 ConstraintType::NotNull => {
7986 if col.nullable == Some(false) {
7987 if defer_not_null_after_identity {
7988 pending_not_null_after_identity = true;
7989 continue;
7990 }
7991 if let Some(ref cname) = col.not_null_constraint_name {
7992 self.write_space();
7993 self.write_keyword("CONSTRAINT");
7994 self.write_space();
7995 self.write(cname);
7996 }
7997 self.write_space();
7998 self.write_keyword("NOT NULL");
7999 }
8000 }
8001 ConstraintType::Null => {
8002 if col.nullable == Some(true) {
8003 self.write_space();
8004 self.write_keyword("NULL");
8005 }
8006 }
8007 ConstraintType::Default => {
8008 if let Some(ref default) = col.default {
8009 self.write_space();
8010 self.write_keyword("DEFAULT");
8011 self.write_space();
8012 self.generate_expression(default)?;
8013 }
8014 }
8015 ConstraintType::AutoIncrement => {
8016 if col.auto_increment {
8017 if matches!(
8019 self.config.dialect,
8020 Some(crate::dialects::DialectType::DuckDB)
8021 ) {
8022 } else if matches!(
8024 self.config.dialect,
8025 Some(crate::dialects::DialectType::Materialize)
8026 ) {
8027 if !matches!(col.nullable, Some(false)) {
8029 self.write_space();
8030 self.write_keyword("NOT NULL");
8031 }
8032 } else if matches!(
8033 self.config.dialect,
8034 Some(crate::dialects::DialectType::PostgreSQL)
8035 ) {
8036 self.write_space();
8038 self.generate_auto_increment_keyword(col)?;
8039 } else {
8040 self.write_space();
8041 self.generate_auto_increment_keyword(col)?;
8042 if pending_not_null_after_identity {
8043 self.write_space();
8044 self.write_keyword("NOT NULL");
8045 pending_not_null_after_identity = false;
8046 }
8047 }
8048 } }
8050 ConstraintType::References => {
8051 while references_idx < col.constraints.len() {
8053 if let ColumnConstraint::References(fk_ref) =
8054 &col.constraints[references_idx]
8055 {
8056 if let Some(ref name) = fk_ref.constraint_name {
8058 self.write_space();
8059 self.write_keyword("CONSTRAINT");
8060 self.write_space();
8061 self.write(name);
8062 }
8063 self.write_space();
8064 if fk_ref.has_foreign_key_keywords {
8065 self.write_keyword("FOREIGN KEY");
8066 self.write_space();
8067 }
8068 self.write_keyword("REFERENCES");
8069 self.write_space();
8070 self.generate_table(&fk_ref.table)?;
8071 if !fk_ref.columns.is_empty() {
8072 self.write(" (");
8073 for (i, c) in fk_ref.columns.iter().enumerate() {
8074 if i > 0 {
8075 self.write(", ");
8076 }
8077 self.generate_identifier(c)?;
8078 }
8079 self.write(")");
8080 }
8081 self.generate_referential_actions(fk_ref)?;
8082 references_idx += 1;
8083 break;
8084 }
8085 references_idx += 1;
8086 }
8087 }
8088 ConstraintType::Check => {
8089 while check_idx < col.constraints.len() {
8091 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
8092 if check_idx == 0 {
8094 if let Some(ref cname) = col.check_constraint_name {
8095 self.write_space();
8096 self.write_keyword("CONSTRAINT");
8097 self.write_space();
8098 self.write(cname);
8099 }
8100 }
8101 self.write_space();
8102 self.write_keyword("CHECK");
8103 self.write(" (");
8104 self.generate_expression(expr)?;
8105 self.write(")");
8106 check_idx += 1;
8107 break;
8108 }
8109 check_idx += 1;
8110 }
8111 }
8112 ConstraintType::GeneratedAsIdentity => {
8113 while generated_idx < col.constraints.len() {
8115 if let ColumnConstraint::GeneratedAsIdentity(gen) =
8116 &col.constraints[generated_idx]
8117 {
8118 self.write_space();
8119 if matches!(
8121 self.config.dialect,
8122 Some(crate::dialects::DialectType::Redshift)
8123 ) {
8124 self.write_keyword("IDENTITY");
8125 self.write("(");
8126 if let Some(ref start) = gen.start {
8127 self.generate_expression(start)?;
8128 } else {
8129 self.write("0");
8130 }
8131 self.write(", ");
8132 if let Some(ref incr) = gen.increment {
8133 self.generate_expression(incr)?;
8134 } else {
8135 self.write("1");
8136 }
8137 self.write(")");
8138 } else {
8139 self.write_keyword("GENERATED");
8140 if gen.always {
8141 self.write_space();
8142 self.write_keyword("ALWAYS");
8143 } else {
8144 self.write_space();
8145 self.write_keyword("BY DEFAULT");
8146 if gen.on_null {
8147 self.write_space();
8148 self.write_keyword("ON NULL");
8149 }
8150 }
8151 self.write_space();
8152 self.write_keyword("AS IDENTITY");
8153
8154 let has_options = gen.start.is_some()
8155 || gen.increment.is_some()
8156 || gen.minvalue.is_some()
8157 || gen.maxvalue.is_some()
8158 || gen.cycle.is_some();
8159 if has_options {
8160 self.write(" (");
8161 let mut first = true;
8162 if let Some(ref start) = gen.start {
8163 if !first {
8164 self.write(" ");
8165 }
8166 first = false;
8167 self.write_keyword("START WITH");
8168 self.write_space();
8169 self.generate_expression(start)?;
8170 }
8171 if let Some(ref incr) = gen.increment {
8172 if !first {
8173 self.write(" ");
8174 }
8175 first = false;
8176 self.write_keyword("INCREMENT BY");
8177 self.write_space();
8178 self.generate_expression(incr)?;
8179 }
8180 if let Some(ref minv) = gen.minvalue {
8181 if !first {
8182 self.write(" ");
8183 }
8184 first = false;
8185 self.write_keyword("MINVALUE");
8186 self.write_space();
8187 self.generate_expression(minv)?;
8188 }
8189 if let Some(ref maxv) = gen.maxvalue {
8190 if !first {
8191 self.write(" ");
8192 }
8193 first = false;
8194 self.write_keyword("MAXVALUE");
8195 self.write_space();
8196 self.generate_expression(maxv)?;
8197 }
8198 if let Some(cycle) = gen.cycle {
8199 if !first {
8200 self.write(" ");
8201 }
8202 if cycle {
8203 self.write_keyword("CYCLE");
8204 } else {
8205 self.write_keyword("NO CYCLE");
8206 }
8207 }
8208 self.write(")");
8209 }
8210 }
8211 generated_idx += 1;
8212 break;
8213 }
8214 generated_idx += 1;
8215 }
8216 }
8217 ConstraintType::Collate => {
8218 while collate_idx < col.constraints.len() {
8220 if let ColumnConstraint::Collate(collation) =
8221 &col.constraints[collate_idx]
8222 {
8223 self.write_space();
8224 self.write_keyword("COLLATE");
8225 self.write_space();
8226 self.generate_identifier(collation)?;
8227 collate_idx += 1;
8228 break;
8229 }
8230 collate_idx += 1;
8231 }
8232 }
8233 ConstraintType::Comment => {
8234 while comment_idx < col.constraints.len() {
8236 if let ColumnConstraint::Comment(comment) =
8237 &col.constraints[comment_idx]
8238 {
8239 self.write_space();
8240 self.write_keyword("COMMENT");
8241 self.write_space();
8242 self.generate_string_literal(comment)?;
8243 comment_idx += 1;
8244 break;
8245 }
8246 comment_idx += 1;
8247 }
8248 }
8249 ConstraintType::Tags => {
8250 for constraint in &col.constraints {
8252 if let ColumnConstraint::Tags(tags) = constraint {
8253 self.write_space();
8254 self.write_keyword("TAG");
8255 self.write(" (");
8256 for (i, expr) in tags.expressions.iter().enumerate() {
8257 if i > 0 {
8258 self.write(", ");
8259 }
8260 self.generate_expression(expr)?;
8261 }
8262 self.write(")");
8263 break;
8264 }
8265 }
8266 }
8267 ConstraintType::ComputedColumn => {
8268 for constraint in &col.constraints {
8270 if let ColumnConstraint::ComputedColumn(cc) = constraint {
8271 self.write_space();
8272 self.generate_computed_column_inline(cc)?;
8273 break;
8274 }
8275 }
8276 }
8277 ConstraintType::GeneratedAsRow => {
8278 for constraint in &col.constraints {
8280 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
8281 self.write_space();
8282 self.generate_generated_as_row_inline(gar)?;
8283 break;
8284 }
8285 }
8286 }
8287 ConstraintType::OnUpdate => {
8288 if let Some(ref expr) = col.on_update {
8289 self.write_space();
8290 self.write_keyword("ON UPDATE");
8291 self.write_space();
8292 self.generate_expression(expr)?;
8293 }
8294 }
8295 ConstraintType::Encode => {
8296 if let Some(ref encoding) = col.encoding {
8297 self.write_space();
8298 self.write_keyword("ENCODE");
8299 self.write_space();
8300 self.write(encoding);
8301 }
8302 }
8303 ConstraintType::Path => {
8304 for constraint in &col.constraints {
8306 if let ColumnConstraint::Path(path_expr) = constraint {
8307 self.write_space();
8308 self.write_keyword("PATH");
8309 self.write_space();
8310 self.generate_expression(path_expr)?;
8311 break;
8312 }
8313 }
8314 }
8315 }
8316 }
8317 if pending_not_null_after_identity {
8318 self.write_space();
8319 self.write_keyword("NOT NULL");
8320 }
8321 } else {
8322 if col.primary_key {
8324 self.write_space();
8325 self.write_keyword("PRIMARY KEY");
8326 if let Some(ref order) = col.primary_key_order {
8327 self.write_space();
8328 match order {
8329 SortOrder::Asc => self.write_keyword("ASC"),
8330 SortOrder::Desc => self.write_keyword("DESC"),
8331 }
8332 }
8333 }
8334
8335 if col.unique {
8336 self.write_space();
8337 self.write_keyword("UNIQUE");
8338 if col.unique_nulls_not_distinct {
8340 self.write(" NULLS NOT DISTINCT");
8341 }
8342 }
8343
8344 match col.nullable {
8345 Some(false) => {
8346 self.write_space();
8347 self.write_keyword("NOT NULL");
8348 }
8349 Some(true) => {
8350 self.write_space();
8351 self.write_keyword("NULL");
8352 }
8353 None => {}
8354 }
8355
8356 if let Some(ref default) = col.default {
8357 self.write_space();
8358 self.write_keyword("DEFAULT");
8359 self.write_space();
8360 self.generate_expression(default)?;
8361 }
8362
8363 if col.auto_increment {
8364 self.write_space();
8365 self.generate_auto_increment_keyword(col)?;
8366 }
8367
8368 for constraint in &col.constraints {
8370 match constraint {
8371 ColumnConstraint::References(fk_ref) => {
8372 self.write_space();
8373 if fk_ref.has_foreign_key_keywords {
8374 self.write_keyword("FOREIGN KEY");
8375 self.write_space();
8376 }
8377 self.write_keyword("REFERENCES");
8378 self.write_space();
8379 self.generate_table(&fk_ref.table)?;
8380 if !fk_ref.columns.is_empty() {
8381 self.write(" (");
8382 for (i, c) in fk_ref.columns.iter().enumerate() {
8383 if i > 0 {
8384 self.write(", ");
8385 }
8386 self.generate_identifier(c)?;
8387 }
8388 self.write(")");
8389 }
8390 self.generate_referential_actions(fk_ref)?;
8391 }
8392 ColumnConstraint::Check(expr) => {
8393 self.write_space();
8394 self.write_keyword("CHECK");
8395 self.write(" (");
8396 self.generate_expression(expr)?;
8397 self.write(")");
8398 }
8399 ColumnConstraint::GeneratedAsIdentity(gen) => {
8400 self.write_space();
8401 if matches!(
8403 self.config.dialect,
8404 Some(crate::dialects::DialectType::Redshift)
8405 ) {
8406 self.write_keyword("IDENTITY");
8407 self.write("(");
8408 if let Some(ref start) = gen.start {
8409 self.generate_expression(start)?;
8410 } else {
8411 self.write("0");
8412 }
8413 self.write(", ");
8414 if let Some(ref incr) = gen.increment {
8415 self.generate_expression(incr)?;
8416 } else {
8417 self.write("1");
8418 }
8419 self.write(")");
8420 } else {
8421 self.write_keyword("GENERATED");
8422 if gen.always {
8423 self.write_space();
8424 self.write_keyword("ALWAYS");
8425 } else {
8426 self.write_space();
8427 self.write_keyword("BY DEFAULT");
8428 if gen.on_null {
8429 self.write_space();
8430 self.write_keyword("ON NULL");
8431 }
8432 }
8433 self.write_space();
8434 self.write_keyword("AS IDENTITY");
8435
8436 let has_options = gen.start.is_some()
8437 || gen.increment.is_some()
8438 || gen.minvalue.is_some()
8439 || gen.maxvalue.is_some()
8440 || gen.cycle.is_some();
8441 if has_options {
8442 self.write(" (");
8443 let mut first = true;
8444 if let Some(ref start) = gen.start {
8445 if !first {
8446 self.write(" ");
8447 }
8448 first = false;
8449 self.write_keyword("START WITH");
8450 self.write_space();
8451 self.generate_expression(start)?;
8452 }
8453 if let Some(ref incr) = gen.increment {
8454 if !first {
8455 self.write(" ");
8456 }
8457 first = false;
8458 self.write_keyword("INCREMENT BY");
8459 self.write_space();
8460 self.generate_expression(incr)?;
8461 }
8462 if let Some(ref minv) = gen.minvalue {
8463 if !first {
8464 self.write(" ");
8465 }
8466 first = false;
8467 self.write_keyword("MINVALUE");
8468 self.write_space();
8469 self.generate_expression(minv)?;
8470 }
8471 if let Some(ref maxv) = gen.maxvalue {
8472 if !first {
8473 self.write(" ");
8474 }
8475 first = false;
8476 self.write_keyword("MAXVALUE");
8477 self.write_space();
8478 self.generate_expression(maxv)?;
8479 }
8480 if let Some(cycle) = gen.cycle {
8481 if !first {
8482 self.write(" ");
8483 }
8484 if cycle {
8485 self.write_keyword("CYCLE");
8486 } else {
8487 self.write_keyword("NO CYCLE");
8488 }
8489 }
8490 self.write(")");
8491 }
8492 }
8493 }
8494 ColumnConstraint::Collate(collation) => {
8495 self.write_space();
8496 self.write_keyword("COLLATE");
8497 self.write_space();
8498 self.generate_identifier(collation)?;
8499 }
8500 ColumnConstraint::Comment(comment) => {
8501 self.write_space();
8502 self.write_keyword("COMMENT");
8503 self.write_space();
8504 self.generate_string_literal(comment)?;
8505 }
8506 ColumnConstraint::Path(path_expr) => {
8507 self.write_space();
8508 self.write_keyword("PATH");
8509 self.write_space();
8510 self.generate_expression(path_expr)?;
8511 }
8512 _ => {} }
8514 }
8515
8516 if let Some(ref encoding) = col.encoding {
8518 self.write_space();
8519 self.write_keyword("ENCODE");
8520 self.write_space();
8521 self.write(encoding);
8522 }
8523 }
8524
8525 if let Some(ref codec) = col.codec {
8527 self.write_space();
8528 self.write_keyword("CODEC");
8529 self.write("(");
8530 self.write(codec);
8531 self.write(")");
8532 }
8533
8534 if let Some(ref ephemeral) = col.ephemeral {
8536 self.write_space();
8537 self.write_keyword("EPHEMERAL");
8538 if let Some(ref expr) = ephemeral {
8539 self.write_space();
8540 self.generate_expression(expr)?;
8541 }
8542 }
8543
8544 if let Some(ref mat_expr) = col.materialized_expr {
8546 self.write_space();
8547 self.write_keyword("MATERIALIZED");
8548 self.write_space();
8549 self.generate_expression(mat_expr)?;
8550 }
8551
8552 if let Some(ref alias_expr) = col.alias_expr {
8554 self.write_space();
8555 self.write_keyword("ALIAS");
8556 self.write_space();
8557 self.generate_expression(alias_expr)?;
8558 }
8559
8560 if let Some(ref ttl_expr) = col.ttl_expr {
8562 self.write_space();
8563 self.write_keyword("TTL");
8564 self.write_space();
8565 self.generate_expression(ttl_expr)?;
8566 }
8567
8568 if col.not_for_replication
8570 && matches!(
8571 self.config.dialect,
8572 Some(crate::dialects::DialectType::TSQL)
8573 | Some(crate::dialects::DialectType::Fabric)
8574 )
8575 {
8576 self.write_space();
8577 self.write_keyword("NOT FOR REPLICATION");
8578 }
8579
8580 if !col.options.is_empty() {
8582 self.write_space();
8583 self.generate_options_clause(&col.options)?;
8584 }
8585
8586 if !col.primary_key
8589 && self
8590 .sqlite_inline_pk_columns
8591 .contains(&col.name.name.to_lowercase())
8592 {
8593 self.write_space();
8594 self.write_keyword("PRIMARY KEY");
8595 }
8596
8597 if serial_expansion.is_some() {
8600 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
8601 self.write_space();
8602 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
8603 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
8604 self.write_space();
8605 self.write_keyword("NOT NULL");
8606 }
8607 }
8608
8609 Ok(())
8610 }
8611
8612 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
8613 match constraint {
8614 TableConstraint::PrimaryKey {
8615 name,
8616 columns,
8617 include_columns,
8618 modifiers,
8619 has_constraint_keyword,
8620 } => {
8621 if let Some(ref n) = name {
8622 if *has_constraint_keyword {
8623 self.write_keyword("CONSTRAINT");
8624 self.write_space();
8625 self.generate_identifier(n)?;
8626 self.write_space();
8627 }
8628 }
8629 self.write_keyword("PRIMARY KEY");
8630 if let Some(ref clustered) = modifiers.clustered {
8632 self.write_space();
8633 self.write_keyword(clustered);
8634 }
8635 if let Some(ref n) = name {
8637 if !*has_constraint_keyword {
8638 self.write_space();
8639 self.generate_identifier(n)?;
8640 }
8641 }
8642 self.write(" (");
8643 for (i, col) in columns.iter().enumerate() {
8644 if i > 0 {
8645 self.write(", ");
8646 }
8647 self.generate_identifier(col)?;
8648 }
8649 self.write(")");
8650 if !include_columns.is_empty() {
8651 self.write_space();
8652 self.write_keyword("INCLUDE");
8653 self.write(" (");
8654 for (i, col) in include_columns.iter().enumerate() {
8655 if i > 0 {
8656 self.write(", ");
8657 }
8658 self.generate_identifier(col)?;
8659 }
8660 self.write(")");
8661 }
8662 self.generate_constraint_modifiers(modifiers);
8663 }
8664 TableConstraint::Unique {
8665 name,
8666 columns,
8667 columns_parenthesized,
8668 modifiers,
8669 has_constraint_keyword,
8670 nulls_not_distinct,
8671 } => {
8672 if let Some(ref n) = name {
8673 if *has_constraint_keyword {
8674 self.write_keyword("CONSTRAINT");
8675 self.write_space();
8676 self.generate_identifier(n)?;
8677 self.write_space();
8678 }
8679 }
8680 self.write_keyword("UNIQUE");
8681 if let Some(ref clustered) = modifiers.clustered {
8683 self.write_space();
8684 self.write_keyword(clustered);
8685 }
8686 if *nulls_not_distinct {
8688 self.write(" NULLS NOT DISTINCT");
8689 }
8690 if let Some(ref n) = name {
8692 if !*has_constraint_keyword {
8693 self.write_space();
8694 self.generate_identifier(n)?;
8695 }
8696 }
8697 if *columns_parenthesized {
8698 self.write(" (");
8699 for (i, col) in columns.iter().enumerate() {
8700 if i > 0 {
8701 self.write(", ");
8702 }
8703 self.generate_identifier(col)?;
8704 }
8705 self.write(")");
8706 } else {
8707 for col in columns.iter() {
8709 self.write_space();
8710 self.generate_identifier(col)?;
8711 }
8712 }
8713 self.generate_constraint_modifiers(modifiers);
8714 }
8715 TableConstraint::ForeignKey {
8716 name,
8717 columns,
8718 references,
8719 on_delete,
8720 on_update,
8721 modifiers,
8722 } => {
8723 if let Some(ref n) = name {
8724 self.write_keyword("CONSTRAINT");
8725 self.write_space();
8726 self.generate_identifier(n)?;
8727 self.write_space();
8728 }
8729 self.write_keyword("FOREIGN KEY");
8730 self.write(" (");
8731 for (i, col) in columns.iter().enumerate() {
8732 if i > 0 {
8733 self.write(", ");
8734 }
8735 self.generate_identifier(col)?;
8736 }
8737 self.write(")");
8738 if let Some(ref refs) = references {
8739 self.write(" ");
8740 self.write_keyword("REFERENCES");
8741 self.write_space();
8742 self.generate_table(&refs.table)?;
8743 if !refs.columns.is_empty() {
8744 if self.config.pretty {
8745 self.write(" (");
8746 self.write_newline();
8747 self.indent_level += 1;
8748 for (i, col) in refs.columns.iter().enumerate() {
8749 if i > 0 {
8750 self.write(",");
8751 self.write_newline();
8752 }
8753 self.write_indent();
8754 self.generate_identifier(col)?;
8755 }
8756 self.indent_level -= 1;
8757 self.write_newline();
8758 self.write_indent();
8759 self.write(")");
8760 } else {
8761 self.write(" (");
8762 for (i, col) in refs.columns.iter().enumerate() {
8763 if i > 0 {
8764 self.write(", ");
8765 }
8766 self.generate_identifier(col)?;
8767 }
8768 self.write(")");
8769 }
8770 }
8771 self.generate_referential_actions(refs)?;
8772 } else {
8773 if let Some(ref action) = on_delete {
8775 self.write_space();
8776 self.write_keyword("ON DELETE");
8777 self.write_space();
8778 self.generate_referential_action(action);
8779 }
8780 if let Some(ref action) = on_update {
8781 self.write_space();
8782 self.write_keyword("ON UPDATE");
8783 self.write_space();
8784 self.generate_referential_action(action);
8785 }
8786 }
8787 self.generate_constraint_modifiers(modifiers);
8788 }
8789 TableConstraint::Check {
8790 name,
8791 expression,
8792 modifiers,
8793 } => {
8794 if let Some(ref n) = name {
8795 self.write_keyword("CONSTRAINT");
8796 self.write_space();
8797 self.generate_identifier(n)?;
8798 self.write_space();
8799 }
8800 self.write_keyword("CHECK");
8801 self.write(" (");
8802 self.generate_expression(expression)?;
8803 self.write(")");
8804 self.generate_constraint_modifiers(modifiers);
8805 }
8806 TableConstraint::Index {
8807 name,
8808 columns,
8809 kind,
8810 modifiers,
8811 use_key_keyword,
8812 expression,
8813 index_type,
8814 granularity,
8815 } => {
8816 if expression.is_some() {
8818 self.write_keyword("INDEX");
8819 if let Some(ref n) = name {
8820 self.write_space();
8821 self.generate_identifier(n)?;
8822 }
8823 if let Some(ref expr) = expression {
8824 self.write_space();
8825 self.generate_expression(expr)?;
8826 }
8827 if let Some(ref idx_type) = index_type {
8828 self.write_space();
8829 self.write_keyword("TYPE");
8830 self.write_space();
8831 self.generate_expression(idx_type)?;
8832 }
8833 if let Some(ref gran) = granularity {
8834 self.write_space();
8835 self.write_keyword("GRANULARITY");
8836 self.write_space();
8837 self.generate_expression(gran)?;
8838 }
8839 } else {
8840 use crate::dialects::DialectType;
8844 let index_keyword = if *use_key_keyword
8845 && !matches!(self.config.dialect, Some(DialectType::MySQL))
8846 {
8847 "KEY"
8848 } else {
8849 "INDEX"
8850 };
8851
8852 if let Some(ref k) = kind {
8854 self.write_keyword(k);
8855 if k != "UNIQUE" {
8857 self.write_space();
8858 self.write_keyword(index_keyword);
8859 }
8860 } else {
8861 self.write_keyword(index_keyword);
8862 }
8863
8864 if modifiers.using_before_columns && name.is_none() {
8866 if let Some(ref using) = modifiers.using {
8867 self.write_space();
8868 self.write_keyword("USING");
8869 self.write_space();
8870 self.write_keyword(using);
8871 }
8872 }
8873
8874 if let Some(ref n) = name {
8876 self.write_space();
8877 self.generate_identifier(n)?;
8878 }
8879
8880 if modifiers.using_before_columns && name.is_some() {
8882 if let Some(ref using) = modifiers.using {
8883 self.write_space();
8884 self.write_keyword("USING");
8885 self.write_space();
8886 self.write_keyword(using);
8887 }
8888 }
8889
8890 self.write(" (");
8892 for (i, col) in columns.iter().enumerate() {
8893 if i > 0 {
8894 self.write(", ");
8895 }
8896 self.generate_identifier(col)?;
8897 }
8898 self.write(")");
8899
8900 if !modifiers.using_before_columns {
8902 if let Some(ref using) = modifiers.using {
8903 self.write_space();
8904 self.write_keyword("USING");
8905 self.write_space();
8906 self.write_keyword(using);
8907 }
8908 }
8909
8910 self.generate_constraint_modifiers_without_using(modifiers);
8912 }
8913 }
8914 TableConstraint::Projection { name, expression } => {
8915 self.write_keyword("PROJECTION");
8917 self.write_space();
8918 self.generate_identifier(name)?;
8919 self.write(" (");
8920 self.generate_expression(expression)?;
8921 self.write(")");
8922 }
8923 TableConstraint::Like { source, options } => {
8924 self.write_keyword("LIKE");
8925 self.write_space();
8926 self.generate_table(source)?;
8927 for (action, prop) in options {
8928 self.write_space();
8929 match action {
8930 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
8931 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
8932 }
8933 self.write_space();
8934 self.write_keyword(prop);
8935 }
8936 }
8937 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
8938 self.write_keyword("PERIOD FOR SYSTEM_TIME");
8939 self.write(" (");
8940 self.generate_identifier(start_col)?;
8941 self.write(", ");
8942 self.generate_identifier(end_col)?;
8943 self.write(")");
8944 }
8945 TableConstraint::Exclude {
8946 name,
8947 using,
8948 elements,
8949 include_columns,
8950 where_clause,
8951 with_params,
8952 using_index_tablespace,
8953 modifiers: _,
8954 } => {
8955 if let Some(ref n) = name {
8956 self.write_keyword("CONSTRAINT");
8957 self.write_space();
8958 self.generate_identifier(n)?;
8959 self.write_space();
8960 }
8961 self.write_keyword("EXCLUDE");
8962 if let Some(ref method) = using {
8963 self.write_space();
8964 self.write_keyword("USING");
8965 self.write_space();
8966 self.write(method);
8967 self.write("(");
8968 } else {
8969 self.write(" (");
8970 }
8971 for (i, elem) in elements.iter().enumerate() {
8972 if i > 0 {
8973 self.write(", ");
8974 }
8975 self.write(&elem.expression);
8976 self.write_space();
8977 self.write_keyword("WITH");
8978 self.write_space();
8979 self.write(&elem.operator);
8980 }
8981 self.write(")");
8982 if !include_columns.is_empty() {
8983 self.write_space();
8984 self.write_keyword("INCLUDE");
8985 self.write(" (");
8986 for (i, col) in include_columns.iter().enumerate() {
8987 if i > 0 {
8988 self.write(", ");
8989 }
8990 self.generate_identifier(col)?;
8991 }
8992 self.write(")");
8993 }
8994 if !with_params.is_empty() {
8995 self.write_space();
8996 self.write_keyword("WITH");
8997 self.write(" (");
8998 for (i, (key, val)) in with_params.iter().enumerate() {
8999 if i > 0 {
9000 self.write(", ");
9001 }
9002 self.write(key);
9003 self.write("=");
9004 self.write(val);
9005 }
9006 self.write(")");
9007 }
9008 if let Some(ref tablespace) = using_index_tablespace {
9009 self.write_space();
9010 self.write_keyword("USING INDEX TABLESPACE");
9011 self.write_space();
9012 self.write(tablespace);
9013 }
9014 if let Some(ref where_expr) = where_clause {
9015 self.write_space();
9016 self.write_keyword("WHERE");
9017 self.write(" (");
9018 self.generate_expression(where_expr)?;
9019 self.write(")");
9020 }
9021 }
9022 TableConstraint::Tags(tags) => {
9023 self.write_keyword("TAG");
9024 self.write(" (");
9025 for (i, expr) in tags.expressions.iter().enumerate() {
9026 if i > 0 {
9027 self.write(", ");
9028 }
9029 self.generate_expression(expr)?;
9030 }
9031 self.write(")");
9032 }
9033 TableConstraint::InitiallyDeferred { deferred } => {
9034 self.write_keyword("INITIALLY");
9035 self.write_space();
9036 if *deferred {
9037 self.write_keyword("DEFERRED");
9038 } else {
9039 self.write_keyword("IMMEDIATE");
9040 }
9041 }
9042 }
9043 Ok(())
9044 }
9045
9046 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9047 if let Some(using) = &modifiers.using {
9049 self.write_space();
9050 self.write_keyword("USING");
9051 self.write_space();
9052 self.write_keyword(using);
9053 }
9054 if let Some(enforced) = modifiers.enforced {
9056 self.write_space();
9057 if enforced {
9058 self.write_keyword("ENFORCED");
9059 } else {
9060 self.write_keyword("NOT ENFORCED");
9061 }
9062 }
9063 if let Some(deferrable) = modifiers.deferrable {
9065 self.write_space();
9066 if deferrable {
9067 self.write_keyword("DEFERRABLE");
9068 } else {
9069 self.write_keyword("NOT DEFERRABLE");
9070 }
9071 }
9072 if let Some(initially_deferred) = modifiers.initially_deferred {
9074 self.write_space();
9075 if initially_deferred {
9076 self.write_keyword("INITIALLY DEFERRED");
9077 } else {
9078 self.write_keyword("INITIALLY IMMEDIATE");
9079 }
9080 }
9081 if modifiers.norely {
9083 self.write_space();
9084 self.write_keyword("NORELY");
9085 }
9086 if modifiers.rely {
9088 self.write_space();
9089 self.write_keyword("RELY");
9090 }
9091 if modifiers.not_valid {
9093 self.write_space();
9094 self.write_keyword("NOT VALID");
9095 }
9096 if let Some(on_conflict) = &modifiers.on_conflict {
9098 self.write_space();
9099 self.write_keyword("ON CONFLICT");
9100 self.write_space();
9101 self.write_keyword(on_conflict);
9102 }
9103 if !modifiers.with_options.is_empty() {
9105 self.write_space();
9106 self.write_keyword("WITH");
9107 self.write(" (");
9108 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
9109 if i > 0 {
9110 self.write(", ");
9111 }
9112 self.write(key);
9113 self.write("=");
9114 self.write(value);
9115 }
9116 self.write(")");
9117 }
9118 if let Some(ref fg) = modifiers.on_filegroup {
9120 self.write_space();
9121 self.write_keyword("ON");
9122 self.write_space();
9123 let _ = self.generate_identifier(fg);
9124 }
9125 }
9126
9127 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
9129 if let Some(enforced) = modifiers.enforced {
9131 self.write_space();
9132 if enforced {
9133 self.write_keyword("ENFORCED");
9134 } else {
9135 self.write_keyword("NOT ENFORCED");
9136 }
9137 }
9138 if let Some(deferrable) = modifiers.deferrable {
9140 self.write_space();
9141 if deferrable {
9142 self.write_keyword("DEFERRABLE");
9143 } else {
9144 self.write_keyword("NOT DEFERRABLE");
9145 }
9146 }
9147 if let Some(initially_deferred) = modifiers.initially_deferred {
9149 self.write_space();
9150 if initially_deferred {
9151 self.write_keyword("INITIALLY DEFERRED");
9152 } else {
9153 self.write_keyword("INITIALLY IMMEDIATE");
9154 }
9155 }
9156 if modifiers.norely {
9158 self.write_space();
9159 self.write_keyword("NORELY");
9160 }
9161 if modifiers.rely {
9163 self.write_space();
9164 self.write_keyword("RELY");
9165 }
9166 if modifiers.not_valid {
9168 self.write_space();
9169 self.write_keyword("NOT VALID");
9170 }
9171 if let Some(on_conflict) = &modifiers.on_conflict {
9173 self.write_space();
9174 self.write_keyword("ON CONFLICT");
9175 self.write_space();
9176 self.write_keyword(on_conflict);
9177 }
9178 self.generate_index_specific_modifiers(modifiers);
9180 }
9181
9182 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9184 if let Some(ref comment) = modifiers.comment {
9185 self.write_space();
9186 self.write_keyword("COMMENT");
9187 self.write(" '");
9188 self.write(comment);
9189 self.write("'");
9190 }
9191 if let Some(visible) = modifiers.visible {
9192 self.write_space();
9193 if visible {
9194 self.write_keyword("VISIBLE");
9195 } else {
9196 self.write_keyword("INVISIBLE");
9197 }
9198 }
9199 if let Some(ref attr) = modifiers.engine_attribute {
9200 self.write_space();
9201 self.write_keyword("ENGINE_ATTRIBUTE");
9202 self.write(" = '");
9203 self.write(attr);
9204 self.write("'");
9205 }
9206 if let Some(ref parser) = modifiers.with_parser {
9207 self.write_space();
9208 self.write_keyword("WITH PARSER");
9209 self.write_space();
9210 self.write(parser);
9211 }
9212 }
9213
9214 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
9215 if !fk_ref.match_after_actions {
9217 if let Some(ref match_type) = fk_ref.match_type {
9218 self.write_space();
9219 self.write_keyword("MATCH");
9220 self.write_space();
9221 match match_type {
9222 MatchType::Full => self.write_keyword("FULL"),
9223 MatchType::Partial => self.write_keyword("PARTIAL"),
9224 MatchType::Simple => self.write_keyword("SIMPLE"),
9225 }
9226 }
9227 }
9228
9229 if fk_ref.on_update_first {
9231 if let Some(ref action) = fk_ref.on_update {
9232 self.write_space();
9233 self.write_keyword("ON UPDATE");
9234 self.write_space();
9235 self.generate_referential_action(action);
9236 }
9237 if let Some(ref action) = fk_ref.on_delete {
9238 self.write_space();
9239 self.write_keyword("ON DELETE");
9240 self.write_space();
9241 self.generate_referential_action(action);
9242 }
9243 } else {
9244 if let Some(ref action) = fk_ref.on_delete {
9245 self.write_space();
9246 self.write_keyword("ON DELETE");
9247 self.write_space();
9248 self.generate_referential_action(action);
9249 }
9250 if let Some(ref action) = fk_ref.on_update {
9251 self.write_space();
9252 self.write_keyword("ON UPDATE");
9253 self.write_space();
9254 self.generate_referential_action(action);
9255 }
9256 }
9257
9258 if fk_ref.match_after_actions {
9260 if let Some(ref match_type) = fk_ref.match_type {
9261 self.write_space();
9262 self.write_keyword("MATCH");
9263 self.write_space();
9264 match match_type {
9265 MatchType::Full => self.write_keyword("FULL"),
9266 MatchType::Partial => self.write_keyword("PARTIAL"),
9267 MatchType::Simple => self.write_keyword("SIMPLE"),
9268 }
9269 }
9270 }
9271
9272 if let Some(deferrable) = fk_ref.deferrable {
9274 self.write_space();
9275 if deferrable {
9276 self.write_keyword("DEFERRABLE");
9277 } else {
9278 self.write_keyword("NOT DEFERRABLE");
9279 }
9280 }
9281
9282 Ok(())
9283 }
9284
9285 fn generate_referential_action(&mut self, action: &ReferentialAction) {
9286 match action {
9287 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
9288 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
9289 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
9290 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
9291 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
9292 }
9293 }
9294
9295 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
9296 let saved_athena_hive_context = self.athena_hive_context;
9298 if matches!(
9299 self.config.dialect,
9300 Some(crate::dialects::DialectType::Athena)
9301 ) {
9302 self.athena_hive_context = true;
9303 }
9304
9305 for comment in &dt.leading_comments {
9307 self.write_formatted_comment(comment);
9308 self.write_space();
9309 }
9310 self.write_keyword("DROP TABLE");
9311
9312 if dt.if_exists {
9313 self.write_space();
9314 self.write_keyword("IF EXISTS");
9315 }
9316
9317 self.write_space();
9318 for (i, table) in dt.names.iter().enumerate() {
9319 if i > 0 {
9320 self.write(", ");
9321 }
9322 self.generate_table(table)?;
9323 }
9324
9325 if dt.cascade_constraints {
9326 self.write_space();
9327 self.write_keyword("CASCADE CONSTRAINTS");
9328 } else if dt.cascade {
9329 self.write_space();
9330 self.write_keyword("CASCADE");
9331 }
9332
9333 if dt.purge {
9334 self.write_space();
9335 self.write_keyword("PURGE");
9336 }
9337
9338 self.athena_hive_context = saved_athena_hive_context;
9340
9341 Ok(())
9342 }
9343
9344 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
9345 let saved_athena_hive_context = self.athena_hive_context;
9347 if matches!(
9348 self.config.dialect,
9349 Some(crate::dialects::DialectType::Athena)
9350 ) {
9351 self.athena_hive_context = true;
9352 }
9353
9354 self.write_keyword("ALTER TABLE");
9355 if at.if_exists {
9356 self.write_space();
9357 self.write_keyword("IF EXISTS");
9358 }
9359 self.write_space();
9360 self.generate_table(&at.name)?;
9361
9362 if let Some(ref on_cluster) = at.on_cluster {
9364 self.write_space();
9365 self.generate_on_cluster(on_cluster)?;
9366 }
9367
9368 if let Some(ref partition) = at.partition {
9370 self.write_space();
9371 self.write_keyword("PARTITION");
9372 self.write("(");
9373 for (i, (key, value)) in partition.iter().enumerate() {
9374 if i > 0 {
9375 self.write(", ");
9376 }
9377 self.generate_identifier(key)?;
9378 self.write(" = ");
9379 self.generate_expression(value)?;
9380 }
9381 self.write(")");
9382 }
9383
9384 if let Some(ref with_check) = at.with_check {
9386 self.write_space();
9387 self.write_keyword(with_check);
9388 }
9389
9390 if self.config.pretty {
9391 self.write_newline();
9393 self.indent_level += 1;
9394 for (i, action) in at.actions.iter().enumerate() {
9395 let is_continuation = i > 0
9397 && matches!(
9398 (&at.actions[i - 1], action),
9399 (
9400 AlterTableAction::AddColumn { .. },
9401 AlterTableAction::AddColumn { .. }
9402 ) | (
9403 AlterTableAction::AddConstraint(_),
9404 AlterTableAction::AddConstraint(_)
9405 )
9406 );
9407 if i > 0 {
9408 self.write(",");
9409 self.write_newline();
9410 }
9411 self.write_indent();
9412 self.generate_alter_action_with_continuation(action, is_continuation)?;
9413 }
9414 self.indent_level -= 1;
9415 } else {
9416 for (i, action) in at.actions.iter().enumerate() {
9417 let is_continuation = i > 0
9419 && matches!(
9420 (&at.actions[i - 1], action),
9421 (
9422 AlterTableAction::AddColumn { .. },
9423 AlterTableAction::AddColumn { .. }
9424 ) | (
9425 AlterTableAction::AddConstraint(_),
9426 AlterTableAction::AddConstraint(_)
9427 )
9428 );
9429 if i > 0 {
9430 self.write(",");
9431 }
9432 self.write_space();
9433 self.generate_alter_action_with_continuation(action, is_continuation)?;
9434 }
9435 }
9436
9437 if let Some(ref algorithm) = at.algorithm {
9439 self.write(", ");
9440 self.write_keyword("ALGORITHM");
9441 self.write("=");
9442 self.write_keyword(algorithm);
9443 }
9444 if let Some(ref lock) = at.lock {
9445 self.write(", ");
9446 self.write_keyword("LOCK");
9447 self.write("=");
9448 self.write_keyword(lock);
9449 }
9450
9451 self.athena_hive_context = saved_athena_hive_context;
9453
9454 Ok(())
9455 }
9456
9457 fn generate_alter_action_with_continuation(
9458 &mut self,
9459 action: &AlterTableAction,
9460 is_continuation: bool,
9461 ) -> Result<()> {
9462 match action {
9463 AlterTableAction::AddColumn {
9464 column,
9465 if_not_exists,
9466 position,
9467 } => {
9468 use crate::dialects::DialectType;
9469 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
9473 let is_tsql_like = matches!(
9474 self.config.dialect,
9475 Some(DialectType::TSQL) | Some(DialectType::Fabric)
9476 );
9477 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
9479
9480 if is_continuation && (is_snowflake || is_tsql_like) {
9481 } else if is_snowflake {
9483 self.write_keyword("ADD");
9484 self.write_space();
9485 } else if is_athena {
9486 self.write_keyword("ADD COLUMNS");
9488 self.write(" (");
9489 } else if self.config.alter_table_include_column_keyword {
9490 self.write_keyword("ADD COLUMN");
9491 self.write_space();
9492 } else {
9493 self.write_keyword("ADD");
9495 self.write_space();
9496 }
9497
9498 if *if_not_exists {
9499 self.write_keyword("IF NOT EXISTS");
9500 self.write_space();
9501 }
9502 self.generate_column_def(column)?;
9503
9504 if is_athena {
9506 self.write(")");
9507 }
9508
9509 if let Some(pos) = position {
9511 self.write_space();
9512 match pos {
9513 ColumnPosition::First => self.write_keyword("FIRST"),
9514 ColumnPosition::After(col_name) => {
9515 self.write_keyword("AFTER");
9516 self.write_space();
9517 self.generate_identifier(col_name)?;
9518 }
9519 }
9520 }
9521 }
9522 AlterTableAction::DropColumn {
9523 name,
9524 if_exists,
9525 cascade,
9526 } => {
9527 self.write_keyword("DROP COLUMN");
9528 if *if_exists {
9529 self.write_space();
9530 self.write_keyword("IF EXISTS");
9531 }
9532 self.write_space();
9533 self.generate_identifier(name)?;
9534 if *cascade {
9535 self.write_space();
9536 self.write_keyword("CASCADE");
9537 }
9538 }
9539 AlterTableAction::DropColumns { names } => {
9540 self.write_keyword("DROP COLUMNS");
9541 self.write(" (");
9542 for (i, name) in names.iter().enumerate() {
9543 if i > 0 {
9544 self.write(", ");
9545 }
9546 self.generate_identifier(name)?;
9547 }
9548 self.write(")");
9549 }
9550 AlterTableAction::RenameColumn {
9551 old_name,
9552 new_name,
9553 if_exists,
9554 } => {
9555 self.write_keyword("RENAME COLUMN");
9556 if *if_exists {
9557 self.write_space();
9558 self.write_keyword("IF EXISTS");
9559 }
9560 self.write_space();
9561 self.generate_identifier(old_name)?;
9562 self.write_space();
9563 self.write_keyword("TO");
9564 self.write_space();
9565 self.generate_identifier(new_name)?;
9566 }
9567 AlterTableAction::AlterColumn {
9568 name,
9569 action,
9570 use_modify_keyword,
9571 } => {
9572 use crate::dialects::DialectType;
9573 let use_modify = *use_modify_keyword
9576 || (matches!(self.config.dialect, Some(DialectType::MySQL))
9577 && matches!(action, AlterColumnAction::SetDataType { .. }));
9578 if use_modify {
9579 self.write_keyword("MODIFY COLUMN");
9580 self.write_space();
9581 self.generate_identifier(name)?;
9582 if let AlterColumnAction::SetDataType {
9584 data_type,
9585 using: _,
9586 collate,
9587 } = action
9588 {
9589 self.write_space();
9590 self.generate_data_type(data_type)?;
9591 if let Some(collate_name) = collate {
9593 self.write_space();
9594 self.write_keyword("COLLATE");
9595 self.write_space();
9596 self.write(&format!("'{}'", collate_name));
9598 }
9599 } else {
9600 self.write_space();
9601 self.generate_alter_column_action(action)?;
9602 }
9603 } else if matches!(self.config.dialect, Some(DialectType::Hive))
9604 && matches!(action, AlterColumnAction::SetDataType { .. })
9605 {
9606 self.write_keyword("CHANGE COLUMN");
9608 self.write_space();
9609 self.generate_identifier(name)?;
9610 self.write_space();
9611 self.generate_identifier(name)?;
9612 if let AlterColumnAction::SetDataType { data_type, .. } = action {
9613 self.write_space();
9614 self.generate_data_type(data_type)?;
9615 }
9616 } else {
9617 self.write_keyword("ALTER COLUMN");
9618 self.write_space();
9619 self.generate_identifier(name)?;
9620 self.write_space();
9621 self.generate_alter_column_action(action)?;
9622 }
9623 }
9624 AlterTableAction::RenameTable(new_name) => {
9625 let mysql_like = matches!(
9627 self.config.dialect,
9628 Some(DialectType::MySQL)
9629 | Some(DialectType::Doris)
9630 | Some(DialectType::StarRocks)
9631 | Some(DialectType::SingleStore)
9632 );
9633 if mysql_like {
9634 self.write_keyword("RENAME");
9635 } else {
9636 self.write_keyword("RENAME TO");
9637 }
9638 self.write_space();
9639 let rename_table_with_db = !matches!(
9641 self.config.dialect,
9642 Some(DialectType::Doris)
9643 | Some(DialectType::DuckDB)
9644 | Some(DialectType::BigQuery)
9645 | Some(DialectType::PostgreSQL)
9646 );
9647 if !rename_table_with_db {
9648 let mut stripped = new_name.clone();
9649 stripped.schema = None;
9650 stripped.catalog = None;
9651 self.generate_table(&stripped)?;
9652 } else {
9653 self.generate_table(new_name)?;
9654 }
9655 }
9656 AlterTableAction::AddConstraint(constraint) => {
9657 if !is_continuation {
9660 self.write_keyword("ADD");
9661 self.write_space();
9662 }
9663 self.generate_table_constraint(constraint)?;
9664 }
9665 AlterTableAction::DropConstraint { name, if_exists } => {
9666 self.write_keyword("DROP CONSTRAINT");
9667 if *if_exists {
9668 self.write_space();
9669 self.write_keyword("IF EXISTS");
9670 }
9671 self.write_space();
9672 self.generate_identifier(name)?;
9673 }
9674 AlterTableAction::DropForeignKey { name } => {
9675 self.write_keyword("DROP FOREIGN KEY");
9676 self.write_space();
9677 self.generate_identifier(name)?;
9678 }
9679 AlterTableAction::DropPartition {
9680 partitions,
9681 if_exists,
9682 } => {
9683 self.write_keyword("DROP");
9684 if *if_exists {
9685 self.write_space();
9686 self.write_keyword("IF EXISTS");
9687 }
9688 for (i, partition) in partitions.iter().enumerate() {
9689 if i > 0 {
9690 self.write(",");
9691 }
9692 self.write_space();
9693 self.write_keyword("PARTITION");
9694 if partition.len() == 1 && partition[0].0.name == "__expr__" {
9696 self.write_space();
9698 self.generate_expression(&partition[0].1)?;
9699 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
9700 self.write_space();
9702 self.write_keyword("ALL");
9703 } else if partition.len() == 1 && partition[0].0.name == "ID" {
9704 self.write_space();
9706 self.write_keyword("ID");
9707 self.write_space();
9708 self.generate_expression(&partition[0].1)?;
9709 } else {
9710 self.write("(");
9712 for (j, (key, value)) in partition.iter().enumerate() {
9713 if j > 0 {
9714 self.write(", ");
9715 }
9716 self.generate_identifier(key)?;
9717 self.write(" = ");
9718 self.generate_expression(value)?;
9719 }
9720 self.write(")");
9721 }
9722 }
9723 }
9724 AlterTableAction::Delete { where_clause } => {
9725 self.write_keyword("DELETE");
9726 self.write_space();
9727 self.write_keyword("WHERE");
9728 self.write_space();
9729 self.generate_expression(where_clause)?;
9730 }
9731 AlterTableAction::SwapWith(target) => {
9732 self.write_keyword("SWAP WITH");
9733 self.write_space();
9734 self.generate_table(target)?;
9735 }
9736 AlterTableAction::SetProperty { properties } => {
9737 use crate::dialects::DialectType;
9738 self.write_keyword("SET");
9739 let is_trino_presto = matches!(
9741 self.config.dialect,
9742 Some(DialectType::Trino) | Some(DialectType::Presto)
9743 );
9744 if is_trino_presto {
9745 self.write_space();
9746 self.write_keyword("PROPERTIES");
9747 }
9748 let eq = if is_trino_presto { " = " } else { "=" };
9749 for (i, (key, value)) in properties.iter().enumerate() {
9750 if i > 0 {
9751 self.write(",");
9752 }
9753 self.write_space();
9754 if key.contains(' ') {
9756 self.generate_string_literal(key)?;
9757 } else {
9758 self.write(key);
9759 }
9760 self.write(eq);
9761 self.generate_expression(value)?;
9762 }
9763 }
9764 AlterTableAction::UnsetProperty { properties } => {
9765 self.write_keyword("UNSET");
9766 for (i, name) in properties.iter().enumerate() {
9767 if i > 0 {
9768 self.write(",");
9769 }
9770 self.write_space();
9771 self.write(name);
9772 }
9773 }
9774 AlterTableAction::ClusterBy { expressions } => {
9775 self.write_keyword("CLUSTER BY");
9776 self.write(" (");
9777 for (i, expr) in expressions.iter().enumerate() {
9778 if i > 0 {
9779 self.write(", ");
9780 }
9781 self.generate_expression(expr)?;
9782 }
9783 self.write(")");
9784 }
9785 AlterTableAction::SetTag { expressions } => {
9786 self.write_keyword("SET TAG");
9787 for (i, (key, value)) in expressions.iter().enumerate() {
9788 if i > 0 {
9789 self.write(",");
9790 }
9791 self.write_space();
9792 self.write(key);
9793 self.write(" = ");
9794 self.generate_expression(value)?;
9795 }
9796 }
9797 AlterTableAction::UnsetTag { names } => {
9798 self.write_keyword("UNSET TAG");
9799 for (i, name) in names.iter().enumerate() {
9800 if i > 0 {
9801 self.write(",");
9802 }
9803 self.write_space();
9804 self.write(name);
9805 }
9806 }
9807 AlterTableAction::SetOptions { expressions } => {
9808 self.write_keyword("SET");
9809 self.write(" (");
9810 for (i, expr) in expressions.iter().enumerate() {
9811 if i > 0 {
9812 self.write(", ");
9813 }
9814 self.generate_expression(expr)?;
9815 }
9816 self.write(")");
9817 }
9818 AlterTableAction::AlterIndex { name, visible } => {
9819 self.write_keyword("ALTER INDEX");
9820 self.write_space();
9821 self.generate_identifier(name)?;
9822 self.write_space();
9823 if *visible {
9824 self.write_keyword("VISIBLE");
9825 } else {
9826 self.write_keyword("INVISIBLE");
9827 }
9828 }
9829 AlterTableAction::SetAttribute { attribute } => {
9830 self.write_keyword("SET");
9831 self.write_space();
9832 self.write_keyword(attribute);
9833 }
9834 AlterTableAction::SetStageFileFormat { options } => {
9835 self.write_keyword("SET");
9836 self.write_space();
9837 self.write_keyword("STAGE_FILE_FORMAT");
9838 self.write(" = (");
9839 if let Some(opts) = options {
9840 self.generate_space_separated_properties(opts)?;
9841 }
9842 self.write(")");
9843 }
9844 AlterTableAction::SetStageCopyOptions { options } => {
9845 self.write_keyword("SET");
9846 self.write_space();
9847 self.write_keyword("STAGE_COPY_OPTIONS");
9848 self.write(" = (");
9849 if let Some(opts) = options {
9850 self.generate_space_separated_properties(opts)?;
9851 }
9852 self.write(")");
9853 }
9854 AlterTableAction::AddColumns { columns, cascade } => {
9855 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
9858 if is_oracle {
9859 self.write_keyword("ADD");
9860 } else {
9861 self.write_keyword("ADD COLUMNS");
9862 }
9863 self.write(" (");
9864 for (i, col) in columns.iter().enumerate() {
9865 if i > 0 {
9866 self.write(", ");
9867 }
9868 self.generate_column_def(col)?;
9869 }
9870 self.write(")");
9871 if *cascade {
9872 self.write_space();
9873 self.write_keyword("CASCADE");
9874 }
9875 }
9876 AlterTableAction::ChangeColumn {
9877 old_name,
9878 new_name,
9879 data_type,
9880 comment,
9881 cascade,
9882 } => {
9883 use crate::dialects::DialectType;
9884 let is_spark = matches!(
9885 self.config.dialect,
9886 Some(DialectType::Spark) | Some(DialectType::Databricks)
9887 );
9888 let is_rename = old_name.name != new_name.name;
9889
9890 if is_spark {
9891 if is_rename {
9892 self.write_keyword("RENAME COLUMN");
9894 self.write_space();
9895 self.generate_identifier(old_name)?;
9896 self.write_space();
9897 self.write_keyword("TO");
9898 self.write_space();
9899 self.generate_identifier(new_name)?;
9900 } else if comment.is_some() {
9901 self.write_keyword("ALTER COLUMN");
9903 self.write_space();
9904 self.generate_identifier(old_name)?;
9905 self.write_space();
9906 self.write_keyword("COMMENT");
9907 self.write_space();
9908 self.write("'");
9909 self.write(comment.as_ref().unwrap());
9910 self.write("'");
9911 } else if data_type.is_some() {
9912 self.write_keyword("ALTER COLUMN");
9914 self.write_space();
9915 self.generate_identifier(old_name)?;
9916 self.write_space();
9917 self.write_keyword("TYPE");
9918 self.write_space();
9919 self.generate_data_type(data_type.as_ref().unwrap())?;
9920 } else {
9921 self.write_keyword("CHANGE COLUMN");
9923 self.write_space();
9924 self.generate_identifier(old_name)?;
9925 self.write_space();
9926 self.generate_identifier(new_name)?;
9927 }
9928 } else {
9929 if data_type.is_some() {
9931 self.write_keyword("CHANGE COLUMN");
9932 } else {
9933 self.write_keyword("CHANGE");
9934 }
9935 self.write_space();
9936 self.generate_identifier(old_name)?;
9937 self.write_space();
9938 self.generate_identifier(new_name)?;
9939 if let Some(ref dt) = data_type {
9940 self.write_space();
9941 self.generate_data_type(dt)?;
9942 }
9943 if let Some(ref c) = comment {
9944 self.write_space();
9945 self.write_keyword("COMMENT");
9946 self.write_space();
9947 self.write("'");
9948 self.write(c);
9949 self.write("'");
9950 }
9951 if *cascade {
9952 self.write_space();
9953 self.write_keyword("CASCADE");
9954 }
9955 }
9956 }
9957 AlterTableAction::AddPartition {
9958 partition,
9959 if_not_exists,
9960 location,
9961 } => {
9962 self.write_keyword("ADD");
9963 self.write_space();
9964 if *if_not_exists {
9965 self.write_keyword("IF NOT EXISTS");
9966 self.write_space();
9967 }
9968 self.generate_expression(partition)?;
9969 if let Some(ref loc) = location {
9970 self.write_space();
9971 self.write_keyword("LOCATION");
9972 self.write_space();
9973 self.generate_expression(loc)?;
9974 }
9975 }
9976 AlterTableAction::AlterSortKey {
9977 this,
9978 expressions,
9979 compound,
9980 } => {
9981 self.write_keyword("ALTER");
9983 if *compound {
9984 self.write_space();
9985 self.write_keyword("COMPOUND");
9986 }
9987 self.write_space();
9988 self.write_keyword("SORTKEY");
9989 self.write_space();
9990 if let Some(style) = this {
9991 self.write_keyword(style);
9992 } else if !expressions.is_empty() {
9993 self.write("(");
9994 for (i, expr) in expressions.iter().enumerate() {
9995 if i > 0 {
9996 self.write(", ");
9997 }
9998 self.generate_expression(expr)?;
9999 }
10000 self.write(")");
10001 }
10002 }
10003 AlterTableAction::AlterDistStyle { style, distkey } => {
10004 self.write_keyword("ALTER");
10006 self.write_space();
10007 self.write_keyword("DISTSTYLE");
10008 self.write_space();
10009 self.write_keyword(style);
10010 if let Some(col) = distkey {
10011 self.write_space();
10012 self.write_keyword("DISTKEY");
10013 self.write_space();
10014 self.generate_identifier(col)?;
10015 }
10016 }
10017 AlterTableAction::SetTableProperties { properties } => {
10018 self.write_keyword("SET TABLE PROPERTIES");
10020 self.write(" (");
10021 for (i, (key, value)) in properties.iter().enumerate() {
10022 if i > 0 {
10023 self.write(", ");
10024 }
10025 self.generate_expression(key)?;
10026 self.write(" = ");
10027 self.generate_expression(value)?;
10028 }
10029 self.write(")");
10030 }
10031 AlterTableAction::SetLocation { location } => {
10032 self.write_keyword("SET LOCATION");
10034 self.write_space();
10035 self.write("'");
10036 self.write(location);
10037 self.write("'");
10038 }
10039 AlterTableAction::SetFileFormat { format } => {
10040 self.write_keyword("SET FILE FORMAT");
10042 self.write_space();
10043 self.write_keyword(format);
10044 }
10045 AlterTableAction::ReplacePartition { partition, source } => {
10046 self.write_keyword("REPLACE PARTITION");
10048 self.write_space();
10049 self.generate_expression(partition)?;
10050 if let Some(src) = source {
10051 self.write_space();
10052 self.write_keyword("FROM");
10053 self.write_space();
10054 self.generate_expression(src)?;
10055 }
10056 }
10057 AlterTableAction::Raw { sql } => {
10058 self.write(sql);
10059 }
10060 }
10061 Ok(())
10062 }
10063
10064 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
10065 match action {
10066 AlterColumnAction::SetDataType {
10067 data_type,
10068 using,
10069 collate,
10070 } => {
10071 use crate::dialects::DialectType;
10072 let is_no_prefix = matches!(
10077 self.config.dialect,
10078 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
10079 );
10080 let is_type_only = matches!(
10081 self.config.dialect,
10082 Some(DialectType::Redshift)
10083 | Some(DialectType::Spark)
10084 | Some(DialectType::Databricks)
10085 );
10086 if is_type_only {
10087 self.write_keyword("TYPE");
10088 self.write_space();
10089 } else if !is_no_prefix {
10090 self.write_keyword("SET DATA TYPE");
10091 self.write_space();
10092 }
10093 self.generate_data_type(data_type)?;
10094 if let Some(ref collation) = collate {
10095 self.write_space();
10096 self.write_keyword("COLLATE");
10097 self.write_space();
10098 self.write(collation);
10099 }
10100 if let Some(ref using_expr) = using {
10101 self.write_space();
10102 self.write_keyword("USING");
10103 self.write_space();
10104 self.generate_expression(using_expr)?;
10105 }
10106 }
10107 AlterColumnAction::SetDefault(expr) => {
10108 self.write_keyword("SET DEFAULT");
10109 self.write_space();
10110 self.generate_expression(expr)?;
10111 }
10112 AlterColumnAction::DropDefault => {
10113 self.write_keyword("DROP DEFAULT");
10114 }
10115 AlterColumnAction::SetNotNull => {
10116 self.write_keyword("SET NOT NULL");
10117 }
10118 AlterColumnAction::DropNotNull => {
10119 self.write_keyword("DROP NOT NULL");
10120 }
10121 AlterColumnAction::Comment(comment) => {
10122 self.write_keyword("COMMENT");
10123 self.write_space();
10124 self.generate_string_literal(comment)?;
10125 }
10126 AlterColumnAction::SetVisible => {
10127 self.write_keyword("SET VISIBLE");
10128 }
10129 AlterColumnAction::SetInvisible => {
10130 self.write_keyword("SET INVISIBLE");
10131 }
10132 }
10133 Ok(())
10134 }
10135
10136 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
10137 self.write_keyword("CREATE");
10138
10139 if ci.unique {
10140 self.write_space();
10141 self.write_keyword("UNIQUE");
10142 }
10143
10144 if let Some(ref clustered) = ci.clustered {
10146 self.write_space();
10147 self.write_keyword(clustered);
10148 }
10149
10150 self.write_space();
10151 self.write_keyword("INDEX");
10152
10153 if ci.concurrently {
10155 self.write_space();
10156 self.write_keyword("CONCURRENTLY");
10157 }
10158
10159 if ci.if_not_exists {
10160 self.write_space();
10161 self.write_keyword("IF NOT EXISTS");
10162 }
10163
10164 if !ci.name.name.is_empty() {
10166 self.write_space();
10167 self.generate_identifier(&ci.name)?;
10168 }
10169 self.write_space();
10170 self.write_keyword("ON");
10171 if matches!(self.config.dialect, Some(DialectType::Hive)) {
10173 self.write_space();
10174 self.write_keyword("TABLE");
10175 }
10176 self.write_space();
10177 self.generate_table(&ci.table)?;
10178
10179 if !ci.columns.is_empty() || ci.using.is_some() {
10182 let space_before_paren = false;
10183
10184 if let Some(ref using) = ci.using {
10185 self.write_space();
10186 self.write_keyword("USING");
10187 self.write_space();
10188 self.write(using);
10189 if space_before_paren {
10190 self.write(" (");
10191 } else {
10192 self.write("(");
10193 }
10194 } else {
10195 if space_before_paren {
10196 self.write(" (");
10197 } else {
10198 self.write("(");
10199 }
10200 }
10201 for (i, col) in ci.columns.iter().enumerate() {
10202 if i > 0 {
10203 self.write(", ");
10204 }
10205 self.generate_identifier(&col.column)?;
10206 if let Some(ref opclass) = col.opclass {
10207 self.write_space();
10208 self.write(opclass);
10209 }
10210 if col.desc {
10211 self.write_space();
10212 self.write_keyword("DESC");
10213 } else if col.asc {
10214 self.write_space();
10215 self.write_keyword("ASC");
10216 }
10217 if let Some(nulls_first) = col.nulls_first {
10218 self.write_space();
10219 self.write_keyword("NULLS");
10220 self.write_space();
10221 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
10222 }
10223 }
10224 self.write(")");
10225 }
10226
10227 if !ci.include_columns.is_empty() {
10229 self.write_space();
10230 self.write_keyword("INCLUDE");
10231 self.write(" (");
10232 for (i, col) in ci.include_columns.iter().enumerate() {
10233 if i > 0 {
10234 self.write(", ");
10235 }
10236 self.generate_identifier(col)?;
10237 }
10238 self.write(")");
10239 }
10240
10241 if !ci.with_options.is_empty() {
10243 self.write_space();
10244 self.write_keyword("WITH");
10245 self.write(" (");
10246 for (i, (key, value)) in ci.with_options.iter().enumerate() {
10247 if i > 0 {
10248 self.write(", ");
10249 }
10250 self.write(key);
10251 self.write("=");
10252 self.write(value);
10253 }
10254 self.write(")");
10255 }
10256
10257 if let Some(ref where_clause) = ci.where_clause {
10259 self.write_space();
10260 self.write_keyword("WHERE");
10261 self.write_space();
10262 self.generate_expression(where_clause)?;
10263 }
10264
10265 if let Some(ref on_fg) = ci.on_filegroup {
10267 self.write_space();
10268 self.write_keyword("ON");
10269 self.write_space();
10270 self.write(on_fg);
10271 }
10272
10273 Ok(())
10274 }
10275
10276 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
10277 self.write_keyword("DROP INDEX");
10278
10279 if di.concurrently {
10280 self.write_space();
10281 self.write_keyword("CONCURRENTLY");
10282 }
10283
10284 if di.if_exists {
10285 self.write_space();
10286 self.write_keyword("IF EXISTS");
10287 }
10288
10289 self.write_space();
10290 self.generate_identifier(&di.name)?;
10291
10292 if let Some(ref table) = di.table {
10293 self.write_space();
10294 self.write_keyword("ON");
10295 self.write_space();
10296 self.generate_table(table)?;
10297 }
10298
10299 Ok(())
10300 }
10301
10302 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
10303 self.write_keyword("CREATE");
10304
10305 if let Some(ref algorithm) = cv.algorithm {
10307 self.write_space();
10308 self.write_keyword("ALGORITHM");
10309 self.write("=");
10310 self.write_keyword(algorithm);
10311 }
10312
10313 if let Some(ref definer) = cv.definer {
10315 self.write_space();
10316 self.write_keyword("DEFINER");
10317 self.write("=");
10318 self.write(definer);
10319 }
10320
10321 if cv.security_sql_style {
10323 if let Some(ref security) = cv.security {
10324 self.write_space();
10325 self.write_keyword("SQL SECURITY");
10326 self.write_space();
10327 match security {
10328 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10329 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10330 FunctionSecurity::None => self.write_keyword("NONE"),
10331 }
10332 }
10333 }
10334
10335 if cv.or_replace {
10336 self.write_space();
10337 self.write_keyword("OR REPLACE");
10338 }
10339
10340 if cv.temporary {
10341 self.write_space();
10342 self.write_keyword("TEMPORARY");
10343 }
10344
10345 if cv.materialized {
10346 self.write_space();
10347 self.write_keyword("MATERIALIZED");
10348 }
10349
10350 if cv.secure {
10352 self.write_space();
10353 self.write_keyword("SECURE");
10354 }
10355
10356 self.write_space();
10357 self.write_keyword("VIEW");
10358
10359 if cv.if_not_exists {
10360 self.write_space();
10361 self.write_keyword("IF NOT EXISTS");
10362 }
10363
10364 self.write_space();
10365 self.generate_table(&cv.name)?;
10366
10367 if let Some(ref on_cluster) = cv.on_cluster {
10369 self.write_space();
10370 self.generate_on_cluster(on_cluster)?;
10371 }
10372
10373 if let Some(ref to_table) = cv.to_table {
10375 self.write_space();
10376 self.write_keyword("TO");
10377 self.write_space();
10378 self.generate_table(to_table)?;
10379 }
10380
10381 if !cv.materialized {
10384 if !cv.columns.is_empty() {
10386 self.write(" (");
10387 for (i, col) in cv.columns.iter().enumerate() {
10388 if i > 0 {
10389 self.write(", ");
10390 }
10391 self.generate_identifier(&col.name)?;
10392 if !col.options.is_empty() {
10394 self.write_space();
10395 self.generate_options_clause(&col.options)?;
10396 }
10397 if let Some(ref comment) = col.comment {
10398 self.write_space();
10399 self.write_keyword("COMMENT");
10400 self.write_space();
10401 self.generate_string_literal(comment)?;
10402 }
10403 }
10404 self.write(")");
10405 }
10406
10407 if !cv.security_sql_style {
10409 if let Some(ref security) = cv.security {
10410 self.write_space();
10411 self.write_keyword("SECURITY");
10412 self.write_space();
10413 match security {
10414 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10415 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10416 FunctionSecurity::None => self.write_keyword("NONE"),
10417 }
10418 }
10419 }
10420
10421 if cv.copy_grants {
10423 self.write_space();
10424 self.write_keyword("COPY GRANTS");
10425 }
10426 } else {
10427 if cv.copy_grants {
10429 self.write_space();
10430 self.write_keyword("COPY GRANTS");
10431 }
10432
10433 if let Some(ref schema) = cv.schema {
10435 self.write(" (");
10436 for (i, expr) in schema.expressions.iter().enumerate() {
10437 if i > 0 {
10438 self.write(", ");
10439 }
10440 self.generate_expression(expr)?;
10441 }
10442 self.write(")");
10443 } else if !cv.columns.is_empty() {
10444 self.write(" (");
10446 for (i, col) in cv.columns.iter().enumerate() {
10447 if i > 0 {
10448 self.write(", ");
10449 }
10450 self.generate_identifier(&col.name)?;
10451 if !col.options.is_empty() {
10453 self.write_space();
10454 self.generate_options_clause(&col.options)?;
10455 }
10456 if let Some(ref comment) = col.comment {
10457 self.write_space();
10458 self.write_keyword("COMMENT");
10459 self.write_space();
10460 self.generate_string_literal(comment)?;
10461 }
10462 }
10463 self.write(")");
10464 }
10465
10466 if let Some(ref unique_key) = cv.unique_key {
10468 self.write_space();
10469 self.write_keyword("KEY");
10470 self.write(" (");
10471 for (i, expr) in unique_key.expressions.iter().enumerate() {
10472 if i > 0 {
10473 self.write(", ");
10474 }
10475 self.generate_expression(expr)?;
10476 }
10477 self.write(")");
10478 }
10479 }
10480
10481 if let Some(ref comment) = cv.comment {
10483 self.write_space();
10484 self.write_keyword("COMMENT");
10485 self.write("=");
10486 self.generate_string_literal(comment)?;
10487 }
10488
10489 if !cv.tags.is_empty() {
10491 self.write_space();
10492 self.write_keyword("TAG");
10493 self.write(" (");
10494 for (i, (name, value)) in cv.tags.iter().enumerate() {
10495 if i > 0 {
10496 self.write(", ");
10497 }
10498 self.write(name);
10499 self.write("='");
10500 self.write(value);
10501 self.write("'");
10502 }
10503 self.write(")");
10504 }
10505
10506 if !cv.options.is_empty() {
10508 self.write_space();
10509 self.generate_options_clause(&cv.options)?;
10510 }
10511
10512 if let Some(ref build) = cv.build {
10514 self.write_space();
10515 self.write_keyword("BUILD");
10516 self.write_space();
10517 self.write_keyword(build);
10518 }
10519
10520 if let Some(ref refresh) = cv.refresh {
10522 self.write_space();
10523 self.generate_refresh_trigger_property(refresh)?;
10524 }
10525
10526 if let Some(auto_refresh) = cv.auto_refresh {
10528 self.write_space();
10529 self.write_keyword("AUTO REFRESH");
10530 self.write_space();
10531 if auto_refresh {
10532 self.write_keyword("YES");
10533 } else {
10534 self.write_keyword("NO");
10535 }
10536 }
10537
10538 for prop in &cv.table_properties {
10540 self.write_space();
10541 self.generate_expression(prop)?;
10542 }
10543
10544 if !matches!(&cv.query, Expression::Null(_)) {
10546 self.write_space();
10547 self.write_keyword("AS");
10548 self.write_space();
10549
10550 if let Some(ref mode) = cv.locking_mode {
10552 self.write_keyword("LOCKING");
10553 self.write_space();
10554 self.write_keyword(mode);
10555 if let Some(ref access) = cv.locking_access {
10556 self.write_space();
10557 self.write_keyword("FOR");
10558 self.write_space();
10559 self.write_keyword(access);
10560 }
10561 self.write_space();
10562 }
10563
10564 if cv.query_parenthesized {
10565 self.write("(");
10566 }
10567 self.generate_expression(&cv.query)?;
10568 if cv.query_parenthesized {
10569 self.write(")");
10570 }
10571 }
10572
10573 if cv.no_schema_binding {
10575 self.write_space();
10576 self.write_keyword("WITH NO SCHEMA BINDING");
10577 }
10578
10579 Ok(())
10580 }
10581
10582 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
10583 self.write_keyword("DROP");
10584
10585 if dv.materialized {
10586 self.write_space();
10587 self.write_keyword("MATERIALIZED");
10588 }
10589
10590 self.write_space();
10591 self.write_keyword("VIEW");
10592
10593 if dv.if_exists {
10594 self.write_space();
10595 self.write_keyword("IF EXISTS");
10596 }
10597
10598 self.write_space();
10599 self.generate_table(&dv.name)?;
10600
10601 Ok(())
10602 }
10603
10604 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
10605 match tr.target {
10606 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
10607 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
10608 }
10609 if tr.if_exists {
10610 self.write_space();
10611 self.write_keyword("IF EXISTS");
10612 }
10613 self.write_space();
10614 self.generate_table(&tr.table)?;
10615
10616 if let Some(ref on_cluster) = tr.on_cluster {
10618 self.write_space();
10619 self.generate_on_cluster(on_cluster)?;
10620 }
10621
10622 if !tr.extra_tables.is_empty() {
10624 let skip_first = if let Some(first) = tr.extra_tables.first() {
10626 first.table.name == tr.table.name && first.star
10627 } else {
10628 false
10629 };
10630
10631 let strip_star = matches!(
10633 self.config.dialect,
10634 Some(crate::dialects::DialectType::PostgreSQL)
10635 | Some(crate::dialects::DialectType::Redshift)
10636 );
10637 if skip_first && !strip_star {
10638 self.write("*");
10639 }
10640
10641 for (i, entry) in tr.extra_tables.iter().enumerate() {
10643 if i == 0 && skip_first {
10644 continue; }
10646 self.write(", ");
10647 self.generate_table(&entry.table)?;
10648 if entry.star && !strip_star {
10649 self.write("*");
10650 }
10651 }
10652 }
10653
10654 if let Some(identity) = &tr.identity {
10656 self.write_space();
10657 match identity {
10658 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
10659 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
10660 }
10661 }
10662
10663 if tr.cascade {
10664 self.write_space();
10665 self.write_keyword("CASCADE");
10666 }
10667
10668 if tr.restrict {
10669 self.write_space();
10670 self.write_keyword("RESTRICT");
10671 }
10672
10673 if let Some(ref partition) = tr.partition {
10675 self.write_space();
10676 self.generate_expression(partition)?;
10677 }
10678
10679 Ok(())
10680 }
10681
10682 fn generate_use(&mut self, u: &Use) -> Result<()> {
10683 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
10685 self.write_keyword("DATABASE");
10686 self.write_space();
10687 self.generate_identifier(&u.this)?;
10688 return Ok(());
10689 }
10690
10691 self.write_keyword("USE");
10692
10693 if let Some(kind) = &u.kind {
10694 self.write_space();
10695 match kind {
10696 UseKind::Database => self.write_keyword("DATABASE"),
10697 UseKind::Schema => self.write_keyword("SCHEMA"),
10698 UseKind::Role => self.write_keyword("ROLE"),
10699 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
10700 UseKind::Catalog => self.write_keyword("CATALOG"),
10701 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
10702 }
10703 }
10704
10705 self.write_space();
10706 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
10709 self.write(&u.this.name);
10710 } else {
10711 self.generate_identifier(&u.this)?;
10712 }
10713 Ok(())
10714 }
10715
10716 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
10717 self.write_keyword("CACHE");
10718 if c.lazy {
10719 self.write_space();
10720 self.write_keyword("LAZY");
10721 }
10722 self.write_space();
10723 self.write_keyword("TABLE");
10724 self.write_space();
10725 self.generate_identifier(&c.table)?;
10726
10727 if !c.options.is_empty() {
10729 self.write_space();
10730 self.write_keyword("OPTIONS");
10731 self.write("(");
10732 for (i, (key, value)) in c.options.iter().enumerate() {
10733 if i > 0 {
10734 self.write(", ");
10735 }
10736 self.generate_expression(key)?;
10737 self.write(" = ");
10738 self.generate_expression(value)?;
10739 }
10740 self.write(")");
10741 }
10742
10743 if let Some(query) = &c.query {
10745 self.write_space();
10746 self.write_keyword("AS");
10747 self.write_space();
10748 self.generate_expression(query)?;
10749 }
10750
10751 Ok(())
10752 }
10753
10754 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
10755 self.write_keyword("UNCACHE TABLE");
10756 if u.if_exists {
10757 self.write_space();
10758 self.write_keyword("IF EXISTS");
10759 }
10760 self.write_space();
10761 self.generate_identifier(&u.table)?;
10762 Ok(())
10763 }
10764
10765 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
10766 self.write_keyword("LOAD DATA");
10767 if l.local {
10768 self.write_space();
10769 self.write_keyword("LOCAL");
10770 }
10771 self.write_space();
10772 self.write_keyword("INPATH");
10773 self.write_space();
10774 self.write("'");
10775 self.write(&l.inpath);
10776 self.write("'");
10777
10778 if l.overwrite {
10779 self.write_space();
10780 self.write_keyword("OVERWRITE");
10781 }
10782
10783 self.write_space();
10784 self.write_keyword("INTO TABLE");
10785 self.write_space();
10786 self.generate_expression(&l.table)?;
10787
10788 if !l.partition.is_empty() {
10790 self.write_space();
10791 self.write_keyword("PARTITION");
10792 self.write("(");
10793 for (i, (col, val)) in l.partition.iter().enumerate() {
10794 if i > 0 {
10795 self.write(", ");
10796 }
10797 self.generate_identifier(col)?;
10798 self.write(" = ");
10799 self.generate_expression(val)?;
10800 }
10801 self.write(")");
10802 }
10803
10804 if let Some(fmt) = &l.input_format {
10806 self.write_space();
10807 self.write_keyword("INPUTFORMAT");
10808 self.write_space();
10809 self.write("'");
10810 self.write(fmt);
10811 self.write("'");
10812 }
10813
10814 if let Some(serde) = &l.serde {
10816 self.write_space();
10817 self.write_keyword("SERDE");
10818 self.write_space();
10819 self.write("'");
10820 self.write(serde);
10821 self.write("'");
10822 }
10823
10824 Ok(())
10825 }
10826
10827 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
10828 self.write_keyword("PRAGMA");
10829 self.write_space();
10830
10831 if let Some(schema) = &p.schema {
10833 self.generate_identifier(schema)?;
10834 self.write(".");
10835 }
10836
10837 self.generate_identifier(&p.name)?;
10839
10840 if let Some(value) = &p.value {
10842 self.write(" = ");
10843 self.generate_expression(value)?;
10844 } else if !p.args.is_empty() {
10845 self.write("(");
10846 for (i, arg) in p.args.iter().enumerate() {
10847 if i > 0 {
10848 self.write(", ");
10849 }
10850 self.generate_expression(arg)?;
10851 }
10852 self.write(")");
10853 }
10854
10855 Ok(())
10856 }
10857
10858 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
10859 self.write_keyword("GRANT");
10860 self.write_space();
10861
10862 for (i, privilege) in g.privileges.iter().enumerate() {
10864 if i > 0 {
10865 self.write(", ");
10866 }
10867 self.write_keyword(&privilege.name);
10868 if !privilege.columns.is_empty() {
10870 self.write("(");
10871 for (j, col) in privilege.columns.iter().enumerate() {
10872 if j > 0 {
10873 self.write(", ");
10874 }
10875 self.write(col);
10876 }
10877 self.write(")");
10878 }
10879 }
10880
10881 self.write_space();
10882 self.write_keyword("ON");
10883 self.write_space();
10884
10885 if let Some(kind) = &g.kind {
10887 self.write_keyword(kind);
10888 self.write_space();
10889 }
10890
10891 {
10893 use crate::dialects::DialectType;
10894 let should_upper = matches!(
10895 self.config.dialect,
10896 Some(DialectType::PostgreSQL)
10897 | Some(DialectType::CockroachDB)
10898 | Some(DialectType::Materialize)
10899 | Some(DialectType::RisingWave)
10900 ) && (g.kind.as_deref() == Some("FUNCTION")
10901 || g.kind.as_deref() == Some("PROCEDURE"));
10902 if should_upper {
10903 use crate::expressions::Identifier;
10904 let upper_id = Identifier {
10905 name: g.securable.name.to_uppercase(),
10906 quoted: g.securable.quoted,
10907 ..g.securable.clone()
10908 };
10909 self.generate_identifier(&upper_id)?;
10910 } else {
10911 self.generate_identifier(&g.securable)?;
10912 }
10913 }
10914
10915 if !g.function_params.is_empty() {
10917 self.write("(");
10918 for (i, param) in g.function_params.iter().enumerate() {
10919 if i > 0 {
10920 self.write(", ");
10921 }
10922 self.write(param);
10923 }
10924 self.write(")");
10925 }
10926
10927 self.write_space();
10928 self.write_keyword("TO");
10929 self.write_space();
10930
10931 for (i, principal) in g.principals.iter().enumerate() {
10933 if i > 0 {
10934 self.write(", ");
10935 }
10936 if principal.is_role {
10937 self.write_keyword("ROLE");
10938 self.write_space();
10939 } else if principal.is_group {
10940 self.write_keyword("GROUP");
10941 self.write_space();
10942 }
10943 self.generate_identifier(&principal.name)?;
10944 }
10945
10946 if g.grant_option {
10948 self.write_space();
10949 self.write_keyword("WITH GRANT OPTION");
10950 }
10951
10952 if let Some(ref principal) = g.as_principal {
10954 self.write_space();
10955 self.write_keyword("AS");
10956 self.write_space();
10957 self.generate_identifier(principal)?;
10958 }
10959
10960 Ok(())
10961 }
10962
10963 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
10964 self.write_keyword("REVOKE");
10965 self.write_space();
10966
10967 if r.grant_option {
10969 self.write_keyword("GRANT OPTION FOR");
10970 self.write_space();
10971 }
10972
10973 for (i, privilege) in r.privileges.iter().enumerate() {
10975 if i > 0 {
10976 self.write(", ");
10977 }
10978 self.write_keyword(&privilege.name);
10979 if !privilege.columns.is_empty() {
10981 self.write("(");
10982 for (j, col) in privilege.columns.iter().enumerate() {
10983 if j > 0 {
10984 self.write(", ");
10985 }
10986 self.write(col);
10987 }
10988 self.write(")");
10989 }
10990 }
10991
10992 self.write_space();
10993 self.write_keyword("ON");
10994 self.write_space();
10995
10996 if let Some(kind) = &r.kind {
10998 self.write_keyword(kind);
10999 self.write_space();
11000 }
11001
11002 {
11004 use crate::dialects::DialectType;
11005 let should_upper = matches!(
11006 self.config.dialect,
11007 Some(DialectType::PostgreSQL)
11008 | Some(DialectType::CockroachDB)
11009 | Some(DialectType::Materialize)
11010 | Some(DialectType::RisingWave)
11011 ) && (r.kind.as_deref() == Some("FUNCTION")
11012 || r.kind.as_deref() == Some("PROCEDURE"));
11013 if should_upper {
11014 use crate::expressions::Identifier;
11015 let upper_id = Identifier {
11016 name: r.securable.name.to_uppercase(),
11017 quoted: r.securable.quoted,
11018 ..r.securable.clone()
11019 };
11020 self.generate_identifier(&upper_id)?;
11021 } else {
11022 self.generate_identifier(&r.securable)?;
11023 }
11024 }
11025
11026 if !r.function_params.is_empty() {
11028 self.write("(");
11029 for (i, param) in r.function_params.iter().enumerate() {
11030 if i > 0 {
11031 self.write(", ");
11032 }
11033 self.write(param);
11034 }
11035 self.write(")");
11036 }
11037
11038 self.write_space();
11039 self.write_keyword("FROM");
11040 self.write_space();
11041
11042 for (i, principal) in r.principals.iter().enumerate() {
11044 if i > 0 {
11045 self.write(", ");
11046 }
11047 if principal.is_role {
11048 self.write_keyword("ROLE");
11049 self.write_space();
11050 } else if principal.is_group {
11051 self.write_keyword("GROUP");
11052 self.write_space();
11053 }
11054 self.generate_identifier(&principal.name)?;
11055 }
11056
11057 if r.cascade {
11059 self.write_space();
11060 self.write_keyword("CASCADE");
11061 } else if r.restrict {
11062 self.write_space();
11063 self.write_keyword("RESTRICT");
11064 }
11065
11066 Ok(())
11067 }
11068
11069 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
11070 self.write_keyword("COMMENT");
11071
11072 if c.exists {
11074 self.write_space();
11075 self.write_keyword("IF EXISTS");
11076 }
11077
11078 self.write_space();
11079 self.write_keyword("ON");
11080
11081 if c.materialized {
11083 self.write_space();
11084 self.write_keyword("MATERIALIZED");
11085 }
11086
11087 self.write_space();
11088 self.write_keyword(&c.kind);
11089 self.write_space();
11090
11091 self.generate_expression(&c.this)?;
11093
11094 self.write_space();
11095 self.write_keyword("IS");
11096 self.write_space();
11097
11098 self.generate_expression(&c.expression)?;
11100
11101 Ok(())
11102 }
11103
11104 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
11105 self.write_keyword("SET");
11106
11107 for (i, item) in s.items.iter().enumerate() {
11108 if i > 0 {
11109 self.write(",");
11110 }
11111 self.write_space();
11112
11113 if let Some(ref kind) = item.kind {
11115 self.write_keyword(kind);
11116 self.write_space();
11117 }
11118
11119 let name_str = match &item.name {
11121 Expression::Identifier(id) => Some(id.name.as_str()),
11122 _ => None,
11123 };
11124
11125 let is_transaction = name_str == Some("TRANSACTION");
11126 let is_character_set = name_str == Some("CHARACTER SET");
11127 let is_names = name_str == Some("NAMES");
11128 let is_collate = name_str == Some("COLLATE");
11129 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
11130 let name_has_variable_prefix = name_str.map_or(false, |n| n.starts_with("VARIABLE "));
11131 let is_variable = has_variable_kind || name_has_variable_prefix;
11132 let is_value_only =
11133 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
11134
11135 if is_transaction {
11136 self.write_keyword("TRANSACTION");
11138 if let Expression::Identifier(id) = &item.value {
11139 if !id.name.is_empty() {
11140 self.write_space();
11141 self.write(&id.name);
11142 }
11143 }
11144 } else if is_character_set {
11145 self.write_keyword("CHARACTER SET");
11147 self.write_space();
11148 self.generate_set_value(&item.value)?;
11149 } else if is_names {
11150 self.write_keyword("NAMES");
11152 self.write_space();
11153 self.generate_set_value(&item.value)?;
11154 } else if is_collate {
11155 self.write_keyword("COLLATE");
11157 self.write_space();
11158 self.generate_set_value(&item.value)?;
11159 } else if is_variable {
11160 if name_has_variable_prefix && !has_variable_kind {
11164 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
11165 self.write_keyword("VARIABLE");
11166 self.write_space();
11167 }
11168 }
11169 if let Some(ns) = name_str {
11171 let var_name = if name_has_variable_prefix {
11172 &ns["VARIABLE ".len()..]
11173 } else {
11174 ns
11175 };
11176 self.write(var_name);
11177 } else {
11178 self.generate_expression(&item.name)?;
11179 }
11180 self.write(" = ");
11181 self.generate_set_value(&item.value)?;
11182 } else if is_value_only {
11183 self.generate_expression(&item.name)?;
11185 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
11186 self.generate_expression(&item.name)?;
11188 self.write_space();
11189 self.generate_set_value(&item.value)?;
11190 } else {
11191 match &item.name {
11194 Expression::Identifier(id) => {
11195 self.write(&id.name);
11196 }
11197 _ => {
11198 self.generate_expression(&item.name)?;
11199 }
11200 }
11201 self.write(" = ");
11202 self.generate_set_value(&item.value)?;
11203 }
11204 }
11205
11206 Ok(())
11207 }
11208
11209 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
11212 if let Expression::Identifier(id) = value {
11213 match id.name.as_str() {
11214 "DEFAULT" | "ON" | "OFF" => {
11215 self.write_keyword(&id.name);
11216 return Ok(());
11217 }
11218 _ => {}
11219 }
11220 }
11221 self.generate_expression(value)
11222 }
11223
11224 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
11227 self.write_keyword("ALTER");
11228 if let Some(ref algorithm) = av.algorithm {
11230 self.write_space();
11231 self.write_keyword("ALGORITHM");
11232 self.write(" = ");
11233 self.write_keyword(algorithm);
11234 }
11235 if let Some(ref definer) = av.definer {
11236 self.write_space();
11237 self.write_keyword("DEFINER");
11238 self.write(" = ");
11239 self.write(definer);
11240 }
11241 if let Some(ref sql_security) = av.sql_security {
11242 self.write_space();
11243 self.write_keyword("SQL SECURITY");
11244 self.write(" = ");
11245 self.write_keyword(sql_security);
11246 }
11247 self.write_space();
11248 self.write_keyword("VIEW");
11249 self.write_space();
11250 self.generate_table(&av.name)?;
11251
11252 if !av.columns.is_empty() {
11254 self.write(" (");
11255 for (i, col) in av.columns.iter().enumerate() {
11256 if i > 0 {
11257 self.write(", ");
11258 }
11259 self.generate_identifier(&col.name)?;
11260 if let Some(ref comment) = col.comment {
11261 self.write_space();
11262 self.write_keyword("COMMENT");
11263 self.write(" ");
11264 self.generate_string_literal(comment)?;
11265 }
11266 }
11267 self.write(")");
11268 }
11269
11270 if let Some(ref opt) = av.with_option {
11272 self.write_space();
11273 self.write_keyword("WITH");
11274 self.write_space();
11275 self.write_keyword(opt);
11276 }
11277
11278 for action in &av.actions {
11279 self.write_space();
11280 match action {
11281 AlterViewAction::Rename(new_name) => {
11282 self.write_keyword("RENAME TO");
11283 self.write_space();
11284 self.generate_table(new_name)?;
11285 }
11286 AlterViewAction::OwnerTo(owner) => {
11287 self.write_keyword("OWNER TO");
11288 self.write_space();
11289 self.generate_identifier(owner)?;
11290 }
11291 AlterViewAction::SetSchema(schema) => {
11292 self.write_keyword("SET SCHEMA");
11293 self.write_space();
11294 self.generate_identifier(schema)?;
11295 }
11296 AlterViewAction::SetAuthorization(auth) => {
11297 self.write_keyword("SET AUTHORIZATION");
11298 self.write_space();
11299 self.write(auth);
11300 }
11301 AlterViewAction::AlterColumn { name, action } => {
11302 self.write_keyword("ALTER COLUMN");
11303 self.write_space();
11304 self.generate_identifier(name)?;
11305 self.write_space();
11306 self.generate_alter_column_action(action)?;
11307 }
11308 AlterViewAction::AsSelect(query) => {
11309 self.write_keyword("AS");
11310 self.write_space();
11311 self.generate_expression(query)?;
11312 }
11313 AlterViewAction::SetTblproperties(props) => {
11314 self.write_keyword("SET TBLPROPERTIES");
11315 self.write(" (");
11316 for (i, (key, value)) in props.iter().enumerate() {
11317 if i > 0 {
11318 self.write(", ");
11319 }
11320 self.generate_string_literal(key)?;
11321 self.write("=");
11322 self.generate_string_literal(value)?;
11323 }
11324 self.write(")");
11325 }
11326 AlterViewAction::UnsetTblproperties(keys) => {
11327 self.write_keyword("UNSET TBLPROPERTIES");
11328 self.write(" (");
11329 for (i, key) in keys.iter().enumerate() {
11330 if i > 0 {
11331 self.write(", ");
11332 }
11333 self.generate_string_literal(key)?;
11334 }
11335 self.write(")");
11336 }
11337 }
11338 }
11339
11340 Ok(())
11341 }
11342
11343 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
11344 self.write_keyword("ALTER INDEX");
11345 self.write_space();
11346 self.generate_identifier(&ai.name)?;
11347
11348 if let Some(table) = &ai.table {
11349 self.write_space();
11350 self.write_keyword("ON");
11351 self.write_space();
11352 self.generate_table(table)?;
11353 }
11354
11355 for action in &ai.actions {
11356 self.write_space();
11357 match action {
11358 AlterIndexAction::Rename(new_name) => {
11359 self.write_keyword("RENAME TO");
11360 self.write_space();
11361 self.generate_identifier(new_name)?;
11362 }
11363 AlterIndexAction::SetTablespace(tablespace) => {
11364 self.write_keyword("SET TABLESPACE");
11365 self.write_space();
11366 self.generate_identifier(tablespace)?;
11367 }
11368 AlterIndexAction::Visible(visible) => {
11369 if *visible {
11370 self.write_keyword("VISIBLE");
11371 } else {
11372 self.write_keyword("INVISIBLE");
11373 }
11374 }
11375 }
11376 }
11377
11378 Ok(())
11379 }
11380
11381 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
11382 for comment in &cs.leading_comments {
11384 self.write_formatted_comment(comment);
11385 self.write_space();
11386 }
11387
11388 let saved_athena_hive_context = self.athena_hive_context;
11390 if matches!(
11391 self.config.dialect,
11392 Some(crate::dialects::DialectType::Athena)
11393 ) {
11394 self.athena_hive_context = true;
11395 }
11396
11397 self.write_keyword("CREATE SCHEMA");
11398
11399 if cs.if_not_exists {
11400 self.write_space();
11401 self.write_keyword("IF NOT EXISTS");
11402 }
11403
11404 self.write_space();
11405 self.generate_identifier(&cs.name)?;
11406
11407 if let Some(ref clone_src) = cs.clone_from {
11408 self.write_keyword(" CLONE ");
11409 self.generate_identifier(clone_src)?;
11410 }
11411
11412 if let Some(ref at_clause) = cs.at_clause {
11413 self.write_space();
11414 self.generate_expression(at_clause)?;
11415 }
11416
11417 if let Some(auth) = &cs.authorization {
11418 self.write_space();
11419 self.write_keyword("AUTHORIZATION");
11420 self.write_space();
11421 self.generate_identifier(auth)?;
11422 }
11423
11424 let with_properties: Vec<_> = cs
11427 .properties
11428 .iter()
11429 .filter(|p| matches!(p, Expression::Property(_)))
11430 .collect();
11431 let other_properties: Vec<_> = cs
11432 .properties
11433 .iter()
11434 .filter(|p| !matches!(p, Expression::Property(_)))
11435 .collect();
11436
11437 if !with_properties.is_empty() {
11439 self.write_space();
11440 self.write_keyword("WITH");
11441 self.write(" (");
11442 for (i, prop) in with_properties.iter().enumerate() {
11443 if i > 0 {
11444 self.write(", ");
11445 }
11446 self.generate_expression(prop)?;
11447 }
11448 self.write(")");
11449 }
11450
11451 for prop in other_properties {
11453 self.write_space();
11454 self.generate_expression(prop)?;
11455 }
11456
11457 self.athena_hive_context = saved_athena_hive_context;
11459
11460 Ok(())
11461 }
11462
11463 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
11464 self.write_keyword("DROP SCHEMA");
11465
11466 if ds.if_exists {
11467 self.write_space();
11468 self.write_keyword("IF EXISTS");
11469 }
11470
11471 self.write_space();
11472 self.generate_identifier(&ds.name)?;
11473
11474 if ds.cascade {
11475 self.write_space();
11476 self.write_keyword("CASCADE");
11477 }
11478
11479 Ok(())
11480 }
11481
11482 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
11483 self.write_keyword("DROP NAMESPACE");
11484
11485 if dn.if_exists {
11486 self.write_space();
11487 self.write_keyword("IF EXISTS");
11488 }
11489
11490 self.write_space();
11491 self.generate_identifier(&dn.name)?;
11492
11493 if dn.cascade {
11494 self.write_space();
11495 self.write_keyword("CASCADE");
11496 }
11497
11498 Ok(())
11499 }
11500
11501 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
11502 self.write_keyword("CREATE DATABASE");
11503
11504 if cd.if_not_exists {
11505 self.write_space();
11506 self.write_keyword("IF NOT EXISTS");
11507 }
11508
11509 self.write_space();
11510 self.generate_identifier(&cd.name)?;
11511
11512 if let Some(ref clone_src) = cd.clone_from {
11513 self.write_keyword(" CLONE ");
11514 self.generate_identifier(clone_src)?;
11515 }
11516
11517 if let Some(ref at_clause) = cd.at_clause {
11519 self.write_space();
11520 self.generate_expression(at_clause)?;
11521 }
11522
11523 for option in &cd.options {
11524 self.write_space();
11525 match option {
11526 DatabaseOption::CharacterSet(charset) => {
11527 self.write_keyword("CHARACTER SET");
11528 self.write(" = ");
11529 self.write(&format!("'{}'", charset));
11530 }
11531 DatabaseOption::Collate(collate) => {
11532 self.write_keyword("COLLATE");
11533 self.write(" = ");
11534 self.write(&format!("'{}'", collate));
11535 }
11536 DatabaseOption::Owner(owner) => {
11537 self.write_keyword("OWNER");
11538 self.write(" = ");
11539 self.generate_identifier(owner)?;
11540 }
11541 DatabaseOption::Template(template) => {
11542 self.write_keyword("TEMPLATE");
11543 self.write(" = ");
11544 self.generate_identifier(template)?;
11545 }
11546 DatabaseOption::Encoding(encoding) => {
11547 self.write_keyword("ENCODING");
11548 self.write(" = ");
11549 self.write(&format!("'{}'", encoding));
11550 }
11551 DatabaseOption::Location(location) => {
11552 self.write_keyword("LOCATION");
11553 self.write(" = ");
11554 self.write(&format!("'{}'", location));
11555 }
11556 }
11557 }
11558
11559 Ok(())
11560 }
11561
11562 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
11563 self.write_keyword("DROP DATABASE");
11564
11565 if dd.if_exists {
11566 self.write_space();
11567 self.write_keyword("IF EXISTS");
11568 }
11569
11570 self.write_space();
11571 self.generate_identifier(&dd.name)?;
11572
11573 Ok(())
11574 }
11575
11576 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
11577 self.write_keyword("CREATE");
11578
11579 if cf.or_replace {
11580 self.write_space();
11581 self.write_keyword("OR REPLACE");
11582 }
11583
11584 if cf.temporary {
11585 self.write_space();
11586 self.write_keyword("TEMPORARY");
11587 }
11588
11589 self.write_space();
11590 if cf.is_table_function {
11591 self.write_keyword("TABLE FUNCTION");
11592 } else {
11593 self.write_keyword("FUNCTION");
11594 }
11595
11596 if cf.if_not_exists {
11597 self.write_space();
11598 self.write_keyword("IF NOT EXISTS");
11599 }
11600
11601 self.write_space();
11602 self.generate_table(&cf.name)?;
11603 if cf.has_parens {
11604 let func_multiline = self.config.pretty
11605 && matches!(
11606 self.config.dialect,
11607 Some(crate::dialects::DialectType::TSQL)
11608 | Some(crate::dialects::DialectType::Fabric)
11609 )
11610 && !cf.parameters.is_empty();
11611 if func_multiline {
11612 self.write("(\n");
11613 self.indent_level += 2;
11614 self.write_indent();
11615 self.generate_function_parameters(&cf.parameters)?;
11616 self.write("\n");
11617 self.indent_level -= 2;
11618 self.write(")");
11619 } else {
11620 self.write("(");
11621 self.generate_function_parameters(&cf.parameters)?;
11622 self.write(")");
11623 }
11624 }
11625
11626 let use_multiline = self.config.pretty
11629 && matches!(
11630 self.config.dialect,
11631 Some(crate::dialects::DialectType::BigQuery)
11632 | Some(crate::dialects::DialectType::TSQL)
11633 | Some(crate::dialects::DialectType::Fabric)
11634 );
11635
11636 if cf.language_first {
11637 if let Some(lang) = &cf.language {
11639 if use_multiline {
11640 self.write_newline();
11641 } else {
11642 self.write_space();
11643 }
11644 self.write_keyword("LANGUAGE");
11645 self.write_space();
11646 self.write(lang);
11647 }
11648
11649 if let Some(sql_data) = &cf.sql_data_access {
11651 self.write_space();
11652 match sql_data {
11653 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
11654 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
11655 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
11656 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
11657 }
11658 }
11659
11660 if let Some(ref rtb) = cf.returns_table_body {
11661 if use_multiline {
11662 self.write_newline();
11663 } else {
11664 self.write_space();
11665 }
11666 self.write_keyword("RETURNS");
11667 self.write_space();
11668 self.write(rtb);
11669 } else if let Some(return_type) = &cf.return_type {
11670 if use_multiline {
11671 self.write_newline();
11672 } else {
11673 self.write_space();
11674 }
11675 self.write_keyword("RETURNS");
11676 self.write_space();
11677 self.generate_data_type(return_type)?;
11678 }
11679 } else {
11680 let is_duckdb = matches!(
11683 self.config.dialect,
11684 Some(crate::dialects::DialectType::DuckDB)
11685 );
11686 if let Some(ref rtb) = cf.returns_table_body {
11687 if !(is_duckdb && rtb.is_empty()) {
11688 if use_multiline {
11689 self.write_newline();
11690 } else {
11691 self.write_space();
11692 }
11693 self.write_keyword("RETURNS");
11694 self.write_space();
11695 self.write(rtb);
11696 }
11697 } else if let Some(return_type) = &cf.return_type {
11698 if use_multiline {
11699 self.write_newline();
11700 } else {
11701 self.write_space();
11702 }
11703 self.write_keyword("RETURNS");
11704 self.write_space();
11705 self.generate_data_type(return_type)?;
11706 }
11707 }
11708
11709 if !cf.property_order.is_empty() {
11711 let is_bigquery = matches!(
11713 self.config.dialect,
11714 Some(crate::dialects::DialectType::BigQuery)
11715 );
11716 let property_order = if is_bigquery {
11717 let mut reordered = Vec::new();
11719 let mut has_as = false;
11720 let mut has_options = false;
11721 for prop in &cf.property_order {
11722 match prop {
11723 FunctionPropertyKind::As => has_as = true,
11724 FunctionPropertyKind::Options => has_options = true,
11725 _ => {}
11726 }
11727 }
11728 if has_as && has_options {
11729 for prop in &cf.property_order {
11731 if *prop != FunctionPropertyKind::As
11732 && *prop != FunctionPropertyKind::Options
11733 {
11734 reordered.push(*prop);
11735 }
11736 }
11737 reordered.push(FunctionPropertyKind::Options);
11738 reordered.push(FunctionPropertyKind::As);
11739 reordered
11740 } else {
11741 cf.property_order.clone()
11742 }
11743 } else {
11744 cf.property_order.clone()
11745 };
11746
11747 for prop in &property_order {
11748 match prop {
11749 FunctionPropertyKind::Set => {
11750 self.generate_function_set_options(cf)?;
11751 }
11752 FunctionPropertyKind::As => {
11753 self.generate_function_body(cf)?;
11754 }
11755 FunctionPropertyKind::Language => {
11756 if !cf.language_first {
11757 if let Some(lang) = &cf.language {
11759 let use_multiline = self.config.pretty
11761 && matches!(
11762 self.config.dialect,
11763 Some(crate::dialects::DialectType::BigQuery)
11764 );
11765 if use_multiline {
11766 self.write_newline();
11767 } else {
11768 self.write_space();
11769 }
11770 self.write_keyword("LANGUAGE");
11771 self.write_space();
11772 self.write(lang);
11773 }
11774 }
11775 }
11776 FunctionPropertyKind::Determinism => {
11777 self.generate_function_determinism(cf)?;
11778 }
11779 FunctionPropertyKind::NullInput => {
11780 self.generate_function_null_input(cf)?;
11781 }
11782 FunctionPropertyKind::Security => {
11783 self.generate_function_security(cf)?;
11784 }
11785 FunctionPropertyKind::SqlDataAccess => {
11786 if !cf.language_first {
11787 self.generate_function_sql_data_access(cf)?;
11789 }
11790 }
11791 FunctionPropertyKind::Options => {
11792 if !cf.options.is_empty() {
11793 self.write_space();
11794 self.generate_options_clause(&cf.options)?;
11795 }
11796 }
11797 FunctionPropertyKind::Environment => {
11798 if !cf.environment.is_empty() {
11799 self.write_space();
11800 self.generate_environment_clause(&cf.environment)?;
11801 }
11802 }
11803 }
11804 }
11805
11806 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
11808 {
11809 self.write_space();
11810 self.generate_options_clause(&cf.options)?;
11811 }
11812
11813 if !cf.environment.is_empty()
11815 && !cf
11816 .property_order
11817 .contains(&FunctionPropertyKind::Environment)
11818 {
11819 self.write_space();
11820 self.generate_environment_clause(&cf.environment)?;
11821 }
11822 } else {
11823 if matches!(
11826 self.config.dialect,
11827 Some(crate::dialects::DialectType::BigQuery)
11828 ) {
11829 self.generate_function_determinism(cf)?;
11830 }
11831
11832 let use_multiline = self.config.pretty
11834 && matches!(
11835 self.config.dialect,
11836 Some(crate::dialects::DialectType::BigQuery)
11837 );
11838
11839 if !cf.language_first {
11840 if let Some(lang) = &cf.language {
11841 if use_multiline {
11842 self.write_newline();
11843 } else {
11844 self.write_space();
11845 }
11846 self.write_keyword("LANGUAGE");
11847 self.write_space();
11848 self.write(lang);
11849 }
11850
11851 self.generate_function_sql_data_access(cf)?;
11853 }
11854
11855 if !matches!(
11857 self.config.dialect,
11858 Some(crate::dialects::DialectType::BigQuery)
11859 ) {
11860 self.generate_function_determinism(cf)?;
11861 }
11862
11863 self.generate_function_null_input(cf)?;
11864 self.generate_function_security(cf)?;
11865 self.generate_function_set_options(cf)?;
11866
11867 if !cf.options.is_empty() {
11869 self.write_space();
11870 self.generate_options_clause(&cf.options)?;
11871 }
11872
11873 if !cf.environment.is_empty() {
11875 self.write_space();
11876 self.generate_environment_clause(&cf.environment)?;
11877 }
11878
11879 self.generate_function_body(cf)?;
11880 }
11881
11882 Ok(())
11883 }
11884
11885 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
11887 for opt in &cf.set_options {
11888 self.write_space();
11889 self.write_keyword("SET");
11890 self.write_space();
11891 self.write(&opt.name);
11892 match &opt.value {
11893 FunctionSetValue::Value { value, use_to } => {
11894 if *use_to {
11895 self.write(" TO ");
11896 } else {
11897 self.write(" = ");
11898 }
11899 self.write(value);
11900 }
11901 FunctionSetValue::FromCurrent => {
11902 self.write_space();
11903 self.write_keyword("FROM CURRENT");
11904 }
11905 }
11906 }
11907 Ok(())
11908 }
11909
11910 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
11912 if let Some(body) = &cf.body {
11913 self.write_space();
11915 let use_multiline = self.config.pretty
11917 && matches!(
11918 self.config.dialect,
11919 Some(crate::dialects::DialectType::BigQuery)
11920 );
11921 match body {
11922 FunctionBody::Block(block) => {
11923 self.write_keyword("AS");
11924 if matches!(
11925 self.config.dialect,
11926 Some(crate::dialects::DialectType::TSQL)
11927 ) {
11928 self.write(" BEGIN ");
11929 self.write(block);
11930 self.write(" END");
11931 } else if matches!(
11932 self.config.dialect,
11933 Some(crate::dialects::DialectType::PostgreSQL)
11934 ) {
11935 self.write(" $$");
11936 self.write(block);
11937 self.write("$$");
11938 } else {
11939 let escaped = self.escape_block_for_single_quote(block);
11941 if use_multiline {
11943 self.write_newline();
11944 } else {
11945 self.write(" ");
11946 }
11947 self.write("'");
11948 self.write(&escaped);
11949 self.write("'");
11950 }
11951 }
11952 FunctionBody::StringLiteral(s) => {
11953 self.write_keyword("AS");
11954 if use_multiline {
11956 self.write_newline();
11957 } else {
11958 self.write(" ");
11959 }
11960 self.write("'");
11961 self.write(s);
11962 self.write("'");
11963 }
11964 FunctionBody::Expression(expr) => {
11965 self.write_keyword("AS");
11966 self.write_space();
11967 self.generate_expression(expr)?;
11968 }
11969 FunctionBody::External(name) => {
11970 self.write_keyword("EXTERNAL NAME");
11971 self.write(" '");
11972 self.write(name);
11973 self.write("'");
11974 }
11975 FunctionBody::Return(expr) => {
11976 if matches!(
11977 self.config.dialect,
11978 Some(crate::dialects::DialectType::DuckDB)
11979 ) {
11980 self.write_keyword("AS");
11982 self.write_space();
11983 if cf.returns_table_body.is_some() {
11985 self.write_keyword("TABLE");
11986 self.write_space();
11987 }
11988 self.generate_expression(expr)?;
11989 } else {
11990 if self.config.create_function_return_as {
11991 self.write_keyword("AS");
11992 if self.config.pretty
11994 && matches!(
11995 self.config.dialect,
11996 Some(crate::dialects::DialectType::TSQL)
11997 | Some(crate::dialects::DialectType::Fabric)
11998 )
11999 {
12000 self.write_newline();
12001 } else {
12002 self.write_space();
12003 }
12004 }
12005 self.write_keyword("RETURN");
12006 self.write_space();
12007 self.generate_expression(expr)?;
12008 }
12009 }
12010 FunctionBody::Statements(stmts) => {
12011 self.write_keyword("AS");
12012 self.write(" BEGIN ");
12013 for (i, stmt) in stmts.iter().enumerate() {
12014 if i > 0 {
12015 self.write(" ");
12016 }
12017 self.generate_expression(stmt)?;
12018 }
12019 self.write(" END");
12020 }
12021 FunctionBody::DollarQuoted { content, tag } => {
12022 self.write_keyword("AS");
12023 self.write(" ");
12024 let supports_dollar_quoting = matches!(
12026 self.config.dialect,
12027 Some(crate::dialects::DialectType::PostgreSQL)
12028 | Some(crate::dialects::DialectType::Databricks)
12029 | Some(crate::dialects::DialectType::Redshift)
12030 | Some(crate::dialects::DialectType::DuckDB)
12031 );
12032 if supports_dollar_quoting {
12033 self.write("$");
12035 if let Some(t) = tag {
12036 self.write(t);
12037 }
12038 self.write("$");
12039 self.write(content);
12040 self.write("$");
12041 if let Some(t) = tag {
12042 self.write(t);
12043 }
12044 self.write("$");
12045 } else {
12046 let escaped = self.escape_block_for_single_quote(content);
12048 self.write("'");
12049 self.write(&escaped);
12050 self.write("'");
12051 }
12052 }
12053 }
12054 }
12055 Ok(())
12056 }
12057
12058 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
12060 if let Some(det) = cf.deterministic {
12061 self.write_space();
12062 if matches!(
12063 self.config.dialect,
12064 Some(crate::dialects::DialectType::BigQuery)
12065 ) {
12066 if det {
12068 self.write_keyword("DETERMINISTIC");
12069 } else {
12070 self.write_keyword("NOT DETERMINISTIC");
12071 }
12072 } else {
12073 if det {
12075 self.write_keyword("IMMUTABLE");
12076 } else {
12077 self.write_keyword("VOLATILE");
12078 }
12079 }
12080 }
12081 Ok(())
12082 }
12083
12084 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
12086 if let Some(returns_null) = cf.returns_null_on_null_input {
12087 self.write_space();
12088 if returns_null {
12089 if cf.strict {
12090 self.write_keyword("STRICT");
12091 } else {
12092 self.write_keyword("RETURNS NULL ON NULL INPUT");
12093 }
12094 } else {
12095 self.write_keyword("CALLED ON NULL INPUT");
12096 }
12097 }
12098 Ok(())
12099 }
12100
12101 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
12103 if let Some(security) = &cf.security {
12104 self.write_space();
12105 self.write_keyword("SECURITY");
12106 self.write_space();
12107 match security {
12108 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12109 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12110 FunctionSecurity::None => self.write_keyword("NONE"),
12111 }
12112 }
12113 Ok(())
12114 }
12115
12116 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
12118 if let Some(sql_data) = &cf.sql_data_access {
12119 self.write_space();
12120 match sql_data {
12121 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12122 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12123 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12124 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12125 }
12126 }
12127 Ok(())
12128 }
12129
12130 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
12131 for (i, param) in params.iter().enumerate() {
12132 if i > 0 {
12133 self.write(", ");
12134 }
12135
12136 if let Some(mode) = ¶m.mode {
12137 if let Some(text) = ¶m.mode_text {
12138 self.write(text);
12139 } else {
12140 match mode {
12141 ParameterMode::In => self.write_keyword("IN"),
12142 ParameterMode::Out => self.write_keyword("OUT"),
12143 ParameterMode::InOut => self.write_keyword("INOUT"),
12144 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
12145 }
12146 }
12147 self.write_space();
12148 }
12149
12150 if let Some(name) = ¶m.name {
12151 self.generate_identifier(name)?;
12152 let skip_type =
12154 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
12155 if !skip_type {
12156 self.write_space();
12157 self.generate_data_type(¶m.data_type)?;
12158 }
12159 } else {
12160 self.generate_data_type(¶m.data_type)?;
12161 }
12162
12163 if let Some(default) = ¶m.default {
12164 if self.config.parameter_default_equals {
12165 self.write(" = ");
12166 } else {
12167 self.write(" DEFAULT ");
12168 }
12169 self.generate_expression(default)?;
12170 }
12171 }
12172
12173 Ok(())
12174 }
12175
12176 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
12177 self.write_keyword("DROP FUNCTION");
12178
12179 if df.if_exists {
12180 self.write_space();
12181 self.write_keyword("IF EXISTS");
12182 }
12183
12184 self.write_space();
12185 self.generate_table(&df.name)?;
12186
12187 if let Some(params) = &df.parameters {
12188 self.write(" (");
12189 for (i, dt) in params.iter().enumerate() {
12190 if i > 0 {
12191 self.write(", ");
12192 }
12193 self.generate_data_type(dt)?;
12194 }
12195 self.write(")");
12196 }
12197
12198 if df.cascade {
12199 self.write_space();
12200 self.write_keyword("CASCADE");
12201 }
12202
12203 Ok(())
12204 }
12205
12206 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
12207 self.write_keyword("CREATE");
12208
12209 if cp.or_replace {
12210 self.write_space();
12211 self.write_keyword("OR REPLACE");
12212 }
12213
12214 self.write_space();
12215 if cp.use_proc_keyword {
12216 self.write_keyword("PROC");
12217 } else {
12218 self.write_keyword("PROCEDURE");
12219 }
12220
12221 if cp.if_not_exists {
12222 self.write_space();
12223 self.write_keyword("IF NOT EXISTS");
12224 }
12225
12226 self.write_space();
12227 self.generate_table(&cp.name)?;
12228 if cp.has_parens {
12229 self.write("(");
12230 self.generate_function_parameters(&cp.parameters)?;
12231 self.write(")");
12232 } else if !cp.parameters.is_empty() {
12233 self.write_space();
12235 self.generate_function_parameters(&cp.parameters)?;
12236 }
12237
12238 if let Some(return_type) = &cp.return_type {
12240 self.write_space();
12241 self.write_keyword("RETURNS");
12242 self.write_space();
12243 self.generate_data_type(return_type)?;
12244 }
12245
12246 if let Some(execute_as) = &cp.execute_as {
12248 self.write_space();
12249 self.write_keyword("EXECUTE AS");
12250 self.write_space();
12251 self.write_keyword(execute_as);
12252 }
12253
12254 if let Some(lang) = &cp.language {
12255 self.write_space();
12256 self.write_keyword("LANGUAGE");
12257 self.write_space();
12258 self.write(lang);
12259 }
12260
12261 if let Some(security) = &cp.security {
12262 self.write_space();
12263 self.write_keyword("SECURITY");
12264 self.write_space();
12265 match security {
12266 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12267 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12268 FunctionSecurity::None => self.write_keyword("NONE"),
12269 }
12270 }
12271
12272 if !cp.with_options.is_empty() {
12274 self.write_space();
12275 self.write_keyword("WITH");
12276 self.write_space();
12277 for (i, opt) in cp.with_options.iter().enumerate() {
12278 if i > 0 {
12279 self.write(", ");
12280 }
12281 self.write(opt);
12282 }
12283 }
12284
12285 if let Some(body) = &cp.body {
12286 self.write_space();
12287 match body {
12288 FunctionBody::Block(block) => {
12289 self.write_keyword("AS");
12290 if matches!(
12291 self.config.dialect,
12292 Some(crate::dialects::DialectType::TSQL)
12293 ) {
12294 self.write(" BEGIN ");
12295 self.write(block);
12296 self.write(" END");
12297 } else if matches!(
12298 self.config.dialect,
12299 Some(crate::dialects::DialectType::PostgreSQL)
12300 ) {
12301 self.write(" $$");
12302 self.write(block);
12303 self.write("$$");
12304 } else {
12305 let escaped = self.escape_block_for_single_quote(block);
12307 self.write(" '");
12308 self.write(&escaped);
12309 self.write("'");
12310 }
12311 }
12312 FunctionBody::StringLiteral(s) => {
12313 self.write_keyword("AS");
12314 self.write(" '");
12315 self.write(s);
12316 self.write("'");
12317 }
12318 FunctionBody::Expression(expr) => {
12319 self.write_keyword("AS");
12320 self.write_space();
12321 self.generate_expression(expr)?;
12322 }
12323 FunctionBody::External(name) => {
12324 self.write_keyword("EXTERNAL NAME");
12325 self.write(" '");
12326 self.write(name);
12327 self.write("'");
12328 }
12329 FunctionBody::Return(expr) => {
12330 self.write_keyword("RETURN");
12331 self.write_space();
12332 self.generate_expression(expr)?;
12333 }
12334 FunctionBody::Statements(stmts) => {
12335 self.write_keyword("AS");
12336 self.write(" BEGIN ");
12337 for (i, stmt) in stmts.iter().enumerate() {
12338 if i > 0 {
12339 self.write(" ");
12340 }
12341 self.generate_expression(stmt)?;
12342 }
12343 self.write(" END");
12344 }
12345 FunctionBody::DollarQuoted { content, tag } => {
12346 self.write_keyword("AS");
12347 self.write(" ");
12348 let supports_dollar_quoting = matches!(
12350 self.config.dialect,
12351 Some(crate::dialects::DialectType::PostgreSQL)
12352 | Some(crate::dialects::DialectType::Databricks)
12353 | Some(crate::dialects::DialectType::Redshift)
12354 | Some(crate::dialects::DialectType::DuckDB)
12355 );
12356 if supports_dollar_quoting {
12357 self.write("$");
12359 if let Some(t) = tag {
12360 self.write(t);
12361 }
12362 self.write("$");
12363 self.write(content);
12364 self.write("$");
12365 if let Some(t) = tag {
12366 self.write(t);
12367 }
12368 self.write("$");
12369 } else {
12370 let escaped = self.escape_block_for_single_quote(content);
12372 self.write("'");
12373 self.write(&escaped);
12374 self.write("'");
12375 }
12376 }
12377 }
12378 }
12379
12380 Ok(())
12381 }
12382
12383 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
12384 self.write_keyword("DROP PROCEDURE");
12385
12386 if dp.if_exists {
12387 self.write_space();
12388 self.write_keyword("IF EXISTS");
12389 }
12390
12391 self.write_space();
12392 self.generate_table(&dp.name)?;
12393
12394 if let Some(params) = &dp.parameters {
12395 self.write(" (");
12396 for (i, dt) in params.iter().enumerate() {
12397 if i > 0 {
12398 self.write(", ");
12399 }
12400 self.generate_data_type(dt)?;
12401 }
12402 self.write(")");
12403 }
12404
12405 if dp.cascade {
12406 self.write_space();
12407 self.write_keyword("CASCADE");
12408 }
12409
12410 Ok(())
12411 }
12412
12413 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
12414 self.write_keyword("CREATE");
12415
12416 if cs.or_replace {
12417 self.write_space();
12418 self.write_keyword("OR REPLACE");
12419 }
12420
12421 if cs.temporary {
12422 self.write_space();
12423 self.write_keyword("TEMPORARY");
12424 }
12425
12426 self.write_space();
12427 self.write_keyword("SEQUENCE");
12428
12429 if cs.if_not_exists {
12430 self.write_space();
12431 self.write_keyword("IF NOT EXISTS");
12432 }
12433
12434 self.write_space();
12435 self.generate_table(&cs.name)?;
12436
12437 if let Some(as_type) = &cs.as_type {
12439 self.write_space();
12440 self.write_keyword("AS");
12441 self.write_space();
12442 self.generate_data_type(as_type)?;
12443 }
12444
12445 if let Some(comment) = &cs.comment {
12447 self.write_space();
12448 self.write_keyword("COMMENT");
12449 self.write("=");
12450 self.generate_string_literal(comment)?;
12451 }
12452
12453 if !cs.property_order.is_empty() {
12455 for prop in &cs.property_order {
12456 match prop {
12457 SeqPropKind::Start => {
12458 if let Some(start) = cs.start {
12459 self.write_space();
12460 self.write_keyword("START WITH");
12461 self.write(&format!(" {}", start));
12462 }
12463 }
12464 SeqPropKind::Increment => {
12465 if let Some(inc) = cs.increment {
12466 self.write_space();
12467 self.write_keyword("INCREMENT BY");
12468 self.write(&format!(" {}", inc));
12469 }
12470 }
12471 SeqPropKind::Minvalue => {
12472 if let Some(min) = &cs.minvalue {
12473 self.write_space();
12474 match min {
12475 SequenceBound::Value(v) => {
12476 self.write_keyword("MINVALUE");
12477 self.write(&format!(" {}", v));
12478 }
12479 SequenceBound::None => {
12480 self.write_keyword("NO MINVALUE");
12481 }
12482 }
12483 }
12484 }
12485 SeqPropKind::Maxvalue => {
12486 if let Some(max) = &cs.maxvalue {
12487 self.write_space();
12488 match max {
12489 SequenceBound::Value(v) => {
12490 self.write_keyword("MAXVALUE");
12491 self.write(&format!(" {}", v));
12492 }
12493 SequenceBound::None => {
12494 self.write_keyword("NO MAXVALUE");
12495 }
12496 }
12497 }
12498 }
12499 SeqPropKind::Cache => {
12500 if let Some(cache) = cs.cache {
12501 self.write_space();
12502 self.write_keyword("CACHE");
12503 self.write(&format!(" {}", cache));
12504 }
12505 }
12506 SeqPropKind::NoCache => {
12507 self.write_space();
12508 self.write_keyword("NO CACHE");
12509 }
12510 SeqPropKind::NoCacheWord => {
12511 self.write_space();
12512 self.write_keyword("NOCACHE");
12513 }
12514 SeqPropKind::Cycle => {
12515 self.write_space();
12516 self.write_keyword("CYCLE");
12517 }
12518 SeqPropKind::NoCycle => {
12519 self.write_space();
12520 self.write_keyword("NO CYCLE");
12521 }
12522 SeqPropKind::NoCycleWord => {
12523 self.write_space();
12524 self.write_keyword("NOCYCLE");
12525 }
12526 SeqPropKind::OwnedBy => {
12527 if !cs.owned_by_none {
12529 if let Some(owned) = &cs.owned_by {
12530 self.write_space();
12531 self.write_keyword("OWNED BY");
12532 self.write_space();
12533 self.generate_table(owned)?;
12534 }
12535 }
12536 }
12537 SeqPropKind::Order => {
12538 self.write_space();
12539 self.write_keyword("ORDER");
12540 }
12541 SeqPropKind::NoOrder => {
12542 self.write_space();
12543 self.write_keyword("NOORDER");
12544 }
12545 SeqPropKind::Comment => {
12546 }
12548 SeqPropKind::Sharing => {
12549 if let Some(val) = &cs.sharing {
12550 self.write_space();
12551 self.write(&format!("SHARING={}", val));
12552 }
12553 }
12554 SeqPropKind::Keep => {
12555 self.write_space();
12556 self.write_keyword("KEEP");
12557 }
12558 SeqPropKind::NoKeep => {
12559 self.write_space();
12560 self.write_keyword("NOKEEP");
12561 }
12562 SeqPropKind::Scale => {
12563 self.write_space();
12564 self.write_keyword("SCALE");
12565 if let Some(modifier) = &cs.scale_modifier {
12566 if !modifier.is_empty() {
12567 self.write_space();
12568 self.write_keyword(modifier);
12569 }
12570 }
12571 }
12572 SeqPropKind::NoScale => {
12573 self.write_space();
12574 self.write_keyword("NOSCALE");
12575 }
12576 SeqPropKind::Shard => {
12577 self.write_space();
12578 self.write_keyword("SHARD");
12579 if let Some(modifier) = &cs.shard_modifier {
12580 if !modifier.is_empty() {
12581 self.write_space();
12582 self.write_keyword(modifier);
12583 }
12584 }
12585 }
12586 SeqPropKind::NoShard => {
12587 self.write_space();
12588 self.write_keyword("NOSHARD");
12589 }
12590 SeqPropKind::Session => {
12591 self.write_space();
12592 self.write_keyword("SESSION");
12593 }
12594 SeqPropKind::Global => {
12595 self.write_space();
12596 self.write_keyword("GLOBAL");
12597 }
12598 SeqPropKind::NoMinvalueWord => {
12599 self.write_space();
12600 self.write_keyword("NOMINVALUE");
12601 }
12602 SeqPropKind::NoMaxvalueWord => {
12603 self.write_space();
12604 self.write_keyword("NOMAXVALUE");
12605 }
12606 }
12607 }
12608 } else {
12609 if let Some(inc) = cs.increment {
12611 self.write_space();
12612 self.write_keyword("INCREMENT BY");
12613 self.write(&format!(" {}", inc));
12614 }
12615
12616 if let Some(min) = &cs.minvalue {
12617 self.write_space();
12618 match min {
12619 SequenceBound::Value(v) => {
12620 self.write_keyword("MINVALUE");
12621 self.write(&format!(" {}", v));
12622 }
12623 SequenceBound::None => {
12624 self.write_keyword("NO MINVALUE");
12625 }
12626 }
12627 }
12628
12629 if let Some(max) = &cs.maxvalue {
12630 self.write_space();
12631 match max {
12632 SequenceBound::Value(v) => {
12633 self.write_keyword("MAXVALUE");
12634 self.write(&format!(" {}", v));
12635 }
12636 SequenceBound::None => {
12637 self.write_keyword("NO MAXVALUE");
12638 }
12639 }
12640 }
12641
12642 if let Some(start) = cs.start {
12643 self.write_space();
12644 self.write_keyword("START WITH");
12645 self.write(&format!(" {}", start));
12646 }
12647
12648 if let Some(cache) = cs.cache {
12649 self.write_space();
12650 self.write_keyword("CACHE");
12651 self.write(&format!(" {}", cache));
12652 }
12653
12654 if cs.cycle {
12655 self.write_space();
12656 self.write_keyword("CYCLE");
12657 }
12658
12659 if let Some(owned) = &cs.owned_by {
12660 self.write_space();
12661 self.write_keyword("OWNED BY");
12662 self.write_space();
12663 self.generate_table(owned)?;
12664 }
12665 }
12666
12667 Ok(())
12668 }
12669
12670 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
12671 self.write_keyword("DROP SEQUENCE");
12672
12673 if ds.if_exists {
12674 self.write_space();
12675 self.write_keyword("IF EXISTS");
12676 }
12677
12678 self.write_space();
12679 self.generate_table(&ds.name)?;
12680
12681 if ds.cascade {
12682 self.write_space();
12683 self.write_keyword("CASCADE");
12684 }
12685
12686 Ok(())
12687 }
12688
12689 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
12690 self.write_keyword("ALTER SEQUENCE");
12691
12692 if als.if_exists {
12693 self.write_space();
12694 self.write_keyword("IF EXISTS");
12695 }
12696
12697 self.write_space();
12698 self.generate_table(&als.name)?;
12699
12700 if let Some(inc) = als.increment {
12701 self.write_space();
12702 self.write_keyword("INCREMENT BY");
12703 self.write(&format!(" {}", inc));
12704 }
12705
12706 if let Some(min) = &als.minvalue {
12707 self.write_space();
12708 match min {
12709 SequenceBound::Value(v) => {
12710 self.write_keyword("MINVALUE");
12711 self.write(&format!(" {}", v));
12712 }
12713 SequenceBound::None => {
12714 self.write_keyword("NO MINVALUE");
12715 }
12716 }
12717 }
12718
12719 if let Some(max) = &als.maxvalue {
12720 self.write_space();
12721 match max {
12722 SequenceBound::Value(v) => {
12723 self.write_keyword("MAXVALUE");
12724 self.write(&format!(" {}", v));
12725 }
12726 SequenceBound::None => {
12727 self.write_keyword("NO MAXVALUE");
12728 }
12729 }
12730 }
12731
12732 if let Some(start) = als.start {
12733 self.write_space();
12734 self.write_keyword("START WITH");
12735 self.write(&format!(" {}", start));
12736 }
12737
12738 if let Some(restart) = &als.restart {
12739 self.write_space();
12740 self.write_keyword("RESTART");
12741 if let Some(val) = restart {
12742 self.write_keyword(" WITH");
12743 self.write(&format!(" {}", val));
12744 }
12745 }
12746
12747 if let Some(cache) = als.cache {
12748 self.write_space();
12749 self.write_keyword("CACHE");
12750 self.write(&format!(" {}", cache));
12751 }
12752
12753 if let Some(cycle) = als.cycle {
12754 self.write_space();
12755 if cycle {
12756 self.write_keyword("CYCLE");
12757 } else {
12758 self.write_keyword("NO CYCLE");
12759 }
12760 }
12761
12762 if let Some(owned) = &als.owned_by {
12763 self.write_space();
12764 self.write_keyword("OWNED BY");
12765 self.write_space();
12766 if let Some(table) = owned {
12767 self.generate_table(table)?;
12768 } else {
12769 self.write_keyword("NONE");
12770 }
12771 }
12772
12773 Ok(())
12774 }
12775
12776 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
12777 self.write_keyword("CREATE");
12778
12779 if ct.or_replace {
12780 self.write_space();
12781 self.write_keyword("OR REPLACE");
12782 }
12783
12784 if ct.constraint {
12785 self.write_space();
12786 self.write_keyword("CONSTRAINT");
12787 }
12788
12789 self.write_space();
12790 self.write_keyword("TRIGGER");
12791 self.write_space();
12792 self.generate_identifier(&ct.name)?;
12793
12794 self.write_space();
12795 match ct.timing {
12796 TriggerTiming::Before => self.write_keyword("BEFORE"),
12797 TriggerTiming::After => self.write_keyword("AFTER"),
12798 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
12799 }
12800
12801 for (i, event) in ct.events.iter().enumerate() {
12803 if i > 0 {
12804 self.write_keyword(" OR");
12805 }
12806 self.write_space();
12807 match event {
12808 TriggerEvent::Insert => self.write_keyword("INSERT"),
12809 TriggerEvent::Update(cols) => {
12810 self.write_keyword("UPDATE");
12811 if let Some(cols) = cols {
12812 self.write_space();
12813 self.write_keyword("OF");
12814 for (j, col) in cols.iter().enumerate() {
12815 if j > 0 {
12816 self.write(",");
12817 }
12818 self.write_space();
12819 self.generate_identifier(col)?;
12820 }
12821 }
12822 }
12823 TriggerEvent::Delete => self.write_keyword("DELETE"),
12824 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
12825 }
12826 }
12827
12828 self.write_space();
12829 self.write_keyword("ON");
12830 self.write_space();
12831 self.generate_table(&ct.table)?;
12832
12833 if let Some(ref_clause) = &ct.referencing {
12835 self.write_space();
12836 self.write_keyword("REFERENCING");
12837 if let Some(old_table) = &ref_clause.old_table {
12838 self.write_space();
12839 self.write_keyword("OLD TABLE AS");
12840 self.write_space();
12841 self.generate_identifier(old_table)?;
12842 }
12843 if let Some(new_table) = &ref_clause.new_table {
12844 self.write_space();
12845 self.write_keyword("NEW TABLE AS");
12846 self.write_space();
12847 self.generate_identifier(new_table)?;
12848 }
12849 if let Some(old_row) = &ref_clause.old_row {
12850 self.write_space();
12851 self.write_keyword("OLD ROW AS");
12852 self.write_space();
12853 self.generate_identifier(old_row)?;
12854 }
12855 if let Some(new_row) = &ref_clause.new_row {
12856 self.write_space();
12857 self.write_keyword("NEW ROW AS");
12858 self.write_space();
12859 self.generate_identifier(new_row)?;
12860 }
12861 }
12862
12863 if let Some(deferrable) = ct.deferrable {
12865 self.write_space();
12866 if deferrable {
12867 self.write_keyword("DEFERRABLE");
12868 } else {
12869 self.write_keyword("NOT DEFERRABLE");
12870 }
12871 }
12872
12873 if let Some(initially) = ct.initially_deferred {
12874 self.write_space();
12875 self.write_keyword("INITIALLY");
12876 self.write_space();
12877 if initially {
12878 self.write_keyword("DEFERRED");
12879 } else {
12880 self.write_keyword("IMMEDIATE");
12881 }
12882 }
12883
12884 self.write_space();
12885 self.write_keyword("FOR EACH");
12886 self.write_space();
12887 match ct.for_each {
12888 TriggerForEach::Row => self.write_keyword("ROW"),
12889 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
12890 }
12891
12892 if let Some(when) = &ct.when {
12894 self.write_space();
12895 self.write_keyword("WHEN");
12896 self.write(" (");
12897 self.generate_expression(when)?;
12898 self.write(")");
12899 }
12900
12901 self.write_space();
12903 match &ct.body {
12904 TriggerBody::Execute { function, args } => {
12905 self.write_keyword("EXECUTE FUNCTION");
12906 self.write_space();
12907 self.generate_table(function)?;
12908 self.write("(");
12909 for (i, arg) in args.iter().enumerate() {
12910 if i > 0 {
12911 self.write(", ");
12912 }
12913 self.generate_expression(arg)?;
12914 }
12915 self.write(")");
12916 }
12917 TriggerBody::Block(block) => {
12918 self.write_keyword("BEGIN");
12919 self.write_space();
12920 self.write(block);
12921 self.write_space();
12922 self.write_keyword("END");
12923 }
12924 }
12925
12926 Ok(())
12927 }
12928
12929 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
12930 self.write_keyword("DROP TRIGGER");
12931
12932 if dt.if_exists {
12933 self.write_space();
12934 self.write_keyword("IF EXISTS");
12935 }
12936
12937 self.write_space();
12938 self.generate_identifier(&dt.name)?;
12939
12940 if let Some(table) = &dt.table {
12941 self.write_space();
12942 self.write_keyword("ON");
12943 self.write_space();
12944 self.generate_table(table)?;
12945 }
12946
12947 if dt.cascade {
12948 self.write_space();
12949 self.write_keyword("CASCADE");
12950 }
12951
12952 Ok(())
12953 }
12954
12955 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
12956 self.write_keyword("CREATE TYPE");
12957
12958 if ct.if_not_exists {
12959 self.write_space();
12960 self.write_keyword("IF NOT EXISTS");
12961 }
12962
12963 self.write_space();
12964 self.generate_table(&ct.name)?;
12965
12966 self.write_space();
12967 self.write_keyword("AS");
12968 self.write_space();
12969
12970 match &ct.definition {
12971 TypeDefinition::Enum(values) => {
12972 self.write_keyword("ENUM");
12973 self.write(" (");
12974 for (i, val) in values.iter().enumerate() {
12975 if i > 0 {
12976 self.write(", ");
12977 }
12978 self.write(&format!("'{}'", val));
12979 }
12980 self.write(")");
12981 }
12982 TypeDefinition::Composite(attrs) => {
12983 self.write("(");
12984 for (i, attr) in attrs.iter().enumerate() {
12985 if i > 0 {
12986 self.write(", ");
12987 }
12988 self.generate_identifier(&attr.name)?;
12989 self.write_space();
12990 self.generate_data_type(&attr.data_type)?;
12991 if let Some(collate) = &attr.collate {
12992 self.write_space();
12993 self.write_keyword("COLLATE");
12994 self.write_space();
12995 self.generate_identifier(collate)?;
12996 }
12997 }
12998 self.write(")");
12999 }
13000 TypeDefinition::Range {
13001 subtype,
13002 subtype_diff,
13003 canonical,
13004 } => {
13005 self.write_keyword("RANGE");
13006 self.write(" (");
13007 self.write_keyword("SUBTYPE");
13008 self.write(" = ");
13009 self.generate_data_type(subtype)?;
13010 if let Some(diff) = subtype_diff {
13011 self.write(", ");
13012 self.write_keyword("SUBTYPE_DIFF");
13013 self.write(" = ");
13014 self.write(diff);
13015 }
13016 if let Some(canon) = canonical {
13017 self.write(", ");
13018 self.write_keyword("CANONICAL");
13019 self.write(" = ");
13020 self.write(canon);
13021 }
13022 self.write(")");
13023 }
13024 TypeDefinition::Base {
13025 input,
13026 output,
13027 internallength,
13028 } => {
13029 self.write("(");
13030 self.write_keyword("INPUT");
13031 self.write(" = ");
13032 self.write(input);
13033 self.write(", ");
13034 self.write_keyword("OUTPUT");
13035 self.write(" = ");
13036 self.write(output);
13037 if let Some(len) = internallength {
13038 self.write(", ");
13039 self.write_keyword("INTERNALLENGTH");
13040 self.write(" = ");
13041 self.write(&len.to_string());
13042 }
13043 self.write(")");
13044 }
13045 TypeDefinition::Domain {
13046 base_type,
13047 default,
13048 constraints,
13049 } => {
13050 self.generate_data_type(base_type)?;
13051 if let Some(def) = default {
13052 self.write_space();
13053 self.write_keyword("DEFAULT");
13054 self.write_space();
13055 self.generate_expression(def)?;
13056 }
13057 for constr in constraints {
13058 self.write_space();
13059 if let Some(name) = &constr.name {
13060 self.write_keyword("CONSTRAINT");
13061 self.write_space();
13062 self.generate_identifier(name)?;
13063 self.write_space();
13064 }
13065 self.write_keyword("CHECK");
13066 self.write(" (");
13067 self.generate_expression(&constr.check)?;
13068 self.write(")");
13069 }
13070 }
13071 }
13072
13073 Ok(())
13074 }
13075
13076 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
13077 self.write_keyword("DROP TYPE");
13078
13079 if dt.if_exists {
13080 self.write_space();
13081 self.write_keyword("IF EXISTS");
13082 }
13083
13084 self.write_space();
13085 self.generate_table(&dt.name)?;
13086
13087 if dt.cascade {
13088 self.write_space();
13089 self.write_keyword("CASCADE");
13090 }
13091
13092 Ok(())
13093 }
13094
13095 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
13096 let saved_athena_hive_context = self.athena_hive_context;
13098 if matches!(
13099 self.config.dialect,
13100 Some(crate::dialects::DialectType::Athena)
13101 ) {
13102 self.athena_hive_context = true;
13103 }
13104
13105 for comment in &d.leading_comments {
13107 self.write_formatted_comment(comment);
13108 self.write(" ");
13109 }
13110
13111 self.write_keyword("DESCRIBE");
13112
13113 if d.extended {
13114 self.write_space();
13115 self.write_keyword("EXTENDED");
13116 } else if d.formatted {
13117 self.write_space();
13118 self.write_keyword("FORMATTED");
13119 }
13120
13121 if let Some(ref style) = d.style {
13123 self.write_space();
13124 self.write_keyword(style);
13125 }
13126
13127 let should_output_kind = match self.config.dialect {
13129 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
13131 false
13132 }
13133 Some(DialectType::Snowflake) => true,
13135 _ => d.kind.is_some(),
13136 };
13137 if should_output_kind {
13138 if let Some(ref kind) = d.kind {
13139 self.write_space();
13140 self.write_keyword(kind);
13141 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
13142 self.write_space();
13143 self.write_keyword("TABLE");
13144 }
13145 }
13146
13147 self.write_space();
13148 self.generate_expression(&d.target)?;
13149
13150 if let Some(ref partition) = d.partition {
13152 self.write_space();
13153 self.generate_expression(partition)?;
13154 }
13155
13156 if d.as_json {
13158 self.write_space();
13159 self.write_keyword("AS JSON");
13160 }
13161
13162 for (name, value) in &d.properties {
13164 self.write_space();
13165 self.write(name);
13166 self.write("=");
13167 self.write(value);
13168 }
13169
13170 self.athena_hive_context = saved_athena_hive_context;
13172
13173 Ok(())
13174 }
13175
13176 fn generate_show(&mut self, s: &Show) -> Result<()> {
13179 self.write_keyword("SHOW");
13180 self.write_space();
13181
13182 let show_terse = s.terse
13185 && !matches!(
13186 s.this.as_str(),
13187 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
13188 );
13189 if show_terse {
13190 self.write_keyword("TERSE");
13191 self.write_space();
13192 }
13193
13194 self.write_keyword(&s.this);
13196
13197 if let Some(ref target_expr) = s.target {
13199 self.write_space();
13200 self.generate_expression(target_expr)?;
13201 }
13202
13203 if s.history {
13205 self.write_space();
13206 self.write_keyword("HISTORY");
13207 }
13208
13209 if let Some(ref for_target) = s.for_target {
13211 self.write_space();
13212 self.write_keyword("FOR");
13213 self.write_space();
13214 self.generate_expression(for_target)?;
13215 }
13216
13217 use crate::dialects::DialectType;
13221 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
13222
13223 if !is_snowflake && s.from.is_some() {
13224 if let Some(ref scope_kind) = s.scope_kind {
13228 self.write_space();
13229 self.write_keyword("IN");
13230 self.write_space();
13231 self.write_keyword(scope_kind);
13232 if let Some(ref scope) = s.scope {
13233 self.write_space();
13234 self.generate_expression(scope)?;
13235 }
13236 } else if let Some(ref scope) = s.scope {
13237 self.write_space();
13238 self.write_keyword("IN");
13239 self.write_space();
13240 self.generate_expression(scope)?;
13241 }
13242
13243 if let Some(ref from) = s.from {
13245 self.write_space();
13246 self.write_keyword("FROM");
13247 self.write_space();
13248 self.generate_expression(from)?;
13249 }
13250
13251 if let Some(ref db) = s.db {
13253 self.write_space();
13254 self.write_keyword("FROM");
13255 self.write_space();
13256 self.generate_expression(db)?;
13257 }
13258
13259 if let Some(ref like) = s.like {
13261 self.write_space();
13262 self.write_keyword("LIKE");
13263 self.write_space();
13264 self.generate_expression(like)?;
13265 }
13266 } else {
13267 if let Some(ref like) = s.like {
13271 self.write_space();
13272 self.write_keyword("LIKE");
13273 self.write_space();
13274 self.generate_expression(like)?;
13275 }
13276
13277 if let Some(ref scope_kind) = s.scope_kind {
13279 self.write_space();
13280 self.write_keyword("IN");
13281 self.write_space();
13282 self.write_keyword(scope_kind);
13283 if let Some(ref scope) = s.scope {
13284 self.write_space();
13285 self.generate_expression(scope)?;
13286 }
13287 } else if let Some(ref scope) = s.scope {
13288 self.write_space();
13289 self.write_keyword("IN");
13290 self.write_space();
13291 self.generate_expression(scope)?;
13292 }
13293 }
13294
13295 if let Some(ref starts_with) = s.starts_with {
13297 self.write_space();
13298 self.write_keyword("STARTS WITH");
13299 self.write_space();
13300 self.generate_expression(starts_with)?;
13301 }
13302
13303 if let Some(ref limit) = s.limit {
13305 self.write_space();
13306 self.generate_limit(limit)?;
13307 }
13308
13309 if is_snowflake {
13311 if let Some(ref from) = s.from {
13312 self.write_space();
13313 self.write_keyword("FROM");
13314 self.write_space();
13315 self.generate_expression(from)?;
13316 }
13317 }
13318
13319 if let Some(ref where_clause) = s.where_clause {
13321 self.write_space();
13322 self.write_keyword("WHERE");
13323 self.write_space();
13324 self.generate_expression(where_clause)?;
13325 }
13326
13327 if let Some(is_mutex) = s.mutex {
13329 self.write_space();
13330 if is_mutex {
13331 self.write_keyword("MUTEX");
13332 } else {
13333 self.write_keyword("STATUS");
13334 }
13335 }
13336
13337 if !s.privileges.is_empty() {
13339 self.write_space();
13340 self.write_keyword("WITH PRIVILEGES");
13341 self.write_space();
13342 for (i, priv_name) in s.privileges.iter().enumerate() {
13343 if i > 0 {
13344 self.write(", ");
13345 }
13346 self.write_keyword(priv_name);
13347 }
13348 }
13349
13350 Ok(())
13351 }
13352
13353 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
13356 use crate::dialects::DialectType;
13357 match lit {
13358 Literal::String(s) => {
13359 self.generate_string_literal(s)?;
13360 }
13361 Literal::Number(n) => {
13362 if matches!(self.config.dialect, Some(DialectType::MySQL))
13363 && n.len() > 2
13364 && (n.starts_with("0x") || n.starts_with("0X"))
13365 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
13366 {
13367 return self.generate_identifier(&Identifier {
13368 name: n.clone(),
13369 quoted: true,
13370 trailing_comments: Vec::new(),
13371 });
13372 }
13373 if n.starts_with('.') {
13376 self.write("0");
13377 self.write(n);
13378 } else if n.starts_with("-.") {
13379 self.write("-0");
13381 self.write(&n[1..]);
13382 } else {
13383 self.write(n);
13384 }
13385 }
13386 Literal::HexString(h) => {
13387 match self.config.dialect {
13389 Some(DialectType::Spark)
13390 | Some(DialectType::Databricks)
13391 | Some(DialectType::Teradata) => self.write("X'"),
13392 _ => self.write("x'"),
13393 }
13394 self.write(h);
13395 self.write("'");
13396 }
13397 Literal::HexNumber(h) => {
13398 match self.config.dialect {
13402 Some(DialectType::BigQuery)
13403 | Some(DialectType::TSQL)
13404 | Some(DialectType::Fabric) => {
13405 self.write("0x");
13406 self.write(h);
13407 }
13408 _ => {
13409 if let Ok(val) = u64::from_str_radix(h, 16) {
13411 self.write(&val.to_string());
13412 } else {
13413 self.write("0x");
13415 self.write(h);
13416 }
13417 }
13418 }
13419 }
13420 Literal::BitString(b) => {
13421 self.write("B'");
13423 self.write(b);
13424 self.write("'");
13425 }
13426 Literal::ByteString(b) => {
13427 self.write("b'");
13429 self.write_escaped_byte_string(b);
13431 self.write("'");
13432 }
13433 Literal::NationalString(s) => {
13434 let keep_n_prefix = matches!(
13437 self.config.dialect,
13438 Some(DialectType::TSQL)
13439 | Some(DialectType::Oracle)
13440 | Some(DialectType::MySQL)
13441 | None
13442 );
13443 if keep_n_prefix {
13444 self.write("N'");
13445 } else {
13446 self.write("'");
13447 }
13448 self.write(s);
13449 self.write("'");
13450 }
13451 Literal::Date(d) => {
13452 self.generate_date_literal(d)?;
13453 }
13454 Literal::Time(t) => {
13455 self.generate_time_literal(t)?;
13456 }
13457 Literal::Timestamp(ts) => {
13458 self.generate_timestamp_literal(ts)?;
13459 }
13460 Literal::Datetime(dt) => {
13461 self.generate_datetime_literal(dt)?;
13462 }
13463 Literal::TripleQuotedString(s, _quote_char) => {
13464 if matches!(
13466 self.config.dialect,
13467 Some(crate::dialects::DialectType::BigQuery)
13468 | Some(crate::dialects::DialectType::DuckDB)
13469 | Some(crate::dialects::DialectType::Snowflake)
13470 | Some(crate::dialects::DialectType::Spark)
13471 | Some(crate::dialects::DialectType::Hive)
13472 | Some(crate::dialects::DialectType::Presto)
13473 | Some(crate::dialects::DialectType::Trino)
13474 | Some(crate::dialects::DialectType::PostgreSQL)
13475 | Some(crate::dialects::DialectType::MySQL)
13476 | Some(crate::dialects::DialectType::Redshift)
13477 | Some(crate::dialects::DialectType::TSQL)
13478 | Some(crate::dialects::DialectType::Oracle)
13479 | Some(crate::dialects::DialectType::ClickHouse)
13480 | Some(crate::dialects::DialectType::Databricks)
13481 | Some(crate::dialects::DialectType::SQLite)
13482 ) {
13483 self.generate_string_literal(s)?;
13484 } else {
13485 let quotes = format!("{0}{0}{0}", _quote_char);
13487 self.write("es);
13488 self.write(s);
13489 self.write("es);
13490 }
13491 }
13492 Literal::EscapeString(s) => {
13493 use crate::dialects::DialectType;
13497 let content = if let Some(c) = s.strip_prefix("e:") {
13498 c
13499 } else if let Some(c) = s.strip_prefix("E:") {
13500 c
13501 } else {
13502 s.as_str()
13503 };
13504
13505 if matches!(
13507 self.config.dialect,
13508 Some(DialectType::MySQL) | Some(DialectType::TiDB)
13509 ) {
13510 self.write(content);
13511 } else {
13512 let prefix = if matches!(
13514 self.config.dialect,
13515 Some(DialectType::SingleStore)
13516 | Some(DialectType::DuckDB)
13517 | Some(DialectType::PostgreSQL)
13518 | Some(DialectType::CockroachDB)
13519 | Some(DialectType::Materialize)
13520 | Some(DialectType::RisingWave)
13521 ) {
13522 "e'"
13523 } else {
13524 "E'"
13525 };
13526
13527 let normalized = content.replace("\\'", "''");
13529 self.write(prefix);
13530 self.write(&normalized);
13531 self.write("'");
13532 }
13533 }
13534 Literal::DollarString(s) => {
13535 use crate::dialects::DialectType;
13538 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
13540 let escape_backslash = matches!(self.config.dialect, Some(DialectType::Snowflake));
13542 let use_backslash_quote =
13546 matches!(self.config.dialect, Some(DialectType::Snowflake));
13547
13548 let mut escaped = String::with_capacity(content.len() + 4);
13549 for ch in content.chars() {
13550 if escape_backslash && ch == '\\' {
13551 escaped.push('\\');
13553 escaped.push('\\');
13554 } else if ch == '\'' {
13555 if use_backslash_quote {
13556 escaped.push('\\');
13557 escaped.push('\'');
13558 } else {
13559 escaped.push('\'');
13560 escaped.push('\'');
13561 }
13562 } else {
13563 escaped.push(ch);
13564 }
13565 }
13566 self.write("'");
13567 self.write(&escaped);
13568 self.write("'");
13569 }
13570 Literal::RawString(s) => {
13571 use crate::dialects::DialectType;
13577
13578 let escape_backslash = matches!(
13580 self.config.dialect,
13581 Some(DialectType::BigQuery)
13582 | Some(DialectType::MySQL)
13583 | Some(DialectType::SingleStore)
13584 | Some(DialectType::TiDB)
13585 | Some(DialectType::Hive)
13586 | Some(DialectType::Spark)
13587 | Some(DialectType::Databricks)
13588 | Some(DialectType::Drill)
13589 | Some(DialectType::Snowflake)
13590 | Some(DialectType::Redshift)
13591 | Some(DialectType::ClickHouse)
13592 );
13593
13594 let backslash_escapes_quote = matches!(
13597 self.config.dialect,
13598 Some(DialectType::BigQuery)
13599 | Some(DialectType::Hive)
13600 | Some(DialectType::Spark)
13601 | Some(DialectType::Databricks)
13602 | Some(DialectType::Drill)
13603 | Some(DialectType::Snowflake)
13604 | Some(DialectType::Redshift)
13605 );
13606
13607 let supports_escape_sequences = escape_backslash;
13610
13611 let mut escaped = String::with_capacity(s.len() + 4);
13612 for ch in s.chars() {
13613 if escape_backslash && ch == '\\' {
13614 escaped.push('\\');
13616 escaped.push('\\');
13617 } else if ch == '\'' {
13618 if backslash_escapes_quote {
13619 escaped.push('\\');
13621 escaped.push('\'');
13622 } else {
13623 escaped.push('\'');
13625 escaped.push('\'');
13626 }
13627 } else if supports_escape_sequences {
13628 match ch {
13631 '\n' => {
13632 escaped.push('\\');
13633 escaped.push('n');
13634 }
13635 '\r' => {
13636 escaped.push('\\');
13637 escaped.push('r');
13638 }
13639 '\t' => {
13640 escaped.push('\\');
13641 escaped.push('t');
13642 }
13643 '\x07' => {
13644 escaped.push('\\');
13645 escaped.push('a');
13646 }
13647 '\x08' => {
13648 escaped.push('\\');
13649 escaped.push('b');
13650 }
13651 '\x0C' => {
13652 escaped.push('\\');
13653 escaped.push('f');
13654 }
13655 '\x0B' => {
13656 escaped.push('\\');
13657 escaped.push('v');
13658 }
13659 _ => escaped.push(ch),
13660 }
13661 } else {
13662 escaped.push(ch);
13663 }
13664 }
13665 self.write("'");
13666 self.write(&escaped);
13667 self.write("'");
13668 }
13669 }
13670 Ok(())
13671 }
13672
13673 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
13675 use crate::dialects::DialectType;
13676
13677 match self.config.dialect {
13678 Some(DialectType::TSQL) => {
13680 self.write("CAST('");
13681 self.write(d);
13682 self.write("' AS DATE)");
13683 }
13684 Some(DialectType::BigQuery) => {
13687 self.write("CAST('");
13688 self.write(d);
13689 self.write("' AS DATE)");
13690 }
13691 Some(DialectType::Exasol) => {
13694 self.write("CAST('");
13695 self.write(d);
13696 self.write("' AS DATE)");
13697 }
13698 Some(DialectType::Snowflake) => {
13701 self.write("CAST('");
13702 self.write(d);
13703 self.write("' AS DATE)");
13704 }
13705 Some(DialectType::PostgreSQL)
13707 | Some(DialectType::MySQL)
13708 | Some(DialectType::SingleStore)
13709 | Some(DialectType::TiDB)
13710 | Some(DialectType::Redshift) => {
13711 self.write("CAST('");
13712 self.write(d);
13713 self.write("' AS DATE)");
13714 }
13715 Some(DialectType::DuckDB)
13717 | Some(DialectType::Presto)
13718 | Some(DialectType::Trino)
13719 | Some(DialectType::Athena)
13720 | Some(DialectType::Spark)
13721 | Some(DialectType::Databricks)
13722 | Some(DialectType::Hive) => {
13723 self.write("CAST('");
13724 self.write(d);
13725 self.write("' AS DATE)");
13726 }
13727 Some(DialectType::Oracle) => {
13729 self.write("TO_DATE('");
13730 self.write(d);
13731 self.write("', 'YYYY-MM-DD')");
13732 }
13733 _ => {
13735 self.write_keyword("DATE");
13736 self.write(" '");
13737 self.write(d);
13738 self.write("'");
13739 }
13740 }
13741 Ok(())
13742 }
13743
13744 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
13746 use crate::dialects::DialectType;
13747
13748 match self.config.dialect {
13749 Some(DialectType::TSQL) => {
13751 self.write("CAST('");
13752 self.write(t);
13753 self.write("' AS TIME)");
13754 }
13755 _ => {
13757 self.write_keyword("TIME");
13758 self.write(" '");
13759 self.write(t);
13760 self.write("'");
13761 }
13762 }
13763 Ok(())
13764 }
13765
13766 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
13768 use crate::expressions::Literal;
13769
13770 match expr {
13771 Expression::Literal(Literal::Date(d)) => {
13772 self.write("CAST('");
13774 self.write(d);
13775 self.write("' AS DATE)");
13776 }
13777 _ => {
13778 self.generate_expression(expr)?;
13780 }
13781 }
13782 Ok(())
13783 }
13784
13785 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
13787 use crate::dialects::DialectType;
13788
13789 match self.config.dialect {
13790 Some(DialectType::TSQL) => {
13792 self.write("CAST('");
13793 self.write(ts);
13794 self.write("' AS DATETIME2)");
13795 }
13796 Some(DialectType::BigQuery) => {
13799 self.write("CAST('");
13800 self.write(ts);
13801 self.write("' AS TIMESTAMP)");
13802 }
13803 Some(DialectType::Snowflake) => {
13806 self.write("CAST('");
13807 self.write(ts);
13808 self.write("' AS TIMESTAMP)");
13809 }
13810 Some(DialectType::Dremio) => {
13813 self.write("CAST('");
13814 self.write(ts);
13815 self.write("' AS TIMESTAMP)");
13816 }
13817 Some(DialectType::Exasol) => {
13820 self.write("CAST('");
13821 self.write(ts);
13822 self.write("' AS TIMESTAMP)");
13823 }
13824 Some(DialectType::Oracle) => {
13827 self.write("TO_TIMESTAMP('");
13828 self.write(ts);
13829 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
13830 }
13831 Some(DialectType::Presto) | Some(DialectType::Trino) => {
13833 if Self::timestamp_has_timezone(ts) {
13834 self.write("CAST('");
13835 self.write(ts);
13836 self.write("' AS TIMESTAMP WITH TIME ZONE)");
13837 } else {
13838 self.write("CAST('");
13839 self.write(ts);
13840 self.write("' AS TIMESTAMP)");
13841 }
13842 }
13843 Some(DialectType::ClickHouse) => {
13845 self.write("CAST('");
13846 self.write(ts);
13847 self.write("' AS Nullable(DateTime))");
13848 }
13849 Some(DialectType::Spark) => {
13851 self.write("CAST('");
13852 self.write(ts);
13853 self.write("' AS TIMESTAMP)");
13854 }
13855 Some(DialectType::Redshift) => {
13858 if ts == "epoch" {
13859 self.write_keyword("TIMESTAMP");
13860 self.write(" '");
13861 self.write(ts);
13862 self.write("'");
13863 } else {
13864 self.write("CAST('");
13865 self.write(ts);
13866 self.write("' AS TIMESTAMP)");
13867 }
13868 }
13869 Some(DialectType::PostgreSQL)
13871 | Some(DialectType::Hive)
13872 | Some(DialectType::SQLite)
13873 | Some(DialectType::DuckDB)
13874 | Some(DialectType::Athena)
13875 | Some(DialectType::Drill)
13876 | Some(DialectType::Teradata) => {
13877 self.write("CAST('");
13878 self.write(ts);
13879 self.write("' AS TIMESTAMP)");
13880 }
13881 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
13883 self.write("CAST('");
13884 self.write(ts);
13885 self.write("' AS DATETIME)");
13886 }
13887 Some(DialectType::Databricks) => {
13889 self.write("CAST('");
13890 self.write(ts);
13891 self.write("' AS TIMESTAMP_NTZ)");
13892 }
13893 _ => {
13895 self.write_keyword("TIMESTAMP");
13896 self.write(" '");
13897 self.write(ts);
13898 self.write("'");
13899 }
13900 }
13901 Ok(())
13902 }
13903
13904 fn timestamp_has_timezone(ts: &str) -> bool {
13907 let ts_lower = ts.to_lowercase();
13911
13912 let continent_prefixes = [
13914 "africa/",
13915 "america/",
13916 "antarctica/",
13917 "arctic/",
13918 "asia/",
13919 "atlantic/",
13920 "australia/",
13921 "europe/",
13922 "indian/",
13923 "pacific/",
13924 "etc/",
13925 "brazil/",
13926 "canada/",
13927 "chile/",
13928 "mexico/",
13929 "us/",
13930 ];
13931
13932 for prefix in &continent_prefixes {
13933 if ts_lower.contains(prefix) {
13934 return true;
13935 }
13936 }
13937
13938 let tz_abbrevs = [
13941 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
13942 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
13943 " sgt", " aest", " aedt", " acst", " acdt", " awst",
13944 ];
13945
13946 for abbrev in &tz_abbrevs {
13947 if ts_lower.ends_with(abbrev) {
13948 return true;
13949 }
13950 }
13951
13952 let trimmed = ts.trim();
13956 if let Some(last_space) = trimmed.rfind(' ') {
13957 let suffix = &trimmed[last_space + 1..];
13958 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
13959 let rest = &suffix[1..];
13961 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
13962 return true;
13963 }
13964 }
13965 }
13966
13967 false
13968 }
13969
13970 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
13972 use crate::dialects::DialectType;
13973
13974 match self.config.dialect {
13975 Some(DialectType::BigQuery) => {
13978 self.write("CAST('");
13979 self.write(dt);
13980 self.write("' AS DATETIME)");
13981 }
13982 Some(DialectType::DuckDB) => {
13984 self.write("CAST('");
13985 self.write(dt);
13986 self.write("' AS TIMESTAMP)");
13987 }
13988 _ => {
13991 self.write_keyword("DATETIME");
13992 self.write(" '");
13993 self.write(dt);
13994 self.write("'");
13995 }
13996 }
13997 Ok(())
13998 }
13999
14000 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
14002 use crate::dialects::DialectType;
14003
14004 match self.config.dialect {
14005 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
14009 self.write("'");
14011 for c in s.chars() {
14012 match c {
14013 '\'' => self.write("\\'"),
14014 '\\' => self.write("\\\\"),
14015 '\n' => self.write("\\n"),
14016 '\r' => self.write("\\r"),
14017 '\t' => self.write("\\t"),
14018 '\0' => self.write("\\0"),
14019 _ => self.output.push(c),
14020 }
14021 }
14022 self.write("'");
14023 }
14024 Some(DialectType::Drill) => {
14025 self.write("'");
14028 for c in s.chars() {
14029 match c {
14030 '\'' => self.write("''"),
14031 '\\' => self.write("\\\\"),
14032 '\n' => self.write("\\n"),
14033 '\r' => self.write("\\r"),
14034 '\t' => self.write("\\t"),
14035 '\0' => self.write("\\0"),
14036 _ => self.output.push(c),
14037 }
14038 }
14039 self.write("'");
14040 }
14041 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
14042 self.write("'");
14043 for c in s.chars() {
14044 match c {
14045 '\'' => self.write("''"),
14047 '\\' => self.write("\\\\"),
14048 '\n' => self.write("\\n"),
14049 '\r' => self.write("\\r"),
14050 '\t' => self.write("\\t"),
14051 '\0' => self.output.push('\0'),
14053 _ => self.output.push(c),
14054 }
14055 }
14056 self.write("'");
14057 }
14058 Some(DialectType::BigQuery) => {
14060 self.write("'");
14061 for c in s.chars() {
14062 match c {
14063 '\'' => self.write("\\'"),
14064 '\\' => self.write("\\\\"),
14065 '\n' => self.write("\\n"),
14066 '\r' => self.write("\\r"),
14067 '\t' => self.write("\\t"),
14068 '\0' => self.write("\\0"),
14069 '\x07' => self.write("\\a"),
14070 '\x08' => self.write("\\b"),
14071 '\x0C' => self.write("\\f"),
14072 '\x0B' => self.write("\\v"),
14073 _ => self.output.push(c),
14074 }
14075 }
14076 self.write("'");
14077 }
14078 Some(DialectType::Athena) => {
14082 if self.athena_hive_context {
14083 self.write("'");
14085 for c in s.chars() {
14086 match c {
14087 '\'' => self.write("\\'"),
14088 '\\' => self.write("\\\\"),
14089 '\n' => self.write("\\n"),
14090 '\r' => self.write("\\r"),
14091 '\t' => self.write("\\t"),
14092 '\0' => self.write("\\0"),
14093 _ => self.output.push(c),
14094 }
14095 }
14096 self.write("'");
14097 } else {
14098 self.write("'");
14100 for c in s.chars() {
14101 match c {
14102 '\'' => self.write("''"),
14103 _ => self.output.push(c),
14105 }
14106 }
14107 self.write("'");
14108 }
14109 }
14110 Some(DialectType::Snowflake) => {
14115 self.write("'");
14116 for c in s.chars() {
14117 match c {
14118 '\'' => self.write("\\'"),
14119 '\n' => self.write("\\n"),
14122 '\r' => self.write("\\r"),
14123 '\t' => self.write("\\t"),
14124 _ => self.output.push(c),
14125 }
14126 }
14127 self.write("'");
14128 }
14129 Some(DialectType::PostgreSQL) => {
14131 self.write("'");
14132 for c in s.chars() {
14133 match c {
14134 '\'' => self.write("''"),
14135 _ => self.output.push(c),
14136 }
14137 }
14138 self.write("'");
14139 }
14140 Some(DialectType::Redshift) => {
14142 self.write("'");
14143 for c in s.chars() {
14144 match c {
14145 '\'' => self.write("\\'"),
14146 _ => self.output.push(c),
14147 }
14148 }
14149 self.write("'");
14150 }
14151 Some(DialectType::Oracle) => {
14153 self.write("'");
14154 self.write(&s.replace('\'', "''"));
14155 self.write("'");
14156 }
14157 Some(DialectType::ClickHouse) => {
14160 self.write("'");
14161 for c in s.chars() {
14162 match c {
14163 '\'' => self.write("''"),
14164 '\\' => self.write("\\\\"),
14165 '\n' => self.write("\\n"),
14166 '\r' => self.write("\\r"),
14167 '\t' => self.write("\\t"),
14168 '\0' => self.write("\\0"),
14169 _ => self.output.push(c),
14170 }
14171 }
14172 self.write("'");
14173 }
14174 _ => {
14177 self.write("'");
14178 self.write(&s.replace('\'', "''"));
14179 self.write("'");
14180 }
14181 }
14182 Ok(())
14183 }
14184
14185 fn write_escaped_byte_string(&mut self, s: &str) {
14188 for c in s.chars() {
14189 match c {
14190 '\'' => self.write("\\'"),
14192 '\\' => self.write("\\\\"),
14194 _ if !c.is_control() => self.output.push(c),
14196 _ => {
14198 let byte = c as u32;
14199 if byte < 256 {
14200 self.write(&format!("\\x{:02x}", byte));
14201 } else {
14202 for b in c.to_string().as_bytes() {
14204 self.write(&format!("\\x{:02x}", b));
14205 }
14206 }
14207 }
14208 }
14209 }
14210 }
14211
14212 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
14213 use crate::dialects::DialectType;
14214
14215 match self.config.dialect {
14217 Some(DialectType::TSQL) => {
14220 self.write(if b.value { "1" } else { "0" });
14221 }
14222 Some(DialectType::Oracle) => {
14224 self.write(if b.value { "1" } else { "0" });
14225 }
14226 Some(DialectType::MySQL) => {
14228 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14229 }
14230 _ => {
14232 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14233 }
14234 }
14235 Ok(())
14236 }
14237
14238 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
14241 let name = &id.name;
14242 let quote_style = &self.config.identifier_quote_style;
14243
14244 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
14248
14249 let output_name = if self.config.normalize_identifiers && !id.quoted {
14251 name.to_lowercase()
14252 } else {
14253 name.to_string()
14254 };
14255
14256 if needs_quoting {
14257 let escaped_name = if quote_style.start == quote_style.end {
14259 output_name.replace(
14260 quote_style.end,
14261 &format!("{}{}", quote_style.end, quote_style.end),
14262 )
14263 } else {
14264 output_name.replace(
14265 quote_style.end,
14266 &format!("{}{}", quote_style.end, quote_style.end),
14267 )
14268 };
14269 self.write(&format!(
14270 "{}{}{}",
14271 quote_style.start, escaped_name, quote_style.end
14272 ));
14273 } else {
14274 self.write(&output_name);
14275 }
14276
14277 for comment in &id.trailing_comments {
14279 self.write(" ");
14280 self.write_formatted_comment(comment);
14281 }
14282 Ok(())
14283 }
14284
14285 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
14286 use crate::dialects::DialectType;
14287
14288 let name = &id.name;
14289
14290 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
14292 && self.athena_hive_context
14293 {
14294 &IdentifierQuoteStyle::BACKTICK
14295 } else {
14296 &self.config.identifier_quote_style
14297 };
14298
14299 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
14306 let needs_digit_quoting = starts_with_digit
14307 && !self.config.identifiers_can_start_with_digit
14308 && self.config.dialect.is_some();
14309 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
14310 && name.len() > 2
14311 && (name.starts_with("0x") || name.starts_with("0X"))
14312 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
14313 let needs_quoting = id.quoted
14314 || self.is_reserved_keyword(name)
14315 || self.config.always_quote_identifiers
14316 || needs_digit_quoting
14317 || mysql_invalid_hex_identifier;
14318
14319 let (base_name, suffix) = if needs_quoting {
14322 if let Some(paren_pos) = name.find('(') {
14324 let base = &name[..paren_pos];
14325 let rest = &name[paren_pos..];
14326 if rest.starts_with('(')
14328 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
14329 {
14330 let close_paren = rest.find(')').unwrap_or(rest.len());
14332 let inside = &rest[1..close_paren];
14333 if inside.chars().all(|c| c.is_ascii_digit()) {
14334 (base.to_string(), rest.to_string())
14335 } else {
14336 (name.to_string(), String::new())
14337 }
14338 } else {
14339 (name.to_string(), String::new())
14340 }
14341 } else if name.ends_with(" ASC") {
14342 let base = &name[..name.len() - 4];
14343 (base.to_string(), " ASC".to_string())
14344 } else if name.ends_with(" DESC") {
14345 let base = &name[..name.len() - 5];
14346 (base.to_string(), " DESC".to_string())
14347 } else {
14348 (name.to_string(), String::new())
14349 }
14350 } else {
14351 (name.to_string(), String::new())
14352 };
14353
14354 let output_name = if self.config.normalize_identifiers && !id.quoted {
14358 base_name.to_lowercase()
14359 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
14360 && !id.quoted
14361 && self.is_reserved_keyword(name)
14362 {
14363 base_name.to_uppercase()
14366 } else {
14367 base_name
14368 };
14369
14370 if needs_quoting {
14371 let escaped_name = if quote_style.start == quote_style.end {
14373 output_name.replace(
14375 quote_style.end,
14376 &format!("{}{}", quote_style.end, quote_style.end),
14377 )
14378 } else {
14379 output_name.replace(
14381 quote_style.end,
14382 &format!("{}{}", quote_style.end, quote_style.end),
14383 )
14384 };
14385 self.write(&format!(
14386 "{}{}{}{}",
14387 quote_style.start, escaped_name, quote_style.end, suffix
14388 ));
14389 } else {
14390 self.write(&output_name);
14391 }
14392
14393 for comment in &id.trailing_comments {
14395 self.write(" ");
14396 self.write_formatted_comment(comment);
14397 }
14398 Ok(())
14399 }
14400
14401 fn generate_column(&mut self, col: &Column) -> Result<()> {
14402 use crate::dialects::DialectType;
14403
14404 if let Some(table) = &col.table {
14405 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
14409 && !table.quoted
14410 && table.name.eq_ignore_ascii_case("LOCAL");
14411
14412 if is_exasol_local_prefix {
14413 self.write("LOCAL");
14415 } else {
14416 self.generate_identifier(table)?;
14417 }
14418 self.write(".");
14419 }
14420 self.generate_identifier(&col.name)?;
14421 if col.join_mark && self.config.supports_column_join_marks {
14424 self.write(" (+)");
14425 }
14426 for comment in &col.trailing_comments {
14428 self.write_space();
14429 self.write_formatted_comment(comment);
14430 }
14431 Ok(())
14432 }
14433
14434 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
14437 use crate::dialects::DialectType;
14438 use crate::expressions::PseudocolumnType;
14439
14440 if pc.kind == PseudocolumnType::Sysdate
14442 && !matches!(
14443 self.config.dialect,
14444 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
14445 )
14446 {
14447 self.write_keyword("CURRENT_TIMESTAMP");
14448 if matches!(
14450 self.config.dialect,
14451 Some(DialectType::MySQL)
14452 | Some(DialectType::ClickHouse)
14453 | Some(DialectType::Spark)
14454 | Some(DialectType::Databricks)
14455 | Some(DialectType::Hive)
14456 ) {
14457 self.write("()");
14458 }
14459 } else {
14460 self.write(pc.kind.as_str());
14461 }
14462 Ok(())
14463 }
14464
14465 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
14467 use crate::dialects::DialectType;
14468
14469 let supports_connect_by = matches!(
14472 self.config.dialect,
14473 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
14474 );
14475
14476 if !supports_connect_by && self.config.dialect.is_some() {
14477 if self.config.pretty {
14479 self.write_newline();
14480 } else {
14481 self.write_space();
14482 }
14483 self.write("/* CONNECT BY requires manual conversion to recursive CTE */");
14484 }
14485
14486 if let Some(start) = &connect.start {
14488 if self.config.pretty {
14489 self.write_newline();
14490 } else {
14491 self.write_space();
14492 }
14493 self.write_keyword("START WITH");
14494 self.write_space();
14495 self.generate_expression(start)?;
14496 }
14497
14498 if self.config.pretty {
14500 self.write_newline();
14501 } else {
14502 self.write_space();
14503 }
14504 self.write_keyword("CONNECT BY");
14505 if connect.nocycle {
14506 self.write_space();
14507 self.write_keyword("NOCYCLE");
14508 }
14509 self.write_space();
14510 self.generate_expression(&connect.connect)?;
14511
14512 Ok(())
14513 }
14514
14515 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
14517 self.generate_connect(connect)
14518 }
14519
14520 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
14522 self.write_keyword("PRIOR");
14523 self.write_space();
14524 self.generate_expression(&prior.this)?;
14525 Ok(())
14526 }
14527
14528 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
14531 self.write_keyword("CONNECT_BY_ROOT");
14532 self.write_space();
14533 self.generate_expression(&cbr.this)?;
14534 Ok(())
14535 }
14536
14537 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
14539 use crate::dialects::DialectType;
14540
14541 let supports_match_recognize = matches!(
14543 self.config.dialect,
14544 Some(DialectType::Oracle)
14545 | Some(DialectType::Snowflake)
14546 | Some(DialectType::Presto)
14547 | Some(DialectType::Trino)
14548 );
14549
14550 if let Some(source) = &mr.this {
14552 self.generate_expression(source)?;
14553 }
14554
14555 if !supports_match_recognize {
14556 self.write("/* MATCH_RECOGNIZE not supported in this dialect */");
14557 return Ok(());
14558 }
14559
14560 if self.config.pretty {
14562 self.write_newline();
14563 } else {
14564 self.write_space();
14565 }
14566
14567 self.write_keyword("MATCH_RECOGNIZE");
14568 self.write(" (");
14569
14570 if self.config.pretty {
14571 self.indent_level += 1;
14572 }
14573
14574 let mut needs_separator = false;
14575
14576 if let Some(partition_by) = &mr.partition_by {
14578 if !partition_by.is_empty() {
14579 if self.config.pretty {
14580 self.write_newline();
14581 self.write_indent();
14582 }
14583 self.write_keyword("PARTITION BY");
14584 self.write_space();
14585 for (i, expr) in partition_by.iter().enumerate() {
14586 if i > 0 {
14587 self.write(", ");
14588 }
14589 self.generate_expression(expr)?;
14590 }
14591 needs_separator = true;
14592 }
14593 }
14594
14595 if let Some(order_by) = &mr.order_by {
14597 if !order_by.is_empty() {
14598 if needs_separator {
14599 if self.config.pretty {
14600 self.write_newline();
14601 self.write_indent();
14602 } else {
14603 self.write_space();
14604 }
14605 } else if self.config.pretty {
14606 self.write_newline();
14607 self.write_indent();
14608 }
14609 self.write_keyword("ORDER BY");
14610 if self.config.pretty {
14612 self.indent_level += 1;
14613 for (i, ordered) in order_by.iter().enumerate() {
14614 if i > 0 {
14615 self.write(",");
14616 }
14617 self.write_newline();
14618 self.write_indent();
14619 self.generate_ordered(ordered)?;
14620 }
14621 self.indent_level -= 1;
14622 } else {
14623 self.write_space();
14624 for (i, ordered) in order_by.iter().enumerate() {
14625 if i > 0 {
14626 self.write(", ");
14627 }
14628 self.generate_ordered(ordered)?;
14629 }
14630 }
14631 needs_separator = true;
14632 }
14633 }
14634
14635 if let Some(measures) = &mr.measures {
14637 if !measures.is_empty() {
14638 if needs_separator {
14639 if self.config.pretty {
14640 self.write_newline();
14641 self.write_indent();
14642 } else {
14643 self.write_space();
14644 }
14645 } else if self.config.pretty {
14646 self.write_newline();
14647 self.write_indent();
14648 }
14649 self.write_keyword("MEASURES");
14650 if self.config.pretty {
14652 self.indent_level += 1;
14653 for (i, measure) in measures.iter().enumerate() {
14654 if i > 0 {
14655 self.write(",");
14656 }
14657 self.write_newline();
14658 self.write_indent();
14659 if let Some(semantics) = &measure.window_frame {
14661 match semantics {
14662 MatchRecognizeSemantics::Running => {
14663 self.write_keyword("RUNNING");
14664 self.write_space();
14665 }
14666 MatchRecognizeSemantics::Final => {
14667 self.write_keyword("FINAL");
14668 self.write_space();
14669 }
14670 }
14671 }
14672 self.generate_expression(&measure.this)?;
14673 }
14674 self.indent_level -= 1;
14675 } else {
14676 self.write_space();
14677 for (i, measure) in measures.iter().enumerate() {
14678 if i > 0 {
14679 self.write(", ");
14680 }
14681 if let Some(semantics) = &measure.window_frame {
14683 match semantics {
14684 MatchRecognizeSemantics::Running => {
14685 self.write_keyword("RUNNING");
14686 self.write_space();
14687 }
14688 MatchRecognizeSemantics::Final => {
14689 self.write_keyword("FINAL");
14690 self.write_space();
14691 }
14692 }
14693 }
14694 self.generate_expression(&measure.this)?;
14695 }
14696 }
14697 needs_separator = true;
14698 }
14699 }
14700
14701 if let Some(rows) = &mr.rows {
14703 if needs_separator {
14704 if self.config.pretty {
14705 self.write_newline();
14706 self.write_indent();
14707 } else {
14708 self.write_space();
14709 }
14710 } else if self.config.pretty {
14711 self.write_newline();
14712 self.write_indent();
14713 }
14714 match rows {
14715 MatchRecognizeRows::OneRowPerMatch => {
14716 self.write_keyword("ONE ROW PER MATCH");
14717 }
14718 MatchRecognizeRows::AllRowsPerMatch => {
14719 self.write_keyword("ALL ROWS PER MATCH");
14720 }
14721 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
14722 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
14723 }
14724 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
14725 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
14726 }
14727 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
14728 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
14729 }
14730 }
14731 needs_separator = true;
14732 }
14733
14734 if let Some(after) = &mr.after {
14736 if needs_separator {
14737 if self.config.pretty {
14738 self.write_newline();
14739 self.write_indent();
14740 } else {
14741 self.write_space();
14742 }
14743 } else if self.config.pretty {
14744 self.write_newline();
14745 self.write_indent();
14746 }
14747 match after {
14748 MatchRecognizeAfter::PastLastRow => {
14749 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
14750 }
14751 MatchRecognizeAfter::ToNextRow => {
14752 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
14753 }
14754 MatchRecognizeAfter::ToFirst(ident) => {
14755 self.write_keyword("AFTER MATCH SKIP TO FIRST");
14756 self.write_space();
14757 self.generate_identifier(ident)?;
14758 }
14759 MatchRecognizeAfter::ToLast(ident) => {
14760 self.write_keyword("AFTER MATCH SKIP TO LAST");
14761 self.write_space();
14762 self.generate_identifier(ident)?;
14763 }
14764 }
14765 needs_separator = true;
14766 }
14767
14768 if let Some(pattern) = &mr.pattern {
14770 if needs_separator {
14771 if self.config.pretty {
14772 self.write_newline();
14773 self.write_indent();
14774 } else {
14775 self.write_space();
14776 }
14777 } else if self.config.pretty {
14778 self.write_newline();
14779 self.write_indent();
14780 }
14781 self.write_keyword("PATTERN");
14782 self.write_space();
14783 self.write("(");
14784 self.write(pattern);
14785 self.write(")");
14786 needs_separator = true;
14787 }
14788
14789 if let Some(define) = &mr.define {
14791 if !define.is_empty() {
14792 if needs_separator {
14793 if self.config.pretty {
14794 self.write_newline();
14795 self.write_indent();
14796 } else {
14797 self.write_space();
14798 }
14799 } else if self.config.pretty {
14800 self.write_newline();
14801 self.write_indent();
14802 }
14803 self.write_keyword("DEFINE");
14804 if self.config.pretty {
14806 self.indent_level += 1;
14807 for (i, (name, expr)) in define.iter().enumerate() {
14808 if i > 0 {
14809 self.write(",");
14810 }
14811 self.write_newline();
14812 self.write_indent();
14813 self.generate_identifier(name)?;
14814 self.write(" AS ");
14815 self.generate_expression(expr)?;
14816 }
14817 self.indent_level -= 1;
14818 } else {
14819 self.write_space();
14820 for (i, (name, expr)) in define.iter().enumerate() {
14821 if i > 0 {
14822 self.write(", ");
14823 }
14824 self.generate_identifier(name)?;
14825 self.write(" AS ");
14826 self.generate_expression(expr)?;
14827 }
14828 }
14829 }
14830 }
14831
14832 if self.config.pretty {
14833 self.indent_level -= 1;
14834 self.write_newline();
14835 }
14836 self.write(")");
14837
14838 if let Some(alias) = &mr.alias {
14840 self.write(" ");
14841 if mr.alias_explicit_as {
14842 self.write_keyword("AS");
14843 self.write(" ");
14844 }
14845 self.generate_identifier(alias)?;
14846 }
14847
14848 Ok(())
14849 }
14850
14851 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
14853 use crate::dialects::DialectType;
14854
14855 let supports_hints = matches!(
14857 self.config.dialect,
14858 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
14860 Some(DialectType::Spark) | Some(DialectType::Hive) |
14861 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
14862 );
14863
14864 if !supports_hints || hint.expressions.is_empty() {
14865 return Ok(());
14866 }
14867
14868 let mut hint_strings: Vec<String> = Vec::new();
14871 for expr in &hint.expressions {
14872 match expr {
14873 HintExpression::Raw(text) => {
14874 let parsed = self.parse_raw_hint_text(text);
14876 hint_strings.extend(parsed);
14877 }
14878 _ => {
14879 hint_strings.push(self.hint_expression_to_string(expr)?);
14880 }
14881 }
14882 }
14883
14884 let use_multiline = self.config.pretty && hint_strings.len() > 1;
14888
14889 if use_multiline {
14890 self.write(" /*+ ");
14892 for (i, hint_str) in hint_strings.iter().enumerate() {
14893 if i > 0 {
14894 self.write_newline();
14895 self.write(" "); }
14897 self.write(hint_str);
14898 }
14899 self.write(" */");
14900 } else {
14901 self.write(" /*+ ");
14903 let sep = match self.config.dialect {
14904 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
14905 _ => " ",
14906 };
14907 for (i, hint_str) in hint_strings.iter().enumerate() {
14908 if i > 0 {
14909 self.write(sep);
14910 }
14911 self.write(hint_str);
14912 }
14913 self.write(" */");
14914 }
14915
14916 Ok(())
14917 }
14918
14919 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
14923 let mut results = Vec::new();
14924 let mut chars = text.chars().peekable();
14925 let mut current = String::new();
14926 let mut paren_depth = 0;
14927 let mut has_unparseable_content = false;
14928 let mut position_after_last_function = 0;
14929 let mut char_position = 0;
14930
14931 while let Some(c) = chars.next() {
14932 char_position += c.len_utf8();
14933 match c {
14934 '(' => {
14935 paren_depth += 1;
14936 current.push(c);
14937 }
14938 ')' => {
14939 paren_depth -= 1;
14940 current.push(c);
14941 if paren_depth == 0 {
14943 let trimmed = current.trim().to_string();
14944 if !trimmed.is_empty() {
14945 let formatted = self.format_hint_function(&trimmed);
14947 results.push(formatted);
14948 }
14949 current.clear();
14950 position_after_last_function = char_position;
14951 }
14952 }
14953 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
14954 }
14956 _ if paren_depth == 0 => {
14957 current.push(c);
14959 }
14960 _ => {
14961 current.push(c);
14962 }
14963 }
14964 }
14965
14966 let remaining_text = text[position_after_last_function..].trim();
14968 if !remaining_text.is_empty() {
14969 let words: Vec<&str> = remaining_text.split_whitespace().collect();
14973 let looks_like_hint_functions = words.iter().all(|word| {
14974 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
14976 });
14977
14978 if !looks_like_hint_functions && words.len() > 1 {
14979 has_unparseable_content = true;
14980 }
14981 }
14982
14983 if has_unparseable_content {
14985 return vec![text.trim().to_string()];
14986 }
14987
14988 if results.is_empty() {
14990 results.push(text.trim().to_string());
14991 }
14992
14993 results
14994 }
14995
14996 fn format_hint_function(&self, hint: &str) -> String {
14999 if !self.config.pretty {
15000 return hint.to_string();
15001 }
15002
15003 if let Some(paren_pos) = hint.find('(') {
15005 if hint.ends_with(')') {
15006 let name = &hint[..paren_pos];
15007 let args_str = &hint[paren_pos + 1..hint.len() - 1];
15008
15009 let args: Vec<&str> = args_str.split_whitespace().collect();
15011
15012 let total_args_width: usize =
15014 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() {
15018 let mut result = format!("{}(\n", name);
15019 for arg in &args {
15020 result.push_str(" "); result.push_str(arg);
15022 result.push('\n');
15023 }
15024 result.push_str(" )"); return result;
15026 }
15027 }
15028 }
15029
15030 hint.to_string()
15031 }
15032
15033 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
15035 match expr {
15036 HintExpression::Function { name, args } => {
15037 let arg_strings: Vec<String> = args
15039 .iter()
15040 .map(|arg| {
15041 let mut gen = Generator::with_config(self.config.clone());
15042 gen.generate_expression(arg)?;
15043 Ok(gen.output)
15044 })
15045 .collect::<Result<Vec<_>>>()?;
15046
15047 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
15049 + arg_strings.len().saturating_sub(1); let args_multiline =
15054 self.config.pretty && total_args_width > self.config.max_text_width;
15055
15056 if args_multiline && !arg_strings.is_empty() {
15057 let mut result = format!("{}(\n", name);
15059 for arg_str in &arg_strings {
15060 result.push_str(" "); result.push_str(arg_str);
15062 result.push('\n');
15063 }
15064 result.push_str(" )"); Ok(result)
15066 } else {
15067 let args_str = arg_strings.join(" ");
15069 Ok(format!("{}({})", name, args_str))
15070 }
15071 }
15072 HintExpression::Identifier(name) => Ok(name.clone()),
15073 HintExpression::Raw(text) => {
15074 if self.config.pretty {
15076 Ok(self.format_hint_function(text))
15077 } else {
15078 Ok(text.clone())
15079 }
15080 }
15081 }
15082 }
15083
15084 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
15085 if table.only {
15087 self.write_keyword("ONLY");
15088 self.write_space();
15089 }
15090
15091 if let Some(ref identifier_func) = table.identifier_func {
15093 self.generate_expression(identifier_func)?;
15094 } else {
15095 if let Some(catalog) = &table.catalog {
15096 self.generate_identifier(catalog)?;
15097 self.write(".");
15098 }
15099 if let Some(schema) = &table.schema {
15100 self.generate_identifier(schema)?;
15101 self.write(".");
15102 }
15103 self.generate_identifier(&table.name)?;
15104 }
15105
15106 if let Some(changes) = &table.changes {
15108 self.write(" ");
15109 self.generate_changes(changes)?;
15110 }
15111
15112 if !table.partitions.is_empty() {
15114 self.write_space();
15115 self.write_keyword("PARTITION");
15116 self.write("(");
15117 for (i, partition) in table.partitions.iter().enumerate() {
15118 if i > 0 {
15119 self.write(", ");
15120 }
15121 self.generate_identifier(partition)?;
15122 }
15123 self.write(")");
15124 }
15125
15126 if table.changes.is_none() {
15129 if let Some(when) = &table.when {
15130 self.write_space();
15131 self.generate_historical_data(when)?;
15132 }
15133 }
15134
15135 if let Some(ref system_time) = table.system_time {
15137 self.write_space();
15138 self.write(system_time);
15139 }
15140
15141 if let Some(ref version) = table.version {
15143 self.write_space();
15144 self.generate_version(version)?;
15145 }
15146
15147 let alias_post_tablesample = self.config.alias_post_tablesample;
15151
15152 if alias_post_tablesample {
15153 self.generate_table_sample_clause(table)?;
15155 }
15156
15157 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
15160 && table.hints.iter().any(|h| {
15161 if let Expression::Identifier(id) = h {
15162 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
15163 } else {
15164 false
15165 }
15166 });
15167 if !table.hints.is_empty() && !is_sqlite_hint {
15168 for hint in &table.hints {
15169 self.write_space();
15170 self.generate_expression(hint)?;
15171 }
15172 }
15173
15174 if let Some(alias) = &table.alias {
15175 self.write_space();
15176 let always_use_as = self.config.dialect.is_none()
15179 || matches!(
15180 self.config.dialect,
15181 Some(DialectType::Generic)
15182 | Some(DialectType::PostgreSQL)
15183 | Some(DialectType::Redshift)
15184 | Some(DialectType::Snowflake)
15185 | Some(DialectType::BigQuery)
15186 | Some(DialectType::Presto)
15187 | Some(DialectType::Trino)
15188 | Some(DialectType::TSQL)
15189 | Some(DialectType::Fabric)
15190 | Some(DialectType::MySQL)
15191 | Some(DialectType::Spark)
15192 | Some(DialectType::Hive)
15193 | Some(DialectType::SQLite)
15194 | Some(DialectType::Drill)
15195 );
15196 let is_stage_ref = table.name.name.starts_with('@');
15197 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
15199 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
15200 self.write_keyword("AS");
15201 self.write_space();
15202 }
15203 self.generate_identifier(alias)?;
15204
15205 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
15208 self.write("(");
15209 for (i, col_alias) in table.column_aliases.iter().enumerate() {
15210 if i > 0 {
15211 self.write(", ");
15212 }
15213 self.generate_identifier(col_alias)?;
15214 }
15215 self.write(")");
15216 }
15217 }
15218
15219 if !alias_post_tablesample {
15221 self.generate_table_sample_clause(table)?;
15222 }
15223
15224 if is_sqlite_hint {
15226 for hint in &table.hints {
15227 self.write_space();
15228 self.generate_expression(hint)?;
15229 }
15230 }
15231
15232 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
15234 self.write_space();
15235 self.write_keyword("FINAL");
15236 }
15237
15238 for comment in &table.trailing_comments {
15240 self.write_space();
15241 self.write_formatted_comment(comment);
15242 }
15243
15244 Ok(())
15245 }
15246
15247 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
15249 if let Some(ref ts) = table.table_sample {
15250 self.write_space();
15251 if ts.is_using_sample {
15252 self.write_keyword("USING SAMPLE");
15253 } else {
15254 self.write_keyword(self.config.tablesample_keywords);
15256 }
15257 self.generate_sample_body(ts)?;
15258 if let Some(ref seed) = ts.seed {
15260 self.write_space();
15261 self.write_keyword(self.config.tablesample_seed_keyword);
15262 self.write(" (");
15263 self.generate_expression(seed)?;
15264 self.write(")");
15265 }
15266 }
15267 Ok(())
15268 }
15269
15270 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
15271 if sr.quoted {
15275 self.write("'");
15276 }
15277
15278 self.write(&sr.name);
15279 if let Some(path) = &sr.path {
15280 self.write(path);
15281 }
15282
15283 if sr.quoted {
15284 self.write("'");
15285 }
15286
15287 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
15289 if has_options {
15290 self.write(" (");
15291 let mut first = true;
15292
15293 if let Some(file_format) = &sr.file_format {
15294 if !first {
15295 self.write(", ");
15296 }
15297 self.write_keyword("FILE_FORMAT");
15298 self.write(" => ");
15299 self.generate_expression(file_format)?;
15300 first = false;
15301 }
15302
15303 if let Some(pattern) = &sr.pattern {
15304 if !first {
15305 self.write(", ");
15306 }
15307 self.write_keyword("PATTERN");
15308 self.write(" => '");
15309 self.write(pattern);
15310 self.write("'");
15311 }
15312
15313 self.write(")");
15314 }
15315 Ok(())
15316 }
15317
15318 fn generate_star(&mut self, star: &Star) -> Result<()> {
15319 use crate::dialects::DialectType;
15320
15321 if let Some(table) = &star.table {
15322 self.generate_identifier(table)?;
15323 self.write(".");
15324 }
15325 self.write("*");
15326
15327 if let Some(except) = &star.except {
15329 if !except.is_empty() {
15330 self.write_space();
15331 match self.config.dialect {
15333 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
15334 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
15335 self.write_keyword("EXCLUDE")
15336 }
15337 _ => self.write_keyword("EXCEPT"), }
15339 self.write(" (");
15340 for (i, col) in except.iter().enumerate() {
15341 if i > 0 {
15342 self.write(", ");
15343 }
15344 self.generate_identifier(col)?;
15345 }
15346 self.write(")");
15347 }
15348 }
15349
15350 if let Some(replace) = &star.replace {
15352 if !replace.is_empty() {
15353 self.write_space();
15354 self.write_keyword("REPLACE");
15355 self.write(" (");
15356 for (i, alias) in replace.iter().enumerate() {
15357 if i > 0 {
15358 self.write(", ");
15359 }
15360 self.generate_expression(&alias.this)?;
15361 self.write_space();
15362 self.write_keyword("AS");
15363 self.write_space();
15364 self.generate_identifier(&alias.alias)?;
15365 }
15366 self.write(")");
15367 }
15368 }
15369
15370 if let Some(rename) = &star.rename {
15372 if !rename.is_empty() {
15373 self.write_space();
15374 self.write_keyword("RENAME");
15375 self.write(" (");
15376 for (i, (old_name, new_name)) in rename.iter().enumerate() {
15377 if i > 0 {
15378 self.write(", ");
15379 }
15380 self.generate_identifier(old_name)?;
15381 self.write_space();
15382 self.write_keyword("AS");
15383 self.write_space();
15384 self.generate_identifier(new_name)?;
15385 }
15386 self.write(")");
15387 }
15388 }
15389
15390 for comment in &star.trailing_comments {
15392 self.write_space();
15393 self.write_formatted_comment(comment);
15394 }
15395
15396 Ok(())
15397 }
15398
15399 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
15401 self.write("{");
15402 match expr {
15403 Expression::Star(star) => {
15404 self.generate_star(star)?;
15406 }
15407 Expression::ILike(ilike) => {
15408 self.generate_expression(&ilike.left)?;
15410 self.write_space();
15411 self.write_keyword("ILIKE");
15412 self.write_space();
15413 self.generate_expression(&ilike.right)?;
15414 }
15415 _ => {
15416 self.generate_expression(expr)?;
15417 }
15418 }
15419 self.write("}");
15420 Ok(())
15421 }
15422
15423 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
15424 match &alias.this {
15428 Expression::Column(col) => {
15429 if let Some(table) = &col.table {
15431 self.generate_identifier(table)?;
15432 self.write(".");
15433 }
15434 self.generate_identifier(&col.name)?;
15435 }
15436 _ => {
15437 self.generate_expression(&alias.this)?;
15438 }
15439 }
15440
15441 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
15445 for comment in &alias.pre_alias_comments {
15446 self.write_space();
15447 self.write_formatted_comment(comment);
15448 }
15449 }
15450
15451 use crate::dialects::DialectType;
15452
15453 let is_table_source = matches!(
15459 &alias.this,
15460 Expression::JSONTable(_)
15461 | Expression::XMLTable(_)
15462 | Expression::TableFromRows(_)
15463 | Expression::Unnest(_)
15464 | Expression::MatchRecognize(_)
15465 | Expression::Select(_)
15466 | Expression::Subquery(_)
15467 | Expression::Paren(_)
15468 );
15469 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
15470 let skip_as = is_table_source && dialect_skips_table_alias_as;
15471
15472 self.write_space();
15473 if !skip_as {
15474 self.write_keyword("AS");
15475 self.write_space();
15476 }
15477
15478 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
15480
15481 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
15483 self.write("(");
15485 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
15486 if i > 0 {
15487 self.write(", ");
15488 }
15489 self.generate_alias_identifier(col_alias)?;
15490 }
15491 self.write(")");
15492 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
15493 self.generate_alias_identifier(&alias.alias)?;
15495 self.write("(");
15496 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
15497 if i > 0 {
15498 self.write(", ");
15499 }
15500 self.generate_alias_identifier(col_alias)?;
15501 }
15502 self.write(")");
15503 } else {
15504 self.generate_alias_identifier(&alias.alias)?;
15506 }
15507
15508 for comment in &alias.trailing_comments {
15510 self.write_space();
15511 self.write_formatted_comment(comment);
15512 }
15513
15514 if alias.trailing_comments.is_empty() {
15519 for comment in &alias.pre_alias_comments {
15520 self.write_space();
15521 self.write_formatted_comment(comment);
15522 }
15523 }
15524
15525 Ok(())
15526 }
15527
15528 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
15529 use crate::dialects::DialectType;
15530
15531 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
15533 self.generate_expression(&cast.this)?;
15534 self.write(" :> ");
15535 self.generate_data_type(&cast.to)?;
15536 return Ok(());
15537 }
15538
15539 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
15541 let is_unknown_type = matches!(cast.to, DataType::Unknown)
15542 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
15543 if is_unknown_type {
15544 if let Some(format) = &cast.format {
15545 self.write_keyword("CAST");
15546 self.write("(");
15547 self.generate_expression(&cast.this)?;
15548 self.write_space();
15549 self.write_keyword("AS");
15550 self.write_space();
15551 self.write_keyword("FORMAT");
15552 self.write_space();
15553 self.generate_expression(format)?;
15554 self.write(")");
15555 return Ok(());
15556 }
15557 }
15558 }
15559
15560 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
15563 if let Some(format) = &cast.format {
15564 let is_date = matches!(cast.to, DataType::Date);
15566 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
15567
15568 if is_date || is_timestamp {
15569 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
15570 self.write_keyword(func_name);
15571 self.write("(");
15572 self.generate_expression(&cast.this)?;
15573 self.write(", ");
15574
15575 if let Expression::Literal(Literal::String(fmt_str)) = format.as_ref() {
15578 let normalized = self.normalize_oracle_format(fmt_str);
15579 self.write("'");
15580 self.write(&normalized);
15581 self.write("'");
15582 } else {
15583 self.generate_expression(format)?;
15584 }
15585
15586 self.write(")");
15587 return Ok(());
15588 }
15589 }
15590 }
15591
15592 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
15595 if let Expression::Array(arr) = &cast.this {
15596 self.generate_data_type(&cast.to)?;
15597 self.write("[");
15599 for (i, expr) in arr.expressions.iter().enumerate() {
15600 if i > 0 {
15601 self.write(", ");
15602 }
15603 self.generate_expression(expr)?;
15604 }
15605 self.write("]");
15606 return Ok(());
15607 }
15608 if matches!(&cast.this, Expression::ArrayFunc(_)) {
15609 self.generate_data_type(&cast.to)?;
15610 self.generate_expression(&cast.this)?;
15611 return Ok(());
15612 }
15613 }
15614
15615 if matches!(
15618 self.config.dialect,
15619 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
15620 ) {
15621 if let Expression::Struct(ref s) = cast.this {
15622 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
15623 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
15624 self.write_keyword("CAST");
15625 self.write("(");
15626 self.generate_struct_as_row(s)?;
15627 self.write_space();
15628 self.write_keyword("AS");
15629 self.write_space();
15630 self.generate_data_type(&cast.to)?;
15631 self.write(")");
15632 return Ok(());
15633 }
15634 }
15635 }
15636
15637 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
15640
15641 if use_double_colon {
15642 self.generate_expression(&cast.this)?;
15644 self.write("::");
15645 self.generate_data_type(&cast.to)?;
15646 } else {
15647 self.write_keyword("CAST");
15649 self.write("(");
15650 self.generate_expression(&cast.this)?;
15651 self.write_space();
15652 self.write_keyword("AS");
15653 self.write_space();
15654 if matches!(
15657 self.config.dialect,
15658 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
15659 ) {
15660 match &cast.to {
15661 DataType::Custom { ref name } => {
15662 let upper = name.to_uppercase();
15663 match upper.as_str() {
15664 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" | "LONGBLOB" | "MEDIUMBLOB"
15665 | "TINYBLOB" => {
15666 self.write_keyword("CHAR");
15667 }
15668 _ => {
15669 self.generate_data_type(&cast.to)?;
15670 }
15671 }
15672 }
15673 DataType::VarChar { length, .. } => {
15674 self.write_keyword("CHAR");
15676 if let Some(n) = length {
15677 self.write(&format!("({})", n));
15678 }
15679 }
15680 DataType::Text => {
15681 self.write_keyword("CHAR");
15683 }
15684 DataType::Timestamp {
15685 precision,
15686 timezone: false,
15687 } => {
15688 self.write_keyword("DATETIME");
15690 if let Some(p) = precision {
15691 self.write(&format!("({})", p));
15692 }
15693 }
15694 _ => {
15695 self.generate_data_type(&cast.to)?;
15696 }
15697 }
15698 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
15699 match &cast.to {
15701 DataType::String { length } => {
15702 self.write_keyword("VARCHAR");
15703 if let Some(n) = length {
15704 self.write(&format!("({})", n));
15705 }
15706 }
15707 _ => {
15708 self.generate_data_type(&cast.to)?;
15709 }
15710 }
15711 } else {
15712 self.generate_data_type(&cast.to)?;
15713 }
15714
15715 if let Some(default) = &cast.default {
15717 self.write_space();
15718 self.write_keyword("DEFAULT");
15719 self.write_space();
15720 self.generate_expression(default)?;
15721 self.write_space();
15722 self.write_keyword("ON");
15723 self.write_space();
15724 self.write_keyword("CONVERSION");
15725 self.write_space();
15726 self.write_keyword("ERROR");
15727 }
15728
15729 if let Some(format) = &cast.format {
15732 if matches!(
15734 self.config.dialect,
15735 Some(crate::dialects::DialectType::Oracle)
15736 ) {
15737 self.write(", ");
15738 } else {
15739 self.write_space();
15740 self.write_keyword("FORMAT");
15741 self.write_space();
15742 }
15743 self.generate_expression(format)?;
15744 }
15745
15746 self.write(")");
15747 for comment in &cast.trailing_comments {
15749 self.write_space();
15750 self.write_formatted_comment(comment);
15751 }
15752 }
15753 Ok(())
15754 }
15755
15756 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
15759 self.write_keyword("ROW");
15760 self.write("(");
15761 for (i, (_, expr)) in s.fields.iter().enumerate() {
15762 if i > 0 {
15763 self.write(", ");
15764 }
15765 if let Expression::Struct(ref inner_s) = expr {
15767 self.generate_struct_as_row(inner_s)?;
15768 } else {
15769 self.generate_expression(expr)?;
15770 }
15771 }
15772 self.write(")");
15773 Ok(())
15774 }
15775
15776 fn normalize_oracle_format(&self, format: &str) -> String {
15779 let mut result = String::new();
15782 let chars: Vec<char> = format.chars().collect();
15783 let mut i = 0;
15784
15785 while i < chars.len() {
15786 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
15787 if i + 2 < chars.len() {
15789 let next = chars[i + 2];
15790 if next == '1' || next == '2' {
15791 result.push('H');
15793 result.push('H');
15794 i += 2;
15795 continue;
15796 }
15797 }
15798 result.push_str("HH12");
15800 i += 2;
15801 } else {
15802 result.push(chars[i]);
15803 i += 1;
15804 }
15805 }
15806
15807 result
15808 }
15809
15810 fn dialect_prefers_double_colon(&self) -> bool {
15814 false
15817 }
15818
15819 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15821 use crate::dialects::DialectType;
15822
15823 let use_percent_operator = matches!(
15825 self.config.dialect,
15826 Some(DialectType::Snowflake)
15827 | Some(DialectType::MySQL)
15828 | Some(DialectType::Presto)
15829 | Some(DialectType::Trino)
15830 | Some(DialectType::PostgreSQL)
15831 | Some(DialectType::DuckDB)
15832 | Some(DialectType::Hive)
15833 | Some(DialectType::Spark)
15834 | Some(DialectType::Databricks)
15835 | Some(DialectType::Athena)
15836 );
15837
15838 if use_percent_operator {
15839 let needs_paren = |e: &Expression| matches!(e, Expression::Add(_) | Expression::Sub(_));
15842 if needs_paren(&f.this) {
15843 self.write("(");
15844 self.generate_expression(&f.this)?;
15845 self.write(")");
15846 } else {
15847 self.generate_expression(&f.this)?;
15848 }
15849 self.write(" % ");
15850 if needs_paren(&f.expression) {
15851 self.write("(");
15852 self.generate_expression(&f.expression)?;
15853 self.write(")");
15854 } else {
15855 self.generate_expression(&f.expression)?;
15856 }
15857 Ok(())
15858 } else {
15859 self.generate_binary_func("MOD", &f.this, &f.expression)
15860 }
15861 }
15862
15863 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15865 use crate::dialects::DialectType;
15866
15867 let func_name = match self.config.dialect {
15869 Some(DialectType::Snowflake) => "COALESCE",
15870 _ => "IFNULL",
15871 };
15872
15873 self.generate_binary_func(func_name, &f.this, &f.expression)
15874 }
15875
15876 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
15878 if let Some(ref original_name) = f.original_name {
15880 return self.generate_binary_func(original_name, &f.this, &f.expression);
15881 }
15882
15883 use crate::dialects::DialectType;
15885 let func_name = match self.config.dialect {
15886 Some(DialectType::Snowflake)
15887 | Some(DialectType::ClickHouse)
15888 | Some(DialectType::PostgreSQL)
15889 | Some(DialectType::Presto)
15890 | Some(DialectType::Trino)
15891 | Some(DialectType::Athena)
15892 | Some(DialectType::DuckDB)
15893 | Some(DialectType::BigQuery)
15894 | Some(DialectType::Spark)
15895 | Some(DialectType::Databricks)
15896 | Some(DialectType::Hive) => "COALESCE",
15897 Some(DialectType::MySQL)
15898 | Some(DialectType::Doris)
15899 | Some(DialectType::StarRocks)
15900 | Some(DialectType::SingleStore)
15901 | Some(DialectType::TiDB) => "IFNULL",
15902 _ => "NVL",
15903 };
15904
15905 self.generate_binary_func(func_name, &f.this, &f.expression)
15906 }
15907
15908 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
15910 use crate::dialects::DialectType;
15911
15912 let func_name = match self.config.dialect {
15914 Some(DialectType::Snowflake) => "STDDEV",
15915 _ => "STDDEV_SAMP",
15916 };
15917
15918 self.generate_agg_func(func_name, f)
15919 }
15920
15921 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
15922 self.generate_expression(&coll.this)?;
15923 self.write_space();
15924 self.write_keyword("COLLATE");
15925 self.write_space();
15926 if coll.quoted {
15927 self.write("'");
15929 self.write(&coll.collation);
15930 self.write("'");
15931 } else if coll.double_quoted {
15932 self.write("\"");
15934 self.write(&coll.collation);
15935 self.write("\"");
15936 } else {
15937 self.write(&coll.collation);
15939 }
15940 Ok(())
15941 }
15942
15943 fn generate_case(&mut self, case: &Case) -> Result<()> {
15944 let multiline_case = if self.config.pretty {
15946 let mut statements: Vec<String> = Vec::new();
15948 let operand_str = if let Some(operand) = &case.operand {
15949 let s = self.generate_to_string(operand)?;
15950 statements.push(format!("CASE {}", s));
15951 s
15952 } else {
15953 statements.push("CASE".to_string());
15954 String::new()
15955 };
15956 let _ = operand_str;
15957 for (condition, result) in &case.whens {
15958 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
15959 statements.push(format!("THEN {}", self.generate_to_string(result)?));
15960 }
15961 if let Some(else_) = &case.else_ {
15962 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
15963 }
15964 statements.push("END".to_string());
15965 self.too_wide(&statements)
15966 } else {
15967 false
15968 };
15969
15970 self.write_keyword("CASE");
15971 if let Some(operand) = &case.operand {
15972 self.write_space();
15973 self.generate_expression(operand)?;
15974 }
15975 if multiline_case {
15976 self.indent_level += 1;
15977 }
15978 for (condition, result) in &case.whens {
15979 if multiline_case {
15980 self.write_newline();
15981 self.write_indent();
15982 } else {
15983 self.write_space();
15984 }
15985 self.write_keyword("WHEN");
15986 self.write_space();
15987 self.generate_expression(condition)?;
15988 if multiline_case {
15989 self.write_newline();
15990 self.write_indent();
15991 } else {
15992 self.write_space();
15993 }
15994 self.write_keyword("THEN");
15995 self.write_space();
15996 self.generate_expression(result)?;
15997 }
15998 if let Some(else_) = &case.else_ {
15999 if multiline_case {
16000 self.write_newline();
16001 self.write_indent();
16002 } else {
16003 self.write_space();
16004 }
16005 self.write_keyword("ELSE");
16006 self.write_space();
16007 self.generate_expression(else_)?;
16008 }
16009 if multiline_case {
16010 self.indent_level -= 1;
16011 self.write_newline();
16012 self.write_indent();
16013 } else {
16014 self.write_space();
16015 }
16016 self.write_keyword("END");
16017 for comment in &case.comments {
16019 self.write(" ");
16020 self.write_formatted_comment(comment);
16021 }
16022 Ok(())
16023 }
16024
16025 fn generate_function(&mut self, func: &Function) -> Result<()> {
16026 let normalized_name = self.normalize_func_name(&func.name);
16028 let upper_name = func.name.to_uppercase();
16029
16030 if matches!(self.config.dialect, Some(DialectType::DuckDB))
16032 && upper_name == "ARRAY_CONSTRUCT_COMPACT"
16033 {
16034 self.write("LIST_FILTER(");
16035 self.write("[");
16036 for (i, arg) in func.args.iter().enumerate() {
16037 if i > 0 {
16038 self.write(", ");
16039 }
16040 self.generate_expression(arg)?;
16041 }
16042 self.write("], _u -> NOT _u IS NULL)");
16043 return Ok(());
16044 }
16045
16046 if upper_name == "STRUCT"
16048 && !matches!(
16049 self.config.dialect,
16050 Some(DialectType::BigQuery)
16051 | Some(DialectType::Spark)
16052 | Some(DialectType::Databricks)
16053 | Some(DialectType::Hive)
16054 | None
16055 )
16056 {
16057 return self.generate_struct_function_cross_dialect(func);
16058 }
16059
16060 if upper_name == "__SS_JSON_PATH_QMARK__" && func.args.len() == 2 {
16063 self.generate_expression(&func.args[0])?;
16064 self.write("::?");
16065 if let Expression::Literal(crate::expressions::Literal::String(key)) = &func.args[1] {
16067 self.write(key);
16068 } else {
16069 self.generate_expression(&func.args[1])?;
16070 }
16071 return Ok(());
16072 }
16073
16074 if upper_name == "__PG_BITWISE_XOR__" && func.args.len() == 2 {
16076 self.generate_expression(&func.args[0])?;
16077 self.write(" # ");
16078 self.generate_expression(&func.args[1])?;
16079 return Ok(());
16080 }
16081
16082 if matches!(
16084 self.config.dialect,
16085 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
16086 ) && upper_name == "TRY"
16087 && func.args.len() == 1
16088 {
16089 self.generate_expression(&func.args[0])?;
16090 return Ok(());
16091 }
16092
16093 if self.config.dialect == Some(DialectType::ClickHouse)
16095 && upper_name == "TOSTARTOFDAY"
16096 && func.args.len() == 1
16097 {
16098 self.write("dateTrunc('DAY', ");
16099 self.generate_expression(&func.args[0])?;
16100 self.write(")");
16101 return Ok(());
16102 }
16103
16104 if self.config.dialect == Some(DialectType::Redshift)
16106 && upper_name == "CONCAT"
16107 && func.args.len() >= 2
16108 {
16109 for (i, arg) in func.args.iter().enumerate() {
16110 if i > 0 {
16111 self.write(" || ");
16112 }
16113 self.generate_expression(arg)?;
16114 }
16115 return Ok(());
16116 }
16117
16118 if self.config.dialect == Some(DialectType::Redshift)
16120 && upper_name == "CONCAT_WS"
16121 && func.args.len() >= 2
16122 {
16123 let sep = &func.args[0];
16124 for (i, arg) in func.args.iter().skip(1).enumerate() {
16125 if i > 0 {
16126 self.write(" || ");
16127 self.generate_expression(sep)?;
16128 self.write(" || ");
16129 }
16130 self.generate_expression(arg)?;
16131 }
16132 return Ok(());
16133 }
16134
16135 if self.config.dialect == Some(DialectType::Redshift)
16138 && (upper_name == "DATEDIFF" || upper_name == "DATE_DIFF")
16139 && func.args.len() == 3
16140 {
16141 self.write_keyword("DATEDIFF");
16142 self.write("(");
16143 self.write_redshift_date_part(&func.args[0]);
16145 self.write(", ");
16146 self.generate_expression(&func.args[1])?;
16147 self.write(", ");
16148 self.generate_expression(&func.args[2])?;
16149 self.write(")");
16150 return Ok(());
16151 }
16152
16153 if self.config.dialect == Some(DialectType::Redshift)
16156 && (upper_name == "DATEADD" || upper_name == "DATE_ADD")
16157 && func.args.len() == 3
16158 {
16159 self.write_keyword("DATEADD");
16160 self.write("(");
16161 self.write_redshift_date_part(&func.args[0]);
16163 self.write(", ");
16164 self.generate_expression(&func.args[1])?;
16165 self.write(", ");
16166 self.generate_expression(&func.args[2])?;
16167 self.write(")");
16168 return Ok(());
16169 }
16170
16171 if upper_name == "UUID_STRING"
16173 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
16174 {
16175 let func_name = match self.config.dialect {
16176 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
16177 Some(DialectType::BigQuery) => "GENERATE_UUID",
16178 _ => "UUID",
16179 };
16180 self.write_keyword(func_name);
16181 self.write("()");
16182 return Ok(());
16183 }
16184
16185 if self.config.dialect == Some(DialectType::Redshift)
16188 && upper_name == "DATE_TRUNC"
16189 && func.args.len() == 2
16190 {
16191 self.write_keyword("DATE_TRUNC");
16192 self.write("(");
16193 self.write_redshift_date_part_quoted(&func.args[0]);
16195 self.write(", ");
16196 self.generate_expression(&func.args[1])?;
16197 self.write(")");
16198 return Ok(());
16199 }
16200
16201 if matches!(
16203 self.config.dialect,
16204 Some(DialectType::TSQL) | Some(DialectType::Fabric)
16205 ) && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16206 && func.args.len() == 2
16207 {
16208 self.write_keyword("DATEPART");
16209 self.write("(");
16210 self.generate_expression(&func.args[0])?;
16211 self.write(", ");
16212 self.generate_expression(&func.args[1])?;
16213 self.write(")");
16214 return Ok(());
16215 }
16216
16217 if matches!(
16219 self.config.dialect,
16220 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
16221 ) && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16222 && func.args.len() == 2
16223 {
16224 self.write_keyword("EXTRACT");
16225 self.write("(");
16226 match &func.args[0] {
16228 Expression::Literal(crate::expressions::Literal::String(s)) => {
16229 self.write(&s.to_lowercase());
16230 }
16231 _ => self.generate_expression(&func.args[0])?,
16232 }
16233 self.write_space();
16234 self.write_keyword("FROM");
16235 self.write_space();
16236 self.generate_expression(&func.args[1])?;
16237 self.write(")");
16238 return Ok(());
16239 }
16240
16241 if self.config.dialect == Some(DialectType::Dremio)
16244 && (upper_name == "DATE_PART" || upper_name == "DATEPART")
16245 && func.args.len() == 2
16246 {
16247 self.write_keyword("EXTRACT");
16248 self.write("(");
16249 self.generate_expression(&func.args[0])?;
16250 self.write_space();
16251 self.write_keyword("FROM");
16252 self.write_space();
16253 self.generate_dremio_date_expression(&func.args[1])?;
16255 self.write(")");
16256 return Ok(());
16257 }
16258
16259 if self.config.dialect == Some(DialectType::Dremio)
16261 && upper_name == "CURRENT_DATE_UTC"
16262 && func.args.is_empty()
16263 {
16264 self.write_keyword("CURRENT_DATE_UTC");
16265 return Ok(());
16266 }
16267
16268 if self.config.dialect == Some(DialectType::Dremio)
16272 && upper_name == "DATETYPE"
16273 && func.args.len() == 3
16274 {
16275 fn get_int_literal(expr: &Expression) -> Option<i64> {
16277 if let Expression::Literal(crate::expressions::Literal::Number(s)) = expr {
16278 s.parse::<i64>().ok()
16279 } else {
16280 None
16281 }
16282 }
16283
16284 if let (Some(year), Some(month), Some(day)) = (
16286 get_int_literal(&func.args[0]),
16287 get_int_literal(&func.args[1]),
16288 get_int_literal(&func.args[2]),
16289 ) {
16290 self.write_keyword("DATE");
16292 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
16293 return Ok(());
16294 }
16295
16296 self.write_keyword("CAST");
16298 self.write("(");
16299 self.write_keyword("CONCAT");
16300 self.write("(");
16301 self.generate_expression(&func.args[0])?;
16302 self.write(", '-', ");
16303 self.generate_expression(&func.args[1])?;
16304 self.write(", '-', ");
16305 self.generate_expression(&func.args[2])?;
16306 self.write(")");
16307 self.write_space();
16308 self.write_keyword("AS");
16309 self.write_space();
16310 self.write_keyword("DATE");
16311 self.write(")");
16312 return Ok(());
16313 }
16314
16315 let is_presto_like = matches!(
16318 self.config.dialect,
16319 Some(DialectType::Presto) | Some(DialectType::Trino)
16320 );
16321 if is_presto_like && upper_name == "DATE_ADD" && func.args.len() == 3 {
16322 self.write_keyword("DATE_ADD");
16323 self.write("(");
16324 self.generate_expression(&func.args[0])?;
16326 self.write(", ");
16327 let interval = &func.args[1];
16329 let needs_cast = !self.returns_integer_type(interval);
16330 if needs_cast {
16331 self.write_keyword("CAST");
16332 self.write("(");
16333 }
16334 self.generate_expression(interval)?;
16335 if needs_cast {
16336 self.write_space();
16337 self.write_keyword("AS");
16338 self.write_space();
16339 self.write_keyword("BIGINT");
16340 self.write(")");
16341 }
16342 self.write(", ");
16343 self.generate_expression(&func.args[2])?;
16345 self.write(")");
16346 return Ok(());
16347 }
16348
16349 let use_brackets = func.use_bracket_syntax;
16351
16352 let has_ordinality = upper_name.ends_with(" WITH ORDINALITY");
16357 let output_name = if has_ordinality {
16358 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
16359 self.normalize_func_name(base_name)
16360 } else {
16361 normalized_name.clone()
16362 };
16363
16364 if func.name.contains('.') && !has_ordinality {
16367 if func.quoted {
16370 self.write("`");
16371 self.write(&func.name);
16372 self.write("`");
16373 } else {
16374 self.write(&func.name);
16375 }
16376 } else {
16377 self.write(&output_name);
16378 }
16379
16380 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
16383 let needs_parens = match upper_name.as_str() {
16384 "CURRENT_USER" | "SESSION_USER" | "SYSTEM_USER" => matches!(
16385 self.config.dialect,
16386 Some(DialectType::Snowflake)
16387 | Some(DialectType::Spark)
16388 | Some(DialectType::Databricks)
16389 | Some(DialectType::Hive)
16390 ),
16391 _ => false,
16392 };
16393 !needs_parens
16394 };
16395 if force_parens {
16396 for comment in &func.trailing_comments {
16398 self.write_space();
16399 self.write_formatted_comment(comment);
16400 }
16401 return Ok(());
16402 }
16403
16404 if upper_name == "CUBE" || upper_name == "ROLLUP" || upper_name == "GROUPING SETS" {
16406 self.write(" (");
16407 } else if use_brackets {
16408 self.write("[");
16409 } else {
16410 self.write("(");
16411 }
16412 if func.distinct {
16413 self.write_keyword("DISTINCT");
16414 self.write_space();
16415 }
16416
16417 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
16419 && (upper_name == "TABLE" || upper_name == "FLATTEN");
16420 let is_grouping_func =
16422 upper_name == "GROUPING SETS" || upper_name == "CUBE" || upper_name == "ROLLUP";
16423 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
16424 if is_grouping_func {
16425 true
16426 } else {
16427 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
16429 for arg in &func.args {
16430 let mut temp_gen = Generator::with_config(self.config.clone());
16431 temp_gen.config.pretty = false; temp_gen.generate_expression(arg)?;
16433 expr_strings.push(temp_gen.output);
16434 }
16435 self.too_wide(&expr_strings)
16436 }
16437 } else {
16438 false
16439 };
16440
16441 if should_split {
16442 self.write_newline();
16444 self.indent_level += 1;
16445 for (i, arg) in func.args.iter().enumerate() {
16446 self.write_indent();
16447 self.generate_expression(arg)?;
16448 if i + 1 < func.args.len() {
16449 self.write(",");
16450 }
16451 self.write_newline();
16452 }
16453 self.indent_level -= 1;
16454 self.write_indent();
16455 } else {
16456 for (i, arg) in func.args.iter().enumerate() {
16458 if i > 0 {
16459 self.write(", ");
16460 }
16461 self.generate_expression(arg)?;
16462 }
16463 }
16464
16465 if use_brackets {
16466 self.write("]");
16467 } else {
16468 self.write(")");
16469 }
16470 if has_ordinality {
16472 self.write_space();
16473 self.write_keyword("WITH ORDINALITY");
16474 }
16475 for comment in &func.trailing_comments {
16477 self.write_space();
16478 self.write_formatted_comment(comment);
16479 }
16480 Ok(())
16481 }
16482
16483 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
16484 let mut normalized_name = self.normalize_func_name(&func.name);
16486
16487 let upper = normalized_name.to_uppercase();
16489 if upper == "MAX_BY" || upper == "MIN_BY" {
16490 let is_max = upper == "MAX_BY";
16491 match self.config.dialect {
16492 Some(DialectType::ClickHouse) => {
16493 normalized_name = if is_max {
16494 "argMax".to_string()
16495 } else {
16496 "argMin".to_string()
16497 };
16498 }
16499 Some(DialectType::DuckDB) => {
16500 normalized_name = if is_max {
16501 "ARG_MAX".to_string()
16502 } else {
16503 "ARG_MIN".to_string()
16504 };
16505 }
16506 _ => {}
16507 }
16508 }
16509 self.write(&normalized_name);
16510 self.write("(");
16511 if func.distinct {
16512 self.write_keyword("DISTINCT");
16513 self.write_space();
16514 }
16515
16516 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
16520 let needs_multi_arg_transform =
16521 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
16522
16523 if needs_multi_arg_transform {
16524 self.write_keyword("CASE");
16526 for arg in &func.args {
16527 self.write_space();
16528 self.write_keyword("WHEN");
16529 self.write_space();
16530 self.generate_expression(arg)?;
16531 self.write_space();
16532 self.write_keyword("IS NULL THEN NULL");
16533 }
16534 self.write_space();
16535 self.write_keyword("ELSE");
16536 self.write(" (");
16537 for (i, arg) in func.args.iter().enumerate() {
16538 if i > 0 {
16539 self.write(", ");
16540 }
16541 self.generate_expression(arg)?;
16542 }
16543 self.write(")");
16544 self.write_space();
16545 self.write_keyword("END");
16546 } else {
16547 for (i, arg) in func.args.iter().enumerate() {
16548 if i > 0 {
16549 self.write(", ");
16550 }
16551 self.generate_expression(arg)?;
16552 }
16553 }
16554
16555 if self.config.ignore_nulls_in_func
16557 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
16558 {
16559 if let Some(ignore) = func.ignore_nulls {
16560 self.write_space();
16561 if ignore {
16562 self.write_keyword("IGNORE NULLS");
16563 } else {
16564 self.write_keyword("RESPECT NULLS");
16565 }
16566 }
16567 }
16568
16569 if !func.order_by.is_empty() {
16571 self.write_space();
16572 self.write_keyword("ORDER BY");
16573 self.write_space();
16574 for (i, ord) in func.order_by.iter().enumerate() {
16575 if i > 0 {
16576 self.write(", ");
16577 }
16578 self.generate_ordered(ord)?;
16579 }
16580 }
16581
16582 if let Some(limit) = &func.limit {
16584 self.write_space();
16585 self.write_keyword("LIMIT");
16586 self.write_space();
16587 if let Expression::Tuple(t) = limit.as_ref() {
16589 if t.expressions.len() == 2 {
16590 self.generate_expression(&t.expressions[0])?;
16591 self.write(", ");
16592 self.generate_expression(&t.expressions[1])?;
16593 } else {
16594 self.generate_expression(limit)?;
16595 }
16596 } else {
16597 self.generate_expression(limit)?;
16598 }
16599 }
16600
16601 self.write(")");
16602
16603 if !self.config.ignore_nulls_in_func
16605 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
16606 {
16607 if let Some(ignore) = func.ignore_nulls {
16608 self.write_space();
16609 if ignore {
16610 self.write_keyword("IGNORE NULLS");
16611 } else {
16612 self.write_keyword("RESPECT NULLS");
16613 }
16614 }
16615 }
16616
16617 if let Some(filter) = &func.filter {
16618 self.write_space();
16619 self.write_keyword("FILTER");
16620 self.write("(");
16621 self.write_keyword("WHERE");
16622 self.write_space();
16623 self.generate_expression(filter)?;
16624 self.write(")");
16625 }
16626
16627 Ok(())
16628 }
16629
16630 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
16631 self.generate_expression(&wf.this)?;
16632
16633 if let Some(keep) = &wf.keep {
16635 self.write_space();
16636 self.write_keyword("KEEP");
16637 self.write(" (");
16638 self.write_keyword("DENSE_RANK");
16639 self.write_space();
16640 if keep.first {
16641 self.write_keyword("FIRST");
16642 } else {
16643 self.write_keyword("LAST");
16644 }
16645 self.write_space();
16646 self.write_keyword("ORDER BY");
16647 self.write_space();
16648 for (i, ord) in keep.order_by.iter().enumerate() {
16649 if i > 0 {
16650 self.write(", ");
16651 }
16652 self.generate_ordered(ord)?;
16653 }
16654 self.write(")");
16655 }
16656
16657 let has_over = !wf.over.partition_by.is_empty()
16659 || !wf.over.order_by.is_empty()
16660 || wf.over.frame.is_some()
16661 || wf.over.window_name.is_some();
16662
16663 if has_over {
16665 self.write_space();
16666 self.write_keyword("OVER");
16667
16668 let has_specs = !wf.over.partition_by.is_empty()
16670 || !wf.over.order_by.is_empty()
16671 || wf.over.frame.is_some();
16672
16673 if wf.over.window_name.is_some() && !has_specs {
16674 self.write_space();
16676 self.write(&wf.over.window_name.as_ref().unwrap().name);
16677 } else {
16678 self.write(" (");
16680 self.generate_over(&wf.over)?;
16681 self.write(")");
16682 }
16683 } else if wf.keep.is_none() {
16684 self.write_space();
16686 self.write_keyword("OVER");
16687 self.write(" ()");
16688 }
16689
16690 Ok(())
16691 }
16692
16693 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
16695 self.generate_expression(&wg.this)?;
16696 self.write_space();
16697 self.write_keyword("WITHIN GROUP");
16698 self.write(" (");
16699 self.write_keyword("ORDER BY");
16700 self.write_space();
16701 for (i, ord) in wg.order_by.iter().enumerate() {
16702 if i > 0 {
16703 self.write(", ");
16704 }
16705 self.generate_ordered(ord)?;
16706 }
16707 self.write(")");
16708 Ok(())
16709 }
16710
16711 fn generate_over(&mut self, over: &Over) -> Result<()> {
16713 let mut has_content = false;
16714
16715 if let Some(name) = &over.window_name {
16717 self.write(&name.name);
16718 has_content = true;
16719 }
16720
16721 if !over.partition_by.is_empty() {
16723 if has_content {
16724 self.write_space();
16725 }
16726 self.write_keyword("PARTITION BY");
16727 self.write_space();
16728 for (i, expr) in over.partition_by.iter().enumerate() {
16729 if i > 0 {
16730 self.write(", ");
16731 }
16732 self.generate_expression(expr)?;
16733 }
16734 has_content = true;
16735 }
16736
16737 if !over.order_by.is_empty() {
16739 if has_content {
16740 self.write_space();
16741 }
16742 self.write_keyword("ORDER BY");
16743 self.write_space();
16744 for (i, ordered) in over.order_by.iter().enumerate() {
16745 if i > 0 {
16746 self.write(", ");
16747 }
16748 self.generate_ordered(ordered)?;
16749 }
16750 has_content = true;
16751 }
16752
16753 if let Some(frame) = &over.frame {
16755 if has_content {
16756 self.write_space();
16757 }
16758 self.generate_window_frame(frame)?;
16759 }
16760
16761 Ok(())
16762 }
16763
16764 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
16765 let lowercase_frame = self.config.lowercase_window_frame_keywords;
16767
16768 if !lowercase_frame {
16770 if let Some(kind_text) = &frame.kind_text {
16771 self.write(kind_text);
16772 } else {
16773 match frame.kind {
16774 WindowFrameKind::Rows => self.write_keyword("ROWS"),
16775 WindowFrameKind::Range => self.write_keyword("RANGE"),
16776 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
16777 }
16778 }
16779 } else {
16780 match frame.kind {
16781 WindowFrameKind::Rows => self.write("rows"),
16782 WindowFrameKind::Range => self.write("range"),
16783 WindowFrameKind::Groups => self.write("groups"),
16784 }
16785 }
16786
16787 self.write_space();
16790 let should_normalize = self.config.normalize_window_frame_between
16791 && frame.end.is_none()
16792 && matches!(
16793 frame.start,
16794 WindowFrameBound::Preceding(_)
16795 | WindowFrameBound::Following(_)
16796 | WindowFrameBound::UnboundedPreceding
16797 | WindowFrameBound::UnboundedFollowing
16798 );
16799
16800 if let Some(end) = &frame.end {
16801 self.write_keyword("BETWEEN");
16803 self.write_space();
16804 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16805 self.write_space();
16806 self.write_keyword("AND");
16807 self.write_space();
16808 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
16809 } else if should_normalize {
16810 self.write_keyword("BETWEEN");
16812 self.write_space();
16813 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16814 self.write_space();
16815 self.write_keyword("AND");
16816 self.write_space();
16817 self.write_keyword("CURRENT ROW");
16818 } else {
16819 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
16821 }
16822
16823 if let Some(exclude) = &frame.exclude {
16825 self.write_space();
16826 self.write_keyword("EXCLUDE");
16827 self.write_space();
16828 match exclude {
16829 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
16830 WindowFrameExclude::Group => self.write_keyword("GROUP"),
16831 WindowFrameExclude::Ties => self.write_keyword("TIES"),
16832 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
16833 }
16834 }
16835
16836 Ok(())
16837 }
16838
16839 fn generate_window_frame_bound(
16840 &mut self,
16841 bound: &WindowFrameBound,
16842 side_text: Option<&str>,
16843 ) -> Result<()> {
16844 let lowercase_frame = self.config.lowercase_window_frame_keywords;
16846
16847 match bound {
16848 WindowFrameBound::CurrentRow => {
16849 self.write_keyword("CURRENT ROW");
16850 }
16851 WindowFrameBound::UnboundedPreceding => {
16852 self.write_keyword("UNBOUNDED");
16853 self.write_space();
16854 if lowercase_frame {
16855 self.write("preceding");
16856 } else if let Some(text) = side_text {
16857 self.write(text);
16858 } else {
16859 self.write_keyword("PRECEDING");
16860 }
16861 }
16862 WindowFrameBound::UnboundedFollowing => {
16863 self.write_keyword("UNBOUNDED");
16864 self.write_space();
16865 if lowercase_frame {
16866 self.write("following");
16867 } else if let Some(text) = side_text {
16868 self.write(text);
16869 } else {
16870 self.write_keyword("FOLLOWING");
16871 }
16872 }
16873 WindowFrameBound::Preceding(expr) => {
16874 self.generate_expression(expr)?;
16875 self.write_space();
16876 if lowercase_frame {
16877 self.write("preceding");
16878 } else if let Some(text) = side_text {
16879 self.write(text);
16880 } else {
16881 self.write_keyword("PRECEDING");
16882 }
16883 }
16884 WindowFrameBound::Following(expr) => {
16885 self.generate_expression(expr)?;
16886 self.write_space();
16887 if lowercase_frame {
16888 self.write("following");
16889 } else if let Some(text) = side_text {
16890 self.write(text);
16891 } else {
16892 self.write_keyword("FOLLOWING");
16893 }
16894 }
16895 WindowFrameBound::BarePreceding => {
16896 if lowercase_frame {
16897 self.write("preceding");
16898 } else if let Some(text) = side_text {
16899 self.write(text);
16900 } else {
16901 self.write_keyword("PRECEDING");
16902 }
16903 }
16904 WindowFrameBound::BareFollowing => {
16905 if lowercase_frame {
16906 self.write("following");
16907 } else if let Some(text) = side_text {
16908 self.write(text);
16909 } else {
16910 self.write_keyword("FOLLOWING");
16911 }
16912 }
16913 WindowFrameBound::Value(expr) => {
16914 self.generate_expression(expr)?;
16916 }
16917 }
16918 Ok(())
16919 }
16920
16921 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
16922 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
16925 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
16926 && !matches!(&interval.this, Some(Expression::Literal(_)));
16927
16928 if self.config.single_string_interval {
16931 if let (
16932 Some(Expression::Literal(Literal::String(ref val))),
16933 Some(IntervalUnitSpec::Simple {
16934 ref unit,
16935 ref use_plural,
16936 }),
16937 ) = (&interval.this, &interval.unit)
16938 {
16939 self.write_keyword("INTERVAL");
16940 self.write_space();
16941 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
16942 let unit_str = self.interval_unit_str(unit, effective_plural);
16943 self.write("'");
16944 self.write(val);
16945 self.write(" ");
16946 self.write(&unit_str);
16947 self.write("'");
16948 return Ok(());
16949 }
16950 }
16951
16952 if !skip_interval_keyword {
16953 self.write_keyword("INTERVAL");
16954 }
16955
16956 if let Some(ref value) = interval.this {
16958 if !skip_interval_keyword {
16959 self.write_space();
16960 }
16961 let needs_parens = interval.unit.is_some()
16965 && matches!(
16966 value,
16967 Expression::Add(_)
16968 | Expression::Sub(_)
16969 | Expression::Mul(_)
16970 | Expression::Div(_)
16971 | Expression::Mod(_)
16972 | Expression::BitwiseAnd(_)
16973 | Expression::BitwiseOr(_)
16974 | Expression::BitwiseXor(_)
16975 );
16976 if needs_parens {
16977 self.write("(");
16978 }
16979 self.generate_expression(value)?;
16980 if needs_parens {
16981 self.write(")");
16982 }
16983 }
16984
16985 if let Some(ref unit_spec) = interval.unit {
16987 self.write_space();
16988 self.write_interval_unit_spec(unit_spec)?;
16989 }
16990
16991 Ok(())
16992 }
16993
16994 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
16996 match (unit, use_plural) {
16997 (IntervalUnit::Year, false) => "YEAR",
16998 (IntervalUnit::Year, true) => "YEARS",
16999 (IntervalUnit::Quarter, false) => "QUARTER",
17000 (IntervalUnit::Quarter, true) => "QUARTERS",
17001 (IntervalUnit::Month, false) => "MONTH",
17002 (IntervalUnit::Month, true) => "MONTHS",
17003 (IntervalUnit::Week, false) => "WEEK",
17004 (IntervalUnit::Week, true) => "WEEKS",
17005 (IntervalUnit::Day, false) => "DAY",
17006 (IntervalUnit::Day, true) => "DAYS",
17007 (IntervalUnit::Hour, false) => "HOUR",
17008 (IntervalUnit::Hour, true) => "HOURS",
17009 (IntervalUnit::Minute, false) => "MINUTE",
17010 (IntervalUnit::Minute, true) => "MINUTES",
17011 (IntervalUnit::Second, false) => "SECOND",
17012 (IntervalUnit::Second, true) => "SECONDS",
17013 (IntervalUnit::Millisecond, false) => "MILLISECOND",
17014 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
17015 (IntervalUnit::Microsecond, false) => "MICROSECOND",
17016 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
17017 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
17018 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
17019 }
17020 }
17021
17022 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
17023 match unit_spec {
17024 IntervalUnitSpec::Simple { unit, use_plural } => {
17025 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
17027 self.write_simple_interval_unit(unit, effective_plural);
17028 }
17029 IntervalUnitSpec::Span(span) => {
17030 self.write_simple_interval_unit(&span.this, false);
17031 self.write_space();
17032 self.write_keyword("TO");
17033 self.write_space();
17034 self.write_simple_interval_unit(&span.expression, false);
17035 }
17036 IntervalUnitSpec::ExprSpan(span) => {
17037 self.generate_expression(&span.this)?;
17039 self.write_space();
17040 self.write_keyword("TO");
17041 self.write_space();
17042 self.generate_expression(&span.expression)?;
17043 }
17044 IntervalUnitSpec::Expr(expr) => {
17045 self.generate_expression(expr)?;
17046 }
17047 }
17048 Ok(())
17049 }
17050
17051 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
17052 match (unit, use_plural) {
17054 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
17055 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
17056 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
17057 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
17058 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
17059 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
17060 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
17061 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
17062 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
17063 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
17064 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
17065 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
17066 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
17067 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
17068 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
17069 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
17070 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
17071 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
17072 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
17073 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
17074 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
17075 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
17076 }
17077 }
17078
17079 fn write_redshift_date_part(&mut self, expr: &Expression) {
17082 let part_str = self.extract_date_part_string(expr);
17083 if let Some(part) = part_str {
17084 let normalized = self.normalize_date_part(&part);
17085 self.write_keyword(&normalized);
17086 } else {
17087 let _ = self.generate_expression(expr);
17089 }
17090 }
17091
17092 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
17095 let part_str = self.extract_date_part_string(expr);
17096 if let Some(part) = part_str {
17097 let normalized = self.normalize_date_part(&part);
17098 self.write("'");
17099 self.write(&normalized);
17100 self.write("'");
17101 } else {
17102 let _ = self.generate_expression(expr);
17104 }
17105 }
17106
17107 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
17109 match expr {
17110 Expression::Literal(crate::expressions::Literal::String(s)) => Some(s.clone()),
17111 Expression::Identifier(id) => Some(id.name.clone()),
17112 Expression::Column(col) if col.table.is_none() => {
17113 Some(col.name.name.clone())
17115 }
17116 _ => None,
17117 }
17118 }
17119
17120 fn normalize_date_part(&self, part: &str) -> String {
17123 let lower = part.to_lowercase();
17124 match lower.as_str() {
17125 "day" | "days" | "d" => "DAY".to_string(),
17126 "month" | "months" | "mon" | "mm" => "MONTH".to_string(),
17127 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
17128 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
17129 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
17130 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
17131 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
17132 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
17133 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
17134 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
17135 _ => part.to_uppercase(),
17136 }
17137 }
17138
17139 fn write_datetime_field(&mut self, field: &DateTimeField) {
17140 match field {
17141 DateTimeField::Year => self.write_keyword("YEAR"),
17142 DateTimeField::Month => self.write_keyword("MONTH"),
17143 DateTimeField::Day => self.write_keyword("DAY"),
17144 DateTimeField::Hour => self.write_keyword("HOUR"),
17145 DateTimeField::Minute => self.write_keyword("MINUTE"),
17146 DateTimeField::Second => self.write_keyword("SECOND"),
17147 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
17148 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
17149 DateTimeField::DayOfWeek => {
17150 let name = match self.config.dialect {
17151 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
17152 _ => "DOW",
17153 };
17154 self.write_keyword(name);
17155 }
17156 DateTimeField::DayOfYear => {
17157 let name = match self.config.dialect {
17158 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
17159 _ => "DOY",
17160 };
17161 self.write_keyword(name);
17162 }
17163 DateTimeField::Week => self.write_keyword("WEEK"),
17164 DateTimeField::WeekWithModifier(modifier) => {
17165 self.write_keyword("WEEK");
17166 self.write("(");
17167 self.write(modifier);
17168 self.write(")");
17169 }
17170 DateTimeField::Quarter => self.write_keyword("QUARTER"),
17171 DateTimeField::Epoch => self.write_keyword("EPOCH"),
17172 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
17173 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
17174 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
17175 DateTimeField::Date => self.write_keyword("DATE"),
17176 DateTimeField::Time => self.write_keyword("TIME"),
17177 DateTimeField::Custom(name) => self.write(name),
17178 }
17179 }
17180
17181 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
17183 match field {
17184 DateTimeField::Year => self.write("year"),
17185 DateTimeField::Month => self.write("month"),
17186 DateTimeField::Day => self.write("day"),
17187 DateTimeField::Hour => self.write("hour"),
17188 DateTimeField::Minute => self.write("minute"),
17189 DateTimeField::Second => self.write("second"),
17190 DateTimeField::Millisecond => self.write("millisecond"),
17191 DateTimeField::Microsecond => self.write("microsecond"),
17192 DateTimeField::DayOfWeek => self.write("dow"),
17193 DateTimeField::DayOfYear => self.write("doy"),
17194 DateTimeField::Week => self.write("week"),
17195 DateTimeField::WeekWithModifier(modifier) => {
17196 self.write("week(");
17197 self.write(modifier);
17198 self.write(")");
17199 }
17200 DateTimeField::Quarter => self.write("quarter"),
17201 DateTimeField::Epoch => self.write("epoch"),
17202 DateTimeField::Timezone => self.write("timezone"),
17203 DateTimeField::TimezoneHour => self.write("timezone_hour"),
17204 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
17205 DateTimeField::Date => self.write("date"),
17206 DateTimeField::Time => self.write("time"),
17207 DateTimeField::Custom(name) => self.write(name),
17208 }
17209 }
17210
17211 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
17214 self.write_keyword(name);
17215 self.write("(");
17216 self.generate_expression(arg)?;
17217 self.write(")");
17218 Ok(())
17219 }
17220
17221 fn generate_unary_func(
17223 &mut self,
17224 default_name: &str,
17225 f: &crate::expressions::UnaryFunc,
17226 ) -> Result<()> {
17227 let name = f.original_name.as_deref().unwrap_or(default_name);
17228 self.write_keyword(name);
17229 self.write("(");
17230 self.generate_expression(&f.this)?;
17231 self.write(")");
17232 Ok(())
17233 }
17234
17235 fn generate_sqrt_cbrt(
17237 &mut self,
17238 f: &crate::expressions::UnaryFunc,
17239 func_name: &str,
17240 _op: &str,
17241 ) -> Result<()> {
17242 self.write_keyword(func_name);
17245 self.write("(");
17246 self.generate_expression(&f.this)?;
17247 self.write(")");
17248 Ok(())
17249 }
17250
17251 fn generate_binary_func(
17252 &mut self,
17253 name: &str,
17254 arg1: &Expression,
17255 arg2: &Expression,
17256 ) -> Result<()> {
17257 self.write_keyword(name);
17258 self.write("(");
17259 self.generate_expression(arg1)?;
17260 self.write(", ");
17261 self.generate_expression(arg2)?;
17262 self.write(")");
17263 Ok(())
17264 }
17265
17266 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
17270 let func_name = f.name.as_deref().unwrap_or("CHAR");
17272 self.write_keyword(func_name);
17273 self.write("(");
17274 for (i, arg) in f.args.iter().enumerate() {
17275 if i > 0 {
17276 self.write(", ");
17277 }
17278 self.generate_expression(arg)?;
17279 }
17280 if let Some(ref charset) = f.charset {
17281 self.write(" ");
17282 self.write_keyword("USING");
17283 self.write(" ");
17284 self.write(charset);
17285 }
17286 self.write(")");
17287 Ok(())
17288 }
17289
17290 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
17291 use crate::dialects::DialectType;
17292
17293 match self.config.dialect {
17294 Some(DialectType::Teradata) => {
17295 self.generate_expression(&f.this)?;
17297 self.write(" ** ");
17298 self.generate_expression(&f.expression)?;
17299 Ok(())
17300 }
17301 _ => {
17302 self.generate_binary_func("POWER", &f.this, &f.expression)
17304 }
17305 }
17306 }
17307
17308 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
17309 self.write_func_name(name);
17310 self.write("(");
17311 for (i, arg) in args.iter().enumerate() {
17312 if i > 0 {
17313 self.write(", ");
17314 }
17315 self.generate_expression(arg)?;
17316 }
17317 self.write(")");
17318 Ok(())
17319 }
17320
17321 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
17324 self.write_keyword("CONCAT_WS");
17325 self.write("(");
17326 self.generate_expression(&f.separator)?;
17327 for expr in &f.expressions {
17328 self.write(", ");
17329 self.generate_expression(expr)?;
17330 }
17331 self.write(")");
17332 Ok(())
17333 }
17334
17335 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
17336 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
17338 if is_oracle {
17339 self.write_keyword("SUBSTR");
17340 } else {
17341 self.write_keyword("SUBSTRING");
17342 }
17343 self.write("(");
17344 self.generate_expression(&f.this)?;
17345 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
17347 let use_comma_syntax = matches!(
17349 self.config.dialect,
17350 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
17351 );
17352 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
17353 self.write_space();
17355 self.write_keyword("FROM");
17356 self.write_space();
17357 self.generate_expression(&f.start)?;
17358 if let Some(length) = &f.length {
17359 self.write_space();
17360 self.write_keyword("FOR");
17361 self.write_space();
17362 self.generate_expression(length)?;
17363 }
17364 } else {
17365 self.write(", ");
17367 self.generate_expression(&f.start)?;
17368 if let Some(length) = &f.length {
17369 self.write(", ");
17370 self.generate_expression(length)?;
17371 }
17372 }
17373 self.write(")");
17374 Ok(())
17375 }
17376
17377 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
17378 self.write_keyword("OVERLAY");
17379 self.write("(");
17380 self.generate_expression(&f.this)?;
17381 self.write_space();
17382 self.write_keyword("PLACING");
17383 self.write_space();
17384 self.generate_expression(&f.replacement)?;
17385 self.write_space();
17386 self.write_keyword("FROM");
17387 self.write_space();
17388 self.generate_expression(&f.from)?;
17389 if let Some(length) = &f.length {
17390 self.write_space();
17391 self.write_keyword("FOR");
17392 self.write_space();
17393 self.generate_expression(length)?;
17394 }
17395 self.write(")");
17396 Ok(())
17397 }
17398
17399 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
17400 if f.position_explicit && f.characters.is_none() {
17403 match f.position {
17404 TrimPosition::Leading => {
17405 self.write_keyword("LTRIM");
17406 self.write("(");
17407 self.generate_expression(&f.this)?;
17408 self.write(")");
17409 return Ok(());
17410 }
17411 TrimPosition::Trailing => {
17412 self.write_keyword("RTRIM");
17413 self.write("(");
17414 self.generate_expression(&f.this)?;
17415 self.write(")");
17416 return Ok(());
17417 }
17418 TrimPosition::Both => {
17419 }
17422 }
17423 }
17424
17425 self.write_keyword("TRIM");
17426 self.write("(");
17427 let force_standard = f.characters.is_some()
17430 && !f.sql_standard_syntax
17431 && matches!(
17432 self.config.dialect,
17433 Some(DialectType::Hive)
17434 | Some(DialectType::Spark)
17435 | Some(DialectType::Databricks)
17436 | Some(DialectType::ClickHouse)
17437 );
17438 let use_standard = (f.sql_standard_syntax || force_standard)
17439 && !(f.position_explicit
17440 && f.characters.is_none()
17441 && matches!(f.position, TrimPosition::Both));
17442 if use_standard {
17443 if f.position_explicit {
17446 match f.position {
17447 TrimPosition::Both => self.write_keyword("BOTH"),
17448 TrimPosition::Leading => self.write_keyword("LEADING"),
17449 TrimPosition::Trailing => self.write_keyword("TRAILING"),
17450 }
17451 self.write_space();
17452 }
17453 if let Some(chars) = &f.characters {
17454 self.generate_expression(chars)?;
17455 self.write_space();
17456 }
17457 self.write_keyword("FROM");
17458 self.write_space();
17459 self.generate_expression(&f.this)?;
17460 } else {
17461 self.generate_expression(&f.this)?;
17463 if let Some(chars) = &f.characters {
17464 self.write(", ");
17465 self.generate_expression(chars)?;
17466 }
17467 }
17468 self.write(")");
17469 Ok(())
17470 }
17471
17472 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
17473 self.write_keyword("REPLACE");
17474 self.write("(");
17475 self.generate_expression(&f.this)?;
17476 self.write(", ");
17477 self.generate_expression(&f.old)?;
17478 self.write(", ");
17479 self.generate_expression(&f.new)?;
17480 self.write(")");
17481 Ok(())
17482 }
17483
17484 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
17485 self.write_keyword(name);
17486 self.write("(");
17487 self.generate_expression(&f.this)?;
17488 self.write(", ");
17489 self.generate_expression(&f.length)?;
17490 self.write(")");
17491 Ok(())
17492 }
17493
17494 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
17495 self.write_keyword("REPEAT");
17496 self.write("(");
17497 self.generate_expression(&f.this)?;
17498 self.write(", ");
17499 self.generate_expression(&f.times)?;
17500 self.write(")");
17501 Ok(())
17502 }
17503
17504 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
17505 self.write_keyword(name);
17506 self.write("(");
17507 self.generate_expression(&f.this)?;
17508 self.write(", ");
17509 self.generate_expression(&f.length)?;
17510 if let Some(fill) = &f.fill {
17511 self.write(", ");
17512 self.generate_expression(fill)?;
17513 }
17514 self.write(")");
17515 Ok(())
17516 }
17517
17518 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
17519 self.write_keyword("SPLIT");
17520 self.write("(");
17521 self.generate_expression(&f.this)?;
17522 self.write(", ");
17523 self.generate_expression(&f.delimiter)?;
17524 self.write(")");
17525 Ok(())
17526 }
17527
17528 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
17529 use crate::dialects::DialectType;
17530 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
17532 self.generate_expression(&f.this)?;
17533 self.write(" ~ ");
17534 self.generate_expression(&f.pattern)?;
17535 } else if matches!(
17536 self.config.dialect,
17537 Some(DialectType::SingleStore)
17538 | Some(DialectType::Spark)
17539 | Some(DialectType::Hive)
17540 | Some(DialectType::Databricks)
17541 ) && f.flags.is_none()
17542 {
17543 self.generate_expression(&f.this)?;
17545 self.write_keyword(" RLIKE ");
17546 self.generate_expression(&f.pattern)?;
17547 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
17548 self.write_keyword("REGEXP");
17550 self.write("(");
17551 self.generate_expression(&f.this)?;
17552 self.write(", ");
17553 self.generate_expression(&f.pattern)?;
17554 if let Some(flags) = &f.flags {
17555 self.write(", ");
17556 self.generate_expression(flags)?;
17557 }
17558 self.write(")");
17559 } else {
17560 self.write_keyword("REGEXP_LIKE");
17561 self.write("(");
17562 self.generate_expression(&f.this)?;
17563 self.write(", ");
17564 self.generate_expression(&f.pattern)?;
17565 if let Some(flags) = &f.flags {
17566 self.write(", ");
17567 self.generate_expression(flags)?;
17568 }
17569 self.write(")");
17570 }
17571 Ok(())
17572 }
17573
17574 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
17575 self.write_keyword("REGEXP_REPLACE");
17576 self.write("(");
17577 self.generate_expression(&f.this)?;
17578 self.write(", ");
17579 self.generate_expression(&f.pattern)?;
17580 self.write(", ");
17581 self.generate_expression(&f.replacement)?;
17582 if let Some(flags) = &f.flags {
17583 self.write(", ");
17584 self.generate_expression(flags)?;
17585 }
17586 self.write(")");
17587 Ok(())
17588 }
17589
17590 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
17591 self.write_keyword("REGEXP_EXTRACT");
17592 self.write("(");
17593 self.generate_expression(&f.this)?;
17594 self.write(", ");
17595 self.generate_expression(&f.pattern)?;
17596 if let Some(group) = &f.group {
17597 self.write(", ");
17598 self.generate_expression(group)?;
17599 }
17600 self.write(")");
17601 Ok(())
17602 }
17603
17604 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
17607 self.write_keyword("ROUND");
17608 self.write("(");
17609 self.generate_expression(&f.this)?;
17610 if let Some(decimals) = &f.decimals {
17611 self.write(", ");
17612 self.generate_expression(decimals)?;
17613 }
17614 self.write(")");
17615 Ok(())
17616 }
17617
17618 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
17619 self.write_keyword("FLOOR");
17620 self.write("(");
17621 self.generate_expression(&f.this)?;
17622 if let Some(to) = &f.to {
17624 self.write(" ");
17625 self.write_keyword("TO");
17626 self.write(" ");
17627 self.generate_expression(to)?;
17628 } else if let Some(scale) = &f.scale {
17629 self.write(", ");
17630 self.generate_expression(scale)?;
17631 }
17632 self.write(")");
17633 Ok(())
17634 }
17635
17636 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
17637 self.write_keyword("CEIL");
17638 self.write("(");
17639 self.generate_expression(&f.this)?;
17640 if let Some(to) = &f.to {
17642 self.write(" ");
17643 self.write_keyword("TO");
17644 self.write(" ");
17645 self.generate_expression(to)?;
17646 } else 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_log(&mut self, f: &LogFunc) -> Result<()> {
17655 use crate::expressions::Literal;
17656
17657 if let Some(base) = &f.base {
17658 if self.is_log_base_none() {
17661 if matches!(base, Expression::Literal(Literal::Number(s)) if s == "2") {
17662 self.write_func_name("LOG2");
17663 self.write("(");
17664 self.generate_expression(&f.this)?;
17665 self.write(")");
17666 return Ok(());
17667 } else if matches!(base, Expression::Literal(Literal::Number(s)) if s == "10") {
17668 self.write_func_name("LOG10");
17669 self.write("(");
17670 self.generate_expression(&f.this)?;
17671 self.write(")");
17672 return Ok(());
17673 }
17674 }
17676
17677 self.write_func_name("LOG");
17678 self.write("(");
17679 if self.is_log_value_first() {
17680 self.generate_expression(&f.this)?;
17682 self.write(", ");
17683 self.generate_expression(base)?;
17684 } else {
17685 self.generate_expression(base)?;
17687 self.write(", ");
17688 self.generate_expression(&f.this)?;
17689 }
17690 self.write(")");
17691 } else {
17692 self.write_func_name("LOG");
17694 self.write("(");
17695 self.generate_expression(&f.this)?;
17696 self.write(")");
17697 }
17698 Ok(())
17699 }
17700
17701 fn is_log_value_first(&self) -> bool {
17704 use crate::dialects::DialectType;
17705 matches!(
17706 self.config.dialect,
17707 Some(DialectType::BigQuery)
17708 | Some(DialectType::TSQL)
17709 | Some(DialectType::Tableau)
17710 | Some(DialectType::Fabric)
17711 )
17712 }
17713
17714 fn is_log_base_none(&self) -> bool {
17717 use crate::dialects::DialectType;
17718 matches!(
17719 self.config.dialect,
17720 Some(DialectType::Presto)
17721 | Some(DialectType::Trino)
17722 | Some(DialectType::ClickHouse)
17723 | Some(DialectType::Athena)
17724 )
17725 }
17726
17727 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
17730 self.write_keyword("CURRENT_TIME");
17731 if let Some(precision) = f.precision {
17732 self.write(&format!("({})", precision));
17733 }
17734 Ok(())
17735 }
17736
17737 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
17738 use crate::dialects::DialectType;
17739
17740 if f.sysdate {
17742 match self.config.dialect {
17743 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
17744 self.write_keyword("SYSDATE");
17745 return Ok(());
17746 }
17747 Some(DialectType::Snowflake) => {
17748 self.write_keyword("SYSDATE");
17750 self.write("()");
17751 return Ok(());
17752 }
17753 _ => {
17754 }
17756 }
17757 }
17758
17759 self.write_keyword("CURRENT_TIMESTAMP");
17760 if let Some(precision) = f.precision {
17762 self.write(&format!("({})", precision));
17763 } else if matches!(
17764 self.config.dialect,
17765 Some(crate::dialects::DialectType::MySQL)
17766 | Some(crate::dialects::DialectType::SingleStore)
17767 | Some(crate::dialects::DialectType::TiDB)
17768 | Some(crate::dialects::DialectType::Spark)
17769 | Some(crate::dialects::DialectType::Hive)
17770 | Some(crate::dialects::DialectType::Databricks)
17771 | Some(crate::dialects::DialectType::ClickHouse)
17772 | Some(crate::dialects::DialectType::BigQuery)
17773 | Some(crate::dialects::DialectType::Snowflake)
17774 ) {
17775 self.write("()");
17776 }
17777 Ok(())
17778 }
17779
17780 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
17781 if self.config.dialect == Some(DialectType::Exasol) {
17783 self.write_keyword("CONVERT_TZ");
17784 self.write("(");
17785 self.generate_expression(&f.this)?;
17786 self.write(", 'UTC', ");
17787 self.generate_expression(&f.zone)?;
17788 self.write(")");
17789 return Ok(());
17790 }
17791
17792 self.generate_expression(&f.this)?;
17793 self.write_space();
17794 self.write_keyword("AT TIME ZONE");
17795 self.write_space();
17796 self.generate_expression(&f.zone)?;
17797 Ok(())
17798 }
17799
17800 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
17801 use crate::dialects::DialectType;
17802
17803 let is_presto_like = matches!(
17806 self.config.dialect,
17807 Some(DialectType::Presto) | Some(DialectType::Trino)
17808 );
17809
17810 if is_presto_like {
17811 self.write_keyword(name);
17812 self.write("(");
17813 self.write("'");
17815 self.write_simple_interval_unit(&f.unit, false);
17816 self.write("'");
17817 self.write(", ");
17818 let needs_cast = !self.returns_integer_type(&f.interval);
17820 if needs_cast {
17821 self.write_keyword("CAST");
17822 self.write("(");
17823 }
17824 self.generate_expression(&f.interval)?;
17825 if needs_cast {
17826 self.write_space();
17827 self.write_keyword("AS");
17828 self.write_space();
17829 self.write_keyword("BIGINT");
17830 self.write(")");
17831 }
17832 self.write(", ");
17833 self.generate_expression(&f.this)?;
17834 self.write(")");
17835 } else {
17836 self.write_keyword(name);
17837 self.write("(");
17838 self.generate_expression(&f.this)?;
17839 self.write(", ");
17840 self.write_keyword("INTERVAL");
17841 self.write_space();
17842 self.generate_expression(&f.interval)?;
17843 self.write_space();
17844 self.write_simple_interval_unit(&f.unit, false); self.write(")");
17846 }
17847 Ok(())
17848 }
17849
17850 fn returns_integer_type(&self, expr: &Expression) -> bool {
17853 use crate::expressions::{DataType, Literal};
17854 match expr {
17855 Expression::Literal(Literal::Number(n)) => !n.contains('.'),
17857
17858 Expression::Floor(f) => self.returns_integer_type(&f.this),
17860
17861 Expression::Round(f) => {
17863 f.decimals.is_none() && self.returns_integer_type(&f.this)
17865 }
17866
17867 Expression::Sign(f) => self.returns_integer_type(&f.this),
17869
17870 Expression::Abs(f) => self.returns_integer_type(&f.this),
17872
17873 Expression::Mul(op) => {
17875 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17876 }
17877 Expression::Add(op) => {
17878 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17879 }
17880 Expression::Sub(op) => {
17881 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
17882 }
17883 Expression::Mod(op) => self.returns_integer_type(&op.left),
17884
17885 Expression::Cast(c) => matches!(
17887 &c.to,
17888 DataType::BigInt { .. }
17889 | DataType::Int { .. }
17890 | DataType::SmallInt { .. }
17891 | DataType::TinyInt { .. }
17892 ),
17893
17894 Expression::Neg(op) => self.returns_integer_type(&op.this),
17896
17897 Expression::Paren(p) => self.returns_integer_type(&p.this),
17899
17900 _ => false,
17903 }
17904 }
17905
17906 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
17907 self.write_keyword("DATEDIFF");
17908 self.write("(");
17909 if let Some(unit) = &f.unit {
17910 self.write_simple_interval_unit(unit, false); self.write(", ");
17912 }
17913 self.generate_expression(&f.this)?;
17914 self.write(", ");
17915 self.generate_expression(&f.expression)?;
17916 self.write(")");
17917 Ok(())
17918 }
17919
17920 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
17921 self.write_keyword("DATE_TRUNC");
17922 self.write("('");
17923 self.write_datetime_field(&f.unit);
17924 self.write("', ");
17925 self.generate_expression(&f.this)?;
17926 self.write(")");
17927 Ok(())
17928 }
17929
17930 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
17931 use crate::dialects::DialectType;
17932 use crate::expressions::DateTimeField;
17933
17934 self.write_keyword("LAST_DAY");
17935 self.write("(");
17936 self.generate_expression(&f.this)?;
17937 if let Some(unit) = &f.unit {
17938 self.write(", ");
17939 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
17942 if let DateTimeField::WeekWithModifier(_) = unit {
17943 self.write_keyword("WEEK");
17944 } else {
17945 self.write_datetime_field(unit);
17946 }
17947 } else {
17948 self.write_datetime_field(unit);
17949 }
17950 }
17951 self.write(")");
17952 Ok(())
17953 }
17954
17955 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
17956 if matches!(
17958 self.config.dialect,
17959 Some(DialectType::TSQL) | Some(DialectType::Fabric)
17960 ) {
17961 self.write_keyword("DATEPART");
17962 self.write("(");
17963 self.write_datetime_field(&f.field);
17964 self.write(", ");
17965 self.generate_expression(&f.this)?;
17966 self.write(")");
17967 return Ok(());
17968 }
17969 self.write_keyword("EXTRACT");
17970 self.write("(");
17971 if matches!(
17973 self.config.dialect,
17974 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
17975 ) {
17976 self.write_datetime_field_lower(&f.field);
17977 } else {
17978 self.write_datetime_field(&f.field);
17979 }
17980 self.write_space();
17981 self.write_keyword("FROM");
17982 self.write_space();
17983 self.generate_expression(&f.this)?;
17984 self.write(")");
17985 Ok(())
17986 }
17987
17988 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
17989 self.write_keyword("TO_DATE");
17990 self.write("(");
17991 self.generate_expression(&f.this)?;
17992 if let Some(format) = &f.format {
17993 self.write(", ");
17994 self.generate_expression(format)?;
17995 }
17996 self.write(")");
17997 Ok(())
17998 }
17999
18000 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
18001 self.write_keyword("TO_TIMESTAMP");
18002 self.write("(");
18003 self.generate_expression(&f.this)?;
18004 if let Some(format) = &f.format {
18005 self.write(", ");
18006 self.generate_expression(format)?;
18007 }
18008 self.write(")");
18009 Ok(())
18010 }
18011
18012 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
18015 use crate::dialects::DialectType;
18016
18017 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
18019 self.write_keyword("CASE WHEN");
18020 self.write_space();
18021 self.generate_expression(&f.condition)?;
18022 self.write_space();
18023 self.write_keyword("THEN");
18024 self.write_space();
18025 self.generate_expression(&f.true_value)?;
18026 if let Some(false_val) = &f.false_value {
18027 self.write_space();
18028 self.write_keyword("ELSE");
18029 self.write_space();
18030 self.generate_expression(false_val)?;
18031 }
18032 self.write_space();
18033 self.write_keyword("END");
18034 return Ok(());
18035 }
18036
18037 if self.config.dialect == Some(DialectType::Exasol) {
18039 self.write_keyword("IF");
18040 self.write_space();
18041 self.generate_expression(&f.condition)?;
18042 self.write_space();
18043 self.write_keyword("THEN");
18044 self.write_space();
18045 self.generate_expression(&f.true_value)?;
18046 if let Some(false_val) = &f.false_value {
18047 self.write_space();
18048 self.write_keyword("ELSE");
18049 self.write_space();
18050 self.generate_expression(false_val)?;
18051 }
18052 self.write_space();
18053 self.write_keyword("ENDIF");
18054 return Ok(());
18055 }
18056
18057 let func_name = match self.config.dialect {
18059 Some(DialectType::Snowflake) => "IFF",
18060 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
18061 Some(DialectType::Drill) => "`IF`",
18062 _ => "IF",
18063 };
18064 self.write(func_name);
18065 self.write("(");
18066 self.generate_expression(&f.condition)?;
18067 self.write(", ");
18068 self.generate_expression(&f.true_value)?;
18069 if let Some(false_val) = &f.false_value {
18070 self.write(", ");
18071 self.generate_expression(false_val)?;
18072 }
18073 self.write(")");
18074 Ok(())
18075 }
18076
18077 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
18078 self.write_keyword("NVL2");
18079 self.write("(");
18080 self.generate_expression(&f.this)?;
18081 self.write(", ");
18082 self.generate_expression(&f.true_value)?;
18083 self.write(", ");
18084 self.generate_expression(&f.false_value)?;
18085 self.write(")");
18086 Ok(())
18087 }
18088
18089 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
18092 let count_name = match self.config.normalize_functions {
18094 NormalizeFunctions::Upper => "COUNT".to_string(),
18095 NormalizeFunctions::Lower => "count".to_string(),
18096 NormalizeFunctions::None => f
18097 .original_name
18098 .clone()
18099 .unwrap_or_else(|| "COUNT".to_string()),
18100 };
18101 self.write(&count_name);
18102 self.write("(");
18103 if f.distinct {
18104 self.write_keyword("DISTINCT");
18105 self.write_space();
18106 }
18107 if f.star {
18108 self.write("*");
18109 } else if let Some(ref expr) = f.this {
18110 if let Expression::Tuple(tuple) = expr {
18112 let needs_transform =
18116 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
18117
18118 if needs_transform {
18119 self.write_keyword("CASE");
18121 for e in &tuple.expressions {
18122 self.write_space();
18123 self.write_keyword("WHEN");
18124 self.write_space();
18125 self.generate_expression(e)?;
18126 self.write_space();
18127 self.write_keyword("IS NULL THEN NULL");
18128 }
18129 self.write_space();
18130 self.write_keyword("ELSE");
18131 self.write(" (");
18132 for (i, e) in tuple.expressions.iter().enumerate() {
18133 if i > 0 {
18134 self.write(", ");
18135 }
18136 self.generate_expression(e)?;
18137 }
18138 self.write(")");
18139 self.write_space();
18140 self.write_keyword("END");
18141 } else {
18142 for (i, e) in tuple.expressions.iter().enumerate() {
18143 if i > 0 {
18144 self.write(", ");
18145 }
18146 self.generate_expression(e)?;
18147 }
18148 }
18149 } else {
18150 self.generate_expression(expr)?;
18151 }
18152 }
18153 if let Some(ignore) = f.ignore_nulls {
18155 self.write_space();
18156 if ignore {
18157 self.write_keyword("IGNORE NULLS");
18158 } else {
18159 self.write_keyword("RESPECT NULLS");
18160 }
18161 }
18162 self.write(")");
18163 if let Some(ref filter) = f.filter {
18164 self.write_space();
18165 self.write_keyword("FILTER");
18166 self.write("(");
18167 self.write_keyword("WHERE");
18168 self.write_space();
18169 self.generate_expression(filter)?;
18170 self.write(")");
18171 }
18172 Ok(())
18173 }
18174
18175 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
18176 let func_name = match self.config.normalize_functions {
18178 NormalizeFunctions::Upper => name.to_uppercase(),
18179 NormalizeFunctions::Lower => name.to_lowercase(),
18180 NormalizeFunctions::None => {
18181 if let Some(ref original) = f.name {
18184 original.clone()
18185 } else {
18186 name.to_lowercase()
18187 }
18188 }
18189 };
18190 self.write(&func_name);
18191 self.write("(");
18192 if f.distinct {
18193 self.write_keyword("DISTINCT");
18194 self.write_space();
18195 }
18196 if !matches!(f.this, Expression::Null(_)) {
18198 self.generate_expression(&f.this)?;
18199 }
18200 if self.config.ignore_nulls_in_func
18203 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18204 {
18205 match f.ignore_nulls {
18206 Some(true) => {
18207 self.write_space();
18208 self.write_keyword("IGNORE NULLS");
18209 }
18210 Some(false) => {
18211 self.write_space();
18212 self.write_keyword("RESPECT NULLS");
18213 }
18214 None => {}
18215 }
18216 }
18217 if let Some((ref expr, is_max)) = f.having_max {
18220 self.write_space();
18221 self.write_keyword("HAVING");
18222 self.write_space();
18223 if is_max {
18224 self.write_keyword("MAX");
18225 } else {
18226 self.write_keyword("MIN");
18227 }
18228 self.write_space();
18229 self.generate_expression(expr)?;
18230 }
18231 if !f.order_by.is_empty() {
18233 self.write_space();
18234 self.write_keyword("ORDER BY");
18235 self.write_space();
18236 for (i, ord) in f.order_by.iter().enumerate() {
18237 if i > 0 {
18238 self.write(", ");
18239 }
18240 self.generate_ordered(ord)?;
18241 }
18242 }
18243 if let Some(ref limit) = f.limit {
18245 self.write_space();
18246 self.write_keyword("LIMIT");
18247 self.write_space();
18248 if let Expression::Tuple(t) = limit.as_ref() {
18250 if t.expressions.len() == 2 {
18251 self.generate_expression(&t.expressions[0])?;
18252 self.write(", ");
18253 self.generate_expression(&t.expressions[1])?;
18254 } else {
18255 self.generate_expression(limit)?;
18256 }
18257 } else {
18258 self.generate_expression(limit)?;
18259 }
18260 }
18261 self.write(")");
18262 if !self.config.ignore_nulls_in_func
18265 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18266 {
18267 match f.ignore_nulls {
18268 Some(true) => {
18269 self.write_space();
18270 self.write_keyword("IGNORE NULLS");
18271 }
18272 Some(false) => {
18273 self.write_space();
18274 self.write_keyword("RESPECT NULLS");
18275 }
18276 None => {}
18277 }
18278 }
18279 if let Some(ref filter) = f.filter {
18280 self.write_space();
18281 self.write_keyword("FILTER");
18282 self.write("(");
18283 self.write_keyword("WHERE");
18284 self.write_space();
18285 self.generate_expression(filter)?;
18286 self.write(")");
18287 }
18288 Ok(())
18289 }
18290
18291 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
18292 self.write_keyword("GROUP_CONCAT");
18293 self.write("(");
18294 if f.distinct {
18295 self.write_keyword("DISTINCT");
18296 self.write_space();
18297 }
18298 self.generate_expression(&f.this)?;
18299 if let Some(ref order_by) = f.order_by {
18300 self.write_space();
18301 self.write_keyword("ORDER BY");
18302 self.write_space();
18303 for (i, ord) in order_by.iter().enumerate() {
18304 if i > 0 {
18305 self.write(", ");
18306 }
18307 self.generate_ordered(ord)?;
18308 }
18309 }
18310 if let Some(ref sep) = f.separator {
18311 if matches!(
18314 self.config.dialect,
18315 Some(crate::dialects::DialectType::SQLite)
18316 ) {
18317 self.write(", ");
18318 self.generate_expression(sep)?;
18319 } else {
18320 self.write_space();
18321 self.write_keyword("SEPARATOR");
18322 self.write_space();
18323 self.generate_expression(sep)?;
18324 }
18325 }
18326 self.write(")");
18327 if let Some(ref filter) = f.filter {
18328 self.write_space();
18329 self.write_keyword("FILTER");
18330 self.write("(");
18331 self.write_keyword("WHERE");
18332 self.write_space();
18333 self.generate_expression(filter)?;
18334 self.write(")");
18335 }
18336 Ok(())
18337 }
18338
18339 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
18340 let is_tsql = matches!(
18341 self.config.dialect,
18342 Some(crate::dialects::DialectType::TSQL)
18343 );
18344 self.write_keyword("STRING_AGG");
18345 self.write("(");
18346 if f.distinct {
18347 self.write_keyword("DISTINCT");
18348 self.write_space();
18349 }
18350 self.generate_expression(&f.this)?;
18351 if let Some(ref separator) = f.separator {
18352 self.write(", ");
18353 self.generate_expression(separator)?;
18354 }
18355 if !is_tsql {
18357 if let Some(ref order_by) = f.order_by {
18358 self.write_space();
18359 self.write_keyword("ORDER BY");
18360 self.write_space();
18361 for (i, ord) in order_by.iter().enumerate() {
18362 if i > 0 {
18363 self.write(", ");
18364 }
18365 self.generate_ordered(ord)?;
18366 }
18367 }
18368 }
18369 if let Some(ref limit) = f.limit {
18370 self.write_space();
18371 self.write_keyword("LIMIT");
18372 self.write_space();
18373 self.generate_expression(limit)?;
18374 }
18375 self.write(")");
18376 if is_tsql {
18378 if let Some(ref order_by) = f.order_by {
18379 self.write_space();
18380 self.write_keyword("WITHIN GROUP");
18381 self.write(" (");
18382 self.write_keyword("ORDER BY");
18383 self.write_space();
18384 for (i, ord) in order_by.iter().enumerate() {
18385 if i > 0 {
18386 self.write(", ");
18387 }
18388 self.generate_ordered(ord)?;
18389 }
18390 self.write(")");
18391 }
18392 }
18393 if let Some(ref filter) = f.filter {
18394 self.write_space();
18395 self.write_keyword("FILTER");
18396 self.write("(");
18397 self.write_keyword("WHERE");
18398 self.write_space();
18399 self.generate_expression(filter)?;
18400 self.write(")");
18401 }
18402 Ok(())
18403 }
18404
18405 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
18406 use crate::dialects::DialectType;
18407 self.write_keyword("LISTAGG");
18408 self.write("(");
18409 if f.distinct {
18410 self.write_keyword("DISTINCT");
18411 self.write_space();
18412 }
18413 self.generate_expression(&f.this)?;
18414 if let Some(ref sep) = f.separator {
18415 self.write(", ");
18416 self.generate_expression(sep)?;
18417 } else if matches!(
18418 self.config.dialect,
18419 Some(DialectType::Trino) | Some(DialectType::Presto)
18420 ) {
18421 self.write(", ','");
18423 }
18424 if let Some(ref overflow) = f.on_overflow {
18425 self.write_space();
18426 self.write_keyword("ON OVERFLOW");
18427 self.write_space();
18428 match overflow {
18429 ListAggOverflow::Error => self.write_keyword("ERROR"),
18430 ListAggOverflow::Truncate { filler, with_count } => {
18431 self.write_keyword("TRUNCATE");
18432 if let Some(ref fill) = filler {
18433 self.write_space();
18434 self.generate_expression(fill)?;
18435 }
18436 if *with_count {
18437 self.write_space();
18438 self.write_keyword("WITH COUNT");
18439 } else {
18440 self.write_space();
18441 self.write_keyword("WITHOUT COUNT");
18442 }
18443 }
18444 }
18445 }
18446 self.write(")");
18447 if let Some(ref order_by) = f.order_by {
18448 self.write_space();
18449 self.write_keyword("WITHIN GROUP");
18450 self.write(" (");
18451 self.write_keyword("ORDER BY");
18452 self.write_space();
18453 for (i, ord) in order_by.iter().enumerate() {
18454 if i > 0 {
18455 self.write(", ");
18456 }
18457 self.generate_ordered(ord)?;
18458 }
18459 self.write(")");
18460 }
18461 if let Some(ref filter) = f.filter {
18462 self.write_space();
18463 self.write_keyword("FILTER");
18464 self.write("(");
18465 self.write_keyword("WHERE");
18466 self.write_space();
18467 self.generate_expression(filter)?;
18468 self.write(")");
18469 }
18470 Ok(())
18471 }
18472
18473 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
18474 self.write_keyword("SUM_IF");
18475 self.write("(");
18476 self.generate_expression(&f.this)?;
18477 self.write(", ");
18478 self.generate_expression(&f.condition)?;
18479 self.write(")");
18480 if let Some(ref filter) = f.filter {
18481 self.write_space();
18482 self.write_keyword("FILTER");
18483 self.write("(");
18484 self.write_keyword("WHERE");
18485 self.write_space();
18486 self.generate_expression(filter)?;
18487 self.write(")");
18488 }
18489 Ok(())
18490 }
18491
18492 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
18493 self.write_keyword("APPROX_PERCENTILE");
18494 self.write("(");
18495 self.generate_expression(&f.this)?;
18496 self.write(", ");
18497 self.generate_expression(&f.percentile)?;
18498 if let Some(ref acc) = f.accuracy {
18499 self.write(", ");
18500 self.generate_expression(acc)?;
18501 }
18502 self.write(")");
18503 if let Some(ref filter) = f.filter {
18504 self.write_space();
18505 self.write_keyword("FILTER");
18506 self.write("(");
18507 self.write_keyword("WHERE");
18508 self.write_space();
18509 self.generate_expression(filter)?;
18510 self.write(")");
18511 }
18512 Ok(())
18513 }
18514
18515 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
18516 self.write_keyword(name);
18517 self.write("(");
18518 self.generate_expression(&f.percentile)?;
18519 self.write(")");
18520 if let Some(ref order_by) = f.order_by {
18521 self.write_space();
18522 self.write_keyword("WITHIN GROUP");
18523 self.write(" (");
18524 self.write_keyword("ORDER BY");
18525 self.write_space();
18526 self.generate_expression(&f.this)?;
18527 for ord in order_by.iter() {
18528 if ord.desc {
18529 self.write_space();
18530 self.write_keyword("DESC");
18531 }
18532 }
18533 self.write(")");
18534 }
18535 if let Some(ref filter) = f.filter {
18536 self.write_space();
18537 self.write_keyword("FILTER");
18538 self.write("(");
18539 self.write_keyword("WHERE");
18540 self.write_space();
18541 self.generate_expression(filter)?;
18542 self.write(")");
18543 }
18544 Ok(())
18545 }
18546
18547 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
18550 self.write_keyword("NTILE");
18551 self.write("(");
18552 if let Some(num_buckets) = &f.num_buckets {
18553 self.generate_expression(num_buckets)?;
18554 }
18555 if let Some(order_by) = &f.order_by {
18556 self.write_keyword(" ORDER BY ");
18557 for (i, ob) in order_by.iter().enumerate() {
18558 if i > 0 {
18559 self.write(", ");
18560 }
18561 self.generate_ordered(ob)?;
18562 }
18563 }
18564 self.write(")");
18565 Ok(())
18566 }
18567
18568 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
18569 self.write_keyword(name);
18570 self.write("(");
18571 self.generate_expression(&f.this)?;
18572 if let Some(ref offset) = f.offset {
18573 self.write(", ");
18574 self.generate_expression(offset)?;
18575 if let Some(ref default) = f.default {
18576 self.write(", ");
18577 self.generate_expression(default)?;
18578 }
18579 }
18580 if f.ignore_nulls && self.config.ignore_nulls_in_func {
18582 self.write_space();
18583 self.write_keyword("IGNORE NULLS");
18584 }
18585 self.write(")");
18586 if f.ignore_nulls && !self.config.ignore_nulls_in_func {
18588 self.write_space();
18589 self.write_keyword("IGNORE NULLS");
18590 }
18591 Ok(())
18592 }
18593
18594 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
18595 self.write_keyword(name);
18596 self.write("(");
18597 self.generate_expression(&f.this)?;
18598 if self.config.ignore_nulls_in_func {
18600 match f.ignore_nulls {
18601 Some(true) => {
18602 self.write_space();
18603 self.write_keyword("IGNORE NULLS");
18604 }
18605 Some(false) => {
18606 self.write_space();
18607 self.write_keyword("RESPECT NULLS");
18608 }
18609 None => {}
18610 }
18611 }
18612 self.write(")");
18613 if !self.config.ignore_nulls_in_func {
18615 match f.ignore_nulls {
18616 Some(true) => {
18617 self.write_space();
18618 self.write_keyword("IGNORE NULLS");
18619 }
18620 Some(false) => {
18621 self.write_space();
18622 self.write_keyword("RESPECT NULLS");
18623 }
18624 None => {}
18625 }
18626 }
18627 Ok(())
18628 }
18629
18630 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
18631 self.write_keyword("NTH_VALUE");
18632 self.write("(");
18633 self.generate_expression(&f.this)?;
18634 self.write(", ");
18635 self.generate_expression(&f.offset)?;
18636 if self.config.ignore_nulls_in_func {
18638 match f.ignore_nulls {
18639 Some(true) => {
18640 self.write_space();
18641 self.write_keyword("IGNORE NULLS");
18642 }
18643 Some(false) => {
18644 self.write_space();
18645 self.write_keyword("RESPECT NULLS");
18646 }
18647 None => {}
18648 }
18649 }
18650 self.write(")");
18651 if matches!(
18653 self.config.dialect,
18654 Some(crate::dialects::DialectType::Snowflake)
18655 ) {
18656 match f.from_first {
18657 Some(true) => {
18658 self.write_space();
18659 self.write_keyword("FROM FIRST");
18660 }
18661 Some(false) => {
18662 self.write_space();
18663 self.write_keyword("FROM LAST");
18664 }
18665 None => {}
18666 }
18667 }
18668 if !self.config.ignore_nulls_in_func {
18670 match f.ignore_nulls {
18671 Some(true) => {
18672 self.write_space();
18673 self.write_keyword("IGNORE NULLS");
18674 }
18675 Some(false) => {
18676 self.write_space();
18677 self.write_keyword("RESPECT NULLS");
18678 }
18679 None => {}
18680 }
18681 }
18682 Ok(())
18683 }
18684
18685 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
18688 if matches!(
18691 self.config.dialect,
18692 Some(crate::dialects::DialectType::ClickHouse)
18693 ) {
18694 self.write_keyword("POSITION");
18695 self.write("(");
18696 self.generate_expression(&f.string)?;
18697 self.write(", ");
18698 self.generate_expression(&f.substring)?;
18699 if let Some(ref start) = f.start {
18700 self.write(", ");
18701 self.generate_expression(start)?;
18702 }
18703 self.write(")");
18704 return Ok(());
18705 }
18706
18707 self.write_keyword("POSITION");
18708 self.write("(");
18709 self.generate_expression(&f.substring)?;
18710 self.write_space();
18711 self.write_keyword("IN");
18712 self.write_space();
18713 self.generate_expression(&f.string)?;
18714 if let Some(ref start) = f.start {
18715 self.write(", ");
18716 self.generate_expression(start)?;
18717 }
18718 self.write(")");
18719 Ok(())
18720 }
18721
18722 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
18725 if f.lower.is_some() || f.upper.is_some() {
18727 self.write_keyword("RANDOM");
18728 self.write("(");
18729 if let Some(ref lower) = f.lower {
18730 self.generate_expression(lower)?;
18731 }
18732 if let Some(ref upper) = f.upper {
18733 self.write(", ");
18734 self.generate_expression(upper)?;
18735 }
18736 self.write(")");
18737 return Ok(());
18738 }
18739 let func_name = match self.config.dialect {
18741 Some(crate::dialects::DialectType::Snowflake)
18742 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
18743 _ => "RAND",
18744 };
18745 self.write_keyword(func_name);
18746 self.write("(");
18747 if !matches!(
18749 self.config.dialect,
18750 Some(crate::dialects::DialectType::DuckDB)
18751 ) {
18752 if let Some(ref seed) = f.seed {
18753 self.generate_expression(seed)?;
18754 }
18755 }
18756 self.write(")");
18757 Ok(())
18758 }
18759
18760 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
18761 self.write_keyword("TRUNCATE");
18762 self.write("(");
18763 self.generate_expression(&f.this)?;
18764 if let Some(ref decimals) = f.decimals {
18765 self.write(", ");
18766 self.generate_expression(decimals)?;
18767 }
18768 self.write(")");
18769 Ok(())
18770 }
18771
18772 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
18775 self.write_keyword("DECODE");
18776 self.write("(");
18777 self.generate_expression(&f.this)?;
18778 for (search, result) in &f.search_results {
18779 self.write(", ");
18780 self.generate_expression(search)?;
18781 self.write(", ");
18782 self.generate_expression(result)?;
18783 }
18784 if let Some(ref default) = f.default {
18785 self.write(", ");
18786 self.generate_expression(default)?;
18787 }
18788 self.write(")");
18789 Ok(())
18790 }
18791
18792 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
18795 self.write_keyword(name);
18796 self.write("(");
18797 self.generate_expression(&f.this)?;
18798 self.write(", ");
18799 self.generate_expression(&f.format)?;
18800 self.write(")");
18801 Ok(())
18802 }
18803
18804 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
18805 self.write_keyword("FROM_UNIXTIME");
18806 self.write("(");
18807 self.generate_expression(&f.this)?;
18808 if let Some(ref format) = f.format {
18809 self.write(", ");
18810 self.generate_expression(format)?;
18811 }
18812 self.write(")");
18813 Ok(())
18814 }
18815
18816 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
18817 self.write_keyword("UNIX_TIMESTAMP");
18818 self.write("(");
18819 if let Some(ref expr) = f.this {
18820 self.generate_expression(expr)?;
18821 if let Some(ref format) = f.format {
18822 self.write(", ");
18823 self.generate_expression(format)?;
18824 }
18825 } else if matches!(
18826 self.config.dialect,
18827 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
18828 ) {
18829 self.write_keyword("CURRENT_TIMESTAMP");
18831 self.write("()");
18832 }
18833 self.write(")");
18834 Ok(())
18835 }
18836
18837 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
18838 self.write_keyword("MAKE_DATE");
18839 self.write("(");
18840 self.generate_expression(&f.year)?;
18841 self.write(", ");
18842 self.generate_expression(&f.month)?;
18843 self.write(", ");
18844 self.generate_expression(&f.day)?;
18845 self.write(")");
18846 Ok(())
18847 }
18848
18849 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
18850 self.write_keyword("MAKE_TIMESTAMP");
18851 self.write("(");
18852 self.generate_expression(&f.year)?;
18853 self.write(", ");
18854 self.generate_expression(&f.month)?;
18855 self.write(", ");
18856 self.generate_expression(&f.day)?;
18857 self.write(", ");
18858 self.generate_expression(&f.hour)?;
18859 self.write(", ");
18860 self.generate_expression(&f.minute)?;
18861 self.write(", ");
18862 self.generate_expression(&f.second)?;
18863 if let Some(ref tz) = f.timezone {
18864 self.write(", ");
18865 self.generate_expression(tz)?;
18866 }
18867 self.write(")");
18868 Ok(())
18869 }
18870
18871 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
18873 match expr {
18874 Expression::Struct(s) => {
18875 if s.fields.iter().all(|(name, _)| name.is_some()) {
18876 Some(
18877 s.fields
18878 .iter()
18879 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
18880 .collect(),
18881 )
18882 } else {
18883 None
18884 }
18885 }
18886 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
18887 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
18889 Some(
18890 f.args
18891 .iter()
18892 .filter_map(|a| {
18893 if let Expression::Alias(alias) = a {
18894 Some(alias.alias.name.clone())
18895 } else {
18896 None
18897 }
18898 })
18899 .collect(),
18900 )
18901 } else {
18902 None
18903 }
18904 }
18905 _ => None,
18906 }
18907 }
18908
18909 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
18911 match expr {
18912 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
18913 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
18914 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
18915 }
18916 _ => false,
18917 }
18918 }
18919
18920 fn struct_field_count(expr: &Expression) -> usize {
18922 match expr {
18923 Expression::Struct(s) => s.fields.len(),
18924 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => f.args.len(),
18925 _ => 0,
18926 }
18927 }
18928
18929 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
18931 match expr {
18932 Expression::Struct(s) => {
18933 let mut new_fields = Vec::with_capacity(s.fields.len());
18934 for (i, (name, value)) in s.fields.iter().enumerate() {
18935 if name.is_none() && i < field_names.len() {
18936 new_fields.push((Some(field_names[i].clone()), value.clone()));
18937 } else {
18938 new_fields.push((name.clone(), value.clone()));
18939 }
18940 }
18941 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
18942 }
18943 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
18944 let mut new_args = Vec::with_capacity(f.args.len());
18945 for (i, arg) in f.args.iter().enumerate() {
18946 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
18947 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
18949 this: arg.clone(),
18950 alias: crate::expressions::Identifier::new(field_names[i].clone()),
18951 column_aliases: Vec::new(),
18952 pre_alias_comments: Vec::new(),
18953 trailing_comments: Vec::new(),
18954 })));
18955 } else {
18956 new_args.push(arg.clone());
18957 }
18958 }
18959 Expression::Function(Box::new(crate::expressions::Function {
18960 name: f.name.clone(),
18961 args: new_args,
18962 distinct: f.distinct,
18963 trailing_comments: f.trailing_comments.clone(),
18964 use_bracket_syntax: f.use_bracket_syntax,
18965 no_parens: f.no_parens,
18966 quoted: f.quoted,
18967 }))
18968 }
18969 _ => expr.clone(),
18970 }
18971 }
18972
18973 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
18977 let first = match expressions.first() {
18978 Some(e) => e,
18979 None => return expressions.to_vec(),
18980 };
18981
18982 let field_names = match Self::extract_struct_field_names(first) {
18983 Some(names) if !names.is_empty() => names,
18984 _ => return expressions.to_vec(),
18985 };
18986
18987 let mut result = Vec::with_capacity(expressions.len());
18988 for (idx, expr) in expressions.iter().enumerate() {
18989 if idx == 0 {
18990 result.push(expr.clone());
18991 continue;
18992 }
18993 if Self::struct_field_count(expr) == field_names.len()
18995 && Self::struct_has_unnamed_fields(expr)
18996 {
18997 result.push(Self::apply_struct_field_names(expr, &field_names));
18998 } else {
18999 result.push(expr.clone());
19000 }
19001 }
19002 result
19003 }
19004
19005 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
19008 let needs_inheritance = matches!(
19011 self.config.dialect,
19012 Some(DialectType::DuckDB)
19013 | Some(DialectType::Spark)
19014 | Some(DialectType::Databricks)
19015 | Some(DialectType::Hive)
19016 | Some(DialectType::Snowflake)
19017 | Some(DialectType::Presto)
19018 | Some(DialectType::Trino)
19019 );
19020 let propagated: Vec<Expression>;
19021 let expressions = if needs_inheritance && f.expressions.len() > 1 {
19022 propagated = Self::inherit_struct_field_names(&f.expressions);
19023 &propagated
19024 } else {
19025 &f.expressions
19026 };
19027
19028 let should_split = if self.config.pretty && !expressions.is_empty() {
19030 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
19031 for expr in expressions {
19032 let mut temp_gen = Generator::with_config(self.config.clone());
19033 temp_gen.config.pretty = false;
19034 temp_gen.generate_expression(expr)?;
19035 expr_strings.push(temp_gen.output);
19036 }
19037 self.too_wide(&expr_strings)
19038 } else {
19039 false
19040 };
19041
19042 if f.bracket_notation {
19043 let (open, close) = match self.config.dialect {
19047 None
19048 | Some(DialectType::Generic)
19049 | Some(DialectType::Spark)
19050 | Some(DialectType::Databricks)
19051 | Some(DialectType::Hive) => {
19052 self.write_keyword("ARRAY");
19053 ("(", ")")
19054 }
19055 Some(DialectType::Presto)
19056 | Some(DialectType::Trino)
19057 | Some(DialectType::PostgreSQL)
19058 | Some(DialectType::Redshift)
19059 | Some(DialectType::Materialize)
19060 | Some(DialectType::RisingWave)
19061 | Some(DialectType::CockroachDB) => {
19062 self.write_keyword("ARRAY");
19063 ("[", "]")
19064 }
19065 _ => ("[", "]"),
19066 };
19067 self.write(open);
19068 if should_split {
19069 self.write_newline();
19070 self.indent_level += 1;
19071 for (i, expr) in expressions.iter().enumerate() {
19072 self.write_indent();
19073 self.generate_expression(expr)?;
19074 if i + 1 < expressions.len() {
19075 self.write(",");
19076 }
19077 self.write_newline();
19078 }
19079 self.indent_level -= 1;
19080 self.write_indent();
19081 } else {
19082 for (i, expr) in expressions.iter().enumerate() {
19083 if i > 0 {
19084 self.write(", ");
19085 }
19086 self.generate_expression(expr)?;
19087 }
19088 }
19089 self.write(close);
19090 } else {
19091 if f.use_list_keyword {
19093 self.write_keyword("LIST");
19094 } else {
19095 self.write_keyword("ARRAY");
19096 }
19097 let has_subquery = expressions
19100 .iter()
19101 .any(|e| matches!(e, Expression::Select(_)));
19102 let (open, close) = if matches!(
19103 self.config.dialect,
19104 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
19105 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
19106 && has_subquery)
19107 {
19108 ("(", ")")
19109 } else {
19110 ("[", "]")
19111 };
19112 self.write(open);
19113 if should_split {
19114 self.write_newline();
19115 self.indent_level += 1;
19116 for (i, expr) in expressions.iter().enumerate() {
19117 self.write_indent();
19118 self.generate_expression(expr)?;
19119 if i + 1 < expressions.len() {
19120 self.write(",");
19121 }
19122 self.write_newline();
19123 }
19124 self.indent_level -= 1;
19125 self.write_indent();
19126 } else {
19127 for (i, expr) in expressions.iter().enumerate() {
19128 if i > 0 {
19129 self.write(", ");
19130 }
19131 self.generate_expression(expr)?;
19132 }
19133 }
19134 self.write(close);
19135 }
19136 Ok(())
19137 }
19138
19139 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
19140 self.write_keyword("ARRAY_SORT");
19141 self.write("(");
19142 self.generate_expression(&f.this)?;
19143 if let Some(ref comp) = f.comparator {
19144 self.write(", ");
19145 self.generate_expression(comp)?;
19146 }
19147 self.write(")");
19148 Ok(())
19149 }
19150
19151 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
19152 self.write_keyword(name);
19153 self.write("(");
19154 self.generate_expression(&f.this)?;
19155 self.write(", ");
19156 self.generate_expression(&f.separator)?;
19157 if let Some(ref null_rep) = f.null_replacement {
19158 self.write(", ");
19159 self.generate_expression(null_rep)?;
19160 }
19161 self.write(")");
19162 Ok(())
19163 }
19164
19165 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
19166 self.write_keyword("UNNEST");
19167 self.write("(");
19168 self.generate_expression(&f.this)?;
19169 for extra in &f.expressions {
19170 self.write(", ");
19171 self.generate_expression(extra)?;
19172 }
19173 self.write(")");
19174 if f.with_ordinality {
19175 self.write_space();
19176 if self.config.unnest_with_ordinality {
19177 self.write_keyword("WITH ORDINALITY");
19179 } else if f.offset_alias.is_some() {
19180 if let Some(ref alias) = f.alias {
19183 self.write_keyword("AS");
19184 self.write_space();
19185 self.generate_identifier(alias)?;
19186 self.write_space();
19187 }
19188 self.write_keyword("WITH OFFSET");
19189 if let Some(ref offset_alias) = f.offset_alias {
19190 self.write_space();
19191 self.write_keyword("AS");
19192 self.write_space();
19193 self.generate_identifier(offset_alias)?;
19194 }
19195 } else {
19196 self.write_keyword("WITH OFFSET");
19198 if f.alias.is_none() {
19199 self.write(" AS offset");
19200 }
19201 }
19202 }
19203 if let Some(ref alias) = f.alias {
19204 let should_add_alias = if !f.with_ordinality {
19206 true
19207 } else if self.config.unnest_with_ordinality {
19208 true
19210 } else if f.offset_alias.is_some() {
19211 false
19213 } else {
19214 true
19216 };
19217 if should_add_alias {
19218 self.write_space();
19219 self.write_keyword("AS");
19220 self.write_space();
19221 self.generate_identifier(alias)?;
19222 }
19223 }
19224 Ok(())
19225 }
19226
19227 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
19228 self.write_keyword("FILTER");
19229 self.write("(");
19230 self.generate_expression(&f.this)?;
19231 self.write(", ");
19232 self.generate_expression(&f.filter)?;
19233 self.write(")");
19234 Ok(())
19235 }
19236
19237 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
19238 self.write_keyword("TRANSFORM");
19239 self.write("(");
19240 self.generate_expression(&f.this)?;
19241 self.write(", ");
19242 self.generate_expression(&f.transform)?;
19243 self.write(")");
19244 Ok(())
19245 }
19246
19247 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
19248 self.write_keyword(name);
19249 self.write("(");
19250 self.generate_expression(&f.start)?;
19251 self.write(", ");
19252 self.generate_expression(&f.stop)?;
19253 if let Some(ref step) = f.step {
19254 self.write(", ");
19255 self.generate_expression(step)?;
19256 }
19257 self.write(")");
19258 Ok(())
19259 }
19260
19261 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
19264 self.write_keyword("STRUCT");
19265 self.write("(");
19266 for (i, (name, expr)) in f.fields.iter().enumerate() {
19267 if i > 0 {
19268 self.write(", ");
19269 }
19270 if let Some(ref id) = name {
19271 self.generate_identifier(id)?;
19272 self.write(" ");
19273 self.write_keyword("AS");
19274 self.write(" ");
19275 }
19276 self.generate_expression(expr)?;
19277 }
19278 self.write(")");
19279 Ok(())
19280 }
19281
19282 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
19284 let mut names: Vec<Option<String>> = Vec::new();
19287 let mut values: Vec<&Expression> = Vec::new();
19288 let mut all_named = true;
19289
19290 for arg in &func.args {
19291 match arg {
19292 Expression::Alias(a) => {
19293 names.push(Some(a.alias.name.clone()));
19294 values.push(&a.this);
19295 }
19296 _ => {
19297 names.push(None);
19298 values.push(arg);
19299 all_named = false;
19300 }
19301 }
19302 }
19303
19304 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
19305 self.write("{");
19307 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19308 if i > 0 {
19309 self.write(", ");
19310 }
19311 if let Some(n) = name {
19312 self.write("'");
19313 self.write(n);
19314 self.write("'");
19315 } else {
19316 self.write("'_");
19317 self.write(&i.to_string());
19318 self.write("'");
19319 }
19320 self.write(": ");
19321 self.generate_expression(value)?;
19322 }
19323 self.write("}");
19324 return Ok(());
19325 }
19326
19327 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
19328 self.write_keyword("OBJECT_CONSTRUCT");
19330 self.write("(");
19331 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19332 if i > 0 {
19333 self.write(", ");
19334 }
19335 if let Some(n) = name {
19336 self.write("'");
19337 self.write(n);
19338 self.write("'");
19339 } else {
19340 self.write("'_");
19341 self.write(&i.to_string());
19342 self.write("'");
19343 }
19344 self.write(", ");
19345 self.generate_expression(value)?;
19346 }
19347 self.write(")");
19348 return Ok(());
19349 }
19350
19351 if matches!(
19352 self.config.dialect,
19353 Some(DialectType::Presto) | Some(DialectType::Trino)
19354 ) {
19355 if all_named && !names.is_empty() {
19356 self.write_keyword("CAST");
19359 self.write("(");
19360 self.write_keyword("ROW");
19361 self.write("(");
19362 for (i, value) in values.iter().enumerate() {
19363 if i > 0 {
19364 self.write(", ");
19365 }
19366 self.generate_expression(value)?;
19367 }
19368 self.write(")");
19369 self.write(" ");
19370 self.write_keyword("AS");
19371 self.write(" ");
19372 self.write_keyword("ROW");
19373 self.write("(");
19374 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
19375 if i > 0 {
19376 self.write(", ");
19377 }
19378 if let Some(n) = name {
19379 self.write(n);
19380 }
19381 self.write(" ");
19382 let type_str = Self::infer_sql_type_for_presto(value);
19383 self.write_keyword(&type_str);
19384 }
19385 self.write(")");
19386 self.write(")");
19387 } else {
19388 self.write_keyword("ROW");
19390 self.write("(");
19391 for (i, value) in values.iter().enumerate() {
19392 if i > 0 {
19393 self.write(", ");
19394 }
19395 self.generate_expression(value)?;
19396 }
19397 self.write(")");
19398 }
19399 return Ok(());
19400 }
19401
19402 self.write_keyword("ROW");
19404 self.write("(");
19405 for (i, value) in values.iter().enumerate() {
19406 if i > 0 {
19407 self.write(", ");
19408 }
19409 self.generate_expression(value)?;
19410 }
19411 self.write(")");
19412 Ok(())
19413 }
19414
19415 fn infer_sql_type_for_presto(expr: &Expression) -> String {
19417 match expr {
19418 Expression::Literal(crate::expressions::Literal::String(_)) => "VARCHAR".to_string(),
19419 Expression::Literal(crate::expressions::Literal::Number(n)) => {
19420 if n.contains('.') {
19421 "DOUBLE".to_string()
19422 } else {
19423 "INTEGER".to_string()
19424 }
19425 }
19426 Expression::Boolean(_) => "BOOLEAN".to_string(),
19427 Expression::Literal(crate::expressions::Literal::Date(_)) => "DATE".to_string(),
19428 Expression::Literal(crate::expressions::Literal::Timestamp(_)) => {
19429 "TIMESTAMP".to_string()
19430 }
19431 Expression::Literal(crate::expressions::Literal::Datetime(_)) => {
19432 "TIMESTAMP".to_string()
19433 }
19434 Expression::Array(_) | Expression::ArrayFunc(_) => {
19435 "ARRAY(VARCHAR)".to_string()
19437 }
19438 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
19440 Expression::Function(f) => {
19441 let up = f.name.to_uppercase();
19442 if up == "STRUCT" {
19443 "ROW".to_string()
19444 } else if up == "CURRENT_DATE" {
19445 "DATE".to_string()
19446 } else if up == "CURRENT_TIMESTAMP" || up == "NOW" {
19447 "TIMESTAMP".to_string()
19448 } else {
19449 "VARCHAR".to_string()
19450 }
19451 }
19452 _ => "VARCHAR".to_string(),
19453 }
19454 }
19455
19456 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
19457 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
19459 self.write_keyword("STRUCT_EXTRACT");
19460 self.write("(");
19461 self.generate_expression(&f.this)?;
19462 self.write(", ");
19463 self.write("'");
19465 self.write(&f.field.name);
19466 self.write("'");
19467 self.write(")");
19468 return Ok(());
19469 }
19470 self.generate_expression(&f.this)?;
19471 self.write(".");
19472 self.generate_identifier(&f.field)
19473 }
19474
19475 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
19476 self.write_keyword("NAMED_STRUCT");
19477 self.write("(");
19478 for (i, (name, value)) in f.pairs.iter().enumerate() {
19479 if i > 0 {
19480 self.write(", ");
19481 }
19482 self.generate_expression(name)?;
19483 self.write(", ");
19484 self.generate_expression(value)?;
19485 }
19486 self.write(")");
19487 Ok(())
19488 }
19489
19490 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
19493 if f.curly_brace_syntax {
19494 if f.with_map_keyword {
19496 self.write_keyword("MAP");
19497 self.write(" ");
19498 }
19499 self.write("{");
19500 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
19501 if i > 0 {
19502 self.write(", ");
19503 }
19504 self.generate_expression(key)?;
19505 self.write(": ");
19506 self.generate_expression(val)?;
19507 }
19508 self.write("}");
19509 } else {
19510 self.write_keyword("MAP");
19512 self.write("(");
19513 self.write_keyword("ARRAY");
19514 self.write("[");
19515 for (i, key) in f.keys.iter().enumerate() {
19516 if i > 0 {
19517 self.write(", ");
19518 }
19519 self.generate_expression(key)?;
19520 }
19521 self.write("], ");
19522 self.write_keyword("ARRAY");
19523 self.write("[");
19524 for (i, val) in f.values.iter().enumerate() {
19525 if i > 0 {
19526 self.write(", ");
19527 }
19528 self.generate_expression(val)?;
19529 }
19530 self.write("])");
19531 }
19532 Ok(())
19533 }
19534
19535 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
19536 self.write_keyword(name);
19537 self.write("(");
19538 self.generate_expression(&f.this)?;
19539 self.write(", ");
19540 self.generate_expression(&f.transform)?;
19541 self.write(")");
19542 Ok(())
19543 }
19544
19545 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
19548 use crate::dialects::DialectType;
19549
19550 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
19552
19553 if use_arrow {
19554 self.generate_expression(&f.this)?;
19556 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
19557 self.write(" ->> ");
19558 } else {
19559 self.write(" -> ");
19560 }
19561 self.generate_expression(&f.path)?;
19562 return Ok(());
19563 }
19564
19565 if f.hash_arrow_syntax
19567 && matches!(
19568 self.config.dialect,
19569 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19570 )
19571 {
19572 self.generate_expression(&f.this)?;
19573 self.write(" #>> ");
19574 self.generate_expression(&f.path)?;
19575 return Ok(());
19576 }
19577
19578 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
19581 match name {
19582 "JSON_EXTRACT_SCALAR"
19583 | "JSON_EXTRACT_PATH_TEXT"
19584 | "JSON_EXTRACT"
19585 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
19586 _ => name,
19587 }
19588 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
19589 match name {
19590 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
19591 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
19592 _ => name,
19593 }
19594 } else {
19595 name
19596 };
19597
19598 self.write_keyword(func_name);
19599 self.write("(");
19600 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
19602 if let Expression::Cast(ref cast) = f.this {
19603 if matches!(cast.to, crate::expressions::DataType::Json) {
19604 self.generate_expression(&cast.this)?;
19605 } else {
19606 self.generate_expression(&f.this)?;
19607 }
19608 } else {
19609 self.generate_expression(&f.this)?;
19610 }
19611 } else {
19612 self.generate_expression(&f.this)?;
19613 }
19614 if matches!(
19617 self.config.dialect,
19618 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19619 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
19620 {
19621 if let Expression::Literal(Literal::String(ref s)) = f.path {
19622 let parts = Self::decompose_json_path(s);
19623 for part in &parts {
19624 self.write(", '");
19625 self.write(part);
19626 self.write("'");
19627 }
19628 } else {
19629 self.write(", ");
19630 self.generate_expression(&f.path)?;
19631 }
19632 } else {
19633 self.write(", ");
19634 self.generate_expression(&f.path)?;
19635 }
19636
19637 if let Some(ref wrapper) = f.wrapper_option {
19640 self.write_space();
19641 self.write_keyword(wrapper);
19642 }
19643 if let Some(ref quotes) = f.quotes_option {
19644 self.write_space();
19645 self.write_keyword(quotes);
19646 if f.on_scalar_string {
19647 self.write_space();
19648 self.write_keyword("ON SCALAR STRING");
19649 }
19650 }
19651 if let Some(ref on_err) = f.on_error {
19652 self.write_space();
19653 self.write_keyword(on_err);
19654 }
19655 if let Some(ref ret_type) = f.returning {
19656 self.write_space();
19657 self.write_keyword("RETURNING");
19658 self.write_space();
19659 self.generate_data_type(ret_type)?;
19660 }
19661
19662 self.write(")");
19663 Ok(())
19664 }
19665
19666 fn dialect_supports_json_arrow(&self) -> bool {
19668 use crate::dialects::DialectType;
19669 match self.config.dialect {
19670 Some(DialectType::PostgreSQL) => true,
19672 Some(DialectType::MySQL) => true,
19673 Some(DialectType::DuckDB) => true,
19674 Some(DialectType::CockroachDB) => true,
19675 Some(DialectType::StarRocks) => true,
19676 Some(DialectType::SQLite) => true,
19677 _ => false,
19679 }
19680 }
19681
19682 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
19683 use crate::dialects::DialectType;
19684
19685 if matches!(
19687 self.config.dialect,
19688 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
19689 ) && name == "JSON_EXTRACT_PATH"
19690 {
19691 self.generate_expression(&f.this)?;
19692 self.write(" #> ");
19693 if f.paths.len() == 1 {
19694 self.generate_expression(&f.paths[0])?;
19695 } else {
19696 self.write_keyword("ARRAY");
19698 self.write("[");
19699 for (i, path) in f.paths.iter().enumerate() {
19700 if i > 0 {
19701 self.write(", ");
19702 }
19703 self.generate_expression(path)?;
19704 }
19705 self.write("]");
19706 }
19707 return Ok(());
19708 }
19709
19710 self.write_keyword(name);
19711 self.write("(");
19712 self.generate_expression(&f.this)?;
19713 for path in &f.paths {
19714 self.write(", ");
19715 self.generate_expression(path)?;
19716 }
19717 self.write(")");
19718 Ok(())
19719 }
19720
19721 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
19722 use crate::dialects::DialectType;
19723
19724 self.write_keyword("JSON_OBJECT");
19725 self.write("(");
19726 if f.star {
19727 self.write("*");
19728 } else {
19729 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
19733 || matches!(
19734 self.config.dialect,
19735 Some(DialectType::BigQuery)
19736 | Some(DialectType::MySQL)
19737 | Some(DialectType::SQLite)
19738 );
19739
19740 for (i, (key, value)) in f.pairs.iter().enumerate() {
19741 if i > 0 {
19742 self.write(", ");
19743 }
19744 self.generate_expression(key)?;
19745 if use_comma_syntax {
19746 self.write(", ");
19747 } else {
19748 self.write(": ");
19749 }
19750 self.generate_expression(value)?;
19751 }
19752 }
19753 if let Some(null_handling) = f.null_handling {
19754 self.write_space();
19755 match null_handling {
19756 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19757 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19758 }
19759 }
19760 if f.with_unique_keys {
19761 self.write_space();
19762 self.write_keyword("WITH UNIQUE KEYS");
19763 }
19764 if let Some(ref ret_type) = f.returning_type {
19765 self.write_space();
19766 self.write_keyword("RETURNING");
19767 self.write_space();
19768 self.generate_data_type(ret_type)?;
19769 if f.format_json {
19770 self.write_space();
19771 self.write_keyword("FORMAT JSON");
19772 }
19773 if let Some(ref enc) = f.encoding {
19774 self.write_space();
19775 self.write_keyword("ENCODING");
19776 self.write_space();
19777 self.write(enc);
19778 }
19779 }
19780 self.write(")");
19781 Ok(())
19782 }
19783
19784 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
19785 self.write_keyword(name);
19786 self.write("(");
19787 self.generate_expression(&f.this)?;
19788 for (path, value) in &f.path_values {
19789 self.write(", ");
19790 self.generate_expression(path)?;
19791 self.write(", ");
19792 self.generate_expression(value)?;
19793 }
19794 self.write(")");
19795 Ok(())
19796 }
19797
19798 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
19799 self.write_keyword("JSON_ARRAYAGG");
19800 self.write("(");
19801 self.generate_expression(&f.this)?;
19802 if let Some(ref order_by) = f.order_by {
19803 self.write_space();
19804 self.write_keyword("ORDER BY");
19805 self.write_space();
19806 for (i, ord) in order_by.iter().enumerate() {
19807 if i > 0 {
19808 self.write(", ");
19809 }
19810 self.generate_ordered(ord)?;
19811 }
19812 }
19813 if let Some(null_handling) = f.null_handling {
19814 self.write_space();
19815 match null_handling {
19816 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19817 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19818 }
19819 }
19820 self.write(")");
19821 if let Some(ref filter) = f.filter {
19822 self.write_space();
19823 self.write_keyword("FILTER");
19824 self.write("(");
19825 self.write_keyword("WHERE");
19826 self.write_space();
19827 self.generate_expression(filter)?;
19828 self.write(")");
19829 }
19830 Ok(())
19831 }
19832
19833 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
19834 self.write_keyword("JSON_OBJECTAGG");
19835 self.write("(");
19836 self.generate_expression(&f.key)?;
19837 self.write(": ");
19838 self.generate_expression(&f.value)?;
19839 if let Some(null_handling) = f.null_handling {
19840 self.write_space();
19841 match null_handling {
19842 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
19843 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
19844 }
19845 }
19846 self.write(")");
19847 if let Some(ref filter) = f.filter {
19848 self.write_space();
19849 self.write_keyword("FILTER");
19850 self.write("(");
19851 self.write_keyword("WHERE");
19852 self.write_space();
19853 self.generate_expression(filter)?;
19854 self.write(")");
19855 }
19856 Ok(())
19857 }
19858
19859 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
19862 use crate::dialects::DialectType;
19863
19864 if self.config.dialect == Some(DialectType::Redshift) {
19866 self.write_keyword("CAST");
19867 self.write("(");
19868 self.generate_expression(&f.this)?;
19869 self.write_space();
19870 self.write_keyword("AS");
19871 self.write_space();
19872 self.generate_data_type(&f.to)?;
19873 self.write(")");
19874 return Ok(());
19875 }
19876
19877 self.write_keyword("CONVERT");
19878 self.write("(");
19879 self.generate_data_type(&f.to)?;
19880 self.write(", ");
19881 self.generate_expression(&f.this)?;
19882 if let Some(ref style) = f.style {
19883 self.write(", ");
19884 self.generate_expression(style)?;
19885 }
19886 self.write(")");
19887 Ok(())
19888 }
19889
19890 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
19893 if f.colon {
19894 self.write_keyword("LAMBDA");
19896 self.write_space();
19897 for (i, param) in f.parameters.iter().enumerate() {
19898 if i > 0 {
19899 self.write(", ");
19900 }
19901 self.generate_identifier(param)?;
19902 }
19903 self.write(" : ");
19904 } else {
19905 if f.parameters.len() == 1 {
19907 self.generate_identifier(&f.parameters[0])?;
19908 } else {
19909 self.write("(");
19910 for (i, param) in f.parameters.iter().enumerate() {
19911 if i > 0 {
19912 self.write(", ");
19913 }
19914 self.generate_identifier(param)?;
19915 }
19916 self.write(")");
19917 }
19918 self.write(" -> ");
19919 }
19920 self.generate_expression(&f.body)
19921 }
19922
19923 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
19924 self.generate_identifier(&f.name)?;
19925 match f.separator {
19926 NamedArgSeparator::DArrow => self.write(" => "),
19927 NamedArgSeparator::ColonEq => self.write(" := "),
19928 NamedArgSeparator::Eq => self.write(" = "),
19929 }
19930 self.generate_expression(&f.value)
19931 }
19932
19933 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
19934 self.write_keyword(&f.prefix);
19935 self.write(" ");
19936 self.generate_expression(&f.this)
19937 }
19938
19939 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
19940 match f.style {
19941 ParameterStyle::Question => self.write("?"),
19942 ParameterStyle::Dollar => {
19943 self.write("$");
19944 if let Some(idx) = f.index {
19945 self.write(&idx.to_string());
19946 } else if let Some(ref name) = f.name {
19947 self.write(name);
19949 }
19950 }
19951 ParameterStyle::DollarBrace => {
19952 self.write("${");
19954 if let Some(ref name) = f.name {
19955 self.write(name);
19956 }
19957 if let Some(ref expr) = f.expression {
19958 self.write(":");
19959 self.write(expr);
19960 }
19961 self.write("}");
19962 }
19963 ParameterStyle::Colon => {
19964 self.write(":");
19965 if let Some(idx) = f.index {
19966 self.write(&idx.to_string());
19967 } else if let Some(ref name) = f.name {
19968 self.write(name);
19969 }
19970 }
19971 ParameterStyle::At => {
19972 self.write("@");
19973 if let Some(ref name) = f.name {
19974 if f.string_quoted {
19975 self.write("'");
19976 self.write(name);
19977 self.write("'");
19978 } else if f.quoted {
19979 self.write("\"");
19980 self.write(name);
19981 self.write("\"");
19982 } else {
19983 self.write(name);
19984 }
19985 }
19986 }
19987 ParameterStyle::DoubleAt => {
19988 self.write("@@");
19989 if let Some(ref name) = f.name {
19990 self.write(name);
19991 }
19992 }
19993 ParameterStyle::DoubleDollar => {
19994 self.write("$$");
19995 if let Some(ref name) = f.name {
19996 self.write(name);
19997 }
19998 }
19999 ParameterStyle::Percent => {
20000 if let Some(ref name) = f.name {
20001 self.write("%(");
20003 self.write(name);
20004 self.write(")s");
20005 } else {
20006 self.write("%s");
20008 }
20009 }
20010 ParameterStyle::Brace => {
20011 self.write("{");
20014 if let Some(ref name) = f.name {
20015 self.write(name);
20016 }
20017 if let Some(ref expr) = f.expression {
20018 self.write(": ");
20019 self.write(expr);
20020 }
20021 self.write("}");
20022 }
20023 }
20024 Ok(())
20025 }
20026
20027 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
20028 self.write("?");
20029 if let Some(idx) = f.index {
20030 self.write(&idx.to_string());
20031 }
20032 Ok(())
20033 }
20034
20035 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
20036 if f.is_block {
20037 self.write("/*");
20038 self.write(&f.text);
20039 self.write("*/");
20040 } else {
20041 self.write("--");
20042 self.write(&f.text);
20043 }
20044 Ok(())
20045 }
20046
20047 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
20050 self.generate_expression(&f.this)?;
20051 if f.not {
20052 self.write_space();
20053 self.write_keyword("NOT");
20054 }
20055 self.write_space();
20056 self.write_keyword("SIMILAR TO");
20057 self.write_space();
20058 self.generate_expression(&f.pattern)?;
20059 if let Some(ref escape) = f.escape {
20060 self.write_space();
20061 self.write_keyword("ESCAPE");
20062 self.write_space();
20063 self.generate_expression(escape)?;
20064 }
20065 Ok(())
20066 }
20067
20068 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
20069 self.generate_expression(&f.this)?;
20070 self.write_space();
20071 if let Some(op) = &f.op {
20073 match op {
20074 QuantifiedOp::Eq => self.write("="),
20075 QuantifiedOp::Neq => self.write("<>"),
20076 QuantifiedOp::Lt => self.write("<"),
20077 QuantifiedOp::Lte => self.write("<="),
20078 QuantifiedOp::Gt => self.write(">"),
20079 QuantifiedOp::Gte => self.write(">="),
20080 }
20081 self.write_space();
20082 }
20083 self.write_keyword(name);
20084
20085 if matches!(&f.subquery, Expression::Subquery(_)) {
20087 self.write_space();
20088 self.generate_expression(&f.subquery)?;
20089 } else {
20090 self.write("(");
20091
20092 let is_statement = matches!(
20093 &f.subquery,
20094 Expression::Select(_)
20095 | Expression::Union(_)
20096 | Expression::Intersect(_)
20097 | Expression::Except(_)
20098 );
20099
20100 if self.config.pretty && is_statement {
20101 self.write_newline();
20102 self.indent_level += 1;
20103 self.write_indent();
20104 }
20105 self.generate_expression(&f.subquery)?;
20106 if self.config.pretty && is_statement {
20107 self.write_newline();
20108 self.indent_level -= 1;
20109 self.write_indent();
20110 }
20111 self.write(")");
20112 }
20113 Ok(())
20114 }
20115
20116 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
20117 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
20119 self.generate_expression(this)?;
20120 self.write_space();
20121 self.write_keyword("OVERLAPS");
20122 self.write_space();
20123 self.generate_expression(expr)?;
20124 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
20125 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
20126 {
20127 self.write("(");
20129 self.generate_expression(ls)?;
20130 self.write(", ");
20131 self.generate_expression(le)?;
20132 self.write(")");
20133 self.write_space();
20134 self.write_keyword("OVERLAPS");
20135 self.write_space();
20136 self.write("(");
20137 self.generate_expression(rs)?;
20138 self.write(", ");
20139 self.generate_expression(re)?;
20140 self.write(")");
20141 }
20142 Ok(())
20143 }
20144
20145 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
20148 use crate::dialects::DialectType;
20149
20150 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
20152 self.generate_expression(&cast.this)?;
20153 self.write(" !:> ");
20154 self.generate_data_type(&cast.to)?;
20155 return Ok(());
20156 }
20157
20158 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
20160 self.write_keyword("TRYCAST");
20161 self.write("(");
20162 self.generate_expression(&cast.this)?;
20163 self.write_space();
20164 self.write_keyword("AS");
20165 self.write_space();
20166 self.generate_data_type(&cast.to)?;
20167 self.write(")");
20168 return Ok(());
20169 }
20170
20171 let keyword = if matches!(
20173 self.config.dialect,
20174 Some(DialectType::Hive)
20175 | Some(DialectType::MySQL)
20176 | Some(DialectType::SQLite)
20177 | Some(DialectType::Oracle)
20178 | Some(DialectType::ClickHouse)
20179 | Some(DialectType::Redshift)
20180 | Some(DialectType::PostgreSQL)
20181 | Some(DialectType::StarRocks)
20182 | Some(DialectType::Doris)
20183 ) {
20184 "CAST"
20185 } else {
20186 "TRY_CAST"
20187 };
20188
20189 self.write_keyword(keyword);
20190 self.write("(");
20191 self.generate_expression(&cast.this)?;
20192 self.write_space();
20193 self.write_keyword("AS");
20194 self.write_space();
20195 self.generate_data_type(&cast.to)?;
20196
20197 if let Some(format) = &cast.format {
20199 self.write_space();
20200 self.write_keyword("FORMAT");
20201 self.write_space();
20202 self.generate_expression(format)?;
20203 }
20204
20205 self.write(")");
20206 Ok(())
20207 }
20208
20209 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
20210 self.write_keyword("SAFE_CAST");
20211 self.write("(");
20212 self.generate_expression(&cast.this)?;
20213 self.write_space();
20214 self.write_keyword("AS");
20215 self.write_space();
20216 self.generate_data_type(&cast.to)?;
20217
20218 if let Some(format) = &cast.format {
20220 self.write_space();
20221 self.write_keyword("FORMAT");
20222 self.write_space();
20223 self.generate_expression(format)?;
20224 }
20225
20226 self.write(")");
20227 Ok(())
20228 }
20229
20230 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
20233 self.generate_expression(&s.this)?;
20234 self.write("[");
20235 self.generate_expression(&s.index)?;
20236 self.write("]");
20237 Ok(())
20238 }
20239
20240 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
20241 self.generate_expression(&d.this)?;
20242 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
20245 && matches!(
20246 &d.this,
20247 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
20248 );
20249 if use_colon {
20250 self.write(":");
20251 } else {
20252 self.write(".");
20253 }
20254 self.generate_identifier(&d.field)
20255 }
20256
20257 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
20258 self.generate_expression(&m.this)?;
20259 self.write(".");
20260 if m.method.quoted {
20263 let q = self.config.identifier_quote;
20264 self.write(&format!("{}{}{}", q, m.method.name, q));
20265 } else {
20266 self.write(&m.method.name);
20267 }
20268 self.write("(");
20269 for (i, arg) in m.args.iter().enumerate() {
20270 if i > 0 {
20271 self.write(", ");
20272 }
20273 self.generate_expression(arg)?;
20274 }
20275 self.write(")");
20276 Ok(())
20277 }
20278
20279 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
20280 let needs_parens = matches!(
20283 &s.this,
20284 Expression::JsonExtract(f) if f.arrow_syntax
20285 ) || matches!(
20286 &s.this,
20287 Expression::JsonExtractScalar(f) if f.arrow_syntax
20288 );
20289
20290 if needs_parens {
20291 self.write("(");
20292 }
20293 self.generate_expression(&s.this)?;
20294 if needs_parens {
20295 self.write(")");
20296 }
20297 self.write("[");
20298 if let Some(start) = &s.start {
20299 self.generate_expression(start)?;
20300 }
20301 self.write(":");
20302 if let Some(end) = &s.end {
20303 self.generate_expression(end)?;
20304 }
20305 self.write("]");
20306 Ok(())
20307 }
20308
20309 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
20310 match &op.left {
20314 Expression::Column(col) => {
20315 if let Some(table) = &col.table {
20318 self.generate_identifier(table)?;
20319 self.write(".");
20320 }
20321 self.generate_identifier(&col.name)?;
20322 if col.join_mark && self.config.supports_column_join_marks {
20324 self.write(" (+)");
20325 }
20326 if op.left_comments.is_empty() {
20328 for comment in &col.trailing_comments {
20329 self.write_space();
20330 self.write_formatted_comment(comment);
20331 }
20332 }
20333 }
20334 Expression::Add(inner_op)
20335 | Expression::Sub(inner_op)
20336 | Expression::Mul(inner_op)
20337 | Expression::Div(inner_op)
20338 | Expression::Concat(inner_op) => {
20339 self.generate_binary_op_no_trailing(inner_op, match &op.left {
20341 Expression::Add(_) => "+",
20342 Expression::Sub(_) => "-",
20343 Expression::Mul(_) => "*",
20344 Expression::Div(_) => "/",
20345 Expression::Concat(_) => "||",
20346 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
20347 })?;
20348 }
20349 _ => {
20350 self.generate_expression(&op.left)?;
20351 }
20352 }
20353 for comment in &op.left_comments {
20355 self.write_space();
20356 self.write_formatted_comment(comment);
20357 }
20358 if self.config.pretty
20359 && matches!(self.config.dialect, Some(DialectType::Snowflake))
20360 && (operator == "AND" || operator == "OR")
20361 {
20362 self.write_newline();
20363 self.write_indent();
20364 self.write_keyword(operator);
20365 } else {
20366 self.write_space();
20367 if operator.chars().all(|c| c.is_alphabetic()) {
20368 self.write_keyword(operator);
20369 } else {
20370 self.write(operator);
20371 }
20372 }
20373 for comment in &op.operator_comments {
20375 self.write_space();
20376 self.write_formatted_comment(comment);
20377 }
20378 self.write_space();
20379 self.generate_expression(&op.right)?;
20380 for comment in &op.trailing_comments {
20382 self.write_space();
20383 self.write_formatted_comment(comment);
20384 }
20385 Ok(())
20386 }
20387
20388 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
20390 self.generate_expression(&op.left)?;
20391 self.write_space();
20392 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
20394 self.write("`ILIKE`");
20395 } else {
20396 self.write_keyword(operator);
20397 }
20398 if let Some(quantifier) = &op.quantifier {
20399 self.write_space();
20400 self.write_keyword(quantifier);
20401 }
20402 self.write_space();
20403 self.generate_expression(&op.right)?;
20404 if let Some(escape) = &op.escape {
20405 self.write_space();
20406 self.write_keyword("ESCAPE");
20407 self.write_space();
20408 self.generate_expression(escape)?;
20409 }
20410 Ok(())
20411 }
20412
20413 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
20416 use crate::dialects::DialectType;
20417 self.generate_expression(&op.left)?;
20418 self.write_space();
20419 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
20420 self.write("<=>");
20421 } else {
20422 self.write_keyword("IS NOT DISTINCT FROM");
20423 }
20424 self.write_space();
20425 self.generate_expression(&op.right)?;
20426 Ok(())
20427 }
20428
20429 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
20431 self.generate_expression(&op.left)?;
20432 self.write_space();
20433 self.write_keyword("IS DISTINCT FROM");
20434 self.write_space();
20435 self.generate_expression(&op.right)?;
20436 Ok(())
20437 }
20438
20439 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
20441 match &op.left {
20443 Expression::Column(col) => {
20444 if let Some(table) = &col.table {
20445 self.generate_identifier(table)?;
20446 self.write(".");
20447 }
20448 self.generate_identifier(&col.name)?;
20449 if col.join_mark && self.config.supports_column_join_marks {
20451 self.write(" (+)");
20452 }
20453 }
20454 Expression::Add(inner_op)
20455 | Expression::Sub(inner_op)
20456 | Expression::Mul(inner_op)
20457 | Expression::Div(inner_op)
20458 | Expression::Concat(inner_op) => {
20459 self.generate_binary_op_no_trailing(inner_op, match &op.left {
20460 Expression::Add(_) => "+",
20461 Expression::Sub(_) => "-",
20462 Expression::Mul(_) => "*",
20463 Expression::Div(_) => "/",
20464 Expression::Concat(_) => "||",
20465 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
20466 })?;
20467 }
20468 _ => {
20469 self.generate_expression(&op.left)?;
20470 }
20471 }
20472 for comment in &op.left_comments {
20474 self.write_space();
20475 self.write_formatted_comment(comment);
20476 }
20477 self.write_space();
20478 if operator.chars().all(|c| c.is_alphabetic()) {
20479 self.write_keyword(operator);
20480 } else {
20481 self.write(operator);
20482 }
20483 for comment in &op.operator_comments {
20485 self.write_space();
20486 self.write_formatted_comment(comment);
20487 }
20488 self.write_space();
20489 match &op.right {
20492 Expression::Column(col) => {
20493 if let Some(table) = &col.table {
20494 self.generate_identifier(table)?;
20495 self.write(".");
20496 }
20497 self.generate_identifier(&col.name)?;
20498 if col.join_mark && self.config.supports_column_join_marks {
20500 self.write(" (+)");
20501 }
20502 }
20503 _ => {
20504 self.generate_expression(&op.right)?;
20505 }
20506 }
20507 Ok(())
20509 }
20510
20511 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
20512 if operator.chars().all(|c| c.is_alphabetic()) {
20513 self.write_keyword(operator);
20514 self.write_space();
20515 } else {
20516 self.write(operator);
20517 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
20519 self.write_space();
20520 }
20521 }
20522 self.generate_expression(&op.this)
20523 }
20524
20525 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
20526 let is_generic =
20530 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
20531 let use_prefix_not =
20532 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
20533 if use_prefix_not {
20534 self.write_keyword("NOT");
20535 self.write_space();
20536 }
20537 self.generate_expression(&in_expr.this)?;
20538 if in_expr.global {
20539 self.write_space();
20540 self.write_keyword("GLOBAL");
20541 }
20542 if in_expr.not && !use_prefix_not {
20543 self.write_space();
20544 self.write_keyword("NOT");
20545 }
20546 self.write_space();
20547 self.write_keyword("IN");
20548
20549 if let Some(unnest_expr) = &in_expr.unnest {
20551 self.write_space();
20552 self.write_keyword("UNNEST");
20553 self.write("(");
20554 self.generate_expression(unnest_expr)?;
20555 self.write(")");
20556 return Ok(());
20557 }
20558
20559 if let Some(query) = &in_expr.query {
20560 let is_bare = in_expr.expressions.is_empty()
20563 && !matches!(
20564 query,
20565 Expression::Select(_)
20566 | Expression::Union(_)
20567 | Expression::Intersect(_)
20568 | Expression::Except(_)
20569 | Expression::Subquery(_)
20570 );
20571 if is_bare {
20572 self.write_space();
20574 self.generate_expression(query)?;
20575 } else {
20576 self.write(" (");
20578 let is_statement = matches!(
20579 query,
20580 Expression::Select(_)
20581 | Expression::Union(_)
20582 | Expression::Intersect(_)
20583 | Expression::Except(_)
20584 | Expression::Subquery(_)
20585 );
20586 if self.config.pretty && is_statement {
20587 self.write_newline();
20588 self.indent_level += 1;
20589 self.write_indent();
20590 }
20591 self.generate_expression(query)?;
20592 if self.config.pretty && is_statement {
20593 self.write_newline();
20594 self.indent_level -= 1;
20595 self.write_indent();
20596 }
20597 self.write(")");
20598 }
20599 } else {
20600 let is_duckdb = matches!(
20604 self.config.dialect,
20605 Some(crate::dialects::DialectType::DuckDB)
20606 );
20607 let is_clickhouse = matches!(
20608 self.config.dialect,
20609 Some(crate::dialects::DialectType::ClickHouse)
20610 );
20611 let single_expr = in_expr.expressions.len() == 1;
20612 if is_clickhouse && single_expr {
20613 if let Expression::Array(arr) = &in_expr.expressions[0] {
20614 self.write(" (");
20616 for (i, expr) in arr.expressions.iter().enumerate() {
20617 if i > 0 {
20618 self.write(", ");
20619 }
20620 self.generate_expression(expr)?;
20621 }
20622 self.write(")");
20623 } else {
20624 self.write_space();
20625 self.generate_expression(&in_expr.expressions[0])?;
20626 }
20627 } else {
20628 let is_bare_ref = single_expr
20629 && matches!(
20630 &in_expr.expressions[0],
20631 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
20632 );
20633 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
20634 self.write_space();
20637 self.generate_expression(&in_expr.expressions[0])?;
20638 } else {
20639 self.write(" (");
20641 for (i, expr) in in_expr.expressions.iter().enumerate() {
20642 if i > 0 {
20643 self.write(", ");
20644 }
20645 self.generate_expression(expr)?;
20646 }
20647 self.write(")");
20648 }
20649 }
20650 }
20651
20652 Ok(())
20653 }
20654
20655 fn generate_between(&mut self, between: &Between) -> Result<()> {
20656 let use_prefix_not = between.not
20658 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
20659 if use_prefix_not {
20660 self.write_keyword("NOT");
20661 self.write_space();
20662 }
20663 self.generate_expression(&between.this)?;
20664 if between.not && !use_prefix_not {
20665 self.write_space();
20666 self.write_keyword("NOT");
20667 }
20668 self.write_space();
20669 self.write_keyword("BETWEEN");
20670 if let Some(sym) = between.symmetric {
20672 if sym {
20673 self.write(" SYMMETRIC");
20674 } else {
20675 self.write(" ASYMMETRIC");
20676 }
20677 }
20678 self.write_space();
20679 self.generate_expression(&between.low)?;
20680 self.write_space();
20681 self.write_keyword("AND");
20682 self.write_space();
20683 self.generate_expression(&between.high)
20684 }
20685
20686 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
20687 let use_prefix_not = is_null.not
20689 && (self.config.dialect.is_none()
20690 || self.config.dialect == Some(DialectType::Generic)
20691 || is_null.postfix_form);
20692 if use_prefix_not {
20693 self.write_keyword("NOT");
20695 self.write_space();
20696 self.generate_expression(&is_null.this)?;
20697 self.write_space();
20698 self.write_keyword("IS");
20699 self.write_space();
20700 self.write_keyword("NULL");
20701 } else {
20702 self.generate_expression(&is_null.this)?;
20703 self.write_space();
20704 self.write_keyword("IS");
20705 if is_null.not {
20706 self.write_space();
20707 self.write_keyword("NOT");
20708 }
20709 self.write_space();
20710 self.write_keyword("NULL");
20711 }
20712 Ok(())
20713 }
20714
20715 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
20716 self.generate_expression(&is_true.this)?;
20717 self.write_space();
20718 self.write_keyword("IS");
20719 if is_true.not {
20720 self.write_space();
20721 self.write_keyword("NOT");
20722 }
20723 self.write_space();
20724 self.write_keyword("TRUE");
20725 Ok(())
20726 }
20727
20728 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
20729 self.generate_expression(&is_false.this)?;
20730 self.write_space();
20731 self.write_keyword("IS");
20732 if is_false.not {
20733 self.write_space();
20734 self.write_keyword("NOT");
20735 }
20736 self.write_space();
20737 self.write_keyword("FALSE");
20738 Ok(())
20739 }
20740
20741 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
20742 self.generate_expression(&is_json.this)?;
20743 self.write_space();
20744 self.write_keyword("IS");
20745 if is_json.negated {
20746 self.write_space();
20747 self.write_keyword("NOT");
20748 }
20749 self.write_space();
20750 self.write_keyword("JSON");
20751
20752 if let Some(ref json_type) = is_json.json_type {
20754 self.write_space();
20755 self.write_keyword(json_type);
20756 }
20757
20758 match &is_json.unique_keys {
20760 Some(JsonUniqueKeys::With) => {
20761 self.write_space();
20762 self.write_keyword("WITH UNIQUE KEYS");
20763 }
20764 Some(JsonUniqueKeys::Without) => {
20765 self.write_space();
20766 self.write_keyword("WITHOUT UNIQUE KEYS");
20767 }
20768 Some(JsonUniqueKeys::Shorthand) => {
20769 self.write_space();
20770 self.write_keyword("UNIQUE KEYS");
20771 }
20772 None => {}
20773 }
20774
20775 Ok(())
20776 }
20777
20778 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
20779 self.generate_expression(&is_expr.left)?;
20780 self.write_space();
20781 self.write_keyword("IS");
20782 self.write_space();
20783 self.generate_expression(&is_expr.right)
20784 }
20785
20786 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
20787 if exists.not {
20788 self.write_keyword("NOT");
20789 self.write_space();
20790 }
20791 self.write_keyword("EXISTS");
20792 self.write("(");
20793 let is_statement = matches!(
20794 &exists.this,
20795 Expression::Select(_)
20796 | Expression::Union(_)
20797 | Expression::Intersect(_)
20798 | Expression::Except(_)
20799 );
20800 if self.config.pretty && is_statement {
20801 self.write_newline();
20802 self.indent_level += 1;
20803 self.write_indent();
20804 self.generate_expression(&exists.this)?;
20805 self.write_newline();
20806 self.indent_level -= 1;
20807 self.write_indent();
20808 self.write(")");
20809 } else {
20810 self.generate_expression(&exists.this)?;
20811 self.write(")");
20812 }
20813 Ok(())
20814 }
20815
20816 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
20817 self.generate_expression(&op.left)?;
20818 self.write_space();
20819 self.write_keyword("MEMBER OF");
20820 self.write("(");
20821 self.generate_expression(&op.right)?;
20822 self.write(")");
20823 Ok(())
20824 }
20825
20826 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
20827 if subquery.lateral {
20828 self.write_keyword("LATERAL");
20829 self.write_space();
20830 }
20831
20832 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
20836 matches!(
20837 &p.this,
20838 Expression::Select(_)
20839 | Expression::Union(_)
20840 | Expression::Intersect(_)
20841 | Expression::Except(_)
20842 | Expression::Subquery(_)
20843 )
20844 } else {
20845 false
20846 };
20847
20848 let is_statement = matches!(
20850 &subquery.this,
20851 Expression::Select(_)
20852 | Expression::Union(_)
20853 | Expression::Intersect(_)
20854 | Expression::Except(_)
20855 | Expression::Merge(_)
20856 );
20857
20858 if !skip_outer_parens {
20859 self.write("(");
20860 if self.config.pretty && is_statement {
20861 self.write_newline();
20862 self.indent_level += 1;
20863 self.write_indent();
20864 }
20865 }
20866 self.generate_expression(&subquery.this)?;
20867
20868 if subquery.modifiers_inside {
20870 if let Some(order_by) = &subquery.order_by {
20872 self.write_space();
20873 self.write_keyword("ORDER BY");
20874 self.write_space();
20875 for (i, ord) in order_by.expressions.iter().enumerate() {
20876 if i > 0 {
20877 self.write(", ");
20878 }
20879 self.generate_ordered(ord)?;
20880 }
20881 }
20882
20883 if let Some(limit) = &subquery.limit {
20884 self.write_space();
20885 self.write_keyword("LIMIT");
20886 self.write_space();
20887 self.generate_expression(&limit.this)?;
20888 if limit.percent {
20889 self.write_space();
20890 self.write_keyword("PERCENT");
20891 }
20892 }
20893
20894 if let Some(offset) = &subquery.offset {
20895 self.write_space();
20896 self.write_keyword("OFFSET");
20897 self.write_space();
20898 self.generate_expression(&offset.this)?;
20899 }
20900 }
20901
20902 if !skip_outer_parens {
20903 if self.config.pretty && is_statement {
20904 self.write_newline();
20905 self.indent_level -= 1;
20906 self.write_indent();
20907 }
20908 self.write(")");
20909 }
20910
20911 if !subquery.modifiers_inside {
20913 if let Some(order_by) = &subquery.order_by {
20914 self.write_space();
20915 self.write_keyword("ORDER BY");
20916 self.write_space();
20917 for (i, ord) in order_by.expressions.iter().enumerate() {
20918 if i > 0 {
20919 self.write(", ");
20920 }
20921 self.generate_ordered(ord)?;
20922 }
20923 }
20924
20925 if let Some(limit) = &subquery.limit {
20926 self.write_space();
20927 self.write_keyword("LIMIT");
20928 self.write_space();
20929 self.generate_expression(&limit.this)?;
20930 if limit.percent {
20931 self.write_space();
20932 self.write_keyword("PERCENT");
20933 }
20934 }
20935
20936 if let Some(offset) = &subquery.offset {
20937 self.write_space();
20938 self.write_keyword("OFFSET");
20939 self.write_space();
20940 self.generate_expression(&offset.this)?;
20941 }
20942
20943 if let Some(distribute_by) = &subquery.distribute_by {
20945 self.write_space();
20946 self.write_keyword("DISTRIBUTE BY");
20947 self.write_space();
20948 for (i, expr) in distribute_by.expressions.iter().enumerate() {
20949 if i > 0 {
20950 self.write(", ");
20951 }
20952 self.generate_expression(expr)?;
20953 }
20954 }
20955
20956 if let Some(sort_by) = &subquery.sort_by {
20958 self.write_space();
20959 self.write_keyword("SORT BY");
20960 self.write_space();
20961 for (i, ord) in sort_by.expressions.iter().enumerate() {
20962 if i > 0 {
20963 self.write(", ");
20964 }
20965 self.generate_ordered(ord)?;
20966 }
20967 }
20968
20969 if let Some(cluster_by) = &subquery.cluster_by {
20971 self.write_space();
20972 self.write_keyword("CLUSTER BY");
20973 self.write_space();
20974 for (i, ord) in cluster_by.expressions.iter().enumerate() {
20975 if i > 0 {
20976 self.write(", ");
20977 }
20978 self.generate_ordered(ord)?;
20979 }
20980 }
20981 }
20982
20983 if let Some(alias) = &subquery.alias {
20984 self.write_space();
20985 let skip_as = matches!(
20987 self.config.dialect,
20988 Some(crate::dialects::DialectType::Oracle)
20989 );
20990 if !skip_as {
20991 self.write_keyword("AS");
20992 self.write_space();
20993 }
20994 self.generate_identifier(alias)?;
20995 if !subquery.column_aliases.is_empty() {
20996 self.write("(");
20997 for (i, col) in subquery.column_aliases.iter().enumerate() {
20998 if i > 0 {
20999 self.write(", ");
21000 }
21001 self.generate_identifier(col)?;
21002 }
21003 self.write(")");
21004 }
21005 }
21006 for comment in &subquery.trailing_comments {
21008 self.write(" ");
21009 self.write_formatted_comment(comment);
21010 }
21011 Ok(())
21012 }
21013
21014 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
21015 if let Some(ref with) = pivot.with {
21017 self.generate_with(with)?;
21018 self.write_space();
21019 }
21020
21021 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
21022
21023 let is_redshift_unpivot = pivot.unpivot
21027 && pivot.expressions.is_empty()
21028 && pivot.fields.is_empty()
21029 && pivot.using.is_empty()
21030 && pivot.into.is_none()
21031 && !matches!(&pivot.this, Expression::Null(_));
21032
21033 if is_redshift_unpivot {
21034 self.write_keyword("UNPIVOT");
21036 self.write_space();
21037 self.generate_expression(&pivot.this)?;
21038 if let Some(alias) = &pivot.alias {
21040 self.write_space();
21041 self.write_keyword("AS");
21042 self.write_space();
21043 self.write(&alias.name);
21045 }
21046 return Ok(());
21047 }
21048
21049 let is_simplified = !pivot.using.is_empty()
21051 || pivot.into.is_some()
21052 || (pivot.fields.is_empty()
21053 && !pivot.expressions.is_empty()
21054 && !matches!(&pivot.this, Expression::Null(_)));
21055
21056 if is_simplified {
21057 self.write_keyword(direction);
21061 self.write_space();
21062 self.generate_expression(&pivot.this)?;
21063
21064 if !pivot.expressions.is_empty() {
21065 self.write_space();
21066 self.write_keyword("ON");
21067 self.write_space();
21068 for (i, expr) in pivot.expressions.iter().enumerate() {
21069 if i > 0 {
21070 self.write(", ");
21071 }
21072 self.generate_expression(expr)?;
21073 }
21074 }
21075
21076 if let Some(into) = &pivot.into {
21078 self.write_space();
21079 self.write_keyword("INTO");
21080 self.write_space();
21081 self.generate_expression(into)?;
21082 }
21083
21084 if !pivot.using.is_empty() {
21086 self.write_space();
21087 self.write_keyword("USING");
21088 self.write_space();
21089 for (i, expr) in pivot.using.iter().enumerate() {
21090 if i > 0 {
21091 self.write(", ");
21092 }
21093 self.generate_expression(expr)?;
21094 }
21095 }
21096
21097 if let Some(group) = &pivot.group {
21099 self.write_space();
21100 self.generate_expression(group)?;
21101 }
21102 } else {
21103 if !matches!(&pivot.this, Expression::Null(_)) {
21108 self.generate_expression(&pivot.this)?;
21109 self.write_space();
21110 }
21111 self.write_keyword(direction);
21112 self.write("(");
21113
21114 for (i, expr) in pivot.expressions.iter().enumerate() {
21116 if i > 0 {
21117 self.write(", ");
21118 }
21119 self.generate_expression(expr)?;
21120 }
21121
21122 if !pivot.fields.is_empty() {
21124 if !pivot.expressions.is_empty() {
21125 self.write_space();
21126 }
21127 self.write_keyword("FOR");
21128 self.write_space();
21129 for (i, field) in pivot.fields.iter().enumerate() {
21130 if i > 0 {
21131 self.write_space();
21132 }
21133 self.generate_expression(field)?;
21135 }
21136 }
21137
21138 if let Some(default_val) = &pivot.default_on_null {
21140 self.write_space();
21141 self.write_keyword("DEFAULT ON NULL");
21142 self.write(" (");
21143 self.generate_expression(default_val)?;
21144 self.write(")");
21145 }
21146
21147 if let Some(group) = &pivot.group {
21149 self.write_space();
21150 self.generate_expression(group)?;
21151 }
21152
21153 self.write(")");
21154 }
21155
21156 if let Some(alias) = &pivot.alias {
21158 self.write_space();
21159 self.write_keyword("AS");
21160 self.write_space();
21161 self.generate_identifier(alias)?;
21162 }
21163
21164 Ok(())
21165 }
21166
21167 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
21168 self.generate_expression(&unpivot.this)?;
21169 self.write_space();
21170 self.write_keyword("UNPIVOT");
21171 if let Some(include) = unpivot.include_nulls {
21173 self.write_space();
21174 if include {
21175 self.write_keyword("INCLUDE NULLS");
21176 } else {
21177 self.write_keyword("EXCLUDE NULLS");
21178 }
21179 self.write_space();
21180 }
21181 self.write("(");
21182 if unpivot.value_column_parenthesized {
21183 self.write("(");
21184 }
21185 self.generate_identifier(&unpivot.value_column)?;
21186 for extra_col in &unpivot.extra_value_columns {
21188 self.write(", ");
21189 self.generate_identifier(extra_col)?;
21190 }
21191 if unpivot.value_column_parenthesized {
21192 self.write(")");
21193 }
21194 self.write_space();
21195 self.write_keyword("FOR");
21196 self.write_space();
21197 self.generate_identifier(&unpivot.name_column)?;
21198 self.write_space();
21199 self.write_keyword("IN");
21200 self.write(" (");
21201 for (i, col) in unpivot.columns.iter().enumerate() {
21202 if i > 0 {
21203 self.write(", ");
21204 }
21205 self.generate_expression(col)?;
21206 }
21207 self.write("))");
21208 if let Some(alias) = &unpivot.alias {
21209 self.write_space();
21210 self.write_keyword("AS");
21211 self.write_space();
21212 self.generate_identifier(alias)?;
21213 }
21214 Ok(())
21215 }
21216
21217 fn generate_values(&mut self, values: &Values) -> Result<()> {
21218 self.write_keyword("VALUES");
21219 for (i, row) in values.expressions.iter().enumerate() {
21220 if i > 0 {
21221 self.write(",");
21222 }
21223 self.write(" (");
21224 for (j, expr) in row.expressions.iter().enumerate() {
21225 if j > 0 {
21226 self.write(", ");
21227 }
21228 self.generate_expression(expr)?;
21229 }
21230 self.write(")");
21231 }
21232 if let Some(alias) = &values.alias {
21233 self.write_space();
21234 self.write_keyword("AS");
21235 self.write_space();
21236 self.generate_identifier(alias)?;
21237 if !values.column_aliases.is_empty() {
21238 self.write("(");
21239 for (i, col) in values.column_aliases.iter().enumerate() {
21240 if i > 0 {
21241 self.write(", ");
21242 }
21243 self.generate_identifier(col)?;
21244 }
21245 self.write(")");
21246 }
21247 }
21248 Ok(())
21249 }
21250
21251 fn generate_array(&mut self, arr: &Array) -> Result<()> {
21252 let needs_inheritance = matches!(
21254 self.config.dialect,
21255 Some(DialectType::DuckDB)
21256 | Some(DialectType::Spark)
21257 | Some(DialectType::Databricks)
21258 | Some(DialectType::Hive)
21259 | Some(DialectType::Snowflake)
21260 | Some(DialectType::Presto)
21261 | Some(DialectType::Trino)
21262 );
21263 let propagated: Vec<Expression>;
21264 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
21265 propagated = Self::inherit_struct_field_names(&arr.expressions);
21266 &propagated
21267 } else {
21268 &arr.expressions
21269 };
21270
21271 let use_parens =
21274 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
21275 if !self.config.array_bracket_only {
21276 self.write_keyword("ARRAY");
21277 }
21278 if use_parens {
21279 self.write("(");
21280 } else {
21281 self.write("[");
21282 }
21283 for (i, expr) in expressions.iter().enumerate() {
21284 if i > 0 {
21285 self.write(", ");
21286 }
21287 self.generate_expression(expr)?;
21288 }
21289 if use_parens {
21290 self.write(")");
21291 } else {
21292 self.write("]");
21293 }
21294 Ok(())
21295 }
21296
21297 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
21298 if tuple.expressions.len() == 2 {
21301 if let Expression::TableAlias(_) = &tuple.expressions[1] {
21302 self.generate_expression(&tuple.expressions[0])?;
21304 self.write_space();
21305 self.write_keyword("AS");
21306 self.write_space();
21307 self.generate_expression(&tuple.expressions[1])?;
21308 return Ok(());
21309 }
21310 }
21311
21312 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
21315 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
21316 for expr in &tuple.expressions {
21317 expr_strings.push(self.generate_to_string(expr)?);
21318 }
21319 self.too_wide(&expr_strings)
21320 } else {
21321 false
21322 };
21323
21324 if expand_tuple {
21325 self.write("(");
21326 self.write_newline();
21327 self.indent_level += 1;
21328 for (i, expr) in tuple.expressions.iter().enumerate() {
21329 if i > 0 {
21330 self.write(",");
21331 self.write_newline();
21332 }
21333 self.write_indent();
21334 self.generate_expression(expr)?;
21335 }
21336 self.indent_level -= 1;
21337 self.write_newline();
21338 self.write_indent();
21339 self.write(")");
21340 } else {
21341 self.write("(");
21342 for (i, expr) in tuple.expressions.iter().enumerate() {
21343 if i > 0 {
21344 self.write(", ");
21345 }
21346 self.generate_expression(expr)?;
21347 }
21348 self.write(")");
21349 }
21350 Ok(())
21351 }
21352
21353 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
21354 self.generate_expression(&pipe.this)?;
21355 self.write(" |> ");
21356 self.generate_expression(&pipe.expression)?;
21357 Ok(())
21358 }
21359
21360 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
21361 self.generate_expression(&ordered.this)?;
21362 if ordered.desc {
21363 self.write_space();
21364 self.write_keyword("DESC");
21365 } else if ordered.explicit_asc {
21366 self.write_space();
21367 self.write_keyword("ASC");
21368 }
21369 if let Some(nulls_first) = ordered.nulls_first {
21370 let is_asc = !ordered.desc;
21384 let is_nulls_are_large = matches!(
21385 self.config.dialect,
21386 Some(DialectType::Oracle)
21387 | Some(DialectType::PostgreSQL)
21388 | Some(DialectType::Redshift)
21389 | Some(DialectType::Snowflake)
21390 );
21391 let is_nulls_are_last = matches!(
21392 self.config.dialect,
21393 Some(DialectType::Dremio)
21394 | Some(DialectType::DuckDB)
21395 | Some(DialectType::Presto)
21396 | Some(DialectType::Trino)
21397 | Some(DialectType::Athena)
21398 | Some(DialectType::ClickHouse)
21399 | Some(DialectType::Drill)
21400 | Some(DialectType::Exasol)
21401 );
21402
21403 let is_default_nulls = if is_nulls_are_large {
21405 (is_asc && !nulls_first) || (!is_asc && nulls_first)
21407 } else if is_nulls_are_last {
21408 !nulls_first
21410 } else {
21411 false
21412 };
21413
21414 if !is_default_nulls {
21415 self.write_space();
21416 self.write_keyword("NULLS");
21417 self.write_space();
21418 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
21419 }
21420 }
21421 if let Some(ref with_fill) = ordered.with_fill {
21423 self.write_space();
21424 self.generate_with_fill(with_fill)?;
21425 }
21426 Ok(())
21427 }
21428
21429 fn write_clickhouse_type(&mut self, type_str: &str) {
21431 if self.clickhouse_nullable_depth < 0 {
21432 self.write(type_str);
21434 } else {
21435 self.write(&format!("Nullable({})", type_str));
21436 }
21437 }
21438
21439 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
21440 use crate::dialects::DialectType;
21441
21442 match dt {
21443 DataType::Boolean => {
21444 match self.config.dialect {
21446 Some(DialectType::TSQL) => self.write_keyword("BIT"),
21447 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
21449 self.write_keyword("NUMBER(1)")
21451 }
21452 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
21454 }
21455 }
21456 DataType::TinyInt { length } => {
21457 match self.config.dialect {
21461 Some(DialectType::PostgreSQL)
21462 | Some(DialectType::Redshift)
21463 | Some(DialectType::Oracle)
21464 | Some(DialectType::Exasol) => {
21465 self.write_keyword("SMALLINT");
21466 }
21467 Some(DialectType::Teradata) => {
21468 self.write_keyword("BYTEINT");
21470 }
21471 Some(DialectType::Dremio) => {
21472 self.write_keyword("INT");
21474 }
21475 Some(DialectType::ClickHouse) => {
21476 self.write_clickhouse_type("Int8");
21477 }
21478 _ => {
21479 self.write_keyword("TINYINT");
21480 }
21481 }
21482 if let Some(n) = length {
21483 if !matches!(
21484 self.config.dialect,
21485 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
21486 ) {
21487 self.write(&format!("({})", n));
21488 }
21489 }
21490 }
21491 DataType::SmallInt { length } => {
21492 match self.config.dialect {
21494 Some(DialectType::Dremio) => {
21495 self.write_keyword("INT");
21496 }
21497 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
21498 self.write_keyword("INTEGER");
21499 }
21500 Some(DialectType::BigQuery) => {
21501 self.write_keyword("INT64");
21502 }
21503 Some(DialectType::ClickHouse) => {
21504 self.write_clickhouse_type("Int16");
21505 }
21506 _ => {
21507 self.write_keyword("SMALLINT");
21508 if let Some(n) = length {
21509 self.write(&format!("({})", n));
21510 }
21511 }
21512 }
21513 }
21514 DataType::Int {
21515 length,
21516 integer_spelling,
21517 } => {
21518 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
21520 self.write_keyword("INT64");
21521 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21522 self.write_clickhouse_type("Int32");
21523 } else {
21524 let use_integer = match self.config.dialect {
21526 Some(DialectType::TSQL)
21527 | Some(DialectType::Fabric)
21528 | Some(DialectType::Presto)
21529 | Some(DialectType::Trino)
21530 | Some(DialectType::SQLite)
21531 | Some(DialectType::Redshift) => true,
21532 Some(DialectType::Databricks) => *integer_spelling,
21534 _ => false,
21535 };
21536 if use_integer {
21537 self.write_keyword("INTEGER");
21538 } else {
21539 self.write_keyword("INT");
21540 }
21541 if let Some(n) = length {
21542 self.write(&format!("({})", n));
21543 }
21544 }
21545 }
21546 DataType::BigInt { length } => {
21547 match self.config.dialect {
21549 Some(DialectType::Oracle) => {
21550 self.write_keyword("INT");
21552 }
21553 Some(DialectType::ClickHouse) => {
21554 self.write_clickhouse_type("Int64");
21555 }
21556 _ => {
21557 self.write_keyword("BIGINT");
21558 if let Some(n) = length {
21559 self.write(&format!("({})", n));
21560 }
21561 }
21562 }
21563 }
21564 DataType::Float {
21565 precision,
21566 scale,
21567 real_spelling,
21568 } => {
21569 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21573 self.write_clickhouse_type("Float32");
21574 } else if *real_spelling
21575 && !matches!(
21576 self.config.dialect,
21577 Some(DialectType::Spark)
21578 | Some(DialectType::Databricks)
21579 | Some(DialectType::Hive)
21580 | Some(DialectType::Snowflake)
21581 | Some(DialectType::MySQL)
21582 | Some(DialectType::BigQuery)
21583 )
21584 {
21585 self.write_keyword("REAL")
21586 } else {
21587 match self.config.dialect {
21588 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
21589 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
21590 _ => self.write_keyword("FLOAT"),
21591 }
21592 }
21593 if !matches!(
21596 self.config.dialect,
21597 Some(DialectType::Spark)
21598 | Some(DialectType::Databricks)
21599 | Some(DialectType::Hive)
21600 | Some(DialectType::Presto)
21601 | Some(DialectType::Trino)
21602 ) {
21603 if let Some(p) = precision {
21604 self.write(&format!("({}", p));
21605 if let Some(s) = scale {
21606 self.write(&format!(", {})", s));
21607 } else {
21608 self.write(")");
21609 }
21610 }
21611 }
21612 }
21613 DataType::Double { precision, scale } => {
21614 match self.config.dialect {
21616 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21617 self.write_keyword("FLOAT")
21618 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
21620 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
21621 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
21622 Some(DialectType::SQLite) => self.write_keyword("REAL"),
21623 Some(DialectType::PostgreSQL)
21624 | Some(DialectType::Redshift)
21625 | Some(DialectType::Teradata)
21626 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
21627 _ => self.write_keyword("DOUBLE"),
21628 }
21629 if let Some(p) = precision {
21631 self.write(&format!("({}", p));
21632 if let Some(s) = scale {
21633 self.write(&format!(", {})", s));
21634 } else {
21635 self.write(")");
21636 }
21637 }
21638 }
21639 DataType::Decimal { precision, scale } => {
21640 match self.config.dialect {
21642 Some(DialectType::ClickHouse) => {
21643 self.write("Decimal");
21644 if let Some(p) = precision {
21645 self.write(&format!("({}", p));
21646 if let Some(s) = scale {
21647 self.write(&format!(", {}", s));
21648 }
21649 self.write(")");
21650 }
21651 }
21652 Some(DialectType::Oracle) => {
21653 self.write_keyword("NUMBER");
21655 if let Some(p) = precision {
21656 self.write(&format!("({}", p));
21657 if let Some(s) = scale {
21658 self.write(&format!(", {}", s));
21659 }
21660 self.write(")");
21661 }
21662 }
21663 Some(DialectType::BigQuery) => {
21664 self.write_keyword("NUMERIC");
21666 if let Some(p) = precision {
21667 self.write(&format!("({}", p));
21668 if let Some(s) = scale {
21669 self.write(&format!(", {}", s));
21670 }
21671 self.write(")");
21672 }
21673 }
21674 _ => {
21675 self.write_keyword("DECIMAL");
21676 if let Some(p) = precision {
21677 self.write(&format!("({}", p));
21678 if let Some(s) = scale {
21679 self.write(&format!(", {}", s));
21680 }
21681 self.write(")");
21682 }
21683 }
21684 }
21685 }
21686 DataType::Char { length } => {
21687 match self.config.dialect {
21689 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
21690 self.write_keyword("TEXT");
21692 }
21693 Some(DialectType::Hive)
21694 | Some(DialectType::Spark)
21695 | Some(DialectType::Databricks) => {
21696 if length.is_some()
21699 && !matches!(self.config.dialect, Some(DialectType::Hive))
21700 {
21701 self.write_keyword("CHAR");
21702 if let Some(n) = length {
21703 self.write(&format!("({})", n));
21704 }
21705 } else {
21706 self.write_keyword("STRING");
21707 }
21708 }
21709 Some(DialectType::Dremio) => {
21710 self.write_keyword("VARCHAR");
21712 if let Some(n) = length {
21713 self.write(&format!("({})", n));
21714 }
21715 }
21716 _ => {
21717 self.write_keyword("CHAR");
21718 if let Some(n) = length {
21719 self.write(&format!("({})", n));
21720 }
21721 }
21722 }
21723 }
21724 DataType::VarChar {
21725 length,
21726 parenthesized_length,
21727 } => {
21728 match self.config.dialect {
21730 Some(DialectType::Oracle) => {
21731 self.write_keyword("VARCHAR2");
21732 if let Some(n) = length {
21733 self.write(&format!("({})", n));
21734 }
21735 }
21736 Some(DialectType::DuckDB) => {
21737 self.write_keyword("TEXT");
21739 if let Some(n) = length {
21740 self.write(&format!("({})", n));
21741 }
21742 }
21743 Some(DialectType::SQLite) => {
21744 self.write_keyword("TEXT");
21746 if let Some(n) = length {
21747 self.write(&format!("({})", n));
21748 }
21749 }
21750 Some(DialectType::MySQL) if length.is_none() => {
21751 self.write_keyword("TEXT");
21753 }
21754 Some(DialectType::Hive)
21755 | Some(DialectType::Spark)
21756 | Some(DialectType::Databricks)
21757 if length.is_none() =>
21758 {
21759 self.write_keyword("STRING");
21761 }
21762 _ => {
21763 self.write_keyword("VARCHAR");
21764 if let Some(n) = length {
21765 if *parenthesized_length {
21767 self.write(&format!("(({}))", n));
21768 } else {
21769 self.write(&format!("({})", n));
21770 }
21771 }
21772 }
21773 }
21774 }
21775 DataType::Text => {
21776 match self.config.dialect {
21778 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
21779 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21780 self.write_keyword("VARCHAR(MAX)")
21781 }
21782 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
21783 Some(DialectType::Snowflake)
21784 | Some(DialectType::Dremio)
21785 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
21786 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
21787 Some(DialectType::Presto)
21788 | Some(DialectType::Trino)
21789 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
21790 Some(DialectType::Spark)
21791 | Some(DialectType::Databricks)
21792 | Some(DialectType::Hive) => self.write_keyword("STRING"),
21793 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
21794 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
21795 self.write_keyword("STRING")
21796 }
21797 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
21798 _ => self.write_keyword("TEXT"),
21799 }
21800 }
21801 DataType::TextWithLength { length } => {
21802 match self.config.dialect {
21804 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
21805 Some(DialectType::Hive)
21806 | Some(DialectType::Spark)
21807 | Some(DialectType::Databricks) => {
21808 self.write(&format!("VARCHAR({})", length));
21809 }
21810 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
21811 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
21812 Some(DialectType::Snowflake)
21813 | Some(DialectType::Presto)
21814 | Some(DialectType::Trino)
21815 | Some(DialectType::Athena)
21816 | Some(DialectType::Drill)
21817 | Some(DialectType::Dremio) => {
21818 self.write(&format!("VARCHAR({})", length));
21819 }
21820 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21821 self.write(&format!("VARCHAR({})", length))
21822 }
21823 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
21824 self.write(&format!("STRING({})", length))
21825 }
21826 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
21827 _ => self.write(&format!("TEXT({})", length)),
21828 }
21829 }
21830 DataType::String { length } => {
21831 match self.config.dialect {
21833 Some(DialectType::ClickHouse) => {
21834 self.write("String");
21836 if let Some(n) = length {
21837 self.write(&format!("({})", n));
21838 }
21839 }
21840 Some(DialectType::BigQuery)
21841 | Some(DialectType::Hive)
21842 | Some(DialectType::Spark)
21843 | Some(DialectType::Databricks)
21844 | Some(DialectType::StarRocks)
21845 | Some(DialectType::Doris) => {
21846 self.write_keyword("STRING");
21847 if let Some(n) = length {
21848 self.write(&format!("({})", n));
21849 }
21850 }
21851 Some(DialectType::PostgreSQL) => {
21852 if let Some(n) = length {
21854 self.write_keyword("VARCHAR");
21855 self.write(&format!("({})", n));
21856 } else {
21857 self.write_keyword("TEXT");
21858 }
21859 }
21860 Some(DialectType::Redshift) => {
21861 if let Some(n) = length {
21863 self.write_keyword("VARCHAR");
21864 self.write(&format!("({})", n));
21865 } else {
21866 self.write_keyword("VARCHAR(MAX)");
21867 }
21868 }
21869 Some(DialectType::MySQL) => {
21870 if let Some(n) = length {
21872 self.write_keyword("VARCHAR");
21873 self.write(&format!("({})", n));
21874 } else {
21875 self.write_keyword("TEXT");
21876 }
21877 }
21878 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
21879 if let Some(n) = length {
21881 self.write_keyword("VARCHAR");
21882 self.write(&format!("({})", n));
21883 } else {
21884 self.write_keyword("VARCHAR(MAX)");
21885 }
21886 }
21887 Some(DialectType::Oracle) => {
21888 self.write_keyword("CLOB");
21890 }
21891 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
21892 self.write_keyword("TEXT");
21894 if let Some(n) = length {
21895 self.write(&format!("({})", n));
21896 }
21897 }
21898 Some(DialectType::Presto)
21899 | Some(DialectType::Trino)
21900 | Some(DialectType::Drill)
21901 | Some(DialectType::Dremio) => {
21902 self.write_keyword("VARCHAR");
21904 if let Some(n) = length {
21905 self.write(&format!("({})", n));
21906 }
21907 }
21908 Some(DialectType::Snowflake) => {
21909 self.write_keyword("STRING");
21912 if let Some(n) = length {
21913 self.write(&format!("({})", n));
21914 }
21915 }
21916 _ => {
21917 self.write_keyword("STRING");
21919 if let Some(n) = length {
21920 self.write(&format!("({})", n));
21921 }
21922 }
21923 }
21924 }
21925 DataType::Binary { length } => {
21926 match self.config.dialect {
21928 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
21929 self.write_keyword("BYTEA");
21930 if let Some(n) = length {
21931 self.write(&format!("({})", n));
21932 }
21933 }
21934 Some(DialectType::Redshift) => {
21935 self.write_keyword("VARBYTE");
21936 if let Some(n) = length {
21937 self.write(&format!("({})", n));
21938 }
21939 }
21940 Some(DialectType::DuckDB)
21941 | Some(DialectType::SQLite)
21942 | Some(DialectType::Oracle) => {
21943 self.write_keyword("BLOB");
21945 if let Some(n) = length {
21946 self.write(&format!("({})", n));
21947 }
21948 }
21949 Some(DialectType::Presto)
21950 | Some(DialectType::Trino)
21951 | Some(DialectType::Athena)
21952 | Some(DialectType::Drill)
21953 | Some(DialectType::Dremio) => {
21954 self.write_keyword("VARBINARY");
21956 if let Some(n) = length {
21957 self.write(&format!("({})", n));
21958 }
21959 }
21960 Some(DialectType::ClickHouse) => {
21961 if self.clickhouse_nullable_depth < 0 {
21963 self.write("BINARY");
21964 } else {
21965 self.write("Nullable(BINARY");
21966 }
21967 if let Some(n) = length {
21968 self.write(&format!("({})", n));
21969 }
21970 if self.clickhouse_nullable_depth >= 0 {
21971 self.write(")");
21972 }
21973 }
21974 _ => {
21975 self.write_keyword("BINARY");
21976 if let Some(n) = length {
21977 self.write(&format!("({})", n));
21978 }
21979 }
21980 }
21981 }
21982 DataType::VarBinary { length } => {
21983 match self.config.dialect {
21985 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
21986 self.write_keyword("BYTEA");
21987 if let Some(n) = length {
21988 self.write(&format!("({})", n));
21989 }
21990 }
21991 Some(DialectType::Redshift) => {
21992 self.write_keyword("VARBYTE");
21993 if let Some(n) = length {
21994 self.write(&format!("({})", n));
21995 }
21996 }
21997 Some(DialectType::DuckDB)
21998 | Some(DialectType::SQLite)
21999 | Some(DialectType::Oracle) => {
22000 self.write_keyword("BLOB");
22002 if let Some(n) = length {
22003 self.write(&format!("({})", n));
22004 }
22005 }
22006 Some(DialectType::Exasol) => {
22007 self.write_keyword("VARCHAR");
22009 }
22010 Some(DialectType::Spark)
22011 | Some(DialectType::Hive)
22012 | Some(DialectType::Databricks) => {
22013 self.write_keyword("BINARY");
22015 if let Some(n) = length {
22016 self.write(&format!("({})", n));
22017 }
22018 }
22019 Some(DialectType::ClickHouse) => {
22020 self.write_clickhouse_type("String");
22022 }
22023 _ => {
22024 self.write_keyword("VARBINARY");
22025 if let Some(n) = length {
22026 self.write(&format!("({})", n));
22027 }
22028 }
22029 }
22030 }
22031 DataType::Blob => {
22032 match self.config.dialect {
22034 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
22035 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
22036 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22037 self.write_keyword("VARBINARY")
22038 }
22039 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
22040 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
22041 Some(DialectType::Presto)
22042 | Some(DialectType::Trino)
22043 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
22044 Some(DialectType::DuckDB) => {
22045 self.write_keyword("VARBINARY");
22048 }
22049 Some(DialectType::Spark)
22050 | Some(DialectType::Databricks)
22051 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
22052 Some(DialectType::ClickHouse) => {
22053 self.write("Nullable(String)");
22057 }
22058 _ => self.write_keyword("BLOB"),
22059 }
22060 }
22061 DataType::Bit { length } => {
22062 match self.config.dialect {
22064 Some(DialectType::Dremio)
22065 | Some(DialectType::Spark)
22066 | Some(DialectType::Databricks)
22067 | Some(DialectType::Hive)
22068 | Some(DialectType::Snowflake)
22069 | Some(DialectType::BigQuery)
22070 | Some(DialectType::Presto)
22071 | Some(DialectType::Trino)
22072 | Some(DialectType::ClickHouse)
22073 | Some(DialectType::Redshift) => {
22074 self.write_keyword("BOOLEAN");
22076 }
22077 _ => {
22078 self.write_keyword("BIT");
22079 if let Some(n) = length {
22080 self.write(&format!("({})", n));
22081 }
22082 }
22083 }
22084 }
22085 DataType::VarBit { length } => {
22086 self.write_keyword("VARBIT");
22087 if let Some(n) = length {
22088 self.write(&format!("({})", n));
22089 }
22090 }
22091 DataType::Date => self.write_keyword("DATE"),
22092 DataType::Time {
22093 precision,
22094 timezone,
22095 } => {
22096 if *timezone {
22097 match self.config.dialect {
22099 Some(DialectType::DuckDB) => {
22100 self.write_keyword("TIMETZ");
22102 }
22103 Some(DialectType::PostgreSQL) => {
22104 self.write_keyword("TIMETZ");
22106 if let Some(p) = precision {
22107 self.write(&format!("({})", p));
22108 }
22109 }
22110 _ => {
22111 self.write_keyword("TIME");
22113 if let Some(p) = precision {
22114 self.write(&format!("({})", p));
22115 }
22116 self.write_keyword(" WITH TIME ZONE");
22117 }
22118 }
22119 } else {
22120 if matches!(
22122 self.config.dialect,
22123 Some(DialectType::Spark)
22124 | Some(DialectType::Databricks)
22125 | Some(DialectType::Hive)
22126 ) {
22127 self.write_keyword("TIMESTAMP");
22128 } else {
22129 self.write_keyword("TIME");
22130 if let Some(p) = precision {
22131 self.write(&format!("({})", p));
22132 }
22133 }
22134 }
22135 }
22136 DataType::Timestamp {
22137 precision,
22138 timezone,
22139 } => {
22140 match self.config.dialect {
22142 Some(DialectType::ClickHouse) => {
22143 self.write("DateTime");
22144 if let Some(p) = precision {
22145 self.write(&format!("({})", p));
22146 }
22147 }
22148 Some(DialectType::TSQL) => {
22149 if *timezone {
22150 self.write_keyword("DATETIMEOFFSET");
22151 } else {
22152 self.write_keyword("DATETIME2");
22153 }
22154 if let Some(p) = precision {
22155 self.write(&format!("({})", p));
22156 }
22157 }
22158 Some(DialectType::MySQL) => {
22159 self.write_keyword("TIMESTAMP");
22161 if let Some(p) = precision {
22162 self.write(&format!("({})", p));
22163 }
22164 }
22165 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
22166 self.write_keyword("DATETIME");
22168 if let Some(p) = precision {
22169 self.write(&format!("({})", p));
22170 }
22171 }
22172 Some(DialectType::BigQuery) => {
22173 if *timezone {
22175 self.write_keyword("TIMESTAMP");
22176 } else {
22177 self.write_keyword("DATETIME");
22178 }
22179 }
22180 Some(DialectType::DuckDB) => {
22181 if *timezone {
22183 self.write_keyword("TIMESTAMPTZ");
22184 } else {
22185 self.write_keyword("TIMESTAMP");
22186 if let Some(p) = precision {
22187 self.write(&format!("({})", p));
22188 }
22189 }
22190 }
22191 _ => {
22192 if *timezone && !self.config.tz_to_with_time_zone {
22193 self.write_keyword("TIMESTAMPTZ");
22195 if let Some(p) = precision {
22196 self.write(&format!("({})", p));
22197 }
22198 } else {
22199 self.write_keyword("TIMESTAMP");
22200 if let Some(p) = precision {
22201 self.write(&format!("({})", p));
22202 }
22203 if *timezone {
22204 self.write_space();
22205 self.write_keyword("WITH TIME ZONE");
22206 }
22207 }
22208 }
22209 }
22210 }
22211 DataType::Interval { unit, to } => {
22212 self.write_keyword("INTERVAL");
22213 if let Some(u) = unit {
22214 self.write_space();
22215 self.write_keyword(u);
22216 }
22217 if let Some(t) = to {
22219 self.write_space();
22220 self.write_keyword("TO");
22221 self.write_space();
22222 self.write_keyword(t);
22223 }
22224 }
22225 DataType::Json => {
22226 match self.config.dialect {
22228 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
22231 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
22232 _ => self.write_keyword("JSON"),
22233 }
22234 }
22235 DataType::JsonB => {
22236 match self.config.dialect {
22238 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
22239 Some(DialectType::Doris) => self.write_keyword("JSONB"),
22240 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
22241 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
22242 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
22245 }
22246 DataType::Uuid => {
22247 match self.config.dialect {
22249 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
22250 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
22251 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
22252 Some(DialectType::BigQuery)
22253 | Some(DialectType::Spark)
22254 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
22255 _ => self.write_keyword("UUID"),
22256 }
22257 }
22258 DataType::Array {
22259 element_type,
22260 dimension,
22261 } => {
22262 match self.config.dialect {
22264 Some(DialectType::PostgreSQL)
22265 | Some(DialectType::Redshift)
22266 | Some(DialectType::DuckDB) => {
22267 self.generate_data_type(element_type)?;
22269 if let Some(dim) = dimension {
22270 self.write(&format!("[{}]", dim));
22271 } else {
22272 self.write("[]");
22273 }
22274 }
22275 Some(DialectType::BigQuery) => {
22276 self.write_keyword("ARRAY<");
22277 self.generate_data_type(element_type)?;
22278 self.write(">");
22279 }
22280 Some(DialectType::Snowflake)
22281 | Some(DialectType::Presto)
22282 | Some(DialectType::Trino)
22283 | Some(DialectType::ClickHouse) => {
22284 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22286 self.write("Array(");
22287 } else {
22288 self.write_keyword("ARRAY(");
22289 }
22290 self.generate_data_type(element_type)?;
22291 self.write(")");
22292 }
22293 Some(DialectType::TSQL)
22294 | Some(DialectType::MySQL)
22295 | Some(DialectType::Oracle) => {
22296 match self.config.dialect {
22299 Some(DialectType::MySQL) => self.write_keyword("JSON"),
22300 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
22301 _ => self.write_keyword("JSON"),
22302 }
22303 }
22304 _ => {
22305 self.write_keyword("ARRAY<");
22307 self.generate_data_type(element_type)?;
22308 self.write(">");
22309 }
22310 }
22311 }
22312 DataType::List { element_type } => {
22313 self.generate_data_type(element_type)?;
22315 self.write_keyword(" LIST");
22316 }
22317 DataType::Map {
22318 key_type,
22319 value_type,
22320 } => {
22321 match self.config.dialect {
22323 Some(DialectType::Materialize) => {
22324 self.write_keyword("MAP[");
22326 self.generate_data_type(key_type)?;
22327 self.write(" => ");
22328 self.generate_data_type(value_type)?;
22329 self.write("]");
22330 }
22331 Some(DialectType::Snowflake)
22332 | Some(DialectType::RisingWave)
22333 | Some(DialectType::DuckDB)
22334 | Some(DialectType::Presto)
22335 | Some(DialectType::Trino)
22336 | Some(DialectType::Athena) => {
22337 self.write_keyword("MAP(");
22338 self.generate_data_type(key_type)?;
22339 self.write(", ");
22340 self.generate_data_type(value_type)?;
22341 self.write(")");
22342 }
22343 Some(DialectType::ClickHouse) => {
22344 self.write("Map(");
22347 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
22349 self.clickhouse_nullable_depth = 0;
22350 self.write(", ");
22351 self.generate_data_type(value_type)?;
22352 self.write(")");
22353 }
22354 _ => {
22355 self.write_keyword("MAP<");
22356 self.generate_data_type(key_type)?;
22357 self.write(", ");
22358 self.generate_data_type(value_type)?;
22359 self.write(">");
22360 }
22361 }
22362 }
22363 DataType::Vector {
22364 element_type,
22365 dimension,
22366 } => {
22367 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
22368 self.write_keyword("VECTOR(");
22370 if let Some(dim) = dimension {
22371 self.write(&dim.to_string());
22372 }
22373 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
22375 DataType::TinyInt { .. } => Some("I8"),
22376 DataType::SmallInt { .. } => Some("I16"),
22377 DataType::Int { .. } => Some("I32"),
22378 DataType::BigInt { .. } => Some("I64"),
22379 DataType::Float { .. } => Some("F32"),
22380 DataType::Double { .. } => Some("F64"),
22381 _ => None,
22382 });
22383 if let Some(alias) = type_alias {
22384 if dimension.is_some() {
22385 self.write(", ");
22386 }
22387 self.write(alias);
22388 }
22389 self.write(")");
22390 } else {
22391 self.write_keyword("VECTOR(");
22393 if let Some(ref et) = element_type {
22394 self.generate_data_type(et)?;
22395 if dimension.is_some() {
22396 self.write(", ");
22397 }
22398 }
22399 if let Some(dim) = dimension {
22400 self.write(&dim.to_string());
22401 }
22402 self.write(")");
22403 }
22404 }
22405 DataType::Object { fields, modifier } => {
22406 self.write_keyword("OBJECT(");
22407 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
22408 if i > 0 {
22409 self.write(", ");
22410 }
22411 self.write(name);
22412 self.write(" ");
22413 self.generate_data_type(dt)?;
22414 if *not_null {
22415 self.write_keyword(" NOT NULL");
22416 }
22417 }
22418 self.write(")");
22419 if let Some(mod_str) = modifier {
22420 self.write(" ");
22421 self.write_keyword(mod_str);
22422 }
22423 }
22424 DataType::Struct { fields, nested } => {
22425 match self.config.dialect {
22427 Some(DialectType::Snowflake) => {
22428 self.write_keyword("OBJECT(");
22430 for (i, field) in fields.iter().enumerate() {
22431 if i > 0 {
22432 self.write(", ");
22433 }
22434 if !field.name.is_empty() {
22435 self.write(&field.name);
22436 self.write(" ");
22437 }
22438 self.generate_data_type(&field.data_type)?;
22439 }
22440 self.write(")");
22441 }
22442 Some(DialectType::Presto) | Some(DialectType::Trino) => {
22443 self.write_keyword("ROW(");
22445 for (i, field) in fields.iter().enumerate() {
22446 if i > 0 {
22447 self.write(", ");
22448 }
22449 if !field.name.is_empty() {
22450 self.write(&field.name);
22451 self.write(" ");
22452 }
22453 self.generate_data_type(&field.data_type)?;
22454 }
22455 self.write(")");
22456 }
22457 Some(DialectType::DuckDB) => {
22458 self.write_keyword("STRUCT(");
22460 for (i, field) in fields.iter().enumerate() {
22461 if i > 0 {
22462 self.write(", ");
22463 }
22464 if !field.name.is_empty() {
22465 self.write(&field.name);
22466 self.write(" ");
22467 }
22468 self.generate_data_type(&field.data_type)?;
22469 }
22470 self.write(")");
22471 }
22472 Some(DialectType::ClickHouse) => {
22473 self.write("Tuple(");
22475 for (i, field) in fields.iter().enumerate() {
22476 if i > 0 {
22477 self.write(", ");
22478 }
22479 if !field.name.is_empty() {
22480 self.write(&field.name);
22481 self.write(" ");
22482 }
22483 self.generate_data_type(&field.data_type)?;
22484 }
22485 self.write(")");
22486 }
22487 Some(DialectType::SingleStore) => {
22488 self.write_keyword("RECORD(");
22490 for (i, field) in fields.iter().enumerate() {
22491 if i > 0 {
22492 self.write(", ");
22493 }
22494 if !field.name.is_empty() {
22495 self.write(&field.name);
22496 self.write(" ");
22497 }
22498 self.generate_data_type(&field.data_type)?;
22499 }
22500 self.write(")");
22501 }
22502 _ => {
22503 let force_angle_brackets = matches!(
22505 self.config.dialect,
22506 Some(DialectType::Hive)
22507 | Some(DialectType::Spark)
22508 | Some(DialectType::Databricks)
22509 );
22510 if *nested && !force_angle_brackets {
22511 self.write_keyword("STRUCT(");
22512 for (i, field) in fields.iter().enumerate() {
22513 if i > 0 {
22514 self.write(", ");
22515 }
22516 if !field.name.is_empty() {
22517 self.write(&field.name);
22518 self.write(" ");
22519 }
22520 self.generate_data_type(&field.data_type)?;
22521 }
22522 self.write(")");
22523 } else {
22524 self.write_keyword("STRUCT<");
22525 for (i, field) in fields.iter().enumerate() {
22526 if i > 0 {
22527 self.write(", ");
22528 }
22529 if !field.name.is_empty() {
22530 self.write(&field.name);
22532 self.write(self.config.struct_field_sep);
22533 }
22534 self.generate_data_type(&field.data_type)?;
22536 if let Some(comment) = &field.comment {
22538 self.write(" COMMENT '");
22539 self.write(comment);
22540 self.write("'");
22541 }
22542 if !field.options.is_empty() {
22544 self.write(" ");
22545 self.generate_options_clause(&field.options)?;
22546 }
22547 }
22548 self.write(">");
22549 }
22550 }
22551 }
22552 }
22553 DataType::Enum {
22554 values,
22555 assignments,
22556 } => {
22557 if self.config.dialect == Some(DialectType::ClickHouse) {
22560 self.write("Enum(");
22561 } else {
22562 self.write_keyword("ENUM(");
22563 }
22564 for (i, val) in values.iter().enumerate() {
22565 if i > 0 {
22566 self.write(", ");
22567 }
22568 self.write("'");
22569 self.write(val);
22570 self.write("'");
22571 if let Some(Some(assignment)) = assignments.get(i) {
22572 self.write(" = ");
22573 self.write(assignment);
22574 }
22575 }
22576 self.write(")");
22577 }
22578 DataType::Set { values } => {
22579 self.write_keyword("SET(");
22581 for (i, val) in values.iter().enumerate() {
22582 if i > 0 {
22583 self.write(", ");
22584 }
22585 self.write("'");
22586 self.write(val);
22587 self.write("'");
22588 }
22589 self.write(")");
22590 }
22591 DataType::Union { fields } => {
22592 self.write_keyword("UNION(");
22594 for (i, (name, dt)) in fields.iter().enumerate() {
22595 if i > 0 {
22596 self.write(", ");
22597 }
22598 if !name.is_empty() {
22599 self.write(name);
22600 self.write(" ");
22601 }
22602 self.generate_data_type(dt)?;
22603 }
22604 self.write(")");
22605 }
22606 DataType::Nullable { inner } => {
22607 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22609 self.write("Nullable(");
22610 let saved_depth = self.clickhouse_nullable_depth;
22612 self.clickhouse_nullable_depth = -1;
22613 self.generate_data_type(inner)?;
22614 self.clickhouse_nullable_depth = saved_depth;
22615 self.write(")");
22616 } else {
22617 match inner.as_ref() {
22619 DataType::Custom { name } if name.to_uppercase() == "DATETIME" => {
22620 self.generate_data_type(&DataType::Timestamp {
22621 precision: None,
22622 timezone: false,
22623 })?;
22624 }
22625 _ => {
22626 self.generate_data_type(inner)?;
22627 }
22628 }
22629 }
22630 }
22631 DataType::Custom { name } => {
22632 let name_upper = name.to_uppercase();
22634 match self.config.dialect {
22635 Some(DialectType::ClickHouse) => {
22636 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
22637 (name_upper[..idx].to_string(), &name[idx..])
22638 } else {
22639 (name_upper.clone(), "")
22640 };
22641 let mapped = match base_upper.as_str() {
22642 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
22643 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
22644 "DATETIME64" => "DateTime64",
22645 "DATE32" => "Date32",
22646 "INT" => "Int32",
22647 "MEDIUMINT" => "Int32",
22648 "INT8" => "Int8",
22649 "INT16" => "Int16",
22650 "INT32" => "Int32",
22651 "INT64" => "Int64",
22652 "INT128" => "Int128",
22653 "INT256" => "Int256",
22654 "UINT8" => "UInt8",
22655 "UINT16" => "UInt16",
22656 "UINT32" => "UInt32",
22657 "UINT64" => "UInt64",
22658 "UINT128" => "UInt128",
22659 "UINT256" => "UInt256",
22660 "FLOAT32" => "Float32",
22661 "FLOAT64" => "Float64",
22662 "DECIMAL32" => "Decimal32",
22663 "DECIMAL64" => "Decimal64",
22664 "DECIMAL128" => "Decimal128",
22665 "DECIMAL256" => "Decimal256",
22666 "ENUM" => "Enum",
22667 "ENUM8" => "Enum8",
22668 "ENUM16" => "Enum16",
22669 "FIXEDSTRING" => "FixedString",
22670 "NESTED" => "Nested",
22671 "LOWCARDINALITY" => "LowCardinality",
22672 "NULLABLE" => "Nullable",
22673 "IPV4" => "IPv4",
22674 "IPV6" => "IPv6",
22675 "POINT" => "Point",
22676 "RING" => "Ring",
22677 "LINESTRING" => "LineString",
22678 "MULTILINESTRING" => "MultiLineString",
22679 "POLYGON" => "Polygon",
22680 "MULTIPOLYGON" => "MultiPolygon",
22681 "AGGREGATEFUNCTION" => "AggregateFunction",
22682 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
22683 "DYNAMIC" => "Dynamic",
22684 _ => "",
22685 };
22686 if mapped.is_empty() {
22687 self.write(name);
22688 } else {
22689 self.write(mapped);
22690 self.write(suffix);
22691 }
22692 }
22693 Some(DialectType::MySQL)
22694 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
22695 {
22696 self.write_keyword("TIMESTAMP");
22698 }
22699 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
22700 self.write_keyword("SQL_VARIANT");
22701 }
22702 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
22703 self.write_keyword("DECIMAL(38, 5)");
22704 }
22705 Some(DialectType::Exasol) => {
22706 match name_upper.as_str() {
22708 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
22710 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
22712 "MEDIUMINT" => self.write_keyword("INT"),
22714 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
22716 self.write_keyword("DECIMAL")
22717 }
22718 "DATETIME" => self.write_keyword("TIMESTAMP"),
22720 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
22721 _ => self.write(name),
22722 }
22723 }
22724 Some(DialectType::Dremio) => {
22725 match name_upper.as_str() {
22727 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
22728 "ARRAY" => self.write_keyword("LIST"),
22729 "NCHAR" => self.write_keyword("VARCHAR"),
22730 _ => self.write(name),
22731 }
22732 }
22733 _ => {
22735 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
22737 (name_upper[..idx].to_string(), Some(&name[idx..]))
22738 } else {
22739 (name_upper.clone(), None)
22740 };
22741
22742 match base_upper.as_str() {
22743 "INT64"
22744 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22745 {
22746 self.write_keyword("BIGINT");
22747 }
22748 "FLOAT64"
22749 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22750 {
22751 self.write_keyword("DOUBLE");
22752 }
22753 "BOOL"
22754 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22755 {
22756 self.write_keyword("BOOLEAN");
22757 }
22758 "BYTES"
22759 if matches!(
22760 self.config.dialect,
22761 Some(DialectType::Spark)
22762 | Some(DialectType::Hive)
22763 | Some(DialectType::Databricks)
22764 ) =>
22765 {
22766 self.write_keyword("BINARY");
22767 }
22768 "BYTES"
22769 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
22770 {
22771 self.write_keyword("VARBINARY");
22772 }
22773 "DATETIME2" | "SMALLDATETIME"
22775 if !matches!(
22776 self.config.dialect,
22777 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22778 ) =>
22779 {
22780 if matches!(
22782 self.config.dialect,
22783 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22784 ) {
22785 self.write_keyword("TIMESTAMP");
22786 if let Some(args) = _args_str {
22787 self.write(args);
22788 }
22789 } else {
22790 self.write_keyword("TIMESTAMP");
22791 }
22792 }
22793 "DATETIMEOFFSET"
22795 if !matches!(
22796 self.config.dialect,
22797 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22798 ) =>
22799 {
22800 if matches!(
22801 self.config.dialect,
22802 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22803 ) {
22804 self.write_keyword("TIMESTAMPTZ");
22805 if let Some(args) = _args_str {
22806 self.write(args);
22807 }
22808 } else {
22809 self.write_keyword("TIMESTAMPTZ");
22810 }
22811 }
22812 "UNIQUEIDENTIFIER"
22814 if !matches!(
22815 self.config.dialect,
22816 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22817 ) =>
22818 {
22819 match self.config.dialect {
22820 Some(DialectType::Spark)
22821 | Some(DialectType::Databricks)
22822 | Some(DialectType::Hive) => self.write_keyword("STRING"),
22823 _ => self.write_keyword("UUID"),
22824 }
22825 }
22826 "BIT"
22828 if !matches!(
22829 self.config.dialect,
22830 Some(DialectType::TSQL)
22831 | Some(DialectType::Fabric)
22832 | Some(DialectType::PostgreSQL)
22833 | Some(DialectType::MySQL)
22834 | Some(DialectType::DuckDB)
22835 ) =>
22836 {
22837 self.write_keyword("BOOLEAN");
22838 }
22839 "NVARCHAR"
22841 if !matches!(
22842 self.config.dialect,
22843 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22844 ) =>
22845 {
22846 match self.config.dialect {
22847 Some(DialectType::Oracle) => {
22848 self.write_keyword("NVARCHAR2");
22850 if let Some(args) = _args_str {
22851 self.write(args);
22852 }
22853 }
22854 Some(DialectType::BigQuery) => {
22855 self.write_keyword("STRING");
22857 }
22858 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
22859 self.write_keyword("TEXT");
22860 if let Some(args) = _args_str {
22861 self.write(args);
22862 }
22863 }
22864 Some(DialectType::Hive) => {
22865 self.write_keyword("STRING");
22867 }
22868 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
22869 if _args_str.is_some() {
22870 self.write_keyword("VARCHAR");
22871 self.write(_args_str.unwrap());
22872 } else {
22873 self.write_keyword("STRING");
22874 }
22875 }
22876 _ => {
22877 self.write_keyword("VARCHAR");
22878 if let Some(args) = _args_str {
22879 self.write(args);
22880 }
22881 }
22882 }
22883 }
22884 "NCHAR"
22886 if !matches!(
22887 self.config.dialect,
22888 Some(DialectType::TSQL) | Some(DialectType::Fabric)
22889 ) =>
22890 {
22891 match self.config.dialect {
22892 Some(DialectType::Oracle) => {
22893 self.write_keyword("NCHAR");
22895 if let Some(args) = _args_str {
22896 self.write(args);
22897 }
22898 }
22899 Some(DialectType::BigQuery) => {
22900 self.write_keyword("STRING");
22902 }
22903 Some(DialectType::Hive) => {
22904 self.write_keyword("STRING");
22906 }
22907 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
22908 self.write_keyword("TEXT");
22909 if let Some(args) = _args_str {
22910 self.write(args);
22911 }
22912 }
22913 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
22914 if _args_str.is_some() {
22915 self.write_keyword("CHAR");
22916 self.write(_args_str.unwrap());
22917 } else {
22918 self.write_keyword("STRING");
22919 }
22920 }
22921 _ => {
22922 self.write_keyword("CHAR");
22923 if let Some(args) = _args_str {
22924 self.write(args);
22925 }
22926 }
22927 }
22928 }
22929 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
22932 Some(DialectType::MySQL)
22933 | Some(DialectType::SingleStore)
22934 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
22935 Some(DialectType::Spark)
22936 | Some(DialectType::Databricks)
22937 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
22938 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
22939 Some(DialectType::Presto)
22940 | Some(DialectType::Trino)
22941 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
22942 Some(DialectType::Snowflake)
22943 | Some(DialectType::Redshift)
22944 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
22945 _ => self.write_keyword("TEXT"),
22946 },
22947 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
22950 Some(DialectType::MySQL)
22951 | Some(DialectType::SingleStore)
22952 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
22953 Some(DialectType::Spark)
22954 | Some(DialectType::Databricks)
22955 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
22956 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
22957 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
22958 Some(DialectType::Presto)
22959 | Some(DialectType::Trino)
22960 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
22961 Some(DialectType::Snowflake)
22962 | Some(DialectType::Redshift)
22963 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
22964 _ => self.write_keyword("BLOB"),
22965 },
22966 "LONGVARCHAR" => match self.config.dialect {
22968 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
22969 _ => self.write_keyword("VARCHAR"),
22970 },
22971 "DATETIME" => {
22973 match self.config.dialect {
22974 Some(DialectType::MySQL)
22975 | Some(DialectType::Doris)
22976 | Some(DialectType::StarRocks)
22977 | Some(DialectType::TSQL)
22978 | Some(DialectType::Fabric)
22979 | Some(DialectType::BigQuery)
22980 | Some(DialectType::SQLite)
22981 | Some(DialectType::Snowflake) => {
22982 self.write_keyword("DATETIME");
22983 if let Some(args) = _args_str {
22984 self.write(args);
22985 }
22986 }
22987 Some(_) => {
22988 self.write_keyword("TIMESTAMP");
22990 if let Some(args) = _args_str {
22991 self.write(args);
22992 }
22993 }
22994 None => {
22995 self.write(name);
22997 }
22998 }
22999 }
23000 "VARCHAR2"
23002 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
23003 {
23004 match self.config.dialect {
23005 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23006 self.write_keyword("TEXT");
23007 }
23008 Some(DialectType::Hive)
23009 | Some(DialectType::Spark)
23010 | Some(DialectType::Databricks)
23011 | Some(DialectType::BigQuery)
23012 | Some(DialectType::ClickHouse)
23013 | Some(DialectType::StarRocks)
23014 | Some(DialectType::Doris) => {
23015 self.write_keyword("STRING");
23016 }
23017 _ => {
23018 self.write_keyword("VARCHAR");
23019 if let Some(args) = _args_str {
23020 self.write(args);
23021 }
23022 }
23023 }
23024 }
23025 "NVARCHAR2"
23026 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
23027 {
23028 match self.config.dialect {
23029 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23030 self.write_keyword("TEXT");
23031 }
23032 Some(DialectType::Hive)
23033 | Some(DialectType::Spark)
23034 | Some(DialectType::Databricks)
23035 | Some(DialectType::BigQuery)
23036 | Some(DialectType::ClickHouse)
23037 | Some(DialectType::StarRocks)
23038 | Some(DialectType::Doris) => {
23039 self.write_keyword("STRING");
23040 }
23041 _ => {
23042 self.write_keyword("VARCHAR");
23043 if let Some(args) = _args_str {
23044 self.write(args);
23045 }
23046 }
23047 }
23048 }
23049 _ => self.write(name),
23050 }
23051 }
23052 }
23053 }
23054 DataType::Geometry { subtype, srid } => {
23055 match self.config.dialect {
23057 Some(DialectType::MySQL) => {
23058 if let Some(sub) = subtype {
23060 self.write_keyword(sub);
23061 if let Some(s) = srid {
23062 self.write(" SRID ");
23063 self.write(&s.to_string());
23064 }
23065 } else {
23066 self.write_keyword("GEOMETRY");
23067 }
23068 }
23069 Some(DialectType::BigQuery) => {
23070 self.write_keyword("GEOGRAPHY");
23072 }
23073 Some(DialectType::Teradata) => {
23074 self.write_keyword("ST_GEOMETRY");
23076 if subtype.is_some() || srid.is_some() {
23077 self.write("(");
23078 if let Some(sub) = subtype {
23079 self.write_keyword(sub);
23080 }
23081 if let Some(s) = srid {
23082 if subtype.is_some() {
23083 self.write(", ");
23084 }
23085 self.write(&s.to_string());
23086 }
23087 self.write(")");
23088 }
23089 }
23090 _ => {
23091 self.write_keyword("GEOMETRY");
23093 if subtype.is_some() || srid.is_some() {
23094 self.write("(");
23095 if let Some(sub) = subtype {
23096 self.write_keyword(sub);
23097 }
23098 if let Some(s) = srid {
23099 if subtype.is_some() {
23100 self.write(", ");
23101 }
23102 self.write(&s.to_string());
23103 }
23104 self.write(")");
23105 }
23106 }
23107 }
23108 }
23109 DataType::Geography { subtype, srid } => {
23110 match self.config.dialect {
23112 Some(DialectType::MySQL) => {
23113 if let Some(sub) = subtype {
23115 self.write_keyword(sub);
23116 } else {
23117 self.write_keyword("GEOMETRY");
23118 }
23119 let effective_srid = srid.unwrap_or(4326);
23121 self.write(" SRID ");
23122 self.write(&effective_srid.to_string());
23123 }
23124 Some(DialectType::BigQuery) => {
23125 self.write_keyword("GEOGRAPHY");
23127 }
23128 Some(DialectType::Snowflake) => {
23129 self.write_keyword("GEOGRAPHY");
23131 }
23132 _ => {
23133 self.write_keyword("GEOGRAPHY");
23135 if subtype.is_some() || srid.is_some() {
23136 self.write("(");
23137 if let Some(sub) = subtype {
23138 self.write_keyword(sub);
23139 }
23140 if let Some(s) = srid {
23141 if subtype.is_some() {
23142 self.write(", ");
23143 }
23144 self.write(&s.to_string());
23145 }
23146 self.write(")");
23147 }
23148 }
23149 }
23150 }
23151 DataType::CharacterSet { name } => {
23152 self.write_keyword("CHAR CHARACTER SET ");
23154 self.write(name);
23155 }
23156 _ => self.write("UNKNOWN"),
23157 }
23158 Ok(())
23159 }
23160
23161 fn write(&mut self, s: &str) {
23164 self.output.push_str(s);
23165 }
23166
23167 fn write_space(&mut self) {
23168 self.output.push(' ');
23169 }
23170
23171 fn write_keyword(&mut self, keyword: &str) {
23172 if self.config.uppercase_keywords {
23173 self.output.push_str(keyword);
23174 } else {
23175 self.output.push_str(&keyword.to_lowercase());
23176 }
23177 }
23178
23179 fn write_func_name(&mut self, name: &str) {
23181 let normalized = self.normalize_func_name(name);
23182 self.output.push_str(&normalized);
23183 }
23184
23185 fn convert_strptime_to_exasol_format(format: &str) -> String {
23189 let mut result = String::new();
23190 let chars: Vec<char> = format.chars().collect();
23191 let mut i = 0;
23192 while i < chars.len() {
23193 if chars[i] == '%' && i + 1 < chars.len() {
23194 let spec = chars[i + 1];
23195 let exasol_spec = match spec {
23196 'Y' => "YYYY",
23197 'y' => "YY",
23198 'm' => "MM",
23199 'd' => "DD",
23200 'H' => "HH",
23201 'M' => "MI",
23202 'S' => "SS",
23203 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
23215 result.push('%');
23217 result.push(spec);
23218 i += 2;
23219 continue;
23220 }
23221 };
23222 result.push_str(exasol_spec);
23223 i += 2;
23224 } else {
23225 result.push(chars[i]);
23226 i += 1;
23227 }
23228 }
23229 result
23230 }
23231
23232 fn convert_strptime_to_postgres_format(format: &str) -> String {
23236 let mut result = String::new();
23237 let chars: Vec<char> = format.chars().collect();
23238 let mut i = 0;
23239 while i < chars.len() {
23240 if chars[i] == '%' && i + 1 < chars.len() {
23241 if chars[i + 1] == '-' && i + 2 < chars.len() {
23243 let spec = chars[i + 2];
23244 let pg_spec = match spec {
23245 'd' => "FMDD",
23246 'm' => "FMMM",
23247 'H' => "FMHH24",
23248 'M' => "FMMI",
23249 'S' => "FMSS",
23250 _ => {
23251 result.push('%');
23252 result.push('-');
23253 result.push(spec);
23254 i += 3;
23255 continue;
23256 }
23257 };
23258 result.push_str(pg_spec);
23259 i += 3;
23260 continue;
23261 }
23262 let spec = chars[i + 1];
23263 let pg_spec = match spec {
23264 'Y' => "YYYY",
23265 'y' => "YY",
23266 'm' => "MM",
23267 'd' => "DD",
23268 'H' => "HH24",
23269 'I' => "HH12",
23270 'M' => "MI",
23271 'S' => "SS",
23272 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
23283 result.push('%');
23285 result.push(spec);
23286 i += 2;
23287 continue;
23288 }
23289 };
23290 result.push_str(pg_spec);
23291 i += 2;
23292 } else {
23293 result.push(chars[i]);
23294 i += 1;
23295 }
23296 }
23297 result
23298 }
23299
23300 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
23302 if self.config.limit_only_literals {
23303 if let Some(value) = Self::try_evaluate_constant(expr) {
23304 self.write(&value.to_string());
23305 return Ok(());
23306 }
23307 }
23308 self.generate_expression(expr)
23309 }
23310
23311 fn write_formatted_comment(&mut self, comment: &str) {
23315 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
23318 &comment[2..comment.len() - 2]
23321 } else if comment.starts_with("--") {
23322 &comment[2..]
23325 } else {
23326 comment
23328 };
23329 if content.trim().is_empty() {
23331 return;
23332 }
23333 self.output.push_str("/*");
23335 if !content.starts_with(' ') {
23336 self.output.push(' ');
23337 }
23338 self.output.push_str(content);
23339 if !content.ends_with(' ') {
23340 self.output.push(' ');
23341 }
23342 self.output.push_str("*/");
23343 }
23344
23345 fn escape_block_for_single_quote(&self, block: &str) -> String {
23348 let escape_backslash = matches!(
23349 self.config.dialect,
23350 Some(crate::dialects::DialectType::Snowflake)
23351 );
23352 let mut escaped = String::with_capacity(block.len() + 4);
23353 for ch in block.chars() {
23354 if ch == '\'' {
23355 escaped.push('\\');
23356 escaped.push('\'');
23357 } else if escape_backslash && ch == '\\' {
23358 escaped.push('\\');
23359 escaped.push('\\');
23360 } else {
23361 escaped.push(ch);
23362 }
23363 }
23364 escaped
23365 }
23366
23367 fn write_newline(&mut self) {
23368 self.output.push('\n');
23369 }
23370
23371 fn write_indent(&mut self) {
23372 for _ in 0..self.indent_level {
23373 self.output.push_str(&self.config.indent);
23374 }
23375 }
23376
23377 fn too_wide(&self, args: &[String]) -> bool {
23383 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
23384 }
23385
23386 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
23389 let config = GeneratorConfig {
23390 pretty: false,
23391 dialect: self.config.dialect,
23392 ..Default::default()
23393 };
23394 let mut gen = Generator::with_config(config);
23395 gen.generate_expression(expr)?;
23396 Ok(gen.output)
23397 }
23398
23399 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
23402 if self.config.pretty {
23403 self.write_newline();
23404 self.write_indent();
23405 self.write_keyword(keyword);
23406 self.write_newline();
23407 self.indent_level += 1;
23408 self.write_indent();
23409 self.generate_expression(condition)?;
23410 self.indent_level -= 1;
23411 } else {
23412 self.write_space();
23413 self.write_keyword(keyword);
23414 self.write_space();
23415 self.generate_expression(condition)?;
23416 }
23417 Ok(())
23418 }
23419
23420 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
23423 if exprs.is_empty() {
23424 return Ok(());
23425 }
23426
23427 if self.config.pretty {
23428 self.write_newline();
23429 self.write_indent();
23430 self.write_keyword(keyword);
23431 self.write_newline();
23432 self.indent_level += 1;
23433 for (i, expr) in exprs.iter().enumerate() {
23434 if i > 0 {
23435 self.write(",");
23436 self.write_newline();
23437 }
23438 self.write_indent();
23439 self.generate_expression(expr)?;
23440 }
23441 self.indent_level -= 1;
23442 } else {
23443 self.write_space();
23444 self.write_keyword(keyword);
23445 self.write_space();
23446 for (i, expr) in exprs.iter().enumerate() {
23447 if i > 0 {
23448 self.write(", ");
23449 }
23450 self.generate_expression(expr)?;
23451 }
23452 }
23453 Ok(())
23454 }
23455
23456 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
23458 if orderings.is_empty() {
23459 return Ok(());
23460 }
23461
23462 if self.config.pretty {
23463 self.write_newline();
23464 self.write_indent();
23465 self.write_keyword(keyword);
23466 self.write_newline();
23467 self.indent_level += 1;
23468 for (i, ordered) in orderings.iter().enumerate() {
23469 if i > 0 {
23470 self.write(",");
23471 self.write_newline();
23472 }
23473 self.write_indent();
23474 self.generate_ordered(ordered)?;
23475 }
23476 self.indent_level -= 1;
23477 } else {
23478 self.write_space();
23479 self.write_keyword(keyword);
23480 self.write_space();
23481 for (i, ordered) in orderings.iter().enumerate() {
23482 if i > 0 {
23483 self.write(", ");
23484 }
23485 self.generate_ordered(ordered)?;
23486 }
23487 }
23488 Ok(())
23489 }
23490
23491 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
23493 if windows.is_empty() {
23494 return Ok(());
23495 }
23496
23497 if self.config.pretty {
23498 self.write_newline();
23499 self.write_indent();
23500 self.write_keyword("WINDOW");
23501 self.write_newline();
23502 self.indent_level += 1;
23503 for (i, named_window) in windows.iter().enumerate() {
23504 if i > 0 {
23505 self.write(",");
23506 self.write_newline();
23507 }
23508 self.write_indent();
23509 self.generate_identifier(&named_window.name)?;
23510 self.write_space();
23511 self.write_keyword("AS");
23512 self.write(" (");
23513 self.generate_over(&named_window.spec)?;
23514 self.write(")");
23515 }
23516 self.indent_level -= 1;
23517 } else {
23518 self.write_space();
23519 self.write_keyword("WINDOW");
23520 self.write_space();
23521 for (i, named_window) in windows.iter().enumerate() {
23522 if i > 0 {
23523 self.write(", ");
23524 }
23525 self.generate_identifier(&named_window.name)?;
23526 self.write_space();
23527 self.write_keyword("AS");
23528 self.write(" (");
23529 self.generate_over(&named_window.spec)?;
23530 self.write(")");
23531 }
23532 }
23533 Ok(())
23534 }
23535
23536 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
23538 self.write_keyword("AI_AGG");
23540 self.write("(");
23541 self.generate_expression(&e.this)?;
23542 self.write(", ");
23543 self.generate_expression(&e.expression)?;
23544 self.write(")");
23545 Ok(())
23546 }
23547
23548 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
23549 self.write_keyword("AI_CLASSIFY");
23551 self.write("(");
23552 self.generate_expression(&e.this)?;
23553 if let Some(categories) = &e.categories {
23554 self.write(", ");
23555 self.generate_expression(categories)?;
23556 }
23557 if let Some(config) = &e.config {
23558 self.write(", ");
23559 self.generate_expression(config)?;
23560 }
23561 self.write(")");
23562 Ok(())
23563 }
23564
23565 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
23566 self.write_keyword("ADD");
23568 self.write_space();
23569 if e.exists {
23570 self.write_keyword("IF NOT EXISTS");
23571 self.write_space();
23572 }
23573 self.generate_expression(&e.this)?;
23574 if let Some(location) = &e.location {
23575 self.write_space();
23576 self.generate_expression(location)?;
23577 }
23578 Ok(())
23579 }
23580
23581 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
23582 self.write_keyword("ALGORITHM");
23584 self.write("=");
23585 self.generate_expression(&e.this)?;
23586 Ok(())
23587 }
23588
23589 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
23590 self.generate_expression(&e.this)?;
23592 self.write_space();
23593 self.write_keyword("AS");
23594 self.write(" (");
23595 for (i, expr) in e.expressions.iter().enumerate() {
23596 if i > 0 {
23597 self.write(", ");
23598 }
23599 self.generate_expression(expr)?;
23600 }
23601 self.write(")");
23602 Ok(())
23603 }
23604
23605 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
23606 self.write_keyword("ALLOWED_VALUES");
23608 self.write_space();
23609 for (i, expr) in e.expressions.iter().enumerate() {
23610 if i > 0 {
23611 self.write(", ");
23612 }
23613 self.generate_expression(expr)?;
23614 }
23615 Ok(())
23616 }
23617
23618 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
23619 self.write_keyword("ALTER COLUMN");
23621 self.write_space();
23622 self.generate_expression(&e.this)?;
23623
23624 if let Some(dtype) = &e.dtype {
23625 self.write_space();
23626 self.write_keyword("SET DATA TYPE");
23627 self.write_space();
23628 self.generate_expression(dtype)?;
23629 if let Some(collate) = &e.collate {
23630 self.write_space();
23631 self.write_keyword("COLLATE");
23632 self.write_space();
23633 self.generate_expression(collate)?;
23634 }
23635 if let Some(using) = &e.using {
23636 self.write_space();
23637 self.write_keyword("USING");
23638 self.write_space();
23639 self.generate_expression(using)?;
23640 }
23641 } else if let Some(default) = &e.default {
23642 self.write_space();
23643 self.write_keyword("SET DEFAULT");
23644 self.write_space();
23645 self.generate_expression(default)?;
23646 } else if let Some(comment) = &e.comment {
23647 self.write_space();
23648 self.write_keyword("COMMENT");
23649 self.write_space();
23650 self.generate_expression(comment)?;
23651 } else if let Some(drop) = &e.drop {
23652 self.write_space();
23653 self.write_keyword("DROP");
23654 self.write_space();
23655 self.generate_expression(drop)?;
23656 } else if let Some(visible) = &e.visible {
23657 self.write_space();
23658 self.generate_expression(visible)?;
23659 } else if let Some(rename_to) = &e.rename_to {
23660 self.write_space();
23661 self.write_keyword("RENAME TO");
23662 self.write_space();
23663 self.generate_expression(rename_to)?;
23664 } else if let Some(allow_null) = &e.allow_null {
23665 self.write_space();
23666 self.generate_expression(allow_null)?;
23667 }
23668 Ok(())
23669 }
23670
23671 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
23672 self.write_keyword("ALTER SESSION");
23674 self.write_space();
23675 if e.unset.is_some() {
23676 self.write_keyword("UNSET");
23677 } else {
23678 self.write_keyword("SET");
23679 }
23680 self.write_space();
23681 for (i, expr) in e.expressions.iter().enumerate() {
23682 if i > 0 {
23683 self.write(", ");
23684 }
23685 self.generate_expression(expr)?;
23686 }
23687 Ok(())
23688 }
23689
23690 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
23691 self.write_keyword("SET");
23693
23694 if let Some(opt) = &e.option {
23696 self.write_space();
23697 self.generate_expression(opt)?;
23698 }
23699
23700 if !e.expressions.is_empty() {
23703 let is_properties = e
23705 .expressions
23706 .iter()
23707 .any(|expr| matches!(expr, Expression::Eq(_)));
23708 if is_properties && e.option.is_none() {
23709 self.write_space();
23710 self.write_keyword("PROPERTIES");
23711 }
23712 self.write_space();
23713 for (i, expr) in e.expressions.iter().enumerate() {
23714 if i > 0 {
23715 self.write(", ");
23716 }
23717 self.generate_expression(expr)?;
23718 }
23719 }
23720
23721 if let Some(file_format) = &e.file_format {
23723 self.write(" ");
23724 self.write_keyword("STAGE_FILE_FORMAT");
23725 self.write(" = (");
23726 self.generate_space_separated_properties(file_format)?;
23727 self.write(")");
23728 }
23729
23730 if let Some(copy_options) = &e.copy_options {
23732 self.write(" ");
23733 self.write_keyword("STAGE_COPY_OPTIONS");
23734 self.write(" = (");
23735 self.generate_space_separated_properties(copy_options)?;
23736 self.write(")");
23737 }
23738
23739 if let Some(tag) = &e.tag {
23741 self.write(" ");
23742 self.write_keyword("TAG");
23743 self.write(" ");
23744 self.generate_expression(tag)?;
23745 }
23746
23747 Ok(())
23748 }
23749
23750 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
23752 match expr {
23753 Expression::Tuple(t) => {
23754 for (i, prop) in t.expressions.iter().enumerate() {
23755 if i > 0 {
23756 self.write(" ");
23757 }
23758 self.generate_expression(prop)?;
23759 }
23760 }
23761 _ => {
23762 self.generate_expression(expr)?;
23763 }
23764 }
23765 Ok(())
23766 }
23767
23768 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
23769 self.write_keyword("ALTER");
23771 if e.compound.is_some() {
23772 self.write_space();
23773 self.write_keyword("COMPOUND");
23774 }
23775 self.write_space();
23776 self.write_keyword("SORTKEY");
23777 self.write_space();
23778 if let Some(this) = &e.this {
23779 self.generate_expression(this)?;
23780 } else if !e.expressions.is_empty() {
23781 self.write("(");
23782 for (i, expr) in e.expressions.iter().enumerate() {
23783 if i > 0 {
23784 self.write(", ");
23785 }
23786 self.generate_expression(expr)?;
23787 }
23788 self.write(")");
23789 }
23790 Ok(())
23791 }
23792
23793 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
23794 self.write_keyword("ANALYZE");
23796 if !e.options.is_empty() {
23797 self.write_space();
23798 for (i, opt) in e.options.iter().enumerate() {
23799 if i > 0 {
23800 self.write_space();
23801 }
23802 if let Expression::Identifier(id) = opt {
23804 self.write_keyword(&id.name);
23805 } else {
23806 self.generate_expression(opt)?;
23807 }
23808 }
23809 }
23810 if let Some(kind) = &e.kind {
23811 self.write_space();
23812 self.write_keyword(kind);
23813 }
23814 if let Some(this) = &e.this {
23815 self.write_space();
23816 self.generate_expression(this)?;
23817 }
23818 if !e.columns.is_empty() {
23820 self.write("(");
23821 for (i, col) in e.columns.iter().enumerate() {
23822 if i > 0 {
23823 self.write(", ");
23824 }
23825 self.write(col);
23826 }
23827 self.write(")");
23828 }
23829 if let Some(partition) = &e.partition {
23830 self.write_space();
23831 self.generate_expression(partition)?;
23832 }
23833 if let Some(mode) = &e.mode {
23834 self.write_space();
23835 self.generate_expression(mode)?;
23836 }
23837 if let Some(expression) = &e.expression {
23838 self.write_space();
23839 self.generate_expression(expression)?;
23840 }
23841 if !e.properties.is_empty() {
23842 self.write_space();
23843 self.write_keyword(self.config.with_properties_prefix);
23844 self.write(" (");
23845 for (i, prop) in e.properties.iter().enumerate() {
23846 if i > 0 {
23847 self.write(", ");
23848 }
23849 self.generate_expression(prop)?;
23850 }
23851 self.write(")");
23852 }
23853 Ok(())
23854 }
23855
23856 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
23857 self.write_keyword("DELETE");
23859 if let Some(kind) = &e.kind {
23860 self.write_space();
23861 self.write_keyword(kind);
23862 }
23863 self.write_space();
23864 self.write_keyword("STATISTICS");
23865 Ok(())
23866 }
23867
23868 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
23869 if let Expression::Identifier(id) = e.this.as_ref() {
23872 self.write_keyword(&id.name);
23873 } else {
23874 self.generate_expression(&e.this)?;
23875 }
23876 self.write_space();
23877 self.write_keyword("HISTOGRAM ON");
23878 self.write_space();
23879 for (i, expr) in e.expressions.iter().enumerate() {
23880 if i > 0 {
23881 self.write(", ");
23882 }
23883 self.generate_expression(expr)?;
23884 }
23885 if let Some(expression) = &e.expression {
23886 self.write_space();
23887 self.generate_expression(expression)?;
23888 }
23889 if let Some(update_options) = &e.update_options {
23890 self.write_space();
23891 self.generate_expression(update_options)?;
23892 self.write_space();
23893 self.write_keyword("UPDATE");
23894 }
23895 Ok(())
23896 }
23897
23898 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
23899 self.write_keyword("LIST CHAINED ROWS");
23901 if let Some(expression) = &e.expression {
23902 self.write_space();
23903 self.write_keyword("INTO");
23904 self.write_space();
23905 self.generate_expression(expression)?;
23906 }
23907 Ok(())
23908 }
23909
23910 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
23911 self.write_keyword("SAMPLE");
23913 self.write_space();
23914 if let Some(sample) = &e.sample {
23915 self.generate_expression(sample)?;
23916 self.write_space();
23917 }
23918 self.write_keyword(&e.kind);
23919 Ok(())
23920 }
23921
23922 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
23923 self.write_keyword(&e.kind);
23925 if let Some(option) = &e.option {
23926 self.write_space();
23927 self.generate_expression(option)?;
23928 }
23929 self.write_space();
23930 self.write_keyword("STATISTICS");
23931 if let Some(this) = &e.this {
23932 self.write_space();
23933 self.generate_expression(this)?;
23934 }
23935 if !e.expressions.is_empty() {
23936 self.write_space();
23937 for (i, expr) in e.expressions.iter().enumerate() {
23938 if i > 0 {
23939 self.write(", ");
23940 }
23941 self.generate_expression(expr)?;
23942 }
23943 }
23944 Ok(())
23945 }
23946
23947 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
23948 self.write_keyword("VALIDATE");
23950 self.write_space();
23951 self.write_keyword(&e.kind);
23952 if let Some(this) = &e.this {
23953 self.write_space();
23954 if let Expression::Identifier(id) = this.as_ref() {
23956 self.write_keyword(&id.name);
23957 } else {
23958 self.generate_expression(this)?;
23959 }
23960 }
23961 if let Some(expression) = &e.expression {
23962 self.write_space();
23963 self.write_keyword("INTO");
23964 self.write_space();
23965 self.generate_expression(expression)?;
23966 }
23967 Ok(())
23968 }
23969
23970 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
23971 self.write_keyword("WITH");
23973 self.write_space();
23974 for (i, expr) in e.expressions.iter().enumerate() {
23975 if i > 0 {
23976 self.write(", ");
23977 }
23978 self.generate_expression(expr)?;
23979 }
23980 Ok(())
23981 }
23982
23983 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
23984 self.generate_expression(&e.this)?;
23987 self.write("(");
23988 for (i, arg) in e.expressions.iter().enumerate() {
23989 if i > 0 {
23990 self.write(", ");
23991 }
23992 self.generate_expression(arg)?;
23993 }
23994 self.write(")");
23995 Ok(())
23996 }
23997
23998 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
23999 self.generate_expression(&e.this)?;
24001 self.write("(");
24002 for (i, arg) in e.expressions.iter().enumerate() {
24003 if i > 0 {
24004 self.write(", ");
24005 }
24006 self.generate_expression(arg)?;
24007 }
24008 self.write(")");
24009 Ok(())
24010 }
24011
24012 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
24013 self.generate_expression(&e.this)?;
24015 self.write_space();
24016 self.write_keyword("APPLY");
24017 self.write("(");
24018 self.generate_expression(&e.expression)?;
24019 self.write(")");
24020 Ok(())
24021 }
24022
24023 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
24024 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
24026 self.write("(");
24027 self.generate_expression(&e.this)?;
24028 if let Some(percentile) = &e.percentile {
24029 self.write(", ");
24030 self.generate_expression(percentile)?;
24031 }
24032 self.write(")");
24033 Ok(())
24034 }
24035
24036 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
24037 self.write_keyword("APPROX_QUANTILE");
24039 self.write("(");
24040 self.generate_expression(&e.this)?;
24041 if let Some(quantile) = &e.quantile {
24042 self.write(", ");
24043 self.generate_expression(quantile)?;
24044 }
24045 if let Some(accuracy) = &e.accuracy {
24046 self.write(", ");
24047 self.generate_expression(accuracy)?;
24048 }
24049 if let Some(weight) = &e.weight {
24050 self.write(", ");
24051 self.generate_expression(weight)?;
24052 }
24053 self.write(")");
24054 Ok(())
24055 }
24056
24057 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
24058 self.write_keyword("APPROX_QUANTILES");
24060 self.write("(");
24061 self.generate_expression(&e.this)?;
24062 if let Some(expression) = &e.expression {
24063 self.write(", ");
24064 self.generate_expression(expression)?;
24065 }
24066 self.write(")");
24067 Ok(())
24068 }
24069
24070 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
24071 self.write_keyword("APPROX_TOP_K");
24073 self.write("(");
24074 self.generate_expression(&e.this)?;
24075 if let Some(expression) = &e.expression {
24076 self.write(", ");
24077 self.generate_expression(expression)?;
24078 }
24079 if let Some(counters) = &e.counters {
24080 self.write(", ");
24081 self.generate_expression(counters)?;
24082 }
24083 self.write(")");
24084 Ok(())
24085 }
24086
24087 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
24088 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
24090 self.write("(");
24091 self.generate_expression(&e.this)?;
24092 if let Some(expression) = &e.expression {
24093 self.write(", ");
24094 self.generate_expression(expression)?;
24095 }
24096 self.write(")");
24097 Ok(())
24098 }
24099
24100 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
24101 self.write_keyword("APPROX_TOP_K_COMBINE");
24103 self.write("(");
24104 self.generate_expression(&e.this)?;
24105 if let Some(expression) = &e.expression {
24106 self.write(", ");
24107 self.generate_expression(expression)?;
24108 }
24109 self.write(")");
24110 Ok(())
24111 }
24112
24113 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
24114 self.write_keyword("APPROX_TOP_K_ESTIMATE");
24116 self.write("(");
24117 self.generate_expression(&e.this)?;
24118 if let Some(expression) = &e.expression {
24119 self.write(", ");
24120 self.generate_expression(expression)?;
24121 }
24122 self.write(")");
24123 Ok(())
24124 }
24125
24126 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
24127 self.write_keyword("APPROX_TOP_SUM");
24129 self.write("(");
24130 self.generate_expression(&e.this)?;
24131 self.write(", ");
24132 self.generate_expression(&e.expression)?;
24133 if let Some(count) = &e.count {
24134 self.write(", ");
24135 self.generate_expression(count)?;
24136 }
24137 self.write(")");
24138 Ok(())
24139 }
24140
24141 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
24142 self.write_keyword("ARG_MAX");
24144 self.write("(");
24145 self.generate_expression(&e.this)?;
24146 self.write(", ");
24147 self.generate_expression(&e.expression)?;
24148 if let Some(count) = &e.count {
24149 self.write(", ");
24150 self.generate_expression(count)?;
24151 }
24152 self.write(")");
24153 Ok(())
24154 }
24155
24156 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
24157 self.write_keyword("ARG_MIN");
24159 self.write("(");
24160 self.generate_expression(&e.this)?;
24161 self.write(", ");
24162 self.generate_expression(&e.expression)?;
24163 if let Some(count) = &e.count {
24164 self.write(", ");
24165 self.generate_expression(count)?;
24166 }
24167 self.write(")");
24168 Ok(())
24169 }
24170
24171 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
24172 self.write_keyword("ARRAY_ALL");
24174 self.write("(");
24175 self.generate_expression(&e.this)?;
24176 self.write(", ");
24177 self.generate_expression(&e.expression)?;
24178 self.write(")");
24179 Ok(())
24180 }
24181
24182 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
24183 self.write_keyword("ARRAY_ANY");
24185 self.write("(");
24186 self.generate_expression(&e.this)?;
24187 self.write(", ");
24188 self.generate_expression(&e.expression)?;
24189 self.write(")");
24190 Ok(())
24191 }
24192
24193 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
24194 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
24196 self.write("(");
24197 for (i, expr) in e.expressions.iter().enumerate() {
24198 if i > 0 {
24199 self.write(", ");
24200 }
24201 self.generate_expression(expr)?;
24202 }
24203 self.write(")");
24204 Ok(())
24205 }
24206
24207 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
24208 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24210 self.write("arraySum");
24211 } else {
24212 self.write_keyword("ARRAY_SUM");
24213 }
24214 self.write("(");
24215 self.generate_expression(&e.this)?;
24216 if let Some(expression) = &e.expression {
24217 self.write(", ");
24218 self.generate_expression(expression)?;
24219 }
24220 self.write(")");
24221 Ok(())
24222 }
24223
24224 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
24225 self.generate_expression(&e.this)?;
24227 self.write_space();
24228 self.write_keyword("AT");
24229 self.write_space();
24230 self.generate_expression(&e.expression)?;
24231 Ok(())
24232 }
24233
24234 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
24235 self.write_keyword("ATTACH");
24237 if e.exists {
24238 self.write_space();
24239 self.write_keyword("IF NOT EXISTS");
24240 }
24241 self.write_space();
24242 self.generate_expression(&e.this)?;
24243 if !e.expressions.is_empty() {
24244 self.write(" (");
24245 for (i, expr) in e.expressions.iter().enumerate() {
24246 if i > 0 {
24247 self.write(", ");
24248 }
24249 self.generate_expression(expr)?;
24250 }
24251 self.write(")");
24252 }
24253 Ok(())
24254 }
24255
24256 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
24257 self.generate_expression(&e.this)?;
24260 if let Some(expression) = &e.expression {
24261 self.write_space();
24262 self.generate_expression(expression)?;
24263 }
24264 Ok(())
24265 }
24266
24267 fn generate_auto_increment_keyword(
24271 &mut self,
24272 col: &crate::expressions::ColumnDef,
24273 ) -> Result<()> {
24274 use crate::dialects::DialectType;
24275 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
24276 self.write_keyword("IDENTITY");
24277 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24278 self.write("(");
24279 if let Some(ref start) = col.auto_increment_start {
24280 self.generate_expression(start)?;
24281 } else {
24282 self.write("0");
24283 }
24284 self.write(", ");
24285 if let Some(ref inc) = col.auto_increment_increment {
24286 self.generate_expression(inc)?;
24287 } else {
24288 self.write("1");
24289 }
24290 self.write(")");
24291 }
24292 } else if matches!(
24293 self.config.dialect,
24294 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
24295 ) {
24296 self.write_keyword("AUTOINCREMENT");
24297 if let Some(ref start) = col.auto_increment_start {
24298 self.write_space();
24299 self.write_keyword("START");
24300 self.write_space();
24301 self.generate_expression(start)?;
24302 }
24303 if let Some(ref inc) = col.auto_increment_increment {
24304 self.write_space();
24305 self.write_keyword("INCREMENT");
24306 self.write_space();
24307 self.generate_expression(inc)?;
24308 }
24309 if let Some(order) = col.auto_increment_order {
24310 self.write_space();
24311 if order {
24312 self.write_keyword("ORDER");
24313 } else {
24314 self.write_keyword("NOORDER");
24315 }
24316 }
24317 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
24318 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
24319 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24320 self.write(" (");
24321 let mut first = true;
24322 if let Some(ref start) = col.auto_increment_start {
24323 self.write_keyword("START WITH");
24324 self.write_space();
24325 self.generate_expression(start)?;
24326 first = false;
24327 }
24328 if let Some(ref inc) = col.auto_increment_increment {
24329 if !first {
24330 self.write_space();
24331 }
24332 self.write_keyword("INCREMENT BY");
24333 self.write_space();
24334 self.generate_expression(inc)?;
24335 }
24336 self.write(")");
24337 }
24338 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
24339 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
24340 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24341 self.write(" (");
24342 let mut first = true;
24343 if let Some(ref start) = col.auto_increment_start {
24344 self.write_keyword("START WITH");
24345 self.write_space();
24346 self.generate_expression(start)?;
24347 first = false;
24348 }
24349 if let Some(ref inc) = col.auto_increment_increment {
24350 if !first {
24351 self.write_space();
24352 }
24353 self.write_keyword("INCREMENT BY");
24354 self.write_space();
24355 self.generate_expression(inc)?;
24356 }
24357 self.write(")");
24358 }
24359 } else if matches!(
24360 self.config.dialect,
24361 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24362 ) {
24363 self.write_keyword("IDENTITY");
24364 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
24365 self.write("(");
24366 if let Some(ref start) = col.auto_increment_start {
24367 self.generate_expression(start)?;
24368 } else {
24369 self.write("0");
24370 }
24371 self.write(", ");
24372 if let Some(ref inc) = col.auto_increment_increment {
24373 self.generate_expression(inc)?;
24374 } else {
24375 self.write("1");
24376 }
24377 self.write(")");
24378 }
24379 } else {
24380 self.write_keyword("AUTO_INCREMENT");
24381 if let Some(ref start) = col.auto_increment_start {
24382 self.write_space();
24383 self.write_keyword("START");
24384 self.write_space();
24385 self.generate_expression(start)?;
24386 }
24387 if let Some(ref inc) = col.auto_increment_increment {
24388 self.write_space();
24389 self.write_keyword("INCREMENT");
24390 self.write_space();
24391 self.generate_expression(inc)?;
24392 }
24393 if let Some(order) = col.auto_increment_order {
24394 self.write_space();
24395 if order {
24396 self.write_keyword("ORDER");
24397 } else {
24398 self.write_keyword("NOORDER");
24399 }
24400 }
24401 }
24402 Ok(())
24403 }
24404
24405 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
24406 self.write_keyword("AUTO_INCREMENT");
24408 self.write("=");
24409 self.generate_expression(&e.this)?;
24410 Ok(())
24411 }
24412
24413 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
24414 self.write_keyword("AUTO_REFRESH");
24416 self.write("=");
24417 self.generate_expression(&e.this)?;
24418 Ok(())
24419 }
24420
24421 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
24422 self.write_keyword("BACKUP");
24424 self.write_space();
24425 self.generate_expression(&e.this)?;
24426 Ok(())
24427 }
24428
24429 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
24430 self.write_keyword("BASE64_DECODE_BINARY");
24432 self.write("(");
24433 self.generate_expression(&e.this)?;
24434 if let Some(alphabet) = &e.alphabet {
24435 self.write(", ");
24436 self.generate_expression(alphabet)?;
24437 }
24438 self.write(")");
24439 Ok(())
24440 }
24441
24442 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
24443 self.write_keyword("BASE64_DECODE_STRING");
24445 self.write("(");
24446 self.generate_expression(&e.this)?;
24447 if let Some(alphabet) = &e.alphabet {
24448 self.write(", ");
24449 self.generate_expression(alphabet)?;
24450 }
24451 self.write(")");
24452 Ok(())
24453 }
24454
24455 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
24456 self.write_keyword("BASE64_ENCODE");
24458 self.write("(");
24459 self.generate_expression(&e.this)?;
24460 if let Some(max_line_length) = &e.max_line_length {
24461 self.write(", ");
24462 self.generate_expression(max_line_length)?;
24463 }
24464 if let Some(alphabet) = &e.alphabet {
24465 self.write(", ");
24466 self.generate_expression(alphabet)?;
24467 }
24468 self.write(")");
24469 Ok(())
24470 }
24471
24472 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
24473 self.write_keyword("BLOCKCOMPRESSION");
24475 self.write("=");
24476 if let Some(autotemp) = &e.autotemp {
24477 self.write_keyword("AUTOTEMP");
24478 self.write("(");
24479 self.generate_expression(autotemp)?;
24480 self.write(")");
24481 }
24482 if let Some(always) = &e.always {
24483 self.generate_expression(always)?;
24484 }
24485 if let Some(default) = &e.default {
24486 self.generate_expression(default)?;
24487 }
24488 if let Some(manual) = &e.manual {
24489 self.generate_expression(manual)?;
24490 }
24491 if let Some(never) = &e.never {
24492 self.generate_expression(never)?;
24493 }
24494 Ok(())
24495 }
24496
24497 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
24498 self.write("((");
24500 self.generate_expression(&e.this)?;
24501 self.write(") ");
24502 self.write_keyword("AND");
24503 self.write(" (");
24504 self.generate_expression(&e.expression)?;
24505 self.write("))");
24506 Ok(())
24507 }
24508
24509 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
24510 self.write("((");
24512 self.generate_expression(&e.this)?;
24513 self.write(") ");
24514 self.write_keyword("OR");
24515 self.write(" (");
24516 self.generate_expression(&e.expression)?;
24517 self.write("))");
24518 Ok(())
24519 }
24520
24521 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
24522 self.write_keyword("BUILD");
24524 self.write_space();
24525 self.generate_expression(&e.this)?;
24526 Ok(())
24527 }
24528
24529 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
24530 self.generate_expression(&e.this)?;
24532 Ok(())
24533 }
24534
24535 fn generate_case_specific_column_constraint(
24536 &mut self,
24537 e: &CaseSpecificColumnConstraint,
24538 ) -> Result<()> {
24539 if e.not_.is_some() {
24541 self.write_keyword("NOT");
24542 self.write_space();
24543 }
24544 self.write_keyword("CASESPECIFIC");
24545 Ok(())
24546 }
24547
24548 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
24549 self.write_keyword("CAST");
24551 self.write("(");
24552 self.generate_expression(&e.this)?;
24553 if self.config.dialect == Some(DialectType::ClickHouse) {
24554 self.write(", ");
24556 } else {
24557 self.write_space();
24558 self.write_keyword("AS");
24559 self.write_space();
24560 }
24561 if let Some(to) = &e.to {
24562 self.generate_expression(to)?;
24563 }
24564 self.write(")");
24565 Ok(())
24566 }
24567
24568 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
24569 self.write_keyword("CHANGES");
24572 self.write(" (");
24573 if let Some(information) = &e.information {
24574 self.write_keyword("INFORMATION");
24575 self.write(" => ");
24576 self.generate_expression(information)?;
24577 }
24578 self.write(")");
24579 if let Some(at_before) = &e.at_before {
24581 self.write(" ");
24582 self.generate_expression(at_before)?;
24583 }
24584 if let Some(end) = &e.end {
24585 self.write(" ");
24586 self.generate_expression(end)?;
24587 }
24588 Ok(())
24589 }
24590
24591 fn generate_character_set_column_constraint(
24592 &mut self,
24593 e: &CharacterSetColumnConstraint,
24594 ) -> Result<()> {
24595 self.write_keyword("CHARACTER SET");
24597 self.write_space();
24598 self.generate_expression(&e.this)?;
24599 Ok(())
24600 }
24601
24602 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
24603 if e.default.is_some() {
24605 self.write_keyword("DEFAULT");
24606 self.write_space();
24607 }
24608 self.write_keyword("CHARACTER SET");
24609 self.write("=");
24610 self.generate_expression(&e.this)?;
24611 Ok(())
24612 }
24613
24614 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
24615 self.write_keyword("CHECK");
24617 self.write(" (");
24618 self.generate_expression(&e.this)?;
24619 self.write(")");
24620 if e.enforced.is_some() {
24621 self.write_space();
24622 self.write_keyword("ENFORCED");
24623 }
24624 Ok(())
24625 }
24626
24627 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
24628 self.write_keyword("CHECK_JSON");
24630 self.write("(");
24631 self.generate_expression(&e.this)?;
24632 self.write(")");
24633 Ok(())
24634 }
24635
24636 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
24637 self.write_keyword("CHECK_XML");
24639 self.write("(");
24640 self.generate_expression(&e.this)?;
24641 self.write(")");
24642 Ok(())
24643 }
24644
24645 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
24646 self.write_keyword("CHECKSUM");
24648 self.write("=");
24649 if e.on.is_some() {
24650 self.write_keyword("ON");
24651 } else if e.default.is_some() {
24652 self.write_keyword("DEFAULT");
24653 } else {
24654 self.write_keyword("OFF");
24655 }
24656 Ok(())
24657 }
24658
24659 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
24660 if e.shallow.is_some() {
24662 self.write_keyword("SHALLOW");
24663 self.write_space();
24664 }
24665 if e.copy.is_some() {
24666 self.write_keyword("COPY");
24667 } else {
24668 self.write_keyword("CLONE");
24669 }
24670 self.write_space();
24671 self.generate_expression(&e.this)?;
24672 Ok(())
24673 }
24674
24675 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
24676 self.write_keyword("CLUSTER BY");
24678 self.write(" (");
24679 for (i, ord) in e.expressions.iter().enumerate() {
24680 if i > 0 {
24681 self.write(", ");
24682 }
24683 self.generate_ordered(ord)?;
24684 }
24685 self.write(")");
24686 Ok(())
24687 }
24688
24689 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
24690 self.write_keyword("CLUSTERED BY");
24692 self.write(" (");
24693 for (i, expr) in e.expressions.iter().enumerate() {
24694 if i > 0 {
24695 self.write(", ");
24696 }
24697 self.generate_expression(expr)?;
24698 }
24699 self.write(")");
24700 if let Some(sorted_by) = &e.sorted_by {
24701 self.write_space();
24702 self.write_keyword("SORTED BY");
24703 self.write(" (");
24704 if let Expression::Tuple(t) = sorted_by.as_ref() {
24706 for (i, expr) in t.expressions.iter().enumerate() {
24707 if i > 0 {
24708 self.write(", ");
24709 }
24710 self.generate_expression(expr)?;
24711 }
24712 } else {
24713 self.generate_expression(sorted_by)?;
24714 }
24715 self.write(")");
24716 }
24717 if let Some(buckets) = &e.buckets {
24718 self.write_space();
24719 self.write_keyword("INTO");
24720 self.write_space();
24721 self.generate_expression(buckets)?;
24722 self.write_space();
24723 self.write_keyword("BUCKETS");
24724 }
24725 Ok(())
24726 }
24727
24728 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
24729 if e.default.is_some() {
24733 self.write_keyword("DEFAULT");
24734 self.write_space();
24735 }
24736 self.write_keyword("COLLATE");
24737 match self.config.dialect {
24739 Some(DialectType::BigQuery) => self.write_space(),
24740 _ => self.write("="),
24741 }
24742 self.generate_expression(&e.this)?;
24743 Ok(())
24744 }
24745
24746 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
24747 match e {
24749 ColumnConstraint::NotNull => {
24750 self.write_keyword("NOT NULL");
24751 }
24752 ColumnConstraint::Null => {
24753 self.write_keyword("NULL");
24754 }
24755 ColumnConstraint::Unique => {
24756 self.write_keyword("UNIQUE");
24757 }
24758 ColumnConstraint::PrimaryKey => {
24759 self.write_keyword("PRIMARY KEY");
24760 }
24761 ColumnConstraint::Default(expr) => {
24762 self.write_keyword("DEFAULT");
24763 self.write_space();
24764 self.generate_expression(expr)?;
24765 }
24766 ColumnConstraint::Check(expr) => {
24767 self.write_keyword("CHECK");
24768 self.write(" (");
24769 self.generate_expression(expr)?;
24770 self.write(")");
24771 }
24772 ColumnConstraint::References(fk_ref) => {
24773 if fk_ref.has_foreign_key_keywords {
24774 self.write_keyword("FOREIGN KEY");
24775 self.write_space();
24776 }
24777 self.write_keyword("REFERENCES");
24778 self.write_space();
24779 self.generate_table(&fk_ref.table)?;
24780 if !fk_ref.columns.is_empty() {
24781 self.write(" (");
24782 for (i, col) in fk_ref.columns.iter().enumerate() {
24783 if i > 0 {
24784 self.write(", ");
24785 }
24786 self.generate_identifier(col)?;
24787 }
24788 self.write(")");
24789 }
24790 }
24791 ColumnConstraint::GeneratedAsIdentity(gen) => {
24792 self.write_keyword("GENERATED");
24793 self.write_space();
24794 if gen.always {
24795 self.write_keyword("ALWAYS");
24796 } else {
24797 self.write_keyword("BY DEFAULT");
24798 if gen.on_null {
24799 self.write_space();
24800 self.write_keyword("ON NULL");
24801 }
24802 }
24803 self.write_space();
24804 self.write_keyword("AS IDENTITY");
24805 }
24806 ColumnConstraint::Collate(collation) => {
24807 self.write_keyword("COLLATE");
24808 self.write_space();
24809 self.generate_identifier(collation)?;
24810 }
24811 ColumnConstraint::Comment(comment) => {
24812 self.write_keyword("COMMENT");
24813 self.write(" '");
24814 self.write(comment);
24815 self.write("'");
24816 }
24817 ColumnConstraint::ComputedColumn(cc) => {
24818 self.generate_computed_column_inline(cc)?;
24819 }
24820 ColumnConstraint::GeneratedAsRow(gar) => {
24821 self.generate_generated_as_row_inline(gar)?;
24822 }
24823 ColumnConstraint::Tags(tags) => {
24824 self.write_keyword("TAG");
24825 self.write(" (");
24826 for (i, expr) in tags.expressions.iter().enumerate() {
24827 if i > 0 {
24828 self.write(", ");
24829 }
24830 self.generate_expression(expr)?;
24831 }
24832 self.write(")");
24833 }
24834 ColumnConstraint::Path(path_expr) => {
24835 self.write_keyword("PATH");
24836 self.write_space();
24837 self.generate_expression(path_expr)?;
24838 }
24839 }
24840 Ok(())
24841 }
24842
24843 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
24844 match e {
24846 ColumnPosition::First => {
24847 self.write_keyword("FIRST");
24848 }
24849 ColumnPosition::After(ident) => {
24850 self.write_keyword("AFTER");
24851 self.write_space();
24852 self.generate_identifier(ident)?;
24853 }
24854 }
24855 Ok(())
24856 }
24857
24858 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
24859 self.generate_expression(&e.this)?;
24861 self.write("(");
24862 self.generate_expression(&e.expression)?;
24863 self.write(")");
24864 Ok(())
24865 }
24866
24867 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
24868 if let Some(ref unpack) = e.unpack {
24871 if let Expression::Boolean(b) = unpack.as_ref() {
24872 if b.value {
24873 self.write("*");
24874 }
24875 }
24876 }
24877 self.write_keyword("COLUMNS");
24878 self.write("(");
24879 self.generate_expression(&e.this)?;
24880 self.write(")");
24881 Ok(())
24882 }
24883
24884 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
24885 self.generate_expression(&e.this)?;
24887 self.write("(");
24888 for (i, expr) in e.expressions.iter().enumerate() {
24889 if i > 0 {
24890 self.write(", ");
24891 }
24892 self.generate_expression(expr)?;
24893 }
24894 self.write(")");
24895 Ok(())
24896 }
24897
24898 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
24899 self.generate_expression(&e.this)?;
24901 self.write("(");
24902 for (i, param) in e.params.iter().enumerate() {
24903 if i > 0 {
24904 self.write(", ");
24905 }
24906 self.generate_expression(param)?;
24907 }
24908 self.write(")(");
24909 for (i, expr) in e.expressions.iter().enumerate() {
24910 if i > 0 {
24911 self.write(", ");
24912 }
24913 self.generate_expression(expr)?;
24914 }
24915 self.write(")");
24916 Ok(())
24917 }
24918
24919 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
24920 self.write_keyword("COMMIT");
24922
24923 if e.this.is_none()
24925 && matches!(
24926 self.config.dialect,
24927 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24928 )
24929 {
24930 self.write_space();
24931 self.write_keyword("TRANSACTION");
24932 }
24933
24934 if let Some(this) = &e.this {
24936 let is_transaction_marker = matches!(
24938 this.as_ref(),
24939 Expression::Identifier(id) if id.name == "TRANSACTION"
24940 );
24941
24942 self.write_space();
24943 self.write_keyword("TRANSACTION");
24944
24945 if !is_transaction_marker {
24947 self.write_space();
24948 self.generate_expression(this)?;
24949 }
24950 }
24951
24952 if let Some(durability) = &e.durability {
24954 self.write_space();
24955 self.write_keyword("WITH");
24956 self.write(" (");
24957 self.write_keyword("DELAYED_DURABILITY");
24958 self.write(" = ");
24959 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
24960 self.write_keyword("ON");
24961 } else {
24962 self.write_keyword("OFF");
24963 }
24964 self.write(")");
24965 }
24966
24967 if let Some(chain) = &e.chain {
24969 self.write_space();
24970 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
24971 self.write_keyword("AND NO CHAIN");
24972 } else {
24973 self.write_keyword("AND CHAIN");
24974 }
24975 }
24976 Ok(())
24977 }
24978
24979 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
24980 self.write("[");
24982 self.generate_expression(&e.this)?;
24983 self.write_space();
24984 self.write_keyword("FOR");
24985 self.write_space();
24986 self.generate_expression(&e.expression)?;
24987 if let Some(pos) = &e.position {
24989 self.write(", ");
24990 self.generate_expression(pos)?;
24991 }
24992 if let Some(iterator) = &e.iterator {
24993 self.write_space();
24994 self.write_keyword("IN");
24995 self.write_space();
24996 self.generate_expression(iterator)?;
24997 }
24998 if let Some(condition) = &e.condition {
24999 self.write_space();
25000 self.write_keyword("IF");
25001 self.write_space();
25002 self.generate_expression(condition)?;
25003 }
25004 self.write("]");
25005 Ok(())
25006 }
25007
25008 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
25009 self.write_keyword("COMPRESS");
25011 self.write("(");
25012 self.generate_expression(&e.this)?;
25013 if let Some(method) = &e.method {
25014 self.write(", '");
25015 self.write(method);
25016 self.write("'");
25017 }
25018 self.write(")");
25019 Ok(())
25020 }
25021
25022 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
25023 self.write_keyword("COMPRESS");
25025 if let Some(this) = &e.this {
25026 self.write_space();
25027 self.generate_expression(this)?;
25028 }
25029 Ok(())
25030 }
25031
25032 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
25033 self.write_keyword("AS");
25035 self.write_space();
25036 self.generate_expression(&e.this)?;
25037 if e.not_null.is_some() {
25038 self.write_space();
25039 self.write_keyword("PERSISTED NOT NULL");
25040 } else if e.persisted.is_some() {
25041 self.write_space();
25042 self.write_keyword("PERSISTED");
25043 }
25044 Ok(())
25045 }
25046
25047 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
25051 let computed_expr = if matches!(
25052 self.config.dialect,
25053 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25054 ) {
25055 match &*cc.expression {
25056 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
25057 {
25058 let wrapped = Expression::Cast(Box::new(Cast {
25059 this: y.this.clone(),
25060 to: DataType::Date,
25061 trailing_comments: Vec::new(),
25062 double_colon_syntax: false,
25063 format: None,
25064 default: None,
25065 }));
25066 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
25067 }
25068 Expression::Function(f)
25069 if f.name.eq_ignore_ascii_case("YEAR")
25070 && f.args.len() == 1
25071 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
25072 {
25073 let wrapped = Expression::Cast(Box::new(Cast {
25074 this: f.args[0].clone(),
25075 to: DataType::Date,
25076 trailing_comments: Vec::new(),
25077 double_colon_syntax: false,
25078 format: None,
25079 default: None,
25080 }));
25081 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
25082 }
25083 _ => *cc.expression.clone(),
25084 }
25085 } else {
25086 *cc.expression.clone()
25087 };
25088
25089 match cc.persistence_kind.as_deref() {
25090 Some("STORED") | Some("VIRTUAL") => {
25091 self.write_keyword("GENERATED ALWAYS AS");
25093 self.write(" (");
25094 self.generate_expression(&computed_expr)?;
25095 self.write(")");
25096 self.write_space();
25097 if cc.persisted {
25098 self.write_keyword("STORED");
25099 } else {
25100 self.write_keyword("VIRTUAL");
25101 }
25102 }
25103 Some("PERSISTED") => {
25104 self.write_keyword("AS");
25106 self.write(" (");
25107 self.generate_expression(&computed_expr)?;
25108 self.write(")");
25109 self.write_space();
25110 self.write_keyword("PERSISTED");
25111 if let Some(ref dt) = cc.data_type {
25113 self.write_space();
25114 self.generate_data_type(dt)?;
25115 }
25116 if cc.not_null {
25117 self.write_space();
25118 self.write_keyword("NOT NULL");
25119 }
25120 }
25121 _ => {
25122 if matches!(
25125 self.config.dialect,
25126 Some(DialectType::Spark)
25127 | Some(DialectType::Databricks)
25128 | Some(DialectType::Hive)
25129 ) {
25130 self.write_keyword("GENERATED ALWAYS AS");
25131 self.write(" (");
25132 self.generate_expression(&computed_expr)?;
25133 self.write(")");
25134 } else if matches!(
25135 self.config.dialect,
25136 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25137 ) {
25138 self.write_keyword("AS");
25139 let omit_parens = matches!(computed_expr, Expression::Year(_))
25140 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
25141 if omit_parens {
25142 self.write_space();
25143 self.generate_expression(&computed_expr)?;
25144 } else {
25145 self.write(" (");
25146 self.generate_expression(&computed_expr)?;
25147 self.write(")");
25148 }
25149 } else {
25150 self.write_keyword("AS");
25151 self.write(" (");
25152 self.generate_expression(&computed_expr)?;
25153 self.write(")");
25154 }
25155 }
25156 }
25157 Ok(())
25158 }
25159
25160 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
25163 self.write_keyword("GENERATED ALWAYS AS ROW ");
25164 if gar.start {
25165 self.write_keyword("START");
25166 } else {
25167 self.write_keyword("END");
25168 }
25169 if gar.hidden {
25170 self.write_space();
25171 self.write_keyword("HIDDEN");
25172 }
25173 Ok(())
25174 }
25175
25176 fn generate_system_versioning_content(
25178 &mut self,
25179 e: &WithSystemVersioningProperty,
25180 ) -> Result<()> {
25181 let mut parts = Vec::new();
25182
25183 if let Some(this) = &e.this {
25184 let mut s = String::from("HISTORY_TABLE=");
25185 let mut gen = Generator::new();
25186 gen.config = self.config.clone();
25187 gen.generate_expression(this)?;
25188 s.push_str(&gen.output);
25189 parts.push(s);
25190 }
25191
25192 if let Some(data_consistency) = &e.data_consistency {
25193 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
25194 let mut gen = Generator::new();
25195 gen.config = self.config.clone();
25196 gen.generate_expression(data_consistency)?;
25197 s.push_str(&gen.output);
25198 parts.push(s);
25199 }
25200
25201 if let Some(retention_period) = &e.retention_period {
25202 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
25203 let mut gen = Generator::new();
25204 gen.config = self.config.clone();
25205 gen.generate_expression(retention_period)?;
25206 s.push_str(&gen.output);
25207 parts.push(s);
25208 }
25209
25210 self.write_keyword("SYSTEM_VERSIONING");
25211 self.write("=");
25212
25213 if !parts.is_empty() {
25214 self.write_keyword("ON");
25215 self.write("(");
25216 self.write(&parts.join(", "));
25217 self.write(")");
25218 } else if e.on.is_some() {
25219 self.write_keyword("ON");
25220 } else {
25221 self.write_keyword("OFF");
25222 }
25223
25224 Ok(())
25225 }
25226
25227 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
25228 if e.else_.is_some() {
25231 self.write_keyword("ELSE");
25232 self.write_space();
25233 } else if let Some(expression) = &e.expression {
25234 self.write_keyword("WHEN");
25235 self.write_space();
25236 self.generate_expression(expression)?;
25237 self.write_space();
25238 self.write_keyword("THEN");
25239 self.write_space();
25240 }
25241
25242 if let Expression::Insert(insert) = e.this.as_ref() {
25245 self.write_keyword("INTO");
25246 self.write_space();
25247 self.generate_table(&insert.table)?;
25248
25249 if !insert.columns.is_empty() {
25251 self.write(" (");
25252 for (i, col) in insert.columns.iter().enumerate() {
25253 if i > 0 {
25254 self.write(", ");
25255 }
25256 self.generate_identifier(col)?;
25257 }
25258 self.write(")");
25259 }
25260
25261 if !insert.values.is_empty() {
25263 self.write_space();
25264 self.write_keyword("VALUES");
25265 for (row_idx, row) in insert.values.iter().enumerate() {
25266 if row_idx > 0 {
25267 self.write(", ");
25268 }
25269 self.write(" (");
25270 for (i, val) in row.iter().enumerate() {
25271 if i > 0 {
25272 self.write(", ");
25273 }
25274 self.generate_expression(val)?;
25275 }
25276 self.write(")");
25277 }
25278 }
25279 } else {
25280 self.generate_expression(&e.this)?;
25282 }
25283 Ok(())
25284 }
25285
25286 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
25287 self.write_keyword("CONSTRAINT");
25289 self.write_space();
25290 self.generate_expression(&e.this)?;
25291 if !e.expressions.is_empty() {
25292 self.write_space();
25293 for (i, expr) in e.expressions.iter().enumerate() {
25294 if i > 0 {
25295 self.write_space();
25296 }
25297 self.generate_expression(expr)?;
25298 }
25299 }
25300 Ok(())
25301 }
25302
25303 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
25304 self.write_keyword("CONVERT_TIMEZONE");
25306 self.write("(");
25307 let mut first = true;
25308 if let Some(source_tz) = &e.source_tz {
25309 self.generate_expression(source_tz)?;
25310 first = false;
25311 }
25312 if let Some(target_tz) = &e.target_tz {
25313 if !first {
25314 self.write(", ");
25315 }
25316 self.generate_expression(target_tz)?;
25317 first = false;
25318 }
25319 if let Some(timestamp) = &e.timestamp {
25320 if !first {
25321 self.write(", ");
25322 }
25323 self.generate_expression(timestamp)?;
25324 }
25325 self.write(")");
25326 Ok(())
25327 }
25328
25329 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
25330 self.write_keyword("CONVERT");
25332 self.write("(");
25333 self.generate_expression(&e.this)?;
25334 if let Some(dest) = &e.dest {
25335 self.write_space();
25336 self.write_keyword("USING");
25337 self.write_space();
25338 self.generate_expression(dest)?;
25339 }
25340 self.write(")");
25341 Ok(())
25342 }
25343
25344 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
25345 self.write_keyword("COPY");
25346 if e.is_into {
25347 self.write_space();
25348 self.write_keyword("INTO");
25349 }
25350 self.write_space();
25351
25352 if let Expression::Literal(Literal::String(s)) = &e.this {
25354 if s.starts_with('@') {
25355 self.write(s);
25356 } else {
25357 self.generate_expression(&e.this)?;
25358 }
25359 } else {
25360 self.generate_expression(&e.this)?;
25361 }
25362
25363 if e.kind {
25365 if self.config.pretty {
25367 self.write_newline();
25368 } else {
25369 self.write_space();
25370 }
25371 self.write_keyword("FROM");
25372 self.write_space();
25373 } else if !e.files.is_empty() {
25374 if self.config.pretty {
25376 self.write_newline();
25377 } else {
25378 self.write_space();
25379 }
25380 self.write_keyword("TO");
25381 self.write_space();
25382 }
25383
25384 for (i, file) in e.files.iter().enumerate() {
25386 if i > 0 {
25387 self.write_space();
25388 }
25389 if let Expression::Literal(Literal::String(s)) = file {
25391 if s.starts_with('@') {
25392 self.write(s);
25393 } else {
25394 self.generate_expression(file)?;
25395 }
25396 } else if let Expression::Identifier(id) = file {
25397 if id.quoted {
25399 self.write("`");
25400 self.write(&id.name);
25401 self.write("`");
25402 } else {
25403 self.generate_expression(file)?;
25404 }
25405 } else {
25406 self.generate_expression(file)?;
25407 }
25408 }
25409
25410 if !e.with_wrapped {
25412 if let Some(ref creds) = e.credentials {
25413 if let Some(ref storage) = creds.storage {
25414 if self.config.pretty {
25415 self.write_newline();
25416 } else {
25417 self.write_space();
25418 }
25419 self.write_keyword("STORAGE_INTEGRATION");
25420 self.write(" = ");
25421 self.write(storage);
25422 }
25423 if creds.credentials.is_empty() {
25424 if self.config.pretty {
25426 self.write_newline();
25427 } else {
25428 self.write_space();
25429 }
25430 self.write_keyword("CREDENTIALS");
25431 self.write(" = ()");
25432 } else {
25433 if self.config.pretty {
25434 self.write_newline();
25435 } else {
25436 self.write_space();
25437 }
25438 self.write_keyword("CREDENTIALS");
25439 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
25442 self.write(" '");
25444 self.write(&creds.credentials[0].1);
25445 self.write("'");
25446 } else {
25447 self.write(" = (");
25449 for (i, (k, v)) in creds.credentials.iter().enumerate() {
25450 if i > 0 {
25451 self.write_space();
25452 }
25453 self.write(k);
25454 self.write("='");
25455 self.write(v);
25456 self.write("'");
25457 }
25458 self.write(")");
25459 }
25460 }
25461 if let Some(ref encryption) = creds.encryption {
25462 self.write_space();
25463 self.write_keyword("ENCRYPTION");
25464 self.write(" = ");
25465 self.write(encryption);
25466 }
25467 }
25468 }
25469
25470 if !e.params.is_empty() {
25472 if e.with_wrapped {
25473 self.write_space();
25475 self.write_keyword("WITH");
25476 self.write(" (");
25477 for (i, param) in e.params.iter().enumerate() {
25478 if i > 0 {
25479 self.write(", ");
25480 }
25481 self.generate_copy_param_with_format(param)?;
25482 }
25483 self.write(")");
25484 } else {
25485 for param in &e.params {
25489 if self.config.pretty {
25490 self.write_newline();
25491 } else {
25492 self.write_space();
25493 }
25494 self.write(¶m.name);
25496 if let Some(ref value) = param.value {
25497 if param.eq {
25499 self.write(" = ");
25500 } else {
25501 self.write(" ");
25502 }
25503 if !param.values.is_empty() {
25504 self.write("(");
25505 for (i, v) in param.values.iter().enumerate() {
25506 if i > 0 {
25507 self.write_space();
25508 }
25509 self.generate_copy_nested_param(v)?;
25510 }
25511 self.write(")");
25512 } else {
25513 self.generate_copy_param_value(value)?;
25515 }
25516 } else if !param.values.is_empty() {
25517 if param.eq {
25519 self.write(" = (");
25520 } else {
25521 self.write(" (");
25522 }
25523 let is_key_value_pairs = param
25528 .values
25529 .first()
25530 .map_or(false, |v| matches!(v, Expression::Eq(_)));
25531 let sep = if is_key_value_pairs && param.eq {
25532 " "
25533 } else {
25534 ", "
25535 };
25536 for (i, v) in param.values.iter().enumerate() {
25537 if i > 0 {
25538 self.write(sep);
25539 }
25540 self.generate_copy_nested_param(v)?;
25541 }
25542 self.write(")");
25543 }
25544 }
25545 }
25546 }
25547
25548 Ok(())
25549 }
25550
25551 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
25554 self.write_keyword(¶m.name);
25555 if !param.values.is_empty() {
25556 self.write(" = (");
25558 for (i, v) in param.values.iter().enumerate() {
25559 if i > 0 {
25560 self.write(", ");
25561 }
25562 self.generate_copy_nested_param(v)?;
25563 }
25564 self.write(")");
25565 } else if let Some(ref value) = param.value {
25566 if param.eq {
25567 self.write(" = ");
25568 } else {
25569 self.write(" ");
25570 }
25571 self.generate_expression(value)?;
25572 }
25573 Ok(())
25574 }
25575
25576 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
25578 match expr {
25579 Expression::Eq(eq) => {
25580 match &eq.left {
25582 Expression::Column(c) => self.write(&c.name.name),
25583 _ => self.generate_expression(&eq.left)?,
25584 }
25585 self.write("=");
25586 match &eq.right {
25588 Expression::Literal(Literal::String(s)) => {
25589 self.write("'");
25590 self.write(s);
25591 self.write("'");
25592 }
25593 Expression::Tuple(t) => {
25594 self.write("(");
25596 if self.config.pretty {
25597 self.write_newline();
25598 self.indent_level += 1;
25599 for (i, item) in t.expressions.iter().enumerate() {
25600 if i > 0 {
25601 self.write(", ");
25602 }
25603 self.write_indent();
25604 self.generate_expression(item)?;
25605 }
25606 self.write_newline();
25607 self.indent_level -= 1;
25608 } else {
25609 for (i, item) in t.expressions.iter().enumerate() {
25610 if i > 0 {
25611 self.write(", ");
25612 }
25613 self.generate_expression(item)?;
25614 }
25615 }
25616 self.write(")");
25617 }
25618 _ => self.generate_expression(&eq.right)?,
25619 }
25620 Ok(())
25621 }
25622 Expression::Column(c) => {
25623 self.write(&c.name.name);
25625 Ok(())
25626 }
25627 _ => self.generate_expression(expr),
25628 }
25629 }
25630
25631 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
25634 match expr {
25635 Expression::Column(c) => {
25636 if c.name.quoted {
25638 self.write("\"");
25639 self.write(&c.name.name);
25640 self.write("\"");
25641 } else {
25642 self.write(&c.name.name);
25643 }
25644 Ok(())
25645 }
25646 Expression::Identifier(id) => {
25647 if id.quoted {
25649 self.write("\"");
25650 self.write(&id.name);
25651 self.write("\"");
25652 } else {
25653 self.write(&id.name);
25654 }
25655 Ok(())
25656 }
25657 Expression::Literal(Literal::String(s)) => {
25658 self.write("'");
25660 self.write(s);
25661 self.write("'");
25662 Ok(())
25663 }
25664 _ => self.generate_expression(expr),
25665 }
25666 }
25667
25668 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
25669 self.write_keyword(&e.name);
25670 if let Some(ref value) = e.value {
25671 if e.eq {
25672 self.write(" = ");
25673 } else {
25674 self.write(" ");
25675 }
25676 self.generate_expression(value)?;
25677 }
25678 if !e.values.is_empty() {
25679 if e.eq {
25680 self.write(" = ");
25681 } else {
25682 self.write(" ");
25683 }
25684 self.write("(");
25685 for (i, v) in e.values.iter().enumerate() {
25686 if i > 0 {
25687 self.write(", ");
25688 }
25689 self.generate_expression(v)?;
25690 }
25691 self.write(")");
25692 }
25693 Ok(())
25694 }
25695
25696 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
25697 self.write_keyword("CORR");
25699 self.write("(");
25700 self.generate_expression(&e.this)?;
25701 self.write(", ");
25702 self.generate_expression(&e.expression)?;
25703 self.write(")");
25704 Ok(())
25705 }
25706
25707 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
25708 self.write_keyword("COSINE_DISTANCE");
25710 self.write("(");
25711 self.generate_expression(&e.this)?;
25712 self.write(", ");
25713 self.generate_expression(&e.expression)?;
25714 self.write(")");
25715 Ok(())
25716 }
25717
25718 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
25719 self.write_keyword("COVAR_POP");
25721 self.write("(");
25722 self.generate_expression(&e.this)?;
25723 self.write(", ");
25724 self.generate_expression(&e.expression)?;
25725 self.write(")");
25726 Ok(())
25727 }
25728
25729 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
25730 self.write_keyword("COVAR_SAMP");
25732 self.write("(");
25733 self.generate_expression(&e.this)?;
25734 self.write(", ");
25735 self.generate_expression(&e.expression)?;
25736 self.write(")");
25737 Ok(())
25738 }
25739
25740 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
25741 self.write_keyword("CREDENTIALS");
25743 self.write(" (");
25744 for (i, (key, value)) in e.credentials.iter().enumerate() {
25745 if i > 0 {
25746 self.write(", ");
25747 }
25748 self.write(key);
25749 self.write("='");
25750 self.write(value);
25751 self.write("'");
25752 }
25753 self.write(")");
25754 Ok(())
25755 }
25756
25757 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
25758 self.write_keyword("CREDENTIALS");
25760 self.write("=(");
25761 for (i, expr) in e.expressions.iter().enumerate() {
25762 if i > 0 {
25763 self.write(", ");
25764 }
25765 self.generate_expression(expr)?;
25766 }
25767 self.write(")");
25768 Ok(())
25769 }
25770
25771 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
25772 use crate::dialects::DialectType;
25773
25774 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
25777 self.generate_expression(&e.this)?;
25778 self.write_space();
25779 self.write_keyword("AS");
25780 self.write_space();
25781 self.generate_identifier(&e.alias)?;
25782 return Ok(());
25783 }
25784 self.write(&e.alias.name);
25785
25786 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
25788
25789 if !e.columns.is_empty() && !skip_cte_columns {
25790 self.write("(");
25791 for (i, col) in e.columns.iter().enumerate() {
25792 if i > 0 {
25793 self.write(", ");
25794 }
25795 self.write(&col.name);
25796 }
25797 self.write(")");
25798 }
25799 if !e.key_expressions.is_empty() {
25801 self.write_space();
25802 self.write_keyword("USING KEY");
25803 self.write(" (");
25804 for (i, key) in e.key_expressions.iter().enumerate() {
25805 if i > 0 {
25806 self.write(", ");
25807 }
25808 self.write(&key.name);
25809 }
25810 self.write(")");
25811 }
25812 self.write_space();
25813 self.write_keyword("AS");
25814 self.write_space();
25815 if let Some(materialized) = e.materialized {
25816 if materialized {
25817 self.write_keyword("MATERIALIZED");
25818 } else {
25819 self.write_keyword("NOT MATERIALIZED");
25820 }
25821 self.write_space();
25822 }
25823 self.write("(");
25824 self.generate_expression(&e.this)?;
25825 self.write(")");
25826 Ok(())
25827 }
25828
25829 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
25830 if e.expressions.is_empty() {
25832 self.write_keyword("WITH CUBE");
25833 } else {
25834 self.write_keyword("CUBE");
25835 self.write("(");
25836 for (i, expr) in e.expressions.iter().enumerate() {
25837 if i > 0 {
25838 self.write(", ");
25839 }
25840 self.generate_expression(expr)?;
25841 }
25842 self.write(")");
25843 }
25844 Ok(())
25845 }
25846
25847 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
25848 self.write_keyword("CURRENT_DATETIME");
25850 if let Some(this) = &e.this {
25851 self.write("(");
25852 self.generate_expression(this)?;
25853 self.write(")");
25854 }
25855 Ok(())
25856 }
25857
25858 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
25859 self.write_keyword("CURRENT_SCHEMA");
25861 Ok(())
25862 }
25863
25864 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
25865 self.write_keyword("CURRENT_SCHEMAS");
25867 self.write("(");
25868 if let Some(this) = &e.this {
25869 self.generate_expression(this)?;
25870 }
25871 self.write(")");
25872 Ok(())
25873 }
25874
25875 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
25876 self.write_keyword("CURRENT_USER");
25878 let needs_parens = e.this.is_some()
25880 || matches!(
25881 self.config.dialect,
25882 Some(DialectType::Snowflake)
25883 | Some(DialectType::Spark)
25884 | Some(DialectType::Hive)
25885 | Some(DialectType::DuckDB)
25886 | Some(DialectType::BigQuery)
25887 | Some(DialectType::MySQL)
25888 | Some(DialectType::Databricks)
25889 );
25890 if needs_parens {
25891 self.write("()");
25892 }
25893 Ok(())
25894 }
25895
25896 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
25897 if self.config.dialect == Some(DialectType::Solr) {
25899 self.generate_expression(&e.this)?;
25900 self.write(" ");
25901 self.write_keyword("OR");
25902 self.write(" ");
25903 self.generate_expression(&e.expression)?;
25904 } else {
25905 self.generate_expression(&e.this)?;
25907 self.write(" || ");
25908 self.generate_expression(&e.expression)?;
25909 }
25910 Ok(())
25911 }
25912
25913 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
25914 self.write_keyword("DATABLOCKSIZE");
25916 self.write("=");
25917 if let Some(size) = e.size {
25918 self.write(&size.to_string());
25919 if let Some(units) = &e.units {
25920 self.write_space();
25921 self.generate_expression(units)?;
25922 }
25923 } else if e.minimum.is_some() {
25924 self.write_keyword("MINIMUM");
25925 } else if e.maximum.is_some() {
25926 self.write_keyword("MAXIMUM");
25927 } else if e.default.is_some() {
25928 self.write_keyword("DEFAULT");
25929 }
25930 Ok(())
25931 }
25932
25933 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
25934 self.write_keyword("DATA_DELETION");
25936 self.write("=");
25937
25938 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
25939 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
25940
25941 if is_on {
25942 self.write_keyword("ON");
25943 if has_options {
25944 self.write("(");
25945 let mut first = true;
25946 if let Some(filter_column) = &e.filter_column {
25947 self.write_keyword("FILTER_COLUMN");
25948 self.write("=");
25949 self.generate_expression(filter_column)?;
25950 first = false;
25951 }
25952 if let Some(retention_period) = &e.retention_period {
25953 if !first {
25954 self.write(", ");
25955 }
25956 self.write_keyword("RETENTION_PERIOD");
25957 self.write("=");
25958 self.generate_expression(retention_period)?;
25959 }
25960 self.write(")");
25961 }
25962 } else {
25963 self.write_keyword("OFF");
25964 }
25965 Ok(())
25966 }
25967
25968 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
25972 use crate::dialects::DialectType;
25973 use crate::expressions::Literal;
25974
25975 match self.config.dialect {
25976 Some(DialectType::Exasol) => {
25978 self.write_keyword("TO_DATE");
25979 self.write("(");
25980 match &e.this {
25982 Expression::Literal(Literal::String(s)) => {
25983 self.write("'");
25984 self.write(s);
25985 self.write("'");
25986 }
25987 _ => {
25988 self.generate_expression(&e.this)?;
25989 }
25990 }
25991 self.write(")");
25992 }
25993 _ => {
25995 self.write_keyword("DATE");
25996 self.write("(");
25997 self.generate_expression(&e.this)?;
25998 self.write(")");
25999 }
26000 }
26001 Ok(())
26002 }
26003
26004 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
26005 self.write_keyword("DATE_BIN");
26007 self.write("(");
26008 self.generate_expression(&e.this)?;
26009 self.write(", ");
26010 self.generate_expression(&e.expression)?;
26011 if let Some(origin) = &e.origin {
26012 self.write(", ");
26013 self.generate_expression(origin)?;
26014 }
26015 self.write(")");
26016 Ok(())
26017 }
26018
26019 fn generate_date_format_column_constraint(
26020 &mut self,
26021 e: &DateFormatColumnConstraint,
26022 ) -> Result<()> {
26023 self.write_keyword("FORMAT");
26025 self.write_space();
26026 self.generate_expression(&e.this)?;
26027 Ok(())
26028 }
26029
26030 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
26031 self.write_keyword("DATE_FROM_PARTS");
26033 self.write("(");
26034 let mut first = true;
26035 if let Some(year) = &e.year {
26036 self.generate_expression(year)?;
26037 first = false;
26038 }
26039 if let Some(month) = &e.month {
26040 if !first {
26041 self.write(", ");
26042 }
26043 self.generate_expression(month)?;
26044 first = false;
26045 }
26046 if let Some(day) = &e.day {
26047 if !first {
26048 self.write(", ");
26049 }
26050 self.generate_expression(day)?;
26051 }
26052 self.write(")");
26053 Ok(())
26054 }
26055
26056 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
26057 self.write_keyword("DATETIME");
26059 self.write("(");
26060 self.generate_expression(&e.this)?;
26061 if let Some(expr) = &e.expression {
26062 self.write(", ");
26063 self.generate_expression(expr)?;
26064 }
26065 self.write(")");
26066 Ok(())
26067 }
26068
26069 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
26070 self.write_keyword("DATETIME_ADD");
26072 self.write("(");
26073 self.generate_expression(&e.this)?;
26074 self.write(", ");
26075 self.generate_expression(&e.expression)?;
26076 if let Some(unit) = &e.unit {
26077 self.write(", ");
26078 self.write_keyword(unit);
26079 }
26080 self.write(")");
26081 Ok(())
26082 }
26083
26084 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
26085 self.write_keyword("DATETIME_DIFF");
26087 self.write("(");
26088 self.generate_expression(&e.this)?;
26089 self.write(", ");
26090 self.generate_expression(&e.expression)?;
26091 if let Some(unit) = &e.unit {
26092 self.write(", ");
26093 self.write_keyword(unit);
26094 }
26095 self.write(")");
26096 Ok(())
26097 }
26098
26099 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
26100 self.write_keyword("DATETIME_SUB");
26102 self.write("(");
26103 self.generate_expression(&e.this)?;
26104 self.write(", ");
26105 self.generate_expression(&e.expression)?;
26106 if let Some(unit) = &e.unit {
26107 self.write(", ");
26108 self.write_keyword(unit);
26109 }
26110 self.write(")");
26111 Ok(())
26112 }
26113
26114 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
26115 self.write_keyword("DATETIME_TRUNC");
26117 self.write("(");
26118 self.generate_expression(&e.this)?;
26119 self.write(", ");
26120 self.write_keyword(&e.unit);
26121 if let Some(zone) = &e.zone {
26122 self.write(", ");
26123 self.generate_expression(zone)?;
26124 }
26125 self.write(")");
26126 Ok(())
26127 }
26128
26129 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
26130 self.write_keyword("DAYNAME");
26132 self.write("(");
26133 self.generate_expression(&e.this)?;
26134 self.write(")");
26135 Ok(())
26136 }
26137
26138 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
26139 self.write_keyword("DECLARE");
26141 self.write_space();
26142 for (i, expr) in e.expressions.iter().enumerate() {
26143 if i > 0 {
26144 self.write(", ");
26145 }
26146 self.generate_expression(expr)?;
26147 }
26148 Ok(())
26149 }
26150
26151 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
26152 use crate::dialects::DialectType;
26153
26154 self.generate_expression(&e.this)?;
26156 for name in &e.additional_names {
26158 self.write(", ");
26159 self.generate_expression(name)?;
26160 }
26161 if let Some(kind) = &e.kind {
26162 self.write_space();
26163 match self.config.dialect {
26167 Some(DialectType::BigQuery) => {
26168 self.write(kind);
26169 }
26170 Some(DialectType::TSQL) => {
26171 let is_complex_table = kind.starts_with("TABLE")
26175 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
26176
26177 if is_complex_table {
26178 self.write(kind);
26180 } else {
26181 if !kind.starts_with("CURSOR") {
26183 self.write_keyword("AS");
26184 self.write_space();
26185 }
26186 if kind == "INT" {
26188 self.write("INTEGER");
26189 } else if kind.starts_with("TABLE") {
26190 let normalized = kind
26192 .replace(" INT ", " INTEGER ")
26193 .replace(" INT,", " INTEGER,")
26194 .replace(" INT)", " INTEGER)")
26195 .replace("(INT ", "(INTEGER ");
26196 self.write(&normalized);
26197 } else {
26198 self.write(kind);
26199 }
26200 }
26201 }
26202 _ => {
26203 if e.has_as {
26204 self.write_keyword("AS");
26205 self.write_space();
26206 }
26207 self.write(kind);
26208 }
26209 }
26210 }
26211 if let Some(default) = &e.default {
26212 match self.config.dialect {
26214 Some(DialectType::BigQuery) => {
26215 self.write_space();
26216 self.write_keyword("DEFAULT");
26217 self.write_space();
26218 }
26219 _ => {
26220 self.write(" = ");
26221 }
26222 }
26223 self.generate_expression(default)?;
26224 }
26225 Ok(())
26226 }
26227
26228 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
26229 self.write_keyword("DECODE");
26231 self.write("(");
26232 for (i, expr) in e.expressions.iter().enumerate() {
26233 if i > 0 {
26234 self.write(", ");
26235 }
26236 self.generate_expression(expr)?;
26237 }
26238 self.write(")");
26239 Ok(())
26240 }
26241
26242 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
26243 self.write_keyword("DECOMPRESS");
26245 self.write("(");
26246 self.generate_expression(&e.this)?;
26247 self.write(", '");
26248 self.write(&e.method);
26249 self.write("')");
26250 Ok(())
26251 }
26252
26253 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
26254 self.write_keyword("DECOMPRESS");
26256 self.write("(");
26257 self.generate_expression(&e.this)?;
26258 self.write(", '");
26259 self.write(&e.method);
26260 self.write("')");
26261 Ok(())
26262 }
26263
26264 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
26265 self.write_keyword("DECRYPT");
26267 self.write("(");
26268 self.generate_expression(&e.this)?;
26269 if let Some(passphrase) = &e.passphrase {
26270 self.write(", ");
26271 self.generate_expression(passphrase)?;
26272 }
26273 if let Some(aad) = &e.aad {
26274 self.write(", ");
26275 self.generate_expression(aad)?;
26276 }
26277 if let Some(method) = &e.encryption_method {
26278 self.write(", ");
26279 self.generate_expression(method)?;
26280 }
26281 self.write(")");
26282 Ok(())
26283 }
26284
26285 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
26286 self.write_keyword("DECRYPT_RAW");
26288 self.write("(");
26289 self.generate_expression(&e.this)?;
26290 if let Some(key) = &e.key {
26291 self.write(", ");
26292 self.generate_expression(key)?;
26293 }
26294 if let Some(iv) = &e.iv {
26295 self.write(", ");
26296 self.generate_expression(iv)?;
26297 }
26298 if let Some(aad) = &e.aad {
26299 self.write(", ");
26300 self.generate_expression(aad)?;
26301 }
26302 if let Some(method) = &e.encryption_method {
26303 self.write(", ");
26304 self.generate_expression(method)?;
26305 }
26306 self.write(")");
26307 Ok(())
26308 }
26309
26310 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
26311 self.write_keyword("DEFINER");
26313 self.write(" = ");
26314 self.generate_expression(&e.this)?;
26315 Ok(())
26316 }
26317
26318 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
26319 self.write_keyword("DETACH");
26321 if e.exists {
26322 self.write_keyword(" DATABASE IF EXISTS");
26323 }
26324 self.write_space();
26325 self.generate_expression(&e.this)?;
26326 Ok(())
26327 }
26328
26329 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
26330 let property_name = match e.this.as_ref() {
26331 Expression::Identifier(id) => id.name.as_str(),
26332 Expression::Var(v) => v.this.as_str(),
26333 _ => "DICTIONARY",
26334 };
26335 self.write_keyword(property_name);
26336 self.write("(");
26337 self.write(&e.kind);
26338 if let Some(settings) = &e.settings {
26339 self.write("(");
26340 if let Expression::Tuple(t) = settings.as_ref() {
26341 if self.config.pretty && !t.expressions.is_empty() {
26342 self.write_newline();
26343 self.indent_level += 1;
26344 for (i, pair) in t.expressions.iter().enumerate() {
26345 if i > 0 {
26346 self.write(",");
26347 self.write_newline();
26348 }
26349 self.write_indent();
26350 if let Expression::Tuple(pair_tuple) = pair {
26351 if let Some(k) = pair_tuple.expressions.first() {
26352 self.generate_expression(k)?;
26353 }
26354 if let Some(v) = pair_tuple.expressions.get(1) {
26355 self.write(" ");
26356 self.generate_expression(v)?;
26357 }
26358 } else {
26359 self.generate_expression(pair)?;
26360 }
26361 }
26362 self.indent_level -= 1;
26363 self.write_newline();
26364 self.write_indent();
26365 } else {
26366 for (i, pair) in t.expressions.iter().enumerate() {
26367 if i > 0 {
26368 self.write(", ");
26369 }
26370 if let Expression::Tuple(pair_tuple) = pair {
26371 if let Some(k) = pair_tuple.expressions.first() {
26372 self.generate_expression(k)?;
26373 }
26374 if let Some(v) = pair_tuple.expressions.get(1) {
26375 self.write(" ");
26376 self.generate_expression(v)?;
26377 }
26378 } else {
26379 self.generate_expression(pair)?;
26380 }
26381 }
26382 }
26383 } else {
26384 self.generate_expression(settings)?;
26385 }
26386 self.write(")");
26387 } else if property_name.eq_ignore_ascii_case("LAYOUT") {
26388 self.write("()");
26389 }
26390 self.write(")");
26391 Ok(())
26392 }
26393
26394 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
26395 let property_name = match e.this.as_ref() {
26396 Expression::Identifier(id) => id.name.as_str(),
26397 Expression::Var(v) => v.this.as_str(),
26398 _ => "RANGE",
26399 };
26400 self.write_keyword(property_name);
26401 self.write("(");
26402 if let Some(min) = &e.min {
26403 self.write_keyword("MIN");
26404 self.write_space();
26405 self.generate_expression(min)?;
26406 }
26407 if let Some(max) = &e.max {
26408 self.write_space();
26409 self.write_keyword("MAX");
26410 self.write_space();
26411 self.generate_expression(max)?;
26412 }
26413 self.write(")");
26414 Ok(())
26415 }
26416
26417 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
26418 if e.local.is_some() {
26420 self.write_keyword("LOCAL ");
26421 }
26422 self.write_keyword("DIRECTORY");
26423 self.write_space();
26424 self.generate_expression(&e.this)?;
26425 if let Some(row_format) = &e.row_format {
26426 self.write_space();
26427 self.generate_expression(row_format)?;
26428 }
26429 Ok(())
26430 }
26431
26432 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
26433 self.write_keyword("DISTKEY");
26435 self.write("(");
26436 self.generate_expression(&e.this)?;
26437 self.write(")");
26438 Ok(())
26439 }
26440
26441 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
26442 self.write_keyword("DISTSTYLE");
26444 self.write_space();
26445 self.generate_expression(&e.this)?;
26446 Ok(())
26447 }
26448
26449 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
26450 self.write_keyword("DISTRIBUTE BY");
26452 self.write_space();
26453 for (i, expr) in e.expressions.iter().enumerate() {
26454 if i > 0 {
26455 self.write(", ");
26456 }
26457 self.generate_expression(expr)?;
26458 }
26459 Ok(())
26460 }
26461
26462 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
26463 self.write_keyword("DISTRIBUTED BY");
26465 self.write_space();
26466 self.write(&e.kind);
26467 if !e.expressions.is_empty() {
26468 self.write(" (");
26469 for (i, expr) in e.expressions.iter().enumerate() {
26470 if i > 0 {
26471 self.write(", ");
26472 }
26473 self.generate_expression(expr)?;
26474 }
26475 self.write(")");
26476 }
26477 if let Some(buckets) = &e.buckets {
26478 self.write_space();
26479 self.write_keyword("BUCKETS");
26480 self.write_space();
26481 self.generate_expression(buckets)?;
26482 }
26483 if let Some(order) = &e.order {
26484 self.write_space();
26485 self.generate_expression(order)?;
26486 }
26487 Ok(())
26488 }
26489
26490 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
26491 self.write_keyword("DOT_PRODUCT");
26493 self.write("(");
26494 self.generate_expression(&e.this)?;
26495 self.write(", ");
26496 self.generate_expression(&e.expression)?;
26497 self.write(")");
26498 Ok(())
26499 }
26500
26501 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
26502 self.write_keyword("DROP");
26504 if e.exists {
26505 self.write_keyword(" IF EXISTS ");
26506 } else {
26507 self.write_space();
26508 }
26509 for (i, expr) in e.expressions.iter().enumerate() {
26510 if i > 0 {
26511 self.write(", ");
26512 }
26513 self.generate_expression(expr)?;
26514 }
26515 Ok(())
26516 }
26517
26518 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
26519 self.write_keyword("DUPLICATE KEY");
26521 self.write(" (");
26522 for (i, expr) in e.expressions.iter().enumerate() {
26523 if i > 0 {
26524 self.write(", ");
26525 }
26526 self.generate_expression(expr)?;
26527 }
26528 self.write(")");
26529 Ok(())
26530 }
26531
26532 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
26533 self.write_keyword("ELT");
26535 self.write("(");
26536 self.generate_expression(&e.this)?;
26537 for expr in &e.expressions {
26538 self.write(", ");
26539 self.generate_expression(expr)?;
26540 }
26541 self.write(")");
26542 Ok(())
26543 }
26544
26545 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
26546 self.write_keyword("ENCODE");
26548 self.write("(");
26549 self.generate_expression(&e.this)?;
26550 if let Some(charset) = &e.charset {
26551 self.write(", ");
26552 self.generate_expression(charset)?;
26553 }
26554 self.write(")");
26555 Ok(())
26556 }
26557
26558 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
26559 if e.key.is_some() {
26561 self.write_keyword("KEY ");
26562 }
26563 self.write_keyword("ENCODE");
26564 self.write_space();
26565 self.generate_expression(&e.this)?;
26566 if !e.properties.is_empty() {
26567 self.write(" (");
26568 for (i, prop) in e.properties.iter().enumerate() {
26569 if i > 0 {
26570 self.write(", ");
26571 }
26572 self.generate_expression(prop)?;
26573 }
26574 self.write(")");
26575 }
26576 Ok(())
26577 }
26578
26579 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
26580 self.write_keyword("ENCRYPT");
26582 self.write("(");
26583 self.generate_expression(&e.this)?;
26584 if let Some(passphrase) = &e.passphrase {
26585 self.write(", ");
26586 self.generate_expression(passphrase)?;
26587 }
26588 if let Some(aad) = &e.aad {
26589 self.write(", ");
26590 self.generate_expression(aad)?;
26591 }
26592 if let Some(method) = &e.encryption_method {
26593 self.write(", ");
26594 self.generate_expression(method)?;
26595 }
26596 self.write(")");
26597 Ok(())
26598 }
26599
26600 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
26601 self.write_keyword("ENCRYPT_RAW");
26603 self.write("(");
26604 self.generate_expression(&e.this)?;
26605 if let Some(key) = &e.key {
26606 self.write(", ");
26607 self.generate_expression(key)?;
26608 }
26609 if let Some(iv) = &e.iv {
26610 self.write(", ");
26611 self.generate_expression(iv)?;
26612 }
26613 if let Some(aad) = &e.aad {
26614 self.write(", ");
26615 self.generate_expression(aad)?;
26616 }
26617 if let Some(method) = &e.encryption_method {
26618 self.write(", ");
26619 self.generate_expression(method)?;
26620 }
26621 self.write(")");
26622 Ok(())
26623 }
26624
26625 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
26626 self.write_keyword("ENGINE");
26628 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
26629 self.write("=");
26630 } else {
26631 self.write(" = ");
26632 }
26633 self.generate_expression(&e.this)?;
26634 Ok(())
26635 }
26636
26637 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
26638 self.write_keyword("ENVIRONMENT");
26640 self.write(" (");
26641 for (i, expr) in e.expressions.iter().enumerate() {
26642 if i > 0 {
26643 self.write(", ");
26644 }
26645 self.generate_expression(expr)?;
26646 }
26647 self.write(")");
26648 Ok(())
26649 }
26650
26651 fn generate_ephemeral_column_constraint(
26652 &mut self,
26653 e: &EphemeralColumnConstraint,
26654 ) -> Result<()> {
26655 self.write_keyword("EPHEMERAL");
26657 if let Some(this) = &e.this {
26658 self.write_space();
26659 self.generate_expression(this)?;
26660 }
26661 Ok(())
26662 }
26663
26664 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
26665 self.write_keyword("EQUAL_NULL");
26667 self.write("(");
26668 self.generate_expression(&e.this)?;
26669 self.write(", ");
26670 self.generate_expression(&e.expression)?;
26671 self.write(")");
26672 Ok(())
26673 }
26674
26675 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
26676 use crate::dialects::DialectType;
26677
26678 match self.config.dialect {
26680 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
26681 self.generate_expression(&e.this)?;
26682 self.write(" <-> ");
26683 self.generate_expression(&e.expression)?;
26684 }
26685 _ => {
26686 self.write_keyword("EUCLIDEAN_DISTANCE");
26688 self.write("(");
26689 self.generate_expression(&e.this)?;
26690 self.write(", ");
26691 self.generate_expression(&e.expression)?;
26692 self.write(")");
26693 }
26694 }
26695 Ok(())
26696 }
26697
26698 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
26699 self.write_keyword("EXECUTE AS");
26701 self.write_space();
26702 self.generate_expression(&e.this)?;
26703 Ok(())
26704 }
26705
26706 fn generate_export(&mut self, e: &Export) -> Result<()> {
26707 self.write_keyword("EXPORT DATA");
26709 if let Some(connection) = &e.connection {
26710 self.write_space();
26711 self.write_keyword("WITH CONNECTION");
26712 self.write_space();
26713 self.generate_expression(connection)?;
26714 }
26715 if !e.options.is_empty() {
26716 self.write_space();
26717 self.generate_options_clause(&e.options)?;
26718 }
26719 self.write_space();
26720 self.write_keyword("AS");
26721 self.write_space();
26722 self.generate_expression(&e.this)?;
26723 Ok(())
26724 }
26725
26726 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
26727 self.write_keyword("EXTERNAL");
26729 if let Some(this) = &e.this {
26730 self.write_space();
26731 self.generate_expression(this)?;
26732 }
26733 Ok(())
26734 }
26735
26736 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
26737 if e.no.is_some() {
26739 self.write_keyword("NO ");
26740 }
26741 self.write_keyword("FALLBACK");
26742 if e.protection.is_some() {
26743 self.write_keyword(" PROTECTION");
26744 }
26745 Ok(())
26746 }
26747
26748 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
26749 self.write_keyword("FARM_FINGERPRINT");
26751 self.write("(");
26752 for (i, expr) in e.expressions.iter().enumerate() {
26753 if i > 0 {
26754 self.write(", ");
26755 }
26756 self.generate_expression(expr)?;
26757 }
26758 self.write(")");
26759 Ok(())
26760 }
26761
26762 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
26763 self.write_keyword("FEATURES_AT_TIME");
26765 self.write("(");
26766 self.generate_expression(&e.this)?;
26767 if let Some(time) = &e.time {
26768 self.write(", ");
26769 self.generate_expression(time)?;
26770 }
26771 if let Some(num_rows) = &e.num_rows {
26772 self.write(", ");
26773 self.generate_expression(num_rows)?;
26774 }
26775 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
26776 self.write(", ");
26777 self.generate_expression(ignore_nulls)?;
26778 }
26779 self.write(")");
26780 Ok(())
26781 }
26782
26783 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
26784 let use_limit = !e.percent
26786 && !e.with_ties
26787 && e.count.is_some()
26788 && matches!(
26789 self.config.dialect,
26790 Some(DialectType::Spark)
26791 | Some(DialectType::Hive)
26792 | Some(DialectType::DuckDB)
26793 | Some(DialectType::SQLite)
26794 | Some(DialectType::MySQL)
26795 | Some(DialectType::BigQuery)
26796 | Some(DialectType::Databricks)
26797 | Some(DialectType::StarRocks)
26798 | Some(DialectType::Doris)
26799 | Some(DialectType::Athena)
26800 | Some(DialectType::ClickHouse)
26801 );
26802
26803 if use_limit {
26804 self.write_keyword("LIMIT");
26805 self.write_space();
26806 self.generate_expression(e.count.as_ref().unwrap())?;
26807 return Ok(());
26808 }
26809
26810 self.write_keyword("FETCH");
26812 if !e.direction.is_empty() {
26813 self.write_space();
26814 self.write_keyword(&e.direction);
26815 }
26816 if let Some(count) = &e.count {
26817 self.write_space();
26818 self.generate_expression(count)?;
26819 }
26820 if e.percent {
26822 self.write_keyword(" PERCENT");
26823 }
26824 if e.rows {
26825 self.write_keyword(" ROWS");
26826 }
26827 if e.with_ties {
26828 self.write_keyword(" WITH TIES");
26829 } else if e.rows {
26830 self.write_keyword(" ONLY");
26831 } else {
26832 self.write_keyword(" ROWS ONLY");
26833 }
26834 Ok(())
26835 }
26836
26837 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
26838 if e.hive_format.is_some() {
26842 self.write_keyword("STORED AS");
26844 self.write_space();
26845 if let Some(this) = &e.this {
26846 if let Expression::Identifier(id) = this.as_ref() {
26848 self.write_keyword(&id.name.to_uppercase());
26849 } else {
26850 self.generate_expression(this)?;
26851 }
26852 }
26853 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
26854 self.write_keyword("STORED AS");
26856 self.write_space();
26857 if let Some(this) = &e.this {
26858 if let Expression::Identifier(id) = this.as_ref() {
26859 self.write_keyword(&id.name.to_uppercase());
26860 } else {
26861 self.generate_expression(this)?;
26862 }
26863 }
26864 } else if matches!(
26865 self.config.dialect,
26866 Some(DialectType::Spark) | Some(DialectType::Databricks)
26867 ) {
26868 self.write_keyword("USING");
26870 self.write_space();
26871 if let Some(this) = &e.this {
26872 self.generate_expression(this)?;
26873 }
26874 } else {
26875 self.write_keyword("FILE_FORMAT");
26877 self.write(" = ");
26878 if let Some(this) = &e.this {
26879 self.generate_expression(this)?;
26880 } else if !e.expressions.is_empty() {
26881 self.write("(");
26882 for (i, expr) in e.expressions.iter().enumerate() {
26883 if i > 0 {
26884 self.write(", ");
26885 }
26886 self.generate_expression(expr)?;
26887 }
26888 self.write(")");
26889 }
26890 }
26891 Ok(())
26892 }
26893
26894 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
26895 self.generate_expression(&e.this)?;
26897 self.write_space();
26898 self.write_keyword("FILTER");
26899 self.write("(");
26900 self.write_keyword("WHERE");
26901 self.write_space();
26902 self.generate_expression(&e.expression)?;
26903 self.write(")");
26904 Ok(())
26905 }
26906
26907 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
26908 self.write_keyword("FLOAT64");
26910 self.write("(");
26911 self.generate_expression(&e.this)?;
26912 if let Some(expr) = &e.expression {
26913 self.write(", ");
26914 self.generate_expression(expr)?;
26915 }
26916 self.write(")");
26917 Ok(())
26918 }
26919
26920 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
26921 self.write_keyword("FOR");
26923 self.write_space();
26924 self.generate_expression(&e.this)?;
26925 self.write_space();
26926 self.write_keyword("DO");
26927 self.write_space();
26928 self.generate_expression(&e.expression)?;
26929 Ok(())
26930 }
26931
26932 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
26933 self.write_keyword("FOREIGN KEY");
26935 if !e.expressions.is_empty() {
26936 self.write(" (");
26937 for (i, expr) in e.expressions.iter().enumerate() {
26938 if i > 0 {
26939 self.write(", ");
26940 }
26941 self.generate_expression(expr)?;
26942 }
26943 self.write(")");
26944 }
26945 if let Some(reference) = &e.reference {
26946 self.write_space();
26947 self.generate_expression(reference)?;
26948 }
26949 if let Some(delete) = &e.delete {
26950 self.write_space();
26951 self.write_keyword("ON DELETE");
26952 self.write_space();
26953 self.generate_expression(delete)?;
26954 }
26955 if let Some(update) = &e.update {
26956 self.write_space();
26957 self.write_keyword("ON UPDATE");
26958 self.write_space();
26959 self.generate_expression(update)?;
26960 }
26961 if !e.options.is_empty() {
26962 self.write_space();
26963 for (i, opt) in e.options.iter().enumerate() {
26964 if i > 0 {
26965 self.write_space();
26966 }
26967 self.generate_expression(opt)?;
26968 }
26969 }
26970 Ok(())
26971 }
26972
26973 fn generate_format(&mut self, e: &Format) -> Result<()> {
26974 self.write_keyword("FORMAT");
26976 self.write("(");
26977 self.generate_expression(&e.this)?;
26978 for expr in &e.expressions {
26979 self.write(", ");
26980 self.generate_expression(expr)?;
26981 }
26982 self.write(")");
26983 Ok(())
26984 }
26985
26986 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
26987 self.generate_expression(&e.this)?;
26989 self.write(" (");
26990 self.write_keyword("FORMAT");
26991 self.write(" '");
26992 self.write(&e.format);
26993 self.write("')");
26994 Ok(())
26995 }
26996
26997 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
26998 self.write_keyword("FREESPACE");
27000 self.write("=");
27001 self.generate_expression(&e.this)?;
27002 if e.percent.is_some() {
27003 self.write_keyword(" PERCENT");
27004 }
27005 Ok(())
27006 }
27007
27008 fn generate_from(&mut self, e: &From) -> Result<()> {
27009 self.write_keyword("FROM");
27011 self.write_space();
27012
27013 use crate::dialects::DialectType;
27017 let has_tablesample = e
27018 .expressions
27019 .iter()
27020 .any(|expr| matches!(expr, Expression::TableSample(_)));
27021 let is_cross_join_dialect = matches!(
27022 self.config.dialect,
27023 Some(DialectType::BigQuery)
27024 | Some(DialectType::Hive)
27025 | Some(DialectType::Spark)
27026 | Some(DialectType::Databricks)
27027 | Some(DialectType::SQLite)
27028 | Some(DialectType::ClickHouse)
27029 );
27030 let source_is_same_as_target2 = self.config.source_dialect.is_some()
27031 && self.config.source_dialect == self.config.dialect;
27032 let source_is_cross_join_dialect2 = matches!(
27033 self.config.source_dialect,
27034 Some(DialectType::BigQuery)
27035 | Some(DialectType::Hive)
27036 | Some(DialectType::Spark)
27037 | Some(DialectType::Databricks)
27038 | Some(DialectType::SQLite)
27039 | Some(DialectType::ClickHouse)
27040 );
27041 let use_cross_join = !has_tablesample
27042 && is_cross_join_dialect
27043 && (source_is_same_as_target2
27044 || source_is_cross_join_dialect2
27045 || self.config.source_dialect.is_none());
27046
27047 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
27049
27050 for (i, expr) in e.expressions.iter().enumerate() {
27051 if i > 0 {
27052 if use_cross_join {
27053 self.write(" CROSS JOIN ");
27054 } else {
27055 self.write(", ");
27056 }
27057 }
27058 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
27059 self.write("(");
27060 self.generate_expression(expr)?;
27061 self.write(")");
27062 } else {
27063 self.generate_expression(expr)?;
27064 }
27065 }
27066 Ok(())
27067 }
27068
27069 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
27070 self.write_keyword("FROM_BASE");
27072 self.write("(");
27073 self.generate_expression(&e.this)?;
27074 self.write(", ");
27075 self.generate_expression(&e.expression)?;
27076 self.write(")");
27077 Ok(())
27078 }
27079
27080 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
27081 self.generate_expression(&e.this)?;
27083 if let Some(zone) = &e.zone {
27084 self.write_space();
27085 self.write_keyword("AT TIME ZONE");
27086 self.write_space();
27087 self.generate_expression(zone)?;
27088 self.write_space();
27089 self.write_keyword("AT TIME ZONE");
27090 self.write(" 'UTC'");
27091 }
27092 Ok(())
27093 }
27094
27095 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
27096 self.write_keyword("GAP_FILL");
27098 self.write("(");
27099 self.generate_expression(&e.this)?;
27100 if let Some(ts_column) = &e.ts_column {
27101 self.write(", ");
27102 self.generate_expression(ts_column)?;
27103 }
27104 if let Some(bucket_width) = &e.bucket_width {
27105 self.write(", ");
27106 self.generate_expression(bucket_width)?;
27107 }
27108 if let Some(partitioning_columns) = &e.partitioning_columns {
27109 self.write(", ");
27110 self.generate_expression(partitioning_columns)?;
27111 }
27112 if let Some(value_columns) = &e.value_columns {
27113 self.write(", ");
27114 self.generate_expression(value_columns)?;
27115 }
27116 self.write(")");
27117 Ok(())
27118 }
27119
27120 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
27121 self.write_keyword("GENERATE_DATE_ARRAY");
27123 self.write("(");
27124 let mut first = true;
27125 if let Some(start) = &e.start {
27126 self.generate_expression(start)?;
27127 first = false;
27128 }
27129 if let Some(end) = &e.end {
27130 if !first {
27131 self.write(", ");
27132 }
27133 self.generate_expression(end)?;
27134 first = false;
27135 }
27136 if let Some(step) = &e.step {
27137 if !first {
27138 self.write(", ");
27139 }
27140 self.generate_expression(step)?;
27141 }
27142 self.write(")");
27143 Ok(())
27144 }
27145
27146 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
27147 self.write_keyword("ML.GENERATE_EMBEDDING");
27149 self.write("(");
27150 self.generate_expression(&e.this)?;
27151 self.write(", ");
27152 self.generate_expression(&e.expression)?;
27153 if let Some(params) = &e.params_struct {
27154 self.write(", ");
27155 self.generate_expression(params)?;
27156 }
27157 self.write(")");
27158 Ok(())
27159 }
27160
27161 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
27162 let fn_name = match self.config.dialect {
27164 Some(DialectType::Presto)
27165 | Some(DialectType::Trino)
27166 | Some(DialectType::Athena)
27167 | Some(DialectType::Spark)
27168 | Some(DialectType::Databricks)
27169 | Some(DialectType::Hive) => "SEQUENCE",
27170 _ => "GENERATE_SERIES",
27171 };
27172 self.write_keyword(fn_name);
27173 self.write("(");
27174 let mut first = true;
27175 if let Some(start) = &e.start {
27176 self.generate_expression(start)?;
27177 first = false;
27178 }
27179 if let Some(end) = &e.end {
27180 if !first {
27181 self.write(", ");
27182 }
27183 self.generate_expression(end)?;
27184 first = false;
27185 }
27186 if let Some(step) = &e.step {
27187 if !first {
27188 self.write(", ");
27189 }
27190 if matches!(
27193 self.config.dialect,
27194 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
27195 ) {
27196 if let Some(converted) = self.convert_week_interval_to_day(step) {
27197 self.generate_expression(&converted)?;
27198 } else {
27199 self.generate_expression(step)?;
27200 }
27201 } else {
27202 self.generate_expression(step)?;
27203 }
27204 }
27205 self.write(")");
27206 Ok(())
27207 }
27208
27209 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
27212 use crate::expressions::*;
27213 if let Expression::Interval(ref iv) = expr {
27214 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
27216 unit: IntervalUnit::Week,
27217 ..
27218 }) = &iv.unit
27219 {
27220 let count = match &iv.this {
27222 Some(Expression::Literal(Literal::String(s))) => s.clone(),
27223 Some(Expression::Literal(Literal::Number(s))) => s.clone(),
27224 _ => return None,
27225 };
27226 (true, count)
27227 } else if iv.unit.is_none() {
27228 if let Some(Expression::Literal(Literal::String(s))) = &iv.this {
27230 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
27231 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
27232 (true, parts[0].to_string())
27233 } else {
27234 (false, String::new())
27235 }
27236 } else {
27237 (false, String::new())
27238 }
27239 } else {
27240 (false, String::new())
27241 };
27242
27243 if is_week {
27244 let count_expr = Expression::Literal(Literal::Number(count_str));
27246 let day_interval = Expression::Interval(Box::new(Interval {
27247 this: Some(Expression::Literal(Literal::String("7".to_string()))),
27248 unit: Some(IntervalUnitSpec::Simple {
27249 unit: IntervalUnit::Day,
27250 use_plural: false,
27251 }),
27252 }));
27253 let mul = Expression::Mul(Box::new(BinaryOp {
27254 left: count_expr,
27255 right: day_interval,
27256 left_comments: vec![],
27257 operator_comments: vec![],
27258 trailing_comments: vec![],
27259 }));
27260 return Some(Expression::Paren(Box::new(Paren {
27261 this: mul,
27262 trailing_comments: vec![],
27263 })));
27264 }
27265 }
27266 None
27267 }
27268
27269 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
27270 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
27272 self.write("(");
27273 let mut first = true;
27274 if let Some(start) = &e.start {
27275 self.generate_expression(start)?;
27276 first = false;
27277 }
27278 if let Some(end) = &e.end {
27279 if !first {
27280 self.write(", ");
27281 }
27282 self.generate_expression(end)?;
27283 first = false;
27284 }
27285 if let Some(step) = &e.step {
27286 if !first {
27287 self.write(", ");
27288 }
27289 self.generate_expression(step)?;
27290 }
27291 self.write(")");
27292 Ok(())
27293 }
27294
27295 fn generate_generated_as_identity_column_constraint(
27296 &mut self,
27297 e: &GeneratedAsIdentityColumnConstraint,
27298 ) -> Result<()> {
27299 use crate::dialects::DialectType;
27300
27301 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
27303 self.write_keyword("AUTOINCREMENT");
27304 if let Some(start) = &e.start {
27305 self.write_keyword(" START ");
27306 self.generate_expression(start)?;
27307 }
27308 if let Some(increment) = &e.increment {
27309 self.write_keyword(" INCREMENT ");
27310 self.generate_expression(increment)?;
27311 }
27312 return Ok(());
27313 }
27314
27315 self.write_keyword("GENERATED");
27317 if let Some(this) = &e.this {
27318 if let Expression::Boolean(b) = this.as_ref() {
27320 if b.value {
27321 self.write_keyword(" ALWAYS");
27322 } else {
27323 self.write_keyword(" BY DEFAULT");
27324 if e.on_null.is_some() {
27325 self.write_keyword(" ON NULL");
27326 }
27327 }
27328 } else {
27329 self.write_keyword(" ALWAYS");
27330 }
27331 }
27332 self.write_keyword(" AS IDENTITY");
27333 let has_options = e.start.is_some()
27335 || e.increment.is_some()
27336 || e.minvalue.is_some()
27337 || e.maxvalue.is_some();
27338 if has_options {
27339 self.write(" (");
27340 let mut first = true;
27341 if let Some(start) = &e.start {
27342 self.write_keyword("START WITH ");
27343 self.generate_expression(start)?;
27344 first = false;
27345 }
27346 if let Some(increment) = &e.increment {
27347 if !first {
27348 self.write(" ");
27349 }
27350 self.write_keyword("INCREMENT BY ");
27351 self.generate_expression(increment)?;
27352 first = false;
27353 }
27354 if let Some(minvalue) = &e.minvalue {
27355 if !first {
27356 self.write(" ");
27357 }
27358 self.write_keyword("MINVALUE ");
27359 self.generate_expression(minvalue)?;
27360 first = false;
27361 }
27362 if let Some(maxvalue) = &e.maxvalue {
27363 if !first {
27364 self.write(" ");
27365 }
27366 self.write_keyword("MAXVALUE ");
27367 self.generate_expression(maxvalue)?;
27368 }
27369 self.write(")");
27370 }
27371 Ok(())
27372 }
27373
27374 fn generate_generated_as_row_column_constraint(
27375 &mut self,
27376 e: &GeneratedAsRowColumnConstraint,
27377 ) -> Result<()> {
27378 self.write_keyword("GENERATED ALWAYS AS ROW ");
27380 if e.start.is_some() {
27381 self.write_keyword("START");
27382 } else {
27383 self.write_keyword("END");
27384 }
27385 if e.hidden.is_some() {
27386 self.write_keyword(" HIDDEN");
27387 }
27388 Ok(())
27389 }
27390
27391 fn generate_get(&mut self, e: &Get) -> Result<()> {
27392 self.write_keyword("GET");
27394 self.write_space();
27395 self.generate_expression(&e.this)?;
27396 if let Some(target) = &e.target {
27397 self.write_space();
27398 self.generate_expression(target)?;
27399 }
27400 for prop in &e.properties {
27401 self.write_space();
27402 self.generate_expression(prop)?;
27403 }
27404 Ok(())
27405 }
27406
27407 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
27408 self.generate_expression(&e.this)?;
27410 self.write("[");
27411 self.generate_expression(&e.expression)?;
27412 self.write("]");
27413 Ok(())
27414 }
27415
27416 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
27417 self.write_keyword("GETBIT");
27419 self.write("(");
27420 self.generate_expression(&e.this)?;
27421 self.write(", ");
27422 self.generate_expression(&e.expression)?;
27423 self.write(")");
27424 Ok(())
27425 }
27426
27427 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
27428 if e.is_role {
27430 self.write_keyword("ROLE");
27431 self.write_space();
27432 } else if e.is_group {
27433 self.write_keyword("GROUP");
27434 self.write_space();
27435 }
27436 self.write(&e.name.name);
27437 Ok(())
27438 }
27439
27440 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
27441 self.generate_expression(&e.this)?;
27443 if !e.expressions.is_empty() {
27444 self.write("(");
27445 for (i, expr) in e.expressions.iter().enumerate() {
27446 if i > 0 {
27447 self.write(", ");
27448 }
27449 self.generate_expression(expr)?;
27450 }
27451 self.write(")");
27452 }
27453 Ok(())
27454 }
27455
27456 fn generate_group(&mut self, e: &Group) -> Result<()> {
27457 self.write_keyword("GROUP BY");
27459 match e.all {
27461 Some(true) => {
27462 self.write_space();
27463 self.write_keyword("ALL");
27464 }
27465 Some(false) => {
27466 self.write_space();
27467 self.write_keyword("DISTINCT");
27468 }
27469 None => {}
27470 }
27471 if !e.expressions.is_empty() {
27472 self.write_space();
27473 for (i, expr) in e.expressions.iter().enumerate() {
27474 if i > 0 {
27475 self.write(", ");
27476 }
27477 self.generate_expression(expr)?;
27478 }
27479 }
27480 if let Some(cube) = &e.cube {
27482 if !e.expressions.is_empty() {
27483 self.write(", ");
27484 } else {
27485 self.write_space();
27486 }
27487 self.generate_expression(cube)?;
27488 }
27489 if let Some(rollup) = &e.rollup {
27490 if !e.expressions.is_empty() || e.cube.is_some() {
27491 self.write(", ");
27492 } else {
27493 self.write_space();
27494 }
27495 self.generate_expression(rollup)?;
27496 }
27497 if let Some(grouping_sets) = &e.grouping_sets {
27498 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
27499 self.write(", ");
27500 } else {
27501 self.write_space();
27502 }
27503 self.generate_expression(grouping_sets)?;
27504 }
27505 if let Some(totals) = &e.totals {
27506 self.write_space();
27507 self.write_keyword("WITH TOTALS");
27508 self.generate_expression(totals)?;
27509 }
27510 Ok(())
27511 }
27512
27513 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
27514 self.write_keyword("GROUP BY");
27516 match e.all {
27518 Some(true) => {
27519 self.write_space();
27520 self.write_keyword("ALL");
27521 }
27522 Some(false) => {
27523 self.write_space();
27524 self.write_keyword("DISTINCT");
27525 }
27526 None => {}
27527 }
27528
27529 let mut trailing_cube = false;
27532 let mut trailing_rollup = false;
27533 let mut regular_expressions: Vec<&Expression> = Vec::new();
27534
27535 for expr in &e.expressions {
27536 match expr {
27537 Expression::Cube(c) if c.expressions.is_empty() => {
27538 trailing_cube = true;
27539 }
27540 Expression::Rollup(r) if r.expressions.is_empty() => {
27541 trailing_rollup = true;
27542 }
27543 _ => {
27544 regular_expressions.push(expr);
27545 }
27546 }
27547 }
27548
27549 if self.config.pretty {
27551 self.write_newline();
27552 self.indent_level += 1;
27553 for (i, expr) in regular_expressions.iter().enumerate() {
27554 if i > 0 {
27555 self.write(",");
27556 self.write_newline();
27557 }
27558 self.write_indent();
27559 self.generate_expression(expr)?;
27560 }
27561 self.indent_level -= 1;
27562 } else {
27563 self.write_space();
27564 for (i, expr) in regular_expressions.iter().enumerate() {
27565 if i > 0 {
27566 self.write(", ");
27567 }
27568 self.generate_expression(expr)?;
27569 }
27570 }
27571
27572 if trailing_cube {
27574 self.write_space();
27575 self.write_keyword("WITH CUBE");
27576 } else if trailing_rollup {
27577 self.write_space();
27578 self.write_keyword("WITH ROLLUP");
27579 }
27580
27581 if e.totals {
27583 self.write_space();
27584 self.write_keyword("WITH TOTALS");
27585 }
27586
27587 Ok(())
27588 }
27589
27590 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
27591 self.write_keyword("GROUPING");
27593 self.write("(");
27594 for (i, expr) in e.expressions.iter().enumerate() {
27595 if i > 0 {
27596 self.write(", ");
27597 }
27598 self.generate_expression(expr)?;
27599 }
27600 self.write(")");
27601 Ok(())
27602 }
27603
27604 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
27605 self.write_keyword("GROUPING_ID");
27607 self.write("(");
27608 for (i, expr) in e.expressions.iter().enumerate() {
27609 if i > 0 {
27610 self.write(", ");
27611 }
27612 self.generate_expression(expr)?;
27613 }
27614 self.write(")");
27615 Ok(())
27616 }
27617
27618 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
27619 self.write_keyword("GROUPING SETS");
27621 self.write(" (");
27622 for (i, expr) in e.expressions.iter().enumerate() {
27623 if i > 0 {
27624 self.write(", ");
27625 }
27626 self.generate_expression(expr)?;
27627 }
27628 self.write(")");
27629 Ok(())
27630 }
27631
27632 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
27633 self.write_keyword("HASH_AGG");
27635 self.write("(");
27636 self.generate_expression(&e.this)?;
27637 for expr in &e.expressions {
27638 self.write(", ");
27639 self.generate_expression(expr)?;
27640 }
27641 self.write(")");
27642 Ok(())
27643 }
27644
27645 fn generate_having(&mut self, e: &Having) -> Result<()> {
27646 self.write_keyword("HAVING");
27648 self.write_space();
27649 self.generate_expression(&e.this)?;
27650 Ok(())
27651 }
27652
27653 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
27654 self.generate_expression(&e.this)?;
27656 self.write_space();
27657 self.write_keyword("HAVING");
27658 self.write_space();
27659 if e.max.is_some() {
27660 self.write_keyword("MAX");
27661 } else {
27662 self.write_keyword("MIN");
27663 }
27664 self.write_space();
27665 self.generate_expression(&e.expression)?;
27666 Ok(())
27667 }
27668
27669 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
27670 use crate::dialects::DialectType;
27671 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
27673 if let Expression::Literal(Literal::String(ref s)) = *e.this {
27675 return self.generate_string_literal(s);
27676 }
27677 }
27678 if matches!(
27680 self.config.dialect,
27681 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
27682 ) {
27683 self.write("$");
27684 if let Some(tag) = &e.tag {
27685 self.generate_expression(tag)?;
27686 }
27687 self.write("$");
27688 self.generate_expression(&e.this)?;
27689 self.write("$");
27690 if let Some(tag) = &e.tag {
27691 self.generate_expression(tag)?;
27692 }
27693 self.write("$");
27694 return Ok(());
27695 }
27696 self.write("$");
27698 if let Some(tag) = &e.tag {
27699 self.generate_expression(tag)?;
27700 }
27701 self.write("$");
27702 self.generate_expression(&e.this)?;
27703 self.write("$");
27704 if let Some(tag) = &e.tag {
27705 self.generate_expression(tag)?;
27706 }
27707 self.write("$");
27708 Ok(())
27709 }
27710
27711 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
27712 self.write_keyword("HEX_ENCODE");
27714 self.write("(");
27715 self.generate_expression(&e.this)?;
27716 self.write(")");
27717 Ok(())
27718 }
27719
27720 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
27721 match e.this.as_ref() {
27724 Expression::Identifier(id) => self.write(&id.name),
27725 other => self.generate_expression(other)?,
27726 }
27727 self.write(" (");
27728 self.write(&e.kind);
27729 self.write(" => ");
27730 self.generate_expression(&e.expression)?;
27731 self.write(")");
27732 Ok(())
27733 }
27734
27735 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
27736 self.write_keyword("HLL");
27738 self.write("(");
27739 self.generate_expression(&e.this)?;
27740 for expr in &e.expressions {
27741 self.write(", ");
27742 self.generate_expression(expr)?;
27743 }
27744 self.write(")");
27745 Ok(())
27746 }
27747
27748 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
27749 if e.input_.is_some() && e.output.is_some() {
27751 self.write_keyword("IN OUT");
27752 } else if e.input_.is_some() {
27753 self.write_keyword("IN");
27754 } else if e.output.is_some() {
27755 self.write_keyword("OUT");
27756 }
27757 Ok(())
27758 }
27759
27760 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
27761 self.write_keyword("INCLUDE");
27763 self.write_space();
27764 self.generate_expression(&e.this)?;
27765 if let Some(column_def) = &e.column_def {
27766 self.write_space();
27767 self.generate_expression(column_def)?;
27768 }
27769 if let Some(alias) = &e.alias {
27770 self.write_space();
27771 self.write_keyword("AS");
27772 self.write_space();
27773 self.write(alias);
27774 }
27775 Ok(())
27776 }
27777
27778 fn generate_index(&mut self, e: &Index) -> Result<()> {
27779 if e.unique {
27781 self.write_keyword("UNIQUE");
27782 self.write_space();
27783 }
27784 if e.primary.is_some() {
27785 self.write_keyword("PRIMARY");
27786 self.write_space();
27787 }
27788 if e.amp.is_some() {
27789 self.write_keyword("AMP");
27790 self.write_space();
27791 }
27792 if e.table.is_none() {
27793 self.write_keyword("INDEX");
27794 self.write_space();
27795 }
27796 if let Some(name) = &e.this {
27797 self.generate_expression(name)?;
27798 self.write_space();
27799 }
27800 if let Some(table) = &e.table {
27801 self.write_keyword("ON");
27802 self.write_space();
27803 self.generate_expression(table)?;
27804 }
27805 if !e.params.is_empty() {
27806 self.write("(");
27807 for (i, param) in e.params.iter().enumerate() {
27808 if i > 0 {
27809 self.write(", ");
27810 }
27811 self.generate_expression(param)?;
27812 }
27813 self.write(")");
27814 }
27815 Ok(())
27816 }
27817
27818 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
27819 if let Some(kind) = &e.kind {
27821 self.write(kind);
27822 self.write_space();
27823 }
27824 self.write_keyword("INDEX");
27825 if let Some(this) = &e.this {
27826 self.write_space();
27827 self.generate_expression(this)?;
27828 }
27829 if let Some(index_type) = &e.index_type {
27830 self.write_space();
27831 self.write_keyword("USING");
27832 self.write_space();
27833 self.generate_expression(index_type)?;
27834 }
27835 if !e.expressions.is_empty() {
27836 self.write(" (");
27837 for (i, expr) in e.expressions.iter().enumerate() {
27838 if i > 0 {
27839 self.write(", ");
27840 }
27841 self.generate_expression(expr)?;
27842 }
27843 self.write(")");
27844 }
27845 for opt in &e.options {
27846 self.write_space();
27847 self.generate_expression(opt)?;
27848 }
27849 Ok(())
27850 }
27851
27852 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
27853 if let Some(key_block_size) = &e.key_block_size {
27855 self.write_keyword("KEY_BLOCK_SIZE");
27856 self.write(" = ");
27857 self.generate_expression(key_block_size)?;
27858 } else if let Some(using) = &e.using {
27859 self.write_keyword("USING");
27860 self.write_space();
27861 self.generate_expression(using)?;
27862 } else if let Some(parser) = &e.parser {
27863 self.write_keyword("WITH PARSER");
27864 self.write_space();
27865 self.generate_expression(parser)?;
27866 } else if let Some(comment) = &e.comment {
27867 self.write_keyword("COMMENT");
27868 self.write_space();
27869 self.generate_expression(comment)?;
27870 } else if let Some(visible) = &e.visible {
27871 self.generate_expression(visible)?;
27872 } else if let Some(engine_attr) = &e.engine_attr {
27873 self.write_keyword("ENGINE_ATTRIBUTE");
27874 self.write(" = ");
27875 self.generate_expression(engine_attr)?;
27876 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
27877 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
27878 self.write(" = ");
27879 self.generate_expression(secondary_engine_attr)?;
27880 }
27881 Ok(())
27882 }
27883
27884 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
27885 if let Some(using) = &e.using {
27887 self.write_keyword("USING");
27888 self.write_space();
27889 self.generate_expression(using)?;
27890 }
27891 if !e.columns.is_empty() {
27892 self.write("(");
27893 for (i, col) in e.columns.iter().enumerate() {
27894 if i > 0 {
27895 self.write(", ");
27896 }
27897 self.generate_expression(col)?;
27898 }
27899 self.write(")");
27900 }
27901 if let Some(partition_by) = &e.partition_by {
27902 self.write_space();
27903 self.write_keyword("PARTITION BY");
27904 self.write_space();
27905 self.generate_expression(partition_by)?;
27906 }
27907 if let Some(where_) = &e.where_ {
27908 self.write_space();
27909 self.generate_expression(where_)?;
27910 }
27911 if let Some(include) = &e.include {
27912 self.write_space();
27913 self.write_keyword("INCLUDE");
27914 self.write(" (");
27915 self.generate_expression(include)?;
27916 self.write(")");
27917 }
27918 if let Some(with_storage) = &e.with_storage {
27919 self.write_space();
27920 self.write_keyword("WITH");
27921 self.write(" (");
27922 self.generate_expression(with_storage)?;
27923 self.write(")");
27924 }
27925 if let Some(tablespace) = &e.tablespace {
27926 self.write_space();
27927 self.write_keyword("USING INDEX TABLESPACE");
27928 self.write_space();
27929 self.generate_expression(tablespace)?;
27930 }
27931 Ok(())
27932 }
27933
27934 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
27935 if let Expression::Identifier(id) = &*e.this {
27939 self.write_keyword(&id.name);
27940 } else {
27941 self.generate_expression(&e.this)?;
27942 }
27943 self.write_space();
27944 self.write_keyword("INDEX");
27945 if let Some(target) = &e.target {
27946 self.write_space();
27947 self.write_keyword("FOR");
27948 self.write_space();
27949 if let Expression::Identifier(id) = &**target {
27950 self.write_keyword(&id.name);
27951 } else {
27952 self.generate_expression(target)?;
27953 }
27954 }
27955 self.write(" (");
27957 for (i, expr) in e.expressions.iter().enumerate() {
27958 if i > 0 {
27959 self.write(", ");
27960 }
27961 self.generate_expression(expr)?;
27962 }
27963 self.write(")");
27964 Ok(())
27965 }
27966
27967 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
27968 self.write_keyword("INHERITS");
27970 self.write(" (");
27971 for (i, expr) in e.expressions.iter().enumerate() {
27972 if i > 0 {
27973 self.write(", ");
27974 }
27975 self.generate_expression(expr)?;
27976 }
27977 self.write(")");
27978 Ok(())
27979 }
27980
27981 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
27982 self.write_keyword("INPUT");
27984 self.write("(");
27985 self.generate_expression(&e.this)?;
27986 self.write(")");
27987 Ok(())
27988 }
27989
27990 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
27991 if let Some(input_format) = &e.input_format {
27993 self.write_keyword("INPUTFORMAT");
27994 self.write_space();
27995 self.generate_expression(input_format)?;
27996 }
27997 if let Some(output_format) = &e.output_format {
27998 if e.input_format.is_some() {
27999 self.write(" ");
28000 }
28001 self.write_keyword("OUTPUTFORMAT");
28002 self.write_space();
28003 self.generate_expression(output_format)?;
28004 }
28005 Ok(())
28006 }
28007
28008 fn generate_install(&mut self, e: &Install) -> Result<()> {
28009 if e.force.is_some() {
28011 self.write_keyword("FORCE");
28012 self.write_space();
28013 }
28014 self.write_keyword("INSTALL");
28015 self.write_space();
28016 self.generate_expression(&e.this)?;
28017 if let Some(from) = &e.from_ {
28018 self.write_space();
28019 self.write_keyword("FROM");
28020 self.write_space();
28021 self.generate_expression(from)?;
28022 }
28023 Ok(())
28024 }
28025
28026 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
28027 self.write_keyword("INTERVAL");
28029 self.write_space();
28030 self.generate_expression(&e.expression)?;
28032 if let Some(unit) = &e.unit {
28033 self.write_space();
28034 self.write(unit);
28035 }
28036 Ok(())
28037 }
28038
28039 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
28040 self.write(&format!("{:?}", e.this).to_uppercase());
28042 self.write_space();
28043 self.write_keyword("TO");
28044 self.write_space();
28045 self.write(&format!("{:?}", e.expression).to_uppercase());
28046 Ok(())
28047 }
28048
28049 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
28050 self.write_keyword("INTO");
28052 if e.temporary {
28053 self.write_keyword(" TEMPORARY");
28054 }
28055 if e.unlogged.is_some() {
28056 self.write_keyword(" UNLOGGED");
28057 }
28058 if let Some(this) = &e.this {
28059 self.write_space();
28060 self.generate_expression(this)?;
28061 }
28062 if !e.expressions.is_empty() {
28063 self.write(" (");
28064 for (i, expr) in e.expressions.iter().enumerate() {
28065 if i > 0 {
28066 self.write(", ");
28067 }
28068 self.generate_expression(expr)?;
28069 }
28070 self.write(")");
28071 }
28072 Ok(())
28073 }
28074
28075 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
28076 self.generate_expression(&e.this)?;
28078 self.write_space();
28079 self.generate_expression(&e.expression)?;
28080 Ok(())
28081 }
28082
28083 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
28084 self.write_keyword("WITH");
28086 if e.no.is_some() {
28087 self.write_keyword(" NO");
28088 }
28089 if e.concurrent.is_some() {
28090 self.write_keyword(" CONCURRENT");
28091 }
28092 self.write_keyword(" ISOLATED LOADING");
28093 if let Some(target) = &e.target {
28094 self.write_space();
28095 self.generate_expression(target)?;
28096 }
28097 Ok(())
28098 }
28099
28100 fn generate_json(&mut self, e: &JSON) -> Result<()> {
28101 self.write_keyword("JSON");
28103 if let Some(this) = &e.this {
28104 self.write_space();
28105 self.generate_expression(this)?;
28106 }
28107 if let Some(with_) = &e.with_ {
28108 if let Expression::Boolean(b) = with_.as_ref() {
28110 if b.value {
28111 self.write_keyword(" WITH");
28112 } else {
28113 self.write_keyword(" WITHOUT");
28114 }
28115 }
28116 }
28117 if e.unique {
28118 self.write_keyword(" UNIQUE KEYS");
28119 }
28120 Ok(())
28121 }
28122
28123 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
28124 self.write_keyword("JSON_ARRAY");
28126 self.write("(");
28127 for (i, expr) in e.expressions.iter().enumerate() {
28128 if i > 0 {
28129 self.write(", ");
28130 }
28131 self.generate_expression(expr)?;
28132 }
28133 if let Some(null_handling) = &e.null_handling {
28134 self.write_space();
28135 self.generate_expression(null_handling)?;
28136 }
28137 if let Some(return_type) = &e.return_type {
28138 self.write_space();
28139 self.write_keyword("RETURNING");
28140 self.write_space();
28141 self.generate_expression(return_type)?;
28142 }
28143 if e.strict.is_some() {
28144 self.write_space();
28145 self.write_keyword("STRICT");
28146 }
28147 self.write(")");
28148 Ok(())
28149 }
28150
28151 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
28152 self.write_keyword("JSON_ARRAYAGG");
28154 self.write("(");
28155 self.generate_expression(&e.this)?;
28156 if let Some(order) = &e.order {
28157 self.write_space();
28158 if let Expression::OrderBy(ob) = order.as_ref() {
28160 self.write_keyword("ORDER BY");
28161 self.write_space();
28162 for (i, ord) in ob.expressions.iter().enumerate() {
28163 if i > 0 {
28164 self.write(", ");
28165 }
28166 self.generate_ordered(ord)?;
28167 }
28168 } else {
28169 self.generate_expression(order)?;
28171 }
28172 }
28173 if let Some(null_handling) = &e.null_handling {
28174 self.write_space();
28175 self.generate_expression(null_handling)?;
28176 }
28177 if let Some(return_type) = &e.return_type {
28178 self.write_space();
28179 self.write_keyword("RETURNING");
28180 self.write_space();
28181 self.generate_expression(return_type)?;
28182 }
28183 if e.strict.is_some() {
28184 self.write_space();
28185 self.write_keyword("STRICT");
28186 }
28187 self.write(")");
28188 Ok(())
28189 }
28190
28191 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
28192 self.write_keyword("JSON_OBJECTAGG");
28194 self.write("(");
28195 for (i, expr) in e.expressions.iter().enumerate() {
28196 if i > 0 {
28197 self.write(", ");
28198 }
28199 self.generate_expression(expr)?;
28200 }
28201 if let Some(null_handling) = &e.null_handling {
28202 self.write_space();
28203 self.generate_expression(null_handling)?;
28204 }
28205 if let Some(unique_keys) = &e.unique_keys {
28206 self.write_space();
28207 if let Expression::Boolean(b) = unique_keys.as_ref() {
28208 if b.value {
28209 self.write_keyword("WITH UNIQUE KEYS");
28210 } else {
28211 self.write_keyword("WITHOUT UNIQUE KEYS");
28212 }
28213 }
28214 }
28215 if let Some(return_type) = &e.return_type {
28216 self.write_space();
28217 self.write_keyword("RETURNING");
28218 self.write_space();
28219 self.generate_expression(return_type)?;
28220 }
28221 self.write(")");
28222 Ok(())
28223 }
28224
28225 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
28226 self.write_keyword("JSON_ARRAY_APPEND");
28228 self.write("(");
28229 self.generate_expression(&e.this)?;
28230 for expr in &e.expressions {
28231 self.write(", ");
28232 self.generate_expression(expr)?;
28233 }
28234 self.write(")");
28235 Ok(())
28236 }
28237
28238 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
28239 self.write_keyword("JSON_ARRAY_CONTAINS");
28241 self.write("(");
28242 self.generate_expression(&e.this)?;
28243 self.write(", ");
28244 self.generate_expression(&e.expression)?;
28245 self.write(")");
28246 Ok(())
28247 }
28248
28249 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
28250 self.write_keyword("JSON_ARRAY_INSERT");
28252 self.write("(");
28253 self.generate_expression(&e.this)?;
28254 for expr in &e.expressions {
28255 self.write(", ");
28256 self.generate_expression(expr)?;
28257 }
28258 self.write(")");
28259 Ok(())
28260 }
28261
28262 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
28263 self.write_keyword("JSONB_EXISTS");
28265 self.write("(");
28266 self.generate_expression(&e.this)?;
28267 if let Some(path) = &e.path {
28268 self.write(", ");
28269 self.generate_expression(path)?;
28270 }
28271 self.write(")");
28272 Ok(())
28273 }
28274
28275 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
28276 self.write_keyword("JSONB_EXTRACT_SCALAR");
28278 self.write("(");
28279 self.generate_expression(&e.this)?;
28280 self.write(", ");
28281 self.generate_expression(&e.expression)?;
28282 self.write(")");
28283 Ok(())
28284 }
28285
28286 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
28287 self.write_keyword("JSONB_OBJECT_AGG");
28289 self.write("(");
28290 self.generate_expression(&e.this)?;
28291 self.write(", ");
28292 self.generate_expression(&e.expression)?;
28293 self.write(")");
28294 Ok(())
28295 }
28296
28297 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
28298 if let Some(nested_schema) = &e.nested_schema {
28300 self.write_keyword("NESTED");
28301 if let Some(path) = &e.path {
28302 self.write_space();
28303 self.write_keyword("PATH");
28304 self.write_space();
28305 self.generate_expression(path)?;
28306 }
28307 self.write_space();
28308 self.generate_expression(nested_schema)?;
28309 } else {
28310 if let Some(this) = &e.this {
28311 self.generate_expression(this)?;
28312 }
28313 if let Some(kind) = &e.kind {
28314 self.write_space();
28315 self.write(kind);
28316 }
28317 if let Some(path) = &e.path {
28318 self.write_space();
28319 self.write_keyword("PATH");
28320 self.write_space();
28321 self.generate_expression(path)?;
28322 }
28323 if e.ordinality.is_some() {
28324 self.write_keyword(" FOR ORDINALITY");
28325 }
28326 }
28327 Ok(())
28328 }
28329
28330 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
28331 self.write_keyword("JSON_EXISTS");
28333 self.write("(");
28334 self.generate_expression(&e.this)?;
28335 if let Some(path) = &e.path {
28336 self.write(", ");
28337 self.generate_expression(path)?;
28338 }
28339 if let Some(passing) = &e.passing {
28340 self.write_space();
28341 self.write_keyword("PASSING");
28342 self.write_space();
28343 self.generate_expression(passing)?;
28344 }
28345 if let Some(on_condition) = &e.on_condition {
28346 self.write_space();
28347 self.generate_expression(on_condition)?;
28348 }
28349 self.write(")");
28350 Ok(())
28351 }
28352
28353 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
28354 self.generate_expression(&e.this)?;
28355 self.write(".:");
28356 self.generate_data_type(&e.to)?;
28357 Ok(())
28358 }
28359
28360 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
28361 self.write_keyword("JSON_EXTRACT_ARRAY");
28363 self.write("(");
28364 self.generate_expression(&e.this)?;
28365 if let Some(expr) = &e.expression {
28366 self.write(", ");
28367 self.generate_expression(expr)?;
28368 }
28369 self.write(")");
28370 Ok(())
28371 }
28372
28373 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
28374 if let Some(option) = &e.option {
28376 self.generate_expression(option)?;
28377 self.write_space();
28378 }
28379 self.write_keyword("QUOTES");
28380 if e.scalar.is_some() {
28381 self.write_keyword(" SCALAR_ONLY");
28382 }
28383 Ok(())
28384 }
28385
28386 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
28387 self.write_keyword("JSON_EXTRACT_SCALAR");
28389 self.write("(");
28390 self.generate_expression(&e.this)?;
28391 self.write(", ");
28392 self.generate_expression(&e.expression)?;
28393 self.write(")");
28394 Ok(())
28395 }
28396
28397 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
28398 if e.variant_extract.is_some() {
28402 use crate::dialects::DialectType;
28403 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
28404 self.generate_expression(&e.this)?;
28406 self.write(":");
28407 match e.expression.as_ref() {
28410 Expression::Literal(Literal::String(s)) => {
28411 self.write(s);
28412 }
28413 _ => {
28414 self.generate_expression(&e.expression)?;
28416 }
28417 }
28418 } else {
28419 self.write_keyword("GET_PATH");
28421 self.write("(");
28422 self.generate_expression(&e.this)?;
28423 self.write(", ");
28424 self.generate_expression(&e.expression)?;
28425 self.write(")");
28426 }
28427 } else {
28428 self.write_keyword("JSON_EXTRACT");
28429 self.write("(");
28430 self.generate_expression(&e.this)?;
28431 self.write(", ");
28432 self.generate_expression(&e.expression)?;
28433 for expr in &e.expressions {
28434 self.write(", ");
28435 self.generate_expression(expr)?;
28436 }
28437 self.write(")");
28438 }
28439 Ok(())
28440 }
28441
28442 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
28443 if let Some(this) = &e.this {
28446 self.generate_expression(this)?;
28447 self.write_space();
28448 }
28449 self.write_keyword("FORMAT JSON");
28450 Ok(())
28451 }
28452
28453 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
28454 self.generate_expression(&e.this)?;
28456 self.write(": ");
28457 self.generate_expression(&e.expression)?;
28458 Ok(())
28459 }
28460
28461 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
28462 self.write_keyword("JSON_KEYS");
28464 self.write("(");
28465 self.generate_expression(&e.this)?;
28466 if let Some(expr) = &e.expression {
28467 self.write(", ");
28468 self.generate_expression(expr)?;
28469 }
28470 for expr in &e.expressions {
28471 self.write(", ");
28472 self.generate_expression(expr)?;
28473 }
28474 self.write(")");
28475 Ok(())
28476 }
28477
28478 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
28479 self.write_keyword("JSON_KEYS");
28481 self.write("(");
28482 self.generate_expression(&e.this)?;
28483 if let Some(expr) = &e.expression {
28484 self.write(", ");
28485 self.generate_expression(expr)?;
28486 }
28487 self.write(")");
28488 Ok(())
28489 }
28490
28491 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
28492 let mut path_str = String::new();
28495 for expr in &e.expressions {
28496 match expr {
28497 Expression::JSONPathRoot(_) => {
28498 path_str.push('$');
28499 }
28500 Expression::JSONPathKey(k) => {
28501 if let Expression::Literal(crate::expressions::Literal::String(s)) =
28503 k.this.as_ref()
28504 {
28505 path_str.push('.');
28506 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
28508 if needs_quoting {
28509 path_str.push('"');
28510 path_str.push_str(s);
28511 path_str.push('"');
28512 } else {
28513 path_str.push_str(s);
28514 }
28515 }
28516 }
28517 Expression::JSONPathSubscript(s) => {
28518 if let Expression::Literal(crate::expressions::Literal::Number(n)) =
28520 s.this.as_ref()
28521 {
28522 path_str.push('[');
28523 path_str.push_str(n);
28524 path_str.push(']');
28525 }
28526 }
28527 _ => {
28528 let mut temp_gen = Self::with_config(self.config.clone());
28530 temp_gen.generate_expression(expr)?;
28531 path_str.push_str(&temp_gen.output);
28532 }
28533 }
28534 }
28535 self.write("'");
28537 self.write(&path_str);
28538 self.write("'");
28539 Ok(())
28540 }
28541
28542 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
28543 self.write("?(");
28545 self.generate_expression(&e.this)?;
28546 self.write(")");
28547 Ok(())
28548 }
28549
28550 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
28551 self.write(".");
28553 self.generate_expression(&e.this)?;
28554 Ok(())
28555 }
28556
28557 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
28558 self.write("..");
28560 if let Some(this) = &e.this {
28561 self.generate_expression(this)?;
28562 }
28563 Ok(())
28564 }
28565
28566 fn generate_json_path_root(&mut self) -> Result<()> {
28567 self.write("$");
28569 Ok(())
28570 }
28571
28572 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
28573 self.write("(");
28575 self.generate_expression(&e.this)?;
28576 self.write(")");
28577 Ok(())
28578 }
28579
28580 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
28581 self.generate_expression(&e.this)?;
28583 Ok(())
28584 }
28585
28586 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
28587 self.write("[");
28589 if let Some(start) = &e.start {
28590 self.generate_expression(start)?;
28591 }
28592 self.write(":");
28593 if let Some(end) = &e.end {
28594 self.generate_expression(end)?;
28595 }
28596 if let Some(step) = &e.step {
28597 self.write(":");
28598 self.generate_expression(step)?;
28599 }
28600 self.write("]");
28601 Ok(())
28602 }
28603
28604 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
28605 self.write("[");
28607 self.generate_expression(&e.this)?;
28608 self.write("]");
28609 Ok(())
28610 }
28611
28612 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
28613 self.write("[");
28615 for (i, expr) in e.expressions.iter().enumerate() {
28616 if i > 0 {
28617 self.write(", ");
28618 }
28619 self.generate_expression(expr)?;
28620 }
28621 self.write("]");
28622 Ok(())
28623 }
28624
28625 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
28626 self.write_keyword("JSON_REMOVE");
28628 self.write("(");
28629 self.generate_expression(&e.this)?;
28630 for expr in &e.expressions {
28631 self.write(", ");
28632 self.generate_expression(expr)?;
28633 }
28634 self.write(")");
28635 Ok(())
28636 }
28637
28638 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
28639 self.write_keyword("COLUMNS");
28642 self.write("(");
28643
28644 if self.config.pretty && !e.expressions.is_empty() {
28645 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
28647 for expr in &e.expressions {
28648 let mut temp_gen = Generator::with_config(self.config.clone());
28649 temp_gen.generate_expression(expr)?;
28650 expr_strings.push(temp_gen.output);
28651 }
28652
28653 if self.too_wide(&expr_strings) {
28655 self.write_newline();
28657 self.indent_level += 1;
28658 for (i, expr_str) in expr_strings.iter().enumerate() {
28659 if i > 0 {
28660 self.write(",");
28661 self.write_newline();
28662 }
28663 self.write_indent();
28664 self.write(expr_str);
28665 }
28666 self.write_newline();
28667 self.indent_level -= 1;
28668 self.write_indent();
28669 } else {
28670 for (i, expr_str) in expr_strings.iter().enumerate() {
28672 if i > 0 {
28673 self.write(", ");
28674 }
28675 self.write(expr_str);
28676 }
28677 }
28678 } else {
28679 for (i, expr) in e.expressions.iter().enumerate() {
28681 if i > 0 {
28682 self.write(", ");
28683 }
28684 self.generate_expression(expr)?;
28685 }
28686 }
28687 self.write(")");
28688 Ok(())
28689 }
28690
28691 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
28692 self.write_keyword("JSON_SET");
28694 self.write("(");
28695 self.generate_expression(&e.this)?;
28696 for expr in &e.expressions {
28697 self.write(", ");
28698 self.generate_expression(expr)?;
28699 }
28700 self.write(")");
28701 Ok(())
28702 }
28703
28704 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
28705 self.write_keyword("JSON_STRIP_NULLS");
28707 self.write("(");
28708 self.generate_expression(&e.this)?;
28709 if let Some(expr) = &e.expression {
28710 self.write(", ");
28711 self.generate_expression(expr)?;
28712 }
28713 self.write(")");
28714 Ok(())
28715 }
28716
28717 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
28718 self.write_keyword("JSON_TABLE");
28720 self.write("(");
28721 self.generate_expression(&e.this)?;
28722 if let Some(path) = &e.path {
28723 self.write(", ");
28724 self.generate_expression(path)?;
28725 }
28726 if let Some(error_handling) = &e.error_handling {
28727 self.write_space();
28728 self.generate_expression(error_handling)?;
28729 }
28730 if let Some(empty_handling) = &e.empty_handling {
28731 self.write_space();
28732 self.generate_expression(empty_handling)?;
28733 }
28734 if let Some(schema) = &e.schema {
28735 self.write_space();
28736 self.generate_expression(schema)?;
28737 }
28738 self.write(")");
28739 Ok(())
28740 }
28741
28742 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
28743 self.write_keyword("JSON_TYPE");
28745 self.write("(");
28746 self.generate_expression(&e.this)?;
28747 self.write(")");
28748 Ok(())
28749 }
28750
28751 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
28752 self.write_keyword("JSON_VALUE");
28754 self.write("(");
28755 self.generate_expression(&e.this)?;
28756 if let Some(path) = &e.path {
28757 self.write(", ");
28758 self.generate_expression(path)?;
28759 }
28760 if let Some(returning) = &e.returning {
28761 self.write_space();
28762 self.write_keyword("RETURNING");
28763 self.write_space();
28764 self.generate_expression(returning)?;
28765 }
28766 if let Some(on_condition) = &e.on_condition {
28767 self.write_space();
28768 self.generate_expression(on_condition)?;
28769 }
28770 self.write(")");
28771 Ok(())
28772 }
28773
28774 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
28775 self.write_keyword("JSON_VALUE_ARRAY");
28777 self.write("(");
28778 self.generate_expression(&e.this)?;
28779 self.write(")");
28780 Ok(())
28781 }
28782
28783 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
28784 self.write_keyword("JAROWINKLER_SIMILARITY");
28786 self.write("(");
28787 self.generate_expression(&e.this)?;
28788 self.write(", ");
28789 self.generate_expression(&e.expression)?;
28790 self.write(")");
28791 Ok(())
28792 }
28793
28794 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
28795 self.generate_expression(&e.this)?;
28797 self.write("(");
28798 for (i, expr) in e.expressions.iter().enumerate() {
28799 if i > 0 {
28800 self.write(", ");
28801 }
28802 self.generate_expression(expr)?;
28803 }
28804 self.write(")");
28805 Ok(())
28806 }
28807
28808 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
28809 if e.no.is_some() {
28811 self.write_keyword("NO ");
28812 }
28813 if let Some(local) = &e.local {
28814 self.generate_expression(local)?;
28815 self.write_space();
28816 }
28817 if e.dual.is_some() {
28818 self.write_keyword("DUAL ");
28819 }
28820 if e.before.is_some() {
28821 self.write_keyword("BEFORE ");
28822 }
28823 if e.after.is_some() {
28824 self.write_keyword("AFTER ");
28825 }
28826 self.write_keyword("JOURNAL");
28827 Ok(())
28828 }
28829
28830 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
28831 self.write_keyword("LANGUAGE");
28833 self.write_space();
28834 self.generate_expression(&e.this)?;
28835 Ok(())
28836 }
28837
28838 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
28839 if e.view.is_some() {
28841 self.write_keyword("LATERAL VIEW");
28843 if e.outer.is_some() {
28844 self.write_space();
28845 self.write_keyword("OUTER");
28846 }
28847 self.write_space();
28848 self.generate_expression(&e.this)?;
28849 if let Some(alias) = &e.alias {
28850 self.write_space();
28851 self.write(alias);
28852 }
28853 } else {
28854 self.write_keyword("LATERAL");
28856 self.write_space();
28857 self.generate_expression(&e.this)?;
28858 if e.ordinality.is_some() {
28859 self.write_space();
28860 self.write_keyword("WITH ORDINALITY");
28861 }
28862 if let Some(alias) = &e.alias {
28863 self.write_space();
28864 self.write_keyword("AS");
28865 self.write_space();
28866 self.write(alias);
28867 if !e.column_aliases.is_empty() {
28868 self.write("(");
28869 for (i, col) in e.column_aliases.iter().enumerate() {
28870 if i > 0 {
28871 self.write(", ");
28872 }
28873 self.write(col);
28874 }
28875 self.write(")");
28876 }
28877 }
28878 }
28879 Ok(())
28880 }
28881
28882 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
28883 self.write_keyword("LIKE");
28885 self.write_space();
28886 self.generate_expression(&e.this)?;
28887 for expr in &e.expressions {
28888 self.write_space();
28889 self.generate_expression(expr)?;
28890 }
28891 Ok(())
28892 }
28893
28894 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
28895 self.write_keyword("LIMIT");
28896 self.write_space();
28897 self.write_limit_expr(&e.this)?;
28898 if e.percent {
28899 self.write_space();
28900 self.write_keyword("PERCENT");
28901 }
28902 for comment in &e.comments {
28904 self.write(" ");
28905 self.write_formatted_comment(comment);
28906 }
28907 Ok(())
28908 }
28909
28910 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
28911 if e.percent.is_some() {
28913 self.write_keyword(" PERCENT");
28914 }
28915 if e.rows.is_some() {
28916 self.write_keyword(" ROWS");
28917 }
28918 if e.with_ties.is_some() {
28919 self.write_keyword(" WITH TIES");
28920 } else if e.rows.is_some() {
28921 self.write_keyword(" ONLY");
28922 }
28923 Ok(())
28924 }
28925
28926 fn generate_list(&mut self, e: &List) -> Result<()> {
28927 use crate::dialects::DialectType;
28928 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
28929
28930 if e.expressions.len() == 1 {
28932 if let Expression::Select(_) = &e.expressions[0] {
28933 self.write_keyword("LIST");
28934 self.write("(");
28935 self.generate_expression(&e.expressions[0])?;
28936 self.write(")");
28937 return Ok(());
28938 }
28939 }
28940
28941 if is_materialize {
28943 self.write_keyword("LIST");
28944 self.write("[");
28945 for (i, expr) in e.expressions.iter().enumerate() {
28946 if i > 0 {
28947 self.write(", ");
28948 }
28949 self.generate_expression(expr)?;
28950 }
28951 self.write("]");
28952 } else {
28953 self.write_keyword("LIST");
28955 self.write("(");
28956 for (i, expr) in e.expressions.iter().enumerate() {
28957 if i > 0 {
28958 self.write(", ");
28959 }
28960 self.generate_expression(expr)?;
28961 }
28962 self.write(")");
28963 }
28964 Ok(())
28965 }
28966
28967 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
28968 if let Expression::Select(_) = &*e.this {
28970 self.write_keyword("MAP");
28971 self.write("(");
28972 self.generate_expression(&e.this)?;
28973 self.write(")");
28974 return Ok(());
28975 }
28976
28977 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
28978
28979 self.write_keyword("MAP");
28981 if is_duckdb {
28982 self.write(" {");
28983 } else {
28984 self.write("[");
28985 }
28986 if let Expression::Struct(s) = &*e.this {
28987 for (i, (_, expr)) in s.fields.iter().enumerate() {
28988 if i > 0 {
28989 self.write(", ");
28990 }
28991 if let Expression::PropertyEQ(op) = expr {
28992 self.generate_expression(&op.left)?;
28993 if is_duckdb {
28994 self.write(": ");
28995 } else {
28996 self.write(" => ");
28997 }
28998 self.generate_expression(&op.right)?;
28999 } else {
29000 self.generate_expression(expr)?;
29001 }
29002 }
29003 }
29004 if is_duckdb {
29005 self.write("}");
29006 } else {
29007 self.write("]");
29008 }
29009 Ok(())
29010 }
29011
29012 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
29013 self.write_keyword("LOCALTIME");
29015 if let Some(precision) = &e.this {
29016 self.write("(");
29017 self.generate_expression(precision)?;
29018 self.write(")");
29019 }
29020 Ok(())
29021 }
29022
29023 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
29024 self.write_keyword("LOCALTIMESTAMP");
29026 if let Some(precision) = &e.this {
29027 self.write("(");
29028 self.generate_expression(precision)?;
29029 self.write(")");
29030 }
29031 Ok(())
29032 }
29033
29034 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
29035 self.write_keyword("LOCATION");
29037 self.write_space();
29038 self.generate_expression(&e.this)?;
29039 Ok(())
29040 }
29041
29042 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
29043 if e.update.is_some() {
29045 if e.key.is_some() {
29046 self.write_keyword("FOR NO KEY UPDATE");
29047 } else {
29048 self.write_keyword("FOR UPDATE");
29049 }
29050 } else {
29051 if e.key.is_some() {
29052 self.write_keyword("FOR KEY SHARE");
29053 } else {
29054 self.write_keyword("FOR SHARE");
29055 }
29056 }
29057 if !e.expressions.is_empty() {
29058 self.write_keyword(" OF ");
29059 for (i, expr) in e.expressions.iter().enumerate() {
29060 if i > 0 {
29061 self.write(", ");
29062 }
29063 self.generate_expression(expr)?;
29064 }
29065 }
29066 if let Some(wait) = &e.wait {
29071 match wait.as_ref() {
29072 Expression::Boolean(b) => {
29073 if b.value {
29074 self.write_keyword(" NOWAIT");
29075 } else {
29076 self.write_keyword(" SKIP LOCKED");
29077 }
29078 }
29079 _ => {
29080 self.write_keyword(" WAIT ");
29082 self.generate_expression(wait)?;
29083 }
29084 }
29085 }
29086 Ok(())
29087 }
29088
29089 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
29090 self.write_keyword("LOCK");
29092 self.write_space();
29093 self.generate_expression(&e.this)?;
29094 Ok(())
29095 }
29096
29097 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
29098 self.write_keyword("LOCKING");
29100 self.write_space();
29101 self.write(&e.kind);
29102 if let Some(this) = &e.this {
29103 self.write_space();
29104 self.generate_expression(this)?;
29105 }
29106 if let Some(for_or_in) = &e.for_or_in {
29107 self.write_space();
29108 self.generate_expression(for_or_in)?;
29109 }
29110 if let Some(lock_type) = &e.lock_type {
29111 self.write_space();
29112 self.generate_expression(lock_type)?;
29113 }
29114 if e.override_.is_some() {
29115 self.write_keyword(" OVERRIDE");
29116 }
29117 Ok(())
29118 }
29119
29120 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
29121 self.generate_expression(&e.this)?;
29123 self.write_space();
29124 self.generate_expression(&e.expression)?;
29125 Ok(())
29126 }
29127
29128 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
29129 if e.no.is_some() {
29131 self.write_keyword("NO ");
29132 }
29133 self.write_keyword("LOG");
29134 Ok(())
29135 }
29136
29137 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
29138 self.write_keyword("MD5");
29140 self.write("(");
29141 self.generate_expression(&e.this)?;
29142 for expr in &e.expressions {
29143 self.write(", ");
29144 self.generate_expression(expr)?;
29145 }
29146 self.write(")");
29147 Ok(())
29148 }
29149
29150 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
29151 self.write_keyword("ML.FORECAST");
29153 self.write("(");
29154 self.generate_expression(&e.this)?;
29155 if let Some(expression) = &e.expression {
29156 self.write(", ");
29157 self.generate_expression(expression)?;
29158 }
29159 if let Some(params) = &e.params_struct {
29160 self.write(", ");
29161 self.generate_expression(params)?;
29162 }
29163 self.write(")");
29164 Ok(())
29165 }
29166
29167 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
29168 self.write_keyword("ML.TRANSLATE");
29170 self.write("(");
29171 self.generate_expression(&e.this)?;
29172 self.write(", ");
29173 self.generate_expression(&e.expression)?;
29174 if let Some(params) = &e.params_struct {
29175 self.write(", ");
29176 self.generate_expression(params)?;
29177 }
29178 self.write(")");
29179 Ok(())
29180 }
29181
29182 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
29183 self.write_keyword("MAKE_INTERVAL");
29185 self.write("(");
29186 let mut first = true;
29187 if let Some(year) = &e.year {
29188 self.write("years => ");
29189 self.generate_expression(year)?;
29190 first = false;
29191 }
29192 if let Some(month) = &e.month {
29193 if !first {
29194 self.write(", ");
29195 }
29196 self.write("months => ");
29197 self.generate_expression(month)?;
29198 first = false;
29199 }
29200 if let Some(week) = &e.week {
29201 if !first {
29202 self.write(", ");
29203 }
29204 self.write("weeks => ");
29205 self.generate_expression(week)?;
29206 first = false;
29207 }
29208 if let Some(day) = &e.day {
29209 if !first {
29210 self.write(", ");
29211 }
29212 self.write("days => ");
29213 self.generate_expression(day)?;
29214 first = false;
29215 }
29216 if let Some(hour) = &e.hour {
29217 if !first {
29218 self.write(", ");
29219 }
29220 self.write("hours => ");
29221 self.generate_expression(hour)?;
29222 first = false;
29223 }
29224 if let Some(minute) = &e.minute {
29225 if !first {
29226 self.write(", ");
29227 }
29228 self.write("mins => ");
29229 self.generate_expression(minute)?;
29230 first = false;
29231 }
29232 if let Some(second) = &e.second {
29233 if !first {
29234 self.write(", ");
29235 }
29236 self.write("secs => ");
29237 self.generate_expression(second)?;
29238 }
29239 self.write(")");
29240 Ok(())
29241 }
29242
29243 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
29244 self.write_keyword("MANHATTAN_DISTANCE");
29246 self.write("(");
29247 self.generate_expression(&e.this)?;
29248 self.write(", ");
29249 self.generate_expression(&e.expression)?;
29250 self.write(")");
29251 Ok(())
29252 }
29253
29254 fn generate_map(&mut self, e: &Map) -> Result<()> {
29255 self.write_keyword("MAP");
29257 self.write("(");
29258 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
29259 if i > 0 {
29260 self.write(", ");
29261 }
29262 self.generate_expression(key)?;
29263 self.write(", ");
29264 self.generate_expression(value)?;
29265 }
29266 self.write(")");
29267 Ok(())
29268 }
29269
29270 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
29271 self.write_keyword("MAP_CAT");
29273 self.write("(");
29274 self.generate_expression(&e.this)?;
29275 self.write(", ");
29276 self.generate_expression(&e.expression)?;
29277 self.write(")");
29278 Ok(())
29279 }
29280
29281 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
29282 self.write_keyword("MAP_DELETE");
29284 self.write("(");
29285 self.generate_expression(&e.this)?;
29286 for expr in &e.expressions {
29287 self.write(", ");
29288 self.generate_expression(expr)?;
29289 }
29290 self.write(")");
29291 Ok(())
29292 }
29293
29294 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
29295 self.write_keyword("MAP_INSERT");
29297 self.write("(");
29298 self.generate_expression(&e.this)?;
29299 if let Some(key) = &e.key {
29300 self.write(", ");
29301 self.generate_expression(key)?;
29302 }
29303 if let Some(value) = &e.value {
29304 self.write(", ");
29305 self.generate_expression(value)?;
29306 }
29307 if let Some(update_flag) = &e.update_flag {
29308 self.write(", ");
29309 self.generate_expression(update_flag)?;
29310 }
29311 self.write(")");
29312 Ok(())
29313 }
29314
29315 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
29316 self.write_keyword("MAP_PICK");
29318 self.write("(");
29319 self.generate_expression(&e.this)?;
29320 for expr in &e.expressions {
29321 self.write(", ");
29322 self.generate_expression(expr)?;
29323 }
29324 self.write(")");
29325 Ok(())
29326 }
29327
29328 fn generate_masking_policy_column_constraint(
29329 &mut self,
29330 e: &MaskingPolicyColumnConstraint,
29331 ) -> Result<()> {
29332 self.write_keyword("MASKING POLICY");
29334 self.write_space();
29335 self.generate_expression(&e.this)?;
29336 if !e.expressions.is_empty() {
29337 self.write_keyword(" USING");
29338 self.write(" (");
29339 for (i, expr) in e.expressions.iter().enumerate() {
29340 if i > 0 {
29341 self.write(", ");
29342 }
29343 self.generate_expression(expr)?;
29344 }
29345 self.write(")");
29346 }
29347 Ok(())
29348 }
29349
29350 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
29351 if matches!(
29352 self.config.dialect,
29353 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
29354 ) {
29355 if e.expressions.len() > 1 {
29356 self.write("(");
29357 }
29358 for (i, expr) in e.expressions.iter().enumerate() {
29359 if i > 0 {
29360 self.write_keyword(" OR ");
29361 }
29362 self.generate_expression(expr)?;
29363 self.write_space();
29364 self.write("@@");
29365 self.write_space();
29366 self.generate_expression(&e.this)?;
29367 }
29368 if e.expressions.len() > 1 {
29369 self.write(")");
29370 }
29371 return Ok(());
29372 }
29373
29374 self.write_keyword("MATCH");
29376 self.write("(");
29377 for (i, expr) in e.expressions.iter().enumerate() {
29378 if i > 0 {
29379 self.write(", ");
29380 }
29381 self.generate_expression(expr)?;
29382 }
29383 self.write(")");
29384 self.write_keyword(" AGAINST");
29385 self.write("(");
29386 self.generate_expression(&e.this)?;
29387 if let Some(modifier) = &e.modifier {
29388 self.write_space();
29389 self.generate_expression(modifier)?;
29390 }
29391 self.write(")");
29392 Ok(())
29393 }
29394
29395 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
29396 if let Some(window_frame) = &e.window_frame {
29398 self.write(&format!("{:?}", window_frame).to_uppercase());
29399 self.write_space();
29400 }
29401 self.generate_expression(&e.this)?;
29402 Ok(())
29403 }
29404
29405 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
29406 self.write_keyword("MATERIALIZED");
29408 if let Some(this) = &e.this {
29409 self.write_space();
29410 self.generate_expression(this)?;
29411 }
29412 Ok(())
29413 }
29414
29415 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
29416 if let Some(with_) = &e.with_ {
29419 self.generate_expression(with_)?;
29420 self.write_space();
29421 }
29422 self.write_keyword("MERGE INTO");
29423 self.write_space();
29424 self.generate_expression(&e.this)?;
29425
29426 if self.config.pretty {
29428 self.write_newline();
29429 self.write_indent();
29430 } else {
29431 self.write_space();
29432 }
29433 self.write_keyword("USING");
29434 self.write_space();
29435 self.generate_expression(&e.using)?;
29436
29437 if let Some(on) = &e.on {
29439 if self.config.pretty {
29440 self.write_newline();
29441 self.write_indent();
29442 } else {
29443 self.write_space();
29444 }
29445 self.write_keyword("ON");
29446 self.write_space();
29447 self.generate_expression(on)?;
29448 }
29449 if let Some(using_cond) = &e.using_cond {
29451 self.write_space();
29452 self.write_keyword("USING");
29453 self.write_space();
29454 self.write("(");
29455 if let Expression::Tuple(tuple) = using_cond.as_ref() {
29457 for (i, col) in tuple.expressions.iter().enumerate() {
29458 if i > 0 {
29459 self.write(", ");
29460 }
29461 self.generate_expression(col)?;
29462 }
29463 } else {
29464 self.generate_expression(using_cond)?;
29465 }
29466 self.write(")");
29467 }
29468 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
29470 if matches!(
29471 self.config.dialect,
29472 Some(crate::DialectType::PostgreSQL)
29473 | Some(crate::DialectType::Redshift)
29474 | Some(crate::DialectType::Trino)
29475 | Some(crate::DialectType::Presto)
29476 | Some(crate::DialectType::Athena)
29477 ) {
29478 let mut names = Vec::new();
29479 match e.this.as_ref() {
29480 Expression::Alias(a) => {
29481 if let Expression::Table(t) = &a.this {
29483 names.push(t.name.name.clone());
29484 } else if let Expression::Identifier(id) = &a.this {
29485 names.push(id.name.clone());
29486 }
29487 names.push(a.alias.name.clone());
29488 }
29489 Expression::Table(t) => {
29490 names.push(t.name.name.clone());
29491 }
29492 Expression::Identifier(id) => {
29493 names.push(id.name.clone());
29494 }
29495 _ => {}
29496 }
29497 self.merge_strip_qualifiers = names;
29498 }
29499
29500 if let Some(whens) = &e.whens {
29502 if self.config.pretty {
29503 self.write_newline();
29504 self.write_indent();
29505 } else {
29506 self.write_space();
29507 }
29508 self.generate_expression(whens)?;
29509 }
29510
29511 self.merge_strip_qualifiers = saved_merge_strip;
29513
29514 if let Some(returning) = &e.returning {
29516 if self.config.pretty {
29517 self.write_newline();
29518 self.write_indent();
29519 } else {
29520 self.write_space();
29521 }
29522 self.generate_expression(returning)?;
29523 }
29524 Ok(())
29525 }
29526
29527 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
29528 if e.no.is_some() {
29530 self.write_keyword("NO MERGEBLOCKRATIO");
29531 } else if e.default.is_some() {
29532 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
29533 } else {
29534 self.write_keyword("MERGEBLOCKRATIO");
29535 self.write("=");
29536 if let Some(this) = &e.this {
29537 self.generate_expression(this)?;
29538 }
29539 if e.percent.is_some() {
29540 self.write_keyword(" PERCENT");
29541 }
29542 }
29543 Ok(())
29544 }
29545
29546 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
29547 self.write_keyword("TTL");
29549 let pretty_clickhouse = self.config.pretty
29550 && matches!(
29551 self.config.dialect,
29552 Some(crate::dialects::DialectType::ClickHouse)
29553 );
29554
29555 if pretty_clickhouse {
29556 self.write_newline();
29557 self.indent_level += 1;
29558 for (i, expr) in e.expressions.iter().enumerate() {
29559 if i > 0 {
29560 self.write(",");
29561 self.write_newline();
29562 }
29563 self.write_indent();
29564 self.generate_expression(expr)?;
29565 }
29566 self.indent_level -= 1;
29567 } else {
29568 self.write_space();
29569 for (i, expr) in e.expressions.iter().enumerate() {
29570 if i > 0 {
29571 self.write(", ");
29572 }
29573 self.generate_expression(expr)?;
29574 }
29575 }
29576
29577 if let Some(where_) = &e.where_ {
29578 if pretty_clickhouse {
29579 self.write_newline();
29580 if let Expression::Where(w) = where_.as_ref() {
29581 self.write_indent();
29582 self.write_keyword("WHERE");
29583 self.write_newline();
29584 self.indent_level += 1;
29585 self.write_indent();
29586 self.generate_expression(&w.this)?;
29587 self.indent_level -= 1;
29588 } else {
29589 self.write_indent();
29590 self.generate_expression(where_)?;
29591 }
29592 } else {
29593 self.write_space();
29594 self.generate_expression(where_)?;
29595 }
29596 }
29597 if let Some(group) = &e.group {
29598 if pretty_clickhouse {
29599 self.write_newline();
29600 if let Expression::Group(g) = group.as_ref() {
29601 self.write_indent();
29602 self.write_keyword("GROUP BY");
29603 self.write_newline();
29604 self.indent_level += 1;
29605 for (i, expr) in g.expressions.iter().enumerate() {
29606 if i > 0 {
29607 self.write(",");
29608 self.write_newline();
29609 }
29610 self.write_indent();
29611 self.generate_expression(expr)?;
29612 }
29613 self.indent_level -= 1;
29614 } else {
29615 self.write_indent();
29616 self.generate_expression(group)?;
29617 }
29618 } else {
29619 self.write_space();
29620 self.generate_expression(group)?;
29621 }
29622 }
29623 if let Some(aggregates) = &e.aggregates {
29624 if pretty_clickhouse {
29625 self.write_newline();
29626 self.write_indent();
29627 self.write_keyword("SET");
29628 self.write_newline();
29629 self.indent_level += 1;
29630 if let Expression::Tuple(t) = aggregates.as_ref() {
29631 for (i, agg) in t.expressions.iter().enumerate() {
29632 if i > 0 {
29633 self.write(",");
29634 self.write_newline();
29635 }
29636 self.write_indent();
29637 self.generate_expression(agg)?;
29638 }
29639 } else {
29640 self.write_indent();
29641 self.generate_expression(aggregates)?;
29642 }
29643 self.indent_level -= 1;
29644 } else {
29645 self.write_space();
29646 self.write_keyword("SET");
29647 self.write_space();
29648 self.generate_expression(aggregates)?;
29649 }
29650 }
29651 Ok(())
29652 }
29653
29654 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
29655 self.generate_expression(&e.this)?;
29657 if e.delete.is_some() {
29658 self.write_keyword(" DELETE");
29659 }
29660 if let Some(recompress) = &e.recompress {
29661 self.write_keyword(" RECOMPRESS ");
29662 self.generate_expression(recompress)?;
29663 }
29664 if let Some(to_disk) = &e.to_disk {
29665 self.write_keyword(" TO DISK ");
29666 self.generate_expression(to_disk)?;
29667 }
29668 if let Some(to_volume) = &e.to_volume {
29669 self.write_keyword(" TO VOLUME ");
29670 self.generate_expression(to_volume)?;
29671 }
29672 Ok(())
29673 }
29674
29675 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
29676 self.write_keyword("MINHASH");
29678 self.write("(");
29679 self.generate_expression(&e.this)?;
29680 for expr in &e.expressions {
29681 self.write(", ");
29682 self.generate_expression(expr)?;
29683 }
29684 self.write(")");
29685 Ok(())
29686 }
29687
29688 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
29689 self.generate_expression(&e.this)?;
29691 self.write("!");
29692 self.generate_expression(&e.expression)?;
29693 Ok(())
29694 }
29695
29696 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
29697 self.write_keyword("MONTHNAME");
29699 self.write("(");
29700 self.generate_expression(&e.this)?;
29701 self.write(")");
29702 Ok(())
29703 }
29704
29705 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
29706 for comment in &e.leading_comments {
29708 self.write_formatted_comment(comment);
29709 if self.config.pretty {
29710 self.write_newline();
29711 self.write_indent();
29712 } else {
29713 self.write_space();
29714 }
29715 }
29716 self.write_keyword("INSERT");
29718 self.write_space();
29719 self.write(&e.kind);
29720 if self.config.pretty {
29721 self.indent_level += 1;
29722 for expr in &e.expressions {
29723 self.write_newline();
29724 self.write_indent();
29725 self.generate_expression(expr)?;
29726 }
29727 self.indent_level -= 1;
29728 } else {
29729 for expr in &e.expressions {
29730 self.write_space();
29731 self.generate_expression(expr)?;
29732 }
29733 }
29734 if let Some(source) = &e.source {
29735 if self.config.pretty {
29736 self.write_newline();
29737 self.write_indent();
29738 } else {
29739 self.write_space();
29740 }
29741 self.generate_expression(source)?;
29742 }
29743 Ok(())
29744 }
29745
29746 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
29747 self.write_keyword("NEXT VALUE FOR");
29749 self.write_space();
29750 self.generate_expression(&e.this)?;
29751 if let Some(order) = &e.order {
29752 self.write_space();
29753 self.write_keyword("OVER");
29754 self.write(" (");
29755 self.generate_expression(order)?;
29756 self.write(")");
29757 }
29758 Ok(())
29759 }
29760
29761 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
29762 self.write_keyword("NORMAL");
29764 self.write("(");
29765 self.generate_expression(&e.this)?;
29766 if let Some(stddev) = &e.stddev {
29767 self.write(", ");
29768 self.generate_expression(stddev)?;
29769 }
29770 if let Some(gen) = &e.gen {
29771 self.write(", ");
29772 self.generate_expression(gen)?;
29773 }
29774 self.write(")");
29775 Ok(())
29776 }
29777
29778 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
29779 if e.is_casefold.is_some() {
29781 self.write_keyword("NORMALIZE_AND_CASEFOLD");
29782 } else {
29783 self.write_keyword("NORMALIZE");
29784 }
29785 self.write("(");
29786 self.generate_expression(&e.this)?;
29787 if let Some(form) = &e.form {
29788 self.write(", ");
29789 self.generate_expression(form)?;
29790 }
29791 self.write(")");
29792 Ok(())
29793 }
29794
29795 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
29796 if e.allow_null.is_none() {
29798 self.write_keyword("NOT ");
29799 }
29800 self.write_keyword("NULL");
29801 Ok(())
29802 }
29803
29804 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
29805 self.write_keyword("NULLIF");
29807 self.write("(");
29808 self.generate_expression(&e.this)?;
29809 self.write(", ");
29810 self.generate_expression(&e.expression)?;
29811 self.write(")");
29812 Ok(())
29813 }
29814
29815 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
29816 self.write_keyword("FORMAT");
29818 self.write("(");
29819 self.generate_expression(&e.this)?;
29820 self.write(", '");
29821 self.write(&e.format);
29822 self.write("'");
29823 if let Some(culture) = &e.culture {
29824 self.write(", ");
29825 self.generate_expression(culture)?;
29826 }
29827 self.write(")");
29828 Ok(())
29829 }
29830
29831 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
29832 self.write_keyword("OBJECT_AGG");
29834 self.write("(");
29835 self.generate_expression(&e.this)?;
29836 self.write(", ");
29837 self.generate_expression(&e.expression)?;
29838 self.write(")");
29839 Ok(())
29840 }
29841
29842 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
29843 self.generate_expression(&e.this)?;
29845 Ok(())
29846 }
29847
29848 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
29849 self.write_keyword("OBJECT_INSERT");
29851 self.write("(");
29852 self.generate_expression(&e.this)?;
29853 if let Some(key) = &e.key {
29854 self.write(", ");
29855 self.generate_expression(key)?;
29856 }
29857 if let Some(value) = &e.value {
29858 self.write(", ");
29859 self.generate_expression(value)?;
29860 }
29861 if let Some(update_flag) = &e.update_flag {
29862 self.write(", ");
29863 self.generate_expression(update_flag)?;
29864 }
29865 self.write(")");
29866 Ok(())
29867 }
29868
29869 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
29870 self.write_keyword("OFFSET");
29872 self.write_space();
29873 self.generate_expression(&e.this)?;
29874 if e.rows == Some(true)
29876 && matches!(
29877 self.config.dialect,
29878 Some(crate::dialects::DialectType::TSQL)
29879 | Some(crate::dialects::DialectType::Oracle)
29880 )
29881 {
29882 self.write_space();
29883 self.write_keyword("ROWS");
29884 }
29885 Ok(())
29886 }
29887
29888 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
29889 self.write_keyword("QUALIFY");
29891 self.write_space();
29892 self.generate_expression(&e.this)?;
29893 Ok(())
29894 }
29895
29896 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
29897 self.write_keyword("ON CLUSTER");
29899 self.write_space();
29900 self.generate_expression(&e.this)?;
29901 Ok(())
29902 }
29903
29904 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
29905 self.write_keyword("ON COMMIT");
29907 if e.delete.is_some() {
29908 self.write_keyword(" DELETE ROWS");
29909 } else {
29910 self.write_keyword(" PRESERVE ROWS");
29911 }
29912 Ok(())
29913 }
29914
29915 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
29916 if let Some(empty) = &e.empty {
29918 self.generate_expression(empty)?;
29919 self.write_keyword(" ON EMPTY");
29920 }
29921 if let Some(error) = &e.error {
29922 if e.empty.is_some() {
29923 self.write_space();
29924 }
29925 self.generate_expression(error)?;
29926 self.write_keyword(" ON ERROR");
29927 }
29928 if let Some(null) = &e.null {
29929 if e.empty.is_some() || e.error.is_some() {
29930 self.write_space();
29931 }
29932 self.generate_expression(null)?;
29933 self.write_keyword(" ON NULL");
29934 }
29935 Ok(())
29936 }
29937
29938 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
29939 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
29941 return Ok(());
29942 }
29943 if e.duplicate.is_some() {
29945 self.write_keyword("ON DUPLICATE KEY UPDATE");
29947 for (i, expr) in e.expressions.iter().enumerate() {
29948 if i > 0 {
29949 self.write(",");
29950 }
29951 self.write_space();
29952 self.generate_expression(expr)?;
29953 }
29954 return Ok(());
29955 } else {
29956 self.write_keyword("ON CONFLICT");
29957 }
29958 if let Some(constraint) = &e.constraint {
29959 self.write_keyword(" ON CONSTRAINT ");
29960 self.generate_expression(constraint)?;
29961 }
29962 if let Some(conflict_keys) = &e.conflict_keys {
29963 if let Expression::Tuple(t) = conflict_keys.as_ref() {
29965 self.write("(");
29966 for (i, expr) in t.expressions.iter().enumerate() {
29967 if i > 0 {
29968 self.write(", ");
29969 }
29970 self.generate_expression(expr)?;
29971 }
29972 self.write(")");
29973 } else {
29974 self.write("(");
29975 self.generate_expression(conflict_keys)?;
29976 self.write(")");
29977 }
29978 }
29979 if let Some(index_predicate) = &e.index_predicate {
29980 self.write_keyword(" WHERE ");
29981 self.generate_expression(index_predicate)?;
29982 }
29983 if let Some(action) = &e.action {
29984 if let Expression::Identifier(id) = action.as_ref() {
29986 if id.name == "NOTHING" || id.name.to_uppercase() == "NOTHING" {
29987 self.write_keyword(" DO NOTHING");
29988 } else {
29989 self.write_keyword(" DO ");
29990 self.generate_expression(action)?;
29991 }
29992 } else if let Expression::Tuple(t) = action.as_ref() {
29993 self.write_keyword(" DO UPDATE SET ");
29995 for (i, expr) in t.expressions.iter().enumerate() {
29996 if i > 0 {
29997 self.write(", ");
29998 }
29999 self.generate_expression(expr)?;
30000 }
30001 } else {
30002 self.write_keyword(" DO ");
30003 self.generate_expression(action)?;
30004 }
30005 }
30006 if let Some(where_) = &e.where_ {
30008 self.write_keyword(" WHERE ");
30009 self.generate_expression(where_)?;
30010 }
30011 Ok(())
30012 }
30013
30014 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
30015 self.write_keyword("ON");
30017 self.write_space();
30018 self.generate_expression(&e.this)?;
30019 Ok(())
30020 }
30021
30022 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
30023 self.generate_expression(&e.this)?;
30025 self.write_space();
30026 self.generate_expression(&e.expression)?;
30027 Ok(())
30028 }
30029
30030 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
30031 self.write_keyword("OPENJSON");
30033 self.write("(");
30034 self.generate_expression(&e.this)?;
30035 if let Some(path) = &e.path {
30036 self.write(", ");
30037 self.generate_expression(path)?;
30038 }
30039 self.write(")");
30040 if !e.expressions.is_empty() {
30041 self.write_keyword(" WITH");
30042 if self.config.pretty {
30043 self.write(" (\n");
30044 self.indent_level += 2;
30045 for (i, expr) in e.expressions.iter().enumerate() {
30046 if i > 0 {
30047 self.write(",\n");
30048 }
30049 self.write_indent();
30050 self.generate_expression(expr)?;
30051 }
30052 self.write("\n");
30053 self.indent_level -= 2;
30054 self.write(")");
30055 } else {
30056 self.write(" (");
30057 for (i, expr) in e.expressions.iter().enumerate() {
30058 if i > 0 {
30059 self.write(", ");
30060 }
30061 self.generate_expression(expr)?;
30062 }
30063 self.write(")");
30064 }
30065 }
30066 Ok(())
30067 }
30068
30069 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
30070 self.generate_expression(&e.this)?;
30072 self.write_space();
30073 if let Some(ref dt) = e.data_type {
30075 self.generate_data_type(dt)?;
30076 } else if !e.kind.is_empty() {
30077 self.write(&e.kind);
30078 }
30079 if let Some(path) = &e.path {
30080 self.write_space();
30081 self.generate_expression(path)?;
30082 }
30083 if e.as_json.is_some() {
30084 self.write_keyword(" AS JSON");
30085 }
30086 Ok(())
30087 }
30088
30089 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
30090 self.generate_expression(&e.this)?;
30092 self.write_space();
30093 if let Some(op) = &e.operator {
30094 self.write_keyword("OPERATOR");
30095 self.write("(");
30096 self.generate_expression(op)?;
30097 self.write(")");
30098 }
30099 for comment in &e.comments {
30101 self.write_space();
30102 self.write_formatted_comment(comment);
30103 }
30104 self.write_space();
30105 self.generate_expression(&e.expression)?;
30106 Ok(())
30107 }
30108
30109 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
30110 self.write_keyword("ORDER BY");
30112 let pretty_clickhouse_single_paren = self.config.pretty
30113 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
30114 && e.expressions.len() == 1
30115 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
30116 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
30117 && e.expressions.len() == 1
30118 && matches!(e.expressions[0].this, Expression::Tuple(_))
30119 && !e.expressions[0].desc
30120 && e.expressions[0].nulls_first.is_none();
30121
30122 if pretty_clickhouse_single_paren {
30123 self.write_space();
30124 if let Expression::Paren(p) = &e.expressions[0].this {
30125 self.write("(");
30126 self.write_newline();
30127 self.indent_level += 1;
30128 self.write_indent();
30129 self.generate_expression(&p.this)?;
30130 self.indent_level -= 1;
30131 self.write_newline();
30132 self.write(")");
30133 }
30134 return Ok(());
30135 }
30136
30137 if clickhouse_single_tuple {
30138 self.write_space();
30139 if let Expression::Tuple(t) = &e.expressions[0].this {
30140 self.write("(");
30141 for (i, expr) in t.expressions.iter().enumerate() {
30142 if i > 0 {
30143 self.write(", ");
30144 }
30145 self.generate_expression(expr)?;
30146 }
30147 self.write(")");
30148 }
30149 return Ok(());
30150 }
30151
30152 self.write_space();
30153 for (i, ordered) in e.expressions.iter().enumerate() {
30154 if i > 0 {
30155 self.write(", ");
30156 }
30157 self.generate_expression(&ordered.this)?;
30158 if ordered.desc {
30159 self.write_space();
30160 self.write_keyword("DESC");
30161 } else if ordered.explicit_asc {
30162 self.write_space();
30163 self.write_keyword("ASC");
30164 }
30165 if let Some(nulls_first) = ordered.nulls_first {
30166 let skip_nulls_last =
30168 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
30169 if !skip_nulls_last {
30170 self.write_space();
30171 self.write_keyword("NULLS");
30172 self.write_space();
30173 if nulls_first {
30174 self.write_keyword("FIRST");
30175 } else {
30176 self.write_keyword("LAST");
30177 }
30178 }
30179 }
30180 }
30181 Ok(())
30182 }
30183
30184 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
30185 self.write_keyword("OUTPUT");
30187 self.write("(");
30188 if self.config.pretty {
30189 self.indent_level += 1;
30190 self.write_newline();
30191 self.write_indent();
30192 self.generate_expression(&e.this)?;
30193 self.indent_level -= 1;
30194 self.write_newline();
30195 } else {
30196 self.generate_expression(&e.this)?;
30197 }
30198 self.write(")");
30199 Ok(())
30200 }
30201
30202 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
30203 self.write_keyword("TRUNCATE");
30205 if let Some(this) = &e.this {
30206 self.write_space();
30207 self.generate_expression(this)?;
30208 }
30209 if e.with_count.is_some() {
30210 self.write_keyword(" WITH COUNT");
30211 } else {
30212 self.write_keyword(" WITHOUT COUNT");
30213 }
30214 Ok(())
30215 }
30216
30217 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
30218 self.generate_expression(&e.this)?;
30220 self.write("(");
30221 for (i, expr) in e.expressions.iter().enumerate() {
30222 if i > 0 {
30223 self.write(", ");
30224 }
30225 self.generate_expression(expr)?;
30226 }
30227 self.write(")(");
30228 for (i, param) in e.params.iter().enumerate() {
30229 if i > 0 {
30230 self.write(", ");
30231 }
30232 self.generate_expression(param)?;
30233 }
30234 self.write(")");
30235 Ok(())
30236 }
30237
30238 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
30239 self.write_keyword("PARSE_DATETIME");
30241 self.write("(");
30242 if let Some(format) = &e.format {
30243 self.write("'");
30244 self.write(format);
30245 self.write("', ");
30246 }
30247 self.generate_expression(&e.this)?;
30248 if let Some(zone) = &e.zone {
30249 self.write(", ");
30250 self.generate_expression(zone)?;
30251 }
30252 self.write(")");
30253 Ok(())
30254 }
30255
30256 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
30257 self.write_keyword("PARSE_IP");
30259 self.write("(");
30260 self.generate_expression(&e.this)?;
30261 if let Some(type_) = &e.type_ {
30262 self.write(", ");
30263 self.generate_expression(type_)?;
30264 }
30265 if let Some(permissive) = &e.permissive {
30266 self.write(", ");
30267 self.generate_expression(permissive)?;
30268 }
30269 self.write(")");
30270 Ok(())
30271 }
30272
30273 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
30274 self.write_keyword("PARSE_JSON");
30276 self.write("(");
30277 self.generate_expression(&e.this)?;
30278 if let Some(expression) = &e.expression {
30279 self.write(", ");
30280 self.generate_expression(expression)?;
30281 }
30282 self.write(")");
30283 Ok(())
30284 }
30285
30286 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
30287 self.write_keyword("PARSE_TIME");
30289 self.write("(");
30290 self.write(&format!("'{}'", e.format));
30291 self.write(", ");
30292 self.generate_expression(&e.this)?;
30293 self.write(")");
30294 Ok(())
30295 }
30296
30297 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
30298 self.write_keyword("PARSE_URL");
30300 self.write("(");
30301 self.generate_expression(&e.this)?;
30302 if let Some(part) = &e.part_to_extract {
30303 self.write(", ");
30304 self.generate_expression(part)?;
30305 }
30306 if let Some(key) = &e.key {
30307 self.write(", ");
30308 self.generate_expression(key)?;
30309 }
30310 if let Some(permissive) = &e.permissive {
30311 self.write(", ");
30312 self.generate_expression(permissive)?;
30313 }
30314 self.write(")");
30315 Ok(())
30316 }
30317
30318 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
30319 if e.subpartition {
30321 self.write_keyword("SUBPARTITION");
30322 } else {
30323 self.write_keyword("PARTITION");
30324 }
30325 self.write("(");
30326 for (i, expr) in e.expressions.iter().enumerate() {
30327 if i > 0 {
30328 self.write(", ");
30329 }
30330 self.generate_expression(expr)?;
30331 }
30332 self.write(")");
30333 Ok(())
30334 }
30335
30336 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
30337 if let Some(this) = &e.this {
30339 if let Some(expression) = &e.expression {
30340 self.write_keyword("WITH");
30342 self.write(" (");
30343 self.write_keyword("MODULUS");
30344 self.write_space();
30345 self.generate_expression(this)?;
30346 self.write(", ");
30347 self.write_keyword("REMAINDER");
30348 self.write_space();
30349 self.generate_expression(expression)?;
30350 self.write(")");
30351 } else {
30352 self.write_keyword("IN");
30354 self.write(" (");
30355 self.generate_partition_bound_values(this)?;
30356 self.write(")");
30357 }
30358 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
30359 self.write_keyword("FROM");
30361 self.write(" (");
30362 self.generate_partition_bound_values(from)?;
30363 self.write(") ");
30364 self.write_keyword("TO");
30365 self.write(" (");
30366 self.generate_partition_bound_values(to)?;
30367 self.write(")");
30368 }
30369 Ok(())
30370 }
30371
30372 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
30375 if let Expression::Tuple(t) = expr {
30376 for (i, e) in t.expressions.iter().enumerate() {
30377 if i > 0 {
30378 self.write(", ");
30379 }
30380 self.generate_expression(e)?;
30381 }
30382 Ok(())
30383 } else {
30384 self.generate_expression(expr)
30385 }
30386 }
30387
30388 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
30389 self.write_keyword("PARTITION BY LIST");
30391 if let Some(partition_exprs) = &e.partition_expressions {
30392 self.write(" (");
30393 self.generate_doris_partition_expressions(partition_exprs)?;
30395 self.write(")");
30396 }
30397 if let Some(create_exprs) = &e.create_expressions {
30398 self.write(" (");
30399 self.generate_doris_partition_definitions(create_exprs)?;
30401 self.write(")");
30402 }
30403 Ok(())
30404 }
30405
30406 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
30407 self.write_keyword("PARTITION BY RANGE");
30409 if let Some(partition_exprs) = &e.partition_expressions {
30410 self.write(" (");
30411 self.generate_doris_partition_expressions(partition_exprs)?;
30413 self.write(")");
30414 }
30415 if let Some(create_exprs) = &e.create_expressions {
30416 self.write(" (");
30417 self.generate_doris_partition_definitions(create_exprs)?;
30419 self.write(")");
30420 }
30421 Ok(())
30422 }
30423
30424 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
30426 if let Expression::Tuple(t) = expr {
30427 for (i, e) in t.expressions.iter().enumerate() {
30428 if i > 0 {
30429 self.write(", ");
30430 }
30431 self.generate_expression(e)?;
30432 }
30433 } else {
30434 self.generate_expression(expr)?;
30435 }
30436 Ok(())
30437 }
30438
30439 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
30441 match expr {
30442 Expression::Tuple(t) => {
30443 for (i, part) in t.expressions.iter().enumerate() {
30445 if i > 0 {
30446 self.write(", ");
30447 }
30448 if let Expression::Partition(p) = part {
30450 for (j, inner) in p.expressions.iter().enumerate() {
30451 if j > 0 {
30452 self.write(", ");
30453 }
30454 self.generate_expression(inner)?;
30455 }
30456 } else {
30457 self.generate_expression(part)?;
30458 }
30459 }
30460 }
30461 Expression::PartitionByRangePropertyDynamic(_) => {
30462 self.generate_expression(expr)?;
30464 }
30465 _ => {
30466 self.generate_expression(expr)?;
30467 }
30468 }
30469 Ok(())
30470 }
30471
30472 fn generate_partition_by_range_property_dynamic(
30473 &mut self,
30474 e: &PartitionByRangePropertyDynamic,
30475 ) -> Result<()> {
30476 if e.use_start_end {
30477 if let Some(start) = &e.start {
30479 self.write_keyword("START");
30480 self.write(" (");
30481 self.generate_expression(start)?;
30482 self.write(")");
30483 }
30484 if let Some(end) = &e.end {
30485 self.write_space();
30486 self.write_keyword("END");
30487 self.write(" (");
30488 self.generate_expression(end)?;
30489 self.write(")");
30490 }
30491 if let Some(every) = &e.every {
30492 self.write_space();
30493 self.write_keyword("EVERY");
30494 self.write(" (");
30495 self.generate_doris_interval(every)?;
30497 self.write(")");
30498 }
30499 } else {
30500 if let Some(start) = &e.start {
30502 self.write_keyword("FROM");
30503 self.write(" (");
30504 self.generate_expression(start)?;
30505 self.write(")");
30506 }
30507 if let Some(end) = &e.end {
30508 self.write_space();
30509 self.write_keyword("TO");
30510 self.write(" (");
30511 self.generate_expression(end)?;
30512 self.write(")");
30513 }
30514 if let Some(every) = &e.every {
30515 self.write_space();
30516 self.generate_doris_interval(every)?;
30518 }
30519 }
30520 Ok(())
30521 }
30522
30523 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
30525 if let Expression::Interval(interval) = expr {
30526 self.write_keyword("INTERVAL");
30527 if let Some(ref value) = interval.this {
30528 self.write_space();
30529 match value {
30533 Expression::Literal(Literal::String(s))
30534 if s.chars()
30535 .all(|c| c.is_ascii_digit() || c == '.' || c == '-')
30536 && !s.is_empty() =>
30537 {
30538 self.write(s);
30539 }
30540 _ => {
30541 self.generate_expression(value)?;
30542 }
30543 }
30544 }
30545 if let Some(ref unit_spec) = interval.unit {
30546 self.write_space();
30547 self.write_interval_unit_spec(unit_spec)?;
30548 }
30549 Ok(())
30550 } else {
30551 self.generate_expression(expr)
30552 }
30553 }
30554
30555 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
30556 self.write_keyword("TRUNCATE");
30558 self.write("(");
30559 self.generate_expression(&e.expression)?;
30560 self.write(", ");
30561 self.generate_expression(&e.this)?;
30562 self.write(")");
30563 Ok(())
30564 }
30565
30566 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
30567 self.write_keyword("PARTITION");
30569 self.write_space();
30570 self.generate_expression(&e.this)?;
30571 self.write_space();
30572 self.write_keyword("VALUES IN");
30573 self.write(" (");
30574 for (i, expr) in e.expressions.iter().enumerate() {
30575 if i > 0 {
30576 self.write(", ");
30577 }
30578 self.generate_expression(expr)?;
30579 }
30580 self.write(")");
30581 Ok(())
30582 }
30583
30584 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
30585 if e.expressions.is_empty() && e.expression.is_some() {
30588 self.generate_expression(&e.this)?;
30590 self.write_space();
30591 self.write_keyword("TO");
30592 self.write_space();
30593 self.generate_expression(e.expression.as_ref().unwrap())?;
30594 return Ok(());
30595 }
30596
30597 self.write_keyword("PARTITION");
30599 self.write_space();
30600 self.generate_expression(&e.this)?;
30601 self.write_space();
30602
30603 if e.expressions.len() == 1 {
30605 self.write_keyword("VALUES LESS THAN");
30607 self.write(" (");
30608 self.generate_expression(&e.expressions[0])?;
30609 self.write(")");
30610 } else if !e.expressions.is_empty() {
30611 self.write_keyword("VALUES");
30613 self.write(" [");
30614 for (i, expr) in e.expressions.iter().enumerate() {
30615 if i > 0 {
30616 self.write(", ");
30617 }
30618 if let Expression::Tuple(t) = expr {
30620 self.write("(");
30621 for (j, inner) in t.expressions.iter().enumerate() {
30622 if j > 0 {
30623 self.write(", ");
30624 }
30625 self.generate_expression(inner)?;
30626 }
30627 self.write(")");
30628 } else {
30629 self.write("(");
30630 self.generate_expression(expr)?;
30631 self.write(")");
30632 }
30633 }
30634 self.write(")");
30635 }
30636 Ok(())
30637 }
30638
30639 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
30640 self.write_keyword("BUCKET");
30642 self.write("(");
30643 self.generate_expression(&e.this)?;
30644 self.write(", ");
30645 self.generate_expression(&e.expression)?;
30646 self.write(")");
30647 Ok(())
30648 }
30649
30650 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
30651 if matches!(
30653 self.config.dialect,
30654 Some(crate::dialects::DialectType::Teradata)
30655 | Some(crate::dialects::DialectType::ClickHouse)
30656 ) {
30657 self.write_keyword("PARTITION BY");
30658 } else {
30659 self.write_keyword("PARTITIONED BY");
30660 }
30661 self.write_space();
30662 if self.config.pretty {
30664 if let Expression::Tuple(ref tuple) = *e.this {
30665 self.write("(");
30666 self.write_newline();
30667 self.indent_level += 1;
30668 for (i, expr) in tuple.expressions.iter().enumerate() {
30669 if i > 0 {
30670 self.write(",");
30671 self.write_newline();
30672 }
30673 self.write_indent();
30674 self.generate_expression(expr)?;
30675 }
30676 self.indent_level -= 1;
30677 self.write_newline();
30678 self.write(")");
30679 } else {
30680 self.generate_expression(&e.this)?;
30681 }
30682 } else {
30683 self.generate_expression(&e.this)?;
30684 }
30685 Ok(())
30686 }
30687
30688 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
30689 self.write_keyword("PARTITION OF");
30691 self.write_space();
30692 self.generate_expression(&e.this)?;
30693 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
30695 self.write_space();
30696 self.write_keyword("FOR VALUES");
30697 self.write_space();
30698 self.generate_expression(&e.expression)?;
30699 } else {
30700 self.write_space();
30701 self.write_keyword("DEFAULT");
30702 }
30703 Ok(())
30704 }
30705
30706 fn generate_period_for_system_time_constraint(
30707 &mut self,
30708 e: &PeriodForSystemTimeConstraint,
30709 ) -> Result<()> {
30710 self.write_keyword("PERIOD FOR SYSTEM_TIME");
30712 self.write(" (");
30713 self.generate_expression(&e.this)?;
30714 self.write(", ");
30715 self.generate_expression(&e.expression)?;
30716 self.write(")");
30717 Ok(())
30718 }
30719
30720 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
30721 self.generate_expression(&e.this)?;
30724 self.write_space();
30725 self.write_keyword("AS");
30726 self.write_space();
30727 if self.config.unpivot_aliases_are_identifiers {
30729 match &e.alias {
30730 Expression::Literal(Literal::String(s)) => {
30731 self.generate_identifier(&Identifier::new(s.clone()))?;
30733 }
30734 Expression::Literal(Literal::Number(n)) => {
30735 let mut id = Identifier::new(n.clone());
30737 id.quoted = true;
30738 self.generate_identifier(&id)?;
30739 }
30740 other => {
30741 self.generate_expression(other)?;
30742 }
30743 }
30744 } else {
30745 self.generate_expression(&e.alias)?;
30746 }
30747 Ok(())
30748 }
30749
30750 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
30751 self.write_keyword("ANY");
30753 if let Some(this) = &e.this {
30754 self.write_space();
30755 self.generate_expression(this)?;
30756 }
30757 Ok(())
30758 }
30759
30760 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
30761 self.write_keyword("ML.PREDICT");
30763 self.write("(");
30764 self.write_keyword("MODEL");
30765 self.write_space();
30766 self.generate_expression(&e.this)?;
30767 self.write(", ");
30768 self.generate_expression(&e.expression)?;
30769 if let Some(params) = &e.params_struct {
30770 self.write(", ");
30771 self.generate_expression(params)?;
30772 }
30773 self.write(")");
30774 Ok(())
30775 }
30776
30777 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
30778 self.write_keyword("PREVIOUS_DAY");
30780 self.write("(");
30781 self.generate_expression(&e.this)?;
30782 self.write(", ");
30783 self.generate_expression(&e.expression)?;
30784 self.write(")");
30785 Ok(())
30786 }
30787
30788 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
30789 self.write_keyword("PRIMARY KEY");
30791 if let Some(name) = &e.this {
30792 self.write_space();
30793 self.generate_expression(name)?;
30794 }
30795 if !e.expressions.is_empty() {
30796 self.write(" (");
30797 for (i, expr) in e.expressions.iter().enumerate() {
30798 if i > 0 {
30799 self.write(", ");
30800 }
30801 self.generate_expression(expr)?;
30802 }
30803 self.write(")");
30804 }
30805 if let Some(include) = &e.include {
30806 self.write_space();
30807 self.generate_expression(include)?;
30808 }
30809 if !e.options.is_empty() {
30810 self.write_space();
30811 for (i, opt) in e.options.iter().enumerate() {
30812 if i > 0 {
30813 self.write_space();
30814 }
30815 self.generate_expression(opt)?;
30816 }
30817 }
30818 Ok(())
30819 }
30820
30821 fn generate_primary_key_column_constraint(
30822 &mut self,
30823 _e: &PrimaryKeyColumnConstraint,
30824 ) -> Result<()> {
30825 self.write_keyword("PRIMARY KEY");
30827 Ok(())
30828 }
30829
30830 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
30831 self.write_keyword("PATH");
30833 self.write_space();
30834 self.generate_expression(&e.this)?;
30835 Ok(())
30836 }
30837
30838 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
30839 self.write_keyword("PROJECTION");
30841 self.write_space();
30842 self.generate_expression(&e.this)?;
30843 self.write(" (");
30844 self.generate_expression(&e.expression)?;
30845 self.write(")");
30846 Ok(())
30847 }
30848
30849 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
30850 for (i, prop) in e.expressions.iter().enumerate() {
30852 if i > 0 {
30853 self.write(", ");
30854 }
30855 self.generate_expression(prop)?;
30856 }
30857 Ok(())
30858 }
30859
30860 fn generate_property(&mut self, e: &Property) -> Result<()> {
30861 self.generate_expression(&e.this)?;
30863 if let Some(value) = &e.value {
30864 self.write("=");
30865 self.generate_expression(value)?;
30866 }
30867 Ok(())
30868 }
30869
30870 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
30872 self.write_keyword("OPTIONS");
30873 self.write(" (");
30874 for (i, opt) in options.iter().enumerate() {
30875 if i > 0 {
30876 self.write(", ");
30877 }
30878 self.generate_option_expression(opt)?;
30879 }
30880 self.write(")");
30881 Ok(())
30882 }
30883
30884 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
30886 self.write_keyword("PROPERTIES");
30887 self.write(" (");
30888 for (i, prop) in properties.iter().enumerate() {
30889 if i > 0 {
30890 self.write(", ");
30891 }
30892 self.generate_option_expression(prop)?;
30893 }
30894 self.write(")");
30895 Ok(())
30896 }
30897
30898 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
30900 self.write_keyword("ENVIRONMENT");
30901 self.write(" (");
30902 for (i, env_item) in environment.iter().enumerate() {
30903 if i > 0 {
30904 self.write(", ");
30905 }
30906 self.generate_environment_expression(env_item)?;
30907 }
30908 self.write(")");
30909 Ok(())
30910 }
30911
30912 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
30914 match expr {
30915 Expression::Eq(eq) => {
30916 self.generate_expression(&eq.left)?;
30918 self.write(" = ");
30919 self.generate_expression(&eq.right)?;
30920 Ok(())
30921 }
30922 _ => self.generate_expression(expr),
30923 }
30924 }
30925
30926 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
30928 self.write_keyword("TBLPROPERTIES");
30929 if self.config.pretty {
30930 self.write(" (");
30931 self.write_newline();
30932 self.indent_level += 1;
30933 for (i, opt) in options.iter().enumerate() {
30934 if i > 0 {
30935 self.write(",");
30936 self.write_newline();
30937 }
30938 self.write_indent();
30939 self.generate_option_expression(opt)?;
30940 }
30941 self.indent_level -= 1;
30942 self.write_newline();
30943 self.write(")");
30944 } else {
30945 self.write(" (");
30946 for (i, opt) in options.iter().enumerate() {
30947 if i > 0 {
30948 self.write(", ");
30949 }
30950 self.generate_option_expression(opt)?;
30951 }
30952 self.write(")");
30953 }
30954 Ok(())
30955 }
30956
30957 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
30959 match expr {
30960 Expression::Eq(eq) => {
30961 self.generate_expression(&eq.left)?;
30963 self.write("=");
30964 self.generate_expression(&eq.right)?;
30965 Ok(())
30966 }
30967 _ => self.generate_expression(expr),
30968 }
30969 }
30970
30971 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
30972 self.generate_expression(&e.this)?;
30974 Ok(())
30975 }
30976
30977 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
30978 self.write_keyword("PUT");
30980 self.write_space();
30981
30982 if e.source_quoted {
30984 self.write("'");
30985 self.write(&e.source);
30986 self.write("'");
30987 } else {
30988 self.write(&e.source);
30989 }
30990
30991 self.write_space();
30992
30993 if let Expression::Literal(Literal::String(s)) = &e.target {
30995 self.write(s);
30996 } else {
30997 self.generate_expression(&e.target)?;
30998 }
30999
31000 for param in &e.params {
31002 self.write_space();
31003 self.write(¶m.name);
31004 if let Some(ref value) = param.value {
31005 self.write("=");
31006 self.generate_expression(value)?;
31007 }
31008 }
31009
31010 Ok(())
31011 }
31012
31013 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
31014 self.write_keyword("QUANTILE");
31016 self.write("(");
31017 self.generate_expression(&e.this)?;
31018 if let Some(quantile) = &e.quantile {
31019 self.write(", ");
31020 self.generate_expression(quantile)?;
31021 }
31022 self.write(")");
31023 Ok(())
31024 }
31025
31026 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
31027 if matches!(
31029 self.config.dialect,
31030 Some(crate::dialects::DialectType::Teradata)
31031 ) {
31032 self.write_keyword("SET");
31033 self.write_space();
31034 }
31035 self.write_keyword("QUERY_BAND");
31036 self.write(" = ");
31037 self.generate_expression(&e.this)?;
31038 if e.update.is_some() {
31039 self.write_space();
31040 self.write_keyword("UPDATE");
31041 }
31042 if let Some(scope) = &e.scope {
31043 self.write_space();
31044 self.write_keyword("FOR");
31045 self.write_space();
31046 self.generate_expression(scope)?;
31047 }
31048 Ok(())
31049 }
31050
31051 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
31052 self.generate_expression(&e.this)?;
31054 if let Some(expression) = &e.expression {
31055 self.write(" = ");
31056 self.generate_expression(expression)?;
31057 }
31058 Ok(())
31059 }
31060
31061 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
31062 self.write_keyword("TRANSFORM");
31064 self.write("(");
31065 for (i, expr) in e.expressions.iter().enumerate() {
31066 if i > 0 {
31067 self.write(", ");
31068 }
31069 self.generate_expression(expr)?;
31070 }
31071 self.write(")");
31072 if let Some(row_format_before) = &e.row_format_before {
31073 self.write_space();
31074 self.generate_expression(row_format_before)?;
31075 }
31076 if let Some(record_writer) = &e.record_writer {
31077 self.write_space();
31078 self.write_keyword("RECORDWRITER");
31079 self.write_space();
31080 self.generate_expression(record_writer)?;
31081 }
31082 if let Some(command_script) = &e.command_script {
31083 self.write_space();
31084 self.write_keyword("USING");
31085 self.write_space();
31086 self.generate_expression(command_script)?;
31087 }
31088 if let Some(schema) = &e.schema {
31089 self.write_space();
31090 self.write_keyword("AS");
31091 self.write_space();
31092 self.generate_expression(schema)?;
31093 }
31094 if let Some(row_format_after) = &e.row_format_after {
31095 self.write_space();
31096 self.generate_expression(row_format_after)?;
31097 }
31098 if let Some(record_reader) = &e.record_reader {
31099 self.write_space();
31100 self.write_keyword("RECORDREADER");
31101 self.write_space();
31102 self.generate_expression(record_reader)?;
31103 }
31104 Ok(())
31105 }
31106
31107 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
31108 self.write_keyword("RANDN");
31110 self.write("(");
31111 if let Some(this) = &e.this {
31112 self.generate_expression(this)?;
31113 }
31114 self.write(")");
31115 Ok(())
31116 }
31117
31118 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
31119 self.write_keyword("RANDSTR");
31121 self.write("(");
31122 self.generate_expression(&e.this)?;
31123 if let Some(generator) = &e.generator {
31124 self.write(", ");
31125 self.generate_expression(generator)?;
31126 }
31127 self.write(")");
31128 Ok(())
31129 }
31130
31131 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
31132 self.write_keyword("RANGE_BUCKET");
31134 self.write("(");
31135 self.generate_expression(&e.this)?;
31136 self.write(", ");
31137 self.generate_expression(&e.expression)?;
31138 self.write(")");
31139 Ok(())
31140 }
31141
31142 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
31143 self.write_keyword("RANGE_N");
31145 self.write("(");
31146 self.generate_expression(&e.this)?;
31147 self.write_space();
31148 self.write_keyword("BETWEEN");
31149 self.write_space();
31150 for (i, expr) in e.expressions.iter().enumerate() {
31151 if i > 0 {
31152 self.write(", ");
31153 }
31154 self.generate_expression(expr)?;
31155 }
31156 if let Some(each) = &e.each {
31157 self.write_space();
31158 self.write_keyword("EACH");
31159 self.write_space();
31160 self.generate_expression(each)?;
31161 }
31162 self.write(")");
31163 Ok(())
31164 }
31165
31166 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
31167 self.write_keyword("READ_CSV");
31169 self.write("(");
31170 self.generate_expression(&e.this)?;
31171 for expr in &e.expressions {
31172 self.write(", ");
31173 self.generate_expression(expr)?;
31174 }
31175 self.write(")");
31176 Ok(())
31177 }
31178
31179 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
31180 self.write_keyword("READ_PARQUET");
31182 self.write("(");
31183 for (i, expr) in e.expressions.iter().enumerate() {
31184 if i > 0 {
31185 self.write(", ");
31186 }
31187 self.generate_expression(expr)?;
31188 }
31189 self.write(")");
31190 Ok(())
31191 }
31192
31193 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
31194 if e.kind == "CYCLE" {
31197 self.write_keyword("CYCLE");
31198 } else {
31199 self.write_keyword("SEARCH");
31200 self.write_space();
31201 self.write(&e.kind);
31202 self.write_space();
31203 self.write_keyword("FIRST BY");
31204 }
31205 self.write_space();
31206 self.generate_expression(&e.this)?;
31207 self.write_space();
31208 self.write_keyword("SET");
31209 self.write_space();
31210 self.generate_expression(&e.expression)?;
31211 if let Some(using) = &e.using {
31212 self.write_space();
31213 self.write_keyword("USING");
31214 self.write_space();
31215 self.generate_expression(using)?;
31216 }
31217 Ok(())
31218 }
31219
31220 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
31221 self.write_keyword("REDUCE");
31223 self.write("(");
31224 self.generate_expression(&e.this)?;
31225 if let Some(initial) = &e.initial {
31226 self.write(", ");
31227 self.generate_expression(initial)?;
31228 }
31229 if let Some(merge) = &e.merge {
31230 self.write(", ");
31231 self.generate_expression(merge)?;
31232 }
31233 if let Some(finish) = &e.finish {
31234 self.write(", ");
31235 self.generate_expression(finish)?;
31236 }
31237 self.write(")");
31238 Ok(())
31239 }
31240
31241 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
31242 self.write_keyword("REFERENCES");
31244 self.write_space();
31245 self.generate_expression(&e.this)?;
31246 if !e.expressions.is_empty() {
31247 self.write(" (");
31248 for (i, expr) in e.expressions.iter().enumerate() {
31249 if i > 0 {
31250 self.write(", ");
31251 }
31252 self.generate_expression(expr)?;
31253 }
31254 self.write(")");
31255 }
31256 for opt in &e.options {
31257 self.write_space();
31258 self.generate_expression(opt)?;
31259 }
31260 Ok(())
31261 }
31262
31263 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
31264 self.write_keyword("REFRESH");
31266 if !e.kind.is_empty() {
31267 self.write_space();
31268 self.write_keyword(&e.kind);
31269 }
31270 self.write_space();
31271 self.generate_expression(&e.this)?;
31272 Ok(())
31273 }
31274
31275 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
31276 self.write_keyword("REFRESH");
31278 self.write_space();
31279 self.write_keyword(&e.method);
31280
31281 if let Some(ref kind) = e.kind {
31282 self.write_space();
31283 self.write_keyword("ON");
31284 self.write_space();
31285 self.write_keyword(kind);
31286
31287 if let Some(ref every) = e.every {
31289 self.write_space();
31290 self.write_keyword("EVERY");
31291 self.write_space();
31292 self.generate_expression(every)?;
31293 if let Some(ref unit) = e.unit {
31294 self.write_space();
31295 self.write_keyword(unit);
31296 }
31297 }
31298
31299 if let Some(ref starts) = e.starts {
31301 self.write_space();
31302 self.write_keyword("STARTS");
31303 self.write_space();
31304 self.generate_expression(starts)?;
31305 }
31306 }
31307 Ok(())
31308 }
31309
31310 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
31311 self.write_keyword("REGEXP_COUNT");
31313 self.write("(");
31314 self.generate_expression(&e.this)?;
31315 self.write(", ");
31316 self.generate_expression(&e.expression)?;
31317 if let Some(position) = &e.position {
31318 self.write(", ");
31319 self.generate_expression(position)?;
31320 }
31321 if let Some(parameters) = &e.parameters {
31322 self.write(", ");
31323 self.generate_expression(parameters)?;
31324 }
31325 self.write(")");
31326 Ok(())
31327 }
31328
31329 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
31330 self.write_keyword("REGEXP_EXTRACT_ALL");
31332 self.write("(");
31333 self.generate_expression(&e.this)?;
31334 self.write(", ");
31335 self.generate_expression(&e.expression)?;
31336 if let Some(group) = &e.group {
31337 self.write(", ");
31338 self.generate_expression(group)?;
31339 }
31340 self.write(")");
31341 Ok(())
31342 }
31343
31344 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
31345 self.write_keyword("REGEXP_FULL_MATCH");
31347 self.write("(");
31348 self.generate_expression(&e.this)?;
31349 self.write(", ");
31350 self.generate_expression(&e.expression)?;
31351 self.write(")");
31352 Ok(())
31353 }
31354
31355 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
31356 use crate::dialects::DialectType;
31357 if matches!(
31359 self.config.dialect,
31360 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
31361 ) && e.flag.is_none()
31362 {
31363 self.generate_expression(&e.this)?;
31364 self.write(" ~* ");
31365 self.generate_expression(&e.expression)?;
31366 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
31367 self.write_keyword("REGEXP_LIKE");
31369 self.write("(");
31370 self.generate_expression(&e.this)?;
31371 self.write(", ");
31372 self.generate_expression(&e.expression)?;
31373 self.write(", ");
31374 if let Some(flag) = &e.flag {
31375 self.generate_expression(flag)?;
31376 } else {
31377 self.write("'i'");
31378 }
31379 self.write(")");
31380 } else {
31381 self.generate_expression(&e.this)?;
31383 self.write_space();
31384 self.write_keyword("REGEXP_ILIKE");
31385 self.write_space();
31386 self.generate_expression(&e.expression)?;
31387 if let Some(flag) = &e.flag {
31388 self.write(", ");
31389 self.generate_expression(flag)?;
31390 }
31391 }
31392 Ok(())
31393 }
31394
31395 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
31396 self.write_keyword("REGEXP_INSTR");
31398 self.write("(");
31399 self.generate_expression(&e.this)?;
31400 self.write(", ");
31401 self.generate_expression(&e.expression)?;
31402 if let Some(position) = &e.position {
31403 self.write(", ");
31404 self.generate_expression(position)?;
31405 }
31406 if let Some(occurrence) = &e.occurrence {
31407 self.write(", ");
31408 self.generate_expression(occurrence)?;
31409 }
31410 if let Some(option) = &e.option {
31411 self.write(", ");
31412 self.generate_expression(option)?;
31413 }
31414 if let Some(parameters) = &e.parameters {
31415 self.write(", ");
31416 self.generate_expression(parameters)?;
31417 }
31418 if let Some(group) = &e.group {
31419 self.write(", ");
31420 self.generate_expression(group)?;
31421 }
31422 self.write(")");
31423 Ok(())
31424 }
31425
31426 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
31427 self.write_keyword("REGEXP_SPLIT");
31429 self.write("(");
31430 self.generate_expression(&e.this)?;
31431 self.write(", ");
31432 self.generate_expression(&e.expression)?;
31433 if let Some(limit) = &e.limit {
31434 self.write(", ");
31435 self.generate_expression(limit)?;
31436 }
31437 self.write(")");
31438 Ok(())
31439 }
31440
31441 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
31442 self.write_keyword("REGR_AVGX");
31444 self.write("(");
31445 self.generate_expression(&e.this)?;
31446 self.write(", ");
31447 self.generate_expression(&e.expression)?;
31448 self.write(")");
31449 Ok(())
31450 }
31451
31452 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
31453 self.write_keyword("REGR_AVGY");
31455 self.write("(");
31456 self.generate_expression(&e.this)?;
31457 self.write(", ");
31458 self.generate_expression(&e.expression)?;
31459 self.write(")");
31460 Ok(())
31461 }
31462
31463 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
31464 self.write_keyword("REGR_COUNT");
31466 self.write("(");
31467 self.generate_expression(&e.this)?;
31468 self.write(", ");
31469 self.generate_expression(&e.expression)?;
31470 self.write(")");
31471 Ok(())
31472 }
31473
31474 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
31475 self.write_keyword("REGR_INTERCEPT");
31477 self.write("(");
31478 self.generate_expression(&e.this)?;
31479 self.write(", ");
31480 self.generate_expression(&e.expression)?;
31481 self.write(")");
31482 Ok(())
31483 }
31484
31485 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
31486 self.write_keyword("REGR_R2");
31488 self.write("(");
31489 self.generate_expression(&e.this)?;
31490 self.write(", ");
31491 self.generate_expression(&e.expression)?;
31492 self.write(")");
31493 Ok(())
31494 }
31495
31496 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
31497 self.write_keyword("REGR_SLOPE");
31499 self.write("(");
31500 self.generate_expression(&e.this)?;
31501 self.write(", ");
31502 self.generate_expression(&e.expression)?;
31503 self.write(")");
31504 Ok(())
31505 }
31506
31507 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
31508 self.write_keyword("REGR_SXX");
31510 self.write("(");
31511 self.generate_expression(&e.this)?;
31512 self.write(", ");
31513 self.generate_expression(&e.expression)?;
31514 self.write(")");
31515 Ok(())
31516 }
31517
31518 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
31519 self.write_keyword("REGR_SXY");
31521 self.write("(");
31522 self.generate_expression(&e.this)?;
31523 self.write(", ");
31524 self.generate_expression(&e.expression)?;
31525 self.write(")");
31526 Ok(())
31527 }
31528
31529 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
31530 self.write_keyword("REGR_SYY");
31532 self.write("(");
31533 self.generate_expression(&e.this)?;
31534 self.write(", ");
31535 self.generate_expression(&e.expression)?;
31536 self.write(")");
31537 Ok(())
31538 }
31539
31540 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
31541 self.write_keyword("REGR_VALX");
31543 self.write("(");
31544 self.generate_expression(&e.this)?;
31545 self.write(", ");
31546 self.generate_expression(&e.expression)?;
31547 self.write(")");
31548 Ok(())
31549 }
31550
31551 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
31552 self.write_keyword("REGR_VALY");
31554 self.write("(");
31555 self.generate_expression(&e.this)?;
31556 self.write(", ");
31557 self.generate_expression(&e.expression)?;
31558 self.write(")");
31559 Ok(())
31560 }
31561
31562 fn generate_remote_with_connection_model_property(
31563 &mut self,
31564 e: &RemoteWithConnectionModelProperty,
31565 ) -> Result<()> {
31566 self.write_keyword("REMOTE WITH CONNECTION");
31568 self.write_space();
31569 self.generate_expression(&e.this)?;
31570 Ok(())
31571 }
31572
31573 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
31574 self.write_keyword("RENAME COLUMN");
31576 if e.exists {
31577 self.write_space();
31578 self.write_keyword("IF EXISTS");
31579 }
31580 self.write_space();
31581 self.generate_expression(&e.this)?;
31582 if let Some(to) = &e.to {
31583 self.write_space();
31584 self.write_keyword("TO");
31585 self.write_space();
31586 self.generate_expression(to)?;
31587 }
31588 Ok(())
31589 }
31590
31591 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
31592 self.write_keyword("REPLACE PARTITION");
31594 self.write_space();
31595 self.generate_expression(&e.expression)?;
31596 if let Some(source) = &e.source {
31597 self.write_space();
31598 self.write_keyword("FROM");
31599 self.write_space();
31600 self.generate_expression(source)?;
31601 }
31602 Ok(())
31603 }
31604
31605 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
31606 let keyword = match self.config.dialect {
31609 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
31610 _ => "RETURNING",
31611 };
31612 self.write_keyword(keyword);
31613 self.write_space();
31614 for (i, expr) in e.expressions.iter().enumerate() {
31615 if i > 0 {
31616 self.write(", ");
31617 }
31618 self.generate_expression(expr)?;
31619 }
31620 if let Some(into) = &e.into {
31621 self.write_space();
31622 self.write_keyword("INTO");
31623 self.write_space();
31624 self.generate_expression(into)?;
31625 }
31626 Ok(())
31627 }
31628
31629 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
31630 self.write_space();
31632 self.write_keyword("OUTPUT");
31633 self.write_space();
31634 for (i, expr) in output.columns.iter().enumerate() {
31635 if i > 0 {
31636 self.write(", ");
31637 }
31638 self.generate_expression(expr)?;
31639 }
31640 if let Some(into_table) = &output.into_table {
31641 self.write_space();
31642 self.write_keyword("INTO");
31643 self.write_space();
31644 self.generate_expression(into_table)?;
31645 }
31646 Ok(())
31647 }
31648
31649 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
31650 self.write_keyword("RETURNS");
31652 if e.is_table.is_some() {
31653 self.write_space();
31654 self.write_keyword("TABLE");
31655 }
31656 if let Some(table) = &e.table {
31657 self.write_space();
31658 self.generate_expression(table)?;
31659 } else if let Some(this) = &e.this {
31660 self.write_space();
31661 self.generate_expression(this)?;
31662 }
31663 if e.null.is_some() {
31664 self.write_space();
31665 self.write_keyword("NULL ON NULL INPUT");
31666 }
31667 Ok(())
31668 }
31669
31670 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
31671 self.write_keyword("ROLLBACK");
31673
31674 if e.this.is_none()
31676 && matches!(
31677 self.config.dialect,
31678 Some(DialectType::TSQL) | Some(DialectType::Fabric)
31679 )
31680 {
31681 self.write_space();
31682 self.write_keyword("TRANSACTION");
31683 }
31684
31685 if let Some(this) = &e.this {
31687 let is_transaction_marker = matches!(
31689 this.as_ref(),
31690 Expression::Identifier(id) if id.name == "TRANSACTION"
31691 );
31692
31693 self.write_space();
31694 self.write_keyword("TRANSACTION");
31695
31696 if !is_transaction_marker {
31698 self.write_space();
31699 self.generate_expression(this)?;
31700 }
31701 }
31702
31703 if let Some(savepoint) = &e.savepoint {
31705 self.write_space();
31706 self.write_keyword("TO");
31707 self.write_space();
31708 self.generate_expression(savepoint)?;
31709 }
31710 Ok(())
31711 }
31712
31713 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
31714 if e.expressions.is_empty() {
31716 self.write_keyword("WITH ROLLUP");
31717 } else {
31718 self.write_keyword("ROLLUP");
31719 self.write("(");
31720 for (i, expr) in e.expressions.iter().enumerate() {
31721 if i > 0 {
31722 self.write(", ");
31723 }
31724 self.generate_expression(expr)?;
31725 }
31726 self.write(")");
31727 }
31728 Ok(())
31729 }
31730
31731 fn generate_row_format_delimited_property(
31732 &mut self,
31733 e: &RowFormatDelimitedProperty,
31734 ) -> Result<()> {
31735 self.write_keyword("ROW FORMAT DELIMITED");
31737 if let Some(fields) = &e.fields {
31738 self.write_space();
31739 self.write_keyword("FIELDS TERMINATED BY");
31740 self.write_space();
31741 self.generate_expression(fields)?;
31742 }
31743 if let Some(escaped) = &e.escaped {
31744 self.write_space();
31745 self.write_keyword("ESCAPED BY");
31746 self.write_space();
31747 self.generate_expression(escaped)?;
31748 }
31749 if let Some(items) = &e.collection_items {
31750 self.write_space();
31751 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
31752 self.write_space();
31753 self.generate_expression(items)?;
31754 }
31755 if let Some(keys) = &e.map_keys {
31756 self.write_space();
31757 self.write_keyword("MAP KEYS TERMINATED BY");
31758 self.write_space();
31759 self.generate_expression(keys)?;
31760 }
31761 if let Some(lines) = &e.lines {
31762 self.write_space();
31763 self.write_keyword("LINES TERMINATED BY");
31764 self.write_space();
31765 self.generate_expression(lines)?;
31766 }
31767 if let Some(null) = &e.null {
31768 self.write_space();
31769 self.write_keyword("NULL DEFINED AS");
31770 self.write_space();
31771 self.generate_expression(null)?;
31772 }
31773 if let Some(serde) = &e.serde {
31774 self.write_space();
31775 self.generate_expression(serde)?;
31776 }
31777 Ok(())
31778 }
31779
31780 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
31781 self.write_keyword("ROW FORMAT");
31783 self.write_space();
31784 self.generate_expression(&e.this)?;
31785 Ok(())
31786 }
31787
31788 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
31789 self.write_keyword("ROW FORMAT SERDE");
31791 self.write_space();
31792 self.generate_expression(&e.this)?;
31793 if let Some(props) = &e.serde_properties {
31794 self.write_space();
31795 self.generate_expression(props)?;
31797 }
31798 Ok(())
31799 }
31800
31801 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
31802 self.write_keyword("SHA2");
31804 self.write("(");
31805 self.generate_expression(&e.this)?;
31806 if let Some(length) = e.length {
31807 self.write(", ");
31808 self.write(&length.to_string());
31809 }
31810 self.write(")");
31811 Ok(())
31812 }
31813
31814 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
31815 self.write_keyword("SHA2_DIGEST");
31817 self.write("(");
31818 self.generate_expression(&e.this)?;
31819 if let Some(length) = e.length {
31820 self.write(", ");
31821 self.write(&length.to_string());
31822 }
31823 self.write(")");
31824 Ok(())
31825 }
31826
31827 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
31828 let name = if matches!(
31829 self.config.dialect,
31830 Some(crate::dialects::DialectType::Spark)
31831 | Some(crate::dialects::DialectType::Databricks)
31832 ) {
31833 "TRY_ADD"
31834 } else {
31835 "SAFE_ADD"
31836 };
31837 self.write_keyword(name);
31838 self.write("(");
31839 self.generate_expression(&e.this)?;
31840 self.write(", ");
31841 self.generate_expression(&e.expression)?;
31842 self.write(")");
31843 Ok(())
31844 }
31845
31846 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
31847 self.write_keyword("SAFE_DIVIDE");
31849 self.write("(");
31850 self.generate_expression(&e.this)?;
31851 self.write(", ");
31852 self.generate_expression(&e.expression)?;
31853 self.write(")");
31854 Ok(())
31855 }
31856
31857 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
31858 let name = if matches!(
31859 self.config.dialect,
31860 Some(crate::dialects::DialectType::Spark)
31861 | Some(crate::dialects::DialectType::Databricks)
31862 ) {
31863 "TRY_MULTIPLY"
31864 } else {
31865 "SAFE_MULTIPLY"
31866 };
31867 self.write_keyword(name);
31868 self.write("(");
31869 self.generate_expression(&e.this)?;
31870 self.write(", ");
31871 self.generate_expression(&e.expression)?;
31872 self.write(")");
31873 Ok(())
31874 }
31875
31876 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
31877 let name = if matches!(
31878 self.config.dialect,
31879 Some(crate::dialects::DialectType::Spark)
31880 | Some(crate::dialects::DialectType::Databricks)
31881 ) {
31882 "TRY_SUBTRACT"
31883 } else {
31884 "SAFE_SUBTRACT"
31885 };
31886 self.write_keyword(name);
31887 self.write("(");
31888 self.generate_expression(&e.this)?;
31889 self.write(", ");
31890 self.generate_expression(&e.expression)?;
31891 self.write(")");
31892 Ok(())
31893 }
31894
31895 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
31898 if matches!(sample.method, SampleMethod::Bucket) {
31900 self.write(" (");
31901 self.write_keyword("BUCKET");
31902 self.write_space();
31903 if let Some(ref num) = sample.bucket_numerator {
31904 self.generate_expression(num)?;
31905 }
31906 self.write_space();
31907 self.write_keyword("OUT OF");
31908 self.write_space();
31909 if let Some(ref denom) = sample.bucket_denominator {
31910 self.generate_expression(denom)?;
31911 }
31912 if let Some(ref field) = sample.bucket_field {
31913 self.write_space();
31914 self.write_keyword("ON");
31915 self.write_space();
31916 self.generate_expression(field)?;
31917 }
31918 self.write(")");
31919 return Ok(());
31920 }
31921
31922 let is_snowflake = matches!(
31924 self.config.dialect,
31925 Some(crate::dialects::DialectType::Snowflake)
31926 );
31927 let is_postgres = matches!(
31928 self.config.dialect,
31929 Some(crate::dialects::DialectType::PostgreSQL)
31930 | Some(crate::dialects::DialectType::Redshift)
31931 );
31932 let is_databricks = matches!(
31934 self.config.dialect,
31935 Some(crate::dialects::DialectType::Databricks)
31936 );
31937 let is_spark = matches!(
31938 self.config.dialect,
31939 Some(crate::dialects::DialectType::Spark)
31940 );
31941 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
31942 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
31944 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
31945 self.write_space();
31946 if !sample.explicit_method && (is_snowflake || force_method) {
31947 self.write_keyword("BERNOULLI");
31949 } else {
31950 match sample.method {
31951 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
31952 SampleMethod::System => self.write_keyword("SYSTEM"),
31953 SampleMethod::Block => self.write_keyword("BLOCK"),
31954 SampleMethod::Row => self.write_keyword("ROW"),
31955 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
31956 SampleMethod::Percent => self.write_keyword("SYSTEM"),
31957 SampleMethod::Bucket => {} }
31959 }
31960 }
31961
31962 let emit_size_no_parens = !self.config.tablesample_requires_parens;
31964 if emit_size_no_parens {
31965 self.write_space();
31966 match &sample.size {
31967 Expression::Tuple(tuple) => {
31968 for (i, expr) in tuple.expressions.iter().enumerate() {
31969 if i > 0 {
31970 self.write(", ");
31971 }
31972 self.generate_expression(expr)?;
31973 }
31974 }
31975 expr => self.generate_expression(expr)?,
31976 }
31977 } else {
31978 self.write(" (");
31979 self.generate_expression(&sample.size)?;
31980 }
31981
31982 let is_rows_method = matches!(
31984 sample.method,
31985 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
31986 );
31987 let is_percent = matches!(
31988 sample.method,
31989 SampleMethod::Percent
31990 | SampleMethod::System
31991 | SampleMethod::Bernoulli
31992 | SampleMethod::Block
31993 );
31994
31995 let is_presto = matches!(
31999 self.config.dialect,
32000 Some(crate::dialects::DialectType::Presto)
32001 | Some(crate::dialects::DialectType::Trino)
32002 | Some(crate::dialects::DialectType::Athena)
32003 );
32004 let should_output_unit = if is_databricks || is_spark {
32005 is_percent || is_rows_method || sample.unit_after_size
32007 } else if is_snowflake || is_postgres || is_presto {
32008 sample.unit_after_size
32009 } else {
32010 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
32011 };
32012
32013 if should_output_unit {
32014 self.write_space();
32015 if sample.is_percent {
32016 self.write_keyword("PERCENT");
32017 } else if is_rows_method && !sample.unit_after_size {
32018 self.write_keyword("ROWS");
32019 } else if sample.unit_after_size {
32020 match sample.method {
32021 SampleMethod::Percent
32022 | SampleMethod::System
32023 | SampleMethod::Bernoulli
32024 | SampleMethod::Block => {
32025 self.write_keyword("PERCENT");
32026 }
32027 SampleMethod::Row | SampleMethod::Reservoir => {
32028 self.write_keyword("ROWS");
32029 }
32030 _ => self.write_keyword("ROWS"),
32031 }
32032 } else {
32033 self.write_keyword("PERCENT");
32034 }
32035 }
32036
32037 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32038 if let Some(ref offset) = sample.offset {
32039 self.write_space();
32040 self.write_keyword("OFFSET");
32041 self.write_space();
32042 self.generate_expression(offset)?;
32043 }
32044 }
32045 if !emit_size_no_parens {
32046 self.write(")");
32047 }
32048
32049 Ok(())
32050 }
32051
32052 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
32053 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32055 self.write_keyword("SAMPLE BY");
32056 } else {
32057 self.write_keyword("SAMPLE");
32058 }
32059 self.write_space();
32060 self.generate_expression(&e.this)?;
32061 Ok(())
32062 }
32063
32064 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
32065 if let Some(this) = &e.this {
32067 self.generate_expression(this)?;
32068 }
32069 if !e.expressions.is_empty() {
32070 if e.this.is_some() {
32072 self.write_space();
32073 }
32074 self.write("(");
32075 for (i, expr) in e.expressions.iter().enumerate() {
32076 if i > 0 {
32077 self.write(", ");
32078 }
32079 self.generate_expression(expr)?;
32080 }
32081 self.write(")");
32082 }
32083 Ok(())
32084 }
32085
32086 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
32087 self.write_keyword("COMMENT");
32089 self.write_space();
32090 self.generate_expression(&e.this)?;
32091 Ok(())
32092 }
32093
32094 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
32095 if let Some(this) = &e.this {
32097 self.generate_expression(this)?;
32098 self.write("::");
32099 }
32100 self.generate_expression(&e.expression)?;
32101 Ok(())
32102 }
32103
32104 fn generate_search(&mut self, e: &Search) -> Result<()> {
32105 self.write_keyword("SEARCH");
32107 self.write("(");
32108 self.generate_expression(&e.this)?;
32109 self.write(", ");
32110 self.generate_expression(&e.expression)?;
32111 if let Some(json_scope) = &e.json_scope {
32112 self.write(", ");
32113 self.generate_expression(json_scope)?;
32114 }
32115 if let Some(analyzer) = &e.analyzer {
32116 self.write(", ");
32117 self.generate_expression(analyzer)?;
32118 }
32119 if let Some(analyzer_options) = &e.analyzer_options {
32120 self.write(", ");
32121 self.generate_expression(analyzer_options)?;
32122 }
32123 if let Some(search_mode) = &e.search_mode {
32124 self.write(", ");
32125 self.generate_expression(search_mode)?;
32126 }
32127 self.write(")");
32128 Ok(())
32129 }
32130
32131 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
32132 self.write_keyword("SEARCH_IP");
32134 self.write("(");
32135 self.generate_expression(&e.this)?;
32136 self.write(", ");
32137 self.generate_expression(&e.expression)?;
32138 self.write(")");
32139 Ok(())
32140 }
32141
32142 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
32143 self.write_keyword("SECURITY");
32145 self.write_space();
32146 self.generate_expression(&e.this)?;
32147 Ok(())
32148 }
32149
32150 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
32151 self.write("SEMANTIC_VIEW(");
32153
32154 if self.config.pretty {
32155 self.write_newline();
32157 self.indent_level += 1;
32158 self.write_indent();
32159 self.generate_expression(&e.this)?;
32160
32161 if let Some(metrics) = &e.metrics {
32162 self.write_newline();
32163 self.write_indent();
32164 self.write_keyword("METRICS");
32165 self.write_space();
32166 self.generate_semantic_view_tuple(metrics)?;
32167 }
32168 if let Some(dimensions) = &e.dimensions {
32169 self.write_newline();
32170 self.write_indent();
32171 self.write_keyword("DIMENSIONS");
32172 self.write_space();
32173 self.generate_semantic_view_tuple(dimensions)?;
32174 }
32175 if let Some(facts) = &e.facts {
32176 self.write_newline();
32177 self.write_indent();
32178 self.write_keyword("FACTS");
32179 self.write_space();
32180 self.generate_semantic_view_tuple(facts)?;
32181 }
32182 if let Some(where_) = &e.where_ {
32183 self.write_newline();
32184 self.write_indent();
32185 self.write_keyword("WHERE");
32186 self.write_space();
32187 self.generate_expression(where_)?;
32188 }
32189 self.write_newline();
32190 self.indent_level -= 1;
32191 self.write_indent();
32192 } else {
32193 self.generate_expression(&e.this)?;
32195 if let Some(metrics) = &e.metrics {
32196 self.write_space();
32197 self.write_keyword("METRICS");
32198 self.write_space();
32199 self.generate_semantic_view_tuple(metrics)?;
32200 }
32201 if let Some(dimensions) = &e.dimensions {
32202 self.write_space();
32203 self.write_keyword("DIMENSIONS");
32204 self.write_space();
32205 self.generate_semantic_view_tuple(dimensions)?;
32206 }
32207 if let Some(facts) = &e.facts {
32208 self.write_space();
32209 self.write_keyword("FACTS");
32210 self.write_space();
32211 self.generate_semantic_view_tuple(facts)?;
32212 }
32213 if let Some(where_) = &e.where_ {
32214 self.write_space();
32215 self.write_keyword("WHERE");
32216 self.write_space();
32217 self.generate_expression(where_)?;
32218 }
32219 }
32220 self.write(")");
32221 Ok(())
32222 }
32223
32224 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
32226 if let Expression::Tuple(t) = expr {
32227 for (i, e) in t.expressions.iter().enumerate() {
32228 if i > 0 {
32229 self.write(", ");
32230 }
32231 self.generate_expression(e)?;
32232 }
32233 } else {
32234 self.generate_expression(expr)?;
32235 }
32236 Ok(())
32237 }
32238
32239 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
32240 if let Some(start) = &e.start {
32242 self.write_keyword("START WITH");
32243 self.write_space();
32244 self.generate_expression(start)?;
32245 }
32246 if let Some(increment) = &e.increment {
32247 self.write_space();
32248 self.write_keyword("INCREMENT BY");
32249 self.write_space();
32250 self.generate_expression(increment)?;
32251 }
32252 if let Some(minvalue) = &e.minvalue {
32253 self.write_space();
32254 self.write_keyword("MINVALUE");
32255 self.write_space();
32256 self.generate_expression(minvalue)?;
32257 }
32258 if let Some(maxvalue) = &e.maxvalue {
32259 self.write_space();
32260 self.write_keyword("MAXVALUE");
32261 self.write_space();
32262 self.generate_expression(maxvalue)?;
32263 }
32264 if let Some(cache) = &e.cache {
32265 self.write_space();
32266 self.write_keyword("CACHE");
32267 self.write_space();
32268 self.generate_expression(cache)?;
32269 }
32270 if let Some(owned) = &e.owned {
32271 self.write_space();
32272 self.write_keyword("OWNED BY");
32273 self.write_space();
32274 self.generate_expression(owned)?;
32275 }
32276 for opt in &e.options {
32277 self.write_space();
32278 self.generate_expression(opt)?;
32279 }
32280 Ok(())
32281 }
32282
32283 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
32284 if e.with_.is_some() {
32286 self.write_keyword("WITH");
32287 self.write_space();
32288 }
32289 self.write_keyword("SERDEPROPERTIES");
32290 self.write(" (");
32291 for (i, expr) in e.expressions.iter().enumerate() {
32292 if i > 0 {
32293 self.write(", ");
32294 }
32295 match expr {
32297 Expression::Eq(eq) => {
32298 self.generate_expression(&eq.left)?;
32299 self.write("=");
32300 self.generate_expression(&eq.right)?;
32301 }
32302 _ => self.generate_expression(expr)?,
32303 }
32304 }
32305 self.write(")");
32306 Ok(())
32307 }
32308
32309 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
32310 self.write("@@");
32312 if let Some(kind) = &e.kind {
32313 self.write(kind);
32314 self.write(".");
32315 }
32316 self.generate_expression(&e.this)?;
32317 Ok(())
32318 }
32319
32320 fn generate_set(&mut self, e: &Set) -> Result<()> {
32321 if e.unset.is_some() {
32323 self.write_keyword("UNSET");
32324 } else {
32325 self.write_keyword("SET");
32326 }
32327 if e.tag.is_some() {
32328 self.write_space();
32329 self.write_keyword("TAG");
32330 }
32331 if !e.expressions.is_empty() {
32332 self.write_space();
32333 for (i, expr) in e.expressions.iter().enumerate() {
32334 if i > 0 {
32335 self.write(", ");
32336 }
32337 self.generate_expression(expr)?;
32338 }
32339 }
32340 Ok(())
32341 }
32342
32343 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
32344 self.write_keyword("SET");
32346 self.write_space();
32347 self.generate_expression(&e.this)?;
32348 Ok(())
32349 }
32350
32351 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
32352 if let Some(kind) = &e.kind {
32354 self.write_keyword(kind);
32355 self.write_space();
32356 }
32357 self.generate_expression(&e.name)?;
32358 self.write(" = ");
32359 self.generate_expression(&e.value)?;
32360 Ok(())
32361 }
32362
32363 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
32364 if let Some(with_) = &e.with_ {
32366 self.generate_expression(with_)?;
32367 self.write_space();
32368 }
32369 self.generate_expression(&e.this)?;
32370 self.write_space();
32371 if let Some(kind) = &e.kind {
32373 self.write_keyword(kind);
32374 }
32375 if e.distinct {
32376 self.write_space();
32377 self.write_keyword("DISTINCT");
32378 } else {
32379 self.write_space();
32380 self.write_keyword("ALL");
32381 }
32382 if e.by_name.is_some() {
32383 self.write_space();
32384 self.write_keyword("BY NAME");
32385 }
32386 self.write_space();
32387 self.generate_expression(&e.expression)?;
32388 Ok(())
32389 }
32390
32391 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
32392 if e.multi.is_some() {
32394 self.write_keyword("MULTISET");
32395 } else {
32396 self.write_keyword("SET");
32397 }
32398 Ok(())
32399 }
32400
32401 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
32402 self.write_keyword("SETTINGS");
32404 if self.config.pretty && e.expressions.len() > 1 {
32405 self.indent_level += 1;
32407 for (i, expr) in e.expressions.iter().enumerate() {
32408 if i > 0 {
32409 self.write(",");
32410 }
32411 self.write_newline();
32412 self.write_indent();
32413 self.generate_expression(expr)?;
32414 }
32415 self.indent_level -= 1;
32416 } else {
32417 self.write_space();
32418 for (i, expr) in e.expressions.iter().enumerate() {
32419 if i > 0 {
32420 self.write(", ");
32421 }
32422 self.generate_expression(expr)?;
32423 }
32424 }
32425 Ok(())
32426 }
32427
32428 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
32429 self.write_keyword("SHARING");
32431 if let Some(this) = &e.this {
32432 self.write(" = ");
32433 self.generate_expression(this)?;
32434 }
32435 Ok(())
32436 }
32437
32438 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
32439 if let Some(begin) = &e.this {
32441 self.generate_expression(begin)?;
32442 }
32443 self.write(":");
32444 if let Some(end) = &e.expression {
32445 self.generate_expression(end)?;
32446 }
32447 if let Some(step) = &e.step {
32448 self.write(":");
32449 self.generate_expression(step)?;
32450 }
32451 Ok(())
32452 }
32453
32454 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
32455 self.write_keyword("SORT_ARRAY");
32457 self.write("(");
32458 self.generate_expression(&e.this)?;
32459 if let Some(asc) = &e.asc {
32460 self.write(", ");
32461 self.generate_expression(asc)?;
32462 }
32463 self.write(")");
32464 Ok(())
32465 }
32466
32467 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
32468 self.write_keyword("SORT BY");
32470 self.write_space();
32471 for (i, expr) in e.expressions.iter().enumerate() {
32472 if i > 0 {
32473 self.write(", ");
32474 }
32475 self.generate_ordered(expr)?;
32476 }
32477 Ok(())
32478 }
32479
32480 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
32481 if e.compound.is_some() {
32483 self.write_keyword("COMPOUND");
32484 self.write_space();
32485 }
32486 self.write_keyword("SORTKEY");
32487 self.write("(");
32488 if let Expression::Tuple(t) = e.this.as_ref() {
32490 for (i, expr) in t.expressions.iter().enumerate() {
32491 if i > 0 {
32492 self.write(", ");
32493 }
32494 self.generate_expression(expr)?;
32495 }
32496 } else {
32497 self.generate_expression(&e.this)?;
32498 }
32499 self.write(")");
32500 Ok(())
32501 }
32502
32503 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
32504 self.write_keyword("SPLIT_PART");
32506 self.write("(");
32507 self.generate_expression(&e.this)?;
32508 if let Some(delimiter) = &e.delimiter {
32509 self.write(", ");
32510 self.generate_expression(delimiter)?;
32511 }
32512 if let Some(part_index) = &e.part_index {
32513 self.write(", ");
32514 self.generate_expression(part_index)?;
32515 }
32516 self.write(")");
32517 Ok(())
32518 }
32519
32520 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
32521 self.generate_expression(&e.this)?;
32523 Ok(())
32524 }
32525
32526 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
32527 self.write_keyword("SQL SECURITY");
32529 self.write_space();
32530 self.generate_expression(&e.this)?;
32531 Ok(())
32532 }
32533
32534 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
32535 self.write_keyword("ST_DISTANCE");
32537 self.write("(");
32538 self.generate_expression(&e.this)?;
32539 self.write(", ");
32540 self.generate_expression(&e.expression)?;
32541 if let Some(use_spheroid) = &e.use_spheroid {
32542 self.write(", ");
32543 self.generate_expression(use_spheroid)?;
32544 }
32545 self.write(")");
32546 Ok(())
32547 }
32548
32549 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
32550 self.write_keyword("ST_POINT");
32552 self.write("(");
32553 self.generate_expression(&e.this)?;
32554 self.write(", ");
32555 self.generate_expression(&e.expression)?;
32556 self.write(")");
32557 Ok(())
32558 }
32559
32560 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
32561 self.generate_expression(&e.this)?;
32563 Ok(())
32564 }
32565
32566 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
32567 self.write_keyword("STANDARD_HASH");
32569 self.write("(");
32570 self.generate_expression(&e.this)?;
32571 if let Some(expression) = &e.expression {
32572 self.write(", ");
32573 self.generate_expression(expression)?;
32574 }
32575 self.write(")");
32576 Ok(())
32577 }
32578
32579 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
32580 self.write_keyword("STORED BY");
32582 self.write_space();
32583 self.generate_expression(&e.this)?;
32584 Ok(())
32585 }
32586
32587 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
32588 use crate::dialects::DialectType;
32591 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
32592 self.write_keyword("CHARINDEX");
32594 self.write("(");
32595 if let Some(substr) = &e.substr {
32596 self.generate_expression(substr)?;
32597 self.write(", ");
32598 }
32599 self.generate_expression(&e.this)?;
32600 if let Some(position) = &e.position {
32601 self.write(", ");
32602 self.generate_expression(position)?;
32603 }
32604 self.write(")");
32605 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
32606 self.write_keyword("POSITION");
32607 self.write("(");
32608 self.generate_expression(&e.this)?;
32609 if let Some(substr) = &e.substr {
32610 self.write(", ");
32611 self.generate_expression(substr)?;
32612 }
32613 if let Some(position) = &e.position {
32614 self.write(", ");
32615 self.generate_expression(position)?;
32616 }
32617 if let Some(occurrence) = &e.occurrence {
32618 self.write(", ");
32619 self.generate_expression(occurrence)?;
32620 }
32621 self.write(")");
32622 } else if matches!(
32623 self.config.dialect,
32624 Some(DialectType::SQLite)
32625 | Some(DialectType::Oracle)
32626 | Some(DialectType::BigQuery)
32627 | Some(DialectType::Teradata)
32628 ) {
32629 self.write_keyword("INSTR");
32630 self.write("(");
32631 self.generate_expression(&e.this)?;
32632 if let Some(substr) = &e.substr {
32633 self.write(", ");
32634 self.generate_expression(substr)?;
32635 }
32636 if let Some(position) = &e.position {
32637 self.write(", ");
32638 self.generate_expression(position)?;
32639 } else if e.occurrence.is_some() {
32640 self.write(", 1");
32643 }
32644 if let Some(occurrence) = &e.occurrence {
32645 self.write(", ");
32646 self.generate_expression(occurrence)?;
32647 }
32648 self.write(")");
32649 } else if matches!(
32650 self.config.dialect,
32651 Some(DialectType::MySQL)
32652 | Some(DialectType::SingleStore)
32653 | Some(DialectType::Doris)
32654 | Some(DialectType::StarRocks)
32655 | Some(DialectType::Hive)
32656 | Some(DialectType::Spark)
32657 | Some(DialectType::Databricks)
32658 ) {
32659 self.write_keyword("LOCATE");
32661 self.write("(");
32662 if let Some(substr) = &e.substr {
32663 self.generate_expression(substr)?;
32664 self.write(", ");
32665 }
32666 self.generate_expression(&e.this)?;
32667 if let Some(position) = &e.position {
32668 self.write(", ");
32669 self.generate_expression(position)?;
32670 }
32671 self.write(")");
32672 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
32673 self.write_keyword("CHARINDEX");
32675 self.write("(");
32676 if let Some(substr) = &e.substr {
32677 self.generate_expression(substr)?;
32678 self.write(", ");
32679 }
32680 self.generate_expression(&e.this)?;
32681 if let Some(position) = &e.position {
32682 self.write(", ");
32683 self.generate_expression(position)?;
32684 }
32685 self.write(")");
32686 } else if matches!(
32687 self.config.dialect,
32688 Some(DialectType::PostgreSQL)
32689 | Some(DialectType::Materialize)
32690 | Some(DialectType::RisingWave)
32691 | Some(DialectType::Redshift)
32692 ) {
32693 self.write_keyword("POSITION");
32695 self.write("(");
32696 if let Some(substr) = &e.substr {
32697 self.generate_expression(substr)?;
32698 self.write(" IN ");
32699 }
32700 self.generate_expression(&e.this)?;
32701 self.write(")");
32702 } else {
32703 self.write_keyword("STRPOS");
32704 self.write("(");
32705 self.generate_expression(&e.this)?;
32706 if let Some(substr) = &e.substr {
32707 self.write(", ");
32708 self.generate_expression(substr)?;
32709 }
32710 if let Some(position) = &e.position {
32711 self.write(", ");
32712 self.generate_expression(position)?;
32713 }
32714 if let Some(occurrence) = &e.occurrence {
32715 self.write(", ");
32716 self.generate_expression(occurrence)?;
32717 }
32718 self.write(")");
32719 }
32720 Ok(())
32721 }
32722
32723 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
32724 match self.config.dialect {
32725 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
32726 self.write_keyword("TO_DATE");
32728 self.write("(");
32729 self.generate_expression(&e.this)?;
32730 if let Some(format) = &e.format {
32731 self.write(", '");
32732 self.write(&Self::strftime_to_java_format(format));
32733 self.write("'");
32734 }
32735 self.write(")");
32736 }
32737 Some(DialectType::DuckDB) => {
32738 self.write_keyword("CAST");
32740 self.write("(");
32741 self.write_keyword("STRPTIME");
32742 self.write("(");
32743 self.generate_expression(&e.this)?;
32744 if let Some(format) = &e.format {
32745 self.write(", '");
32746 self.write(format);
32747 self.write("'");
32748 }
32749 self.write(")");
32750 self.write_keyword(" AS ");
32751 self.write_keyword("DATE");
32752 self.write(")");
32753 }
32754 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
32755 self.write_keyword("TO_DATE");
32757 self.write("(");
32758 self.generate_expression(&e.this)?;
32759 if let Some(format) = &e.format {
32760 self.write(", '");
32761 self.write(&Self::strftime_to_postgres_format(format));
32762 self.write("'");
32763 }
32764 self.write(")");
32765 }
32766 Some(DialectType::BigQuery) => {
32767 self.write_keyword("PARSE_DATE");
32769 self.write("(");
32770 if let Some(format) = &e.format {
32771 self.write("'");
32772 self.write(format);
32773 self.write("'");
32774 self.write(", ");
32775 }
32776 self.generate_expression(&e.this)?;
32777 self.write(")");
32778 }
32779 Some(DialectType::Teradata) => {
32780 self.write_keyword("CAST");
32782 self.write("(");
32783 self.generate_expression(&e.this)?;
32784 self.write_keyword(" AS ");
32785 self.write_keyword("DATE");
32786 if let Some(format) = &e.format {
32787 self.write_keyword(" FORMAT ");
32788 self.write("'");
32789 self.write(&Self::strftime_to_teradata_format(format));
32790 self.write("'");
32791 }
32792 self.write(")");
32793 }
32794 _ => {
32795 self.write_keyword("STR_TO_DATE");
32797 self.write("(");
32798 self.generate_expression(&e.this)?;
32799 if let Some(format) = &e.format {
32800 self.write(", '");
32801 self.write(format);
32802 self.write("'");
32803 }
32804 self.write(")");
32805 }
32806 }
32807 Ok(())
32808 }
32809
32810 fn strftime_to_teradata_format(fmt: &str) -> String {
32812 let mut result = fmt.to_string();
32813 result = result.replace("%Y", "YYYY");
32814 result = result.replace("%y", "YY");
32815 result = result.replace("%m", "MM");
32816 result = result.replace("%B", "MMMM");
32817 result = result.replace("%b", "MMM");
32818 result = result.replace("%d", "DD");
32819 result = result.replace("%j", "DDD");
32820 result = result.replace("%H", "HH");
32821 result = result.replace("%M", "MI");
32822 result = result.replace("%S", "SS");
32823 result = result.replace("%f", "SSSSSS");
32824 result = result.replace("%A", "EEEE");
32825 result = result.replace("%a", "EEE");
32826 result
32827 }
32828
32829 pub fn strftime_to_java_format_static(fmt: &str) -> String {
32832 Self::strftime_to_java_format(fmt)
32833 }
32834
32835 fn strftime_to_java_format(fmt: &str) -> String {
32837 let mut result = fmt.to_string();
32838 result = result.replace("%-d", "d");
32840 result = result.replace("%-m", "M");
32841 result = result.replace("%-H", "H");
32842 result = result.replace("%-M", "m");
32843 result = result.replace("%-S", "s");
32844 result = result.replace("%Y", "yyyy");
32845 result = result.replace("%y", "yy");
32846 result = result.replace("%m", "MM");
32847 result = result.replace("%B", "MMMM");
32848 result = result.replace("%b", "MMM");
32849 result = result.replace("%d", "dd");
32850 result = result.replace("%j", "DDD");
32851 result = result.replace("%H", "HH");
32852 result = result.replace("%M", "mm");
32853 result = result.replace("%S", "ss");
32854 result = result.replace("%f", "SSSSSS");
32855 result = result.replace("%A", "EEEE");
32856 result = result.replace("%a", "EEE");
32857 result
32858 }
32859
32860 fn strftime_to_tsql_format(fmt: &str) -> String {
32863 let mut result = fmt.to_string();
32864 result = result.replace("%-d", "d");
32866 result = result.replace("%-m", "M");
32867 result = result.replace("%-H", "H");
32868 result = result.replace("%-M", "m");
32869 result = result.replace("%-S", "s");
32870 result = result.replace("%Y", "yyyy");
32871 result = result.replace("%y", "yy");
32872 result = result.replace("%m", "MM");
32873 result = result.replace("%B", "MMMM");
32874 result = result.replace("%b", "MMM");
32875 result = result.replace("%d", "dd");
32876 result = result.replace("%j", "DDD");
32877 result = result.replace("%H", "HH");
32878 result = result.replace("%M", "mm");
32879 result = result.replace("%S", "ss");
32880 result = result.replace("%f", "ffffff");
32881 result = result.replace("%A", "dddd");
32882 result = result.replace("%a", "ddd");
32883 result
32884 }
32885
32886 fn decompose_json_path(path: &str) -> Vec<String> {
32889 let mut parts = Vec::new();
32890 let path = if path.starts_with("$.") {
32892 &path[2..]
32893 } else if path.starts_with('$') {
32894 &path[1..]
32895 } else {
32896 path
32897 };
32898 if path.is_empty() {
32899 return parts;
32900 }
32901 let mut current = String::new();
32902 let chars: Vec<char> = path.chars().collect();
32903 let mut i = 0;
32904 while i < chars.len() {
32905 match chars[i] {
32906 '.' => {
32907 if !current.is_empty() {
32908 parts.push(current.clone());
32909 current.clear();
32910 }
32911 i += 1;
32912 }
32913 '[' => {
32914 if !current.is_empty() {
32915 parts.push(current.clone());
32916 current.clear();
32917 }
32918 i += 1;
32919 let mut bracket_content = String::new();
32921 while i < chars.len() && chars[i] != ']' {
32922 if chars[i] == '"' || chars[i] == '\'' {
32924 let quote = chars[i];
32925 i += 1;
32926 while i < chars.len() && chars[i] != quote {
32927 bracket_content.push(chars[i]);
32928 i += 1;
32929 }
32930 if i < chars.len() {
32931 i += 1;
32932 } } else {
32934 bracket_content.push(chars[i]);
32935 i += 1;
32936 }
32937 }
32938 if i < chars.len() {
32939 i += 1;
32940 } if bracket_content != "*" {
32943 parts.push(bracket_content);
32944 }
32945 }
32946 _ => {
32947 current.push(chars[i]);
32948 i += 1;
32949 }
32950 }
32951 }
32952 if !current.is_empty() {
32953 parts.push(current);
32954 }
32955 parts
32956 }
32957
32958 fn strftime_to_postgres_format(fmt: &str) -> String {
32960 let mut result = fmt.to_string();
32961 result = result.replace("%-d", "FMDD");
32963 result = result.replace("%-m", "FMMM");
32964 result = result.replace("%-H", "FMHH24");
32965 result = result.replace("%-M", "FMMI");
32966 result = result.replace("%-S", "FMSS");
32967 result = result.replace("%Y", "YYYY");
32968 result = result.replace("%y", "YY");
32969 result = result.replace("%m", "MM");
32970 result = result.replace("%B", "Month");
32971 result = result.replace("%b", "Mon");
32972 result = result.replace("%d", "DD");
32973 result = result.replace("%j", "DDD");
32974 result = result.replace("%H", "HH24");
32975 result = result.replace("%M", "MI");
32976 result = result.replace("%S", "SS");
32977 result = result.replace("%f", "US");
32978 result = result.replace("%A", "Day");
32979 result = result.replace("%a", "Dy");
32980 result
32981 }
32982
32983 fn strftime_to_snowflake_format(fmt: &str) -> String {
32985 let mut result = fmt.to_string();
32986 result = result.replace("%-d", "dd");
32988 result = result.replace("%-m", "mm"); result = result.replace("%Y", "yyyy");
32990 result = result.replace("%y", "yy");
32991 result = result.replace("%m", "mm");
32992 result = result.replace("%d", "DD");
32993 result = result.replace("%H", "hh24");
32994 result = result.replace("%M", "mi");
32995 result = result.replace("%S", "ss");
32996 result = result.replace("%f", "ff");
32997 result
32998 }
32999
33000 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
33001 self.write_keyword("STR_TO_MAP");
33003 self.write("(");
33004 self.generate_expression(&e.this)?;
33005 let needs_defaults = matches!(
33007 self.config.dialect,
33008 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
33009 );
33010 if let Some(pair_delim) = &e.pair_delim {
33011 self.write(", ");
33012 self.generate_expression(pair_delim)?;
33013 } else if needs_defaults {
33014 self.write(", ','");
33015 }
33016 if let Some(key_value_delim) = &e.key_value_delim {
33017 self.write(", ");
33018 self.generate_expression(key_value_delim)?;
33019 } else if needs_defaults {
33020 self.write(", ':'");
33021 }
33022 self.write(")");
33023 Ok(())
33024 }
33025
33026 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
33027 let is_strftime = e.format.contains('%');
33029 let to_strftime = |f: &str| -> String {
33031 if is_strftime {
33032 f.to_string()
33033 } else {
33034 Self::snowflake_format_to_strftime(f)
33035 }
33036 };
33037 let to_java = |f: &str| -> String {
33039 if is_strftime {
33040 Self::strftime_to_java_format(f)
33041 } else {
33042 Self::snowflake_format_to_spark(f)
33043 }
33044 };
33045 let to_pg = |f: &str| -> String {
33047 if is_strftime {
33048 Self::strftime_to_postgres_format(f)
33049 } else {
33050 Self::convert_strptime_to_postgres_format(f)
33051 }
33052 };
33053
33054 match self.config.dialect {
33055 Some(DialectType::Exasol) => {
33056 self.write_keyword("TO_DATE");
33057 self.write("(");
33058 self.generate_expression(&e.this)?;
33059 self.write(", '");
33060 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
33061 self.write("'");
33062 self.write(")");
33063 }
33064 Some(DialectType::BigQuery) => {
33065 let fmt = to_strftime(&e.format);
33067 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
33069 self.write_keyword("PARSE_TIMESTAMP");
33070 self.write("('");
33071 self.write(&fmt);
33072 self.write("', ");
33073 self.generate_expression(&e.this)?;
33074 self.write(")");
33075 }
33076 Some(DialectType::Hive) => {
33077 let java_fmt = to_java(&e.format);
33080 if java_fmt == "yyyy-MM-dd HH:mm:ss"
33081 || java_fmt == "yyyy-MM-dd"
33082 || e.format == "yyyy-MM-dd HH:mm:ss"
33083 || e.format == "yyyy-MM-dd"
33084 {
33085 self.write_keyword("CAST");
33086 self.write("(");
33087 self.generate_expression(&e.this)?;
33088 self.write(" ");
33089 self.write_keyword("AS TIMESTAMP");
33090 self.write(")");
33091 } else {
33092 self.write_keyword("CAST");
33094 self.write("(");
33095 self.write_keyword("FROM_UNIXTIME");
33096 self.write("(");
33097 self.write_keyword("UNIX_TIMESTAMP");
33098 self.write("(");
33099 self.generate_expression(&e.this)?;
33100 self.write(", '");
33101 self.write(&java_fmt);
33102 self.write("')");
33103 self.write(") ");
33104 self.write_keyword("AS TIMESTAMP");
33105 self.write(")");
33106 }
33107 }
33108 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
33109 let java_fmt = to_java(&e.format);
33111 self.write_keyword("TO_TIMESTAMP");
33112 self.write("(");
33113 self.generate_expression(&e.this)?;
33114 self.write(", '");
33115 self.write(&java_fmt);
33116 self.write("')");
33117 }
33118 Some(DialectType::MySQL) => {
33119 let mut fmt = to_strftime(&e.format);
33121 fmt = fmt.replace("%-d", "%e");
33123 fmt = fmt.replace("%-m", "%c");
33124 fmt = fmt.replace("%H:%M:%S", "%T");
33125 self.write_keyword("STR_TO_DATE");
33126 self.write("(");
33127 self.generate_expression(&e.this)?;
33128 self.write(", '");
33129 self.write(&fmt);
33130 self.write("')");
33131 }
33132 Some(DialectType::Drill) => {
33133 let java_fmt = to_java(&e.format);
33135 let java_fmt = java_fmt.replace('T', "''T''");
33137 self.write_keyword("TO_TIMESTAMP");
33138 self.write("(");
33139 self.generate_expression(&e.this)?;
33140 self.write(", '");
33141 self.write(&java_fmt);
33142 self.write("')");
33143 }
33144 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
33145 let mut fmt = to_strftime(&e.format);
33147 fmt = fmt.replace("%-d", "%e");
33149 fmt = fmt.replace("%-m", "%c");
33150 fmt = fmt.replace("%H:%M:%S", "%T");
33151 self.write_keyword("DATE_PARSE");
33152 self.write("(");
33153 self.generate_expression(&e.this)?;
33154 self.write(", '");
33155 self.write(&fmt);
33156 self.write("')");
33157 }
33158 Some(DialectType::DuckDB) => {
33159 let fmt = to_strftime(&e.format);
33161 self.write_keyword("STRPTIME");
33162 self.write("(");
33163 self.generate_expression(&e.this)?;
33164 self.write(", '");
33165 self.write(&fmt);
33166 self.write("')");
33167 }
33168 Some(DialectType::PostgreSQL)
33169 | Some(DialectType::Redshift)
33170 | Some(DialectType::Materialize) => {
33171 let pg_fmt = to_pg(&e.format);
33173 self.write_keyword("TO_TIMESTAMP");
33174 self.write("(");
33175 self.generate_expression(&e.this)?;
33176 self.write(", '");
33177 self.write(&pg_fmt);
33178 self.write("')");
33179 }
33180 Some(DialectType::Oracle) => {
33181 let pg_fmt = to_pg(&e.format);
33183 self.write_keyword("TO_TIMESTAMP");
33184 self.write("(");
33185 self.generate_expression(&e.this)?;
33186 self.write(", '");
33187 self.write(&pg_fmt);
33188 self.write("')");
33189 }
33190 Some(DialectType::Snowflake) => {
33191 self.write_keyword("TO_TIMESTAMP");
33193 self.write("(");
33194 self.generate_expression(&e.this)?;
33195 self.write(", '");
33196 self.write(&e.format);
33197 self.write("')");
33198 }
33199 _ => {
33200 self.write_keyword("STR_TO_TIME");
33202 self.write("(");
33203 self.generate_expression(&e.this)?;
33204 self.write(", '");
33205 self.write(&e.format);
33206 self.write("'");
33207 self.write(")");
33208 }
33209 }
33210 Ok(())
33211 }
33212
33213 fn snowflake_format_to_strftime(format: &str) -> String {
33215 let mut result = String::new();
33216 let chars: Vec<char> = format.chars().collect();
33217 let mut i = 0;
33218 while i < chars.len() {
33219 let remaining = &format[i..];
33220 if remaining.starts_with("yyyy") {
33221 result.push_str("%Y");
33222 i += 4;
33223 } else if remaining.starts_with("yy") {
33224 result.push_str("%y");
33225 i += 2;
33226 } else if remaining.starts_with("mmmm") {
33227 result.push_str("%B"); i += 4;
33229 } else if remaining.starts_with("mon") {
33230 result.push_str("%b"); i += 3;
33232 } else if remaining.starts_with("mm") {
33233 result.push_str("%m");
33234 i += 2;
33235 } else if remaining.starts_with("DD") {
33236 result.push_str("%d");
33237 i += 2;
33238 } else if remaining.starts_with("dy") {
33239 result.push_str("%a"); i += 2;
33241 } else if remaining.starts_with("hh24") {
33242 result.push_str("%H");
33243 i += 4;
33244 } else if remaining.starts_with("hh12") {
33245 result.push_str("%I");
33246 i += 4;
33247 } else if remaining.starts_with("hh") {
33248 result.push_str("%H");
33249 i += 2;
33250 } else if remaining.starts_with("mi") {
33251 result.push_str("%M");
33252 i += 2;
33253 } else if remaining.starts_with("ss") {
33254 result.push_str("%S");
33255 i += 2;
33256 } else if remaining.starts_with("ff") {
33257 result.push_str("%f");
33259 i += 2;
33260 while i < chars.len() && chars[i].is_ascii_digit() {
33262 i += 1;
33263 }
33264 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
33265 result.push_str("%p");
33266 i += 2;
33267 } else if remaining.starts_with("tz") {
33268 result.push_str("%Z");
33269 i += 2;
33270 } else {
33271 result.push(chars[i]);
33272 i += 1;
33273 }
33274 }
33275 result
33276 }
33277
33278 fn snowflake_format_to_spark(format: &str) -> String {
33280 let mut result = String::new();
33281 let chars: Vec<char> = format.chars().collect();
33282 let mut i = 0;
33283 while i < chars.len() {
33284 let remaining = &format[i..];
33285 if remaining.starts_with("yyyy") {
33286 result.push_str("yyyy");
33287 i += 4;
33288 } else if remaining.starts_with("yy") {
33289 result.push_str("yy");
33290 i += 2;
33291 } else if remaining.starts_with("mmmm") {
33292 result.push_str("MMMM"); i += 4;
33294 } else if remaining.starts_with("mon") {
33295 result.push_str("MMM"); i += 3;
33297 } else if remaining.starts_with("mm") {
33298 result.push_str("MM");
33299 i += 2;
33300 } else if remaining.starts_with("DD") {
33301 result.push_str("dd");
33302 i += 2;
33303 } else if remaining.starts_with("dy") {
33304 result.push_str("EEE"); i += 2;
33306 } else if remaining.starts_with("hh24") {
33307 result.push_str("HH");
33308 i += 4;
33309 } else if remaining.starts_with("hh12") {
33310 result.push_str("hh");
33311 i += 4;
33312 } else if remaining.starts_with("hh") {
33313 result.push_str("HH");
33314 i += 2;
33315 } else if remaining.starts_with("mi") {
33316 result.push_str("mm");
33317 i += 2;
33318 } else if remaining.starts_with("ss") {
33319 result.push_str("ss");
33320 i += 2;
33321 } else if remaining.starts_with("ff") {
33322 result.push_str("SSS"); i += 2;
33324 while i < chars.len() && chars[i].is_ascii_digit() {
33326 i += 1;
33327 }
33328 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
33329 result.push_str("a");
33330 i += 2;
33331 } else if remaining.starts_with("tz") {
33332 result.push_str("z");
33333 i += 2;
33334 } else {
33335 result.push(chars[i]);
33336 i += 1;
33337 }
33338 }
33339 result
33340 }
33341
33342 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
33343 match self.config.dialect {
33344 Some(DialectType::DuckDB) => {
33345 self.write_keyword("EPOCH");
33347 self.write("(");
33348 self.write_keyword("STRPTIME");
33349 self.write("(");
33350 if let Some(this) = &e.this {
33351 self.generate_expression(this)?;
33352 }
33353 if let Some(format) = &e.format {
33354 self.write(", '");
33355 self.write(format);
33356 self.write("'");
33357 }
33358 self.write("))");
33359 }
33360 Some(DialectType::Hive) => {
33361 self.write_keyword("UNIX_TIMESTAMP");
33363 self.write("(");
33364 if let Some(this) = &e.this {
33365 self.generate_expression(this)?;
33366 }
33367 if let Some(format) = &e.format {
33368 let java_fmt = Self::strftime_to_java_format(format);
33369 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
33370 self.write(", '");
33371 self.write(&java_fmt);
33372 self.write("'");
33373 }
33374 }
33375 self.write(")");
33376 }
33377 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
33378 self.write_keyword("UNIX_TIMESTAMP");
33380 self.write("(");
33381 if let Some(this) = &e.this {
33382 self.generate_expression(this)?;
33383 }
33384 if let Some(format) = &e.format {
33385 self.write(", '");
33386 self.write(format);
33387 self.write("'");
33388 }
33389 self.write(")");
33390 }
33391 Some(DialectType::Presto) | Some(DialectType::Trino) => {
33392 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
33395 let java_fmt = Self::strftime_to_java_format(c_fmt);
33396 self.write_keyword("TO_UNIXTIME");
33397 self.write("(");
33398 self.write_keyword("COALESCE");
33399 self.write("(");
33400 self.write_keyword("TRY");
33401 self.write("(");
33402 self.write_keyword("DATE_PARSE");
33403 self.write("(");
33404 self.write_keyword("CAST");
33405 self.write("(");
33406 if let Some(this) = &e.this {
33407 self.generate_expression(this)?;
33408 }
33409 self.write(" ");
33410 self.write_keyword("AS VARCHAR");
33411 self.write("), '");
33412 self.write(c_fmt);
33413 self.write("')), ");
33414 self.write_keyword("PARSE_DATETIME");
33415 self.write("(");
33416 self.write_keyword("DATE_FORMAT");
33417 self.write("(");
33418 self.write_keyword("CAST");
33419 self.write("(");
33420 if let Some(this) = &e.this {
33421 self.generate_expression(this)?;
33422 }
33423 self.write(" ");
33424 self.write_keyword("AS TIMESTAMP");
33425 self.write("), '");
33426 self.write(c_fmt);
33427 self.write("'), '");
33428 self.write(&java_fmt);
33429 self.write("')))");
33430 }
33431 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
33432 self.write_keyword("UNIX_TIMESTAMP");
33434 self.write("(");
33435 if let Some(this) = &e.this {
33436 self.generate_expression(this)?;
33437 }
33438 if let Some(format) = &e.format {
33439 let java_fmt = Self::strftime_to_java_format(format);
33440 self.write(", '");
33441 self.write(&java_fmt);
33442 self.write("'");
33443 }
33444 self.write(")");
33445 }
33446 _ => {
33447 self.write_keyword("STR_TO_UNIX");
33449 self.write("(");
33450 if let Some(this) = &e.this {
33451 self.generate_expression(this)?;
33452 }
33453 if let Some(format) = &e.format {
33454 self.write(", '");
33455 self.write(format);
33456 self.write("'");
33457 }
33458 self.write(")");
33459 }
33460 }
33461 Ok(())
33462 }
33463
33464 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
33465 self.write_keyword("STRING_TO_ARRAY");
33467 self.write("(");
33468 self.generate_expression(&e.this)?;
33469 if let Some(expression) = &e.expression {
33470 self.write(", ");
33471 self.generate_expression(expression)?;
33472 }
33473 if let Some(null_val) = &e.null {
33474 self.write(", ");
33475 self.generate_expression(null_val)?;
33476 }
33477 self.write(")");
33478 Ok(())
33479 }
33480
33481 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
33482 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33483 self.write_keyword("OBJECT_CONSTRUCT");
33485 self.write("(");
33486 for (i, (name, expr)) in e.fields.iter().enumerate() {
33487 if i > 0 {
33488 self.write(", ");
33489 }
33490 if let Some(name) = name {
33491 self.write("'");
33492 self.write(name);
33493 self.write("'");
33494 self.write(", ");
33495 } else {
33496 self.write("'_");
33497 self.write(&i.to_string());
33498 self.write("'");
33499 self.write(", ");
33500 }
33501 self.generate_expression(expr)?;
33502 }
33503 self.write(")");
33504 } else if self.config.struct_curly_brace_notation {
33505 self.write("{");
33507 for (i, (name, expr)) in e.fields.iter().enumerate() {
33508 if i > 0 {
33509 self.write(", ");
33510 }
33511 if let Some(name) = name {
33512 self.write("'");
33514 self.write(name);
33515 self.write("'");
33516 self.write(": ");
33517 } else {
33518 self.write("'_");
33520 self.write(&i.to_string());
33521 self.write("'");
33522 self.write(": ");
33523 }
33524 self.generate_expression(expr)?;
33525 }
33526 self.write("}");
33527 } else {
33528 let value_as_name = matches!(
33532 self.config.dialect,
33533 Some(DialectType::BigQuery)
33534 | Some(DialectType::Spark)
33535 | Some(DialectType::Databricks)
33536 | Some(DialectType::Hive)
33537 );
33538 self.write_keyword("STRUCT");
33539 self.write("(");
33540 for (i, (name, expr)) in e.fields.iter().enumerate() {
33541 if i > 0 {
33542 self.write(", ");
33543 }
33544 if let Some(name) = name {
33545 if value_as_name {
33546 self.generate_expression(expr)?;
33548 self.write_space();
33549 self.write_keyword("AS");
33550 self.write_space();
33551 let needs_quoting = name.contains(' ') || name.contains('-');
33553 if needs_quoting {
33554 if matches!(
33555 self.config.dialect,
33556 Some(DialectType::Spark)
33557 | Some(DialectType::Databricks)
33558 | Some(DialectType::Hive)
33559 ) {
33560 self.write("`");
33561 self.write(name);
33562 self.write("`");
33563 } else {
33564 self.write(name);
33565 }
33566 } else {
33567 self.write(name);
33568 }
33569 } else {
33570 self.write(name);
33572 self.write_space();
33573 self.write_keyword("AS");
33574 self.write_space();
33575 self.generate_expression(expr)?;
33576 }
33577 } else {
33578 self.generate_expression(expr)?;
33579 }
33580 }
33581 self.write(")");
33582 }
33583 Ok(())
33584 }
33585
33586 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
33587 self.write_keyword("STUFF");
33589 self.write("(");
33590 self.generate_expression(&e.this)?;
33591 if let Some(start) = &e.start {
33592 self.write(", ");
33593 self.generate_expression(start)?;
33594 }
33595 if let Some(length) = e.length {
33596 self.write(", ");
33597 self.write(&length.to_string());
33598 }
33599 self.write(", ");
33600 self.generate_expression(&e.expression)?;
33601 self.write(")");
33602 Ok(())
33603 }
33604
33605 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
33606 self.write_keyword("SUBSTRING_INDEX");
33608 self.write("(");
33609 self.generate_expression(&e.this)?;
33610 if let Some(delimiter) = &e.delimiter {
33611 self.write(", ");
33612 self.generate_expression(delimiter)?;
33613 }
33614 if let Some(count) = &e.count {
33615 self.write(", ");
33616 self.generate_expression(count)?;
33617 }
33618 self.write(")");
33619 Ok(())
33620 }
33621
33622 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
33623 self.write_keyword("SUMMARIZE");
33625 if e.table.is_some() {
33626 self.write_space();
33627 self.write_keyword("TABLE");
33628 }
33629 self.write_space();
33630 self.generate_expression(&e.this)?;
33631 Ok(())
33632 }
33633
33634 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
33635 self.write_keyword("SYSTIMESTAMP");
33637 Ok(())
33638 }
33639
33640 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
33641 if let Some(this) = &e.this {
33643 self.generate_expression(this)?;
33644 }
33645 if !e.columns.is_empty() {
33646 self.write("(");
33647 for (i, col) in e.columns.iter().enumerate() {
33648 if i > 0 {
33649 self.write(", ");
33650 }
33651 self.generate_expression(col)?;
33652 }
33653 self.write(")");
33654 }
33655 Ok(())
33656 }
33657
33658 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
33659 self.write_keyword("TABLE");
33661 self.write("(");
33662 self.generate_expression(&e.this)?;
33663 self.write(")");
33664 if let Some(alias) = &e.alias {
33665 self.write_space();
33666 self.write_keyword("AS");
33667 self.write_space();
33668 self.write(alias);
33669 }
33670 Ok(())
33671 }
33672
33673 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
33674 self.write_keyword("ROWS FROM");
33676 self.write(" (");
33677 for (i, expr) in e.expressions.iter().enumerate() {
33678 if i > 0 {
33679 self.write(", ");
33680 }
33681 match expr {
33685 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
33686 self.generate_expression(&tuple.expressions[0])?;
33688 self.write_space();
33689 self.write_keyword("AS");
33690 self.write_space();
33691 self.generate_expression(&tuple.expressions[1])?;
33692 }
33693 _ => {
33694 self.generate_expression(expr)?;
33695 }
33696 }
33697 }
33698 self.write(")");
33699 if e.ordinality {
33700 self.write_space();
33701 self.write_keyword("WITH ORDINALITY");
33702 }
33703 if let Some(alias) = &e.alias {
33704 self.write_space();
33705 self.write_keyword("AS");
33706 self.write_space();
33707 self.generate_expression(alias)?;
33708 }
33709 Ok(())
33710 }
33711
33712 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
33713 use crate::dialects::DialectType;
33714
33715 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
33717 if self.config.alias_post_tablesample {
33719 if let Expression::Subquery(ref s) = **this {
33721 if let Some(ref alias) = s.alias {
33722 let mut subquery_no_alias = (**s).clone();
33724 subquery_no_alias.alias = None;
33725 subquery_no_alias.column_aliases = Vec::new();
33726 self.generate_expression(&Expression::Subquery(Box::new(
33727 subquery_no_alias,
33728 )))?;
33729 self.write_space();
33730 self.write_keyword("TABLESAMPLE");
33731 self.generate_sample_body(sample)?;
33732 if let Some(ref seed) = sample.seed {
33733 self.write_space();
33734 let use_seed = sample.use_seed_keyword
33735 && !matches!(
33736 self.config.dialect,
33737 Some(crate::dialects::DialectType::Databricks)
33738 | Some(crate::dialects::DialectType::Spark)
33739 );
33740 if use_seed {
33741 self.write_keyword("SEED");
33742 } else {
33743 self.write_keyword("REPEATABLE");
33744 }
33745 self.write(" (");
33746 self.generate_expression(seed)?;
33747 self.write(")");
33748 }
33749 self.write_space();
33750 self.write_keyword("AS");
33751 self.write_space();
33752 self.generate_identifier(alias)?;
33753 return Ok(());
33754 }
33755 } else if let Expression::Alias(ref a) = **this {
33756 self.generate_expression(&a.this)?;
33758 self.write_space();
33759 self.write_keyword("TABLESAMPLE");
33760 self.generate_sample_body(sample)?;
33761 if let Some(ref seed) = sample.seed {
33762 self.write_space();
33763 let use_seed = sample.use_seed_keyword
33764 && !matches!(
33765 self.config.dialect,
33766 Some(crate::dialects::DialectType::Databricks)
33767 | Some(crate::dialects::DialectType::Spark)
33768 );
33769 if use_seed {
33770 self.write_keyword("SEED");
33771 } else {
33772 self.write_keyword("REPEATABLE");
33773 }
33774 self.write(" (");
33775 self.generate_expression(seed)?;
33776 self.write(")");
33777 }
33778 self.write_space();
33780 self.write_keyword("AS");
33781 self.write_space();
33782 self.generate_identifier(&a.alias)?;
33783 return Ok(());
33784 }
33785 }
33786 self.generate_expression(this)?;
33788 self.write_space();
33789 self.write_keyword("TABLESAMPLE");
33790 self.generate_sample_body(sample)?;
33791 if let Some(ref seed) = sample.seed {
33793 self.write_space();
33794 let use_seed = sample.use_seed_keyword
33796 && !matches!(
33797 self.config.dialect,
33798 Some(crate::dialects::DialectType::Databricks)
33799 | Some(crate::dialects::DialectType::Spark)
33800 );
33801 if use_seed {
33802 self.write_keyword("SEED");
33803 } else {
33804 self.write_keyword("REPEATABLE");
33805 }
33806 self.write(" (");
33807 self.generate_expression(seed)?;
33808 self.write(")");
33809 }
33810 return Ok(());
33811 }
33812
33813 self.write_keyword("TABLESAMPLE");
33815 if let Some(method) = &e.method {
33816 self.write_space();
33817 self.write_keyword(method);
33818 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33819 self.write_space();
33821 self.write_keyword("BERNOULLI");
33822 }
33823 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
33824 self.write_space();
33825 self.write_keyword("BUCKET");
33826 self.write_space();
33827 self.generate_expression(numerator)?;
33828 self.write_space();
33829 self.write_keyword("OUT OF");
33830 self.write_space();
33831 self.generate_expression(denominator)?;
33832 if let Some(field) = &e.bucket_field {
33833 self.write_space();
33834 self.write_keyword("ON");
33835 self.write_space();
33836 self.generate_expression(field)?;
33837 }
33838 } else if !e.expressions.is_empty() {
33839 self.write(" (");
33840 for (i, expr) in e.expressions.iter().enumerate() {
33841 if i > 0 {
33842 self.write(", ");
33843 }
33844 self.generate_expression(expr)?;
33845 }
33846 self.write(")");
33847 } else if let Some(percent) = &e.percent {
33848 self.write(" (");
33849 self.generate_expression(percent)?;
33850 self.write_space();
33851 self.write_keyword("PERCENT");
33852 self.write(")");
33853 }
33854 Ok(())
33855 }
33856
33857 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
33858 if let Some(prefix) = &e.prefix {
33860 self.generate_expression(prefix)?;
33861 }
33862 if let Some(this) = &e.this {
33863 self.generate_expression(this)?;
33864 }
33865 if let Some(postfix) = &e.postfix {
33866 self.generate_expression(postfix)?;
33867 }
33868 Ok(())
33869 }
33870
33871 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
33872 self.write_keyword("TAG");
33874 self.write(" (");
33875 for (i, expr) in e.expressions.iter().enumerate() {
33876 if i > 0 {
33877 self.write(", ");
33878 }
33879 self.generate_expression(expr)?;
33880 }
33881 self.write(")");
33882 Ok(())
33883 }
33884
33885 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
33886 if let Some(this) = &e.this {
33888 self.generate_expression(this)?;
33889 self.write_space();
33890 }
33891 self.write_keyword("TEMPORARY");
33892 Ok(())
33893 }
33894
33895 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
33898 self.write_keyword("TIME");
33900 self.write("(");
33901 self.generate_expression(&e.this)?;
33902 self.write(")");
33903 Ok(())
33904 }
33905
33906 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
33907 self.write_keyword("TIME_ADD");
33909 self.write("(");
33910 self.generate_expression(&e.this)?;
33911 self.write(", ");
33912 self.generate_expression(&e.expression)?;
33913 if let Some(unit) = &e.unit {
33914 self.write(", ");
33915 self.write_keyword(unit);
33916 }
33917 self.write(")");
33918 Ok(())
33919 }
33920
33921 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
33922 self.write_keyword("TIME_DIFF");
33924 self.write("(");
33925 self.generate_expression(&e.this)?;
33926 self.write(", ");
33927 self.generate_expression(&e.expression)?;
33928 if let Some(unit) = &e.unit {
33929 self.write(", ");
33930 self.write_keyword(unit);
33931 }
33932 self.write(")");
33933 Ok(())
33934 }
33935
33936 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
33937 self.write_keyword("TIME_FROM_PARTS");
33939 self.write("(");
33940 let mut first = true;
33941 if let Some(hour) = &e.hour {
33942 self.generate_expression(hour)?;
33943 first = false;
33944 }
33945 if let Some(minute) = &e.min {
33946 if !first {
33947 self.write(", ");
33948 }
33949 self.generate_expression(minute)?;
33950 first = false;
33951 }
33952 if let Some(second) = &e.sec {
33953 if !first {
33954 self.write(", ");
33955 }
33956 self.generate_expression(second)?;
33957 first = false;
33958 }
33959 if let Some(ns) = &e.nano {
33960 if !first {
33961 self.write(", ");
33962 }
33963 self.generate_expression(ns)?;
33964 }
33965 self.write(")");
33966 Ok(())
33967 }
33968
33969 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
33970 self.write_keyword("TIME_SLICE");
33972 self.write("(");
33973 self.generate_expression(&e.this)?;
33974 self.write(", ");
33975 self.generate_expression(&e.expression)?;
33976 self.write(", ");
33977 self.write_keyword(&e.unit);
33978 self.write(")");
33979 Ok(())
33980 }
33981
33982 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
33983 self.write_keyword("TIME_STR_TO_TIME");
33985 self.write("(");
33986 self.generate_expression(&e.this)?;
33987 self.write(")");
33988 Ok(())
33989 }
33990
33991 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
33992 self.write_keyword("TIME_SUB");
33994 self.write("(");
33995 self.generate_expression(&e.this)?;
33996 self.write(", ");
33997 self.generate_expression(&e.expression)?;
33998 if let Some(unit) = &e.unit {
33999 self.write(", ");
34000 self.write_keyword(unit);
34001 }
34002 self.write(")");
34003 Ok(())
34004 }
34005
34006 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
34007 match self.config.dialect {
34008 Some(DialectType::Exasol) => {
34009 self.write_keyword("TO_CHAR");
34011 self.write("(");
34012 self.generate_expression(&e.this)?;
34013 self.write(", '");
34014 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
34015 self.write("'");
34016 self.write(")");
34017 }
34018 Some(DialectType::PostgreSQL)
34019 | Some(DialectType::Redshift)
34020 | Some(DialectType::Materialize) => {
34021 self.write_keyword("TO_CHAR");
34023 self.write("(");
34024 self.generate_expression(&e.this)?;
34025 self.write(", '");
34026 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
34027 self.write("'");
34028 self.write(")");
34029 }
34030 Some(DialectType::Oracle) => {
34031 self.write_keyword("TO_CHAR");
34033 self.write("(");
34034 self.generate_expression(&e.this)?;
34035 self.write(", '");
34036 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
34037 self.write("'");
34038 self.write(")");
34039 }
34040 Some(DialectType::Drill) => {
34041 self.write_keyword("TO_CHAR");
34043 self.write("(");
34044 self.generate_expression(&e.this)?;
34045 self.write(", '");
34046 self.write(&Self::strftime_to_java_format(&e.format));
34047 self.write("'");
34048 self.write(")");
34049 }
34050 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
34051 self.write_keyword("FORMAT");
34053 self.write("(");
34054 self.generate_expression(&e.this)?;
34055 self.write(", '");
34056 self.write(&Self::strftime_to_tsql_format(&e.format));
34057 self.write("'");
34058 self.write(")");
34059 }
34060 Some(DialectType::DuckDB) => {
34061 self.write_keyword("STRFTIME");
34063 self.write("(");
34064 self.generate_expression(&e.this)?;
34065 self.write(", '");
34066 self.write(&e.format);
34067 self.write("'");
34068 self.write(")");
34069 }
34070 Some(DialectType::BigQuery) => {
34071 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
34074 self.write_keyword("FORMAT_DATE");
34075 self.write("('");
34076 self.write(&fmt);
34077 self.write("', ");
34078 self.generate_expression(&e.this)?;
34079 self.write(")");
34080 }
34081 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
34082 self.write_keyword("DATE_FORMAT");
34084 self.write("(");
34085 self.generate_expression(&e.this)?;
34086 self.write(", '");
34087 self.write(&Self::strftime_to_java_format(&e.format));
34088 self.write("'");
34089 self.write(")");
34090 }
34091 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
34092 self.write_keyword("DATE_FORMAT");
34094 self.write("(");
34095 self.generate_expression(&e.this)?;
34096 self.write(", '");
34097 self.write(&e.format);
34098 self.write("'");
34099 self.write(")");
34100 }
34101 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
34102 self.write_keyword("DATE_FORMAT");
34104 self.write("(");
34105 self.generate_expression(&e.this)?;
34106 self.write(", '");
34107 self.write(&e.format);
34108 self.write("'");
34109 self.write(")");
34110 }
34111 _ => {
34112 self.write_keyword("TIME_TO_STR");
34114 self.write("(");
34115 self.generate_expression(&e.this)?;
34116 self.write(", '");
34117 self.write(&e.format);
34118 self.write("'");
34119 self.write(")");
34120 }
34121 }
34122 Ok(())
34123 }
34124
34125 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
34126 match self.config.dialect {
34127 Some(DialectType::DuckDB) => {
34128 self.write_keyword("EPOCH");
34130 self.write("(");
34131 self.generate_expression(&e.this)?;
34132 self.write(")");
34133 }
34134 Some(DialectType::Hive)
34135 | Some(DialectType::Spark)
34136 | Some(DialectType::Databricks)
34137 | Some(DialectType::Doris)
34138 | Some(DialectType::StarRocks)
34139 | Some(DialectType::Drill) => {
34140 self.write_keyword("UNIX_TIMESTAMP");
34142 self.write("(");
34143 self.generate_expression(&e.this)?;
34144 self.write(")");
34145 }
34146 Some(DialectType::Presto) | Some(DialectType::Trino) => {
34147 self.write_keyword("TO_UNIXTIME");
34149 self.write("(");
34150 self.generate_expression(&e.this)?;
34151 self.write(")");
34152 }
34153 _ => {
34154 self.write_keyword("TIME_TO_UNIX");
34156 self.write("(");
34157 self.generate_expression(&e.this)?;
34158 self.write(")");
34159 }
34160 }
34161 Ok(())
34162 }
34163
34164 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
34165 match self.config.dialect {
34166 Some(DialectType::Hive) => {
34167 self.write_keyword("TO_DATE");
34169 self.write("(");
34170 self.generate_expression(&e.this)?;
34171 self.write(")");
34172 }
34173 _ => {
34174 self.write_keyword("TIME_STR_TO_DATE");
34176 self.write("(");
34177 self.generate_expression(&e.this)?;
34178 self.write(")");
34179 }
34180 }
34181 Ok(())
34182 }
34183
34184 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
34185 self.write_keyword("TIME_TRUNC");
34187 self.write("(");
34188 self.generate_expression(&e.this)?;
34189 self.write(", ");
34190 self.write_keyword(&e.unit);
34191 self.write(")");
34192 Ok(())
34193 }
34194
34195 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
34196 if let Some(unit) = &e.unit {
34198 self.write_keyword(unit);
34199 }
34200 Ok(())
34201 }
34202
34203 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
34207 use crate::dialects::DialectType;
34208 use crate::expressions::Literal;
34209
34210 match self.config.dialect {
34211 Some(DialectType::Exasol) => {
34213 self.write_keyword("TO_TIMESTAMP");
34214 self.write("(");
34215 if let Some(this) = &e.this {
34217 match this.as_ref() {
34218 Expression::Literal(Literal::String(s)) => {
34219 self.write("'");
34220 self.write(s);
34221 self.write("'");
34222 }
34223 _ => {
34224 self.generate_expression(this)?;
34225 }
34226 }
34227 }
34228 self.write(")");
34229 }
34230 _ => {
34232 self.write_keyword("TIMESTAMP");
34233 self.write("(");
34234 if let Some(this) = &e.this {
34235 self.generate_expression(this)?;
34236 }
34237 if let Some(zone) = &e.zone {
34238 self.write(", ");
34239 self.generate_expression(zone)?;
34240 }
34241 self.write(")");
34242 }
34243 }
34244 Ok(())
34245 }
34246
34247 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
34248 self.write_keyword("TIMESTAMP_ADD");
34250 self.write("(");
34251 self.generate_expression(&e.this)?;
34252 self.write(", ");
34253 self.generate_expression(&e.expression)?;
34254 if let Some(unit) = &e.unit {
34255 self.write(", ");
34256 self.write_keyword(unit);
34257 }
34258 self.write(")");
34259 Ok(())
34260 }
34261
34262 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
34263 self.write_keyword("TIMESTAMP_DIFF");
34265 self.write("(");
34266 self.generate_expression(&e.this)?;
34267 self.write(", ");
34268 self.generate_expression(&e.expression)?;
34269 if let Some(unit) = &e.unit {
34270 self.write(", ");
34271 self.write_keyword(unit);
34272 }
34273 self.write(")");
34274 Ok(())
34275 }
34276
34277 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
34278 self.write_keyword("TIMESTAMP_FROM_PARTS");
34280 self.write("(");
34281 if let Some(this) = &e.this {
34282 self.generate_expression(this)?;
34283 }
34284 if let Some(expression) = &e.expression {
34285 self.write(", ");
34286 self.generate_expression(expression)?;
34287 }
34288 if let Some(zone) = &e.zone {
34289 self.write(", ");
34290 self.generate_expression(zone)?;
34291 }
34292 if let Some(milli) = &e.milli {
34293 self.write(", ");
34294 self.generate_expression(milli)?;
34295 }
34296 self.write(")");
34297 Ok(())
34298 }
34299
34300 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
34301 self.write_keyword("TIMESTAMP_SUB");
34303 self.write("(");
34304 self.generate_expression(&e.this)?;
34305 self.write(", ");
34306 self.write_keyword("INTERVAL");
34307 self.write_space();
34308 self.generate_expression(&e.expression)?;
34309 if let Some(unit) = &e.unit {
34310 self.write_space();
34311 self.write_keyword(unit);
34312 }
34313 self.write(")");
34314 Ok(())
34315 }
34316
34317 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
34318 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
34320 self.write("(");
34321 if let Some(zone) = &e.zone {
34322 self.generate_expression(zone)?;
34323 }
34324 self.write(")");
34325 Ok(())
34326 }
34327
34328 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
34329 self.write_keyword("TO_BINARY");
34331 self.write("(");
34332 self.generate_expression(&e.this)?;
34333 if let Some(format) = &e.format {
34334 self.write(", '");
34335 self.write(format);
34336 self.write("'");
34337 }
34338 self.write(")");
34339 Ok(())
34340 }
34341
34342 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
34343 self.write_keyword("TO_BOOLEAN");
34345 self.write("(");
34346 self.generate_expression(&e.this)?;
34347 self.write(")");
34348 Ok(())
34349 }
34350
34351 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
34352 self.write_keyword("TO_CHAR");
34354 self.write("(");
34355 self.generate_expression(&e.this)?;
34356 if let Some(format) = &e.format {
34357 self.write(", '");
34358 self.write(format);
34359 self.write("'");
34360 }
34361 if let Some(nlsparam) = &e.nlsparam {
34362 self.write(", ");
34363 self.generate_expression(nlsparam)?;
34364 }
34365 self.write(")");
34366 Ok(())
34367 }
34368
34369 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
34370 self.write_keyword("TO_DECFLOAT");
34372 self.write("(");
34373 self.generate_expression(&e.this)?;
34374 if let Some(format) = &e.format {
34375 self.write(", '");
34376 self.write(format);
34377 self.write("'");
34378 }
34379 self.write(")");
34380 Ok(())
34381 }
34382
34383 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
34384 self.write_keyword("TO_DOUBLE");
34386 self.write("(");
34387 self.generate_expression(&e.this)?;
34388 if let Some(format) = &e.format {
34389 self.write(", '");
34390 self.write(format);
34391 self.write("'");
34392 }
34393 self.write(")");
34394 Ok(())
34395 }
34396
34397 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
34398 self.write_keyword("TO_FILE");
34400 self.write("(");
34401 self.generate_expression(&e.this)?;
34402 if let Some(path) = &e.path {
34403 self.write(", ");
34404 self.generate_expression(path)?;
34405 }
34406 self.write(")");
34407 Ok(())
34408 }
34409
34410 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
34411 let is_safe = e.safe.is_some();
34414 if is_safe {
34415 self.write_keyword("TRY_TO_NUMBER");
34416 } else {
34417 self.write_keyword("TO_NUMBER");
34418 }
34419 self.write("(");
34420 self.generate_expression(&e.this)?;
34421 if let Some(format) = &e.format {
34422 self.write(", ");
34423 self.generate_expression(format)?;
34424 }
34425 if let Some(nlsparam) = &e.nlsparam {
34426 self.write(", ");
34427 self.generate_expression(nlsparam)?;
34428 }
34429 if let Some(precision) = &e.precision {
34430 self.write(", ");
34431 self.generate_expression(precision)?;
34432 }
34433 if let Some(scale) = &e.scale {
34434 self.write(", ");
34435 self.generate_expression(scale)?;
34436 }
34437 self.write(")");
34438 Ok(())
34439 }
34440
34441 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
34442 self.write_keyword("TO_TABLE");
34444 self.write_space();
34445 self.generate_expression(&e.this)?;
34446 Ok(())
34447 }
34448
34449 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
34450 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
34452 Expression::Identifier(id) => id.name.clone(),
34453 Expression::Literal(Literal::String(s)) => s.clone(),
34454 _ => String::new(),
34455 });
34456
34457 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
34458 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
34459 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
34460 matches!(m.as_ref(), Expression::Literal(Literal::String(_)))
34461 });
34462
34463 let use_start_transaction = matches!(
34465 self.config.dialect,
34466 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
34467 );
34468 let strip_transaction = matches!(
34470 self.config.dialect,
34471 Some(DialectType::Snowflake)
34472 | Some(DialectType::PostgreSQL)
34473 | Some(DialectType::Redshift)
34474 | Some(DialectType::MySQL)
34475 | Some(DialectType::Hive)
34476 | Some(DialectType::Spark)
34477 | Some(DialectType::Databricks)
34478 | Some(DialectType::DuckDB)
34479 | Some(DialectType::Oracle)
34480 | Some(DialectType::Doris)
34481 | Some(DialectType::StarRocks)
34482 | Some(DialectType::Materialize)
34483 | Some(DialectType::ClickHouse)
34484 );
34485
34486 if is_start || use_start_transaction {
34487 self.write_keyword("START TRANSACTION");
34489 if let Some(modes) = &e.modes {
34490 self.write_space();
34491 self.generate_expression(modes)?;
34492 }
34493 } else {
34494 self.write_keyword("BEGIN");
34496
34497 let is_kind = e.this.as_ref().map_or(false, |t| {
34499 if let Expression::Identifier(id) = t.as_ref() {
34500 matches!(
34501 id.name.to_uppercase().as_str(),
34502 "DEFERRED" | "IMMEDIATE" | "EXCLUSIVE"
34503 )
34504 } else {
34505 false
34506 }
34507 });
34508
34509 if is_kind {
34511 if let Some(this) = &e.this {
34512 self.write_space();
34513 if let Expression::Identifier(id) = this.as_ref() {
34514 self.write_keyword(&id.name);
34515 }
34516 }
34517 }
34518
34519 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
34521 self.write_space();
34522 self.write_keyword("TRANSACTION");
34523 }
34524
34525 if !is_kind {
34527 if let Some(this) = &e.this {
34528 self.write_space();
34529 self.generate_expression(this)?;
34530 }
34531 }
34532
34533 if has_with_mark {
34535 self.write_space();
34536 self.write_keyword("WITH MARK");
34537 if let Some(Expression::Literal(Literal::String(desc))) = e.mark.as_deref() {
34538 if !desc.is_empty() {
34539 self.write_space();
34540 self.write(&format!("'{}'", desc));
34541 }
34542 }
34543 }
34544
34545 if let Some(modes) = &e.modes {
34547 self.write_space();
34548 self.generate_expression(modes)?;
34549 }
34550 }
34551 Ok(())
34552 }
34553
34554 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
34555 self.write_keyword("TRANSFORM");
34557 self.write("(");
34558 self.generate_expression(&e.this)?;
34559 self.write(", ");
34560 self.generate_expression(&e.expression)?;
34561 self.write(")");
34562 Ok(())
34563 }
34564
34565 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
34566 self.write_keyword("TRANSFORM");
34568 self.write("(");
34569 if self.config.pretty && !e.expressions.is_empty() {
34570 self.indent_level += 1;
34571 for (i, expr) in e.expressions.iter().enumerate() {
34572 if i > 0 {
34573 self.write(",");
34574 }
34575 self.write_newline();
34576 self.write_indent();
34577 self.generate_expression(expr)?;
34578 }
34579 self.indent_level -= 1;
34580 self.write_newline();
34581 self.write(")");
34582 } else {
34583 for (i, expr) in e.expressions.iter().enumerate() {
34584 if i > 0 {
34585 self.write(", ");
34586 }
34587 self.generate_expression(expr)?;
34588 }
34589 self.write(")");
34590 }
34591 Ok(())
34592 }
34593
34594 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
34595 use crate::dialects::DialectType;
34596 if let Some(this) = &e.this {
34598 self.generate_expression(this)?;
34599 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
34600 self.write_space();
34601 }
34602 }
34603 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
34604 self.write_keyword("TRANSIENT");
34605 }
34606 Ok(())
34607 }
34608
34609 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
34610 self.write_keyword("TRANSLATE");
34612 self.write("(");
34613 self.generate_expression(&e.this)?;
34614 if let Some(from) = &e.from_ {
34615 self.write(", ");
34616 self.generate_expression(from)?;
34617 }
34618 if let Some(to) = &e.to {
34619 self.write(", ");
34620 self.generate_expression(to)?;
34621 }
34622 self.write(")");
34623 Ok(())
34624 }
34625
34626 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
34627 self.write_keyword("TRANSLATE");
34629 self.write("(");
34630 self.generate_expression(&e.this)?;
34631 self.write_space();
34632 self.write_keyword("USING");
34633 self.write_space();
34634 self.generate_expression(&e.expression)?;
34635 if e.with_error.is_some() {
34636 self.write_space();
34637 self.write_keyword("WITH ERROR");
34638 }
34639 self.write(")");
34640 Ok(())
34641 }
34642
34643 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
34644 self.write_keyword("TRUNCATE TABLE");
34646 self.write_space();
34647 for (i, expr) in e.expressions.iter().enumerate() {
34648 if i > 0 {
34649 self.write(", ");
34650 }
34651 self.generate_expression(expr)?;
34652 }
34653 Ok(())
34654 }
34655
34656 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
34657 self.write_keyword("TRY_BASE64_DECODE_BINARY");
34659 self.write("(");
34660 self.generate_expression(&e.this)?;
34661 if let Some(alphabet) = &e.alphabet {
34662 self.write(", ");
34663 self.generate_expression(alphabet)?;
34664 }
34665 self.write(")");
34666 Ok(())
34667 }
34668
34669 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
34670 self.write_keyword("TRY_BASE64_DECODE_STRING");
34672 self.write("(");
34673 self.generate_expression(&e.this)?;
34674 if let Some(alphabet) = &e.alphabet {
34675 self.write(", ");
34676 self.generate_expression(alphabet)?;
34677 }
34678 self.write(")");
34679 Ok(())
34680 }
34681
34682 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
34683 self.write_keyword("TRY_TO_DECFLOAT");
34685 self.write("(");
34686 self.generate_expression(&e.this)?;
34687 if let Some(format) = &e.format {
34688 self.write(", '");
34689 self.write(format);
34690 self.write("'");
34691 }
34692 self.write(")");
34693 Ok(())
34694 }
34695
34696 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
34697 self.write_keyword("TS_OR_DS_ADD");
34699 self.write("(");
34700 self.generate_expression(&e.this)?;
34701 self.write(", ");
34702 self.generate_expression(&e.expression)?;
34703 if let Some(unit) = &e.unit {
34704 self.write(", ");
34705 self.write_keyword(unit);
34706 }
34707 if let Some(return_type) = &e.return_type {
34708 self.write(", ");
34709 self.generate_expression(return_type)?;
34710 }
34711 self.write(")");
34712 Ok(())
34713 }
34714
34715 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
34716 self.write_keyword("TS_OR_DS_DIFF");
34718 self.write("(");
34719 self.generate_expression(&e.this)?;
34720 self.write(", ");
34721 self.generate_expression(&e.expression)?;
34722 if let Some(unit) = &e.unit {
34723 self.write(", ");
34724 self.write_keyword(unit);
34725 }
34726 self.write(")");
34727 Ok(())
34728 }
34729
34730 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
34731 let default_time_format = "%Y-%m-%d %H:%M:%S";
34732 let default_date_format = "%Y-%m-%d";
34733 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
34734 f != default_time_format && f != default_date_format
34735 });
34736
34737 if has_non_default_format {
34738 let fmt = e.format.as_ref().unwrap();
34740 match self.config.dialect {
34741 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
34742 let str_to_time = crate::expressions::StrToTime {
34745 this: Box::new((*e.this).clone()),
34746 format: fmt.clone(),
34747 zone: None,
34748 safe: None,
34749 target_type: None,
34750 };
34751 self.generate_str_to_time(&str_to_time)?;
34752 }
34753 Some(DialectType::Hive)
34754 | Some(DialectType::Spark)
34755 | Some(DialectType::Databricks) => {
34756 self.write_keyword("TO_DATE");
34758 self.write("(");
34759 self.generate_expression(&e.this)?;
34760 self.write(", '");
34761 self.write(&Self::strftime_to_java_format(fmt));
34762 self.write("')");
34763 }
34764 Some(DialectType::Snowflake) => {
34765 self.write_keyword("TO_DATE");
34767 self.write("(");
34768 self.generate_expression(&e.this)?;
34769 self.write(", '");
34770 self.write(&Self::strftime_to_snowflake_format(fmt));
34771 self.write("')");
34772 }
34773 Some(DialectType::Doris) => {
34774 self.write_keyword("TO_DATE");
34776 self.write("(");
34777 self.generate_expression(&e.this)?;
34778 self.write(")");
34779 }
34780 _ => {
34781 self.write_keyword("CAST");
34783 self.write("(");
34784 let str_to_time = crate::expressions::StrToTime {
34785 this: Box::new((*e.this).clone()),
34786 format: fmt.clone(),
34787 zone: None,
34788 safe: None,
34789 target_type: None,
34790 };
34791 self.generate_str_to_time(&str_to_time)?;
34792 self.write_keyword(" AS ");
34793 self.write_keyword("DATE");
34794 self.write(")");
34795 }
34796 }
34797 } else {
34798 match self.config.dialect {
34800 Some(DialectType::MySQL)
34801 | Some(DialectType::SQLite)
34802 | Some(DialectType::StarRocks) => {
34803 self.write_keyword("DATE");
34805 self.write("(");
34806 self.generate_expression(&e.this)?;
34807 self.write(")");
34808 }
34809 Some(DialectType::Hive)
34810 | Some(DialectType::Spark)
34811 | Some(DialectType::Databricks)
34812 | Some(DialectType::Snowflake)
34813 | Some(DialectType::Doris) => {
34814 self.write_keyword("TO_DATE");
34816 self.write("(");
34817 self.generate_expression(&e.this)?;
34818 self.write(")");
34819 }
34820 Some(DialectType::Presto)
34821 | Some(DialectType::Trino)
34822 | Some(DialectType::Athena) => {
34823 self.write_keyword("CAST");
34825 self.write("(");
34826 self.write_keyword("CAST");
34827 self.write("(");
34828 self.generate_expression(&e.this)?;
34829 self.write_keyword(" AS ");
34830 self.write_keyword("TIMESTAMP");
34831 self.write(")");
34832 self.write_keyword(" AS ");
34833 self.write_keyword("DATE");
34834 self.write(")");
34835 }
34836 Some(DialectType::ClickHouse) => {
34837 self.write_keyword("CAST");
34839 self.write("(");
34840 self.generate_expression(&e.this)?;
34841 self.write_keyword(" AS ");
34842 self.write("Nullable(DATE)");
34843 self.write(")");
34844 }
34845 _ => {
34846 self.write_keyword("CAST");
34848 self.write("(");
34849 self.generate_expression(&e.this)?;
34850 self.write_keyword(" AS ");
34851 self.write_keyword("DATE");
34852 self.write(")");
34853 }
34854 }
34855 }
34856 Ok(())
34857 }
34858
34859 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
34860 self.write_keyword("TS_OR_DS_TO_TIME");
34862 self.write("(");
34863 self.generate_expression(&e.this)?;
34864 if let Some(format) = &e.format {
34865 self.write(", '");
34866 self.write(format);
34867 self.write("'");
34868 }
34869 self.write(")");
34870 Ok(())
34871 }
34872
34873 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
34874 self.write_keyword("UNHEX");
34876 self.write("(");
34877 self.generate_expression(&e.this)?;
34878 if let Some(expression) = &e.expression {
34879 self.write(", ");
34880 self.generate_expression(expression)?;
34881 }
34882 self.write(")");
34883 Ok(())
34884 }
34885
34886 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
34887 self.write("U&");
34889 self.generate_expression(&e.this)?;
34890 if let Some(escape) = &e.escape {
34891 self.write_space();
34892 self.write_keyword("UESCAPE");
34893 self.write_space();
34894 self.generate_expression(escape)?;
34895 }
34896 Ok(())
34897 }
34898
34899 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
34900 self.write_keyword("UNIFORM");
34902 self.write("(");
34903 self.generate_expression(&e.this)?;
34904 self.write(", ");
34905 self.generate_expression(&e.expression)?;
34906 if let Some(gen) = &e.gen {
34907 self.write(", ");
34908 self.generate_expression(gen)?;
34909 }
34910 if let Some(seed) = &e.seed {
34911 self.write(", ");
34912 self.generate_expression(seed)?;
34913 }
34914 self.write(")");
34915 Ok(())
34916 }
34917
34918 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
34919 self.write_keyword("UNIQUE");
34921 if e.nulls.is_some() {
34923 self.write(" NULLS NOT DISTINCT");
34924 }
34925 if let Some(this) = &e.this {
34926 self.write_space();
34927 self.generate_expression(this)?;
34928 }
34929 if let Some(index_type) = &e.index_type {
34930 self.write(" USING ");
34931 self.generate_expression(index_type)?;
34932 }
34933 if let Some(on_conflict) = &e.on_conflict {
34934 self.write_space();
34935 self.generate_expression(on_conflict)?;
34936 }
34937 for opt in &e.options {
34938 self.write_space();
34939 self.generate_expression(opt)?;
34940 }
34941 Ok(())
34942 }
34943
34944 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
34945 self.write_keyword("UNIQUE KEY");
34947 self.write(" (");
34948 for (i, expr) in e.expressions.iter().enumerate() {
34949 if i > 0 {
34950 self.write(", ");
34951 }
34952 self.generate_expression(expr)?;
34953 }
34954 self.write(")");
34955 Ok(())
34956 }
34957
34958 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
34959 self.write_keyword("ROLLUP");
34961 self.write(" (");
34962 for (i, index) in e.expressions.iter().enumerate() {
34963 if i > 0 {
34964 self.write(", ");
34965 }
34966 self.generate_identifier(&index.name)?;
34967 self.write("(");
34968 for (j, col) in index.expressions.iter().enumerate() {
34969 if j > 0 {
34970 self.write(", ");
34971 }
34972 self.generate_identifier(col)?;
34973 }
34974 self.write(")");
34975 }
34976 self.write(")");
34977 Ok(())
34978 }
34979
34980 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
34981 match self.config.dialect {
34982 Some(DialectType::DuckDB) => {
34983 self.write_keyword("STRFTIME");
34985 self.write("(");
34986 self.write_keyword("TO_TIMESTAMP");
34987 self.write("(");
34988 self.generate_expression(&e.this)?;
34989 self.write("), '");
34990 if let Some(format) = &e.format {
34991 self.write(format);
34992 }
34993 self.write("')");
34994 }
34995 Some(DialectType::Hive) => {
34996 self.write_keyword("FROM_UNIXTIME");
34998 self.write("(");
34999 self.generate_expression(&e.this)?;
35000 if let Some(format) = &e.format {
35001 if format != "yyyy-MM-dd HH:mm:ss" {
35002 self.write(", '");
35003 self.write(format);
35004 self.write("'");
35005 }
35006 }
35007 self.write(")");
35008 }
35009 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35010 self.write_keyword("DATE_FORMAT");
35012 self.write("(");
35013 self.write_keyword("FROM_UNIXTIME");
35014 self.write("(");
35015 self.generate_expression(&e.this)?;
35016 self.write("), '");
35017 if let Some(format) = &e.format {
35018 self.write(format);
35019 }
35020 self.write("')");
35021 }
35022 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35023 self.write_keyword("FROM_UNIXTIME");
35025 self.write("(");
35026 self.generate_expression(&e.this)?;
35027 if let Some(format) = &e.format {
35028 self.write(", '");
35029 self.write(format);
35030 self.write("'");
35031 }
35032 self.write(")");
35033 }
35034 _ => {
35035 self.write_keyword("UNIX_TO_STR");
35037 self.write("(");
35038 self.generate_expression(&e.this)?;
35039 if let Some(format) = &e.format {
35040 self.write(", '");
35041 self.write(format);
35042 self.write("'");
35043 }
35044 self.write(")");
35045 }
35046 }
35047 Ok(())
35048 }
35049
35050 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
35051 use crate::dialects::DialectType;
35052 let scale = e.scale.unwrap_or(0); match self.config.dialect {
35055 Some(DialectType::Snowflake) => {
35056 self.write_keyword("TO_TIMESTAMP");
35058 self.write("(");
35059 self.generate_expression(&e.this)?;
35060 if let Some(s) = e.scale {
35061 if s > 0 {
35062 self.write(", ");
35063 self.write(&s.to_string());
35064 }
35065 }
35066 self.write(")");
35067 }
35068 Some(DialectType::BigQuery) => {
35069 match scale {
35072 0 => {
35073 self.write_keyword("TIMESTAMP_SECONDS");
35074 self.write("(");
35075 self.generate_expression(&e.this)?;
35076 self.write(")");
35077 }
35078 3 => {
35079 self.write_keyword("TIMESTAMP_MILLIS");
35080 self.write("(");
35081 self.generate_expression(&e.this)?;
35082 self.write(")");
35083 }
35084 6 => {
35085 self.write_keyword("TIMESTAMP_MICROS");
35086 self.write("(");
35087 self.generate_expression(&e.this)?;
35088 self.write(")");
35089 }
35090 _ => {
35091 self.write_keyword("TIMESTAMP_SECONDS");
35093 self.write("(CAST(");
35094 self.generate_expression(&e.this)?;
35095 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
35096 }
35097 }
35098 }
35099 Some(DialectType::Spark) => {
35100 match scale {
35105 0 => {
35106 self.write_keyword("CAST");
35107 self.write("(");
35108 self.write_keyword("FROM_UNIXTIME");
35109 self.write("(");
35110 self.generate_expression(&e.this)?;
35111 self.write(") ");
35112 self.write_keyword("AS TIMESTAMP");
35113 self.write(")");
35114 }
35115 3 => {
35116 self.write_keyword("TIMESTAMP_MILLIS");
35117 self.write("(");
35118 self.generate_expression(&e.this)?;
35119 self.write(")");
35120 }
35121 6 => {
35122 self.write_keyword("TIMESTAMP_MICROS");
35123 self.write("(");
35124 self.generate_expression(&e.this)?;
35125 self.write(")");
35126 }
35127 _ => {
35128 self.write_keyword("TIMESTAMP_SECONDS");
35129 self.write("(");
35130 self.generate_expression(&e.this)?;
35131 self.write(&format!(" / POWER(10, {}))", scale));
35132 }
35133 }
35134 }
35135 Some(DialectType::Databricks) => {
35136 match scale {
35140 0 => {
35141 self.write_keyword("CAST");
35142 self.write("(");
35143 self.write_keyword("FROM_UNIXTIME");
35144 self.write("(");
35145 self.generate_expression(&e.this)?;
35146 self.write(") ");
35147 self.write_keyword("AS TIMESTAMP");
35148 self.write(")");
35149 }
35150 3 => {
35151 self.write_keyword("TIMESTAMP_MILLIS");
35152 self.write("(");
35153 self.generate_expression(&e.this)?;
35154 self.write(")");
35155 }
35156 6 => {
35157 self.write_keyword("TIMESTAMP_MICROS");
35158 self.write("(");
35159 self.generate_expression(&e.this)?;
35160 self.write(")");
35161 }
35162 _ => {
35163 self.write_keyword("TIMESTAMP_SECONDS");
35164 self.write("(");
35165 self.generate_expression(&e.this)?;
35166 self.write(&format!(" / POWER(10, {}))", scale));
35167 }
35168 }
35169 }
35170 Some(DialectType::Hive) => {
35171 if scale == 0 {
35173 self.write_keyword("FROM_UNIXTIME");
35174 self.write("(");
35175 self.generate_expression(&e.this)?;
35176 self.write(")");
35177 } else {
35178 self.write_keyword("FROM_UNIXTIME");
35179 self.write("(");
35180 self.generate_expression(&e.this)?;
35181 self.write(&format!(" / POWER(10, {})", scale));
35182 self.write(")");
35183 }
35184 }
35185 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35186 if scale == 0 {
35189 self.write_keyword("FROM_UNIXTIME");
35190 self.write("(");
35191 self.generate_expression(&e.this)?;
35192 self.write(")");
35193 } else {
35194 self.write_keyword("FROM_UNIXTIME");
35195 self.write("(CAST(");
35196 self.generate_expression(&e.this)?;
35197 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
35198 }
35199 }
35200 Some(DialectType::DuckDB) => {
35201 match scale {
35205 0 => {
35206 self.write_keyword("TO_TIMESTAMP");
35207 self.write("(");
35208 self.generate_expression(&e.this)?;
35209 self.write(")");
35210 }
35211 3 => {
35212 self.write_keyword("EPOCH_MS");
35213 self.write("(");
35214 self.generate_expression(&e.this)?;
35215 self.write(")");
35216 }
35217 6 => {
35218 self.write_keyword("MAKE_TIMESTAMP");
35219 self.write("(");
35220 self.generate_expression(&e.this)?;
35221 self.write(")");
35222 }
35223 _ => {
35224 self.write_keyword("TO_TIMESTAMP");
35225 self.write("(");
35226 self.generate_expression(&e.this)?;
35227 self.write(&format!(" / POWER(10, {}))", scale));
35228 self.write_keyword(" AT TIME ZONE");
35229 self.write(" 'UTC'");
35230 }
35231 }
35232 }
35233 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35234 self.write_keyword("FROM_UNIXTIME");
35236 self.write("(");
35237 self.generate_expression(&e.this)?;
35238 self.write(")");
35239 }
35240 Some(DialectType::Oracle) => {
35241 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
35243 self.generate_expression(&e.this)?;
35244 self.write(" / 86400)");
35245 }
35246 Some(DialectType::Redshift) => {
35247 self.write("(TIMESTAMP 'epoch' + ");
35250 if scale == 0 {
35251 self.generate_expression(&e.this)?;
35252 } else {
35253 self.write("(");
35254 self.generate_expression(&e.this)?;
35255 self.write(&format!(" / POWER(10, {}))", scale));
35256 }
35257 self.write(" * INTERVAL '1 SECOND')");
35258 }
35259 _ => {
35260 self.write_keyword("TO_TIMESTAMP");
35262 self.write("(");
35263 self.generate_expression(&e.this)?;
35264 if let Some(s) = e.scale {
35265 self.write(", ");
35266 self.write(&s.to_string());
35267 }
35268 self.write(")");
35269 }
35270 }
35271 Ok(())
35272 }
35273
35274 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
35275 if !matches!(&*e.this, Expression::Null(_)) {
35277 self.write_keyword("NAME");
35278 self.write_space();
35279 self.generate_expression(&e.this)?;
35280 }
35281 if !e.expressions.is_empty() {
35282 self.write_space();
35283 self.write_keyword("VALUE");
35284 self.write_space();
35285 for (i, expr) in e.expressions.iter().enumerate() {
35286 if i > 0 {
35287 self.write(", ");
35288 }
35289 self.generate_expression(expr)?;
35290 }
35291 }
35292 Ok(())
35293 }
35294
35295 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
35296 if e.wrapped.is_some() {
35298 self.write("(");
35299 }
35300 self.generate_expression(&e.this)?;
35301 if e.wrapped.is_some() {
35302 self.write(")");
35303 }
35304 self.write("(");
35305 for (i, expr) in e.expressions.iter().enumerate() {
35306 if i > 0 {
35307 self.write(", ");
35308 }
35309 self.generate_expression(expr)?;
35310 }
35311 self.write(")");
35312 Ok(())
35313 }
35314
35315 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
35316 self.write_keyword("USING TEMPLATE");
35318 self.write_space();
35319 self.generate_expression(&e.this)?;
35320 Ok(())
35321 }
35322
35323 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
35324 self.write_keyword("UTC_TIME");
35326 Ok(())
35327 }
35328
35329 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
35330 self.write_keyword("UTC_TIMESTAMP");
35332 Ok(())
35333 }
35334
35335 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
35336 use crate::dialects::DialectType;
35337 let func_name = match self.config.dialect {
35339 Some(DialectType::Snowflake) => "UUID_STRING",
35340 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
35341 Some(DialectType::BigQuery) => "GENERATE_UUID",
35342 _ => {
35343 if let Some(name) = &e.name {
35344 name.as_str()
35345 } else {
35346 "UUID"
35347 }
35348 }
35349 };
35350 self.write_keyword(func_name);
35351 self.write("(");
35352 if let Some(this) = &e.this {
35353 self.generate_expression(this)?;
35354 }
35355 self.write(")");
35356 Ok(())
35357 }
35358
35359 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
35360 self.write_keyword("MAP");
35362 self.write("(");
35363 let mut first = true;
35364 for (k, v) in e.keys.iter().zip(e.values.iter()) {
35365 if !first {
35366 self.write(", ");
35367 }
35368 self.generate_expression(k)?;
35369 self.write(", ");
35370 self.generate_expression(v)?;
35371 first = false;
35372 }
35373 self.write(")");
35374 Ok(())
35375 }
35376
35377 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
35378 self.write_keyword("VECTOR_SEARCH");
35380 self.write("(");
35381 self.generate_expression(&e.this)?;
35382 if let Some(col) = &e.column_to_search {
35383 self.write(", ");
35384 self.generate_expression(col)?;
35385 }
35386 if let Some(query_table) = &e.query_table {
35387 self.write(", ");
35388 self.generate_expression(query_table)?;
35389 }
35390 if let Some(query_col) = &e.query_column_to_search {
35391 self.write(", ");
35392 self.generate_expression(query_col)?;
35393 }
35394 if let Some(top_k) = &e.top_k {
35395 self.write(", ");
35396 self.generate_expression(top_k)?;
35397 }
35398 if let Some(dist_type) = &e.distance_type {
35399 self.write(", ");
35400 self.generate_expression(dist_type)?;
35401 }
35402 self.write(")");
35403 Ok(())
35404 }
35405
35406 fn generate_version(&mut self, e: &Version) -> Result<()> {
35407 use crate::dialects::DialectType;
35413 let skip_for = matches!(
35414 self.config.dialect,
35415 Some(DialectType::Hive) | Some(DialectType::Spark)
35416 );
35417 if !skip_for {
35418 self.write_keyword("FOR");
35419 self.write_space();
35420 }
35421 match e.this.as_ref() {
35423 Expression::Identifier(ident) => {
35424 self.write_keyword(&ident.name);
35425 }
35426 _ => {
35427 self.generate_expression(&e.this)?;
35428 }
35429 }
35430 self.write_space();
35431 self.write_keyword(&e.kind);
35432 if let Some(expression) = &e.expression {
35433 self.write_space();
35434 self.generate_expression(expression)?;
35435 }
35436 Ok(())
35437 }
35438
35439 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
35440 self.generate_expression(&e.this)?;
35442 Ok(())
35443 }
35444
35445 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
35446 if e.this.is_some() {
35448 self.write_keyword("NOT VOLATILE");
35449 } else {
35450 self.write_keyword("VOLATILE");
35451 }
35452 Ok(())
35453 }
35454
35455 fn generate_watermark_column_constraint(
35456 &mut self,
35457 e: &WatermarkColumnConstraint,
35458 ) -> Result<()> {
35459 self.write_keyword("WATERMARK FOR");
35461 self.write_space();
35462 self.generate_expression(&e.this)?;
35463 self.write_space();
35464 self.write_keyword("AS");
35465 self.write_space();
35466 self.generate_expression(&e.expression)?;
35467 Ok(())
35468 }
35469
35470 fn generate_week(&mut self, e: &Week) -> Result<()> {
35471 self.write_keyword("WEEK");
35473 self.write("(");
35474 self.generate_expression(&e.this)?;
35475 if let Some(mode) = &e.mode {
35476 self.write(", ");
35477 self.generate_expression(mode)?;
35478 }
35479 self.write(")");
35480 Ok(())
35481 }
35482
35483 fn generate_when(&mut self, e: &When) -> Result<()> {
35484 self.write_keyword("WHEN");
35488 self.write_space();
35489
35490 if let Some(matched) = &e.matched {
35492 match matched.as_ref() {
35494 Expression::Boolean(b) if b.value => {
35495 self.write_keyword("MATCHED");
35496 }
35497 _ => {
35498 self.write_keyword("NOT MATCHED");
35499 }
35500 }
35501 } else {
35502 self.write_keyword("NOT MATCHED");
35503 }
35504
35505 if self.config.matched_by_source {
35510 if let Some(source) = &e.source {
35511 if let Expression::Boolean(b) = source.as_ref() {
35512 if b.value {
35513 self.write_space();
35515 self.write_keyword("BY SOURCE");
35516 }
35517 } else {
35519 self.write_space();
35521 self.write_keyword("BY SOURCE");
35522 }
35523 }
35524 }
35525
35526 if let Some(condition) = &e.condition {
35528 self.write_space();
35529 self.write_keyword("AND");
35530 self.write_space();
35531 self.generate_expression(condition)?;
35532 }
35533
35534 self.write_space();
35535 self.write_keyword("THEN");
35536 self.write_space();
35537
35538 self.generate_merge_action(&e.then)?;
35541
35542 Ok(())
35543 }
35544
35545 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
35546 match action {
35547 Expression::Tuple(tuple) => {
35548 let elements = &tuple.expressions;
35549 if elements.is_empty() {
35550 return self.generate_expression(action);
35551 }
35552 match &elements[0] {
35554 Expression::Var(v) if v.this == "INSERT" => {
35555 self.write_keyword("INSERT");
35556 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
35558 self.write(" *");
35559 } else {
35560 let mut values_idx = 1;
35561 if elements.len() > 1 {
35563 if let Expression::Tuple(cols) = &elements[1] {
35564 if elements.len() > 2 {
35566 self.write(" (");
35568 for (i, col) in cols.expressions.iter().enumerate() {
35569 if i > 0 {
35570 self.write(", ");
35571 }
35572 if !self.merge_strip_qualifiers.is_empty() {
35574 let stripped = self.strip_merge_qualifier(col);
35575 self.generate_expression(&stripped)?;
35576 } else {
35577 self.generate_expression(col)?;
35578 }
35579 }
35580 self.write(")");
35581 values_idx = 2;
35582 } else {
35583 values_idx = 1;
35585 }
35586 }
35587 }
35588 if values_idx < elements.len() {
35590 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
35592 if !is_row {
35593 self.write_space();
35594 self.write_keyword("VALUES");
35595 }
35596 self.write(" ");
35597 if let Expression::Tuple(vals) = &elements[values_idx] {
35598 self.write("(");
35599 for (i, val) in vals.expressions.iter().enumerate() {
35600 if i > 0 {
35601 self.write(", ");
35602 }
35603 self.generate_expression(val)?;
35604 }
35605 self.write(")");
35606 } else {
35607 self.generate_expression(&elements[values_idx])?;
35608 }
35609 }
35610 } }
35612 Expression::Var(v) if v.this == "UPDATE" => {
35613 self.write_keyword("UPDATE");
35614 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
35616 self.write(" *");
35617 } else if elements.len() > 1 {
35618 self.write_space();
35619 self.write_keyword("SET");
35620 if self.config.pretty {
35622 self.write_newline();
35623 self.indent_level += 1;
35624 self.write_indent();
35625 } else {
35626 self.write_space();
35627 }
35628 if let Expression::Tuple(assignments) = &elements[1] {
35629 for (i, assignment) in assignments.expressions.iter().enumerate() {
35630 if i > 0 {
35631 if self.config.pretty {
35632 self.write(",");
35633 self.write_newline();
35634 self.write_indent();
35635 } else {
35636 self.write(", ");
35637 }
35638 }
35639 if !self.merge_strip_qualifiers.is_empty() {
35641 self.generate_merge_set_assignment(assignment)?;
35642 } else {
35643 self.generate_expression(assignment)?;
35644 }
35645 }
35646 } else {
35647 self.generate_expression(&elements[1])?;
35648 }
35649 if self.config.pretty {
35650 self.indent_level -= 1;
35651 }
35652 }
35653 }
35654 _ => {
35655 self.generate_expression(action)?;
35657 }
35658 }
35659 }
35660 Expression::Var(v)
35661 if v.this == "INSERT"
35662 || v.this == "UPDATE"
35663 || v.this == "DELETE"
35664 || v.this == "DO NOTHING" =>
35665 {
35666 self.write_keyword(&v.this);
35667 }
35668 _ => {
35669 self.generate_expression(action)?;
35670 }
35671 }
35672 Ok(())
35673 }
35674
35675 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
35677 match assignment {
35678 Expression::Eq(eq) => {
35679 let stripped_left = self.strip_merge_qualifier(&eq.left);
35681 self.generate_expression(&stripped_left)?;
35682 self.write(" = ");
35683 self.generate_expression(&eq.right)?;
35684 Ok(())
35685 }
35686 other => self.generate_expression(other),
35687 }
35688 }
35689
35690 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
35692 match expr {
35693 Expression::Column(col) => {
35694 if let Some(ref table_ident) = col.table {
35695 if self
35696 .merge_strip_qualifiers
35697 .iter()
35698 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
35699 {
35700 let mut col = col.clone();
35702 col.table = None;
35703 return Expression::Column(col);
35704 }
35705 }
35706 expr.clone()
35707 }
35708 Expression::Dot(dot) => {
35709 if let Expression::Identifier(id) = &dot.this {
35711 if self
35712 .merge_strip_qualifiers
35713 .iter()
35714 .any(|n| n.eq_ignore_ascii_case(&id.name))
35715 {
35716 return Expression::Identifier(dot.field.clone());
35717 }
35718 }
35719 expr.clone()
35720 }
35721 _ => expr.clone(),
35722 }
35723 }
35724
35725 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
35726 for (i, expr) in e.expressions.iter().enumerate() {
35728 if i > 0 {
35729 if self.config.pretty {
35731 self.write_newline();
35732 self.write_indent();
35733 } else {
35734 self.write_space();
35735 }
35736 }
35737 self.generate_expression(expr)?;
35738 }
35739 Ok(())
35740 }
35741
35742 fn generate_where(&mut self, e: &Where) -> Result<()> {
35743 self.write_keyword("WHERE");
35745 self.write_space();
35746 self.generate_expression(&e.this)?;
35747 Ok(())
35748 }
35749
35750 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
35751 self.write_keyword("WIDTH_BUCKET");
35753 self.write("(");
35754 self.generate_expression(&e.this)?;
35755 if let Some(min_value) = &e.min_value {
35756 self.write(", ");
35757 self.generate_expression(min_value)?;
35758 }
35759 if let Some(max_value) = &e.max_value {
35760 self.write(", ");
35761 self.generate_expression(max_value)?;
35762 }
35763 if let Some(num_buckets) = &e.num_buckets {
35764 self.write(", ");
35765 self.generate_expression(num_buckets)?;
35766 }
35767 self.write(")");
35768 Ok(())
35769 }
35770
35771 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
35772 self.generate_window_spec(e)
35774 }
35775
35776 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
35777 let mut has_content = false;
35779
35780 if !e.partition_by.is_empty() {
35782 self.write_keyword("PARTITION BY");
35783 self.write_space();
35784 for (i, expr) in e.partition_by.iter().enumerate() {
35785 if i > 0 {
35786 self.write(", ");
35787 }
35788 self.generate_expression(expr)?;
35789 }
35790 has_content = true;
35791 }
35792
35793 if !e.order_by.is_empty() {
35795 if has_content {
35796 self.write_space();
35797 }
35798 self.write_keyword("ORDER BY");
35799 self.write_space();
35800 for (i, ordered) in e.order_by.iter().enumerate() {
35801 if i > 0 {
35802 self.write(", ");
35803 }
35804 self.generate_expression(&ordered.this)?;
35805 if ordered.desc {
35806 self.write_space();
35807 self.write_keyword("DESC");
35808 } else if ordered.explicit_asc {
35809 self.write_space();
35810 self.write_keyword("ASC");
35811 }
35812 if let Some(nulls_first) = ordered.nulls_first {
35813 self.write_space();
35814 self.write_keyword("NULLS");
35815 self.write_space();
35816 if nulls_first {
35817 self.write_keyword("FIRST");
35818 } else {
35819 self.write_keyword("LAST");
35820 }
35821 }
35822 }
35823 has_content = true;
35824 }
35825
35826 if let Some(frame) = &e.frame {
35828 if has_content {
35829 self.write_space();
35830 }
35831 self.generate_window_frame(frame)?;
35832 }
35833
35834 Ok(())
35835 }
35836
35837 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
35838 self.write_keyword("WITH");
35840 self.write_space();
35841 if e.no.is_some() {
35842 self.write_keyword("NO");
35843 self.write_space();
35844 }
35845 self.write_keyword("DATA");
35846
35847 if let Some(statistics) = &e.statistics {
35849 self.write_space();
35850 self.write_keyword("AND");
35851 self.write_space();
35852 match statistics.as_ref() {
35854 Expression::Boolean(b) if !b.value => {
35855 self.write_keyword("NO");
35856 self.write_space();
35857 }
35858 _ => {}
35859 }
35860 self.write_keyword("STATISTICS");
35861 }
35862 Ok(())
35863 }
35864
35865 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
35866 self.write_keyword("WITH FILL");
35868
35869 if let Some(from_) = &e.from_ {
35870 self.write_space();
35871 self.write_keyword("FROM");
35872 self.write_space();
35873 self.generate_expression(from_)?;
35874 }
35875
35876 if let Some(to) = &e.to {
35877 self.write_space();
35878 self.write_keyword("TO");
35879 self.write_space();
35880 self.generate_expression(to)?;
35881 }
35882
35883 if let Some(step) = &e.step {
35884 self.write_space();
35885 self.write_keyword("STEP");
35886 self.write_space();
35887 self.generate_expression(step)?;
35888 }
35889
35890 if let Some(staleness) = &e.staleness {
35891 self.write_space();
35892 self.write_keyword("STALENESS");
35893 self.write_space();
35894 self.generate_expression(staleness)?;
35895 }
35896
35897 if let Some(interpolate) = &e.interpolate {
35898 self.write_space();
35899 self.write_keyword("INTERPOLATE");
35900 self.write(" (");
35901 self.generate_interpolate_item(interpolate)?;
35903 self.write(")");
35904 }
35905
35906 Ok(())
35907 }
35908
35909 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
35911 match expr {
35912 Expression::Alias(alias) => {
35913 self.generate_identifier(&alias.alias)?;
35915 self.write_space();
35916 self.write_keyword("AS");
35917 self.write_space();
35918 self.generate_expression(&alias.this)?;
35919 }
35920 Expression::Tuple(tuple) => {
35921 for (i, item) in tuple.expressions.iter().enumerate() {
35922 if i > 0 {
35923 self.write(", ");
35924 }
35925 self.generate_interpolate_item(item)?;
35926 }
35927 }
35928 other => {
35929 self.generate_expression(other)?;
35930 }
35931 }
35932 Ok(())
35933 }
35934
35935 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
35936 self.write_keyword("WITH JOURNAL TABLE");
35938 self.write("=");
35939 self.generate_expression(&e.this)?;
35940 Ok(())
35941 }
35942
35943 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
35944 self.generate_expression(&e.this)?;
35946 self.write_space();
35947 self.write_keyword("WITH");
35948 self.write_space();
35949 self.write_keyword(&e.op);
35950 Ok(())
35951 }
35952
35953 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
35954 self.write_keyword("WITH");
35956 self.write_space();
35957 for (i, expr) in e.expressions.iter().enumerate() {
35958 if i > 0 {
35959 self.write(", ");
35960 }
35961 self.generate_expression(expr)?;
35962 }
35963 Ok(())
35964 }
35965
35966 fn generate_with_schema_binding_property(
35967 &mut self,
35968 e: &WithSchemaBindingProperty,
35969 ) -> Result<()> {
35970 self.write_keyword("WITH");
35972 self.write_space();
35973 self.generate_expression(&e.this)?;
35974 Ok(())
35975 }
35976
35977 fn generate_with_system_versioning_property(
35978 &mut self,
35979 e: &WithSystemVersioningProperty,
35980 ) -> Result<()> {
35981 let mut parts = Vec::new();
35987
35988 if let Some(this) = &e.this {
35989 let mut s = String::from("HISTORY_TABLE=");
35991 let mut gen = Generator::new();
35992 gen.generate_expression(this)?;
35993 s.push_str(&gen.output);
35994 parts.push(s);
35995 }
35996
35997 if let Some(data_consistency) = &e.data_consistency {
35998 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
35999 let mut gen = Generator::new();
36000 gen.generate_expression(data_consistency)?;
36001 s.push_str(&gen.output);
36002 parts.push(s);
36003 }
36004
36005 if let Some(retention_period) = &e.retention_period {
36006 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
36007 let mut gen = Generator::new();
36008 gen.generate_expression(retention_period)?;
36009 s.push_str(&gen.output);
36010 parts.push(s);
36011 }
36012
36013 self.write_keyword("SYSTEM_VERSIONING");
36014 self.write("=");
36015
36016 if !parts.is_empty() {
36017 self.write_keyword("ON");
36018 self.write("(");
36019 self.write(&parts.join(", "));
36020 self.write(")");
36021 } else if e.on.is_some() {
36022 self.write_keyword("ON");
36023 } else {
36024 self.write_keyword("OFF");
36025 }
36026
36027 if e.with_.is_some() {
36029 let inner = self.output.clone();
36030 self.output.clear();
36031 self.write("WITH(");
36032 self.write(&inner);
36033 self.write(")");
36034 }
36035
36036 Ok(())
36037 }
36038
36039 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
36040 self.write_keyword("WITH");
36042 self.write(" (");
36043 for (i, expr) in e.expressions.iter().enumerate() {
36044 if i > 0 {
36045 self.write(", ");
36046 }
36047 self.generate_expression(expr)?;
36048 }
36049 self.write(")");
36050 Ok(())
36051 }
36052
36053 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
36054 self.write_keyword("XMLELEMENT");
36057 self.write("(");
36058
36059 if e.evalname.is_some() {
36060 self.write_keyword("EVALNAME");
36061 } else {
36062 self.write_keyword("NAME");
36063 }
36064 self.write_space();
36065 self.generate_expression(&e.this)?;
36066
36067 for expr in &e.expressions {
36068 self.write(", ");
36069 self.generate_expression(expr)?;
36070 }
36071 self.write(")");
36072 Ok(())
36073 }
36074
36075 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
36076 self.write_keyword("XMLGET");
36078 self.write("(");
36079 self.generate_expression(&e.this)?;
36080 self.write(", ");
36081 self.generate_expression(&e.expression)?;
36082 if let Some(instance) = &e.instance {
36083 self.write(", ");
36084 self.generate_expression(instance)?;
36085 }
36086 self.write(")");
36087 Ok(())
36088 }
36089
36090 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
36091 self.generate_expression(&e.this)?;
36093 if let Some(expression) = &e.expression {
36094 self.write("(");
36095 self.generate_expression(expression)?;
36096 self.write(")");
36097 }
36098 Ok(())
36099 }
36100
36101 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
36102 self.write_keyword("XMLTABLE");
36104 self.write("(");
36105
36106 if self.config.pretty {
36107 self.indent_level += 1;
36108 self.write_newline();
36109 self.write_indent();
36110 self.generate_expression(&e.this)?;
36111
36112 if let Some(passing) = &e.passing {
36113 self.write_newline();
36114 self.write_indent();
36115 self.write_keyword("PASSING");
36116 if let Expression::Tuple(tuple) = passing.as_ref() {
36117 for expr in &tuple.expressions {
36118 self.write_newline();
36119 self.indent_level += 1;
36120 self.write_indent();
36121 self.generate_expression(expr)?;
36122 self.indent_level -= 1;
36123 }
36124 } else {
36125 self.write_newline();
36126 self.indent_level += 1;
36127 self.write_indent();
36128 self.generate_expression(passing)?;
36129 self.indent_level -= 1;
36130 }
36131 }
36132
36133 if e.by_ref.is_some() {
36134 self.write_newline();
36135 self.write_indent();
36136 self.write_keyword("RETURNING SEQUENCE BY REF");
36137 }
36138
36139 if !e.columns.is_empty() {
36140 self.write_newline();
36141 self.write_indent();
36142 self.write_keyword("COLUMNS");
36143 for (i, col) in e.columns.iter().enumerate() {
36144 self.write_newline();
36145 self.indent_level += 1;
36146 self.write_indent();
36147 self.generate_expression(col)?;
36148 self.indent_level -= 1;
36149 if i < e.columns.len() - 1 {
36150 self.write(",");
36151 }
36152 }
36153 }
36154
36155 self.indent_level -= 1;
36156 self.write_newline();
36157 self.write_indent();
36158 self.write(")");
36159 return Ok(());
36160 }
36161
36162 if let Some(namespaces) = &e.namespaces {
36164 self.write_keyword("XMLNAMESPACES");
36165 self.write("(");
36166 if let Expression::Tuple(tuple) = namespaces.as_ref() {
36168 for (i, expr) in tuple.expressions.iter().enumerate() {
36169 if i > 0 {
36170 self.write(", ");
36171 }
36172 if !matches!(expr, Expression::Alias(_)) {
36175 self.write_keyword("DEFAULT");
36176 self.write_space();
36177 }
36178 self.generate_expression(expr)?;
36179 }
36180 } else {
36181 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
36183 self.write_keyword("DEFAULT");
36184 self.write_space();
36185 }
36186 self.generate_expression(namespaces)?;
36187 }
36188 self.write("), ");
36189 }
36190
36191 self.generate_expression(&e.this)?;
36193
36194 if let Some(passing) = &e.passing {
36196 self.write_space();
36197 self.write_keyword("PASSING");
36198 self.write_space();
36199 if let Expression::Tuple(tuple) = passing.as_ref() {
36201 for (i, expr) in tuple.expressions.iter().enumerate() {
36202 if i > 0 {
36203 self.write(", ");
36204 }
36205 self.generate_expression(expr)?;
36206 }
36207 } else {
36208 self.generate_expression(passing)?;
36209 }
36210 }
36211
36212 if e.by_ref.is_some() {
36214 self.write_space();
36215 self.write_keyword("RETURNING SEQUENCE BY REF");
36216 }
36217
36218 if !e.columns.is_empty() {
36220 self.write_space();
36221 self.write_keyword("COLUMNS");
36222 self.write_space();
36223 for (i, col) in e.columns.iter().enumerate() {
36224 if i > 0 {
36225 self.write(", ");
36226 }
36227 self.generate_expression(col)?;
36228 }
36229 }
36230
36231 self.write(")");
36232 Ok(())
36233 }
36234
36235 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
36236 if let Some(this) = &e.this {
36239 self.generate_expression(this)?;
36240 if let Some(expression) = &e.expression {
36241 self.write_space();
36242 self.write_keyword("XOR");
36243 self.write_space();
36244 self.generate_expression(expression)?;
36245 }
36246 }
36247
36248 for (i, expr) in e.expressions.iter().enumerate() {
36250 if i > 0 || e.this.is_some() {
36251 self.write_space();
36252 self.write_keyword("XOR");
36253 self.write_space();
36254 }
36255 self.generate_expression(expr)?;
36256 }
36257 Ok(())
36258 }
36259
36260 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
36261 self.write_keyword("ZIPF");
36263 self.write("(");
36264 self.generate_expression(&e.this)?;
36265 if let Some(elementcount) = &e.elementcount {
36266 self.write(", ");
36267 self.generate_expression(elementcount)?;
36268 }
36269 if let Some(gen) = &e.gen {
36270 self.write(", ");
36271 self.generate_expression(gen)?;
36272 }
36273 self.write(")");
36274 Ok(())
36275 }
36276}
36277
36278impl Default for Generator {
36279 fn default() -> Self {
36280 Self::new()
36281 }
36282}
36283
36284#[cfg(test)]
36285mod tests {
36286 use super::*;
36287 use crate::parser::Parser;
36288
36289 fn roundtrip(sql: &str) -> String {
36290 let ast = Parser::parse_sql(sql).unwrap();
36291 Generator::sql(&ast[0]).unwrap()
36292 }
36293
36294 #[test]
36295 fn test_simple_select() {
36296 let result = roundtrip("SELECT 1");
36297 assert_eq!(result, "SELECT 1");
36298 }
36299
36300 #[test]
36301 fn test_select_from() {
36302 let result = roundtrip("SELECT a, b FROM t");
36303 assert_eq!(result, "SELECT a, b FROM t");
36304 }
36305
36306 #[test]
36307 fn test_select_where() {
36308 let result = roundtrip("SELECT * FROM t WHERE x = 1");
36309 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
36310 }
36311
36312 #[test]
36313 fn test_select_join() {
36314 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
36315 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
36316 }
36317
36318 #[test]
36319 fn test_insert() {
36320 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
36321 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
36322 }
36323
36324 #[test]
36325 fn test_pretty_print() {
36326 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
36327 let result = Generator::pretty_sql(&ast[0]).unwrap();
36328 assert!(result.contains('\n'));
36329 }
36330
36331 #[test]
36332 fn test_window_function() {
36333 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
36334 assert_eq!(
36335 result,
36336 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
36337 );
36338 }
36339
36340 #[test]
36341 fn test_window_function_with_frame() {
36342 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
36343 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
36344 }
36345
36346 #[test]
36347 fn test_aggregate_with_filter() {
36348 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
36349 assert_eq!(
36350 result,
36351 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
36352 );
36353 }
36354
36355 #[test]
36356 fn test_subscript() {
36357 let result = roundtrip("SELECT arr[0]");
36358 assert_eq!(result, "SELECT arr[0]");
36359 }
36360
36361 #[test]
36363 fn test_create_table() {
36364 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
36365 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
36366 }
36367
36368 #[test]
36369 fn test_create_table_with_constraints() {
36370 let result = roundtrip(
36371 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
36372 );
36373 assert_eq!(
36374 result,
36375 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
36376 );
36377 }
36378
36379 #[test]
36380 fn test_create_table_if_not_exists() {
36381 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
36382 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
36383 }
36384
36385 #[test]
36386 fn test_drop_table() {
36387 let result = roundtrip("DROP TABLE users");
36388 assert_eq!(result, "DROP TABLE users");
36389 }
36390
36391 #[test]
36392 fn test_drop_table_if_exists_cascade() {
36393 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
36394 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
36395 }
36396
36397 #[test]
36398 fn test_alter_table_add_column() {
36399 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
36400 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
36401 }
36402
36403 #[test]
36404 fn test_alter_table_drop_column() {
36405 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
36406 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
36407 }
36408
36409 #[test]
36410 fn test_create_index() {
36411 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
36412 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
36413 }
36414
36415 #[test]
36416 fn test_create_unique_index() {
36417 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
36418 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
36419 }
36420
36421 #[test]
36422 fn test_drop_index() {
36423 let result = roundtrip("DROP INDEX idx_name");
36424 assert_eq!(result, "DROP INDEX idx_name");
36425 }
36426
36427 #[test]
36428 fn test_create_view() {
36429 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
36430 assert_eq!(
36431 result,
36432 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
36433 );
36434 }
36435
36436 #[test]
36437 fn test_drop_view() {
36438 let result = roundtrip("DROP VIEW active_users");
36439 assert_eq!(result, "DROP VIEW active_users");
36440 }
36441
36442 #[test]
36443 fn test_truncate() {
36444 let result = roundtrip("TRUNCATE TABLE users");
36445 assert_eq!(result, "TRUNCATE TABLE users");
36446 }
36447
36448 #[test]
36449 fn test_string_literal_escaping_default() {
36450 let result = roundtrip("SELECT 'hello'");
36452 assert_eq!(result, "SELECT 'hello'");
36453
36454 let result = roundtrip("SELECT 'it''s a test'");
36456 assert_eq!(result, "SELECT 'it''s a test'");
36457 }
36458
36459 #[test]
36460 fn test_not_in_style_prefix_default_generic() {
36461 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
36462 assert_eq!(
36463 result,
36464 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
36465 );
36466 }
36467
36468 #[test]
36469 fn test_not_in_style_infix_generic_override() {
36470 let ast =
36471 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
36472 .unwrap();
36473 let config = GeneratorConfig {
36474 not_in_style: NotInStyle::Infix,
36475 ..Default::default()
36476 };
36477 let mut gen = Generator::with_config(config);
36478 let result = gen.generate(&ast[0]).unwrap();
36479 assert_eq!(
36480 result,
36481 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
36482 );
36483 }
36484
36485 #[test]
36486 fn test_string_literal_escaping_mysql() {
36487 use crate::dialects::DialectType;
36488
36489 let config = GeneratorConfig {
36490 dialect: Some(DialectType::MySQL),
36491 ..Default::default()
36492 };
36493
36494 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36495 let mut gen = Generator::with_config(config.clone());
36496 let result = gen.generate(&ast[0]).unwrap();
36497 assert_eq!(result, "SELECT 'hello'");
36498
36499 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36501 let mut gen = Generator::with_config(config.clone());
36502 let result = gen.generate(&ast[0]).unwrap();
36503 assert_eq!(result, "SELECT 'it''s'");
36504 }
36505
36506 #[test]
36507 fn test_string_literal_escaping_postgres() {
36508 use crate::dialects::DialectType;
36509
36510 let config = GeneratorConfig {
36511 dialect: Some(DialectType::PostgreSQL),
36512 ..Default::default()
36513 };
36514
36515 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36516 let mut gen = Generator::with_config(config.clone());
36517 let result = gen.generate(&ast[0]).unwrap();
36518 assert_eq!(result, "SELECT 'hello'");
36519
36520 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36522 let mut gen = Generator::with_config(config.clone());
36523 let result = gen.generate(&ast[0]).unwrap();
36524 assert_eq!(result, "SELECT 'it''s'");
36525 }
36526
36527 #[test]
36528 fn test_string_literal_escaping_bigquery() {
36529 use crate::dialects::DialectType;
36530
36531 let config = GeneratorConfig {
36532 dialect: Some(DialectType::BigQuery),
36533 ..Default::default()
36534 };
36535
36536 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
36537 let mut gen = Generator::with_config(config.clone());
36538 let result = gen.generate(&ast[0]).unwrap();
36539 assert_eq!(result, "SELECT 'hello'");
36540
36541 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
36543 let mut gen = Generator::with_config(config.clone());
36544 let result = gen.generate(&ast[0]).unwrap();
36545 assert_eq!(result, "SELECT 'it\\'s'");
36546 }
36547}