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(Expression::Is(
985 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 is_field: false,
1007 })))
1008 }
1009
1010 pub fn between(self, low: Expr, high: Expr) -> Expr {
1012 Expr(Expression::Between(Box::new(Between {
1013 this: self.0,
1014 low: low.0,
1015 high: high.0,
1016 not: false,
1017 symmetric: None,
1018 })))
1019 }
1020
1021 pub fn like(self, pattern: Expr) -> Expr {
1023 Expr(Expression::Like(Box::new(LikeOp {
1024 left: self.0,
1025 right: pattern.0,
1026 escape: None,
1027 quantifier: None,
1028 })))
1029 }
1030
1031 pub fn alias(self, name: &str) -> Expr {
1033 alias(self, name)
1034 }
1035
1036 pub fn cast(self, to: &str) -> Expr {
1040 cast(self, to)
1041 }
1042
1043 pub fn asc(self) -> Expr {
1048 Expr(Expression::Ordered(Box::new(Ordered {
1049 this: self.0,
1050 desc: false,
1051 nulls_first: None,
1052 explicit_asc: true,
1053 with_fill: None,
1054 })))
1055 }
1056
1057 pub fn desc(self) -> Expr {
1061 Expr(Expression::Ordered(Box::new(Ordered {
1062 this: self.0,
1063 desc: true,
1064 nulls_first: None,
1065 explicit_asc: false,
1066 with_fill: None,
1067 })))
1068 }
1069
1070 pub fn ilike(self, pattern: Expr) -> Expr {
1075 Expr(Expression::ILike(Box::new(LikeOp {
1076 left: self.0,
1077 right: pattern.0,
1078 escape: None,
1079 quantifier: None,
1080 })))
1081 }
1082
1083 pub fn rlike(self, pattern: Expr) -> Expr {
1088 Expr(Expression::RegexpLike(Box::new(RegexpFunc {
1089 this: self.0,
1090 pattern: pattern.0,
1091 flags: None,
1092 })))
1093 }
1094
1095 pub fn not_in(self, values: impl IntoIterator<Item = Expr>) -> Expr {
1099 Expr(Expression::In(Box::new(In {
1100 this: self.0,
1101 expressions: values.into_iter().map(|v| v.0).collect(),
1102 query: None,
1103 not: true,
1104 global: false,
1105 unnest: None,
1106 is_field: false,
1107 })))
1108 }
1109}
1110
1111pub struct SelectBuilder {
1137 select: Select,
1138}
1139
1140impl SelectBuilder {
1141 fn new() -> Self {
1142 SelectBuilder {
1143 select: Select::new(),
1144 }
1145 }
1146
1147 pub fn select_cols<I, E>(mut self, expressions: I) -> Self
1152 where
1153 I: IntoIterator<Item = E>,
1154 E: IntoExpr,
1155 {
1156 for expr in expressions {
1157 self.select.expressions.push(expr.into_expr().0);
1158 }
1159 self
1160 }
1161
1162 pub fn from(mut self, table_name: &str) -> Self {
1164 self.select.from = Some(From {
1165 expressions: vec![Expression::Table(TableRef::new(table_name))],
1166 });
1167 self
1168 }
1169
1170 pub fn from_expr(mut self, expr: Expr) -> Self {
1175 self.select.from = Some(From {
1176 expressions: vec![expr.0],
1177 });
1178 self
1179 }
1180
1181 pub fn join(mut self, table_name: &str, on: Expr) -> Self {
1183 self.select.joins.push(Join {
1184 kind: JoinKind::Inner,
1185 this: Expression::Table(TableRef::new(table_name)),
1186 on: Some(on.0),
1187 using: Vec::new(),
1188 use_inner_keyword: false,
1189 use_outer_keyword: false,
1190 deferred_condition: false,
1191 join_hint: None,
1192 match_condition: None,
1193 pivots: Vec::new(),
1194 comments: Vec::new(),
1195 nesting_group: 0,
1196 directed: false,
1197 });
1198 self
1199 }
1200
1201 pub fn left_join(mut self, table_name: &str, on: Expr) -> Self {
1203 self.select.joins.push(Join {
1204 kind: JoinKind::Left,
1205 this: Expression::Table(TableRef::new(table_name)),
1206 on: Some(on.0),
1207 using: Vec::new(),
1208 use_inner_keyword: false,
1209 use_outer_keyword: false,
1210 deferred_condition: false,
1211 join_hint: None,
1212 match_condition: None,
1213 pivots: Vec::new(),
1214 comments: Vec::new(),
1215 nesting_group: 0,
1216 directed: false,
1217 });
1218 self
1219 }
1220
1221 pub fn where_(mut self, condition: Expr) -> Self {
1227 self.select.where_clause = Some(Where { this: condition.0 });
1228 self
1229 }
1230
1231 pub fn group_by<I, E>(mut self, expressions: I) -> Self
1233 where
1234 I: IntoIterator<Item = E>,
1235 E: IntoExpr,
1236 {
1237 self.select.group_by = Some(GroupBy {
1238 expressions: expressions.into_iter().map(|e| e.into_expr().0).collect(),
1239 all: None,
1240 totals: false,
1241 comments: Vec::new(),
1242 });
1243 self
1244 }
1245
1246 pub fn having(mut self, condition: Expr) -> Self {
1248 self.select.having = Some(Having {
1249 this: condition.0,
1250 comments: Vec::new(),
1251 });
1252 self
1253 }
1254
1255 pub fn order_by<I, E>(mut self, expressions: I) -> Self
1261 where
1262 I: IntoIterator<Item = E>,
1263 E: IntoExpr,
1264 {
1265 self.select.order_by = Some(OrderBy {
1266 siblings: false,
1267 comments: Vec::new(),
1268 expressions: expressions
1269 .into_iter()
1270 .map(|e| {
1271 let expr = e.into_expr().0;
1272 match expr {
1273 Expression::Ordered(_) => expr,
1274 other => Expression::Ordered(Box::new(Ordered {
1275 this: other,
1276 desc: false,
1277 nulls_first: None,
1278 explicit_asc: false,
1279 with_fill: None,
1280 })),
1281 }
1282 })
1283 .collect::<Vec<_>>()
1284 .into_iter()
1285 .map(|e| {
1286 if let Expression::Ordered(o) = e {
1287 *o
1288 } else {
1289 Ordered {
1290 this: e,
1291 desc: false,
1292 nulls_first: None,
1293 explicit_asc: false,
1294 with_fill: None,
1295 }
1296 }
1297 })
1298 .collect(),
1299 });
1300 self
1301 }
1302
1303 pub fn sort_by<I, E>(mut self, expressions: I) -> Self
1310 where
1311 I: IntoIterator<Item = E>,
1312 E: IntoExpr,
1313 {
1314 self.select.sort_by = Some(SortBy {
1315 expressions: expressions
1316 .into_iter()
1317 .map(|e| {
1318 let expr = e.into_expr().0;
1319 match expr {
1320 Expression::Ordered(o) => *o,
1321 other => Ordered {
1322 this: other,
1323 desc: false,
1324 nulls_first: None,
1325 explicit_asc: false,
1326 with_fill: None,
1327 },
1328 }
1329 })
1330 .collect(),
1331 });
1332 self
1333 }
1334
1335 pub fn limit(mut self, count: usize) -> Self {
1337 self.select.limit = Some(Limit {
1338 this: Expression::Literal(Literal::Number(count.to_string())),
1339 percent: false,
1340 comments: Vec::new(),
1341 });
1342 self
1343 }
1344
1345 pub fn offset(mut self, count: usize) -> Self {
1347 self.select.offset = Some(Offset {
1348 this: Expression::Literal(Literal::Number(count.to_string())),
1349 rows: None,
1350 });
1351 self
1352 }
1353
1354 pub fn distinct(mut self) -> Self {
1356 self.select.distinct = true;
1357 self
1358 }
1359
1360 pub fn qualify(mut self, condition: Expr) -> Self {
1365 self.select.qualify = Some(Qualify { this: condition.0 });
1366 self
1367 }
1368
1369 pub fn right_join(mut self, table_name: &str, on: Expr) -> Self {
1371 self.select.joins.push(Join {
1372 kind: JoinKind::Right,
1373 this: Expression::Table(TableRef::new(table_name)),
1374 on: Some(on.0),
1375 using: Vec::new(),
1376 use_inner_keyword: false,
1377 use_outer_keyword: false,
1378 deferred_condition: false,
1379 join_hint: None,
1380 match_condition: None,
1381 pivots: Vec::new(),
1382 comments: Vec::new(),
1383 nesting_group: 0,
1384 directed: false,
1385 });
1386 self
1387 }
1388
1389 pub fn cross_join(mut self, table_name: &str) -> Self {
1391 self.select.joins.push(Join {
1392 kind: JoinKind::Cross,
1393 this: Expression::Table(TableRef::new(table_name)),
1394 on: None,
1395 using: Vec::new(),
1396 use_inner_keyword: false,
1397 use_outer_keyword: false,
1398 deferred_condition: false,
1399 join_hint: None,
1400 match_condition: None,
1401 pivots: Vec::new(),
1402 comments: Vec::new(),
1403 nesting_group: 0,
1404 directed: false,
1405 });
1406 self
1407 }
1408
1409 pub fn lateral_view<S: AsRef<str>>(
1416 mut self,
1417 table_function: Expr,
1418 table_alias: &str,
1419 column_aliases: impl IntoIterator<Item = S>,
1420 ) -> Self {
1421 self.select.lateral_views.push(LateralView {
1422 this: table_function.0,
1423 table_alias: Some(Identifier::new(table_alias)),
1424 column_aliases: column_aliases
1425 .into_iter()
1426 .map(|c| Identifier::new(c.as_ref()))
1427 .collect(),
1428 outer: false,
1429 });
1430 self
1431 }
1432
1433 pub fn window(mut self, name: &str, def: WindowDefBuilder) -> Self {
1439 let named_window = NamedWindow {
1440 name: Identifier::new(name),
1441 spec: Over {
1442 window_name: None,
1443 partition_by: def.partition_by,
1444 order_by: def.order_by,
1445 frame: None,
1446 alias: None,
1447 },
1448 };
1449 match self.select.windows {
1450 Some(ref mut windows) => windows.push(named_window),
1451 None => self.select.windows = Some(vec![named_window]),
1452 }
1453 self
1454 }
1455
1456 pub fn for_update(mut self) -> Self {
1461 self.select.locks.push(Lock {
1462 update: Some(Box::new(Expression::Boolean(BooleanLiteral {
1463 value: true,
1464 }))),
1465 expressions: vec![],
1466 wait: None,
1467 key: None,
1468 });
1469 self
1470 }
1471
1472 pub fn for_share(mut self) -> Self {
1477 self.select.locks.push(Lock {
1478 update: None,
1479 expressions: vec![],
1480 wait: None,
1481 key: None,
1482 });
1483 self
1484 }
1485
1486 pub fn hint(mut self, hint_text: &str) -> Self {
1491 let hint_expr = HintExpression::Raw(hint_text.to_string());
1492 match &mut self.select.hint {
1493 Some(h) => h.expressions.push(hint_expr),
1494 None => {
1495 self.select.hint = Some(Hint {
1496 expressions: vec![hint_expr],
1497 })
1498 }
1499 }
1500 self
1501 }
1502
1503 pub fn ctas(self, table_name: &str) -> Expression {
1519 Expression::CreateTable(Box::new(CreateTable {
1520 name: TableRef::new(table_name),
1521 on_cluster: None,
1522 columns: vec![],
1523 constraints: vec![],
1524 if_not_exists: false,
1525 temporary: false,
1526 or_replace: false,
1527 table_modifier: None,
1528 as_select: Some(self.build()),
1529 as_select_parenthesized: false,
1530 on_commit: None,
1531 clone_source: None,
1532 clone_at_clause: None,
1533 is_copy: false,
1534 shallow_clone: false,
1535 leading_comments: vec![],
1536 with_properties: vec![],
1537 teradata_post_name_options: vec![],
1538 with_data: None,
1539 with_statistics: None,
1540 teradata_indexes: vec![],
1541 with_cte: None,
1542 properties: vec![],
1543 partition_of: None,
1544 post_table_properties: vec![],
1545 mysql_table_options: vec![],
1546 inherits: vec![],
1547 on_property: None,
1548 copy_grants: false,
1549 using_template: None,
1550 rollup: None,
1551 }))
1552 }
1553
1554 pub fn union(self, other: SelectBuilder) -> SetOpBuilder {
1558 SetOpBuilder::new(SetOpKind::Union, self, other, false)
1559 }
1560
1561 pub fn union_all(self, other: SelectBuilder) -> SetOpBuilder {
1565 SetOpBuilder::new(SetOpKind::Union, self, other, true)
1566 }
1567
1568 pub fn intersect(self, other: SelectBuilder) -> SetOpBuilder {
1572 SetOpBuilder::new(SetOpKind::Intersect, self, other, false)
1573 }
1574
1575 pub fn except_(self, other: SelectBuilder) -> SetOpBuilder {
1579 SetOpBuilder::new(SetOpKind::Except, self, other, false)
1580 }
1581
1582 pub fn build(self) -> Expression {
1584 Expression::Select(Box::new(self.select))
1585 }
1586
1587 pub fn to_sql(self) -> String {
1592 Generator::sql(&self.build()).unwrap_or_default()
1593 }
1594}
1595
1596pub struct DeleteBuilder {
1605 delete: Delete,
1606}
1607
1608impl DeleteBuilder {
1609 pub fn where_(mut self, condition: Expr) -> Self {
1611 self.delete.where_clause = Some(Where { this: condition.0 });
1612 self
1613 }
1614
1615 pub fn build(self) -> Expression {
1617 Expression::Delete(Box::new(self.delete))
1618 }
1619
1620 pub fn to_sql(self) -> String {
1622 Generator::sql(&self.build()).unwrap_or_default()
1623 }
1624}
1625
1626pub struct InsertBuilder {
1637 insert: Insert,
1638}
1639
1640impl InsertBuilder {
1641 pub fn columns<I, S>(mut self, columns: I) -> Self
1643 where
1644 I: IntoIterator<Item = S>,
1645 S: AsRef<str>,
1646 {
1647 self.insert.columns = columns
1648 .into_iter()
1649 .map(|c| Identifier::new(c.as_ref()))
1650 .collect();
1651 self
1652 }
1653
1654 pub fn values<I>(mut self, values: I) -> Self
1658 where
1659 I: IntoIterator<Item = Expr>,
1660 {
1661 self.insert
1662 .values
1663 .push(values.into_iter().map(|v| v.0).collect());
1664 self
1665 }
1666
1667 pub fn query(mut self, query: SelectBuilder) -> Self {
1671 self.insert.query = Some(query.build());
1672 self
1673 }
1674
1675 pub fn build(self) -> Expression {
1677 Expression::Insert(Box::new(self.insert))
1678 }
1679
1680 pub fn to_sql(self) -> String {
1682 Generator::sql(&self.build()).unwrap_or_default()
1683 }
1684}
1685
1686pub struct UpdateBuilder {
1696 update: Update,
1697}
1698
1699impl UpdateBuilder {
1700 pub fn set(mut self, column: &str, value: Expr) -> Self {
1704 self.update.set.push((Identifier::new(column), value.0));
1705 self
1706 }
1707
1708 pub fn where_(mut self, condition: Expr) -> Self {
1710 self.update.where_clause = Some(Where { this: condition.0 });
1711 self
1712 }
1713
1714 pub fn from(mut self, table_name: &str) -> Self {
1718 self.update.from_clause = Some(From {
1719 expressions: vec![Expression::Table(TableRef::new(table_name))],
1720 });
1721 self
1722 }
1723
1724 pub fn build(self) -> Expression {
1726 Expression::Update(Box::new(self.update))
1727 }
1728
1729 pub fn to_sql(self) -> String {
1731 Generator::sql(&self.build()).unwrap_or_default()
1732 }
1733}
1734
1735pub fn case() -> CaseBuilder {
1760 CaseBuilder {
1761 operand: None,
1762 whens: Vec::new(),
1763 else_: None,
1764 }
1765}
1766
1767pub fn case_of(operand: Expr) -> CaseBuilder {
1788 CaseBuilder {
1789 operand: Some(operand.0),
1790 whens: Vec::new(),
1791 else_: None,
1792 }
1793}
1794
1795pub struct CaseBuilder {
1803 operand: Option<Expression>,
1804 whens: Vec<(Expression, Expression)>,
1805 else_: Option<Expression>,
1806}
1807
1808impl CaseBuilder {
1809 pub fn when(mut self, condition: Expr, result: Expr) -> Self {
1814 self.whens.push((condition.0, result.0));
1815 self
1816 }
1817
1818 pub fn else_(mut self, result: Expr) -> Self {
1823 self.else_ = Some(result.0);
1824 self
1825 }
1826
1827 pub fn build(self) -> Expr {
1829 Expr(self.build_expr())
1830 }
1831
1832 pub fn build_expr(self) -> Expression {
1837 Expression::Case(Box::new(Case {
1838 operand: self.operand,
1839 whens: self.whens,
1840 else_: self.else_,
1841 comments: Vec::new(),
1842 }))
1843 }
1844}
1845
1846pub fn subquery(query: SelectBuilder, alias_name: &str) -> Expr {
1870 subquery_expr(query.build(), alias_name)
1871}
1872
1873pub fn subquery_expr(expr: Expression, alias_name: &str) -> Expr {
1878 Expr(Expression::Subquery(Box::new(Subquery {
1879 this: expr,
1880 alias: Some(Identifier::new(alias_name)),
1881 column_aliases: Vec::new(),
1882 order_by: None,
1883 limit: None,
1884 offset: None,
1885 distribute_by: None,
1886 sort_by: None,
1887 cluster_by: None,
1888 lateral: false,
1889 modifiers_inside: true,
1890 trailing_comments: Vec::new(),
1891 })))
1892}
1893
1894#[derive(Debug, Clone, Copy)]
1900enum SetOpKind {
1901 Union,
1902 Intersect,
1903 Except,
1904}
1905
1906pub struct SetOpBuilder {
1927 kind: SetOpKind,
1928 left: Expression,
1929 right: Expression,
1930 all: bool,
1931 order_by: Option<OrderBy>,
1932 limit: Option<Box<Expression>>,
1933 offset: Option<Box<Expression>>,
1934}
1935
1936impl SetOpBuilder {
1937 fn new(kind: SetOpKind, left: SelectBuilder, right: SelectBuilder, all: bool) -> Self {
1938 SetOpBuilder {
1939 kind,
1940 left: left.build(),
1941 right: right.build(),
1942 all,
1943 order_by: None,
1944 limit: None,
1945 offset: None,
1946 }
1947 }
1948
1949 pub fn order_by<I, E>(mut self, expressions: I) -> Self
1954 where
1955 I: IntoIterator<Item = E>,
1956 E: IntoExpr,
1957 {
1958 self.order_by = Some(OrderBy {
1959 siblings: false,
1960 comments: Vec::new(),
1961 expressions: expressions
1962 .into_iter()
1963 .map(|e| {
1964 let expr = e.into_expr().0;
1965 match expr {
1966 Expression::Ordered(o) => *o,
1967 other => Ordered {
1968 this: other,
1969 desc: false,
1970 nulls_first: None,
1971 explicit_asc: false,
1972 with_fill: None,
1973 },
1974 }
1975 })
1976 .collect(),
1977 });
1978 self
1979 }
1980
1981 pub fn limit(mut self, count: usize) -> Self {
1983 self.limit = Some(Box::new(Expression::Literal(Literal::Number(
1984 count.to_string(),
1985 ))));
1986 self
1987 }
1988
1989 pub fn offset(mut self, count: usize) -> Self {
1991 self.offset = Some(Box::new(Expression::Literal(Literal::Number(
1992 count.to_string(),
1993 ))));
1994 self
1995 }
1996
1997 pub fn build(self) -> Expression {
2002 match self.kind {
2003 SetOpKind::Union => Expression::Union(Box::new(Union {
2004 left: self.left,
2005 right: self.right,
2006 all: self.all,
2007 distinct: false,
2008 with: None,
2009 order_by: self.order_by,
2010 limit: self.limit,
2011 offset: self.offset,
2012 distribute_by: None,
2013 sort_by: None,
2014 cluster_by: None,
2015 by_name: false,
2016 side: None,
2017 kind: None,
2018 corresponding: false,
2019 strict: false,
2020 on_columns: Vec::new(),
2021 })),
2022 SetOpKind::Intersect => Expression::Intersect(Box::new(Intersect {
2023 left: self.left,
2024 right: self.right,
2025 all: self.all,
2026 distinct: false,
2027 with: None,
2028 order_by: self.order_by,
2029 limit: self.limit,
2030 offset: self.offset,
2031 distribute_by: None,
2032 sort_by: None,
2033 cluster_by: None,
2034 by_name: false,
2035 side: None,
2036 kind: None,
2037 corresponding: false,
2038 strict: false,
2039 on_columns: Vec::new(),
2040 })),
2041 SetOpKind::Except => Expression::Except(Box::new(Except {
2042 left: self.left,
2043 right: self.right,
2044 all: self.all,
2045 distinct: false,
2046 with: None,
2047 order_by: self.order_by,
2048 limit: self.limit,
2049 offset: self.offset,
2050 distribute_by: None,
2051 sort_by: None,
2052 cluster_by: None,
2053 by_name: false,
2054 side: None,
2055 kind: None,
2056 corresponding: false,
2057 strict: false,
2058 on_columns: Vec::new(),
2059 })),
2060 }
2061 }
2062
2063 pub fn to_sql(self) -> String {
2065 Generator::sql(&self.build()).unwrap_or_default()
2066 }
2067}
2068
2069pub fn union(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2073 SetOpBuilder::new(SetOpKind::Union, left, right, false)
2074}
2075
2076pub fn union_all(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2080 SetOpBuilder::new(SetOpKind::Union, left, right, true)
2081}
2082
2083pub fn intersect(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2087 SetOpBuilder::new(SetOpKind::Intersect, left, right, false)
2088}
2089
2090pub fn intersect_all(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2094 SetOpBuilder::new(SetOpKind::Intersect, left, right, true)
2095}
2096
2097pub fn except_(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2101 SetOpBuilder::new(SetOpKind::Except, left, right, false)
2102}
2103
2104pub fn except_all(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2108 SetOpBuilder::new(SetOpKind::Except, left, right, true)
2109}
2110
2111pub struct WindowDefBuilder {
2136 partition_by: Vec<Expression>,
2137 order_by: Vec<Ordered>,
2138}
2139
2140impl WindowDefBuilder {
2141 pub fn new() -> Self {
2143 WindowDefBuilder {
2144 partition_by: Vec::new(),
2145 order_by: Vec::new(),
2146 }
2147 }
2148
2149 pub fn partition_by<I, E>(mut self, expressions: I) -> Self
2151 where
2152 I: IntoIterator<Item = E>,
2153 E: IntoExpr,
2154 {
2155 self.partition_by = expressions.into_iter().map(|e| e.into_expr().0).collect();
2156 self
2157 }
2158
2159 pub fn order_by<I, E>(mut self, expressions: I) -> Self
2164 where
2165 I: IntoIterator<Item = E>,
2166 E: IntoExpr,
2167 {
2168 self.order_by = expressions
2169 .into_iter()
2170 .map(|e| {
2171 let expr = e.into_expr().0;
2172 match expr {
2173 Expression::Ordered(o) => *o,
2174 other => Ordered {
2175 this: other,
2176 desc: false,
2177 nulls_first: None,
2178 explicit_asc: false,
2179 with_fill: None,
2180 },
2181 }
2182 })
2183 .collect();
2184 self
2185 }
2186}
2187
2188pub trait IntoExpr {
2204 fn into_expr(self) -> Expr;
2206}
2207
2208impl IntoExpr for Expr {
2209 fn into_expr(self) -> Expr {
2210 self
2211 }
2212}
2213
2214impl IntoExpr for &str {
2215 fn into_expr(self) -> Expr {
2217 col(self)
2218 }
2219}
2220
2221impl IntoExpr for String {
2222 fn into_expr(self) -> Expr {
2224 col(&self)
2225 }
2226}
2227
2228impl IntoExpr for Expression {
2229 fn into_expr(self) -> Expr {
2231 Expr(self)
2232 }
2233}
2234
2235pub trait IntoLiteral {
2250 fn into_literal(self) -> Expr;
2252}
2253
2254impl IntoLiteral for &str {
2255 fn into_literal(self) -> Expr {
2257 Expr(Expression::Literal(Literal::String(self.to_string())))
2258 }
2259}
2260
2261impl IntoLiteral for String {
2262 fn into_literal(self) -> Expr {
2264 Expr(Expression::Literal(Literal::String(self)))
2265 }
2266}
2267
2268impl IntoLiteral for i64 {
2269 fn into_literal(self) -> Expr {
2271 Expr(Expression::Literal(Literal::Number(self.to_string())))
2272 }
2273}
2274
2275impl IntoLiteral for i32 {
2276 fn into_literal(self) -> Expr {
2278 Expr(Expression::Literal(Literal::Number(self.to_string())))
2279 }
2280}
2281
2282impl IntoLiteral for usize {
2283 fn into_literal(self) -> Expr {
2285 Expr(Expression::Literal(Literal::Number(self.to_string())))
2286 }
2287}
2288
2289impl IntoLiteral for f64 {
2290 fn into_literal(self) -> Expr {
2292 Expr(Expression::Literal(Literal::Number(self.to_string())))
2293 }
2294}
2295
2296impl IntoLiteral for bool {
2297 fn into_literal(self) -> Expr {
2299 Expr(Expression::Boolean(BooleanLiteral { value: self }))
2300 }
2301}
2302
2303fn binary_op(left: Expression, right: Expression) -> BinaryOp {
2308 BinaryOp {
2309 left,
2310 right,
2311 left_comments: Vec::new(),
2312 operator_comments: Vec::new(),
2313 trailing_comments: Vec::new(),
2314 }
2315}
2316
2317pub fn merge_into(target: &str) -> MergeBuilder {
2339 MergeBuilder {
2340 target: Expression::Table(TableRef::new(target)),
2341 using: None,
2342 on: None,
2343 whens: Vec::new(),
2344 }
2345}
2346
2347pub struct MergeBuilder {
2351 target: Expression,
2352 using: Option<Expression>,
2353 on: Option<Expression>,
2354 whens: Vec<Expression>,
2355}
2356
2357impl MergeBuilder {
2358 pub fn using(mut self, source: &str, on: Expr) -> Self {
2360 self.using = Some(Expression::Table(TableRef::new(source)));
2361 self.on = Some(on.0);
2362 self
2363 }
2364
2365 pub fn when_matched_update(mut self, assignments: Vec<(&str, Expr)>) -> Self {
2367 let eqs: Vec<Expression> = assignments
2368 .into_iter()
2369 .map(|(col_name, val)| {
2370 Expression::Eq(Box::new(BinaryOp {
2371 left: Expression::Column(Column {
2372 name: Identifier::new(col_name),
2373 table: None,
2374 join_mark: false,
2375 trailing_comments: Vec::new(),
2376 }),
2377 right: val.0,
2378 left_comments: Vec::new(),
2379 operator_comments: Vec::new(),
2380 trailing_comments: Vec::new(),
2381 }))
2382 })
2383 .collect();
2384
2385 let action = Expression::Tuple(Box::new(Tuple {
2386 expressions: vec![
2387 Expression::Var(Box::new(Var {
2388 this: "UPDATE".to_string(),
2389 })),
2390 Expression::Tuple(Box::new(Tuple { expressions: eqs })),
2391 ],
2392 }));
2393
2394 let when = Expression::When(Box::new(When {
2395 matched: Some(Box::new(Expression::Boolean(BooleanLiteral {
2396 value: true,
2397 }))),
2398 source: None,
2399 condition: None,
2400 then: Box::new(action),
2401 }));
2402 self.whens.push(when);
2403 self
2404 }
2405
2406 pub fn when_matched_update_where(
2408 mut self,
2409 condition: Expr,
2410 assignments: Vec<(&str, Expr)>,
2411 ) -> Self {
2412 let eqs: Vec<Expression> = assignments
2413 .into_iter()
2414 .map(|(col_name, val)| {
2415 Expression::Eq(Box::new(BinaryOp {
2416 left: Expression::Column(Column {
2417 name: Identifier::new(col_name),
2418 table: None,
2419 join_mark: false,
2420 trailing_comments: Vec::new(),
2421 }),
2422 right: val.0,
2423 left_comments: Vec::new(),
2424 operator_comments: Vec::new(),
2425 trailing_comments: Vec::new(),
2426 }))
2427 })
2428 .collect();
2429
2430 let action = Expression::Tuple(Box::new(Tuple {
2431 expressions: vec![
2432 Expression::Var(Box::new(Var {
2433 this: "UPDATE".to_string(),
2434 })),
2435 Expression::Tuple(Box::new(Tuple { expressions: eqs })),
2436 ],
2437 }));
2438
2439 let when = Expression::When(Box::new(When {
2440 matched: Some(Box::new(Expression::Boolean(BooleanLiteral {
2441 value: true,
2442 }))),
2443 source: None,
2444 condition: Some(Box::new(condition.0)),
2445 then: Box::new(action),
2446 }));
2447 self.whens.push(when);
2448 self
2449 }
2450
2451 pub fn when_matched_delete(mut self) -> Self {
2453 let action = Expression::Var(Box::new(Var {
2454 this: "DELETE".to_string(),
2455 }));
2456
2457 let when = Expression::When(Box::new(When {
2458 matched: Some(Box::new(Expression::Boolean(BooleanLiteral {
2459 value: true,
2460 }))),
2461 source: None,
2462 condition: None,
2463 then: Box::new(action),
2464 }));
2465 self.whens.push(when);
2466 self
2467 }
2468
2469 pub fn when_not_matched_insert(mut self, columns: &[&str], values: Vec<Expr>) -> Self {
2471 let col_exprs: Vec<Expression> = columns
2472 .iter()
2473 .map(|c| {
2474 Expression::Column(Column {
2475 name: Identifier::new(*c),
2476 table: None,
2477 join_mark: false,
2478 trailing_comments: Vec::new(),
2479 })
2480 })
2481 .collect();
2482 let val_exprs: Vec<Expression> = values.into_iter().map(|v| v.0).collect();
2483
2484 let action = Expression::Tuple(Box::new(Tuple {
2485 expressions: vec![
2486 Expression::Var(Box::new(Var {
2487 this: "INSERT".to_string(),
2488 })),
2489 Expression::Tuple(Box::new(Tuple {
2490 expressions: col_exprs,
2491 })),
2492 Expression::Tuple(Box::new(Tuple {
2493 expressions: val_exprs,
2494 })),
2495 ],
2496 }));
2497
2498 let when = Expression::When(Box::new(When {
2499 matched: Some(Box::new(Expression::Boolean(BooleanLiteral {
2500 value: false,
2501 }))),
2502 source: None,
2503 condition: None,
2504 then: Box::new(action),
2505 }));
2506 self.whens.push(when);
2507 self
2508 }
2509
2510 pub fn build(self) -> Expression {
2512 let whens_expr = Expression::Whens(Box::new(Whens {
2513 expressions: self.whens,
2514 }));
2515
2516 Expression::Merge(Box::new(Merge {
2517 this: Box::new(self.target),
2518 using: Box::new(
2519 self.using
2520 .unwrap_or(Expression::Null(crate::expressions::Null)),
2521 ),
2522 on: self.on.map(Box::new),
2523 using_cond: None,
2524 whens: Some(Box::new(whens_expr)),
2525 with_: None,
2526 returning: None,
2527 }))
2528 }
2529
2530 pub fn to_sql(self) -> String {
2532 Generator::sql(&self.build()).unwrap_or_default()
2533 }
2534}
2535
2536fn parse_simple_data_type(name: &str) -> DataType {
2537 let upper = name.trim().to_uppercase();
2538 match upper.as_str() {
2539 "INT" | "INTEGER" => DataType::Int {
2540 length: None,
2541 integer_spelling: upper == "INTEGER",
2542 },
2543 "BIGINT" => DataType::BigInt { length: None },
2544 "SMALLINT" => DataType::SmallInt { length: None },
2545 "TINYINT" => DataType::TinyInt { length: None },
2546 "FLOAT" => DataType::Float {
2547 precision: None,
2548 scale: None,
2549 real_spelling: false,
2550 },
2551 "DOUBLE" => DataType::Double {
2552 precision: None,
2553 scale: None,
2554 },
2555 "BOOLEAN" | "BOOL" => DataType::Boolean,
2556 "TEXT" => DataType::Text,
2557 "DATE" => DataType::Date,
2558 "TIMESTAMP" => DataType::Timestamp {
2559 precision: None,
2560 timezone: false,
2561 },
2562 "VARCHAR" => DataType::VarChar {
2563 length: None,
2564 parenthesized_length: false,
2565 },
2566 "CHAR" => DataType::Char { length: None },
2567 _ => {
2568 if let Ok(ast) =
2570 crate::parser::Parser::parse_sql(&format!("SELECT CAST(x AS {})", name))
2571 {
2572 if let Expression::Select(s) = &ast[0] {
2573 if let Some(Expression::Cast(c)) = s.expressions.first() {
2574 return c.to.clone();
2575 }
2576 }
2577 }
2578 DataType::Custom {
2580 name: name.to_string(),
2581 }
2582 }
2583 }
2584}
2585
2586#[cfg(test)]
2587mod tests {
2588 use super::*;
2589
2590 #[test]
2591 fn test_simple_select() {
2592 let sql = select(["id", "name"]).from("users").to_sql();
2593 assert_eq!(sql, "SELECT id, name FROM users");
2594 }
2595
2596 #[test]
2597 fn test_select_star() {
2598 let sql = select([star()]).from("users").to_sql();
2599 assert_eq!(sql, "SELECT * FROM users");
2600 }
2601
2602 #[test]
2603 fn test_select_with_where() {
2604 let sql = select(["id", "name"])
2605 .from("users")
2606 .where_(col("age").gt(lit(18)))
2607 .to_sql();
2608 assert_eq!(sql, "SELECT id, name FROM users WHERE age > 18");
2609 }
2610
2611 #[test]
2612 fn test_select_with_join() {
2613 let sql = select(["u.id", "o.amount"])
2614 .from("users")
2615 .join("orders", col("u.id").eq(col("o.user_id")))
2616 .to_sql();
2617 assert_eq!(
2618 sql,
2619 "SELECT u.id, o.amount FROM users JOIN orders ON u.id = o.user_id"
2620 );
2621 }
2622
2623 #[test]
2624 fn test_select_with_group_by_having() {
2625 let sql = select([col("dept"), func("COUNT", [star()]).alias("cnt")])
2626 .from("employees")
2627 .group_by(["dept"])
2628 .having(func("COUNT", [star()]).gt(lit(5)))
2629 .to_sql();
2630 assert_eq!(
2631 sql,
2632 "SELECT dept, COUNT(*) AS cnt FROM employees GROUP BY dept HAVING COUNT(*) > 5"
2633 );
2634 }
2635
2636 #[test]
2637 fn test_select_with_order_limit_offset() {
2638 let sql = select(["id", "name"])
2639 .from("users")
2640 .order_by(["name"])
2641 .limit(10)
2642 .offset(20)
2643 .to_sql();
2644 assert_eq!(
2645 sql,
2646 "SELECT id, name FROM users ORDER BY name LIMIT 10 OFFSET 20"
2647 );
2648 }
2649
2650 #[test]
2651 fn test_select_distinct() {
2652 let sql = select(["name"]).from("users").distinct().to_sql();
2653 assert_eq!(sql, "SELECT DISTINCT name FROM users");
2654 }
2655
2656 #[test]
2657 fn test_insert_values() {
2658 let sql = insert_into("users")
2659 .columns(["id", "name"])
2660 .values([lit(1), lit("Alice")])
2661 .values([lit(2), lit("Bob")])
2662 .to_sql();
2663 assert_eq!(
2664 sql,
2665 "INSERT INTO users (id, name) VALUES (1, 'Alice'), (2, 'Bob')"
2666 );
2667 }
2668
2669 #[test]
2670 fn test_insert_select() {
2671 let sql = insert_into("archive")
2672 .columns(["id", "name"])
2673 .query(select(["id", "name"]).from("users"))
2674 .to_sql();
2675 assert_eq!(
2676 sql,
2677 "INSERT INTO archive (id, name) SELECT id, name FROM users"
2678 );
2679 }
2680
2681 #[test]
2682 fn test_update() {
2683 let sql = update("users")
2684 .set("name", lit("Bob"))
2685 .set("age", lit(30))
2686 .where_(col("id").eq(lit(1)))
2687 .to_sql();
2688 assert_eq!(sql, "UPDATE users SET name = 'Bob', age = 30 WHERE id = 1");
2689 }
2690
2691 #[test]
2692 fn test_delete() {
2693 let sql = delete("users").where_(col("id").eq(lit(1))).to_sql();
2694 assert_eq!(sql, "DELETE FROM users WHERE id = 1");
2695 }
2696
2697 #[test]
2698 fn test_complex_where() {
2699 let sql = select(["id"])
2700 .from("users")
2701 .where_(
2702 col("age")
2703 .gte(lit(18))
2704 .and(col("active").eq(boolean(true)))
2705 .and(col("name").like(lit("%test%"))),
2706 )
2707 .to_sql();
2708 assert_eq!(
2709 sql,
2710 "SELECT id FROM users WHERE age >= 18 AND active = TRUE AND name LIKE '%test%'"
2711 );
2712 }
2713
2714 #[test]
2715 fn test_in_list() {
2716 let sql = select(["id"])
2717 .from("users")
2718 .where_(col("status").in_list([lit("active"), lit("pending")]))
2719 .to_sql();
2720 assert_eq!(
2721 sql,
2722 "SELECT id FROM users WHERE status IN ('active', 'pending')"
2723 );
2724 }
2725
2726 #[test]
2727 fn test_between() {
2728 let sql = select(["id"])
2729 .from("orders")
2730 .where_(col("amount").between(lit(100), lit(500)))
2731 .to_sql();
2732 assert_eq!(
2733 sql,
2734 "SELECT id FROM orders WHERE amount BETWEEN 100 AND 500"
2735 );
2736 }
2737
2738 #[test]
2739 fn test_is_null() {
2740 let sql = select(["id"])
2741 .from("users")
2742 .where_(col("email").is_null())
2743 .to_sql();
2744 assert_eq!(sql, "SELECT id FROM users WHERE email IS NULL");
2745 }
2746
2747 #[test]
2748 fn test_arithmetic() {
2749 let sql = select([col("price").mul(col("quantity")).alias("total")])
2750 .from("items")
2751 .to_sql();
2752 assert_eq!(sql, "SELECT price * quantity AS total FROM items");
2753 }
2754
2755 #[test]
2756 fn test_cast() {
2757 let sql = select([col("id").cast("VARCHAR")]).from("users").to_sql();
2758 assert_eq!(sql, "SELECT CAST(id AS VARCHAR) FROM users");
2759 }
2760
2761 #[test]
2762 fn test_from_starter() {
2763 let sql = from("users").select_cols(["id", "name"]).to_sql();
2764 assert_eq!(sql, "SELECT id, name FROM users");
2765 }
2766
2767 #[test]
2768 fn test_qualified_column() {
2769 let sql = select([col("u.id"), col("u.name")]).from("users").to_sql();
2770 assert_eq!(sql, "SELECT u.id, u.name FROM users");
2771 }
2772
2773 #[test]
2774 fn test_not_condition() {
2775 let sql = select(["id"])
2776 .from("users")
2777 .where_(not(col("active").eq(boolean(true))))
2778 .to_sql();
2779 assert_eq!(sql, "SELECT id FROM users WHERE NOT active = TRUE");
2780 }
2781
2782 #[test]
2783 fn test_order_by_desc() {
2784 let sql = select(["id", "name"])
2785 .from("users")
2786 .order_by([col("name").desc()])
2787 .to_sql();
2788 assert_eq!(sql, "SELECT id, name FROM users ORDER BY name DESC");
2789 }
2790
2791 #[test]
2792 fn test_left_join() {
2793 let sql = select(["u.id", "o.amount"])
2794 .from("users")
2795 .left_join("orders", col("u.id").eq(col("o.user_id")))
2796 .to_sql();
2797 assert_eq!(
2798 sql,
2799 "SELECT u.id, o.amount FROM users LEFT JOIN orders ON u.id = o.user_id"
2800 );
2801 }
2802
2803 #[test]
2804 fn test_build_returns_expression() {
2805 let expr = select(["id"]).from("users").build();
2806 assert!(matches!(expr, Expression::Select(_)));
2807 }
2808
2809 #[test]
2810 fn test_expr_interop() {
2811 let age_check = col("age").gt(lit(18));
2813 let sql = select([col("id"), age_check.alias("is_adult")])
2814 .from("users")
2815 .to_sql();
2816 assert_eq!(sql, "SELECT id, age > 18 AS is_adult FROM users");
2817 }
2818
2819 #[test]
2822 fn test_sql_expr_simple() {
2823 let expr = sql_expr("age > 18");
2824 let sql = select(["id"]).from("users").where_(expr).to_sql();
2825 assert_eq!(sql, "SELECT id FROM users WHERE age > 18");
2826 }
2827
2828 #[test]
2829 fn test_sql_expr_compound() {
2830 let expr = sql_expr("a > 1 AND b < 10");
2831 let sql = select(["*"]).from("t").where_(expr).to_sql();
2832 assert_eq!(sql, "SELECT * FROM t WHERE a > 1 AND b < 10");
2833 }
2834
2835 #[test]
2836 fn test_sql_expr_function() {
2837 let expr = sql_expr("COALESCE(a, b, 0)");
2838 let sql = select([expr.alias("val")]).from("t").to_sql();
2839 assert_eq!(sql, "SELECT COALESCE(a, b, 0) AS val FROM t");
2840 }
2841
2842 #[test]
2843 fn test_condition_alias() {
2844 let cond = condition("x > 0");
2845 let sql = select(["*"]).from("t").where_(cond).to_sql();
2846 assert_eq!(sql, "SELECT * FROM t WHERE x > 0");
2847 }
2848
2849 #[test]
2852 fn test_ilike() {
2853 let sql = select(["id"])
2854 .from("users")
2855 .where_(col("name").ilike(lit("%test%")))
2856 .to_sql();
2857 assert_eq!(sql, "SELECT id FROM users WHERE name ILIKE '%test%'");
2858 }
2859
2860 #[test]
2861 fn test_rlike() {
2862 let sql = select(["id"])
2863 .from("users")
2864 .where_(col("name").rlike(lit("^[A-Z]")))
2865 .to_sql();
2866 assert_eq!(
2867 sql,
2868 "SELECT id FROM users WHERE REGEXP_LIKE(name, '^[A-Z]')"
2869 );
2870 }
2871
2872 #[test]
2873 fn test_not_in() {
2874 let sql = select(["id"])
2875 .from("users")
2876 .where_(col("status").not_in([lit("deleted"), lit("banned")]))
2877 .to_sql();
2878 assert_eq!(
2879 sql,
2880 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
2881 );
2882 }
2883
2884 #[test]
2887 fn test_case_searched() {
2888 let expr = case()
2889 .when(col("x").gt(lit(0)), lit("positive"))
2890 .when(col("x").eq(lit(0)), lit("zero"))
2891 .else_(lit("negative"))
2892 .build();
2893 let sql = select([expr.alias("label")]).from("t").to_sql();
2894 assert_eq!(
2895 sql,
2896 "SELECT CASE WHEN x > 0 THEN 'positive' WHEN x = 0 THEN 'zero' ELSE 'negative' END AS label FROM t"
2897 );
2898 }
2899
2900 #[test]
2901 fn test_case_simple() {
2902 let expr = case_of(col("status"))
2903 .when(lit(1), lit("active"))
2904 .when(lit(0), lit("inactive"))
2905 .build();
2906 let sql = select([expr.alias("status_label")]).from("t").to_sql();
2907 assert_eq!(
2908 sql,
2909 "SELECT CASE status WHEN 1 THEN 'active' WHEN 0 THEN 'inactive' END AS status_label FROM t"
2910 );
2911 }
2912
2913 #[test]
2914 fn test_case_no_else() {
2915 let expr = case().when(col("x").gt(lit(0)), lit("yes")).build();
2916 let sql = select([expr]).from("t").to_sql();
2917 assert_eq!(sql, "SELECT CASE WHEN x > 0 THEN 'yes' END FROM t");
2918 }
2919
2920 #[test]
2923 fn test_subquery_in_from() {
2924 let inner = select(["id", "name"])
2925 .from("users")
2926 .where_(col("active").eq(boolean(true)));
2927 let outer = select(["sub.id"])
2928 .from_expr(subquery(inner, "sub"))
2929 .to_sql();
2930 assert_eq!(
2931 outer,
2932 "SELECT sub.id FROM (SELECT id, name FROM users WHERE active = TRUE) AS sub"
2933 );
2934 }
2935
2936 #[test]
2937 fn test_subquery_in_join() {
2938 let inner = select([col("user_id"), func("SUM", [col("amount")]).alias("total")])
2939 .from("orders")
2940 .group_by(["user_id"]);
2941 let sql = select(["u.name", "o.total"])
2942 .from("users")
2943 .join("orders", col("u.id").eq(col("o.user_id")))
2944 .to_sql();
2945 assert!(sql.contains("JOIN"));
2946 let _sub = subquery(inner, "o");
2948 }
2949
2950 #[test]
2953 fn test_union() {
2954 let sql = union(select(["id"]).from("a"), select(["id"]).from("b")).to_sql();
2955 assert_eq!(sql, "SELECT id FROM a UNION SELECT id FROM b");
2956 }
2957
2958 #[test]
2959 fn test_union_all() {
2960 let sql = union_all(select(["id"]).from("a"), select(["id"]).from("b")).to_sql();
2961 assert_eq!(sql, "SELECT id FROM a UNION ALL SELECT id FROM b");
2962 }
2963
2964 #[test]
2965 fn test_intersect_builder() {
2966 let sql = intersect(select(["id"]).from("a"), select(["id"]).from("b")).to_sql();
2967 assert_eq!(sql, "SELECT id FROM a INTERSECT SELECT id FROM b");
2968 }
2969
2970 #[test]
2971 fn test_except_builder() {
2972 let sql = except_(select(["id"]).from("a"), select(["id"]).from("b")).to_sql();
2973 assert_eq!(sql, "SELECT id FROM a EXCEPT SELECT id FROM b");
2974 }
2975
2976 #[test]
2977 fn test_union_with_order_limit() {
2978 let sql = union(select(["id"]).from("a"), select(["id"]).from("b"))
2979 .order_by(["id"])
2980 .limit(10)
2981 .to_sql();
2982 assert!(sql.contains("UNION"));
2983 assert!(sql.contains("ORDER BY"));
2984 assert!(sql.contains("LIMIT"));
2985 }
2986
2987 #[test]
2988 fn test_select_builder_union() {
2989 let sql = select(["id"])
2990 .from("a")
2991 .union(select(["id"]).from("b"))
2992 .to_sql();
2993 assert_eq!(sql, "SELECT id FROM a UNION SELECT id FROM b");
2994 }
2995
2996 #[test]
2999 fn test_qualify() {
3000 let sql = select(["id", "name"])
3001 .from("users")
3002 .qualify(col("rn").eq(lit(1)))
3003 .to_sql();
3004 assert_eq!(sql, "SELECT id, name FROM users QUALIFY rn = 1");
3005 }
3006
3007 #[test]
3008 fn test_right_join() {
3009 let sql = select(["u.id", "o.amount"])
3010 .from("users")
3011 .right_join("orders", col("u.id").eq(col("o.user_id")))
3012 .to_sql();
3013 assert_eq!(
3014 sql,
3015 "SELECT u.id, o.amount FROM users RIGHT JOIN orders ON u.id = o.user_id"
3016 );
3017 }
3018
3019 #[test]
3020 fn test_cross_join() {
3021 let sql = select(["a.x", "b.y"]).from("a").cross_join("b").to_sql();
3022 assert_eq!(sql, "SELECT a.x, b.y FROM a CROSS JOIN b");
3023 }
3024
3025 #[test]
3026 fn test_lateral_view() {
3027 let sql = select(["id", "col_val"])
3028 .from("t")
3029 .lateral_view(func("EXPLODE", [col("arr")]), "lv", ["col_val"])
3030 .to_sql();
3031 assert!(sql.contains("LATERAL VIEW"));
3032 assert!(sql.contains("EXPLODE"));
3033 }
3034
3035 #[test]
3036 fn test_window_clause() {
3037 let sql = select(["id"])
3038 .from("t")
3039 .window(
3040 "w",
3041 WindowDefBuilder::new()
3042 .partition_by(["dept"])
3043 .order_by(["salary"]),
3044 )
3045 .to_sql();
3046 assert!(sql.contains("WINDOW"));
3047 assert!(sql.contains("PARTITION BY"));
3048 }
3049
3050 #[test]
3053 fn test_xor() {
3054 let sql = select(["*"])
3055 .from("t")
3056 .where_(col("a").xor(col("b")))
3057 .to_sql();
3058 assert_eq!(sql, "SELECT * FROM t WHERE a XOR b");
3059 }
3060
3061 #[test]
3064 fn test_for_update() {
3065 let sql = select(["id"]).from("t").for_update().to_sql();
3066 assert_eq!(sql, "SELECT id FROM t FOR UPDATE");
3067 }
3068
3069 #[test]
3070 fn test_for_share() {
3071 let sql = select(["id"]).from("t").for_share().to_sql();
3072 assert_eq!(sql, "SELECT id FROM t FOR SHARE");
3073 }
3074
3075 #[test]
3078 fn test_hint() {
3079 let sql = select(["*"]).from("t").hint("FULL(t)").to_sql();
3080 assert!(sql.contains("FULL(t)"), "Expected hint in: {}", sql);
3081 }
3082
3083 #[test]
3086 fn test_ctas() {
3087 let expr = select(["*"]).from("t").ctas("new_table");
3088 let sql = Generator::sql(&expr).unwrap();
3089 assert_eq!(sql, "CREATE TABLE new_table AS SELECT * FROM t");
3090 }
3091
3092 #[test]
3095 fn test_merge_update_insert() {
3096 let sql = merge_into("target")
3097 .using("source", col("target.id").eq(col("source.id")))
3098 .when_matched_update(vec![("name", col("source.name"))])
3099 .when_not_matched_insert(&["id", "name"], vec![col("source.id"), col("source.name")])
3100 .to_sql();
3101 assert!(
3102 sql.contains("MERGE INTO"),
3103 "Expected MERGE INTO in: {}",
3104 sql
3105 );
3106 assert!(sql.contains("USING"), "Expected USING in: {}", sql);
3107 assert!(
3108 sql.contains("WHEN MATCHED"),
3109 "Expected WHEN MATCHED in: {}",
3110 sql
3111 );
3112 assert!(
3113 sql.contains("UPDATE SET"),
3114 "Expected UPDATE SET in: {}",
3115 sql
3116 );
3117 assert!(
3118 sql.contains("WHEN NOT MATCHED"),
3119 "Expected WHEN NOT MATCHED in: {}",
3120 sql
3121 );
3122 assert!(sql.contains("INSERT"), "Expected INSERT in: {}", sql);
3123 }
3124
3125 #[test]
3126 fn test_merge_delete() {
3127 let sql = merge_into("target")
3128 .using("source", col("target.id").eq(col("source.id")))
3129 .when_matched_delete()
3130 .to_sql();
3131 assert!(
3132 sql.contains("MERGE INTO"),
3133 "Expected MERGE INTO in: {}",
3134 sql
3135 );
3136 assert!(
3137 sql.contains("WHEN MATCHED THEN DELETE"),
3138 "Expected WHEN MATCHED THEN DELETE in: {}",
3139 sql
3140 );
3141 }
3142
3143 #[test]
3144 fn test_merge_with_condition() {
3145 let sql = merge_into("target")
3146 .using("source", col("target.id").eq(col("source.id")))
3147 .when_matched_update_where(
3148 col("source.active").eq(boolean(true)),
3149 vec![("name", col("source.name"))],
3150 )
3151 .to_sql();
3152 assert!(
3153 sql.contains("MERGE INTO"),
3154 "Expected MERGE INTO in: {}",
3155 sql
3156 );
3157 assert!(
3158 sql.contains("AND source.active = TRUE"),
3159 "Expected condition in: {}",
3160 sql
3161 );
3162 }
3163}