1use crate::expressions::*;
59use crate::generator::Generator;
60use crate::parser::Parser;
61
62pub fn col(name: &str) -> Expr {
86 if let Some((table, column)) = name.rsplit_once('.') {
87 Expr(Expression::Column(Column {
88 name: Identifier::new(column),
89 table: Some(Identifier::new(table)),
90 join_mark: false,
91 trailing_comments: Vec::new(),
92 }))
93 } else {
94 Expr(Expression::Column(Column {
95 name: Identifier::new(name),
96 table: None,
97 join_mark: false,
98 trailing_comments: Vec::new(),
99 }))
100 }
101}
102
103pub fn lit<V: IntoLiteral>(value: V) -> Expr {
119 value.into_literal()
120}
121
122pub fn star() -> Expr {
124 Expr(Expression::star())
125}
126
127pub fn null() -> Expr {
129 Expr(Expression::Null(Null))
130}
131
132pub fn boolean(value: bool) -> Expr {
134 Expr(Expression::Boolean(BooleanLiteral { value }))
135}
136
137pub fn table(name: &str) -> Expr {
154 let parts: Vec<&str> = name.split('.').collect();
155 let table_ref = match parts.len() {
156 3 => TableRef::new_with_catalog(parts[2], parts[1], parts[0]),
157 2 => TableRef::new_with_schema(parts[1], parts[0]),
158 _ => TableRef::new(parts[0]),
159 };
160 Expr(Expression::Table(table_ref))
161}
162
163pub fn func(name: &str, args: impl IntoIterator<Item = Expr>) -> Expr {
180 Expr(Expression::Function(Box::new(Function {
181 name: name.to_string(),
182 args: args.into_iter().map(|a| a.0).collect(),
183 ..Function::default()
184 })))
185}
186
187pub fn cast(expr: Expr, to: &str) -> Expr {
203 let data_type = parse_simple_data_type(to);
204 Expr(Expression::Cast(Box::new(Cast {
205 this: expr.0,
206 to: data_type,
207 trailing_comments: Vec::new(),
208 double_colon_syntax: false,
209 format: None,
210 default: None,
211 })))
212}
213
214pub fn not(expr: Expr) -> Expr {
219 Expr(Expression::Not(Box::new(UnaryOp::new(expr.0))))
220}
221
222pub fn and(left: Expr, right: Expr) -> Expr {
227 left.and(right)
228}
229
230pub fn or(left: Expr, right: Expr) -> Expr {
235 left.or(right)
236}
237
238pub fn alias(expr: Expr, name: &str) -> Expr {
243 Expr(Expression::Alias(Box::new(Alias {
244 this: expr.0,
245 alias: Identifier::new(name),
246 column_aliases: Vec::new(),
247 pre_alias_comments: Vec::new(),
248 trailing_comments: Vec::new(),
249 })))
250}
251
252pub fn sql_expr(sql: &str) -> Expr {
276 let wrapped = format!("SELECT {}", sql);
277 let ast = Parser::parse_sql(&wrapped).expect("sql_expr: failed to parse SQL expression");
278 if let Expression::Select(s) = &ast[0] {
279 if let Some(first) = s.expressions.first() {
280 return Expr(first.clone());
281 }
282 }
283 panic!("sql_expr: failed to extract expression from parsed SQL");
284}
285
286pub fn condition(sql: &str) -> Expr {
295 sql_expr(sql)
296}
297
298pub fn count(expr: Expr) -> Expr {
306 Expr(Expression::Count(Box::new(CountFunc {
307 this: Some(expr.0),
308 star: false,
309 distinct: false,
310 filter: None,
311 ignore_nulls: None,
312 original_name: None,
313 })))
314}
315
316pub fn count_star() -> Expr {
318 Expr(Expression::Count(Box::new(CountFunc {
319 this: None,
320 star: true,
321 distinct: false,
322 filter: None,
323 ignore_nulls: None,
324 original_name: None,
325 })))
326}
327
328pub fn count_distinct(expr: Expr) -> Expr {
330 Expr(Expression::Count(Box::new(CountFunc {
331 this: Some(expr.0),
332 star: false,
333 distinct: true,
334 filter: None,
335 ignore_nulls: None,
336 original_name: None,
337 })))
338}
339
340pub fn sum(expr: Expr) -> Expr {
342 Expr(Expression::Sum(Box::new(AggFunc {
343 this: expr.0,
344 distinct: false,
345 filter: None,
346 order_by: vec![],
347 name: None,
348 ignore_nulls: None,
349 having_max: None,
350 limit: None,
351 })))
352}
353
354pub fn avg(expr: Expr) -> Expr {
356 Expr(Expression::Avg(Box::new(AggFunc {
357 this: expr.0,
358 distinct: false,
359 filter: None,
360 order_by: vec![],
361 name: None,
362 ignore_nulls: None,
363 having_max: None,
364 limit: None,
365 })))
366}
367
368pub fn min_(expr: Expr) -> Expr {
370 Expr(Expression::Min(Box::new(AggFunc {
371 this: expr.0,
372 distinct: false,
373 filter: None,
374 order_by: vec![],
375 name: None,
376 ignore_nulls: None,
377 having_max: None,
378 limit: None,
379 })))
380}
381
382pub fn max_(expr: Expr) -> Expr {
384 Expr(Expression::Max(Box::new(AggFunc {
385 this: expr.0,
386 distinct: false,
387 filter: None,
388 order_by: vec![],
389 name: None,
390 ignore_nulls: None,
391 having_max: None,
392 limit: None,
393 })))
394}
395
396pub fn approx_distinct(expr: Expr) -> Expr {
398 Expr(Expression::ApproxDistinct(Box::new(AggFunc {
399 this: expr.0,
400 distinct: false,
401 filter: None,
402 order_by: vec![],
403 name: None,
404 ignore_nulls: None,
405 having_max: None,
406 limit: None,
407 })))
408}
409
410pub fn upper(expr: Expr) -> Expr {
414 Expr(Expression::Upper(Box::new(UnaryFunc::new(expr.0))))
415}
416
417pub fn lower(expr: Expr) -> Expr {
419 Expr(Expression::Lower(Box::new(UnaryFunc::new(expr.0))))
420}
421
422pub fn length(expr: Expr) -> Expr {
424 Expr(Expression::Length(Box::new(UnaryFunc::new(expr.0))))
425}
426
427pub fn trim(expr: Expr) -> Expr {
429 Expr(Expression::Trim(Box::new(TrimFunc {
430 this: expr.0,
431 characters: None,
432 position: TrimPosition::Both,
433 sql_standard_syntax: false,
434 position_explicit: false,
435 })))
436}
437
438pub fn ltrim(expr: Expr) -> Expr {
440 Expr(Expression::LTrim(Box::new(UnaryFunc::new(expr.0))))
441}
442
443pub fn rtrim(expr: Expr) -> Expr {
445 Expr(Expression::RTrim(Box::new(UnaryFunc::new(expr.0))))
446}
447
448pub fn reverse(expr: Expr) -> Expr {
450 Expr(Expression::Reverse(Box::new(UnaryFunc::new(expr.0))))
451}
452
453pub fn initcap(expr: Expr) -> Expr {
455 Expr(Expression::Initcap(Box::new(UnaryFunc::new(expr.0))))
456}
457
458pub fn substring(expr: Expr, start: Expr, len: Option<Expr>) -> Expr {
460 Expr(Expression::Substring(Box::new(SubstringFunc {
461 this: expr.0,
462 start: start.0,
463 length: len.map(|l| l.0),
464 from_for_syntax: false,
465 })))
466}
467
468pub fn replace_(expr: Expr, old: Expr, new: Expr) -> Expr {
471 Expr(Expression::Replace(Box::new(ReplaceFunc {
472 this: expr.0,
473 old: old.0,
474 new: new.0,
475 })))
476}
477
478pub fn concat_ws(separator: Expr, exprs: impl IntoIterator<Item = Expr>) -> Expr {
480 Expr(Expression::ConcatWs(Box::new(ConcatWs {
481 separator: separator.0,
482 expressions: exprs.into_iter().map(|e| e.0).collect(),
483 })))
484}
485
486pub fn coalesce(exprs: impl IntoIterator<Item = Expr>) -> Expr {
490 Expr(Expression::Coalesce(Box::new(VarArgFunc {
491 expressions: exprs.into_iter().map(|e| e.0).collect(),
492 original_name: None,
493 })))
494}
495
496pub fn null_if(expr1: Expr, expr2: Expr) -> Expr {
498 Expr(Expression::NullIf(Box::new(BinaryFunc {
499 this: expr1.0,
500 expression: expr2.0,
501 original_name: None,
502 })))
503}
504
505pub fn if_null(expr: Expr, fallback: Expr) -> Expr {
507 Expr(Expression::IfNull(Box::new(BinaryFunc {
508 this: expr.0,
509 expression: fallback.0,
510 original_name: None,
511 })))
512}
513
514pub fn abs(expr: Expr) -> Expr {
518 Expr(Expression::Abs(Box::new(UnaryFunc::new(expr.0))))
519}
520
521pub fn round(expr: Expr, decimals: Option<Expr>) -> Expr {
523 Expr(Expression::Round(Box::new(RoundFunc {
524 this: expr.0,
525 decimals: decimals.map(|d| d.0),
526 })))
527}
528
529pub fn floor(expr: Expr) -> Expr {
531 Expr(Expression::Floor(Box::new(FloorFunc {
532 this: expr.0,
533 scale: None,
534 to: None,
535 })))
536}
537
538pub fn ceil(expr: Expr) -> Expr {
540 Expr(Expression::Ceil(Box::new(CeilFunc {
541 this: expr.0,
542 decimals: None,
543 to: None,
544 })))
545}
546
547pub fn power(base: Expr, exponent: Expr) -> Expr {
549 Expr(Expression::Power(Box::new(BinaryFunc {
550 this: base.0,
551 expression: exponent.0,
552 original_name: None,
553 })))
554}
555
556pub fn sqrt(expr: Expr) -> Expr {
558 Expr(Expression::Sqrt(Box::new(UnaryFunc::new(expr.0))))
559}
560
561pub fn ln(expr: Expr) -> Expr {
563 Expr(Expression::Ln(Box::new(UnaryFunc::new(expr.0))))
564}
565
566pub fn exp_(expr: Expr) -> Expr {
568 Expr(Expression::Exp(Box::new(UnaryFunc::new(expr.0))))
569}
570
571pub fn sign(expr: Expr) -> Expr {
573 Expr(Expression::Sign(Box::new(UnaryFunc::new(expr.0))))
574}
575
576pub fn greatest(exprs: impl IntoIterator<Item = Expr>) -> Expr {
578 Expr(Expression::Greatest(Box::new(VarArgFunc {
579 expressions: exprs.into_iter().map(|e| e.0).collect(),
580 original_name: None,
581 })))
582}
583
584pub fn least(exprs: impl IntoIterator<Item = Expr>) -> Expr {
586 Expr(Expression::Least(Box::new(VarArgFunc {
587 expressions: exprs.into_iter().map(|e| e.0).collect(),
588 original_name: None,
589 })))
590}
591
592pub fn current_date_() -> Expr {
596 Expr(Expression::CurrentDate(CurrentDate))
597}
598
599pub fn current_time_() -> Expr {
601 Expr(Expression::CurrentTime(CurrentTime { precision: None }))
602}
603
604pub fn current_timestamp_() -> Expr {
606 Expr(Expression::CurrentTimestamp(CurrentTimestamp {
607 precision: None,
608 sysdate: false,
609 }))
610}
611
612pub fn extract_(field: &str, expr: Expr) -> Expr {
614 Expr(Expression::Extract(Box::new(ExtractFunc {
615 this: expr.0,
616 field: parse_datetime_field(field),
617 })))
618}
619
620fn parse_datetime_field(field: &str) -> DateTimeField {
622 match field.to_uppercase().as_str() {
623 "YEAR" => DateTimeField::Year,
624 "MONTH" => DateTimeField::Month,
625 "DAY" => DateTimeField::Day,
626 "HOUR" => DateTimeField::Hour,
627 "MINUTE" => DateTimeField::Minute,
628 "SECOND" => DateTimeField::Second,
629 "MILLISECOND" => DateTimeField::Millisecond,
630 "MICROSECOND" => DateTimeField::Microsecond,
631 "DOW" | "DAYOFWEEK" => DateTimeField::DayOfWeek,
632 "DOY" | "DAYOFYEAR" => DateTimeField::DayOfYear,
633 "WEEK" => DateTimeField::Week,
634 "QUARTER" => DateTimeField::Quarter,
635 "EPOCH" => DateTimeField::Epoch,
636 "TIMEZONE" => DateTimeField::Timezone,
637 "TIMEZONE_HOUR" => DateTimeField::TimezoneHour,
638 "TIMEZONE_MINUTE" => DateTimeField::TimezoneMinute,
639 "DATE" => DateTimeField::Date,
640 "TIME" => DateTimeField::Time,
641 other => DateTimeField::Custom(other.to_string()),
642 }
643}
644
645pub fn row_number() -> Expr {
649 Expr(Expression::RowNumber(RowNumber))
650}
651
652pub fn rank_() -> Expr {
654 Expr(Expression::Rank(Rank {
655 order_by: None,
656 args: vec![],
657 }))
658}
659
660pub fn dense_rank() -> Expr {
662 Expr(Expression::DenseRank(DenseRank { args: vec![] }))
663}
664
665pub fn select<I, E>(expressions: I) -> SelectBuilder
692where
693 I: IntoIterator<Item = E>,
694 E: IntoExpr,
695{
696 let mut builder = SelectBuilder::new();
697 for expr in expressions {
698 builder.select = builder.select.column(expr.into_expr().0);
699 }
700 builder
701}
702
703pub fn from(table_name: &str) -> SelectBuilder {
718 let mut builder = SelectBuilder::new();
719 builder.select.from = Some(From {
720 expressions: vec![Expression::Table(TableRef::new(table_name))],
721 });
722 builder
723}
724
725pub fn delete(table_name: &str) -> DeleteBuilder {
738 DeleteBuilder {
739 delete: Delete {
740 table: TableRef::new(table_name),
741 on_cluster: None,
742 alias: None,
743 alias_explicit_as: false,
744 using: Vec::new(),
745 where_clause: None,
746 output: None,
747 leading_comments: Vec::new(),
748 with: None,
749 limit: None,
750 order_by: None,
751 returning: Vec::new(),
752 tables: Vec::new(),
753 tables_from_using: false,
754 joins: Vec::new(),
755 force_index: None,
756 no_from: false,
757 },
758 }
759}
760
761pub fn insert_into(table_name: &str) -> InsertBuilder {
778 InsertBuilder {
779 insert: Insert {
780 table: TableRef::new(table_name),
781 columns: Vec::new(),
782 values: Vec::new(),
783 query: None,
784 overwrite: false,
785 partition: Vec::new(),
786 directory: None,
787 returning: Vec::new(),
788 output: None,
789 on_conflict: None,
790 leading_comments: Vec::new(),
791 if_exists: false,
792 with: None,
793 ignore: false,
794 source_alias: None,
795 alias: None,
796 alias_explicit_as: false,
797 default_values: false,
798 by_name: false,
799 conflict_action: None,
800 is_replace: false,
801 hint: None,
802 replace_where: None,
803 source: None,
804 function_target: None,
805 partition_by: None,
806 settings: Vec::new(),
807 },
808 }
809}
810
811pub fn update(table_name: &str) -> UpdateBuilder {
829 UpdateBuilder {
830 update: Update {
831 table: TableRef::new(table_name),
832 extra_tables: Vec::new(),
833 table_joins: Vec::new(),
834 set: Vec::new(),
835 from_clause: None,
836 from_joins: Vec::new(),
837 where_clause: None,
838 returning: Vec::new(),
839 output: None,
840 with: None,
841 leading_comments: Vec::new(),
842 limit: None,
843 order_by: None,
844 from_before_set: false,
845 },
846 }
847}
848
849#[derive(Debug, Clone)]
874pub struct Expr(pub Expression);
875
876impl Expr {
877 pub fn into_inner(self) -> Expression {
879 self.0
880 }
881
882 pub fn to_sql(&self) -> String {
886 Generator::sql(&self.0).unwrap_or_default()
887 }
888
889 pub fn eq(self, other: Expr) -> Expr {
893 Expr(Expression::Eq(Box::new(binary_op(self.0, other.0))))
894 }
895
896 pub fn neq(self, other: Expr) -> Expr {
898 Expr(Expression::Neq(Box::new(binary_op(self.0, other.0))))
899 }
900
901 pub fn lt(self, other: Expr) -> Expr {
903 Expr(Expression::Lt(Box::new(binary_op(self.0, other.0))))
904 }
905
906 pub fn lte(self, other: Expr) -> Expr {
908 Expr(Expression::Lte(Box::new(binary_op(self.0, other.0))))
909 }
910
911 pub fn gt(self, other: Expr) -> Expr {
913 Expr(Expression::Gt(Box::new(binary_op(self.0, other.0))))
914 }
915
916 pub fn gte(self, other: Expr) -> Expr {
918 Expr(Expression::Gte(Box::new(binary_op(self.0, other.0))))
919 }
920
921 pub fn and(self, other: Expr) -> Expr {
925 Expr(Expression::And(Box::new(binary_op(self.0, other.0))))
926 }
927
928 pub fn or(self, other: Expr) -> Expr {
930 Expr(Expression::Or(Box::new(binary_op(self.0, other.0))))
931 }
932
933 pub fn not(self) -> Expr {
935 Expr(Expression::Not(Box::new(UnaryOp::new(self.0))))
936 }
937
938 pub fn xor(self, other: Expr) -> Expr {
940 Expr(Expression::Xor(Box::new(Xor {
941 this: Some(Box::new(self.0)),
942 expression: Some(Box::new(other.0)),
943 expressions: vec![],
944 })))
945 }
946
947 pub fn add(self, other: Expr) -> Expr {
951 Expr(Expression::Add(Box::new(binary_op(self.0, other.0))))
952 }
953
954 pub fn sub(self, other: Expr) -> Expr {
956 Expr(Expression::Sub(Box::new(binary_op(self.0, other.0))))
957 }
958
959 pub fn mul(self, other: Expr) -> Expr {
961 Expr(Expression::Mul(Box::new(binary_op(self.0, other.0))))
962 }
963
964 pub fn div(self, other: Expr) -> Expr {
966 Expr(Expression::Div(Box::new(binary_op(self.0, other.0))))
967 }
968
969 pub fn is_null(self) -> Expr {
973 Expr(Expression::Is(Box::new(BinaryOp {
974 left: self.0,
975 right: Expression::Null(Null),
976 left_comments: Vec::new(),
977 operator_comments: Vec::new(),
978 trailing_comments: Vec::new(),
979 })))
980 }
981
982 pub fn is_not_null(self) -> Expr {
984 Expr(Expression::Not(Box::new(UnaryOp::new(
985 Expression::Is(Box::new(BinaryOp {
986 left: self.0,
987 right: Expression::Null(Null),
988 left_comments: Vec::new(),
989 operator_comments: Vec::new(),
990 trailing_comments: Vec::new(),
991 })),
992 ))))
993 }
994
995 pub fn in_list(self, values: impl IntoIterator<Item = Expr>) -> Expr {
999 Expr(Expression::In(Box::new(In {
1000 this: self.0,
1001 expressions: values.into_iter().map(|v| v.0).collect(),
1002 query: None,
1003 not: false,
1004 global: false,
1005 unnest: None,
1006 })))
1007 }
1008
1009 pub fn between(self, low: Expr, high: Expr) -> Expr {
1011 Expr(Expression::Between(Box::new(Between {
1012 this: self.0,
1013 low: low.0,
1014 high: high.0,
1015 not: false,
1016 })))
1017 }
1018
1019 pub fn like(self, pattern: Expr) -> Expr {
1021 Expr(Expression::Like(Box::new(LikeOp {
1022 left: self.0,
1023 right: pattern.0,
1024 escape: None,
1025 quantifier: None,
1026 })))
1027 }
1028
1029 pub fn alias(self, name: &str) -> Expr {
1031 alias(self, name)
1032 }
1033
1034 pub fn cast(self, to: &str) -> Expr {
1038 cast(self, to)
1039 }
1040
1041 pub fn asc(self) -> Expr {
1046 Expr(Expression::Ordered(Box::new(Ordered {
1047 this: self.0,
1048 desc: false,
1049 nulls_first: None,
1050 explicit_asc: true,
1051 with_fill: None,
1052 })))
1053 }
1054
1055 pub fn desc(self) -> Expr {
1059 Expr(Expression::Ordered(Box::new(Ordered {
1060 this: self.0,
1061 desc: true,
1062 nulls_first: None,
1063 explicit_asc: false,
1064 with_fill: None,
1065 })))
1066 }
1067
1068 pub fn ilike(self, pattern: Expr) -> Expr {
1073 Expr(Expression::ILike(Box::new(LikeOp {
1074 left: self.0,
1075 right: pattern.0,
1076 escape: None,
1077 quantifier: None,
1078 })))
1079 }
1080
1081 pub fn rlike(self, pattern: Expr) -> Expr {
1086 Expr(Expression::RegexpLike(Box::new(RegexpFunc {
1087 this: self.0,
1088 pattern: pattern.0,
1089 flags: None,
1090 })))
1091 }
1092
1093 pub fn not_in(self, values: impl IntoIterator<Item = Expr>) -> Expr {
1097 Expr(Expression::In(Box::new(In {
1098 this: self.0,
1099 expressions: values.into_iter().map(|v| v.0).collect(),
1100 query: None,
1101 not: true,
1102 global: false,
1103 unnest: None,
1104 })))
1105 }
1106}
1107
1108pub struct SelectBuilder {
1134 select: Select,
1135}
1136
1137impl SelectBuilder {
1138 fn new() -> Self {
1139 SelectBuilder {
1140 select: Select::new(),
1141 }
1142 }
1143
1144 pub fn select_cols<I, E>(mut self, expressions: I) -> Self
1149 where
1150 I: IntoIterator<Item = E>,
1151 E: IntoExpr,
1152 {
1153 for expr in expressions {
1154 self.select.expressions.push(expr.into_expr().0);
1155 }
1156 self
1157 }
1158
1159 pub fn from(mut self, table_name: &str) -> Self {
1161 self.select.from = Some(From {
1162 expressions: vec![Expression::Table(TableRef::new(table_name))],
1163 });
1164 self
1165 }
1166
1167 pub fn from_expr(mut self, expr: Expr) -> Self {
1172 self.select.from = Some(From {
1173 expressions: vec![expr.0],
1174 });
1175 self
1176 }
1177
1178 pub fn join(mut self, table_name: &str, on: Expr) -> Self {
1180 self.select.joins.push(Join {
1181 kind: JoinKind::Inner,
1182 this: Expression::Table(TableRef::new(table_name)),
1183 on: Some(on.0),
1184 using: Vec::new(),
1185 use_inner_keyword: false,
1186 use_outer_keyword: false,
1187 deferred_condition: false,
1188 join_hint: None,
1189 match_condition: None,
1190 pivots: Vec::new(),
1191 });
1192 self
1193 }
1194
1195 pub fn left_join(mut self, table_name: &str, on: Expr) -> Self {
1197 self.select.joins.push(Join {
1198 kind: JoinKind::Left,
1199 this: Expression::Table(TableRef::new(table_name)),
1200 on: Some(on.0),
1201 using: Vec::new(),
1202 use_inner_keyword: false,
1203 use_outer_keyword: false,
1204 deferred_condition: false,
1205 join_hint: None,
1206 match_condition: None,
1207 pivots: Vec::new(),
1208 });
1209 self
1210 }
1211
1212 pub fn where_(mut self, condition: Expr) -> Self {
1218 self.select.where_clause = Some(Where { this: condition.0 });
1219 self
1220 }
1221
1222 pub fn group_by<I, E>(mut self, expressions: I) -> Self
1224 where
1225 I: IntoIterator<Item = E>,
1226 E: IntoExpr,
1227 {
1228 self.select.group_by = Some(GroupBy {
1229 expressions: expressions.into_iter().map(|e| e.into_expr().0).collect(),
1230 all: None,
1231 totals: false,
1232 });
1233 self
1234 }
1235
1236 pub fn having(mut self, condition: Expr) -> Self {
1238 self.select.having = Some(Having { this: condition.0 });
1239 self
1240 }
1241
1242 pub fn order_by<I, E>(mut self, expressions: I) -> Self
1248 where
1249 I: IntoIterator<Item = E>,
1250 E: IntoExpr,
1251 {
1252 self.select.order_by = Some(OrderBy {
1253 siblings: false,
1254 expressions: expressions
1255 .into_iter()
1256 .map(|e| {
1257 let expr = e.into_expr().0;
1258 match expr {
1259 Expression::Ordered(_) => expr,
1260 other => Expression::Ordered(Box::new(Ordered {
1261 this: other,
1262 desc: false,
1263 nulls_first: None,
1264 explicit_asc: false,
1265 with_fill: None,
1266 })),
1267 }
1268 })
1269 .collect::<Vec<_>>()
1270 .into_iter()
1271 .map(|e| {
1272 if let Expression::Ordered(o) = e {
1273 *o
1274 } else {
1275 Ordered {
1276 this: e,
1277 desc: false,
1278 nulls_first: None,
1279 explicit_asc: false,
1280 with_fill: None,
1281 }
1282 }
1283 })
1284 .collect(),
1285 });
1286 self
1287 }
1288
1289 pub fn sort_by<I, E>(mut self, expressions: I) -> Self
1296 where
1297 I: IntoIterator<Item = E>,
1298 E: IntoExpr,
1299 {
1300 self.select.sort_by = Some(SortBy {
1301 expressions: expressions
1302 .into_iter()
1303 .map(|e| {
1304 let expr = e.into_expr().0;
1305 match expr {
1306 Expression::Ordered(o) => *o,
1307 other => Ordered {
1308 this: other,
1309 desc: false,
1310 nulls_first: None,
1311 explicit_asc: false,
1312 with_fill: None,
1313 },
1314 }
1315 })
1316 .collect(),
1317 });
1318 self
1319 }
1320
1321 pub fn limit(mut self, count: usize) -> Self {
1323 self.select.limit = Some(Limit {
1324 this: Expression::Literal(Literal::Number(count.to_string())),
1325 percent: false,
1326 });
1327 self
1328 }
1329
1330 pub fn offset(mut self, count: usize) -> Self {
1332 self.select.offset = Some(Offset {
1333 this: Expression::Literal(Literal::Number(count.to_string())),
1334 rows: None,
1335 });
1336 self
1337 }
1338
1339 pub fn distinct(mut self) -> Self {
1341 self.select.distinct = true;
1342 self
1343 }
1344
1345 pub fn qualify(mut self, condition: Expr) -> Self {
1350 self.select.qualify = Some(Qualify { this: condition.0 });
1351 self
1352 }
1353
1354 pub fn right_join(mut self, table_name: &str, on: Expr) -> Self {
1356 self.select.joins.push(Join {
1357 kind: JoinKind::Right,
1358 this: Expression::Table(TableRef::new(table_name)),
1359 on: Some(on.0),
1360 using: Vec::new(),
1361 use_inner_keyword: false,
1362 use_outer_keyword: false,
1363 deferred_condition: false,
1364 join_hint: None,
1365 match_condition: None,
1366 pivots: Vec::new(),
1367 });
1368 self
1369 }
1370
1371 pub fn cross_join(mut self, table_name: &str) -> Self {
1373 self.select.joins.push(Join {
1374 kind: JoinKind::Cross,
1375 this: Expression::Table(TableRef::new(table_name)),
1376 on: None,
1377 using: Vec::new(),
1378 use_inner_keyword: false,
1379 use_outer_keyword: false,
1380 deferred_condition: false,
1381 join_hint: None,
1382 match_condition: None,
1383 pivots: Vec::new(),
1384 });
1385 self
1386 }
1387
1388 pub fn lateral_view<S: AsRef<str>>(
1395 mut self,
1396 table_function: Expr,
1397 table_alias: &str,
1398 column_aliases: impl IntoIterator<Item = S>,
1399 ) -> Self {
1400 self.select.lateral_views.push(LateralView {
1401 this: table_function.0,
1402 table_alias: Some(Identifier::new(table_alias)),
1403 column_aliases: column_aliases
1404 .into_iter()
1405 .map(|c| Identifier::new(c.as_ref()))
1406 .collect(),
1407 outer: false,
1408 });
1409 self
1410 }
1411
1412 pub fn window(mut self, name: &str, def: WindowDefBuilder) -> Self {
1418 let named_window = NamedWindow {
1419 name: Identifier::new(name),
1420 spec: Over {
1421 window_name: None,
1422 partition_by: def.partition_by,
1423 order_by: def.order_by,
1424 frame: None,
1425 alias: None,
1426 },
1427 };
1428 match self.select.windows {
1429 Some(ref mut windows) => windows.push(named_window),
1430 None => self.select.windows = Some(vec![named_window]),
1431 }
1432 self
1433 }
1434
1435 pub fn for_update(mut self) -> Self {
1440 self.select.locks.push(Lock {
1441 update: Some(Box::new(Expression::Boolean(BooleanLiteral { value: true }))),
1442 expressions: vec![],
1443 wait: None,
1444 key: None,
1445 });
1446 self
1447 }
1448
1449 pub fn for_share(mut self) -> Self {
1454 self.select.locks.push(Lock {
1455 update: None,
1456 expressions: vec![],
1457 wait: None,
1458 key: None,
1459 });
1460 self
1461 }
1462
1463 pub fn hint(mut self, hint_text: &str) -> Self {
1468 let hint_expr = HintExpression::Raw(hint_text.to_string());
1469 match &mut self.select.hint {
1470 Some(h) => h.expressions.push(hint_expr),
1471 None => {
1472 self.select.hint = Some(Hint {
1473 expressions: vec![hint_expr],
1474 })
1475 }
1476 }
1477 self
1478 }
1479
1480 pub fn ctas(self, table_name: &str) -> Expression {
1496 Expression::CreateTable(Box::new(CreateTable {
1497 name: TableRef::new(table_name),
1498 on_cluster: None,
1499 columns: vec![],
1500 constraints: vec![],
1501 if_not_exists: false,
1502 temporary: false,
1503 or_replace: false,
1504 table_modifier: None,
1505 as_select: Some(self.build()),
1506 as_select_parenthesized: false,
1507 on_commit: None,
1508 clone_source: None,
1509 clone_at_clause: None,
1510 is_copy: false,
1511 shallow_clone: false,
1512 leading_comments: vec![],
1513 with_properties: vec![],
1514 teradata_post_name_options: vec![],
1515 with_data: None,
1516 with_statistics: None,
1517 teradata_indexes: vec![],
1518 with_cte: None,
1519 properties: vec![],
1520 partition_of: None,
1521 post_table_properties: vec![],
1522 mysql_table_options: vec![],
1523 inherits: vec![],
1524 on_property: None,
1525 copy_grants: false,
1526 using_template: None,
1527 rollup: None,
1528 }))
1529 }
1530
1531 pub fn union(self, other: SelectBuilder) -> SetOpBuilder {
1535 SetOpBuilder::new(SetOpKind::Union, self, other, false)
1536 }
1537
1538 pub fn union_all(self, other: SelectBuilder) -> SetOpBuilder {
1542 SetOpBuilder::new(SetOpKind::Union, self, other, true)
1543 }
1544
1545 pub fn intersect(self, other: SelectBuilder) -> SetOpBuilder {
1549 SetOpBuilder::new(SetOpKind::Intersect, self, other, false)
1550 }
1551
1552 pub fn except_(self, other: SelectBuilder) -> SetOpBuilder {
1556 SetOpBuilder::new(SetOpKind::Except, self, other, false)
1557 }
1558
1559 pub fn build(self) -> Expression {
1561 Expression::Select(Box::new(self.select))
1562 }
1563
1564 pub fn to_sql(self) -> String {
1569 Generator::sql(&self.build()).unwrap_or_default()
1570 }
1571}
1572
1573pub struct DeleteBuilder {
1582 delete: Delete,
1583}
1584
1585impl DeleteBuilder {
1586 pub fn where_(mut self, condition: Expr) -> Self {
1588 self.delete.where_clause = Some(Where { this: condition.0 });
1589 self
1590 }
1591
1592 pub fn build(self) -> Expression {
1594 Expression::Delete(Box::new(self.delete))
1595 }
1596
1597 pub fn to_sql(self) -> String {
1599 Generator::sql(&self.build()).unwrap_or_default()
1600 }
1601}
1602
1603pub struct InsertBuilder {
1614 insert: Insert,
1615}
1616
1617impl InsertBuilder {
1618 pub fn columns<I, S>(mut self, columns: I) -> Self
1620 where
1621 I: IntoIterator<Item = S>,
1622 S: AsRef<str>,
1623 {
1624 self.insert.columns = columns
1625 .into_iter()
1626 .map(|c| Identifier::new(c.as_ref()))
1627 .collect();
1628 self
1629 }
1630
1631 pub fn values<I>(mut self, values: I) -> Self
1635 where
1636 I: IntoIterator<Item = Expr>,
1637 {
1638 self.insert
1639 .values
1640 .push(values.into_iter().map(|v| v.0).collect());
1641 self
1642 }
1643
1644 pub fn query(mut self, query: SelectBuilder) -> Self {
1648 self.insert.query = Some(query.build());
1649 self
1650 }
1651
1652 pub fn build(self) -> Expression {
1654 Expression::Insert(Box::new(self.insert))
1655 }
1656
1657 pub fn to_sql(self) -> String {
1659 Generator::sql(&self.build()).unwrap_or_default()
1660 }
1661}
1662
1663pub struct UpdateBuilder {
1673 update: Update,
1674}
1675
1676impl UpdateBuilder {
1677 pub fn set(mut self, column: &str, value: Expr) -> Self {
1681 self.update
1682 .set
1683 .push((Identifier::new(column), value.0));
1684 self
1685 }
1686
1687 pub fn where_(mut self, condition: Expr) -> Self {
1689 self.update.where_clause = Some(Where { this: condition.0 });
1690 self
1691 }
1692
1693 pub fn from(mut self, table_name: &str) -> Self {
1697 self.update.from_clause = Some(From {
1698 expressions: vec![Expression::Table(TableRef::new(table_name))],
1699 });
1700 self
1701 }
1702
1703 pub fn build(self) -> Expression {
1705 Expression::Update(Box::new(self.update))
1706 }
1707
1708 pub fn to_sql(self) -> String {
1710 Generator::sql(&self.build()).unwrap_or_default()
1711 }
1712}
1713
1714pub fn case() -> CaseBuilder {
1739 CaseBuilder {
1740 operand: None,
1741 whens: Vec::new(),
1742 else_: None,
1743 }
1744}
1745
1746pub fn case_of(operand: Expr) -> CaseBuilder {
1767 CaseBuilder {
1768 operand: Some(operand.0),
1769 whens: Vec::new(),
1770 else_: None,
1771 }
1772}
1773
1774pub struct CaseBuilder {
1782 operand: Option<Expression>,
1783 whens: Vec<(Expression, Expression)>,
1784 else_: Option<Expression>,
1785}
1786
1787impl CaseBuilder {
1788 pub fn when(mut self, condition: Expr, result: Expr) -> Self {
1793 self.whens.push((condition.0, result.0));
1794 self
1795 }
1796
1797 pub fn else_(mut self, result: Expr) -> Self {
1802 self.else_ = Some(result.0);
1803 self
1804 }
1805
1806 pub fn build(self) -> Expr {
1808 Expr(self.build_expr())
1809 }
1810
1811 pub fn build_expr(self) -> Expression {
1816 Expression::Case(Box::new(Case {
1817 operand: self.operand,
1818 whens: self.whens,
1819 else_: self.else_,
1820 }))
1821 }
1822}
1823
1824pub fn subquery(query: SelectBuilder, alias_name: &str) -> Expr {
1848 subquery_expr(query.build(), alias_name)
1849}
1850
1851pub fn subquery_expr(expr: Expression, alias_name: &str) -> Expr {
1856 Expr(Expression::Subquery(Box::new(Subquery {
1857 this: expr,
1858 alias: Some(Identifier::new(alias_name)),
1859 column_aliases: Vec::new(),
1860 order_by: None,
1861 limit: None,
1862 offset: None,
1863 distribute_by: None,
1864 sort_by: None,
1865 cluster_by: None,
1866 lateral: false,
1867 modifiers_inside: true,
1868 trailing_comments: Vec::new(),
1869 })))
1870}
1871
1872#[derive(Debug, Clone, Copy)]
1878enum SetOpKind {
1879 Union,
1880 Intersect,
1881 Except,
1882}
1883
1884pub struct SetOpBuilder {
1905 kind: SetOpKind,
1906 left: Expression,
1907 right: Expression,
1908 all: bool,
1909 order_by: Option<OrderBy>,
1910 limit: Option<Box<Expression>>,
1911 offset: Option<Box<Expression>>,
1912}
1913
1914impl SetOpBuilder {
1915 fn new(kind: SetOpKind, left: SelectBuilder, right: SelectBuilder, all: bool) -> Self {
1916 SetOpBuilder {
1917 kind,
1918 left: left.build(),
1919 right: right.build(),
1920 all,
1921 order_by: None,
1922 limit: None,
1923 offset: None,
1924 }
1925 }
1926
1927 pub fn order_by<I, E>(mut self, expressions: I) -> Self
1932 where
1933 I: IntoIterator<Item = E>,
1934 E: IntoExpr,
1935 {
1936 self.order_by = Some(OrderBy {
1937 siblings: false,
1938 expressions: expressions
1939 .into_iter()
1940 .map(|e| {
1941 let expr = e.into_expr().0;
1942 match expr {
1943 Expression::Ordered(o) => *o,
1944 other => Ordered {
1945 this: other,
1946 desc: false,
1947 nulls_first: None,
1948 explicit_asc: false,
1949 with_fill: None,
1950 },
1951 }
1952 })
1953 .collect(),
1954 });
1955 self
1956 }
1957
1958 pub fn limit(mut self, count: usize) -> Self {
1960 self.limit = Some(Box::new(Expression::Literal(Literal::Number(
1961 count.to_string(),
1962 ))));
1963 self
1964 }
1965
1966 pub fn offset(mut self, count: usize) -> Self {
1968 self.offset = Some(Box::new(Expression::Literal(Literal::Number(
1969 count.to_string(),
1970 ))));
1971 self
1972 }
1973
1974 pub fn build(self) -> Expression {
1979 match self.kind {
1980 SetOpKind::Union => Expression::Union(Box::new(Union {
1981 left: self.left,
1982 right: self.right,
1983 all: self.all,
1984 distinct: false,
1985 with: None,
1986 order_by: self.order_by,
1987 limit: self.limit,
1988 offset: self.offset,
1989 distribute_by: None,
1990 sort_by: None,
1991 cluster_by: None,
1992 by_name: false,
1993 side: None,
1994 kind: None,
1995 corresponding: false,
1996 strict: false,
1997 on_columns: Vec::new(),
1998 })),
1999 SetOpKind::Intersect => Expression::Intersect(Box::new(Intersect {
2000 left: self.left,
2001 right: self.right,
2002 all: self.all,
2003 distinct: false,
2004 with: None,
2005 order_by: self.order_by,
2006 limit: self.limit,
2007 offset: self.offset,
2008 distribute_by: None,
2009 sort_by: None,
2010 cluster_by: None,
2011 by_name: false,
2012 side: None,
2013 kind: None,
2014 corresponding: false,
2015 strict: false,
2016 on_columns: Vec::new(),
2017 })),
2018 SetOpKind::Except => Expression::Except(Box::new(Except {
2019 left: self.left,
2020 right: self.right,
2021 all: self.all,
2022 distinct: false,
2023 with: None,
2024 order_by: self.order_by,
2025 limit: self.limit,
2026 offset: self.offset,
2027 distribute_by: None,
2028 sort_by: None,
2029 cluster_by: None,
2030 by_name: false,
2031 side: None,
2032 kind: None,
2033 corresponding: false,
2034 strict: false,
2035 on_columns: Vec::new(),
2036 })),
2037 }
2038 }
2039
2040 pub fn to_sql(self) -> String {
2042 Generator::sql(&self.build()).unwrap_or_default()
2043 }
2044}
2045
2046pub fn union(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2050 SetOpBuilder::new(SetOpKind::Union, left, right, false)
2051}
2052
2053pub fn union_all(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2057 SetOpBuilder::new(SetOpKind::Union, left, right, true)
2058}
2059
2060pub fn intersect(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2064 SetOpBuilder::new(SetOpKind::Intersect, left, right, false)
2065}
2066
2067pub fn intersect_all(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2071 SetOpBuilder::new(SetOpKind::Intersect, left, right, true)
2072}
2073
2074pub fn except_(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2078 SetOpBuilder::new(SetOpKind::Except, left, right, false)
2079}
2080
2081pub fn except_all(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2085 SetOpBuilder::new(SetOpKind::Except, left, right, true)
2086}
2087
2088pub struct WindowDefBuilder {
2113 partition_by: Vec<Expression>,
2114 order_by: Vec<Ordered>,
2115}
2116
2117impl WindowDefBuilder {
2118 pub fn new() -> Self {
2120 WindowDefBuilder {
2121 partition_by: Vec::new(),
2122 order_by: Vec::new(),
2123 }
2124 }
2125
2126 pub fn partition_by<I, E>(mut self, expressions: I) -> Self
2128 where
2129 I: IntoIterator<Item = E>,
2130 E: IntoExpr,
2131 {
2132 self.partition_by = expressions.into_iter().map(|e| e.into_expr().0).collect();
2133 self
2134 }
2135
2136 pub fn order_by<I, E>(mut self, expressions: I) -> Self
2141 where
2142 I: IntoIterator<Item = E>,
2143 E: IntoExpr,
2144 {
2145 self.order_by = expressions
2146 .into_iter()
2147 .map(|e| {
2148 let expr = e.into_expr().0;
2149 match expr {
2150 Expression::Ordered(o) => *o,
2151 other => Ordered {
2152 this: other,
2153 desc: false,
2154 nulls_first: None,
2155 explicit_asc: false,
2156 with_fill: None,
2157 },
2158 }
2159 })
2160 .collect();
2161 self
2162 }
2163}
2164
2165pub trait IntoExpr {
2181 fn into_expr(self) -> Expr;
2183}
2184
2185impl IntoExpr for Expr {
2186 fn into_expr(self) -> Expr {
2187 self
2188 }
2189}
2190
2191impl IntoExpr for &str {
2192 fn into_expr(self) -> Expr {
2194 col(self)
2195 }
2196}
2197
2198impl IntoExpr for String {
2199 fn into_expr(self) -> Expr {
2201 col(&self)
2202 }
2203}
2204
2205impl IntoExpr for Expression {
2206 fn into_expr(self) -> Expr {
2208 Expr(self)
2209 }
2210}
2211
2212pub trait IntoLiteral {
2227 fn into_literal(self) -> Expr;
2229}
2230
2231impl IntoLiteral for &str {
2232 fn into_literal(self) -> Expr {
2234 Expr(Expression::Literal(Literal::String(self.to_string())))
2235 }
2236}
2237
2238impl IntoLiteral for String {
2239 fn into_literal(self) -> Expr {
2241 Expr(Expression::Literal(Literal::String(self)))
2242 }
2243}
2244
2245impl IntoLiteral for i64 {
2246 fn into_literal(self) -> Expr {
2248 Expr(Expression::Literal(Literal::Number(self.to_string())))
2249 }
2250}
2251
2252impl IntoLiteral for i32 {
2253 fn into_literal(self) -> Expr {
2255 Expr(Expression::Literal(Literal::Number(self.to_string())))
2256 }
2257}
2258
2259impl IntoLiteral for usize {
2260 fn into_literal(self) -> Expr {
2262 Expr(Expression::Literal(Literal::Number(self.to_string())))
2263 }
2264}
2265
2266impl IntoLiteral for f64 {
2267 fn into_literal(self) -> Expr {
2269 Expr(Expression::Literal(Literal::Number(self.to_string())))
2270 }
2271}
2272
2273impl IntoLiteral for bool {
2274 fn into_literal(self) -> Expr {
2276 Expr(Expression::Boolean(BooleanLiteral { value: self }))
2277 }
2278}
2279
2280fn binary_op(left: Expression, right: Expression) -> BinaryOp {
2285 BinaryOp {
2286 left,
2287 right,
2288 left_comments: Vec::new(),
2289 operator_comments: Vec::new(),
2290 trailing_comments: Vec::new(),
2291 }
2292}
2293
2294pub fn merge_into(target: &str) -> MergeBuilder {
2316 MergeBuilder {
2317 target: Expression::Table(TableRef::new(target)),
2318 using: None,
2319 on: None,
2320 whens: Vec::new(),
2321 }
2322}
2323
2324pub struct MergeBuilder {
2328 target: Expression,
2329 using: Option<Expression>,
2330 on: Option<Expression>,
2331 whens: Vec<Expression>,
2332}
2333
2334impl MergeBuilder {
2335 pub fn using(mut self, source: &str, on: Expr) -> Self {
2337 self.using = Some(Expression::Table(TableRef::new(source)));
2338 self.on = Some(on.0);
2339 self
2340 }
2341
2342 pub fn when_matched_update(mut self, assignments: Vec<(&str, Expr)>) -> Self {
2344 let eqs: Vec<Expression> = assignments
2345 .into_iter()
2346 .map(|(col_name, val)| {
2347 Expression::Eq(Box::new(BinaryOp {
2348 left: Expression::Column(Column {
2349 name: Identifier::new(col_name),
2350 table: None,
2351 join_mark: false,
2352 trailing_comments: Vec::new(),
2353 }),
2354 right: val.0,
2355 left_comments: Vec::new(),
2356 operator_comments: Vec::new(),
2357 trailing_comments: Vec::new(),
2358 }))
2359 })
2360 .collect();
2361
2362 let action = Expression::Tuple(Box::new(Tuple {
2363 expressions: vec![
2364 Expression::Var(Box::new(Var {
2365 this: "UPDATE".to_string(),
2366 })),
2367 Expression::Tuple(Box::new(Tuple { expressions: eqs })),
2368 ],
2369 }));
2370
2371 let when = Expression::When(Box::new(When {
2372 matched: Some(Box::new(Expression::Boolean(BooleanLiteral { value: true }))),
2373 source: None,
2374 condition: None,
2375 then: Box::new(action),
2376 }));
2377 self.whens.push(when);
2378 self
2379 }
2380
2381 pub fn when_matched_update_where(
2383 mut self,
2384 condition: Expr,
2385 assignments: Vec<(&str, Expr)>,
2386 ) -> Self {
2387 let eqs: Vec<Expression> = assignments
2388 .into_iter()
2389 .map(|(col_name, val)| {
2390 Expression::Eq(Box::new(BinaryOp {
2391 left: Expression::Column(Column {
2392 name: Identifier::new(col_name),
2393 table: None,
2394 join_mark: false,
2395 trailing_comments: Vec::new(),
2396 }),
2397 right: val.0,
2398 left_comments: Vec::new(),
2399 operator_comments: Vec::new(),
2400 trailing_comments: Vec::new(),
2401 }))
2402 })
2403 .collect();
2404
2405 let action = Expression::Tuple(Box::new(Tuple {
2406 expressions: vec![
2407 Expression::Var(Box::new(Var {
2408 this: "UPDATE".to_string(),
2409 })),
2410 Expression::Tuple(Box::new(Tuple { expressions: eqs })),
2411 ],
2412 }));
2413
2414 let when = Expression::When(Box::new(When {
2415 matched: Some(Box::new(Expression::Boolean(BooleanLiteral { value: true }))),
2416 source: None,
2417 condition: Some(Box::new(condition.0)),
2418 then: Box::new(action),
2419 }));
2420 self.whens.push(when);
2421 self
2422 }
2423
2424 pub fn when_matched_delete(mut self) -> Self {
2426 let action = Expression::Var(Box::new(Var {
2427 this: "DELETE".to_string(),
2428 }));
2429
2430 let when = Expression::When(Box::new(When {
2431 matched: Some(Box::new(Expression::Boolean(BooleanLiteral { value: true }))),
2432 source: None,
2433 condition: None,
2434 then: Box::new(action),
2435 }));
2436 self.whens.push(when);
2437 self
2438 }
2439
2440 pub fn when_not_matched_insert(mut self, columns: &[&str], values: Vec<Expr>) -> Self {
2442 let col_exprs: Vec<Expression> = columns
2443 .iter()
2444 .map(|c| {
2445 Expression::Column(Column {
2446 name: Identifier::new(*c),
2447 table: None,
2448 join_mark: false,
2449 trailing_comments: Vec::new(),
2450 })
2451 })
2452 .collect();
2453 let val_exprs: Vec<Expression> = values.into_iter().map(|v| v.0).collect();
2454
2455 let action = Expression::Tuple(Box::new(Tuple {
2456 expressions: vec![
2457 Expression::Var(Box::new(Var {
2458 this: "INSERT".to_string(),
2459 })),
2460 Expression::Tuple(Box::new(Tuple {
2461 expressions: col_exprs,
2462 })),
2463 Expression::Tuple(Box::new(Tuple {
2464 expressions: val_exprs,
2465 })),
2466 ],
2467 }));
2468
2469 let when = Expression::When(Box::new(When {
2470 matched: Some(Box::new(Expression::Boolean(BooleanLiteral {
2471 value: false,
2472 }))),
2473 source: None,
2474 condition: None,
2475 then: Box::new(action),
2476 }));
2477 self.whens.push(when);
2478 self
2479 }
2480
2481 pub fn build(self) -> Expression {
2483 let whens_expr = Expression::Whens(Box::new(Whens {
2484 expressions: self.whens,
2485 }));
2486
2487 Expression::Merge(Box::new(Merge {
2488 this: Box::new(self.target),
2489 using: Box::new(
2490 self.using
2491 .unwrap_or(Expression::Null(crate::expressions::Null)),
2492 ),
2493 on: self.on.map(Box::new),
2494 using_cond: None,
2495 whens: Some(Box::new(whens_expr)),
2496 with_: None,
2497 returning: None,
2498 }))
2499 }
2500
2501 pub fn to_sql(self) -> String {
2503 Generator::sql(&self.build()).unwrap_or_default()
2504 }
2505}
2506
2507fn parse_simple_data_type(name: &str) -> DataType {
2508 let upper = name.trim().to_uppercase();
2509 match upper.as_str() {
2510 "INT" | "INTEGER" => DataType::Int {
2511 length: None,
2512 integer_spelling: upper == "INTEGER",
2513 },
2514 "BIGINT" => DataType::BigInt { length: None },
2515 "SMALLINT" => DataType::SmallInt { length: None },
2516 "TINYINT" => DataType::TinyInt { length: None },
2517 "FLOAT" => DataType::Float { precision: None, scale: None, real_spelling: false },
2518 "DOUBLE" => DataType::Double {
2519 precision: None,
2520 scale: None,
2521 },
2522 "BOOLEAN" | "BOOL" => DataType::Boolean,
2523 "TEXT" => DataType::Text,
2524 "DATE" => DataType::Date,
2525 "TIMESTAMP" => DataType::Timestamp {
2526 precision: None,
2527 timezone: false,
2528 },
2529 "VARCHAR" => DataType::VarChar {
2530 length: None,
2531 parenthesized_length: false,
2532 },
2533 "CHAR" => DataType::Char { length: None },
2534 _ => {
2535 if let Ok(ast) = crate::parser::Parser::parse_sql(&format!("SELECT CAST(x AS {})", name)) {
2537 if let Expression::Select(s) = &ast[0] {
2538 if let Some(Expression::Cast(c)) = s.expressions.first() {
2539 return c.to.clone();
2540 }
2541 }
2542 }
2543 DataType::Custom { name: name.to_string() }
2545 }
2546 }
2547}
2548
2549#[cfg(test)]
2550mod tests {
2551 use super::*;
2552
2553 #[test]
2554 fn test_simple_select() {
2555 let sql = select(["id", "name"]).from("users").to_sql();
2556 assert_eq!(sql, "SELECT id, name FROM users");
2557 }
2558
2559 #[test]
2560 fn test_select_star() {
2561 let sql = select([star()]).from("users").to_sql();
2562 assert_eq!(sql, "SELECT * FROM users");
2563 }
2564
2565 #[test]
2566 fn test_select_with_where() {
2567 let sql = select(["id", "name"])
2568 .from("users")
2569 .where_(col("age").gt(lit(18)))
2570 .to_sql();
2571 assert_eq!(sql, "SELECT id, name FROM users WHERE age > 18");
2572 }
2573
2574 #[test]
2575 fn test_select_with_join() {
2576 let sql = select(["u.id", "o.amount"])
2577 .from("users")
2578 .join("orders", col("u.id").eq(col("o.user_id")))
2579 .to_sql();
2580 assert_eq!(
2581 sql,
2582 "SELECT u.id, o.amount FROM users JOIN orders ON u.id = o.user_id"
2583 );
2584 }
2585
2586 #[test]
2587 fn test_select_with_group_by_having() {
2588 let sql = select([col("dept"), func("COUNT", [star()]).alias("cnt")])
2589 .from("employees")
2590 .group_by(["dept"])
2591 .having(func("COUNT", [star()]).gt(lit(5)))
2592 .to_sql();
2593 assert_eq!(
2594 sql,
2595 "SELECT dept, COUNT(*) AS cnt FROM employees GROUP BY dept HAVING COUNT(*) > 5"
2596 );
2597 }
2598
2599 #[test]
2600 fn test_select_with_order_limit_offset() {
2601 let sql = select(["id", "name"])
2602 .from("users")
2603 .order_by(["name"])
2604 .limit(10)
2605 .offset(20)
2606 .to_sql();
2607 assert_eq!(
2608 sql,
2609 "SELECT id, name FROM users ORDER BY name LIMIT 10 OFFSET 20"
2610 );
2611 }
2612
2613 #[test]
2614 fn test_select_distinct() {
2615 let sql = select(["name"]).from("users").distinct().to_sql();
2616 assert_eq!(sql, "SELECT DISTINCT name FROM users");
2617 }
2618
2619 #[test]
2620 fn test_insert_values() {
2621 let sql = insert_into("users")
2622 .columns(["id", "name"])
2623 .values([lit(1), lit("Alice")])
2624 .values([lit(2), lit("Bob")])
2625 .to_sql();
2626 assert_eq!(
2627 sql,
2628 "INSERT INTO users (id, name) VALUES (1, 'Alice'), (2, 'Bob')"
2629 );
2630 }
2631
2632 #[test]
2633 fn test_insert_select() {
2634 let sql = insert_into("archive")
2635 .columns(["id", "name"])
2636 .query(select(["id", "name"]).from("users"))
2637 .to_sql();
2638 assert_eq!(
2639 sql,
2640 "INSERT INTO archive (id, name) SELECT id, name FROM users"
2641 );
2642 }
2643
2644 #[test]
2645 fn test_update() {
2646 let sql = update("users")
2647 .set("name", lit("Bob"))
2648 .set("age", lit(30))
2649 .where_(col("id").eq(lit(1)))
2650 .to_sql();
2651 assert_eq!(
2652 sql,
2653 "UPDATE users SET name = 'Bob', age = 30 WHERE id = 1"
2654 );
2655 }
2656
2657 #[test]
2658 fn test_delete() {
2659 let sql = delete("users")
2660 .where_(col("id").eq(lit(1)))
2661 .to_sql();
2662 assert_eq!(sql, "DELETE FROM users WHERE id = 1");
2663 }
2664
2665 #[test]
2666 fn test_complex_where() {
2667 let sql = select(["id"])
2668 .from("users")
2669 .where_(
2670 col("age").gte(lit(18))
2671 .and(col("active").eq(boolean(true)))
2672 .and(col("name").like(lit("%test%"))),
2673 )
2674 .to_sql();
2675 assert_eq!(
2676 sql,
2677 "SELECT id FROM users WHERE age >= 18 AND active = TRUE AND name LIKE '%test%'"
2678 );
2679 }
2680
2681 #[test]
2682 fn test_in_list() {
2683 let sql = select(["id"])
2684 .from("users")
2685 .where_(col("status").in_list([lit("active"), lit("pending")]))
2686 .to_sql();
2687 assert_eq!(
2688 sql,
2689 "SELECT id FROM users WHERE status IN ('active', 'pending')"
2690 );
2691 }
2692
2693 #[test]
2694 fn test_between() {
2695 let sql = select(["id"])
2696 .from("orders")
2697 .where_(col("amount").between(lit(100), lit(500)))
2698 .to_sql();
2699 assert_eq!(
2700 sql,
2701 "SELECT id FROM orders WHERE amount BETWEEN 100 AND 500"
2702 );
2703 }
2704
2705 #[test]
2706 fn test_is_null() {
2707 let sql = select(["id"])
2708 .from("users")
2709 .where_(col("email").is_null())
2710 .to_sql();
2711 assert_eq!(sql, "SELECT id FROM users WHERE email IS NULL");
2712 }
2713
2714 #[test]
2715 fn test_arithmetic() {
2716 let sql = select([col("price").mul(col("quantity")).alias("total")])
2717 .from("items")
2718 .to_sql();
2719 assert_eq!(sql, "SELECT price * quantity AS total FROM items");
2720 }
2721
2722 #[test]
2723 fn test_cast() {
2724 let sql = select([col("id").cast("VARCHAR")])
2725 .from("users")
2726 .to_sql();
2727 assert_eq!(sql, "SELECT CAST(id AS VARCHAR) FROM users");
2728 }
2729
2730 #[test]
2731 fn test_from_starter() {
2732 let sql = from("users").select_cols(["id", "name"]).to_sql();
2733 assert_eq!(sql, "SELECT id, name FROM users");
2734 }
2735
2736 #[test]
2737 fn test_qualified_column() {
2738 let sql = select([col("u.id"), col("u.name")])
2739 .from("users")
2740 .to_sql();
2741 assert_eq!(sql, "SELECT u.id, u.name FROM users");
2742 }
2743
2744 #[test]
2745 fn test_not_condition() {
2746 let sql = select(["id"])
2747 .from("users")
2748 .where_(not(col("active").eq(boolean(true))))
2749 .to_sql();
2750 assert_eq!(sql, "SELECT id FROM users WHERE NOT active = TRUE");
2751 }
2752
2753 #[test]
2754 fn test_order_by_desc() {
2755 let sql = select(["id", "name"])
2756 .from("users")
2757 .order_by([col("name").desc()])
2758 .to_sql();
2759 assert_eq!(sql, "SELECT id, name FROM users ORDER BY name DESC");
2760 }
2761
2762 #[test]
2763 fn test_left_join() {
2764 let sql = select(["u.id", "o.amount"])
2765 .from("users")
2766 .left_join("orders", col("u.id").eq(col("o.user_id")))
2767 .to_sql();
2768 assert_eq!(
2769 sql,
2770 "SELECT u.id, o.amount FROM users LEFT JOIN orders ON u.id = o.user_id"
2771 );
2772 }
2773
2774 #[test]
2775 fn test_build_returns_expression() {
2776 let expr = select(["id"]).from("users").build();
2777 assert!(matches!(expr, Expression::Select(_)));
2778 }
2779
2780 #[test]
2781 fn test_expr_interop() {
2782 let age_check = col("age").gt(lit(18));
2784 let sql = select([col("id"), age_check.alias("is_adult")])
2785 .from("users")
2786 .to_sql();
2787 assert_eq!(sql, "SELECT id, age > 18 AS is_adult FROM users");
2788 }
2789
2790 #[test]
2793 fn test_sql_expr_simple() {
2794 let expr = sql_expr("age > 18");
2795 let sql = select(["id"])
2796 .from("users")
2797 .where_(expr)
2798 .to_sql();
2799 assert_eq!(sql, "SELECT id FROM users WHERE age > 18");
2800 }
2801
2802 #[test]
2803 fn test_sql_expr_compound() {
2804 let expr = sql_expr("a > 1 AND b < 10");
2805 let sql = select(["*"])
2806 .from("t")
2807 .where_(expr)
2808 .to_sql();
2809 assert_eq!(sql, "SELECT * FROM t WHERE a > 1 AND b < 10");
2810 }
2811
2812 #[test]
2813 fn test_sql_expr_function() {
2814 let expr = sql_expr("COALESCE(a, b, 0)");
2815 let sql = select([expr.alias("val")]).from("t").to_sql();
2816 assert_eq!(sql, "SELECT COALESCE(a, b, 0) AS val FROM t");
2817 }
2818
2819 #[test]
2820 fn test_condition_alias() {
2821 let cond = condition("x > 0");
2822 let sql = select(["*"]).from("t").where_(cond).to_sql();
2823 assert_eq!(sql, "SELECT * FROM t WHERE x > 0");
2824 }
2825
2826 #[test]
2829 fn test_ilike() {
2830 let sql = select(["id"])
2831 .from("users")
2832 .where_(col("name").ilike(lit("%test%")))
2833 .to_sql();
2834 assert_eq!(sql, "SELECT id FROM users WHERE name ILIKE '%test%'");
2835 }
2836
2837 #[test]
2838 fn test_rlike() {
2839 let sql = select(["id"])
2840 .from("users")
2841 .where_(col("name").rlike(lit("^[A-Z]")))
2842 .to_sql();
2843 assert_eq!(sql, "SELECT id FROM users WHERE REGEXP_LIKE(name, '^[A-Z]')");
2844 }
2845
2846 #[test]
2847 fn test_not_in() {
2848 let sql = select(["id"])
2849 .from("users")
2850 .where_(col("status").not_in([lit("deleted"), lit("banned")]))
2851 .to_sql();
2852 assert_eq!(
2853 sql,
2854 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
2855 );
2856 }
2857
2858 #[test]
2861 fn test_case_searched() {
2862 let expr = case()
2863 .when(col("x").gt(lit(0)), lit("positive"))
2864 .when(col("x").eq(lit(0)), lit("zero"))
2865 .else_(lit("negative"))
2866 .build();
2867 let sql = select([expr.alias("label")]).from("t").to_sql();
2868 assert_eq!(
2869 sql,
2870 "SELECT CASE WHEN x > 0 THEN 'positive' WHEN x = 0 THEN 'zero' ELSE 'negative' END AS label FROM t"
2871 );
2872 }
2873
2874 #[test]
2875 fn test_case_simple() {
2876 let expr = case_of(col("status"))
2877 .when(lit(1), lit("active"))
2878 .when(lit(0), lit("inactive"))
2879 .build();
2880 let sql = select([expr.alias("status_label")]).from("t").to_sql();
2881 assert_eq!(
2882 sql,
2883 "SELECT CASE status WHEN 1 THEN 'active' WHEN 0 THEN 'inactive' END AS status_label FROM t"
2884 );
2885 }
2886
2887 #[test]
2888 fn test_case_no_else() {
2889 let expr = case()
2890 .when(col("x").gt(lit(0)), lit("yes"))
2891 .build();
2892 let sql = select([expr]).from("t").to_sql();
2893 assert_eq!(sql, "SELECT CASE WHEN x > 0 THEN 'yes' END FROM t");
2894 }
2895
2896 #[test]
2899 fn test_subquery_in_from() {
2900 let inner = select(["id", "name"]).from("users").where_(col("active").eq(boolean(true)));
2901 let outer = select(["sub.id"])
2902 .from_expr(subquery(inner, "sub"))
2903 .to_sql();
2904 assert_eq!(
2905 outer,
2906 "SELECT sub.id FROM (SELECT id, name FROM users WHERE active = TRUE) AS sub"
2907 );
2908 }
2909
2910 #[test]
2911 fn test_subquery_in_join() {
2912 let inner = select([col("user_id"), func("SUM", [col("amount")]).alias("total")])
2913 .from("orders")
2914 .group_by(["user_id"]);
2915 let sql = select(["u.name", "o.total"])
2916 .from("users")
2917 .join("orders", col("u.id").eq(col("o.user_id")))
2918 .to_sql();
2919 assert!(sql.contains("JOIN"));
2920 let _sub = subquery(inner, "o");
2922 }
2923
2924 #[test]
2927 fn test_union() {
2928 let sql = union(
2929 select(["id"]).from("a"),
2930 select(["id"]).from("b"),
2931 )
2932 .to_sql();
2933 assert_eq!(sql, "SELECT id FROM a UNION SELECT id FROM b");
2934 }
2935
2936 #[test]
2937 fn test_union_all() {
2938 let sql = union_all(
2939 select(["id"]).from("a"),
2940 select(["id"]).from("b"),
2941 )
2942 .to_sql();
2943 assert_eq!(sql, "SELECT id FROM a UNION ALL SELECT id FROM b");
2944 }
2945
2946 #[test]
2947 fn test_intersect_builder() {
2948 let sql = intersect(
2949 select(["id"]).from("a"),
2950 select(["id"]).from("b"),
2951 )
2952 .to_sql();
2953 assert_eq!(sql, "SELECT id FROM a INTERSECT SELECT id FROM b");
2954 }
2955
2956 #[test]
2957 fn test_except_builder() {
2958 let sql = except_(
2959 select(["id"]).from("a"),
2960 select(["id"]).from("b"),
2961 )
2962 .to_sql();
2963 assert_eq!(sql, "SELECT id FROM a EXCEPT SELECT id FROM b");
2964 }
2965
2966 #[test]
2967 fn test_union_with_order_limit() {
2968 let sql = union(
2969 select(["id"]).from("a"),
2970 select(["id"]).from("b"),
2971 )
2972 .order_by(["id"])
2973 .limit(10)
2974 .to_sql();
2975 assert!(sql.contains("UNION"));
2976 assert!(sql.contains("ORDER BY"));
2977 assert!(sql.contains("LIMIT"));
2978 }
2979
2980 #[test]
2981 fn test_select_builder_union() {
2982 let sql = select(["id"])
2983 .from("a")
2984 .union(select(["id"]).from("b"))
2985 .to_sql();
2986 assert_eq!(sql, "SELECT id FROM a UNION SELECT id FROM b");
2987 }
2988
2989 #[test]
2992 fn test_qualify() {
2993 let sql = select(["id", "name"])
2994 .from("users")
2995 .qualify(col("rn").eq(lit(1)))
2996 .to_sql();
2997 assert_eq!(
2998 sql,
2999 "SELECT id, name FROM users QUALIFY rn = 1"
3000 );
3001 }
3002
3003 #[test]
3004 fn test_right_join() {
3005 let sql = select(["u.id", "o.amount"])
3006 .from("users")
3007 .right_join("orders", col("u.id").eq(col("o.user_id")))
3008 .to_sql();
3009 assert_eq!(
3010 sql,
3011 "SELECT u.id, o.amount FROM users RIGHT JOIN orders ON u.id = o.user_id"
3012 );
3013 }
3014
3015 #[test]
3016 fn test_cross_join() {
3017 let sql = select(["a.x", "b.y"])
3018 .from("a")
3019 .cross_join("b")
3020 .to_sql();
3021 assert_eq!(sql, "SELECT a.x, b.y FROM a CROSS JOIN b");
3022 }
3023
3024 #[test]
3025 fn test_lateral_view() {
3026 let sql = select(["id", "col_val"])
3027 .from("t")
3028 .lateral_view(func("EXPLODE", [col("arr")]), "lv", ["col_val"])
3029 .to_sql();
3030 assert!(sql.contains("LATERAL VIEW"));
3031 assert!(sql.contains("EXPLODE"));
3032 }
3033
3034 #[test]
3035 fn test_window_clause() {
3036 let sql = select(["id"])
3037 .from("t")
3038 .window(
3039 "w",
3040 WindowDefBuilder::new()
3041 .partition_by(["dept"])
3042 .order_by(["salary"]),
3043 )
3044 .to_sql();
3045 assert!(sql.contains("WINDOW"));
3046 assert!(sql.contains("PARTITION BY"));
3047 }
3048
3049 #[test]
3052 fn test_xor() {
3053 let sql = select(["*"])
3054 .from("t")
3055 .where_(col("a").xor(col("b")))
3056 .to_sql();
3057 assert_eq!(sql, "SELECT * FROM t WHERE a XOR b");
3058 }
3059
3060 #[test]
3063 fn test_for_update() {
3064 let sql = select(["id"]).from("t").for_update().to_sql();
3065 assert_eq!(sql, "SELECT id FROM t FOR UPDATE");
3066 }
3067
3068 #[test]
3069 fn test_for_share() {
3070 let sql = select(["id"]).from("t").for_share().to_sql();
3071 assert_eq!(sql, "SELECT id FROM t FOR SHARE");
3072 }
3073
3074 #[test]
3077 fn test_hint() {
3078 let sql = select(["*"]).from("t").hint("FULL(t)").to_sql();
3079 assert!(sql.contains("FULL(t)"), "Expected hint in: {}", sql);
3080 }
3081
3082 #[test]
3085 fn test_ctas() {
3086 let expr = select(["*"]).from("t").ctas("new_table");
3087 let sql = Generator::sql(&expr).unwrap();
3088 assert_eq!(sql, "CREATE TABLE new_table AS SELECT * FROM t");
3089 }
3090
3091 #[test]
3094 fn test_merge_update_insert() {
3095 let sql = merge_into("target")
3096 .using("source", col("target.id").eq(col("source.id")))
3097 .when_matched_update(vec![("name", col("source.name"))])
3098 .when_not_matched_insert(
3099 &["id", "name"],
3100 vec![col("source.id"), col("source.name")],
3101 )
3102 .to_sql();
3103 assert!(sql.contains("MERGE INTO"), "Expected MERGE INTO in: {}", sql);
3104 assert!(sql.contains("USING"), "Expected USING in: {}", sql);
3105 assert!(sql.contains("WHEN MATCHED"), "Expected WHEN MATCHED in: {}", sql);
3106 assert!(sql.contains("UPDATE SET"), "Expected UPDATE SET in: {}", sql);
3107 assert!(
3108 sql.contains("WHEN NOT MATCHED"),
3109 "Expected WHEN NOT MATCHED in: {}",
3110 sql
3111 );
3112 assert!(sql.contains("INSERT"), "Expected INSERT in: {}", sql);
3113 }
3114
3115 #[test]
3116 fn test_merge_delete() {
3117 let sql = merge_into("target")
3118 .using("source", col("target.id").eq(col("source.id")))
3119 .when_matched_delete()
3120 .to_sql();
3121 assert!(sql.contains("MERGE INTO"), "Expected MERGE INTO in: {}", sql);
3122 assert!(sql.contains("WHEN MATCHED THEN DELETE"), "Expected WHEN MATCHED THEN DELETE in: {}", sql);
3123 }
3124
3125 #[test]
3126 fn test_merge_with_condition() {
3127 let sql = merge_into("target")
3128 .using("source", col("target.id").eq(col("source.id")))
3129 .when_matched_update_where(
3130 col("source.active").eq(boolean(true)),
3131 vec![("name", col("source.name"))],
3132 )
3133 .to_sql();
3134 assert!(sql.contains("MERGE INTO"), "Expected MERGE INTO in: {}", sql);
3135 assert!(sql.contains("AND source.active = TRUE"), "Expected condition in: {}", sql);
3136 }
3137}