1pub(crate) mod engine;
59pub mod plan;
60
61use crate::expressions::*;
62use crate::generator::{Generator, GeneratorConfig, NotInStyle};
63use crate::parser::Parser;
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq)]
68pub struct ClauseOptions {
69 pub append: bool,
70}
71
72impl Default for ClauseOptions {
73 fn default() -> Self {
74 Self { append: true }
75 }
76}
77
78#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
80pub struct LateralViewOptions {
81 pub outer: bool,
82}
83
84#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
86pub struct CtasOptions {
87 pub replace: bool,
88 pub temporary: bool,
89}
90
91fn generate_builder_sql(expression: &Expression) -> String {
92 let mut generator = Generator::with_config(GeneratorConfig {
93 not_in_style: NotInStyle::Infix,
94 ..Default::default()
95 });
96 generator.generate(expression).unwrap_or_default()
97}
98
99fn is_safe_identifier_name(name: &str) -> bool {
100 if name.is_empty() {
101 return false;
102 }
103
104 let mut chars = name.chars();
105 let Some(first) = chars.next() else {
106 return false;
107 };
108
109 if !(first == '_' || first.is_ascii_alphabetic()) {
110 return false;
111 }
112
113 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
114}
115
116fn builder_identifier(name: &str) -> Identifier {
117 if name == "*" || is_safe_identifier_name(name) {
118 Identifier::new(name)
119 } else {
120 Identifier::quoted(name)
121 }
122}
123
124fn builder_table_ref(name: &str) -> TableRef {
125 let parts: Vec<&str> = name.split('.').collect();
126
127 match parts.len() {
128 3 => {
129 let mut t = TableRef::new(parts[2]);
130 t.name = builder_identifier(parts[2]);
131 t.schema = Some(builder_identifier(parts[1]));
132 t.catalog = Some(builder_identifier(parts[0]));
133 t
134 }
135 2 => {
136 let mut t = TableRef::new(parts[1]);
137 t.name = builder_identifier(parts[1]);
138 t.schema = Some(builder_identifier(parts[0]));
139 t
140 }
141 _ => {
142 let first = parts.first().copied().unwrap_or("");
143 let mut t = TableRef::new(first);
144 t.name = builder_identifier(first);
145 t
146 }
147 }
148}
149
150pub fn col(name: &str) -> Expr {
174 let parts: Vec<&str> = name.split('.').collect();
175 if parts.len() >= 3 && parts.iter().all(|part| !part.is_empty()) {
176 let mut expr = Expression::boxed_column(Column {
177 name: builder_identifier(parts[1]),
178 table: Some(builder_identifier(parts[0])),
179 join_mark: false,
180 trailing_comments: Vec::new(),
181 span: None,
182 inferred_type: None,
183 });
184
185 for field in &parts[2..] {
186 expr = Expression::Dot(Box::new(DotAccess {
187 this: expr,
188 field: builder_identifier(field),
189 }));
190 }
191
192 return Expr(expr);
193 }
194
195 if let Some((table, column)) = name.rsplit_once('.') {
196 Expr(Expression::boxed_column(Column {
197 name: builder_identifier(column),
198 table: Some(builder_identifier(table)),
199 join_mark: false,
200 trailing_comments: Vec::new(),
201 span: None,
202 inferred_type: None,
203 }))
204 } else {
205 Expr(Expression::boxed_column(Column {
206 name: builder_identifier(name),
207 table: None,
208 join_mark: false,
209 trailing_comments: Vec::new(),
210 span: None,
211 inferred_type: None,
212 }))
213 }
214}
215
216pub fn lit<V: IntoLiteral>(value: V) -> Expr {
232 value.into_literal()
233}
234
235pub fn star() -> Expr {
237 Expr(Expression::star())
238}
239
240pub fn null() -> Expr {
242 Expr(Expression::Null(Null))
243}
244
245pub fn boolean(value: bool) -> Expr {
247 Expr(Expression::Boolean(BooleanLiteral { value }))
248}
249
250pub fn table(name: &str) -> Expr {
267 Expr(Expression::Table(Box::new(builder_table_ref(name))))
268}
269
270pub fn func(name: &str, args: impl IntoIterator<Item = Expr>) -> Expr {
287 Expr(Expression::Function(Box::new(Function {
288 name: name.to_string(),
289 args: args.into_iter().map(|a| a.0).collect(),
290 ..Function::default()
291 })))
292}
293
294pub fn cast(expr: Expr, to: &str) -> Expr {
310 let data_type = parse_simple_data_type(to);
311 Expr(Expression::Cast(Box::new(Cast {
312 this: expr.0,
313 to: data_type,
314 trailing_comments: Vec::new(),
315 double_colon_syntax: false,
316 format: None,
317 default: None,
318 inferred_type: None,
319 })))
320}
321
322pub fn not(expr: Expr) -> Expr {
327 Expr(Expression::Not(Box::new(UnaryOp::new(expr.0))))
328}
329
330pub fn and(left: Expr, right: Expr) -> Expr {
335 left.and(right)
336}
337
338pub fn or(left: Expr, right: Expr) -> Expr {
343 left.or(right)
344}
345
346pub fn alias(expr: Expr, name: &str) -> Expr {
351 Expr(Expression::Alias(Box::new(Alias {
352 this: expr.0,
353 alias: builder_identifier(name),
354 column_aliases: Vec::new(),
355 alias_explicit_as: false,
356 alias_keyword: None,
357 pre_alias_comments: Vec::new(),
358 trailing_comments: Vec::new(),
359 inferred_type: None,
360 })))
361}
362
363pub fn sql_expr(sql: &str) -> Expr {
387 let wrapped = format!("SELECT {}", sql);
388 let ast = Parser::parse_sql(&wrapped).expect("sql_expr: failed to parse SQL expression");
389 if let Expression::Select(s) = &ast[0] {
390 if let Some(first) = s.expressions.first() {
391 return Expr(first.clone());
392 }
393 }
394 panic!("sql_expr: failed to extract expression from parsed SQL");
395}
396
397pub fn condition(sql: &str) -> Expr {
406 sql_expr(sql)
407}
408
409pub fn count(expr: Expr) -> Expr {
417 Expr(Expression::Count(Box::new(CountFunc {
418 this: Some(expr.0),
419 star: false,
420 distinct: false,
421 filter: None,
422 ignore_nulls: None,
423 original_name: None,
424 inferred_type: None,
425 })))
426}
427
428pub fn count_star() -> Expr {
430 Expr(Expression::Count(Box::new(CountFunc {
431 this: None,
432 star: true,
433 distinct: false,
434 filter: None,
435 ignore_nulls: None,
436 original_name: None,
437 inferred_type: None,
438 })))
439}
440
441pub fn count_distinct(expr: Expr) -> Expr {
443 Expr(Expression::Count(Box::new(CountFunc {
444 this: Some(expr.0),
445 star: false,
446 distinct: true,
447 filter: None,
448 ignore_nulls: None,
449 original_name: None,
450 inferred_type: None,
451 })))
452}
453
454pub fn sum(expr: Expr) -> Expr {
456 Expr(Expression::Sum(Box::new(AggFunc {
457 this: expr.0,
458 distinct: false,
459 filter: None,
460 order_by: vec![],
461 name: None,
462 ignore_nulls: None,
463 having_max: None,
464 limit: None,
465 inferred_type: None,
466 })))
467}
468
469pub fn avg(expr: Expr) -> Expr {
471 Expr(Expression::Avg(Box::new(AggFunc {
472 this: expr.0,
473 distinct: false,
474 filter: None,
475 order_by: vec![],
476 name: None,
477 ignore_nulls: None,
478 having_max: None,
479 limit: None,
480 inferred_type: None,
481 })))
482}
483
484pub fn min_(expr: Expr) -> Expr {
486 Expr(Expression::Min(Box::new(AggFunc {
487 this: expr.0,
488 distinct: false,
489 filter: None,
490 order_by: vec![],
491 name: None,
492 ignore_nulls: None,
493 having_max: None,
494 limit: None,
495 inferred_type: None,
496 })))
497}
498
499pub fn max_(expr: Expr) -> Expr {
501 Expr(Expression::Max(Box::new(AggFunc {
502 this: expr.0,
503 distinct: false,
504 filter: None,
505 order_by: vec![],
506 name: None,
507 ignore_nulls: None,
508 having_max: None,
509 limit: None,
510 inferred_type: None,
511 })))
512}
513
514pub fn approx_distinct(expr: Expr) -> Expr {
516 Expr(Expression::ApproxDistinct(Box::new(AggFunc {
517 this: expr.0,
518 distinct: false,
519 filter: None,
520 order_by: vec![],
521 name: None,
522 ignore_nulls: None,
523 having_max: None,
524 limit: None,
525 inferred_type: None,
526 })))
527}
528
529pub fn upper(expr: Expr) -> Expr {
533 Expr(Expression::Upper(Box::new(UnaryFunc::new(expr.0))))
534}
535
536pub fn lower(expr: Expr) -> Expr {
538 Expr(Expression::Lower(Box::new(UnaryFunc::new(expr.0))))
539}
540
541pub fn length(expr: Expr) -> Expr {
543 Expr(Expression::Length(Box::new(UnaryFunc::new(expr.0))))
544}
545
546pub fn trim(expr: Expr) -> Expr {
548 Expr(Expression::Trim(Box::new(TrimFunc {
549 this: expr.0,
550 characters: None,
551 position: TrimPosition::Both,
552 sql_standard_syntax: false,
553 position_explicit: false,
554 })))
555}
556
557pub fn ltrim(expr: Expr) -> Expr {
559 Expr(Expression::LTrim(Box::new(UnaryFunc::new(expr.0))))
560}
561
562pub fn rtrim(expr: Expr) -> Expr {
564 Expr(Expression::RTrim(Box::new(UnaryFunc::new(expr.0))))
565}
566
567pub fn reverse(expr: Expr) -> Expr {
569 Expr(Expression::Reverse(Box::new(UnaryFunc::new(expr.0))))
570}
571
572pub fn initcap(expr: Expr) -> Expr {
574 Expr(Expression::Initcap(Box::new(UnaryFunc::new(expr.0))))
575}
576
577pub fn substring(expr: Expr, start: Expr, len: Option<Expr>) -> Expr {
579 Expr(Expression::Substring(Box::new(SubstringFunc {
580 this: expr.0,
581 start: start.0,
582 length: len.map(|l| l.0),
583 from_for_syntax: false,
584 })))
585}
586
587pub fn replace_(expr: Expr, old: Expr, new: Expr) -> Expr {
590 Expr(Expression::Replace(Box::new(ReplaceFunc {
591 this: expr.0,
592 old: old.0,
593 new: new.0,
594 })))
595}
596
597pub fn concat_ws(separator: Expr, exprs: impl IntoIterator<Item = Expr>) -> Expr {
599 Expr(Expression::ConcatWs(Box::new(ConcatWs {
600 separator: separator.0,
601 expressions: exprs.into_iter().map(|e| e.0).collect(),
602 })))
603}
604
605pub fn coalesce(exprs: impl IntoIterator<Item = Expr>) -> Expr {
609 Expr(Expression::Coalesce(Box::new(VarArgFunc {
610 expressions: exprs.into_iter().map(|e| e.0).collect(),
611 original_name: None,
612 inferred_type: None,
613 })))
614}
615
616pub fn null_if(expr1: Expr, expr2: Expr) -> Expr {
618 Expr(Expression::NullIf(Box::new(BinaryFunc {
619 this: expr1.0,
620 expression: expr2.0,
621 original_name: None,
622 inferred_type: None,
623 })))
624}
625
626pub fn if_null(expr: Expr, fallback: Expr) -> Expr {
628 Expr(Expression::IfNull(Box::new(BinaryFunc {
629 this: expr.0,
630 expression: fallback.0,
631 original_name: None,
632 inferred_type: None,
633 })))
634}
635
636pub fn abs(expr: Expr) -> Expr {
640 Expr(Expression::Abs(Box::new(UnaryFunc::new(expr.0))))
641}
642
643pub fn round(expr: Expr, decimals: Option<Expr>) -> Expr {
645 Expr(Expression::Round(Box::new(RoundFunc {
646 this: expr.0,
647 decimals: decimals.map(|d| d.0),
648 })))
649}
650
651pub fn floor(expr: Expr) -> Expr {
653 Expr(Expression::Floor(Box::new(FloorFunc {
654 this: expr.0,
655 scale: None,
656 to: None,
657 })))
658}
659
660pub fn ceil(expr: Expr) -> Expr {
662 Expr(Expression::Ceil(Box::new(CeilFunc {
663 this: expr.0,
664 decimals: None,
665 to: None,
666 })))
667}
668
669pub fn power(base: Expr, exponent: Expr) -> Expr {
671 Expr(Expression::Power(Box::new(BinaryFunc {
672 this: base.0,
673 expression: exponent.0,
674 original_name: None,
675 inferred_type: None,
676 })))
677}
678
679pub fn sqrt(expr: Expr) -> Expr {
681 Expr(Expression::Sqrt(Box::new(UnaryFunc::new(expr.0))))
682}
683
684pub fn ln(expr: Expr) -> Expr {
686 Expr(Expression::Ln(Box::new(UnaryFunc::new(expr.0))))
687}
688
689pub fn exp_(expr: Expr) -> Expr {
691 Expr(Expression::Exp(Box::new(UnaryFunc::new(expr.0))))
692}
693
694pub fn sign(expr: Expr) -> Expr {
696 Expr(Expression::Sign(Box::new(UnaryFunc::new(expr.0))))
697}
698
699pub fn greatest(exprs: impl IntoIterator<Item = Expr>) -> Expr {
701 Expr(Expression::Greatest(Box::new(VarArgFunc {
702 expressions: exprs.into_iter().map(|e| e.0).collect(),
703 original_name: None,
704 inferred_type: None,
705 })))
706}
707
708pub fn least(exprs: impl IntoIterator<Item = Expr>) -> Expr {
710 Expr(Expression::Least(Box::new(VarArgFunc {
711 expressions: exprs.into_iter().map(|e| e.0).collect(),
712 original_name: None,
713 inferred_type: None,
714 })))
715}
716
717pub fn current_date_() -> Expr {
721 Expr(Expression::CurrentDate(CurrentDate))
722}
723
724pub fn current_time_() -> Expr {
726 Expr(Expression::CurrentTime(CurrentTime { precision: None }))
727}
728
729pub fn current_timestamp_() -> Expr {
731 Expr(Expression::CurrentTimestamp(CurrentTimestamp {
732 precision: None,
733 sysdate: false,
734 }))
735}
736
737pub fn extract_(field: &str, expr: Expr) -> Expr {
739 Expr(Expression::Extract(Box::new(ExtractFunc {
740 this: expr.0,
741 field: parse_datetime_field(field),
742 })))
743}
744
745fn parse_datetime_field(field: &str) -> DateTimeField {
747 match field.to_uppercase().as_str() {
748 "YEAR" => DateTimeField::Year,
749 "MONTH" => DateTimeField::Month,
750 "DAY" => DateTimeField::Day,
751 "HOUR" => DateTimeField::Hour,
752 "MINUTE" => DateTimeField::Minute,
753 "SECOND" => DateTimeField::Second,
754 "MILLISECOND" => DateTimeField::Millisecond,
755 "MICROSECOND" => DateTimeField::Microsecond,
756 "DOW" | "DAYOFWEEK" => DateTimeField::DayOfWeek,
757 "DOY" | "DAYOFYEAR" => DateTimeField::DayOfYear,
758 "WEEK" => DateTimeField::Week,
759 "QUARTER" => DateTimeField::Quarter,
760 "EPOCH" => DateTimeField::Epoch,
761 "TIMEZONE" => DateTimeField::Timezone,
762 "TIMEZONE_HOUR" => DateTimeField::TimezoneHour,
763 "TIMEZONE_MINUTE" => DateTimeField::TimezoneMinute,
764 "DATE" => DateTimeField::Date,
765 "TIME" => DateTimeField::Time,
766 other => DateTimeField::Custom(other.to_string()),
767 }
768}
769
770pub fn row_number() -> Expr {
774 Expr(Expression::RowNumber(RowNumber))
775}
776
777pub fn rank_() -> Expr {
779 Expr(Expression::Rank(Rank {
780 order_by: None,
781 args: vec![],
782 }))
783}
784
785pub fn dense_rank() -> Expr {
787 Expr(Expression::DenseRank(DenseRank { args: vec![] }))
788}
789
790pub fn select<I, E>(expressions: I) -> SelectBuilder
817where
818 I: IntoIterator<Item = E>,
819 E: IntoExpr,
820{
821 SelectBuilder::new().select_cols(expressions)
822}
823
824pub fn from(table_name: &str) -> SelectBuilder {
839 SelectBuilder::new().from(table_name)
840}
841
842pub fn delete(table_name: &str) -> DeleteBuilder {
855 DeleteBuilder {
856 delete: Delete {
857 table: builder_table_ref(table_name),
858 hint: None,
859 on_cluster: None,
860 alias: None,
861 alias_explicit_as: false,
862 using: Vec::new(),
863 where_clause: None,
864 output: None,
865 leading_comments: Vec::new(),
866 with: None,
867 limit: None,
868 order_by: None,
869 returning: Vec::new(),
870 tables: Vec::new(),
871 tables_from_using: false,
872 joins: Vec::new(),
873 force_index: None,
874 no_from: false,
875 },
876 }
877}
878
879pub fn insert_into(table_name: &str) -> InsertBuilder {
896 InsertBuilder {
897 insert: Insert {
898 table: builder_table_ref(table_name),
899 columns: Vec::new(),
900 values: Vec::new(),
901 query: None,
902 overwrite: false,
903 partition: Vec::new(),
904 directory: None,
905 returning: Vec::new(),
906 output: None,
907 on_conflict: None,
908 leading_comments: Vec::new(),
909 if_exists: false,
910 with: None,
911 ignore: false,
912 source_alias: None,
913 alias: None,
914 alias_explicit_as: false,
915 default_values: false,
916 by_name: false,
917 conflict_action: None,
918 is_replace: false,
919 hint: None,
920 replace_where: None,
921 source: None,
922 function_target: None,
923 partition_by: None,
924 settings: Vec::new(),
925 },
926 }
927}
928
929pub fn update(table_name: &str) -> UpdateBuilder {
947 UpdateBuilder {
948 update: Update {
949 table: builder_table_ref(table_name),
950 hint: None,
951 extra_tables: Vec::new(),
952 table_joins: Vec::new(),
953 set: Vec::new(),
954 from_clause: None,
955 from_joins: Vec::new(),
956 where_clause: None,
957 returning: Vec::new(),
958 output: None,
959 with: None,
960 leading_comments: Vec::new(),
961 limit: None,
962 order_by: None,
963 from_before_set: false,
964 },
965 }
966}
967
968#[derive(Debug, Clone)]
993pub struct Expr(pub Expression);
994
995impl Expr {
996 pub fn into_inner(self) -> Expression {
998 self.0
999 }
1000
1001 pub fn to_sql(&self) -> String {
1005 generate_builder_sql(&self.0)
1006 }
1007
1008 pub fn eq(self, other: Expr) -> Expr {
1012 Expr(engine::binary(engine::BinaryKind::Eq, self.0, other.0))
1013 }
1014
1015 pub fn neq(self, other: Expr) -> Expr {
1017 Expr(engine::binary(engine::BinaryKind::Neq, self.0, other.0))
1018 }
1019
1020 pub fn lt(self, other: Expr) -> Expr {
1022 Expr(engine::binary(engine::BinaryKind::Lt, self.0, other.0))
1023 }
1024
1025 pub fn lte(self, other: Expr) -> Expr {
1027 Expr(engine::binary(engine::BinaryKind::Lte, self.0, other.0))
1028 }
1029
1030 pub fn gt(self, other: Expr) -> Expr {
1032 Expr(engine::binary(engine::BinaryKind::Gt, self.0, other.0))
1033 }
1034
1035 pub fn gte(self, other: Expr) -> Expr {
1037 Expr(engine::binary(engine::BinaryKind::Gte, self.0, other.0))
1038 }
1039
1040 pub fn and(self, other: Expr) -> Expr {
1044 Expr(engine::binary(engine::BinaryKind::And, self.0, other.0))
1045 }
1046
1047 pub fn or(self, other: Expr) -> Expr {
1049 Expr(engine::binary(engine::BinaryKind::Or, self.0, other.0))
1050 }
1051
1052 pub fn not(self) -> Expr {
1054 Expr(engine::unary(engine::UnaryKind::Not, self.0))
1055 }
1056
1057 pub fn xor(self, other: Expr) -> Expr {
1059 Expr(engine::binary(engine::BinaryKind::Xor, self.0, other.0))
1060 }
1061
1062 pub fn add(self, other: Expr) -> Expr {
1066 Expr(engine::binary(engine::BinaryKind::Add, self.0, other.0))
1067 }
1068
1069 pub fn sub(self, other: Expr) -> Expr {
1071 Expr(engine::binary(engine::BinaryKind::Sub, self.0, other.0))
1072 }
1073
1074 pub fn mul(self, other: Expr) -> Expr {
1076 Expr(engine::binary(engine::BinaryKind::Mul, self.0, other.0))
1077 }
1078
1079 pub fn div(self, other: Expr) -> Expr {
1081 Expr(engine::binary(engine::BinaryKind::Div, self.0, other.0))
1082 }
1083
1084 pub fn modulo(self, other: Expr) -> Expr {
1086 Expr(engine::binary(engine::BinaryKind::Mod, self.0, other.0))
1087 }
1088
1089 pub fn neg(self) -> Expr {
1091 Expr(engine::unary(engine::UnaryKind::Neg, self.0))
1092 }
1093
1094 pub fn is(self, other: Expr) -> Expr {
1096 Expr(engine::binary(engine::BinaryKind::Is, self.0, other.0))
1097 }
1098
1099 pub fn is_null(self) -> Expr {
1103 Expr(engine::unary(engine::UnaryKind::IsNull, self.0))
1104 }
1105
1106 pub fn is_not_null(self) -> Expr {
1108 Expr(engine::unary(engine::UnaryKind::IsNotNull, self.0))
1109 }
1110
1111 pub fn in_list(self, values: impl IntoIterator<Item = Expr>) -> Expr {
1115 Expr(Expression::In(Box::new(In {
1116 this: self.0,
1117 expressions: values.into_iter().map(|v| v.0).collect(),
1118 query: None,
1119 not: false,
1120 global: false,
1121 unnest: None,
1122 is_field: false,
1123 })))
1124 }
1125
1126 pub fn between(self, low: Expr, high: Expr) -> Expr {
1128 Expr(Expression::Between(Box::new(Between {
1129 this: self.0,
1130 low: low.0,
1131 high: high.0,
1132 not: false,
1133 symmetric: None,
1134 })))
1135 }
1136
1137 pub fn like(self, pattern: Expr) -> Expr {
1139 Expr(engine::binary(engine::BinaryKind::Like, self.0, pattern.0))
1140 }
1141
1142 pub fn alias(self, name: &str) -> Expr {
1144 alias(self, name)
1145 }
1146
1147 pub fn cast(self, to: &str) -> Expr {
1151 cast(self, to)
1152 }
1153
1154 pub fn asc(self) -> Expr {
1159 Expr(Expression::Ordered(Box::new(Ordered {
1160 this: self.0,
1161 desc: false,
1162 nulls_first: None,
1163 explicit_asc: true,
1164 with_fill: None,
1165 })))
1166 }
1167
1168 pub fn desc(self) -> Expr {
1172 Expr(Expression::Ordered(Box::new(Ordered {
1173 this: self.0,
1174 desc: true,
1175 nulls_first: None,
1176 explicit_asc: false,
1177 with_fill: None,
1178 })))
1179 }
1180
1181 pub fn ilike(self, pattern: Expr) -> Expr {
1186 Expr(engine::binary(engine::BinaryKind::ILike, self.0, pattern.0))
1187 }
1188
1189 pub fn rlike(self, pattern: Expr) -> Expr {
1194 Expr(engine::binary(engine::BinaryKind::RLike, self.0, pattern.0))
1195 }
1196
1197 pub fn not_in(self, values: impl IntoIterator<Item = Expr>) -> Expr {
1201 Expr(Expression::In(Box::new(In {
1202 this: self.0,
1203 expressions: values.into_iter().map(|v| v.0).collect(),
1204 query: None,
1205 not: true,
1206 global: false,
1207 unnest: None,
1208 is_field: false,
1209 })))
1210 }
1211}
1212
1213pub struct SelectBuilder {
1239 select: Select,
1240}
1241
1242impl SelectBuilder {
1243 fn new() -> Self {
1244 SelectBuilder {
1245 select: Select::new(),
1246 }
1247 }
1248
1249 fn edit(mut self, edit: impl FnOnce(&mut Expression)) -> Self {
1250 let mut expression = Expression::Select(Box::new(self.select));
1251 edit(&mut expression);
1252 self.select = match expression {
1253 Expression::Select(select) => *select,
1254 _ => unreachable!("select builder engine changed the expression kind"),
1255 };
1256 self
1257 }
1258
1259 fn join_with_kind(self, table_name: &str, on: Option<Expr>, kind: JoinKind) -> Self {
1260 let join = Join {
1261 kind,
1262 this: Expression::Table(Box::new(builder_table_ref(table_name))),
1263 on: on.map(|expression| expression.0),
1264 using: Vec::new(),
1265 use_inner_keyword: false,
1266 use_outer_keyword: false,
1267 deferred_condition: false,
1268 join_hint: None,
1269 match_condition: None,
1270 pivots: Vec::new(),
1271 comments: Vec::new(),
1272 nesting_group: 0,
1273 directed: false,
1274 };
1275 self.edit(|expression| {
1276 engine::append_join(expression, join).expect("select builder accepts JOIN clauses")
1277 })
1278 }
1279
1280 pub fn select_cols<I, E>(self, expressions: I) -> Self
1285 where
1286 I: IntoIterator<Item = E>,
1287 E: IntoExpr,
1288 {
1289 self.select_cols_with_options(expressions, ClauseOptions::default())
1290 }
1291
1292 pub fn select_cols_with_options<I, E>(self, expressions: I, options: ClauseOptions) -> Self
1294 where
1295 I: IntoIterator<Item = E>,
1296 E: IntoExpr,
1297 {
1298 let values = expressions
1299 .into_iter()
1300 .map(|expression| expression.into_expr().0)
1301 .collect();
1302 self.edit(|expression| {
1303 engine::append_select(expression, values, options.append)
1304 .expect("select builder accepts SELECT clauses")
1305 })
1306 }
1307
1308 pub fn from(self, table_name: &str) -> Self {
1310 self.edit(|expression| {
1311 engine::set_from(
1312 expression,
1313 vec![Expression::Table(Box::new(builder_table_ref(table_name)))],
1314 )
1315 .expect("select builder accepts FROM clauses")
1316 })
1317 }
1318
1319 pub fn from_expr(self, expr: Expr) -> Self {
1324 self.edit(|expression| {
1325 engine::set_from(expression, vec![expr.0]).expect("select builder accepts FROM clauses")
1326 })
1327 }
1328
1329 pub fn join(self, table_name: &str, on: Expr) -> Self {
1331 self.join_with_kind(table_name, Some(on), JoinKind::Inner)
1332 }
1333
1334 pub fn left_join(self, table_name: &str, on: Expr) -> Self {
1336 self.join_with_kind(table_name, Some(on), JoinKind::Left)
1337 }
1338
1339 pub fn where_(self, condition: Expr) -> Self {
1341 self.where_with_options(condition, ClauseOptions::default())
1342 }
1343
1344 pub fn where_with_options(self, condition: Expr, options: ClauseOptions) -> Self {
1346 self.edit(|expression| {
1347 engine::apply_where(expression, condition.0, options.append)
1348 .expect("select builder accepts WHERE clauses")
1349 })
1350 }
1351
1352 pub fn group_by<I, E>(self, expressions: I) -> Self
1354 where
1355 I: IntoIterator<Item = E>,
1356 E: IntoExpr,
1357 {
1358 self.group_by_with_options(expressions, ClauseOptions::default())
1359 }
1360
1361 pub fn group_by_with_options<I, E>(self, expressions: I, options: ClauseOptions) -> Self
1363 where
1364 I: IntoIterator<Item = E>,
1365 E: IntoExpr,
1366 {
1367 let values = expressions
1368 .into_iter()
1369 .map(|expression| expression.into_expr().0)
1370 .collect();
1371 self.edit(|expression| {
1372 engine::apply_group_by(expression, values, options.append)
1373 .expect("select builder accepts GROUP BY clauses")
1374 })
1375 }
1376
1377 pub fn having(self, condition: Expr) -> Self {
1379 self.having_with_options(condition, ClauseOptions::default())
1380 }
1381
1382 pub fn having_with_options(self, condition: Expr, options: ClauseOptions) -> Self {
1384 self.edit(|expression| {
1385 engine::apply_having(expression, condition.0, options.append)
1386 .expect("select builder accepts HAVING clauses")
1387 })
1388 }
1389
1390 pub fn order_by<I, E>(self, expressions: I) -> Self
1396 where
1397 I: IntoIterator<Item = E>,
1398 E: IntoExpr,
1399 {
1400 self.order_by_with_options(expressions, ClauseOptions::default())
1401 }
1402
1403 pub fn order_by_with_options<I, E>(self, expressions: I, options: ClauseOptions) -> Self
1405 where
1406 I: IntoIterator<Item = E>,
1407 E: IntoExpr,
1408 {
1409 let values = expressions
1410 .into_iter()
1411 .map(|expression| engine::ordered(expression.into_expr().0))
1412 .collect();
1413 self.edit(|expression| {
1414 engine::apply_order_by(expression, values, options.append)
1415 .expect("select builder accepts ORDER BY clauses")
1416 })
1417 }
1418
1419 pub fn sort_by<I, E>(self, expressions: I) -> Self
1426 where
1427 I: IntoIterator<Item = E>,
1428 E: IntoExpr,
1429 {
1430 self.sort_by_with_options(expressions, ClauseOptions::default())
1431 }
1432
1433 pub fn sort_by_with_options<I, E>(self, expressions: I, options: ClauseOptions) -> Self
1435 where
1436 I: IntoIterator<Item = E>,
1437 E: IntoExpr,
1438 {
1439 let values = expressions
1440 .into_iter()
1441 .map(|expression| engine::ordered(expression.into_expr().0))
1442 .collect();
1443 self.edit(|expression| {
1444 engine::apply_sort_by(expression, values, options.append)
1445 .expect("select builder accepts SORT BY clauses")
1446 })
1447 }
1448
1449 pub fn limit(self, count: usize) -> Self {
1451 self.edit(|expression| {
1452 engine::apply_limit(
1453 expression,
1454 Expression::Literal(Box::new(Literal::Number(count.to_string()))),
1455 )
1456 .expect("select builder accepts LIMIT clauses")
1457 })
1458 }
1459
1460 pub fn offset(self, count: usize) -> Self {
1462 self.edit(|expression| {
1463 engine::apply_offset(
1464 expression,
1465 Expression::Literal(Box::new(Literal::Number(count.to_string()))),
1466 )
1467 .expect("select builder accepts OFFSET clauses")
1468 })
1469 }
1470
1471 pub fn distinct(self) -> Self {
1473 self.edit(|expression| {
1474 engine::apply_distinct(expression, true)
1475 .expect("select builder accepts DISTINCT clauses")
1476 })
1477 }
1478
1479 pub fn qualify(self, condition: Expr) -> Self {
1484 self.qualify_with_options(condition, ClauseOptions::default())
1485 }
1486
1487 pub fn qualify_with_options(self, condition: Expr, options: ClauseOptions) -> Self {
1489 self.edit(|expression| {
1490 engine::apply_qualify(expression, condition.0, options.append)
1491 .expect("select builder accepts QUALIFY clauses")
1492 })
1493 }
1494
1495 pub fn right_join(self, table_name: &str, on: Expr) -> Self {
1497 self.join_with_kind(table_name, Some(on), JoinKind::Right)
1498 }
1499
1500 pub fn full_join(self, table_name: &str, on: Expr) -> Self {
1502 self.join_with_kind(table_name, Some(on), JoinKind::Full)
1503 }
1504
1505 pub fn cross_join(self, table_name: &str) -> Self {
1507 self.join_with_kind(table_name, None, JoinKind::Cross)
1508 }
1509
1510 pub fn lateral_view<S: AsRef<str>>(
1517 self,
1518 table_function: Expr,
1519 table_alias: &str,
1520 column_aliases: impl IntoIterator<Item = S>,
1521 ) -> Self {
1522 self.lateral_view_with_options(
1523 table_function,
1524 table_alias,
1525 column_aliases,
1526 LateralViewOptions::default(),
1527 )
1528 }
1529
1530 pub fn lateral_view_with_options<S: AsRef<str>>(
1532 self,
1533 table_function: Expr,
1534 table_alias: &str,
1535 column_aliases: impl IntoIterator<Item = S>,
1536 options: LateralViewOptions,
1537 ) -> Self {
1538 let aliases = column_aliases
1539 .into_iter()
1540 .map(|c| builder_identifier(c.as_ref()))
1541 .collect();
1542 self.edit(|expression| {
1543 engine::append_lateral_view(
1544 expression,
1545 table_function.0,
1546 Some(builder_identifier(table_alias)),
1547 aliases,
1548 options.outer,
1549 )
1550 .expect("select builder accepts LATERAL VIEW clauses")
1551 })
1552 }
1553
1554 pub fn window(self, name: &str, def: WindowDefBuilder) -> Self {
1560 let order_by = def.order_by;
1561 self.edit(|expression| {
1562 engine::append_window(
1563 expression,
1564 builder_identifier(name),
1565 def.partition_by,
1566 order_by,
1567 )
1568 .expect("select builder accepts WINDOW clauses")
1569 })
1570 }
1571
1572 pub fn for_update(self) -> Self {
1577 self.edit(|expression| {
1578 engine::append_lock(expression, engine::LockKind::Update)
1579 .expect("select builder accepts locking clauses")
1580 })
1581 }
1582
1583 pub fn for_share(self) -> Self {
1588 self.edit(|expression| {
1589 engine::append_lock(expression, engine::LockKind::Share)
1590 .expect("select builder accepts locking clauses")
1591 })
1592 }
1593
1594 pub fn hint(self, hint_text: &str) -> Self {
1599 self.edit(|expression| {
1600 engine::append_hint(expression, hint_text.to_string())
1601 .expect("select builder accepts query hints")
1602 })
1603 }
1604
1605 pub fn ctas(self, table_name: &str) -> Expression {
1621 self.ctas_with_options(table_name, CtasOptions::default())
1622 }
1623
1624 pub fn ctas_with_options(self, table_name: &str, options: CtasOptions) -> Expression {
1626 engine::create_table_as(
1627 self.build(),
1628 builder_table_ref(table_name),
1629 options.replace,
1630 options.temporary,
1631 )
1632 .expect("select builder CTAS source is a query")
1633 }
1634
1635 pub fn union(self, other: SelectBuilder) -> SetOpBuilder {
1639 SetOpBuilder::new(SetOpKind::Union, self, other, false)
1640 }
1641
1642 pub fn union_all(self, other: SelectBuilder) -> SetOpBuilder {
1646 SetOpBuilder::new(SetOpKind::Union, self, other, true)
1647 }
1648
1649 pub fn intersect(self, other: SelectBuilder) -> SetOpBuilder {
1653 SetOpBuilder::new(SetOpKind::Intersect, self, other, false)
1654 }
1655
1656 pub fn except_(self, other: SelectBuilder) -> SetOpBuilder {
1660 SetOpBuilder::new(SetOpKind::Except, self, other, false)
1661 }
1662
1663 pub fn build(self) -> Expression {
1665 Expression::Select(Box::new(self.select))
1666 }
1667
1668 pub fn to_sql(self) -> String {
1673 generate_builder_sql(&self.build())
1674 }
1675}
1676
1677pub struct DeleteBuilder {
1686 delete: Delete,
1687}
1688
1689impl DeleteBuilder {
1690 pub fn where_(self, condition: Expr) -> Self {
1692 self.where_with_options(condition, ClauseOptions::default())
1693 }
1694
1695 pub fn where_with_options(mut self, condition: Expr, options: ClauseOptions) -> Self {
1697 let mut expression = Expression::Delete(Box::new(self.delete));
1698 engine::apply_where(&mut expression, condition.0, options.append)
1699 .expect("delete builder accepts WHERE clauses");
1700 self.delete = match expression {
1701 Expression::Delete(delete) => *delete,
1702 _ => unreachable!("delete builder engine changed the expression kind"),
1703 };
1704 self
1705 }
1706
1707 pub fn build(self) -> Expression {
1709 Expression::Delete(Box::new(self.delete))
1710 }
1711
1712 pub fn to_sql(self) -> String {
1714 generate_builder_sql(&self.build())
1715 }
1716}
1717
1718pub struct InsertBuilder {
1729 insert: Insert,
1730}
1731
1732impl InsertBuilder {
1733 fn edit(mut self, edit: impl FnOnce(&mut Expression)) -> Self {
1734 let mut expression = Expression::Insert(Box::new(self.insert));
1735 edit(&mut expression);
1736 self.insert = match expression {
1737 Expression::Insert(insert) => *insert,
1738 _ => unreachable!("insert builder engine changed the expression kind"),
1739 };
1740 self
1741 }
1742
1743 pub fn columns<I, S>(self, columns: I) -> Self
1745 where
1746 I: IntoIterator<Item = S>,
1747 S: AsRef<str>,
1748 {
1749 let columns = columns
1750 .into_iter()
1751 .map(|c| builder_identifier(c.as_ref()))
1752 .collect();
1753 self.edit(|expression| {
1754 engine::set_insert_columns(expression, columns)
1755 .expect("insert builder accepts target columns")
1756 })
1757 }
1758
1759 pub fn values<I>(self, values: I) -> Self
1763 where
1764 I: IntoIterator<Item = Expr>,
1765 {
1766 let row = values.into_iter().map(|v| v.0).collect();
1767 self.edit(|expression| {
1768 engine::apply_insert_values(expression, vec![row], true)
1769 .expect("insert builder accepts VALUES clauses")
1770 })
1771 }
1772
1773 pub fn query(self, query: SelectBuilder) -> Self {
1777 self.edit(|expression| {
1778 engine::set_insert_query(expression, query.build())
1779 .expect("insert builder accepts query sources")
1780 })
1781 }
1782
1783 pub fn build(self) -> Expression {
1785 Expression::Insert(Box::new(self.insert))
1786 }
1787
1788 pub fn to_sql(self) -> String {
1790 generate_builder_sql(&self.build())
1791 }
1792}
1793
1794pub struct UpdateBuilder {
1804 update: Update,
1805}
1806
1807impl UpdateBuilder {
1808 fn edit(mut self, edit: impl FnOnce(&mut Expression)) -> Self {
1809 let mut expression = Expression::Update(Box::new(self.update));
1810 edit(&mut expression);
1811 self.update = match expression {
1812 Expression::Update(update) => *update,
1813 _ => unreachable!("update builder engine changed the expression kind"),
1814 };
1815 self
1816 }
1817
1818 pub fn set(self, column: &str, value: Expr) -> Self {
1822 self.edit(|expression| {
1823 engine::append_update_assignments(
1824 expression,
1825 vec![(builder_identifier(column), value.0)],
1826 )
1827 .expect("update builder accepts SET assignments")
1828 })
1829 }
1830
1831 pub fn where_(self, condition: Expr) -> Self {
1833 self.where_with_options(condition, ClauseOptions::default())
1834 }
1835
1836 pub fn where_with_options(mut self, condition: Expr, options: ClauseOptions) -> Self {
1838 let mut expression = Expression::Update(Box::new(self.update));
1839 engine::apply_where(&mut expression, condition.0, options.append)
1840 .expect("update builder accepts WHERE clauses");
1841 self.update = match expression {
1842 Expression::Update(update) => *update,
1843 _ => unreachable!("update builder engine changed the expression kind"),
1844 };
1845 self
1846 }
1847
1848 pub fn from(self, table_name: &str) -> Self {
1852 self.edit(|expression| {
1853 engine::set_from(
1854 expression,
1855 vec![Expression::Table(Box::new(builder_table_ref(table_name)))],
1856 )
1857 .expect("update builder accepts FROM clauses")
1858 })
1859 }
1860
1861 pub fn build(self) -> Expression {
1863 Expression::Update(Box::new(self.update))
1864 }
1865
1866 pub fn to_sql(self) -> String {
1868 generate_builder_sql(&self.build())
1869 }
1870}
1871
1872pub fn case() -> CaseBuilder {
1897 CaseBuilder {
1898 operand: None,
1899 whens: Vec::new(),
1900 else_: None,
1901 }
1902}
1903
1904pub fn case_of(operand: Expr) -> CaseBuilder {
1925 CaseBuilder {
1926 operand: Some(operand.0),
1927 whens: Vec::new(),
1928 else_: None,
1929 }
1930}
1931
1932pub struct CaseBuilder {
1940 operand: Option<Expression>,
1941 whens: Vec<(Expression, Expression)>,
1942 else_: Option<Expression>,
1943}
1944
1945impl CaseBuilder {
1946 pub fn when(mut self, condition: Expr, result: Expr) -> Self {
1951 self.whens.push((condition.0, result.0));
1952 self
1953 }
1954
1955 pub fn else_(mut self, result: Expr) -> Self {
1960 self.else_ = Some(result.0);
1961 self
1962 }
1963
1964 pub fn build(self) -> Expr {
1966 Expr(self.build_expr())
1967 }
1968
1969 pub fn build_expr(self) -> Expression {
1974 let mut expression = engine::case(self.operand);
1975 for (condition, result) in self.whens {
1976 engine::append_case_when(&mut expression, condition, result)
1977 .expect("case builder accepts WHEN branches");
1978 }
1979 if let Some(result) = self.else_ {
1980 engine::set_case_else(&mut expression, result)
1981 .expect("case builder accepts ELSE branches");
1982 }
1983 expression
1984 }
1985}
1986
1987pub fn subquery(query: SelectBuilder, alias_name: &str) -> Expr {
2011 subquery_expr(query.build(), alias_name)
2012}
2013
2014pub fn subquery_expr(expr: Expression, alias_name: &str) -> Expr {
2019 Expr(
2020 engine::subquery(expr, Some(builder_identifier(alias_name)), true)
2021 .expect("subquery builder source is a query"),
2022 )
2023}
2024
2025#[derive(Debug, Clone, Copy)]
2031enum SetOpKind {
2032 Union,
2033 Intersect,
2034 Except,
2035}
2036
2037pub struct SetOpBuilder {
2058 kind: SetOpKind,
2059 left: Expression,
2060 right: Expression,
2061 all: bool,
2062 order_by: Option<OrderBy>,
2063 limit: Option<Box<Expression>>,
2064 offset: Option<Box<Expression>>,
2065}
2066
2067impl SetOpBuilder {
2068 fn new(kind: SetOpKind, left: SelectBuilder, right: SelectBuilder, all: bool) -> Self {
2069 SetOpBuilder {
2070 kind,
2071 left: left.build(),
2072 right: right.build(),
2073 all,
2074 order_by: None,
2075 limit: None,
2076 offset: None,
2077 }
2078 }
2079
2080 pub fn order_by<I, E>(self, expressions: I) -> Self
2085 where
2086 I: IntoIterator<Item = E>,
2087 E: IntoExpr,
2088 {
2089 self.order_by_with_options(expressions, ClauseOptions::default())
2090 }
2091
2092 pub fn order_by_with_options<I, E>(mut self, expressions: I, options: ClauseOptions) -> Self
2094 where
2095 I: IntoIterator<Item = E>,
2096 E: IntoExpr,
2097 {
2098 let values: Vec<_> = expressions
2099 .into_iter()
2100 .map(|expression| engine::ordered(expression.into_expr().0))
2101 .collect();
2102 if options.append {
2103 self.order_by
2104 .get_or_insert_with(|| OrderBy {
2105 siblings: false,
2106 comments: Vec::new(),
2107 expressions: Vec::new(),
2108 })
2109 .expressions
2110 .extend(values);
2111 } else {
2112 self.order_by = Some(OrderBy {
2113 siblings: false,
2114 comments: Vec::new(),
2115 expressions: values,
2116 });
2117 }
2118 self
2119 }
2120
2121 pub fn limit(mut self, count: usize) -> Self {
2123 self.limit = Some(Box::new(Expression::Literal(Box::new(Literal::Number(
2124 count.to_string(),
2125 )))));
2126 self
2127 }
2128
2129 pub fn offset(mut self, count: usize) -> Self {
2131 self.offset = Some(Box::new(Expression::Literal(Box::new(Literal::Number(
2132 count.to_string(),
2133 )))));
2134 self
2135 }
2136
2137 pub fn build(self) -> Expression {
2142 let kind = match self.kind {
2143 SetOpKind::Union => engine::SetKind::Union,
2144 SetOpKind::Intersect => engine::SetKind::Intersect,
2145 SetOpKind::Except => engine::SetKind::Except,
2146 };
2147 let mut expression = engine::set_operation(kind, self.left, self.right, !self.all)
2148 .expect("set builder operands are queries");
2149 if let Some(order_by) = self.order_by {
2150 engine::apply_order_by(&mut expression, order_by.expressions, false)
2151 .expect("set operations accept ORDER BY clauses");
2152 }
2153 if let Some(limit) = self.limit {
2154 engine::apply_limit(&mut expression, *limit)
2155 .expect("set operations accept LIMIT clauses");
2156 }
2157 if let Some(offset) = self.offset {
2158 engine::apply_offset(&mut expression, *offset)
2159 .expect("set operations accept OFFSET clauses");
2160 }
2161 expression
2162 }
2163
2164 pub fn to_sql(self) -> String {
2166 generate_builder_sql(&self.build())
2167 }
2168}
2169
2170pub fn union(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2174 SetOpBuilder::new(SetOpKind::Union, left, right, false)
2175}
2176
2177pub fn union_all(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2181 SetOpBuilder::new(SetOpKind::Union, left, right, true)
2182}
2183
2184pub fn intersect(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2188 SetOpBuilder::new(SetOpKind::Intersect, left, right, false)
2189}
2190
2191pub fn intersect_all(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2195 SetOpBuilder::new(SetOpKind::Intersect, left, right, true)
2196}
2197
2198pub fn except_(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2202 SetOpBuilder::new(SetOpKind::Except, left, right, false)
2203}
2204
2205pub fn except_all(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2209 SetOpBuilder::new(SetOpKind::Except, left, right, true)
2210}
2211
2212pub struct WindowDefBuilder {
2237 partition_by: Vec<Expression>,
2238 order_by: Vec<Ordered>,
2239}
2240
2241impl WindowDefBuilder {
2242 pub fn new() -> Self {
2244 WindowDefBuilder {
2245 partition_by: Vec::new(),
2246 order_by: Vec::new(),
2247 }
2248 }
2249
2250 pub fn partition_by<I, E>(mut self, expressions: I) -> Self
2252 where
2253 I: IntoIterator<Item = E>,
2254 E: IntoExpr,
2255 {
2256 self.partition_by = expressions.into_iter().map(|e| e.into_expr().0).collect();
2257 self
2258 }
2259
2260 pub fn order_by<I, E>(mut self, expressions: I) -> Self
2265 where
2266 I: IntoIterator<Item = E>,
2267 E: IntoExpr,
2268 {
2269 self.order_by = expressions
2270 .into_iter()
2271 .map(|e| {
2272 let expr = e.into_expr().0;
2273 match expr {
2274 Expression::Ordered(o) => *o,
2275 other => Ordered {
2276 this: other,
2277 desc: false,
2278 nulls_first: None,
2279 explicit_asc: false,
2280 with_fill: None,
2281 },
2282 }
2283 })
2284 .collect();
2285 self
2286 }
2287}
2288
2289pub trait IntoExpr {
2308 fn into_expr(self) -> Expr;
2310}
2311
2312impl IntoExpr for Expr {
2313 fn into_expr(self) -> Expr {
2314 self
2315 }
2316}
2317
2318impl IntoExpr for &str {
2319 fn into_expr(self) -> Expr {
2321 col(self)
2322 }
2323}
2324
2325impl IntoExpr for String {
2326 fn into_expr(self) -> Expr {
2328 col(&self)
2329 }
2330}
2331
2332impl IntoExpr for Expression {
2333 fn into_expr(self) -> Expr {
2335 Expr(self)
2336 }
2337}
2338
2339pub trait IntoLiteral {
2354 fn into_literal(self) -> Expr;
2356}
2357
2358impl IntoLiteral for &str {
2359 fn into_literal(self) -> Expr {
2361 Expr(Expression::Literal(Box::new(Literal::String(
2362 self.to_string(),
2363 ))))
2364 }
2365}
2366
2367impl IntoLiteral for String {
2368 fn into_literal(self) -> Expr {
2370 Expr(Expression::Literal(Box::new(Literal::String(self))))
2371 }
2372}
2373
2374impl IntoLiteral for i64 {
2375 fn into_literal(self) -> Expr {
2377 Expr(Expression::Literal(Box::new(Literal::Number(
2378 self.to_string(),
2379 ))))
2380 }
2381}
2382
2383impl IntoLiteral for i32 {
2384 fn into_literal(self) -> Expr {
2386 Expr(Expression::Literal(Box::new(Literal::Number(
2387 self.to_string(),
2388 ))))
2389 }
2390}
2391
2392impl IntoLiteral for usize {
2393 fn into_literal(self) -> Expr {
2395 Expr(Expression::Literal(Box::new(Literal::Number(
2396 self.to_string(),
2397 ))))
2398 }
2399}
2400
2401impl IntoLiteral for f64 {
2402 fn into_literal(self) -> Expr {
2404 Expr(Expression::Literal(Box::new(Literal::Number(
2405 self.to_string(),
2406 ))))
2407 }
2408}
2409
2410impl IntoLiteral for bool {
2411 fn into_literal(self) -> Expr {
2413 Expr(Expression::Boolean(BooleanLiteral { value: self }))
2414 }
2415}
2416
2417pub fn merge_into(target: &str) -> MergeBuilder {
2439 MergeBuilder {
2440 expression: engine::merge(Expression::Table(Box::new(builder_table_ref(target)))),
2441 }
2442}
2443
2444pub struct MergeBuilder {
2448 expression: Expression,
2449}
2450
2451impl MergeBuilder {
2452 pub fn using(mut self, source: &str, on: Expr) -> Self {
2454 engine::set_merge_using(
2455 &mut self.expression,
2456 Expression::Table(Box::new(builder_table_ref(source))),
2457 on.0,
2458 )
2459 .expect("merge builder accepts a USING clause");
2460 self
2461 }
2462
2463 pub fn when_matched_update(mut self, assignments: Vec<(&str, Expr)>) -> Self {
2465 let assignments = assignments
2466 .into_iter()
2467 .map(|(column, value)| (builder_identifier(column), value.0))
2468 .collect();
2469 engine::append_merge_update(&mut self.expression, assignments, None)
2470 .expect("merge builder accepts matched update actions");
2471 self
2472 }
2473
2474 pub fn when_matched_update_where(
2476 mut self,
2477 condition: Expr,
2478 assignments: Vec<(&str, Expr)>,
2479 ) -> Self {
2480 let assignments = assignments
2481 .into_iter()
2482 .map(|(column, value)| (builder_identifier(column), value.0))
2483 .collect();
2484 engine::append_merge_update(&mut self.expression, assignments, Some(condition.0))
2485 .expect("merge builder accepts conditional matched update actions");
2486 self
2487 }
2488
2489 pub fn when_matched_delete(mut self) -> Self {
2491 engine::append_merge_delete(&mut self.expression, None)
2492 .expect("merge builder accepts matched delete actions");
2493 self
2494 }
2495
2496 pub fn when_matched_delete_where(mut self, condition: Expr) -> Self {
2498 engine::append_merge_delete(&mut self.expression, Some(condition.0))
2499 .expect("merge builder accepts conditional matched delete actions");
2500 self
2501 }
2502
2503 pub fn when_not_matched_insert(mut self, columns: &[&str], values: Vec<Expr>) -> Self {
2505 engine::append_merge_insert(
2506 &mut self.expression,
2507 columns
2508 .iter()
2509 .map(|column| builder_identifier(column))
2510 .collect(),
2511 values.into_iter().map(|value| value.0).collect(),
2512 None,
2513 )
2514 .expect("merge builder accepts not-matched insert actions");
2515 self
2516 }
2517
2518 pub fn when_not_matched_insert_where(
2520 mut self,
2521 condition: Expr,
2522 columns: &[&str],
2523 values: Vec<Expr>,
2524 ) -> Self {
2525 engine::append_merge_insert(
2526 &mut self.expression,
2527 columns
2528 .iter()
2529 .map(|column| builder_identifier(column))
2530 .collect(),
2531 values.into_iter().map(|value| value.0).collect(),
2532 Some(condition.0),
2533 )
2534 .expect("merge builder accepts conditional not-matched insert actions");
2535 self
2536 }
2537
2538 pub fn build(self) -> Expression {
2540 self.expression
2541 }
2542
2543 pub fn to_sql(self) -> String {
2545 generate_builder_sql(&self.build())
2546 }
2547}
2548
2549fn parse_simple_data_type(name: &str) -> DataType {
2550 let upper = name.trim().to_uppercase();
2551 match upper.as_str() {
2552 "INT" | "INTEGER" => DataType::Int {
2553 length: None,
2554 integer_spelling: upper == "INTEGER",
2555 },
2556 "BIGINT" => DataType::BigInt { length: None },
2557 "SMALLINT" => DataType::SmallInt { length: None },
2558 "TINYINT" => DataType::TinyInt { length: None },
2559 "FLOAT" => DataType::Float {
2560 precision: None,
2561 scale: None,
2562 real_spelling: false,
2563 },
2564 "DOUBLE" => DataType::Double {
2565 precision: None,
2566 scale: None,
2567 },
2568 "BOOLEAN" | "BOOL" => DataType::Boolean,
2569 "TEXT" => DataType::Text,
2570 "DATE" => DataType::Date,
2571 "TIMESTAMP" => DataType::Timestamp {
2572 precision: None,
2573 timezone: false,
2574 },
2575 "VARCHAR" => DataType::VarChar {
2576 length: None,
2577 parenthesized_length: false,
2578 },
2579 "CHAR" => DataType::Char { length: None },
2580 _ => {
2581 if let Ok(ast) =
2583 crate::parser::Parser::parse_sql(&format!("SELECT CAST(x AS {})", name))
2584 {
2585 if let Expression::Select(s) = &ast[0] {
2586 if let Some(Expression::Cast(c)) = s.expressions.first() {
2587 return c.to.clone();
2588 }
2589 }
2590 }
2591 DataType::Custom {
2593 name: name.to_string(),
2594 }
2595 }
2596 }
2597}
2598
2599#[cfg(test)]
2600mod tests {
2601 use super::*;
2602
2603 #[test]
2604 fn test_simple_select() {
2605 let sql = select(["id", "name"]).from("users").to_sql();
2606 assert_eq!(sql, "SELECT id, name FROM users");
2607 }
2608
2609 #[test]
2610 fn test_builder_quotes_unsafe_identifier_tokens() {
2611 let sql = select(["Name; DROP TABLE titanic"]).to_sql();
2612 assert_eq!(sql, r#"SELECT "Name; DROP TABLE titanic""#);
2613 }
2614
2615 #[test]
2616 fn test_builder_string_literal_requires_lit() {
2617 let sql = select([lit("Name; DROP TABLE titanic")]).to_sql();
2618 assert_eq!(sql, "SELECT 'Name; DROP TABLE titanic'");
2619 }
2620
2621 #[test]
2622 fn test_builder_quotes_unsafe_table_name_tokens() {
2623 let sql = select(["id"]).from("users; DROP TABLE x").to_sql();
2624 assert_eq!(sql, r#"SELECT id FROM "users; DROP TABLE x""#);
2625 }
2626
2627 #[test]
2628 fn test_select_star() {
2629 let sql = select([star()]).from("users").to_sql();
2630 assert_eq!(sql, "SELECT * FROM users");
2631 }
2632
2633 #[test]
2634 fn test_select_with_where() {
2635 let sql = select(["id", "name"])
2636 .from("users")
2637 .where_(col("age").gt(lit(18)))
2638 .to_sql();
2639 assert_eq!(sql, "SELECT id, name FROM users WHERE age > 18");
2640 }
2641
2642 #[test]
2643 fn test_select_with_join() {
2644 let sql = select(["u.id", "o.amount"])
2645 .from("users")
2646 .join("orders", col("u.id").eq(col("o.user_id")))
2647 .to_sql();
2648 assert_eq!(
2649 sql,
2650 "SELECT u.id, o.amount FROM users JOIN orders ON u.id = o.user_id"
2651 );
2652 }
2653
2654 #[test]
2655 fn test_select_with_group_by_having() {
2656 let sql = select([col("dept"), func("COUNT", [star()]).alias("cnt")])
2657 .from("employees")
2658 .group_by(["dept"])
2659 .having(func("COUNT", [star()]).gt(lit(5)))
2660 .to_sql();
2661 assert_eq!(
2662 sql,
2663 "SELECT dept, COUNT(*) AS cnt FROM employees GROUP BY dept HAVING COUNT(*) > 5"
2664 );
2665 }
2666
2667 #[test]
2668 fn test_select_with_order_limit_offset() {
2669 let sql = select(["id", "name"])
2670 .from("users")
2671 .order_by(["name"])
2672 .limit(10)
2673 .offset(20)
2674 .to_sql();
2675 assert_eq!(
2676 sql,
2677 "SELECT id, name FROM users ORDER BY name LIMIT 10 OFFSET 20"
2678 );
2679 }
2680
2681 #[test]
2682 fn test_select_distinct() {
2683 let sql = select(["name"]).from("users").distinct().to_sql();
2684 assert_eq!(sql, "SELECT DISTINCT name FROM users");
2685 }
2686
2687 #[test]
2688 fn test_insert_values() {
2689 let sql = insert_into("users")
2690 .columns(["id", "name"])
2691 .values([lit(1), lit("Alice")])
2692 .values([lit(2), lit("Bob")])
2693 .to_sql();
2694 assert_eq!(
2695 sql,
2696 "INSERT INTO users (id, name) VALUES (1, 'Alice'), (2, 'Bob')"
2697 );
2698 }
2699
2700 #[test]
2701 fn test_insert_select() {
2702 let sql = insert_into("archive")
2703 .columns(["id", "name"])
2704 .query(select(["id", "name"]).from("users"))
2705 .to_sql();
2706 assert_eq!(
2707 sql,
2708 "INSERT INTO archive (id, name) SELECT id, name FROM users"
2709 );
2710 }
2711
2712 #[test]
2713 fn test_update() {
2714 let sql = update("users")
2715 .set("name", lit("Bob"))
2716 .set("age", lit(30))
2717 .where_(col("id").eq(lit(1)))
2718 .to_sql();
2719 assert_eq!(sql, "UPDATE users SET name = 'Bob', age = 30 WHERE id = 1");
2720 }
2721
2722 #[test]
2723 fn test_delete() {
2724 let sql = delete("users").where_(col("id").eq(lit(1))).to_sql();
2725 assert_eq!(sql, "DELETE FROM users WHERE id = 1");
2726 }
2727
2728 #[test]
2729 fn test_complex_where() {
2730 let sql = select(["id"])
2731 .from("users")
2732 .where_(
2733 col("age")
2734 .gte(lit(18))
2735 .and(col("active").eq(boolean(true)))
2736 .and(col("name").like(lit("%test%"))),
2737 )
2738 .to_sql();
2739 assert_eq!(
2740 sql,
2741 "SELECT id FROM users WHERE age >= 18 AND active = TRUE AND name LIKE '%test%'"
2742 );
2743 }
2744
2745 #[test]
2746 fn test_in_list() {
2747 let sql = select(["id"])
2748 .from("users")
2749 .where_(col("status").in_list([lit("active"), lit("pending")]))
2750 .to_sql();
2751 assert_eq!(
2752 sql,
2753 "SELECT id FROM users WHERE status IN ('active', 'pending')"
2754 );
2755 }
2756
2757 #[test]
2758 fn test_between() {
2759 let sql = select(["id"])
2760 .from("orders")
2761 .where_(col("amount").between(lit(100), lit(500)))
2762 .to_sql();
2763 assert_eq!(
2764 sql,
2765 "SELECT id FROM orders WHERE amount BETWEEN 100 AND 500"
2766 );
2767 }
2768
2769 #[test]
2770 fn test_is_null() {
2771 let sql = select(["id"])
2772 .from("users")
2773 .where_(col("email").is_null())
2774 .to_sql();
2775 assert_eq!(sql, "SELECT id FROM users WHERE email IS NULL");
2776 }
2777
2778 #[test]
2779 fn test_arithmetic() {
2780 let sql = select([col("price").mul(col("quantity")).alias("total")])
2781 .from("items")
2782 .to_sql();
2783 assert_eq!(sql, "SELECT price * quantity AS total FROM items");
2784 }
2785
2786 #[test]
2787 fn test_cast() {
2788 let sql = select([col("id").cast("VARCHAR")]).from("users").to_sql();
2789 assert_eq!(sql, "SELECT CAST(id AS VARCHAR) FROM users");
2790 }
2791
2792 #[test]
2793 fn test_from_starter() {
2794 let sql = from("users").select_cols(["id", "name"]).to_sql();
2795 assert_eq!(sql, "SELECT id, name FROM users");
2796 }
2797
2798 #[test]
2799 fn test_qualified_column() {
2800 let sql = select([col("u.id"), col("u.name")]).from("users").to_sql();
2801 assert_eq!(sql, "SELECT u.id, u.name FROM users");
2802 }
2803
2804 #[test]
2805 fn test_nested_dot_column() {
2806 let sql = select([col("t.s.f")]).from("users").to_sql();
2807 assert_eq!(sql, "SELECT t.s.f FROM users");
2808 }
2809
2810 #[test]
2811 fn test_not_condition() {
2812 let sql = select(["id"])
2813 .from("users")
2814 .where_(not(col("active").eq(boolean(true))))
2815 .to_sql();
2816 assert_eq!(sql, "SELECT id FROM users WHERE NOT active = TRUE");
2817 }
2818
2819 #[test]
2820 fn test_order_by_desc() {
2821 let sql = select(["id", "name"])
2822 .from("users")
2823 .order_by([col("name").desc()])
2824 .to_sql();
2825 assert_eq!(sql, "SELECT id, name FROM users ORDER BY name DESC");
2826 }
2827
2828 #[test]
2829 fn test_left_join() {
2830 let sql = select(["u.id", "o.amount"])
2831 .from("users")
2832 .left_join("orders", col("u.id").eq(col("o.user_id")))
2833 .to_sql();
2834 assert_eq!(
2835 sql,
2836 "SELECT u.id, o.amount FROM users LEFT JOIN orders ON u.id = o.user_id"
2837 );
2838 }
2839
2840 #[test]
2841 fn test_build_returns_expression() {
2842 let expr = select(["id"]).from("users").build();
2843 assert!(matches!(expr, Expression::Select(_)));
2844 }
2845
2846 #[test]
2847 fn test_expr_interop() {
2848 let age_check = col("age").gt(lit(18));
2850 let sql = select([col("id"), age_check.alias("is_adult")])
2851 .from("users")
2852 .to_sql();
2853 assert_eq!(sql, "SELECT id, age > 18 AS is_adult FROM users");
2854 }
2855
2856 #[test]
2859 fn test_sql_expr_simple() {
2860 let expr = sql_expr("age > 18");
2861 let sql = select(["id"]).from("users").where_(expr).to_sql();
2862 assert_eq!(sql, "SELECT id FROM users WHERE age > 18");
2863 }
2864
2865 #[test]
2866 fn test_sql_expr_compound() {
2867 let expr = sql_expr("a > 1 AND b < 10");
2868 let sql = select(["*"]).from("t").where_(expr).to_sql();
2869 assert_eq!(sql, "SELECT * FROM t WHERE a > 1 AND b < 10");
2870 }
2871
2872 #[test]
2873 fn test_sql_expr_function() {
2874 let expr = sql_expr("COALESCE(a, b, 0)");
2875 let sql = select([expr.alias("val")]).from("t").to_sql();
2876 assert_eq!(sql, "SELECT COALESCE(a, b, 0) AS val FROM t");
2877 }
2878
2879 #[test]
2880 fn test_condition_alias() {
2881 let cond = condition("x > 0");
2882 let sql = select(["*"]).from("t").where_(cond).to_sql();
2883 assert_eq!(sql, "SELECT * FROM t WHERE x > 0");
2884 }
2885
2886 #[test]
2889 fn test_ilike() {
2890 let sql = select(["id"])
2891 .from("users")
2892 .where_(col("name").ilike(lit("%test%")))
2893 .to_sql();
2894 assert_eq!(sql, "SELECT id FROM users WHERE name ILIKE '%test%'");
2895 }
2896
2897 #[test]
2898 fn test_rlike() {
2899 let sql = select(["id"])
2900 .from("users")
2901 .where_(col("name").rlike(lit("^[A-Z]")))
2902 .to_sql();
2903 assert_eq!(
2904 sql,
2905 "SELECT id FROM users WHERE REGEXP_LIKE(name, '^[A-Z]')"
2906 );
2907 }
2908
2909 #[test]
2910 fn test_not_in() {
2911 let sql = select(["id"])
2912 .from("users")
2913 .where_(col("status").not_in([lit("deleted"), lit("banned")]))
2914 .to_sql();
2915 assert_eq!(
2916 sql,
2917 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
2918 );
2919 }
2920
2921 #[test]
2922 fn repeated_clauses_append_unless_replacement_is_requested() {
2923 let appended = select(["x"])
2924 .where_(col("x").gt(lit(0)))
2925 .where_(col("x").lt(lit(10)))
2926 .group_by(["x"])
2927 .group_by(["y"])
2928 .to_sql();
2929 assert_eq!(appended, "SELECT x WHERE x > 0 AND x < 10 GROUP BY x, y");
2930
2931 let replaced = select(["x"])
2932 .where_(col("x").gt(lit(0)))
2933 .where_with_options(col("x").eq(lit(5)), ClauseOptions { append: false })
2934 .group_by(["x"])
2935 .group_by_with_options(["y"], ClauseOptions { append: false })
2936 .to_sql();
2937 assert_eq!(replaced, "SELECT x WHERE x = 5 GROUP BY y");
2938 }
2939
2940 #[test]
2943 fn test_case_searched() {
2944 let expr = case()
2945 .when(col("x").gt(lit(0)), lit("positive"))
2946 .when(col("x").eq(lit(0)), lit("zero"))
2947 .else_(lit("negative"))
2948 .build();
2949 let sql = select([expr.alias("label")]).from("t").to_sql();
2950 assert_eq!(
2951 sql,
2952 "SELECT CASE WHEN x > 0 THEN 'positive' WHEN x = 0 THEN 'zero' ELSE 'negative' END AS label FROM t"
2953 );
2954 }
2955
2956 #[test]
2957 fn test_case_simple() {
2958 let expr = case_of(col("status"))
2959 .when(lit(1), lit("active"))
2960 .when(lit(0), lit("inactive"))
2961 .build();
2962 let sql = select([expr.alias("status_label")]).from("t").to_sql();
2963 assert_eq!(
2964 sql,
2965 "SELECT CASE status WHEN 1 THEN 'active' WHEN 0 THEN 'inactive' END AS status_label FROM t"
2966 );
2967 }
2968
2969 #[test]
2970 fn test_case_no_else() {
2971 let expr = case().when(col("x").gt(lit(0)), lit("yes")).build();
2972 let sql = select([expr]).from("t").to_sql();
2973 assert_eq!(sql, "SELECT CASE WHEN x > 0 THEN 'yes' END FROM t");
2974 }
2975
2976 #[test]
2979 fn test_subquery_in_from() {
2980 let inner = select(["id", "name"])
2981 .from("users")
2982 .where_(col("active").eq(boolean(true)));
2983 let outer = select(["sub.id"])
2984 .from_expr(subquery(inner, "sub"))
2985 .to_sql();
2986 assert_eq!(
2987 outer,
2988 "SELECT sub.id FROM (SELECT id, name FROM users WHERE active = TRUE) AS sub"
2989 );
2990 }
2991
2992 #[test]
2993 fn test_subquery_in_join() {
2994 let inner = select([col("user_id"), func("SUM", [col("amount")]).alias("total")])
2995 .from("orders")
2996 .group_by(["user_id"]);
2997 let sql = select(["u.name", "o.total"])
2998 .from("users")
2999 .join("orders", col("u.id").eq(col("o.user_id")))
3000 .to_sql();
3001 assert!(sql.contains("JOIN"));
3002 let _sub = subquery(inner, "o");
3004 }
3005
3006 #[test]
3009 fn test_union() {
3010 let sql = union(select(["id"]).from("a"), select(["id"]).from("b")).to_sql();
3011 assert_eq!(sql, "SELECT id FROM a UNION SELECT id FROM b");
3012 }
3013
3014 #[test]
3015 fn test_union_all() {
3016 let sql = union_all(select(["id"]).from("a"), select(["id"]).from("b")).to_sql();
3017 assert_eq!(sql, "SELECT id FROM a UNION ALL SELECT id FROM b");
3018 }
3019
3020 #[test]
3021 fn test_intersect_builder() {
3022 let sql = intersect(select(["id"]).from("a"), select(["id"]).from("b")).to_sql();
3023 assert_eq!(sql, "SELECT id FROM a INTERSECT SELECT id FROM b");
3024 }
3025
3026 #[test]
3027 fn test_except_builder() {
3028 let sql = except_(select(["id"]).from("a"), select(["id"]).from("b")).to_sql();
3029 assert_eq!(sql, "SELECT id FROM a EXCEPT SELECT id FROM b");
3030 }
3031
3032 #[test]
3033 fn test_union_with_order_limit() {
3034 let sql = union(select(["id"]).from("a"), select(["id"]).from("b"))
3035 .order_by(["id"])
3036 .limit(10)
3037 .to_sql();
3038 assert!(sql.contains("UNION"));
3039 assert!(sql.contains("ORDER BY"));
3040 assert!(sql.contains("LIMIT"));
3041 }
3042
3043 #[test]
3044 fn test_select_builder_union() {
3045 let sql = select(["id"])
3046 .from("a")
3047 .union(select(["id"]).from("b"))
3048 .to_sql();
3049 assert_eq!(sql, "SELECT id FROM a UNION SELECT id FROM b");
3050 }
3051
3052 #[test]
3055 fn test_qualify() {
3056 let sql = select(["id", "name"])
3057 .from("users")
3058 .qualify(col("rn").eq(lit(1)))
3059 .to_sql();
3060 assert_eq!(sql, "SELECT id, name FROM users QUALIFY rn = 1");
3061 }
3062
3063 #[test]
3064 fn test_right_join() {
3065 let sql = select(["u.id", "o.amount"])
3066 .from("users")
3067 .right_join("orders", col("u.id").eq(col("o.user_id")))
3068 .to_sql();
3069 assert_eq!(
3070 sql,
3071 "SELECT u.id, o.amount FROM users RIGHT JOIN orders ON u.id = o.user_id"
3072 );
3073 }
3074
3075 #[test]
3076 fn test_cross_join() {
3077 let sql = select(["a.x", "b.y"]).from("a").cross_join("b").to_sql();
3078 assert_eq!(sql, "SELECT a.x, b.y FROM a CROSS JOIN b");
3079 }
3080
3081 #[test]
3082 fn test_lateral_view() {
3083 let sql = select(["id", "col_val"])
3084 .from("t")
3085 .lateral_view(func("EXPLODE", [col("arr")]), "lv", ["col_val"])
3086 .to_sql();
3087 assert!(sql.contains("LATERAL VIEW"));
3088 assert!(sql.contains("EXPLODE"));
3089
3090 let expression = select(["id"])
3091 .from("t")
3092 .lateral_view_with_options(
3093 func("EXPLODE", [col("arr")]),
3094 "lv",
3095 ["value"],
3096 LateralViewOptions { outer: true },
3097 )
3098 .build();
3099 let Expression::Select(select) = expression else {
3100 panic!("expected SELECT")
3101 };
3102 assert!(select.lateral_views[0].outer);
3103 }
3104
3105 #[test]
3106 fn test_window_clause() {
3107 let sql = select(["id"])
3108 .from("t")
3109 .window(
3110 "w",
3111 WindowDefBuilder::new()
3112 .partition_by(["dept"])
3113 .order_by(["salary"]),
3114 )
3115 .to_sql();
3116 assert!(sql.contains("WINDOW"));
3117 assert!(sql.contains("PARTITION BY"));
3118 }
3119
3120 #[test]
3123 fn test_xor() {
3124 let sql = select(["*"])
3125 .from("t")
3126 .where_(col("a").xor(col("b")))
3127 .to_sql();
3128 assert_eq!(sql, "SELECT * FROM t WHERE a XOR b");
3129 }
3130
3131 #[test]
3134 fn test_for_update() {
3135 let sql = select(["id"]).from("t").for_update().to_sql();
3136 assert_eq!(sql, "SELECT id FROM t FOR UPDATE");
3137 }
3138
3139 #[test]
3140 fn test_for_share() {
3141 let sql = select(["id"]).from("t").for_share().to_sql();
3142 assert_eq!(sql, "SELECT id FROM t FOR SHARE");
3143 }
3144
3145 #[test]
3148 fn test_hint() {
3149 let sql = select(["*"]).from("t").hint("FULL(t)").to_sql();
3150 assert!(sql.contains("FULL(t)"), "Expected hint in: {}", sql);
3151 }
3152
3153 #[test]
3156 fn test_ctas() {
3157 let expr = select(["*"]).from("t").ctas("new_table");
3158 let sql = Generator::sql(&expr).unwrap();
3159 assert_eq!(sql, "CREATE TABLE new_table AS SELECT * FROM t");
3160
3161 let expr = select(["*"]).from("t").ctas_with_options(
3162 "new_table",
3163 CtasOptions {
3164 replace: true,
3165 temporary: true,
3166 },
3167 );
3168 let Expression::CreateTable(create) = expr else {
3169 panic!("expected CREATE TABLE")
3170 };
3171 assert!(create.or_replace);
3172 assert!(create.temporary);
3173 }
3174
3175 #[test]
3178 fn test_merge_update_insert() {
3179 let sql = merge_into("target")
3180 .using("source", col("target.id").eq(col("source.id")))
3181 .when_matched_update(vec![("name", col("source.name"))])
3182 .when_not_matched_insert(&["id", "name"], vec![col("source.id"), col("source.name")])
3183 .to_sql();
3184 assert!(
3185 sql.contains("MERGE INTO"),
3186 "Expected MERGE INTO in: {}",
3187 sql
3188 );
3189 assert!(sql.contains("USING"), "Expected USING in: {}", sql);
3190 assert!(
3191 sql.contains("WHEN MATCHED"),
3192 "Expected WHEN MATCHED in: {}",
3193 sql
3194 );
3195 assert!(
3196 sql.contains("UPDATE SET"),
3197 "Expected UPDATE SET in: {}",
3198 sql
3199 );
3200 assert!(
3201 sql.contains("WHEN NOT MATCHED"),
3202 "Expected WHEN NOT MATCHED in: {}",
3203 sql
3204 );
3205 assert!(sql.contains("INSERT"), "Expected INSERT in: {}", sql);
3206 }
3207
3208 #[test]
3209 fn test_merge_delete() {
3210 let sql = merge_into("target")
3211 .using("source", col("target.id").eq(col("source.id")))
3212 .when_matched_delete()
3213 .to_sql();
3214 assert!(
3215 sql.contains("MERGE INTO"),
3216 "Expected MERGE INTO in: {}",
3217 sql
3218 );
3219 assert!(
3220 sql.contains("WHEN MATCHED THEN DELETE"),
3221 "Expected WHEN MATCHED THEN DELETE in: {}",
3222 sql
3223 );
3224 }
3225
3226 #[test]
3227 fn test_merge_with_condition() {
3228 let sql = merge_into("target")
3229 .using("source", col("target.id").eq(col("source.id")))
3230 .when_matched_update_where(
3231 col("source.active").eq(boolean(true)),
3232 vec![("name", col("source.name"))],
3233 )
3234 .to_sql();
3235 assert!(
3236 sql.contains("MERGE INTO"),
3237 "Expected MERGE INTO in: {}",
3238 sql
3239 );
3240 assert!(
3241 sql.contains("AND source.active = TRUE"),
3242 "Expected condition in: {}",
3243 sql
3244 );
3245 }
3246}