1pub mod plan;
59
60use crate::ast_mutation as engine;
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 inferred_type: None,
190 }));
191 }
192
193 return Expr(expr);
194 }
195
196 if let Some((table, column)) = name.rsplit_once('.') {
197 Expr(Expression::boxed_column(Column {
198 name: builder_identifier(column),
199 table: Some(builder_identifier(table)),
200 join_mark: false,
201 trailing_comments: Vec::new(),
202 span: None,
203 inferred_type: None,
204 }))
205 } else {
206 Expr(Expression::boxed_column(Column {
207 name: builder_identifier(name),
208 table: None,
209 join_mark: false,
210 trailing_comments: Vec::new(),
211 span: None,
212 inferred_type: None,
213 }))
214 }
215}
216
217pub fn lit<V: IntoLiteral>(value: V) -> Expr {
233 value.into_literal()
234}
235
236pub fn star() -> Expr {
238 Expr(Expression::star())
239}
240
241pub fn null() -> Expr {
243 Expr(Expression::Null(Null))
244}
245
246pub fn boolean(value: bool) -> Expr {
248 Expr(Expression::Boolean(BooleanLiteral { value }))
249}
250
251pub fn table(name: &str) -> Expr {
268 Expr(Expression::Table(Box::new(builder_table_ref(name))))
269}
270
271pub fn func(name: &str, args: impl IntoIterator<Item = Expr>) -> Expr {
288 Expr(Expression::Function(Box::new(Function {
289 name: name.to_string(),
290 args: args.into_iter().map(|a| a.0).collect(),
291 ..Function::default()
292 })))
293}
294
295pub fn cast(expr: Expr, to: &str) -> Expr {
311 let data_type = parse_simple_data_type(to);
312 Expr(Expression::Cast(Box::new(Cast {
313 this: expr.0,
314 to: data_type,
315 trailing_comments: Vec::new(),
316 double_colon_syntax: false,
317 format: None,
318 default: None,
319 inferred_type: None,
320 })))
321}
322
323pub fn not(expr: Expr) -> Expr {
328 Expr(Expression::Not(Box::new(UnaryOp::new(expr.0))))
329}
330
331pub fn and(left: Expr, right: Expr) -> Expr {
336 left.and(right)
337}
338
339pub fn or(left: Expr, right: Expr) -> Expr {
344 left.or(right)
345}
346
347pub fn alias(expr: Expr, name: &str) -> Expr {
352 Expr(Expression::Alias(Box::new(Alias {
353 this: expr.0,
354 alias: builder_identifier(name),
355 column_aliases: Vec::new(),
356 alias_explicit_as: false,
357 alias_keyword: None,
358 pre_alias_comments: Vec::new(),
359 trailing_comments: Vec::new(),
360 inferred_type: None,
361 })))
362}
363
364pub fn sql_expr(sql: &str) -> Expr {
388 let wrapped = format!("SELECT {}", sql);
389 let ast = Parser::parse_sql(&wrapped).expect("sql_expr: failed to parse SQL expression");
390 if let Expression::Select(s) = &ast[0] {
391 if let Some(first) = s.expressions.first() {
392 return Expr(first.clone());
393 }
394 }
395 panic!("sql_expr: failed to extract expression from parsed SQL");
396}
397
398pub fn condition(sql: &str) -> Expr {
407 sql_expr(sql)
408}
409
410pub fn count(expr: Expr) -> Expr {
418 Expr(Expression::Count(Box::new(CountFunc {
419 this: Some(expr.0),
420 star: false,
421 distinct: false,
422 filter: None,
423 ignore_nulls: None,
424 original_name: None,
425 inferred_type: None,
426 })))
427}
428
429pub fn count_star() -> Expr {
431 Expr(Expression::Count(Box::new(CountFunc {
432 this: None,
433 star: true,
434 distinct: false,
435 filter: None,
436 ignore_nulls: None,
437 original_name: None,
438 inferred_type: None,
439 })))
440}
441
442pub fn count_distinct(expr: Expr) -> Expr {
444 Expr(Expression::Count(Box::new(CountFunc {
445 this: Some(expr.0),
446 star: false,
447 distinct: true,
448 filter: None,
449 ignore_nulls: None,
450 original_name: None,
451 inferred_type: None,
452 })))
453}
454
455pub fn sum(expr: Expr) -> Expr {
457 Expr(Expression::Sum(Box::new(AggFunc {
458 this: expr.0,
459 distinct: false,
460 filter: None,
461 order_by: vec![],
462 name: None,
463 ignore_nulls: None,
464 having_max: None,
465 limit: None,
466 inferred_type: None,
467 })))
468}
469
470pub fn avg(expr: Expr) -> Expr {
472 Expr(Expression::Avg(Box::new(AggFunc {
473 this: expr.0,
474 distinct: false,
475 filter: None,
476 order_by: vec![],
477 name: None,
478 ignore_nulls: None,
479 having_max: None,
480 limit: None,
481 inferred_type: None,
482 })))
483}
484
485pub fn min_(expr: Expr) -> Expr {
487 Expr(Expression::Min(Box::new(AggFunc {
488 this: expr.0,
489 distinct: false,
490 filter: None,
491 order_by: vec![],
492 name: None,
493 ignore_nulls: None,
494 having_max: None,
495 limit: None,
496 inferred_type: None,
497 })))
498}
499
500pub fn max_(expr: Expr) -> Expr {
502 Expr(Expression::Max(Box::new(AggFunc {
503 this: expr.0,
504 distinct: false,
505 filter: None,
506 order_by: vec![],
507 name: None,
508 ignore_nulls: None,
509 having_max: None,
510 limit: None,
511 inferred_type: None,
512 })))
513}
514
515pub fn approx_distinct(expr: Expr) -> Expr {
517 Expr(Expression::ApproxDistinct(Box::new(AggFunc {
518 this: expr.0,
519 distinct: false,
520 filter: None,
521 order_by: vec![],
522 name: None,
523 ignore_nulls: None,
524 having_max: None,
525 limit: None,
526 inferred_type: None,
527 })))
528}
529
530pub fn upper(expr: Expr) -> Expr {
534 Expr(Expression::Upper(Box::new(UnaryFunc::new(expr.0))))
535}
536
537pub fn lower(expr: Expr) -> Expr {
539 Expr(Expression::Lower(Box::new(UnaryFunc::new(expr.0))))
540}
541
542pub fn length(expr: Expr) -> Expr {
544 Expr(Expression::Length(Box::new(UnaryFunc::new(expr.0))))
545}
546
547pub fn trim(expr: Expr) -> Expr {
549 Expr(Expression::Trim(Box::new(TrimFunc {
550 this: expr.0,
551 characters: None,
552 position: TrimPosition::Both,
553 sql_standard_syntax: false,
554 position_explicit: false,
555 inferred_type: None,
556 })))
557}
558
559pub fn ltrim(expr: Expr) -> Expr {
561 Expr(Expression::LTrim(Box::new(UnaryFunc::new(expr.0))))
562}
563
564pub fn rtrim(expr: Expr) -> Expr {
566 Expr(Expression::RTrim(Box::new(UnaryFunc::new(expr.0))))
567}
568
569pub fn reverse(expr: Expr) -> Expr {
571 Expr(Expression::Reverse(Box::new(UnaryFunc::new(expr.0))))
572}
573
574pub fn initcap(expr: Expr) -> Expr {
576 Expr(Expression::Initcap(Box::new(UnaryFunc::new(expr.0))))
577}
578
579pub fn substring(expr: Expr, start: Expr, len: Option<Expr>) -> Expr {
581 Expr(Expression::Substring(Box::new(SubstringFunc {
582 this: expr.0,
583 start: start.0,
584 length: len.map(|l| l.0),
585 from_for_syntax: false,
586 })))
587}
588
589pub fn replace_(expr: Expr, old: Expr, new: Expr) -> Expr {
592 Expr(Expression::Replace(Box::new(ReplaceFunc {
593 this: expr.0,
594 old: old.0,
595 new: new.0,
596 })))
597}
598
599pub fn concat_ws(separator: Expr, exprs: impl IntoIterator<Item = Expr>) -> Expr {
601 Expr(Expression::ConcatWs(Box::new(ConcatWs {
602 separator: separator.0,
603 expressions: exprs.into_iter().map(|e| e.0).collect(),
604 })))
605}
606
607pub fn coalesce(exprs: impl IntoIterator<Item = Expr>) -> Expr {
611 Expr(Expression::Coalesce(Box::new(VarArgFunc {
612 expressions: exprs.into_iter().map(|e| e.0).collect(),
613 original_name: None,
614 inferred_type: None,
615 })))
616}
617
618pub fn null_if(expr1: Expr, expr2: Expr) -> Expr {
620 Expr(Expression::NullIf(Box::new(BinaryFunc {
621 this: expr1.0,
622 expression: expr2.0,
623 original_name: None,
624 inferred_type: None,
625 })))
626}
627
628pub fn if_null(expr: Expr, fallback: Expr) -> Expr {
630 Expr(Expression::IfNull(Box::new(BinaryFunc {
631 this: expr.0,
632 expression: fallback.0,
633 original_name: None,
634 inferred_type: None,
635 })))
636}
637
638pub fn abs(expr: Expr) -> Expr {
642 Expr(Expression::Abs(Box::new(UnaryFunc::new(expr.0))))
643}
644
645pub fn round(expr: Expr, decimals: Option<Expr>) -> Expr {
647 Expr(Expression::Round(Box::new(RoundFunc {
648 this: expr.0,
649 decimals: decimals.map(|d| d.0),
650 })))
651}
652
653pub fn floor(expr: Expr) -> Expr {
655 Expr(Expression::Floor(Box::new(FloorFunc {
656 this: expr.0,
657 scale: None,
658 to: None,
659 })))
660}
661
662pub fn ceil(expr: Expr) -> Expr {
664 Expr(Expression::Ceil(Box::new(CeilFunc {
665 this: expr.0,
666 decimals: None,
667 to: None,
668 })))
669}
670
671pub fn power(base: Expr, exponent: Expr) -> Expr {
673 Expr(Expression::Power(Box::new(BinaryFunc {
674 this: base.0,
675 expression: exponent.0,
676 original_name: None,
677 inferred_type: None,
678 })))
679}
680
681pub fn sqrt(expr: Expr) -> Expr {
683 Expr(Expression::Sqrt(Box::new(UnaryFunc::new(expr.0))))
684}
685
686pub fn ln(expr: Expr) -> Expr {
688 Expr(Expression::Ln(Box::new(UnaryFunc::new(expr.0))))
689}
690
691pub fn exp_(expr: Expr) -> Expr {
693 Expr(Expression::Exp(Box::new(UnaryFunc::new(expr.0))))
694}
695
696pub fn sign(expr: Expr) -> Expr {
698 Expr(Expression::Sign(Box::new(UnaryFunc::new(expr.0))))
699}
700
701pub fn greatest(exprs: impl IntoIterator<Item = Expr>) -> Expr {
703 Expr(Expression::Greatest(Box::new(VarArgFunc {
704 expressions: exprs.into_iter().map(|e| e.0).collect(),
705 original_name: None,
706 inferred_type: None,
707 })))
708}
709
710pub fn least(exprs: impl IntoIterator<Item = Expr>) -> Expr {
712 Expr(Expression::Least(Box::new(VarArgFunc {
713 expressions: exprs.into_iter().map(|e| e.0).collect(),
714 original_name: None,
715 inferred_type: None,
716 })))
717}
718
719pub fn current_date_() -> Expr {
723 Expr(Expression::CurrentDate(CurrentDate))
724}
725
726pub fn current_time_() -> Expr {
728 Expr(Expression::CurrentTime(CurrentTime { precision: None }))
729}
730
731pub fn current_timestamp_() -> Expr {
733 Expr(Expression::CurrentTimestamp(CurrentTimestamp {
734 precision: None,
735 sysdate: false,
736 }))
737}
738
739pub fn extract_(field: &str, expr: Expr) -> Expr {
741 Expr(Expression::Extract(Box::new(ExtractFunc {
742 this: expr.0,
743 field: parse_datetime_field(field),
744 })))
745}
746
747fn parse_datetime_field(field: &str) -> DateTimeField {
749 match field.to_uppercase().as_str() {
750 "YEAR" => DateTimeField::Year,
751 "MONTH" => DateTimeField::Month,
752 "DAY" => DateTimeField::Day,
753 "HOUR" => DateTimeField::Hour,
754 "MINUTE" => DateTimeField::Minute,
755 "SECOND" => DateTimeField::Second,
756 "MILLISECOND" => DateTimeField::Millisecond,
757 "MICROSECOND" => DateTimeField::Microsecond,
758 "DOW" | "DAYOFWEEK" => DateTimeField::DayOfWeek,
759 "DOY" | "DAYOFYEAR" => DateTimeField::DayOfYear,
760 "WEEK" => DateTimeField::Week,
761 "QUARTER" => DateTimeField::Quarter,
762 "EPOCH" => DateTimeField::Epoch,
763 "TIMEZONE" => DateTimeField::Timezone,
764 "TIMEZONE_HOUR" => DateTimeField::TimezoneHour,
765 "TIMEZONE_MINUTE" => DateTimeField::TimezoneMinute,
766 "DATE" => DateTimeField::Date,
767 "TIME" => DateTimeField::Time,
768 other => DateTimeField::Custom(other.to_string()),
769 }
770}
771
772pub fn row_number() -> Expr {
776 Expr(Expression::RowNumber(RowNumber))
777}
778
779pub fn rank_() -> Expr {
781 Expr(Expression::Rank(Rank {
782 order_by: None,
783 args: vec![],
784 }))
785}
786
787pub fn dense_rank() -> Expr {
789 Expr(Expression::DenseRank(DenseRank { args: vec![] }))
790}
791
792pub fn select<I, E>(expressions: I) -> SelectBuilder
819where
820 I: IntoIterator<Item = E>,
821 E: IntoExpr,
822{
823 SelectBuilder::new().select_cols(expressions)
824}
825
826pub fn from(table_name: &str) -> SelectBuilder {
841 SelectBuilder::new().from(table_name)
842}
843
844pub fn delete(table_name: &str) -> DeleteBuilder {
857 DeleteBuilder {
858 delete: Delete {
859 table: builder_table_ref(table_name),
860 hint: None,
861 on_cluster: None,
862 alias: None,
863 alias_explicit_as: false,
864 using: Vec::new(),
865 where_clause: None,
866 output: None,
867 leading_comments: Vec::new(),
868 with: None,
869 limit: None,
870 order_by: None,
871 returning: Vec::new(),
872 tables: Vec::new(),
873 tables_from_using: false,
874 joins: Vec::new(),
875 force_index: None,
876 no_from: false,
877 },
878 }
879}
880
881pub fn insert_into(table_name: &str) -> InsertBuilder {
898 InsertBuilder {
899 insert: Insert {
900 table: builder_table_ref(table_name),
901 columns: Vec::new(),
902 values: Vec::new(),
903 query: None,
904 overwrite: false,
905 partition: Vec::new(),
906 directory: None,
907 returning: Vec::new(),
908 output: None,
909 on_conflict: None,
910 leading_comments: Vec::new(),
911 if_exists: false,
912 with: None,
913 ignore: false,
914 source_alias: None,
915 alias: None,
916 alias_explicit_as: false,
917 default_values: false,
918 by_name: false,
919 conflict_action: None,
920 is_replace: false,
921 hint: None,
922 replace_where: None,
923 source: None,
924 function_target: None,
925 partition_by: None,
926 settings: Vec::new(),
927 },
928 }
929}
930
931pub fn update(table_name: &str) -> UpdateBuilder {
949 UpdateBuilder {
950 update: Update {
951 table: builder_table_ref(table_name),
952 hint: None,
953 extra_tables: Vec::new(),
954 table_joins: Vec::new(),
955 set: Vec::new(),
956 from_clause: None,
957 from_joins: Vec::new(),
958 where_clause: None,
959 returning: Vec::new(),
960 output: None,
961 with: None,
962 leading_comments: Vec::new(),
963 limit: None,
964 order_by: None,
965 from_before_set: false,
966 },
967 }
968}
969
970#[derive(Debug, Clone)]
995pub struct Expr(pub Expression);
996
997impl Expr {
998 pub fn into_inner(self) -> Expression {
1000 self.0
1001 }
1002
1003 pub fn to_sql(&self) -> String {
1007 generate_builder_sql(&self.0)
1008 }
1009
1010 pub fn eq(self, other: Expr) -> Expr {
1014 Expr(engine::binary(engine::BinaryKind::Eq, self.0, other.0))
1015 }
1016
1017 pub fn neq(self, other: Expr) -> Expr {
1019 Expr(engine::binary(engine::BinaryKind::Neq, self.0, other.0))
1020 }
1021
1022 pub fn lt(self, other: Expr) -> Expr {
1024 Expr(engine::binary(engine::BinaryKind::Lt, self.0, other.0))
1025 }
1026
1027 pub fn lte(self, other: Expr) -> Expr {
1029 Expr(engine::binary(engine::BinaryKind::Lte, self.0, other.0))
1030 }
1031
1032 pub fn gt(self, other: Expr) -> Expr {
1034 Expr(engine::binary(engine::BinaryKind::Gt, self.0, other.0))
1035 }
1036
1037 pub fn gte(self, other: Expr) -> Expr {
1039 Expr(engine::binary(engine::BinaryKind::Gte, self.0, other.0))
1040 }
1041
1042 pub fn and(self, other: Expr) -> Expr {
1046 Expr(engine::binary(engine::BinaryKind::And, self.0, other.0))
1047 }
1048
1049 pub fn or(self, other: Expr) -> Expr {
1051 Expr(engine::binary(engine::BinaryKind::Or, self.0, other.0))
1052 }
1053
1054 pub fn not(self) -> Expr {
1056 Expr(engine::unary(engine::UnaryKind::Not, self.0))
1057 }
1058
1059 pub fn xor(self, other: Expr) -> Expr {
1061 Expr(engine::binary(engine::BinaryKind::Xor, self.0, other.0))
1062 }
1063
1064 pub fn add(self, other: Expr) -> Expr {
1068 Expr(engine::binary(engine::BinaryKind::Add, self.0, other.0))
1069 }
1070
1071 pub fn sub(self, other: Expr) -> Expr {
1073 Expr(engine::binary(engine::BinaryKind::Sub, self.0, other.0))
1074 }
1075
1076 pub fn mul(self, other: Expr) -> Expr {
1078 Expr(engine::binary(engine::BinaryKind::Mul, self.0, other.0))
1079 }
1080
1081 pub fn div(self, other: Expr) -> Expr {
1083 Expr(engine::binary(engine::BinaryKind::Div, self.0, other.0))
1084 }
1085
1086 pub fn modulo(self, other: Expr) -> Expr {
1088 Expr(engine::binary(engine::BinaryKind::Mod, self.0, other.0))
1089 }
1090
1091 pub fn neg(self) -> Expr {
1093 Expr(engine::unary(engine::UnaryKind::Neg, self.0))
1094 }
1095
1096 pub fn is(self, other: Expr) -> Expr {
1098 Expr(engine::binary(engine::BinaryKind::Is, self.0, other.0))
1099 }
1100
1101 pub fn is_null(self) -> Expr {
1105 Expr(engine::unary(engine::UnaryKind::IsNull, self.0))
1106 }
1107
1108 pub fn is_not_null(self) -> Expr {
1110 Expr(engine::unary(engine::UnaryKind::IsNotNull, self.0))
1111 }
1112
1113 pub fn in_list(self, values: impl IntoIterator<Item = Expr>) -> Expr {
1117 Expr(Expression::In(Box::new(In {
1118 this: self.0,
1119 expressions: values.into_iter().map(|v| v.0).collect(),
1120 query: None,
1121 not: false,
1122 global: false,
1123 unnest: None,
1124 is_field: false,
1125 })))
1126 }
1127
1128 pub fn between(self, low: Expr, high: Expr) -> Expr {
1130 Expr(Expression::Between(Box::new(Between {
1131 this: self.0,
1132 low: low.0,
1133 high: high.0,
1134 not: false,
1135 symmetric: None,
1136 })))
1137 }
1138
1139 pub fn like(self, pattern: Expr) -> Expr {
1141 Expr(engine::binary(engine::BinaryKind::Like, self.0, pattern.0))
1142 }
1143
1144 pub fn alias(self, name: &str) -> Expr {
1146 alias(self, name)
1147 }
1148
1149 pub fn cast(self, to: &str) -> Expr {
1153 cast(self, to)
1154 }
1155
1156 pub fn asc(self) -> Expr {
1161 Expr(Expression::Ordered(Box::new(Ordered {
1162 this: self.0,
1163 desc: false,
1164 nulls_first: None,
1165 explicit_asc: true,
1166 with_fill: None,
1167 })))
1168 }
1169
1170 pub fn desc(self) -> Expr {
1174 Expr(Expression::Ordered(Box::new(Ordered {
1175 this: self.0,
1176 desc: true,
1177 nulls_first: None,
1178 explicit_asc: false,
1179 with_fill: None,
1180 })))
1181 }
1182
1183 pub fn ilike(self, pattern: Expr) -> Expr {
1188 Expr(engine::binary(engine::BinaryKind::ILike, self.0, pattern.0))
1189 }
1190
1191 pub fn rlike(self, pattern: Expr) -> Expr {
1196 Expr(engine::binary(engine::BinaryKind::RLike, self.0, pattern.0))
1197 }
1198
1199 pub fn not_in(self, values: impl IntoIterator<Item = Expr>) -> Expr {
1203 Expr(Expression::In(Box::new(In {
1204 this: self.0,
1205 expressions: values.into_iter().map(|v| v.0).collect(),
1206 query: None,
1207 not: true,
1208 global: false,
1209 unnest: None,
1210 is_field: false,
1211 })))
1212 }
1213}
1214
1215pub struct SelectBuilder {
1241 select: Select,
1242}
1243
1244impl SelectBuilder {
1245 fn new() -> Self {
1246 SelectBuilder {
1247 select: Select::new(),
1248 }
1249 }
1250
1251 fn edit(mut self, edit: impl FnOnce(&mut Expression)) -> Self {
1252 let mut expression = Expression::Select(Box::new(self.select));
1253 edit(&mut expression);
1254 self.select = match expression {
1255 Expression::Select(select) => *select,
1256 _ => unreachable!("select builder engine changed the expression kind"),
1257 };
1258 self
1259 }
1260
1261 fn join_with_kind(self, table_name: &str, on: Option<Expr>, kind: JoinKind) -> Self {
1262 let join = Join {
1263 kind,
1264 this: Expression::Table(Box::new(builder_table_ref(table_name))),
1265 on: on.map(|expression| expression.0),
1266 using: Vec::new(),
1267 use_inner_keyword: false,
1268 use_outer_keyword: false,
1269 deferred_condition: false,
1270 join_hint: None,
1271 match_condition: None,
1272 pivots: Vec::new(),
1273 comments: Vec::new(),
1274 nesting_group: 0,
1275 directed: false,
1276 };
1277 self.edit(|expression| {
1278 engine::append_join(expression, join).expect("select builder accepts JOIN clauses")
1279 })
1280 }
1281
1282 pub fn select_cols<I, E>(self, expressions: I) -> Self
1287 where
1288 I: IntoIterator<Item = E>,
1289 E: IntoExpr,
1290 {
1291 self.select_cols_with_options(expressions, ClauseOptions::default())
1292 }
1293
1294 pub fn select_cols_with_options<I, E>(self, expressions: I, options: ClauseOptions) -> Self
1296 where
1297 I: IntoIterator<Item = E>,
1298 E: IntoExpr,
1299 {
1300 let values = expressions
1301 .into_iter()
1302 .map(|expression| expression.into_expr().0)
1303 .collect();
1304 self.edit(|expression| {
1305 engine::append_select(expression, values, options.append)
1306 .expect("select builder accepts SELECT clauses")
1307 })
1308 }
1309
1310 pub fn from(self, table_name: &str) -> Self {
1312 self.edit(|expression| {
1313 engine::set_from(
1314 expression,
1315 vec![Expression::Table(Box::new(builder_table_ref(table_name)))],
1316 )
1317 .expect("select builder accepts FROM clauses")
1318 })
1319 }
1320
1321 pub fn from_expr(self, expr: Expr) -> Self {
1326 self.edit(|expression| {
1327 engine::set_from(expression, vec![expr.0]).expect("select builder accepts FROM clauses")
1328 })
1329 }
1330
1331 pub fn join(self, table_name: &str, on: Expr) -> Self {
1333 self.join_with_kind(table_name, Some(on), JoinKind::Inner)
1334 }
1335
1336 pub fn left_join(self, table_name: &str, on: Expr) -> Self {
1338 self.join_with_kind(table_name, Some(on), JoinKind::Left)
1339 }
1340
1341 pub fn where_(self, condition: Expr) -> Self {
1343 self.where_with_options(condition, ClauseOptions::default())
1344 }
1345
1346 pub fn where_with_options(self, condition: Expr, options: ClauseOptions) -> Self {
1348 self.edit(|expression| {
1349 engine::apply_where(expression, condition.0, options.append)
1350 .expect("select builder accepts WHERE clauses")
1351 })
1352 }
1353
1354 pub fn group_by<I, E>(self, expressions: I) -> Self
1356 where
1357 I: IntoIterator<Item = E>,
1358 E: IntoExpr,
1359 {
1360 self.group_by_with_options(expressions, ClauseOptions::default())
1361 }
1362
1363 pub fn group_by_with_options<I, E>(self, expressions: I, options: ClauseOptions) -> Self
1365 where
1366 I: IntoIterator<Item = E>,
1367 E: IntoExpr,
1368 {
1369 let values = expressions
1370 .into_iter()
1371 .map(|expression| expression.into_expr().0)
1372 .collect();
1373 self.edit(|expression| {
1374 engine::apply_group_by(expression, values, options.append)
1375 .expect("select builder accepts GROUP BY clauses")
1376 })
1377 }
1378
1379 pub fn having(self, condition: Expr) -> Self {
1381 self.having_with_options(condition, ClauseOptions::default())
1382 }
1383
1384 pub fn having_with_options(self, condition: Expr, options: ClauseOptions) -> Self {
1386 self.edit(|expression| {
1387 engine::apply_having(expression, condition.0, options.append)
1388 .expect("select builder accepts HAVING clauses")
1389 })
1390 }
1391
1392 pub fn order_by<I, E>(self, expressions: I) -> Self
1398 where
1399 I: IntoIterator<Item = E>,
1400 E: IntoExpr,
1401 {
1402 self.order_by_with_options(expressions, ClauseOptions::default())
1403 }
1404
1405 pub fn order_by_with_options<I, E>(self, expressions: I, options: ClauseOptions) -> Self
1407 where
1408 I: IntoIterator<Item = E>,
1409 E: IntoExpr,
1410 {
1411 let values = expressions
1412 .into_iter()
1413 .map(|expression| engine::ordered(expression.into_expr().0))
1414 .collect();
1415 self.edit(|expression| {
1416 engine::apply_order_by(expression, values, options.append)
1417 .expect("select builder accepts ORDER BY clauses")
1418 })
1419 }
1420
1421 pub fn sort_by<I, E>(self, expressions: I) -> Self
1428 where
1429 I: IntoIterator<Item = E>,
1430 E: IntoExpr,
1431 {
1432 self.sort_by_with_options(expressions, ClauseOptions::default())
1433 }
1434
1435 pub fn sort_by_with_options<I, E>(self, expressions: I, options: ClauseOptions) -> Self
1437 where
1438 I: IntoIterator<Item = E>,
1439 E: IntoExpr,
1440 {
1441 let values = expressions
1442 .into_iter()
1443 .map(|expression| engine::ordered(expression.into_expr().0))
1444 .collect();
1445 self.edit(|expression| {
1446 engine::apply_sort_by(expression, values, options.append)
1447 .expect("select builder accepts SORT BY clauses")
1448 })
1449 }
1450
1451 pub fn limit(self, count: usize) -> Self {
1453 self.edit(|expression| {
1454 engine::apply_limit(
1455 expression,
1456 Expression::Literal(Box::new(Literal::Number(count.to_string()))),
1457 )
1458 .expect("select builder accepts LIMIT clauses")
1459 })
1460 }
1461
1462 pub fn offset(self, count: usize) -> Self {
1464 self.edit(|expression| {
1465 engine::apply_offset(
1466 expression,
1467 Expression::Literal(Box::new(Literal::Number(count.to_string()))),
1468 )
1469 .expect("select builder accepts OFFSET clauses")
1470 })
1471 }
1472
1473 pub fn distinct(self) -> Self {
1475 self.edit(|expression| {
1476 engine::apply_distinct(expression, true)
1477 .expect("select builder accepts DISTINCT clauses")
1478 })
1479 }
1480
1481 pub fn qualify(self, condition: Expr) -> Self {
1486 self.qualify_with_options(condition, ClauseOptions::default())
1487 }
1488
1489 pub fn qualify_with_options(self, condition: Expr, options: ClauseOptions) -> Self {
1491 self.edit(|expression| {
1492 engine::apply_qualify(expression, condition.0, options.append)
1493 .expect("select builder accepts QUALIFY clauses")
1494 })
1495 }
1496
1497 pub fn right_join(self, table_name: &str, on: Expr) -> Self {
1499 self.join_with_kind(table_name, Some(on), JoinKind::Right)
1500 }
1501
1502 pub fn full_join(self, table_name: &str, on: Expr) -> Self {
1504 self.join_with_kind(table_name, Some(on), JoinKind::Full)
1505 }
1506
1507 pub fn cross_join(self, table_name: &str) -> Self {
1509 self.join_with_kind(table_name, None, JoinKind::Cross)
1510 }
1511
1512 pub fn lateral_view<S: AsRef<str>>(
1519 self,
1520 table_function: Expr,
1521 table_alias: &str,
1522 column_aliases: impl IntoIterator<Item = S>,
1523 ) -> Self {
1524 self.lateral_view_with_options(
1525 table_function,
1526 table_alias,
1527 column_aliases,
1528 LateralViewOptions::default(),
1529 )
1530 }
1531
1532 pub fn lateral_view_with_options<S: AsRef<str>>(
1534 self,
1535 table_function: Expr,
1536 table_alias: &str,
1537 column_aliases: impl IntoIterator<Item = S>,
1538 options: LateralViewOptions,
1539 ) -> Self {
1540 let aliases = column_aliases
1541 .into_iter()
1542 .map(|c| builder_identifier(c.as_ref()))
1543 .collect();
1544 self.edit(|expression| {
1545 engine::append_lateral_view(
1546 expression,
1547 table_function.0,
1548 Some(builder_identifier(table_alias)),
1549 aliases,
1550 options.outer,
1551 )
1552 .expect("select builder accepts LATERAL VIEW clauses")
1553 })
1554 }
1555
1556 pub fn window(self, name: &str, def: WindowDefBuilder) -> Self {
1562 let order_by = def.order_by;
1563 self.edit(|expression| {
1564 engine::append_window(
1565 expression,
1566 builder_identifier(name),
1567 def.partition_by,
1568 order_by,
1569 )
1570 .expect("select builder accepts WINDOW clauses")
1571 })
1572 }
1573
1574 pub fn for_update(self) -> Self {
1579 self.edit(|expression| {
1580 engine::append_lock(expression, engine::LockKind::Update)
1581 .expect("select builder accepts locking clauses")
1582 })
1583 }
1584
1585 pub fn for_share(self) -> Self {
1590 self.edit(|expression| {
1591 engine::append_lock(expression, engine::LockKind::Share)
1592 .expect("select builder accepts locking clauses")
1593 })
1594 }
1595
1596 pub fn hint(self, hint_text: &str) -> Self {
1601 self.edit(|expression| {
1602 engine::append_hint(expression, hint_text.to_string())
1603 .expect("select builder accepts query hints")
1604 })
1605 }
1606
1607 pub fn ctas(self, table_name: &str) -> Expression {
1623 self.ctas_with_options(table_name, CtasOptions::default())
1624 }
1625
1626 pub fn ctas_with_options(self, table_name: &str, options: CtasOptions) -> Expression {
1628 engine::create_table_as(
1629 self.build(),
1630 builder_table_ref(table_name),
1631 options.replace,
1632 options.temporary,
1633 )
1634 .expect("select builder CTAS source is a query")
1635 }
1636
1637 pub fn union(self, other: SelectBuilder) -> SetOpBuilder {
1641 SetOpBuilder::new(SetOpKind::Union, self, other, false)
1642 }
1643
1644 pub fn union_all(self, other: SelectBuilder) -> SetOpBuilder {
1648 SetOpBuilder::new(SetOpKind::Union, self, other, true)
1649 }
1650
1651 pub fn intersect(self, other: SelectBuilder) -> SetOpBuilder {
1655 SetOpBuilder::new(SetOpKind::Intersect, self, other, false)
1656 }
1657
1658 pub fn except_(self, other: SelectBuilder) -> SetOpBuilder {
1662 SetOpBuilder::new(SetOpKind::Except, self, other, false)
1663 }
1664
1665 pub fn build(self) -> Expression {
1667 Expression::Select(Box::new(self.select))
1668 }
1669
1670 pub fn to_sql(self) -> String {
1675 generate_builder_sql(&self.build())
1676 }
1677}
1678
1679pub struct DeleteBuilder {
1688 delete: Delete,
1689}
1690
1691impl DeleteBuilder {
1692 pub fn where_(self, condition: Expr) -> Self {
1694 self.where_with_options(condition, ClauseOptions::default())
1695 }
1696
1697 pub fn where_with_options(mut self, condition: Expr, options: ClauseOptions) -> Self {
1699 let mut expression = Expression::Delete(Box::new(self.delete));
1700 engine::apply_where(&mut expression, condition.0, options.append)
1701 .expect("delete builder accepts WHERE clauses");
1702 self.delete = match expression {
1703 Expression::Delete(delete) => *delete,
1704 _ => unreachable!("delete builder engine changed the expression kind"),
1705 };
1706 self
1707 }
1708
1709 pub fn build(self) -> Expression {
1711 Expression::Delete(Box::new(self.delete))
1712 }
1713
1714 pub fn to_sql(self) -> String {
1716 generate_builder_sql(&self.build())
1717 }
1718}
1719
1720pub struct InsertBuilder {
1731 insert: Insert,
1732}
1733
1734impl InsertBuilder {
1735 fn edit(mut self, edit: impl FnOnce(&mut Expression)) -> Self {
1736 let mut expression = Expression::Insert(Box::new(self.insert));
1737 edit(&mut expression);
1738 self.insert = match expression {
1739 Expression::Insert(insert) => *insert,
1740 _ => unreachable!("insert builder engine changed the expression kind"),
1741 };
1742 self
1743 }
1744
1745 pub fn columns<I, S>(self, columns: I) -> Self
1747 where
1748 I: IntoIterator<Item = S>,
1749 S: AsRef<str>,
1750 {
1751 let columns = columns
1752 .into_iter()
1753 .map(|c| builder_identifier(c.as_ref()))
1754 .collect();
1755 self.edit(|expression| {
1756 engine::set_insert_columns(expression, columns)
1757 .expect("insert builder accepts target columns")
1758 })
1759 }
1760
1761 pub fn values<I>(self, values: I) -> Self
1765 where
1766 I: IntoIterator<Item = Expr>,
1767 {
1768 let row = values.into_iter().map(|v| v.0).collect();
1769 self.edit(|expression| {
1770 engine::apply_insert_values(expression, vec![row], true)
1771 .expect("insert builder accepts VALUES clauses")
1772 })
1773 }
1774
1775 pub fn query(self, query: SelectBuilder) -> Self {
1779 self.edit(|expression| {
1780 engine::set_insert_query(expression, query.build())
1781 .expect("insert builder accepts query sources")
1782 })
1783 }
1784
1785 pub fn build(self) -> Expression {
1787 Expression::Insert(Box::new(self.insert))
1788 }
1789
1790 pub fn to_sql(self) -> String {
1792 generate_builder_sql(&self.build())
1793 }
1794}
1795
1796pub struct UpdateBuilder {
1806 update: Update,
1807}
1808
1809impl UpdateBuilder {
1810 fn edit(mut self, edit: impl FnOnce(&mut Expression)) -> Self {
1811 let mut expression = Expression::Update(Box::new(self.update));
1812 edit(&mut expression);
1813 self.update = match expression {
1814 Expression::Update(update) => *update,
1815 _ => unreachable!("update builder engine changed the expression kind"),
1816 };
1817 self
1818 }
1819
1820 pub fn set(self, column: &str, value: Expr) -> Self {
1824 self.edit(|expression| {
1825 engine::append_update_assignments(
1826 expression,
1827 vec![(builder_identifier(column), value.0)],
1828 )
1829 .expect("update builder accepts SET assignments")
1830 })
1831 }
1832
1833 pub fn where_(self, condition: Expr) -> Self {
1835 self.where_with_options(condition, ClauseOptions::default())
1836 }
1837
1838 pub fn where_with_options(mut self, condition: Expr, options: ClauseOptions) -> Self {
1840 let mut expression = Expression::Update(Box::new(self.update));
1841 engine::apply_where(&mut expression, condition.0, options.append)
1842 .expect("update builder accepts WHERE clauses");
1843 self.update = match expression {
1844 Expression::Update(update) => *update,
1845 _ => unreachable!("update builder engine changed the expression kind"),
1846 };
1847 self
1848 }
1849
1850 pub fn from(self, table_name: &str) -> Self {
1854 self.edit(|expression| {
1855 engine::set_from(
1856 expression,
1857 vec![Expression::Table(Box::new(builder_table_ref(table_name)))],
1858 )
1859 .expect("update builder accepts FROM clauses")
1860 })
1861 }
1862
1863 pub fn build(self) -> Expression {
1865 Expression::Update(Box::new(self.update))
1866 }
1867
1868 pub fn to_sql(self) -> String {
1870 generate_builder_sql(&self.build())
1871 }
1872}
1873
1874pub fn case() -> CaseBuilder {
1899 CaseBuilder {
1900 operand: None,
1901 whens: Vec::new(),
1902 else_: None,
1903 }
1904}
1905
1906pub fn case_of(operand: Expr) -> CaseBuilder {
1927 CaseBuilder {
1928 operand: Some(operand.0),
1929 whens: Vec::new(),
1930 else_: None,
1931 }
1932}
1933
1934pub struct CaseBuilder {
1942 operand: Option<Expression>,
1943 whens: Vec<(Expression, Expression)>,
1944 else_: Option<Expression>,
1945}
1946
1947impl CaseBuilder {
1948 pub fn when(mut self, condition: Expr, result: Expr) -> Self {
1953 self.whens.push((condition.0, result.0));
1954 self
1955 }
1956
1957 pub fn else_(mut self, result: Expr) -> Self {
1962 self.else_ = Some(result.0);
1963 self
1964 }
1965
1966 pub fn build(self) -> Expr {
1968 Expr(self.build_expr())
1969 }
1970
1971 pub fn build_expr(self) -> Expression {
1976 let mut expression = engine::case(self.operand);
1977 for (condition, result) in self.whens {
1978 engine::append_case_when(&mut expression, condition, result)
1979 .expect("case builder accepts WHEN branches");
1980 }
1981 if let Some(result) = self.else_ {
1982 engine::set_case_else(&mut expression, result)
1983 .expect("case builder accepts ELSE branches");
1984 }
1985 expression
1986 }
1987}
1988
1989pub fn subquery(query: SelectBuilder, alias_name: &str) -> Expr {
2013 subquery_expr(query.build(), alias_name)
2014}
2015
2016pub fn subquery_expr(expr: Expression, alias_name: &str) -> Expr {
2021 Expr(
2022 engine::subquery(expr, Some(builder_identifier(alias_name)), true)
2023 .expect("subquery builder source is a query"),
2024 )
2025}
2026
2027#[derive(Debug, Clone, Copy)]
2033enum SetOpKind {
2034 Union,
2035 Intersect,
2036 Except,
2037}
2038
2039pub struct SetOpBuilder {
2060 kind: SetOpKind,
2061 left: Expression,
2062 right: Expression,
2063 all: bool,
2064 order_by: Option<OrderBy>,
2065 limit: Option<Box<Expression>>,
2066 offset: Option<Box<Expression>>,
2067}
2068
2069impl SetOpBuilder {
2070 fn new(kind: SetOpKind, left: SelectBuilder, right: SelectBuilder, all: bool) -> Self {
2071 SetOpBuilder {
2072 kind,
2073 left: left.build(),
2074 right: right.build(),
2075 all,
2076 order_by: None,
2077 limit: None,
2078 offset: None,
2079 }
2080 }
2081
2082 pub fn order_by<I, E>(self, expressions: I) -> Self
2087 where
2088 I: IntoIterator<Item = E>,
2089 E: IntoExpr,
2090 {
2091 self.order_by_with_options(expressions, ClauseOptions::default())
2092 }
2093
2094 pub fn order_by_with_options<I, E>(mut self, expressions: I, options: ClauseOptions) -> Self
2096 where
2097 I: IntoIterator<Item = E>,
2098 E: IntoExpr,
2099 {
2100 let values: Vec<_> = expressions
2101 .into_iter()
2102 .map(|expression| engine::ordered(expression.into_expr().0))
2103 .collect();
2104 if options.append {
2105 self.order_by
2106 .get_or_insert_with(|| OrderBy {
2107 siblings: false,
2108 comments: Vec::new(),
2109 expressions: Vec::new(),
2110 })
2111 .expressions
2112 .extend(values);
2113 } else {
2114 self.order_by = Some(OrderBy {
2115 siblings: false,
2116 comments: Vec::new(),
2117 expressions: values,
2118 });
2119 }
2120 self
2121 }
2122
2123 pub fn limit(mut self, count: usize) -> Self {
2125 self.limit = Some(Box::new(Expression::Literal(Box::new(Literal::Number(
2126 count.to_string(),
2127 )))));
2128 self
2129 }
2130
2131 pub fn offset(mut self, count: usize) -> Self {
2133 self.offset = Some(Box::new(Expression::Literal(Box::new(Literal::Number(
2134 count.to_string(),
2135 )))));
2136 self
2137 }
2138
2139 pub fn build(self) -> Expression {
2144 let kind = match self.kind {
2145 SetOpKind::Union => engine::SetKind::Union,
2146 SetOpKind::Intersect => engine::SetKind::Intersect,
2147 SetOpKind::Except => engine::SetKind::Except,
2148 };
2149 let mut expression = engine::set_operation(kind, self.left, self.right, !self.all)
2150 .expect("set builder operands are queries");
2151 if let Some(order_by) = self.order_by {
2152 engine::apply_order_by(&mut expression, order_by.expressions, false)
2153 .expect("set operations accept ORDER BY clauses");
2154 }
2155 if let Some(limit) = self.limit {
2156 engine::apply_limit(&mut expression, *limit)
2157 .expect("set operations accept LIMIT clauses");
2158 }
2159 if let Some(offset) = self.offset {
2160 engine::apply_offset(&mut expression, *offset)
2161 .expect("set operations accept OFFSET clauses");
2162 }
2163 expression
2164 }
2165
2166 pub fn to_sql(self) -> String {
2168 generate_builder_sql(&self.build())
2169 }
2170}
2171
2172pub fn union(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2176 SetOpBuilder::new(SetOpKind::Union, left, right, false)
2177}
2178
2179pub fn union_all(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2183 SetOpBuilder::new(SetOpKind::Union, left, right, true)
2184}
2185
2186pub fn intersect(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2190 SetOpBuilder::new(SetOpKind::Intersect, left, right, false)
2191}
2192
2193pub fn intersect_all(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2197 SetOpBuilder::new(SetOpKind::Intersect, left, right, true)
2198}
2199
2200pub fn except_(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2204 SetOpBuilder::new(SetOpKind::Except, left, right, false)
2205}
2206
2207pub fn except_all(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2211 SetOpBuilder::new(SetOpKind::Except, left, right, true)
2212}
2213
2214pub struct WindowDefBuilder {
2239 partition_by: Vec<Expression>,
2240 order_by: Vec<Ordered>,
2241}
2242
2243impl WindowDefBuilder {
2244 pub fn new() -> Self {
2246 WindowDefBuilder {
2247 partition_by: Vec::new(),
2248 order_by: Vec::new(),
2249 }
2250 }
2251
2252 pub fn partition_by<I, E>(mut self, expressions: I) -> Self
2254 where
2255 I: IntoIterator<Item = E>,
2256 E: IntoExpr,
2257 {
2258 self.partition_by = expressions.into_iter().map(|e| e.into_expr().0).collect();
2259 self
2260 }
2261
2262 pub fn order_by<I, E>(mut self, expressions: I) -> Self
2267 where
2268 I: IntoIterator<Item = E>,
2269 E: IntoExpr,
2270 {
2271 self.order_by = expressions
2272 .into_iter()
2273 .map(|e| {
2274 let expr = e.into_expr().0;
2275 match expr {
2276 Expression::Ordered(o) => *o,
2277 other => Ordered {
2278 this: other,
2279 desc: false,
2280 nulls_first: None,
2281 explicit_asc: false,
2282 with_fill: None,
2283 },
2284 }
2285 })
2286 .collect();
2287 self
2288 }
2289}
2290
2291pub trait IntoExpr {
2310 fn into_expr(self) -> Expr;
2312}
2313
2314impl IntoExpr for Expr {
2315 fn into_expr(self) -> Expr {
2316 self
2317 }
2318}
2319
2320impl IntoExpr for &str {
2321 fn into_expr(self) -> Expr {
2323 col(self)
2324 }
2325}
2326
2327impl IntoExpr for String {
2328 fn into_expr(self) -> Expr {
2330 col(&self)
2331 }
2332}
2333
2334impl IntoExpr for Expression {
2335 fn into_expr(self) -> Expr {
2337 Expr(self)
2338 }
2339}
2340
2341pub trait IntoLiteral {
2356 fn into_literal(self) -> Expr;
2358}
2359
2360impl IntoLiteral for &str {
2361 fn into_literal(self) -> Expr {
2363 Expr(Expression::Literal(Box::new(Literal::String(
2364 self.to_string(),
2365 ))))
2366 }
2367}
2368
2369impl IntoLiteral for String {
2370 fn into_literal(self) -> Expr {
2372 Expr(Expression::Literal(Box::new(Literal::String(self))))
2373 }
2374}
2375
2376impl IntoLiteral for i64 {
2377 fn into_literal(self) -> Expr {
2379 Expr(Expression::Literal(Box::new(Literal::Number(
2380 self.to_string(),
2381 ))))
2382 }
2383}
2384
2385impl IntoLiteral for i32 {
2386 fn into_literal(self) -> Expr {
2388 Expr(Expression::Literal(Box::new(Literal::Number(
2389 self.to_string(),
2390 ))))
2391 }
2392}
2393
2394impl IntoLiteral for usize {
2395 fn into_literal(self) -> Expr {
2397 Expr(Expression::Literal(Box::new(Literal::Number(
2398 self.to_string(),
2399 ))))
2400 }
2401}
2402
2403impl IntoLiteral for f64 {
2404 fn into_literal(self) -> Expr {
2406 Expr(Expression::Literal(Box::new(Literal::Number(
2407 self.to_string(),
2408 ))))
2409 }
2410}
2411
2412impl IntoLiteral for bool {
2413 fn into_literal(self) -> Expr {
2415 Expr(Expression::Boolean(BooleanLiteral { value: self }))
2416 }
2417}
2418
2419pub fn merge_into(target: &str) -> MergeBuilder {
2441 MergeBuilder {
2442 expression: engine::merge(Expression::Table(Box::new(builder_table_ref(target)))),
2443 }
2444}
2445
2446pub struct MergeBuilder {
2450 expression: Expression,
2451}
2452
2453impl MergeBuilder {
2454 pub fn using(mut self, source: &str, on: Expr) -> Self {
2456 engine::set_merge_using(
2457 &mut self.expression,
2458 Expression::Table(Box::new(builder_table_ref(source))),
2459 on.0,
2460 )
2461 .expect("merge builder accepts a USING clause");
2462 self
2463 }
2464
2465 pub fn when_matched_update(mut self, assignments: Vec<(&str, Expr)>) -> Self {
2467 let assignments = assignments
2468 .into_iter()
2469 .map(|(column, value)| (builder_identifier(column), value.0))
2470 .collect();
2471 engine::append_merge_update(&mut self.expression, assignments, None)
2472 .expect("merge builder accepts matched update actions");
2473 self
2474 }
2475
2476 pub fn when_matched_update_where(
2478 mut self,
2479 condition: Expr,
2480 assignments: Vec<(&str, Expr)>,
2481 ) -> Self {
2482 let assignments = assignments
2483 .into_iter()
2484 .map(|(column, value)| (builder_identifier(column), value.0))
2485 .collect();
2486 engine::append_merge_update(&mut self.expression, assignments, Some(condition.0))
2487 .expect("merge builder accepts conditional matched update actions");
2488 self
2489 }
2490
2491 pub fn when_matched_delete(mut self) -> Self {
2493 engine::append_merge_delete(&mut self.expression, None)
2494 .expect("merge builder accepts matched delete actions");
2495 self
2496 }
2497
2498 pub fn when_matched_delete_where(mut self, condition: Expr) -> Self {
2500 engine::append_merge_delete(&mut self.expression, Some(condition.0))
2501 .expect("merge builder accepts conditional matched delete actions");
2502 self
2503 }
2504
2505 pub fn when_not_matched_insert(mut self, columns: &[&str], values: Vec<Expr>) -> Self {
2507 engine::append_merge_insert(
2508 &mut self.expression,
2509 columns
2510 .iter()
2511 .map(|column| builder_identifier(column))
2512 .collect(),
2513 values.into_iter().map(|value| value.0).collect(),
2514 None,
2515 )
2516 .expect("merge builder accepts not-matched insert actions");
2517 self
2518 }
2519
2520 pub fn when_not_matched_insert_where(
2522 mut self,
2523 condition: Expr,
2524 columns: &[&str],
2525 values: Vec<Expr>,
2526 ) -> Self {
2527 engine::append_merge_insert(
2528 &mut self.expression,
2529 columns
2530 .iter()
2531 .map(|column| builder_identifier(column))
2532 .collect(),
2533 values.into_iter().map(|value| value.0).collect(),
2534 Some(condition.0),
2535 )
2536 .expect("merge builder accepts conditional not-matched insert actions");
2537 self
2538 }
2539
2540 pub fn build(self) -> Expression {
2542 self.expression
2543 }
2544
2545 pub fn to_sql(self) -> String {
2547 generate_builder_sql(&self.build())
2548 }
2549}
2550
2551fn parse_simple_data_type(name: &str) -> DataType {
2552 let upper = name.trim().to_uppercase();
2553 match upper.as_str() {
2554 "INT" | "INTEGER" => DataType::Int {
2555 length: None,
2556 integer_spelling: upper == "INTEGER",
2557 },
2558 "BIGINT" => DataType::BigInt { length: None },
2559 "SMALLINT" => DataType::SmallInt { length: None },
2560 "TINYINT" => DataType::TinyInt { length: None },
2561 "FLOAT" => DataType::Float {
2562 precision: None,
2563 scale: None,
2564 real_spelling: false,
2565 },
2566 "DOUBLE" => DataType::Double {
2567 precision: None,
2568 scale: None,
2569 },
2570 "BOOLEAN" | "BOOL" => DataType::Boolean,
2571 "TEXT" => DataType::Text,
2572 "DATE" => DataType::Date,
2573 "TIMESTAMP" => DataType::Timestamp {
2574 precision: None,
2575 timezone: false,
2576 },
2577 "VARCHAR" => DataType::VarChar {
2578 length: None,
2579 parenthesized_length: false,
2580 },
2581 "CHAR" => DataType::Char { length: None },
2582 _ => {
2583 if let Ok(ast) =
2585 crate::parser::Parser::parse_sql(&format!("SELECT CAST(x AS {})", name))
2586 {
2587 if let Expression::Select(s) = &ast[0] {
2588 if let Some(Expression::Cast(c)) = s.expressions.first() {
2589 return c.to.clone();
2590 }
2591 }
2592 }
2593 DataType::Custom {
2595 name: name.to_string(),
2596 }
2597 }
2598 }
2599}
2600
2601#[cfg(test)]
2602mod tests {
2603 use super::*;
2604
2605 #[test]
2606 fn test_simple_select() {
2607 let sql = select(["id", "name"]).from("users").to_sql();
2608 assert_eq!(sql, "SELECT id, name FROM users");
2609 }
2610
2611 #[test]
2612 fn test_builder_quotes_unsafe_identifier_tokens() {
2613 let sql = select(["Name; DROP TABLE titanic"]).to_sql();
2614 assert_eq!(sql, r#"SELECT "Name; DROP TABLE titanic""#);
2615 }
2616
2617 #[test]
2618 fn test_builder_string_literal_requires_lit() {
2619 let sql = select([lit("Name; DROP TABLE titanic")]).to_sql();
2620 assert_eq!(sql, "SELECT 'Name; DROP TABLE titanic'");
2621 }
2622
2623 #[test]
2624 fn test_builder_quotes_unsafe_table_name_tokens() {
2625 let sql = select(["id"]).from("users; DROP TABLE x").to_sql();
2626 assert_eq!(sql, r#"SELECT id FROM "users; DROP TABLE x""#);
2627 }
2628
2629 #[test]
2630 fn test_select_star() {
2631 let sql = select([star()]).from("users").to_sql();
2632 assert_eq!(sql, "SELECT * FROM users");
2633 }
2634
2635 #[test]
2636 fn test_select_with_where() {
2637 let sql = select(["id", "name"])
2638 .from("users")
2639 .where_(col("age").gt(lit(18)))
2640 .to_sql();
2641 assert_eq!(sql, "SELECT id, name FROM users WHERE age > 18");
2642 }
2643
2644 #[test]
2645 fn test_select_with_join() {
2646 let sql = select(["u.id", "o.amount"])
2647 .from("users")
2648 .join("orders", col("u.id").eq(col("o.user_id")))
2649 .to_sql();
2650 assert_eq!(
2651 sql,
2652 "SELECT u.id, o.amount FROM users JOIN orders ON u.id = o.user_id"
2653 );
2654 }
2655
2656 #[test]
2657 fn test_select_with_group_by_having() {
2658 let sql = select([col("dept"), func("COUNT", [star()]).alias("cnt")])
2659 .from("employees")
2660 .group_by(["dept"])
2661 .having(func("COUNT", [star()]).gt(lit(5)))
2662 .to_sql();
2663 assert_eq!(
2664 sql,
2665 "SELECT dept, COUNT(*) AS cnt FROM employees GROUP BY dept HAVING COUNT(*) > 5"
2666 );
2667 }
2668
2669 #[test]
2670 fn test_select_with_order_limit_offset() {
2671 let sql = select(["id", "name"])
2672 .from("users")
2673 .order_by(["name"])
2674 .limit(10)
2675 .offset(20)
2676 .to_sql();
2677 assert_eq!(
2678 sql,
2679 "SELECT id, name FROM users ORDER BY name LIMIT 10 OFFSET 20"
2680 );
2681 }
2682
2683 #[test]
2684 fn test_select_distinct() {
2685 let sql = select(["name"]).from("users").distinct().to_sql();
2686 assert_eq!(sql, "SELECT DISTINCT name FROM users");
2687 }
2688
2689 #[test]
2690 fn test_insert_values() {
2691 let sql = insert_into("users")
2692 .columns(["id", "name"])
2693 .values([lit(1), lit("Alice")])
2694 .values([lit(2), lit("Bob")])
2695 .to_sql();
2696 assert_eq!(
2697 sql,
2698 "INSERT INTO users (id, name) VALUES (1, 'Alice'), (2, 'Bob')"
2699 );
2700 }
2701
2702 #[test]
2703 fn test_insert_select() {
2704 let sql = insert_into("archive")
2705 .columns(["id", "name"])
2706 .query(select(["id", "name"]).from("users"))
2707 .to_sql();
2708 assert_eq!(
2709 sql,
2710 "INSERT INTO archive (id, name) SELECT id, name FROM users"
2711 );
2712 }
2713
2714 #[test]
2715 fn test_update() {
2716 let sql = update("users")
2717 .set("name", lit("Bob"))
2718 .set("age", lit(30))
2719 .where_(col("id").eq(lit(1)))
2720 .to_sql();
2721 assert_eq!(sql, "UPDATE users SET name = 'Bob', age = 30 WHERE id = 1");
2722 }
2723
2724 #[test]
2725 fn test_delete() {
2726 let sql = delete("users").where_(col("id").eq(lit(1))).to_sql();
2727 assert_eq!(sql, "DELETE FROM users WHERE id = 1");
2728 }
2729
2730 #[test]
2731 fn test_complex_where() {
2732 let sql = select(["id"])
2733 .from("users")
2734 .where_(
2735 col("age")
2736 .gte(lit(18))
2737 .and(col("active").eq(boolean(true)))
2738 .and(col("name").like(lit("%test%"))),
2739 )
2740 .to_sql();
2741 assert_eq!(
2742 sql,
2743 "SELECT id FROM users WHERE age >= 18 AND active = TRUE AND name LIKE '%test%'"
2744 );
2745 }
2746
2747 #[test]
2748 fn test_in_list() {
2749 let sql = select(["id"])
2750 .from("users")
2751 .where_(col("status").in_list([lit("active"), lit("pending")]))
2752 .to_sql();
2753 assert_eq!(
2754 sql,
2755 "SELECT id FROM users WHERE status IN ('active', 'pending')"
2756 );
2757 }
2758
2759 #[test]
2760 fn test_between() {
2761 let sql = select(["id"])
2762 .from("orders")
2763 .where_(col("amount").between(lit(100), lit(500)))
2764 .to_sql();
2765 assert_eq!(
2766 sql,
2767 "SELECT id FROM orders WHERE amount BETWEEN 100 AND 500"
2768 );
2769 }
2770
2771 #[test]
2772 fn test_is_null() {
2773 let sql = select(["id"])
2774 .from("users")
2775 .where_(col("email").is_null())
2776 .to_sql();
2777 assert_eq!(sql, "SELECT id FROM users WHERE email IS NULL");
2778 }
2779
2780 #[test]
2781 fn test_arithmetic() {
2782 let sql = select([col("price").mul(col("quantity")).alias("total")])
2783 .from("items")
2784 .to_sql();
2785 assert_eq!(sql, "SELECT price * quantity AS total FROM items");
2786 }
2787
2788 #[test]
2789 fn test_nested_operator_grouping() {
2790 assert_eq!(
2791 or(col("a").eq(lit(1)), col("b").eq(lit(2)))
2792 .and(col("c").eq(lit(3)))
2793 .to_sql(),
2794 "(a = 1 OR b = 2) AND c = 3"
2795 );
2796 assert_eq!(
2797 col("a")
2798 .eq(lit(1))
2799 .and(or(col("b").eq(lit(2)), col("c").eq(lit(3))))
2800 .to_sql(),
2801 "a = 1 AND (b = 2 OR c = 3)"
2802 );
2803 assert_eq!(col("a").add(col("b")).mul(col("c")).to_sql(), "(a + b) * c");
2804 assert_eq!(col("a").mul(col("b").add(col("c"))).to_sql(), "a * (b + c)");
2805 assert_eq!(col("a").sub(col("b").sub(col("c"))).to_sql(), "a - (b - c)");
2806 assert_eq!(col("a").div(col("b").div(col("c"))).to_sql(), "a / (b / c)");
2807 }
2808
2809 #[test]
2810 fn test_cast() {
2811 let sql = select([col("id").cast("VARCHAR")]).from("users").to_sql();
2812 assert_eq!(sql, "SELECT CAST(id AS VARCHAR) FROM users");
2813 }
2814
2815 #[test]
2816 fn test_cast_int128() {
2817 for name in ["HUGEINT", "INT128"] {
2818 let Expression::Cast(cast) = col("value").cast(name).0 else {
2819 panic!("expected cast");
2820 };
2821 assert_eq!(cast.to, DataType::Int128);
2822 }
2823 }
2824
2825 #[test]
2826 fn test_cast_unsigned_integer_types() {
2827 for (name, expected) in [
2828 ("UTINYINT", DataType::UInt8),
2829 ("UINT8", DataType::UInt8),
2830 ("USMALLINT", DataType::UInt16),
2831 ("UINT16", DataType::UInt16),
2832 ("UINTEGER", DataType::UInt32),
2833 ("UINT32", DataType::UInt32),
2834 ("UBIGINT", DataType::UInt64),
2835 ("UINT64", DataType::UInt64),
2836 ("UHUGEINT", DataType::UInt128),
2837 ("UINT128", DataType::UInt128),
2838 ] {
2839 let Expression::Cast(cast) = col("value").cast(name).0 else {
2840 panic!("expected cast")
2841 };
2842 assert_eq!(cast.to, expected, "{name}");
2843 }
2844 }
2845
2846 #[test]
2847 fn test_from_starter() {
2848 let sql = from("users").select_cols(["id", "name"]).to_sql();
2849 assert_eq!(sql, "SELECT id, name FROM users");
2850 }
2851
2852 #[test]
2853 fn test_qualified_column() {
2854 let sql = select([col("u.id"), col("u.name")]).from("users").to_sql();
2855 assert_eq!(sql, "SELECT u.id, u.name FROM users");
2856 }
2857
2858 #[test]
2859 fn test_nested_dot_column() {
2860 let sql = select([col("t.s.f")]).from("users").to_sql();
2861 assert_eq!(sql, "SELECT t.s.f FROM users");
2862 }
2863
2864 #[test]
2865 fn test_not_condition() {
2866 let sql = select(["id"])
2867 .from("users")
2868 .where_(not(col("active").eq(boolean(true))))
2869 .to_sql();
2870 assert_eq!(sql, "SELECT id FROM users WHERE NOT active = TRUE");
2871 }
2872
2873 #[test]
2874 fn test_order_by_desc() {
2875 let sql = select(["id", "name"])
2876 .from("users")
2877 .order_by([col("name").desc()])
2878 .to_sql();
2879 assert_eq!(sql, "SELECT id, name FROM users ORDER BY name DESC");
2880 }
2881
2882 #[test]
2883 fn test_left_join() {
2884 let sql = select(["u.id", "o.amount"])
2885 .from("users")
2886 .left_join("orders", col("u.id").eq(col("o.user_id")))
2887 .to_sql();
2888 assert_eq!(
2889 sql,
2890 "SELECT u.id, o.amount FROM users LEFT JOIN orders ON u.id = o.user_id"
2891 );
2892 }
2893
2894 #[test]
2895 fn test_build_returns_expression() {
2896 let expr = select(["id"]).from("users").build();
2897 assert!(matches!(expr, Expression::Select(_)));
2898 }
2899
2900 #[test]
2901 fn test_expr_interop() {
2902 let age_check = col("age").gt(lit(18));
2904 let sql = select([col("id"), age_check.alias("is_adult")])
2905 .from("users")
2906 .to_sql();
2907 assert_eq!(sql, "SELECT id, age > 18 AS is_adult FROM users");
2908 }
2909
2910 #[test]
2913 fn test_sql_expr_simple() {
2914 let expr = sql_expr("age > 18");
2915 let sql = select(["id"]).from("users").where_(expr).to_sql();
2916 assert_eq!(sql, "SELECT id FROM users WHERE age > 18");
2917 }
2918
2919 #[test]
2920 fn test_sql_expr_compound() {
2921 let expr = sql_expr("a > 1 AND b < 10");
2922 let sql = select(["*"]).from("t").where_(expr).to_sql();
2923 assert_eq!(sql, "SELECT * FROM t WHERE a > 1 AND b < 10");
2924 }
2925
2926 #[test]
2927 fn test_sql_expr_function() {
2928 let expr = sql_expr("COALESCE(a, b, 0)");
2929 let sql = select([expr.alias("val")]).from("t").to_sql();
2930 assert_eq!(sql, "SELECT COALESCE(a, b, 0) AS val FROM t");
2931 }
2932
2933 #[test]
2934 fn test_condition_alias() {
2935 let cond = condition("x > 0");
2936 let sql = select(["*"]).from("t").where_(cond).to_sql();
2937 assert_eq!(sql, "SELECT * FROM t WHERE x > 0");
2938 }
2939
2940 #[test]
2943 fn test_ilike() {
2944 let sql = select(["id"])
2945 .from("users")
2946 .where_(col("name").ilike(lit("%test%")))
2947 .to_sql();
2948 assert_eq!(sql, "SELECT id FROM users WHERE name ILIKE '%test%'");
2949 }
2950
2951 #[test]
2952 fn test_rlike() {
2953 let sql = select(["id"])
2954 .from("users")
2955 .where_(col("name").rlike(lit("^[A-Z]")))
2956 .to_sql();
2957 assert_eq!(
2958 sql,
2959 "SELECT id FROM users WHERE REGEXP_LIKE(name, '^[A-Z]')"
2960 );
2961 }
2962
2963 #[test]
2964 fn test_not_in() {
2965 let sql = select(["id"])
2966 .from("users")
2967 .where_(col("status").not_in([lit("deleted"), lit("banned")]))
2968 .to_sql();
2969 assert_eq!(
2970 sql,
2971 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
2972 );
2973 }
2974
2975 #[test]
2976 fn repeated_clauses_append_unless_replacement_is_requested() {
2977 let appended = select(["x"])
2978 .where_(col("x").gt(lit(0)))
2979 .where_(col("x").lt(lit(10)))
2980 .group_by(["x"])
2981 .group_by(["y"])
2982 .to_sql();
2983 assert_eq!(appended, "SELECT x WHERE x > 0 AND x < 10 GROUP BY x, y");
2984
2985 let replaced = select(["x"])
2986 .where_(col("x").gt(lit(0)))
2987 .where_with_options(col("x").eq(lit(5)), ClauseOptions { append: false })
2988 .group_by(["x"])
2989 .group_by_with_options(["y"], ClauseOptions { append: false })
2990 .to_sql();
2991 assert_eq!(replaced, "SELECT x WHERE x = 5 GROUP BY y");
2992 }
2993
2994 #[test]
2997 fn test_case_searched() {
2998 let expr = case()
2999 .when(col("x").gt(lit(0)), lit("positive"))
3000 .when(col("x").eq(lit(0)), lit("zero"))
3001 .else_(lit("negative"))
3002 .build();
3003 let sql = select([expr.alias("label")]).from("t").to_sql();
3004 assert_eq!(
3005 sql,
3006 "SELECT CASE WHEN x > 0 THEN 'positive' WHEN x = 0 THEN 'zero' ELSE 'negative' END AS label FROM t"
3007 );
3008 }
3009
3010 #[test]
3011 fn test_case_simple() {
3012 let expr = case_of(col("status"))
3013 .when(lit(1), lit("active"))
3014 .when(lit(0), lit("inactive"))
3015 .build();
3016 let sql = select([expr.alias("status_label")]).from("t").to_sql();
3017 assert_eq!(
3018 sql,
3019 "SELECT CASE status WHEN 1 THEN 'active' WHEN 0 THEN 'inactive' END AS status_label FROM t"
3020 );
3021 }
3022
3023 #[test]
3024 fn test_case_no_else() {
3025 let expr = case().when(col("x").gt(lit(0)), lit("yes")).build();
3026 let sql = select([expr]).from("t").to_sql();
3027 assert_eq!(sql, "SELECT CASE WHEN x > 0 THEN 'yes' END FROM t");
3028 }
3029
3030 #[test]
3033 fn test_subquery_in_from() {
3034 let inner = select(["id", "name"])
3035 .from("users")
3036 .where_(col("active").eq(boolean(true)));
3037 let outer = select(["sub.id"])
3038 .from_expr(subquery(inner, "sub"))
3039 .to_sql();
3040 assert_eq!(
3041 outer,
3042 "SELECT sub.id FROM (SELECT id, name FROM users WHERE active = TRUE) AS sub"
3043 );
3044 }
3045
3046 #[test]
3047 fn test_subquery_in_join() {
3048 let inner = select([col("user_id"), func("SUM", [col("amount")]).alias("total")])
3049 .from("orders")
3050 .group_by(["user_id"]);
3051 let sql = select(["u.name", "o.total"])
3052 .from("users")
3053 .join("orders", col("u.id").eq(col("o.user_id")))
3054 .to_sql();
3055 assert!(sql.contains("JOIN"));
3056 let _sub = subquery(inner, "o");
3058 }
3059
3060 #[test]
3063 fn test_union() {
3064 let sql = union(select(["id"]).from("a"), select(["id"]).from("b")).to_sql();
3065 assert_eq!(sql, "SELECT id FROM a UNION SELECT id FROM b");
3066 }
3067
3068 #[test]
3069 fn test_union_all() {
3070 let sql = union_all(select(["id"]).from("a"), select(["id"]).from("b")).to_sql();
3071 assert_eq!(sql, "SELECT id FROM a UNION ALL SELECT id FROM b");
3072 }
3073
3074 #[test]
3075 fn test_intersect_builder() {
3076 let sql = intersect(select(["id"]).from("a"), select(["id"]).from("b")).to_sql();
3077 assert_eq!(sql, "SELECT id FROM a INTERSECT SELECT id FROM b");
3078 }
3079
3080 #[test]
3081 fn test_except_builder() {
3082 let sql = except_(select(["id"]).from("a"), select(["id"]).from("b")).to_sql();
3083 assert_eq!(sql, "SELECT id FROM a EXCEPT SELECT id FROM b");
3084 }
3085
3086 #[test]
3087 fn test_union_with_order_limit() {
3088 let sql = union(select(["id"]).from("a"), select(["id"]).from("b"))
3089 .order_by(["id"])
3090 .limit(10)
3091 .to_sql();
3092 assert!(sql.contains("UNION"));
3093 assert!(sql.contains("ORDER BY"));
3094 assert!(sql.contains("LIMIT"));
3095 }
3096
3097 #[test]
3098 fn test_select_builder_union() {
3099 let sql = select(["id"])
3100 .from("a")
3101 .union(select(["id"]).from("b"))
3102 .to_sql();
3103 assert_eq!(sql, "SELECT id FROM a UNION SELECT id FROM b");
3104 }
3105
3106 #[test]
3109 fn test_qualify() {
3110 let sql = select(["id", "name"])
3111 .from("users")
3112 .qualify(col("rn").eq(lit(1)))
3113 .to_sql();
3114 assert_eq!(sql, "SELECT id, name FROM users QUALIFY rn = 1");
3115 }
3116
3117 #[test]
3118 fn test_right_join() {
3119 let sql = select(["u.id", "o.amount"])
3120 .from("users")
3121 .right_join("orders", col("u.id").eq(col("o.user_id")))
3122 .to_sql();
3123 assert_eq!(
3124 sql,
3125 "SELECT u.id, o.amount FROM users RIGHT JOIN orders ON u.id = o.user_id"
3126 );
3127 }
3128
3129 #[test]
3130 fn test_cross_join() {
3131 let sql = select(["a.x", "b.y"]).from("a").cross_join("b").to_sql();
3132 assert_eq!(sql, "SELECT a.x, b.y FROM a CROSS JOIN b");
3133 }
3134
3135 #[test]
3136 fn test_lateral_view() {
3137 let sql = select(["id", "col_val"])
3138 .from("t")
3139 .lateral_view(func("EXPLODE", [col("arr")]), "lv", ["col_val"])
3140 .to_sql();
3141 assert!(sql.contains("LATERAL VIEW"));
3142 assert!(sql.contains("EXPLODE"));
3143
3144 let expression = select(["id"])
3145 .from("t")
3146 .lateral_view_with_options(
3147 func("EXPLODE", [col("arr")]),
3148 "lv",
3149 ["value"],
3150 LateralViewOptions { outer: true },
3151 )
3152 .build();
3153 let Expression::Select(select) = expression else {
3154 panic!("expected SELECT")
3155 };
3156 assert!(select.lateral_views[0].outer);
3157 }
3158
3159 #[test]
3160 fn test_window_clause() {
3161 let sql = select(["id"])
3162 .from("t")
3163 .window(
3164 "w",
3165 WindowDefBuilder::new()
3166 .partition_by(["dept"])
3167 .order_by(["salary"]),
3168 )
3169 .to_sql();
3170 assert!(sql.contains("WINDOW"));
3171 assert!(sql.contains("PARTITION BY"));
3172 }
3173
3174 #[test]
3177 fn test_xor() {
3178 let sql = select(["*"])
3179 .from("t")
3180 .where_(col("a").xor(col("b")))
3181 .to_sql();
3182 assert_eq!(sql, "SELECT * FROM t WHERE a XOR b");
3183 }
3184
3185 #[test]
3188 fn test_for_update() {
3189 let sql = select(["id"]).from("t").for_update().to_sql();
3190 assert_eq!(sql, "SELECT id FROM t FOR UPDATE");
3191 }
3192
3193 #[test]
3194 fn test_for_share() {
3195 let sql = select(["id"]).from("t").for_share().to_sql();
3196 assert_eq!(sql, "SELECT id FROM t FOR SHARE");
3197 }
3198
3199 #[test]
3202 fn test_hint() {
3203 let sql = select(["*"]).from("t").hint("FULL(t)").to_sql();
3204 assert!(sql.contains("FULL(t)"), "Expected hint in: {}", sql);
3205 }
3206
3207 #[test]
3210 fn test_ctas() {
3211 let expr = select(["*"]).from("t").ctas("new_table");
3212 let sql = Generator::sql(&expr).unwrap();
3213 assert_eq!(sql, "CREATE TABLE new_table AS SELECT * FROM t");
3214
3215 let expr = select(["*"]).from("t").ctas_with_options(
3216 "new_table",
3217 CtasOptions {
3218 replace: true,
3219 temporary: true,
3220 },
3221 );
3222 let Expression::CreateTable(create) = expr else {
3223 panic!("expected CREATE TABLE")
3224 };
3225 assert!(create.or_replace);
3226 assert!(create.temporary);
3227 }
3228
3229 #[test]
3232 fn test_merge_update_insert() {
3233 let sql = merge_into("target")
3234 .using("source", col("target.id").eq(col("source.id")))
3235 .when_matched_update(vec![("name", col("source.name"))])
3236 .when_not_matched_insert(&["id", "name"], vec![col("source.id"), col("source.name")])
3237 .to_sql();
3238 assert!(
3239 sql.contains("MERGE INTO"),
3240 "Expected MERGE INTO in: {}",
3241 sql
3242 );
3243 assert!(sql.contains("USING"), "Expected USING in: {}", sql);
3244 assert!(
3245 sql.contains("WHEN MATCHED"),
3246 "Expected WHEN MATCHED in: {}",
3247 sql
3248 );
3249 assert!(
3250 sql.contains("UPDATE SET"),
3251 "Expected UPDATE SET in: {}",
3252 sql
3253 );
3254 assert!(
3255 sql.contains("WHEN NOT MATCHED"),
3256 "Expected WHEN NOT MATCHED in: {}",
3257 sql
3258 );
3259 assert!(sql.contains("INSERT"), "Expected INSERT in: {}", sql);
3260 }
3261
3262 #[test]
3263 fn test_merge_delete() {
3264 let sql = merge_into("target")
3265 .using("source", col("target.id").eq(col("source.id")))
3266 .when_matched_delete()
3267 .to_sql();
3268 assert!(
3269 sql.contains("MERGE INTO"),
3270 "Expected MERGE INTO in: {}",
3271 sql
3272 );
3273 assert!(
3274 sql.contains("WHEN MATCHED THEN DELETE"),
3275 "Expected WHEN MATCHED THEN DELETE in: {}",
3276 sql
3277 );
3278 }
3279
3280 #[test]
3281 fn test_merge_with_condition() {
3282 let sql = merge_into("target")
3283 .using("source", col("target.id").eq(col("source.id")))
3284 .when_matched_update_where(
3285 col("source.active").eq(boolean(true)),
3286 vec![("name", col("source.name"))],
3287 )
3288 .to_sql();
3289 assert!(
3290 sql.contains("MERGE INTO"),
3291 "Expected MERGE INTO in: {}",
3292 sql
3293 );
3294 assert!(
3295 sql.contains("AND source.active = TRUE"),
3296 "Expected condition in: {}",
3297 sql
3298 );
3299 }
3300}