1use crate::expressions::*;
59use crate::generator::Generator;
60use crate::parser::Parser;
61
62fn is_safe_identifier_name(name: &str) -> bool {
63 if name.is_empty() {
64 return false;
65 }
66
67 let mut chars = name.chars();
68 let Some(first) = chars.next() else {
69 return false;
70 };
71
72 if !(first == '_' || first.is_ascii_alphabetic()) {
73 return false;
74 }
75
76 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
77}
78
79fn builder_identifier(name: &str) -> Identifier {
80 if name == "*" || is_safe_identifier_name(name) {
81 Identifier::new(name)
82 } else {
83 Identifier::quoted(name)
84 }
85}
86
87fn builder_table_ref(name: &str) -> TableRef {
88 let parts: Vec<&str> = name.split('.').collect();
89
90 match parts.len() {
91 3 => {
92 let mut t = TableRef::new(parts[2]);
93 t.name = builder_identifier(parts[2]);
94 t.schema = Some(builder_identifier(parts[1]));
95 t.catalog = Some(builder_identifier(parts[0]));
96 t
97 }
98 2 => {
99 let mut t = TableRef::new(parts[1]);
100 t.name = builder_identifier(parts[1]);
101 t.schema = Some(builder_identifier(parts[0]));
102 t
103 }
104 _ => {
105 let first = parts.first().copied().unwrap_or("");
106 let mut t = TableRef::new(first);
107 t.name = builder_identifier(first);
108 t
109 }
110 }
111}
112
113pub fn col(name: &str) -> Expr {
137 if let Some((table, column)) = name.rsplit_once('.') {
138 Expr(Expression::Column(Column {
139 name: builder_identifier(column),
140 table: Some(builder_identifier(table)),
141 join_mark: false,
142 trailing_comments: Vec::new(),
143 span: None,
144 }))
145 } else {
146 Expr(Expression::Column(Column {
147 name: builder_identifier(name),
148 table: None,
149 join_mark: false,
150 trailing_comments: Vec::new(),
151 span: None,
152 }))
153 }
154}
155
156pub fn lit<V: IntoLiteral>(value: V) -> Expr {
172 value.into_literal()
173}
174
175pub fn star() -> Expr {
177 Expr(Expression::star())
178}
179
180pub fn null() -> Expr {
182 Expr(Expression::Null(Null))
183}
184
185pub fn boolean(value: bool) -> Expr {
187 Expr(Expression::Boolean(BooleanLiteral { value }))
188}
189
190pub fn table(name: &str) -> Expr {
207 Expr(Expression::Table(builder_table_ref(name)))
208}
209
210pub fn func(name: &str, args: impl IntoIterator<Item = Expr>) -> Expr {
227 Expr(Expression::Function(Box::new(Function {
228 name: name.to_string(),
229 args: args.into_iter().map(|a| a.0).collect(),
230 ..Function::default()
231 })))
232}
233
234pub fn cast(expr: Expr, to: &str) -> Expr {
250 let data_type = parse_simple_data_type(to);
251 Expr(Expression::Cast(Box::new(Cast {
252 this: expr.0,
253 to: data_type,
254 trailing_comments: Vec::new(),
255 double_colon_syntax: false,
256 format: None,
257 default: None,
258 })))
259}
260
261pub fn not(expr: Expr) -> Expr {
266 Expr(Expression::Not(Box::new(UnaryOp::new(expr.0))))
267}
268
269pub fn and(left: Expr, right: Expr) -> Expr {
274 left.and(right)
275}
276
277pub fn or(left: Expr, right: Expr) -> Expr {
282 left.or(right)
283}
284
285pub fn alias(expr: Expr, name: &str) -> Expr {
290 Expr(Expression::Alias(Box::new(Alias {
291 this: expr.0,
292 alias: builder_identifier(name),
293 column_aliases: Vec::new(),
294 pre_alias_comments: Vec::new(),
295 trailing_comments: Vec::new(),
296 })))
297}
298
299pub fn sql_expr(sql: &str) -> Expr {
323 let wrapped = format!("SELECT {}", sql);
324 let ast = Parser::parse_sql(&wrapped).expect("sql_expr: failed to parse SQL expression");
325 if let Expression::Select(s) = &ast[0] {
326 if let Some(first) = s.expressions.first() {
327 return Expr(first.clone());
328 }
329 }
330 panic!("sql_expr: failed to extract expression from parsed SQL");
331}
332
333pub fn condition(sql: &str) -> Expr {
342 sql_expr(sql)
343}
344
345pub fn count(expr: Expr) -> Expr {
353 Expr(Expression::Count(Box::new(CountFunc {
354 this: Some(expr.0),
355 star: false,
356 distinct: false,
357 filter: None,
358 ignore_nulls: None,
359 original_name: None,
360 })))
361}
362
363pub fn count_star() -> Expr {
365 Expr(Expression::Count(Box::new(CountFunc {
366 this: None,
367 star: true,
368 distinct: false,
369 filter: None,
370 ignore_nulls: None,
371 original_name: None,
372 })))
373}
374
375pub fn count_distinct(expr: Expr) -> Expr {
377 Expr(Expression::Count(Box::new(CountFunc {
378 this: Some(expr.0),
379 star: false,
380 distinct: true,
381 filter: None,
382 ignore_nulls: None,
383 original_name: None,
384 })))
385}
386
387pub fn sum(expr: Expr) -> Expr {
389 Expr(Expression::Sum(Box::new(AggFunc {
390 this: expr.0,
391 distinct: false,
392 filter: None,
393 order_by: vec![],
394 name: None,
395 ignore_nulls: None,
396 having_max: None,
397 limit: None,
398 })))
399}
400
401pub fn avg(expr: Expr) -> Expr {
403 Expr(Expression::Avg(Box::new(AggFunc {
404 this: expr.0,
405 distinct: false,
406 filter: None,
407 order_by: vec![],
408 name: None,
409 ignore_nulls: None,
410 having_max: None,
411 limit: None,
412 })))
413}
414
415pub fn min_(expr: Expr) -> Expr {
417 Expr(Expression::Min(Box::new(AggFunc {
418 this: expr.0,
419 distinct: false,
420 filter: None,
421 order_by: vec![],
422 name: None,
423 ignore_nulls: None,
424 having_max: None,
425 limit: None,
426 })))
427}
428
429pub fn max_(expr: Expr) -> Expr {
431 Expr(Expression::Max(Box::new(AggFunc {
432 this: expr.0,
433 distinct: false,
434 filter: None,
435 order_by: vec![],
436 name: None,
437 ignore_nulls: None,
438 having_max: None,
439 limit: None,
440 })))
441}
442
443pub fn approx_distinct(expr: Expr) -> Expr {
445 Expr(Expression::ApproxDistinct(Box::new(AggFunc {
446 this: expr.0,
447 distinct: false,
448 filter: None,
449 order_by: vec![],
450 name: None,
451 ignore_nulls: None,
452 having_max: None,
453 limit: None,
454 })))
455}
456
457pub fn upper(expr: Expr) -> Expr {
461 Expr(Expression::Upper(Box::new(UnaryFunc::new(expr.0))))
462}
463
464pub fn lower(expr: Expr) -> Expr {
466 Expr(Expression::Lower(Box::new(UnaryFunc::new(expr.0))))
467}
468
469pub fn length(expr: Expr) -> Expr {
471 Expr(Expression::Length(Box::new(UnaryFunc::new(expr.0))))
472}
473
474pub fn trim(expr: Expr) -> Expr {
476 Expr(Expression::Trim(Box::new(TrimFunc {
477 this: expr.0,
478 characters: None,
479 position: TrimPosition::Both,
480 sql_standard_syntax: false,
481 position_explicit: false,
482 })))
483}
484
485pub fn ltrim(expr: Expr) -> Expr {
487 Expr(Expression::LTrim(Box::new(UnaryFunc::new(expr.0))))
488}
489
490pub fn rtrim(expr: Expr) -> Expr {
492 Expr(Expression::RTrim(Box::new(UnaryFunc::new(expr.0))))
493}
494
495pub fn reverse(expr: Expr) -> Expr {
497 Expr(Expression::Reverse(Box::new(UnaryFunc::new(expr.0))))
498}
499
500pub fn initcap(expr: Expr) -> Expr {
502 Expr(Expression::Initcap(Box::new(UnaryFunc::new(expr.0))))
503}
504
505pub fn substring(expr: Expr, start: Expr, len: Option<Expr>) -> Expr {
507 Expr(Expression::Substring(Box::new(SubstringFunc {
508 this: expr.0,
509 start: start.0,
510 length: len.map(|l| l.0),
511 from_for_syntax: false,
512 })))
513}
514
515pub fn replace_(expr: Expr, old: Expr, new: Expr) -> Expr {
518 Expr(Expression::Replace(Box::new(ReplaceFunc {
519 this: expr.0,
520 old: old.0,
521 new: new.0,
522 })))
523}
524
525pub fn concat_ws(separator: Expr, exprs: impl IntoIterator<Item = Expr>) -> Expr {
527 Expr(Expression::ConcatWs(Box::new(ConcatWs {
528 separator: separator.0,
529 expressions: exprs.into_iter().map(|e| e.0).collect(),
530 })))
531}
532
533pub fn coalesce(exprs: impl IntoIterator<Item = Expr>) -> Expr {
537 Expr(Expression::Coalesce(Box::new(VarArgFunc {
538 expressions: exprs.into_iter().map(|e| e.0).collect(),
539 original_name: None,
540 })))
541}
542
543pub fn null_if(expr1: Expr, expr2: Expr) -> Expr {
545 Expr(Expression::NullIf(Box::new(BinaryFunc {
546 this: expr1.0,
547 expression: expr2.0,
548 original_name: None,
549 })))
550}
551
552pub fn if_null(expr: Expr, fallback: Expr) -> Expr {
554 Expr(Expression::IfNull(Box::new(BinaryFunc {
555 this: expr.0,
556 expression: fallback.0,
557 original_name: None,
558 })))
559}
560
561pub fn abs(expr: Expr) -> Expr {
565 Expr(Expression::Abs(Box::new(UnaryFunc::new(expr.0))))
566}
567
568pub fn round(expr: Expr, decimals: Option<Expr>) -> Expr {
570 Expr(Expression::Round(Box::new(RoundFunc {
571 this: expr.0,
572 decimals: decimals.map(|d| d.0),
573 })))
574}
575
576pub fn floor(expr: Expr) -> Expr {
578 Expr(Expression::Floor(Box::new(FloorFunc {
579 this: expr.0,
580 scale: None,
581 to: None,
582 })))
583}
584
585pub fn ceil(expr: Expr) -> Expr {
587 Expr(Expression::Ceil(Box::new(CeilFunc {
588 this: expr.0,
589 decimals: None,
590 to: None,
591 })))
592}
593
594pub fn power(base: Expr, exponent: Expr) -> Expr {
596 Expr(Expression::Power(Box::new(BinaryFunc {
597 this: base.0,
598 expression: exponent.0,
599 original_name: None,
600 })))
601}
602
603pub fn sqrt(expr: Expr) -> Expr {
605 Expr(Expression::Sqrt(Box::new(UnaryFunc::new(expr.0))))
606}
607
608pub fn ln(expr: Expr) -> Expr {
610 Expr(Expression::Ln(Box::new(UnaryFunc::new(expr.0))))
611}
612
613pub fn exp_(expr: Expr) -> Expr {
615 Expr(Expression::Exp(Box::new(UnaryFunc::new(expr.0))))
616}
617
618pub fn sign(expr: Expr) -> Expr {
620 Expr(Expression::Sign(Box::new(UnaryFunc::new(expr.0))))
621}
622
623pub fn greatest(exprs: impl IntoIterator<Item = Expr>) -> Expr {
625 Expr(Expression::Greatest(Box::new(VarArgFunc {
626 expressions: exprs.into_iter().map(|e| e.0).collect(),
627 original_name: None,
628 })))
629}
630
631pub fn least(exprs: impl IntoIterator<Item = Expr>) -> Expr {
633 Expr(Expression::Least(Box::new(VarArgFunc {
634 expressions: exprs.into_iter().map(|e| e.0).collect(),
635 original_name: None,
636 })))
637}
638
639pub fn current_date_() -> Expr {
643 Expr(Expression::CurrentDate(CurrentDate))
644}
645
646pub fn current_time_() -> Expr {
648 Expr(Expression::CurrentTime(CurrentTime { precision: None }))
649}
650
651pub fn current_timestamp_() -> Expr {
653 Expr(Expression::CurrentTimestamp(CurrentTimestamp {
654 precision: None,
655 sysdate: false,
656 }))
657}
658
659pub fn extract_(field: &str, expr: Expr) -> Expr {
661 Expr(Expression::Extract(Box::new(ExtractFunc {
662 this: expr.0,
663 field: parse_datetime_field(field),
664 })))
665}
666
667fn parse_datetime_field(field: &str) -> DateTimeField {
669 match field.to_uppercase().as_str() {
670 "YEAR" => DateTimeField::Year,
671 "MONTH" => DateTimeField::Month,
672 "DAY" => DateTimeField::Day,
673 "HOUR" => DateTimeField::Hour,
674 "MINUTE" => DateTimeField::Minute,
675 "SECOND" => DateTimeField::Second,
676 "MILLISECOND" => DateTimeField::Millisecond,
677 "MICROSECOND" => DateTimeField::Microsecond,
678 "DOW" | "DAYOFWEEK" => DateTimeField::DayOfWeek,
679 "DOY" | "DAYOFYEAR" => DateTimeField::DayOfYear,
680 "WEEK" => DateTimeField::Week,
681 "QUARTER" => DateTimeField::Quarter,
682 "EPOCH" => DateTimeField::Epoch,
683 "TIMEZONE" => DateTimeField::Timezone,
684 "TIMEZONE_HOUR" => DateTimeField::TimezoneHour,
685 "TIMEZONE_MINUTE" => DateTimeField::TimezoneMinute,
686 "DATE" => DateTimeField::Date,
687 "TIME" => DateTimeField::Time,
688 other => DateTimeField::Custom(other.to_string()),
689 }
690}
691
692pub fn row_number() -> Expr {
696 Expr(Expression::RowNumber(RowNumber))
697}
698
699pub fn rank_() -> Expr {
701 Expr(Expression::Rank(Rank {
702 order_by: None,
703 args: vec![],
704 }))
705}
706
707pub fn dense_rank() -> Expr {
709 Expr(Expression::DenseRank(DenseRank { args: vec![] }))
710}
711
712pub fn select<I, E>(expressions: I) -> SelectBuilder
739where
740 I: IntoIterator<Item = E>,
741 E: IntoExpr,
742{
743 let mut builder = SelectBuilder::new();
744 for expr in expressions {
745 builder.select = builder.select.column(expr.into_expr().0);
746 }
747 builder
748}
749
750pub fn from(table_name: &str) -> SelectBuilder {
765 let mut builder = SelectBuilder::new();
766 builder.select.from = Some(From {
767 expressions: vec![Expression::Table(builder_table_ref(table_name))],
768 });
769 builder
770}
771
772pub fn delete(table_name: &str) -> DeleteBuilder {
785 DeleteBuilder {
786 delete: Delete {
787 table: builder_table_ref(table_name),
788 on_cluster: None,
789 alias: None,
790 alias_explicit_as: false,
791 using: Vec::new(),
792 where_clause: None,
793 output: None,
794 leading_comments: Vec::new(),
795 with: None,
796 limit: None,
797 order_by: None,
798 returning: Vec::new(),
799 tables: Vec::new(),
800 tables_from_using: false,
801 joins: Vec::new(),
802 force_index: None,
803 no_from: false,
804 },
805 }
806}
807
808pub fn insert_into(table_name: &str) -> InsertBuilder {
825 InsertBuilder {
826 insert: Insert {
827 table: builder_table_ref(table_name),
828 columns: Vec::new(),
829 values: Vec::new(),
830 query: None,
831 overwrite: false,
832 partition: Vec::new(),
833 directory: None,
834 returning: Vec::new(),
835 output: None,
836 on_conflict: None,
837 leading_comments: Vec::new(),
838 if_exists: false,
839 with: None,
840 ignore: false,
841 source_alias: None,
842 alias: None,
843 alias_explicit_as: false,
844 default_values: false,
845 by_name: false,
846 conflict_action: None,
847 is_replace: false,
848 hint: None,
849 replace_where: None,
850 source: None,
851 function_target: None,
852 partition_by: None,
853 settings: Vec::new(),
854 },
855 }
856}
857
858pub fn update(table_name: &str) -> UpdateBuilder {
876 UpdateBuilder {
877 update: Update {
878 table: builder_table_ref(table_name),
879 extra_tables: Vec::new(),
880 table_joins: Vec::new(),
881 set: Vec::new(),
882 from_clause: None,
883 from_joins: Vec::new(),
884 where_clause: None,
885 returning: Vec::new(),
886 output: None,
887 with: None,
888 leading_comments: Vec::new(),
889 limit: None,
890 order_by: None,
891 from_before_set: false,
892 },
893 }
894}
895
896#[derive(Debug, Clone)]
921pub struct Expr(pub Expression);
922
923impl Expr {
924 pub fn into_inner(self) -> Expression {
926 self.0
927 }
928
929 pub fn to_sql(&self) -> String {
933 Generator::sql(&self.0).unwrap_or_default()
934 }
935
936 pub fn eq(self, other: Expr) -> Expr {
940 Expr(Expression::Eq(Box::new(binary_op(self.0, other.0))))
941 }
942
943 pub fn neq(self, other: Expr) -> Expr {
945 Expr(Expression::Neq(Box::new(binary_op(self.0, other.0))))
946 }
947
948 pub fn lt(self, other: Expr) -> Expr {
950 Expr(Expression::Lt(Box::new(binary_op(self.0, other.0))))
951 }
952
953 pub fn lte(self, other: Expr) -> Expr {
955 Expr(Expression::Lte(Box::new(binary_op(self.0, other.0))))
956 }
957
958 pub fn gt(self, other: Expr) -> Expr {
960 Expr(Expression::Gt(Box::new(binary_op(self.0, other.0))))
961 }
962
963 pub fn gte(self, other: Expr) -> Expr {
965 Expr(Expression::Gte(Box::new(binary_op(self.0, other.0))))
966 }
967
968 pub fn and(self, other: Expr) -> Expr {
972 Expr(Expression::And(Box::new(binary_op(self.0, other.0))))
973 }
974
975 pub fn or(self, other: Expr) -> Expr {
977 Expr(Expression::Or(Box::new(binary_op(self.0, other.0))))
978 }
979
980 pub fn not(self) -> Expr {
982 Expr(Expression::Not(Box::new(UnaryOp::new(self.0))))
983 }
984
985 pub fn xor(self, other: Expr) -> Expr {
987 Expr(Expression::Xor(Box::new(Xor {
988 this: Some(Box::new(self.0)),
989 expression: Some(Box::new(other.0)),
990 expressions: vec![],
991 })))
992 }
993
994 pub fn add(self, other: Expr) -> Expr {
998 Expr(Expression::Add(Box::new(binary_op(self.0, other.0))))
999 }
1000
1001 pub fn sub(self, other: Expr) -> Expr {
1003 Expr(Expression::Sub(Box::new(binary_op(self.0, other.0))))
1004 }
1005
1006 pub fn mul(self, other: Expr) -> Expr {
1008 Expr(Expression::Mul(Box::new(binary_op(self.0, other.0))))
1009 }
1010
1011 pub fn div(self, other: Expr) -> Expr {
1013 Expr(Expression::Div(Box::new(binary_op(self.0, other.0))))
1014 }
1015
1016 pub fn is_null(self) -> Expr {
1020 Expr(Expression::Is(Box::new(BinaryOp {
1021 left: self.0,
1022 right: Expression::Null(Null),
1023 left_comments: Vec::new(),
1024 operator_comments: Vec::new(),
1025 trailing_comments: Vec::new(),
1026 })))
1027 }
1028
1029 pub fn is_not_null(self) -> Expr {
1031 Expr(Expression::Not(Box::new(UnaryOp::new(Expression::Is(
1032 Box::new(BinaryOp {
1033 left: self.0,
1034 right: Expression::Null(Null),
1035 left_comments: Vec::new(),
1036 operator_comments: Vec::new(),
1037 trailing_comments: Vec::new(),
1038 }),
1039 )))))
1040 }
1041
1042 pub fn in_list(self, values: impl IntoIterator<Item = Expr>) -> Expr {
1046 Expr(Expression::In(Box::new(In {
1047 this: self.0,
1048 expressions: values.into_iter().map(|v| v.0).collect(),
1049 query: None,
1050 not: false,
1051 global: false,
1052 unnest: None,
1053 is_field: false,
1054 })))
1055 }
1056
1057 pub fn between(self, low: Expr, high: Expr) -> Expr {
1059 Expr(Expression::Between(Box::new(Between {
1060 this: self.0,
1061 low: low.0,
1062 high: high.0,
1063 not: false,
1064 symmetric: None,
1065 })))
1066 }
1067
1068 pub fn like(self, pattern: Expr) -> Expr {
1070 Expr(Expression::Like(Box::new(LikeOp {
1071 left: self.0,
1072 right: pattern.0,
1073 escape: None,
1074 quantifier: None,
1075 })))
1076 }
1077
1078 pub fn alias(self, name: &str) -> Expr {
1080 alias(self, name)
1081 }
1082
1083 pub fn cast(self, to: &str) -> Expr {
1087 cast(self, to)
1088 }
1089
1090 pub fn asc(self) -> Expr {
1095 Expr(Expression::Ordered(Box::new(Ordered {
1096 this: self.0,
1097 desc: false,
1098 nulls_first: None,
1099 explicit_asc: true,
1100 with_fill: None,
1101 })))
1102 }
1103
1104 pub fn desc(self) -> Expr {
1108 Expr(Expression::Ordered(Box::new(Ordered {
1109 this: self.0,
1110 desc: true,
1111 nulls_first: None,
1112 explicit_asc: false,
1113 with_fill: None,
1114 })))
1115 }
1116
1117 pub fn ilike(self, pattern: Expr) -> Expr {
1122 Expr(Expression::ILike(Box::new(LikeOp {
1123 left: self.0,
1124 right: pattern.0,
1125 escape: None,
1126 quantifier: None,
1127 })))
1128 }
1129
1130 pub fn rlike(self, pattern: Expr) -> Expr {
1135 Expr(Expression::RegexpLike(Box::new(RegexpFunc {
1136 this: self.0,
1137 pattern: pattern.0,
1138 flags: None,
1139 })))
1140 }
1141
1142 pub fn not_in(self, values: impl IntoIterator<Item = Expr>) -> Expr {
1146 Expr(Expression::In(Box::new(In {
1147 this: self.0,
1148 expressions: values.into_iter().map(|v| v.0).collect(),
1149 query: None,
1150 not: true,
1151 global: false,
1152 unnest: None,
1153 is_field: false,
1154 })))
1155 }
1156}
1157
1158pub struct SelectBuilder {
1184 select: Select,
1185}
1186
1187impl SelectBuilder {
1188 fn new() -> Self {
1189 SelectBuilder {
1190 select: Select::new(),
1191 }
1192 }
1193
1194 pub fn select_cols<I, E>(mut self, expressions: I) -> Self
1199 where
1200 I: IntoIterator<Item = E>,
1201 E: IntoExpr,
1202 {
1203 for expr in expressions {
1204 self.select.expressions.push(expr.into_expr().0);
1205 }
1206 self
1207 }
1208
1209 pub fn from(mut self, table_name: &str) -> Self {
1211 self.select.from = Some(From {
1212 expressions: vec![Expression::Table(builder_table_ref(table_name))],
1213 });
1214 self
1215 }
1216
1217 pub fn from_expr(mut self, expr: Expr) -> Self {
1222 self.select.from = Some(From {
1223 expressions: vec![expr.0],
1224 });
1225 self
1226 }
1227
1228 pub fn join(mut self, table_name: &str, on: Expr) -> Self {
1230 self.select.joins.push(Join {
1231 kind: JoinKind::Inner,
1232 this: Expression::Table(builder_table_ref(table_name)),
1233 on: Some(on.0),
1234 using: Vec::new(),
1235 use_inner_keyword: false,
1236 use_outer_keyword: false,
1237 deferred_condition: false,
1238 join_hint: None,
1239 match_condition: None,
1240 pivots: Vec::new(),
1241 comments: Vec::new(),
1242 nesting_group: 0,
1243 directed: false,
1244 });
1245 self
1246 }
1247
1248 pub fn left_join(mut self, table_name: &str, on: Expr) -> Self {
1250 self.select.joins.push(Join {
1251 kind: JoinKind::Left,
1252 this: Expression::Table(builder_table_ref(table_name)),
1253 on: Some(on.0),
1254 using: Vec::new(),
1255 use_inner_keyword: false,
1256 use_outer_keyword: false,
1257 deferred_condition: false,
1258 join_hint: None,
1259 match_condition: None,
1260 pivots: Vec::new(),
1261 comments: Vec::new(),
1262 nesting_group: 0,
1263 directed: false,
1264 });
1265 self
1266 }
1267
1268 pub fn where_(mut self, condition: Expr) -> Self {
1274 self.select.where_clause = Some(Where { this: condition.0 });
1275 self
1276 }
1277
1278 pub fn group_by<I, E>(mut self, expressions: I) -> Self
1280 where
1281 I: IntoIterator<Item = E>,
1282 E: IntoExpr,
1283 {
1284 self.select.group_by = Some(GroupBy {
1285 expressions: expressions.into_iter().map(|e| e.into_expr().0).collect(),
1286 all: None,
1287 totals: false,
1288 comments: Vec::new(),
1289 });
1290 self
1291 }
1292
1293 pub fn having(mut self, condition: Expr) -> Self {
1295 self.select.having = Some(Having {
1296 this: condition.0,
1297 comments: Vec::new(),
1298 });
1299 self
1300 }
1301
1302 pub fn order_by<I, E>(mut self, expressions: I) -> Self
1308 where
1309 I: IntoIterator<Item = E>,
1310 E: IntoExpr,
1311 {
1312 self.select.order_by = Some(OrderBy {
1313 siblings: false,
1314 comments: Vec::new(),
1315 expressions: expressions
1316 .into_iter()
1317 .map(|e| {
1318 let expr = e.into_expr().0;
1319 match expr {
1320 Expression::Ordered(_) => expr,
1321 other => Expression::Ordered(Box::new(Ordered {
1322 this: other,
1323 desc: false,
1324 nulls_first: None,
1325 explicit_asc: false,
1326 with_fill: None,
1327 })),
1328 }
1329 })
1330 .collect::<Vec<_>>()
1331 .into_iter()
1332 .map(|e| {
1333 if let Expression::Ordered(o) = e {
1334 *o
1335 } else {
1336 Ordered {
1337 this: e,
1338 desc: false,
1339 nulls_first: None,
1340 explicit_asc: false,
1341 with_fill: None,
1342 }
1343 }
1344 })
1345 .collect(),
1346 });
1347 self
1348 }
1349
1350 pub fn sort_by<I, E>(mut self, expressions: I) -> Self
1357 where
1358 I: IntoIterator<Item = E>,
1359 E: IntoExpr,
1360 {
1361 self.select.sort_by = Some(SortBy {
1362 expressions: expressions
1363 .into_iter()
1364 .map(|e| {
1365 let expr = e.into_expr().0;
1366 match expr {
1367 Expression::Ordered(o) => *o,
1368 other => Ordered {
1369 this: other,
1370 desc: false,
1371 nulls_first: None,
1372 explicit_asc: false,
1373 with_fill: None,
1374 },
1375 }
1376 })
1377 .collect(),
1378 });
1379 self
1380 }
1381
1382 pub fn limit(mut self, count: usize) -> Self {
1384 self.select.limit = Some(Limit {
1385 this: Expression::Literal(Literal::Number(count.to_string())),
1386 percent: false,
1387 comments: Vec::new(),
1388 });
1389 self
1390 }
1391
1392 pub fn offset(mut self, count: usize) -> Self {
1394 self.select.offset = Some(Offset {
1395 this: Expression::Literal(Literal::Number(count.to_string())),
1396 rows: None,
1397 });
1398 self
1399 }
1400
1401 pub fn distinct(mut self) -> Self {
1403 self.select.distinct = true;
1404 self
1405 }
1406
1407 pub fn qualify(mut self, condition: Expr) -> Self {
1412 self.select.qualify = Some(Qualify { this: condition.0 });
1413 self
1414 }
1415
1416 pub fn right_join(mut self, table_name: &str, on: Expr) -> Self {
1418 self.select.joins.push(Join {
1419 kind: JoinKind::Right,
1420 this: Expression::Table(builder_table_ref(table_name)),
1421 on: Some(on.0),
1422 using: Vec::new(),
1423 use_inner_keyword: false,
1424 use_outer_keyword: false,
1425 deferred_condition: false,
1426 join_hint: None,
1427 match_condition: None,
1428 pivots: Vec::new(),
1429 comments: Vec::new(),
1430 nesting_group: 0,
1431 directed: false,
1432 });
1433 self
1434 }
1435
1436 pub fn cross_join(mut self, table_name: &str) -> Self {
1438 self.select.joins.push(Join {
1439 kind: JoinKind::Cross,
1440 this: Expression::Table(builder_table_ref(table_name)),
1441 on: None,
1442 using: Vec::new(),
1443 use_inner_keyword: false,
1444 use_outer_keyword: false,
1445 deferred_condition: false,
1446 join_hint: None,
1447 match_condition: None,
1448 pivots: Vec::new(),
1449 comments: Vec::new(),
1450 nesting_group: 0,
1451 directed: false,
1452 });
1453 self
1454 }
1455
1456 pub fn lateral_view<S: AsRef<str>>(
1463 mut self,
1464 table_function: Expr,
1465 table_alias: &str,
1466 column_aliases: impl IntoIterator<Item = S>,
1467 ) -> Self {
1468 self.select.lateral_views.push(LateralView {
1469 this: table_function.0,
1470 table_alias: Some(builder_identifier(table_alias)),
1471 column_aliases: column_aliases
1472 .into_iter()
1473 .map(|c| builder_identifier(c.as_ref()))
1474 .collect(),
1475 outer: false,
1476 });
1477 self
1478 }
1479
1480 pub fn window(mut self, name: &str, def: WindowDefBuilder) -> Self {
1486 let named_window = NamedWindow {
1487 name: builder_identifier(name),
1488 spec: Over {
1489 window_name: None,
1490 partition_by: def.partition_by,
1491 order_by: def.order_by,
1492 frame: None,
1493 alias: None,
1494 },
1495 };
1496 match self.select.windows {
1497 Some(ref mut windows) => windows.push(named_window),
1498 None => self.select.windows = Some(vec![named_window]),
1499 }
1500 self
1501 }
1502
1503 pub fn for_update(mut self) -> Self {
1508 self.select.locks.push(Lock {
1509 update: Some(Box::new(Expression::Boolean(BooleanLiteral {
1510 value: true,
1511 }))),
1512 expressions: vec![],
1513 wait: None,
1514 key: None,
1515 });
1516 self
1517 }
1518
1519 pub fn for_share(mut self) -> Self {
1524 self.select.locks.push(Lock {
1525 update: None,
1526 expressions: vec![],
1527 wait: None,
1528 key: None,
1529 });
1530 self
1531 }
1532
1533 pub fn hint(mut self, hint_text: &str) -> Self {
1538 let hint_expr = HintExpression::Raw(hint_text.to_string());
1539 match &mut self.select.hint {
1540 Some(h) => h.expressions.push(hint_expr),
1541 None => {
1542 self.select.hint = Some(Hint {
1543 expressions: vec![hint_expr],
1544 })
1545 }
1546 }
1547 self
1548 }
1549
1550 pub fn ctas(self, table_name: &str) -> Expression {
1566 Expression::CreateTable(Box::new(CreateTable {
1567 name: builder_table_ref(table_name),
1568 on_cluster: None,
1569 columns: vec![],
1570 constraints: vec![],
1571 if_not_exists: false,
1572 temporary: false,
1573 or_replace: false,
1574 table_modifier: None,
1575 as_select: Some(self.build()),
1576 as_select_parenthesized: false,
1577 on_commit: None,
1578 clone_source: None,
1579 clone_at_clause: None,
1580 is_copy: false,
1581 shallow_clone: false,
1582 leading_comments: vec![],
1583 with_properties: vec![],
1584 teradata_post_name_options: vec![],
1585 with_data: None,
1586 with_statistics: None,
1587 teradata_indexes: vec![],
1588 with_cte: None,
1589 properties: vec![],
1590 partition_of: None,
1591 post_table_properties: vec![],
1592 mysql_table_options: vec![],
1593 inherits: vec![],
1594 on_property: None,
1595 copy_grants: false,
1596 using_template: None,
1597 rollup: None,
1598 }))
1599 }
1600
1601 pub fn union(self, other: SelectBuilder) -> SetOpBuilder {
1605 SetOpBuilder::new(SetOpKind::Union, self, other, false)
1606 }
1607
1608 pub fn union_all(self, other: SelectBuilder) -> SetOpBuilder {
1612 SetOpBuilder::new(SetOpKind::Union, self, other, true)
1613 }
1614
1615 pub fn intersect(self, other: SelectBuilder) -> SetOpBuilder {
1619 SetOpBuilder::new(SetOpKind::Intersect, self, other, false)
1620 }
1621
1622 pub fn except_(self, other: SelectBuilder) -> SetOpBuilder {
1626 SetOpBuilder::new(SetOpKind::Except, self, other, false)
1627 }
1628
1629 pub fn build(self) -> Expression {
1631 Expression::Select(Box::new(self.select))
1632 }
1633
1634 pub fn to_sql(self) -> String {
1639 Generator::sql(&self.build()).unwrap_or_default()
1640 }
1641}
1642
1643pub struct DeleteBuilder {
1652 delete: Delete,
1653}
1654
1655impl DeleteBuilder {
1656 pub fn where_(mut self, condition: Expr) -> Self {
1658 self.delete.where_clause = Some(Where { this: condition.0 });
1659 self
1660 }
1661
1662 pub fn build(self) -> Expression {
1664 Expression::Delete(Box::new(self.delete))
1665 }
1666
1667 pub fn to_sql(self) -> String {
1669 Generator::sql(&self.build()).unwrap_or_default()
1670 }
1671}
1672
1673pub struct InsertBuilder {
1684 insert: Insert,
1685}
1686
1687impl InsertBuilder {
1688 pub fn columns<I, S>(mut self, columns: I) -> Self
1690 where
1691 I: IntoIterator<Item = S>,
1692 S: AsRef<str>,
1693 {
1694 self.insert.columns = columns
1695 .into_iter()
1696 .map(|c| builder_identifier(c.as_ref()))
1697 .collect();
1698 self
1699 }
1700
1701 pub fn values<I>(mut self, values: I) -> Self
1705 where
1706 I: IntoIterator<Item = Expr>,
1707 {
1708 self.insert
1709 .values
1710 .push(values.into_iter().map(|v| v.0).collect());
1711 self
1712 }
1713
1714 pub fn query(mut self, query: SelectBuilder) -> Self {
1718 self.insert.query = Some(query.build());
1719 self
1720 }
1721
1722 pub fn build(self) -> Expression {
1724 Expression::Insert(Box::new(self.insert))
1725 }
1726
1727 pub fn to_sql(self) -> String {
1729 Generator::sql(&self.build()).unwrap_or_default()
1730 }
1731}
1732
1733pub struct UpdateBuilder {
1743 update: Update,
1744}
1745
1746impl UpdateBuilder {
1747 pub fn set(mut self, column: &str, value: Expr) -> Self {
1751 self.update.set.push((builder_identifier(column), value.0));
1752 self
1753 }
1754
1755 pub fn where_(mut self, condition: Expr) -> Self {
1757 self.update.where_clause = Some(Where { this: condition.0 });
1758 self
1759 }
1760
1761 pub fn from(mut self, table_name: &str) -> Self {
1765 self.update.from_clause = Some(From {
1766 expressions: vec![Expression::Table(builder_table_ref(table_name))],
1767 });
1768 self
1769 }
1770
1771 pub fn build(self) -> Expression {
1773 Expression::Update(Box::new(self.update))
1774 }
1775
1776 pub fn to_sql(self) -> String {
1778 Generator::sql(&self.build()).unwrap_or_default()
1779 }
1780}
1781
1782pub fn case() -> CaseBuilder {
1807 CaseBuilder {
1808 operand: None,
1809 whens: Vec::new(),
1810 else_: None,
1811 }
1812}
1813
1814pub fn case_of(operand: Expr) -> CaseBuilder {
1835 CaseBuilder {
1836 operand: Some(operand.0),
1837 whens: Vec::new(),
1838 else_: None,
1839 }
1840}
1841
1842pub struct CaseBuilder {
1850 operand: Option<Expression>,
1851 whens: Vec<(Expression, Expression)>,
1852 else_: Option<Expression>,
1853}
1854
1855impl CaseBuilder {
1856 pub fn when(mut self, condition: Expr, result: Expr) -> Self {
1861 self.whens.push((condition.0, result.0));
1862 self
1863 }
1864
1865 pub fn else_(mut self, result: Expr) -> Self {
1870 self.else_ = Some(result.0);
1871 self
1872 }
1873
1874 pub fn build(self) -> Expr {
1876 Expr(self.build_expr())
1877 }
1878
1879 pub fn build_expr(self) -> Expression {
1884 Expression::Case(Box::new(Case {
1885 operand: self.operand,
1886 whens: self.whens,
1887 else_: self.else_,
1888 comments: Vec::new(),
1889 }))
1890 }
1891}
1892
1893pub fn subquery(query: SelectBuilder, alias_name: &str) -> Expr {
1917 subquery_expr(query.build(), alias_name)
1918}
1919
1920pub fn subquery_expr(expr: Expression, alias_name: &str) -> Expr {
1925 Expr(Expression::Subquery(Box::new(Subquery {
1926 this: expr,
1927 alias: Some(builder_identifier(alias_name)),
1928 column_aliases: Vec::new(),
1929 order_by: None,
1930 limit: None,
1931 offset: None,
1932 distribute_by: None,
1933 sort_by: None,
1934 cluster_by: None,
1935 lateral: false,
1936 modifiers_inside: true,
1937 trailing_comments: Vec::new(),
1938 })))
1939}
1940
1941#[derive(Debug, Clone, Copy)]
1947enum SetOpKind {
1948 Union,
1949 Intersect,
1950 Except,
1951}
1952
1953pub struct SetOpBuilder {
1974 kind: SetOpKind,
1975 left: Expression,
1976 right: Expression,
1977 all: bool,
1978 order_by: Option<OrderBy>,
1979 limit: Option<Box<Expression>>,
1980 offset: Option<Box<Expression>>,
1981}
1982
1983impl SetOpBuilder {
1984 fn new(kind: SetOpKind, left: SelectBuilder, right: SelectBuilder, all: bool) -> Self {
1985 SetOpBuilder {
1986 kind,
1987 left: left.build(),
1988 right: right.build(),
1989 all,
1990 order_by: None,
1991 limit: None,
1992 offset: None,
1993 }
1994 }
1995
1996 pub fn order_by<I, E>(mut self, expressions: I) -> Self
2001 where
2002 I: IntoIterator<Item = E>,
2003 E: IntoExpr,
2004 {
2005 self.order_by = Some(OrderBy {
2006 siblings: false,
2007 comments: Vec::new(),
2008 expressions: expressions
2009 .into_iter()
2010 .map(|e| {
2011 let expr = e.into_expr().0;
2012 match expr {
2013 Expression::Ordered(o) => *o,
2014 other => Ordered {
2015 this: other,
2016 desc: false,
2017 nulls_first: None,
2018 explicit_asc: false,
2019 with_fill: None,
2020 },
2021 }
2022 })
2023 .collect(),
2024 });
2025 self
2026 }
2027
2028 pub fn limit(mut self, count: usize) -> Self {
2030 self.limit = Some(Box::new(Expression::Literal(Literal::Number(
2031 count.to_string(),
2032 ))));
2033 self
2034 }
2035
2036 pub fn offset(mut self, count: usize) -> Self {
2038 self.offset = Some(Box::new(Expression::Literal(Literal::Number(
2039 count.to_string(),
2040 ))));
2041 self
2042 }
2043
2044 pub fn build(self) -> Expression {
2049 match self.kind {
2050 SetOpKind::Union => Expression::Union(Box::new(Union {
2051 left: self.left,
2052 right: self.right,
2053 all: self.all,
2054 distinct: false,
2055 with: None,
2056 order_by: self.order_by,
2057 limit: self.limit,
2058 offset: self.offset,
2059 distribute_by: None,
2060 sort_by: None,
2061 cluster_by: None,
2062 by_name: false,
2063 side: None,
2064 kind: None,
2065 corresponding: false,
2066 strict: false,
2067 on_columns: Vec::new(),
2068 })),
2069 SetOpKind::Intersect => Expression::Intersect(Box::new(Intersect {
2070 left: self.left,
2071 right: self.right,
2072 all: self.all,
2073 distinct: false,
2074 with: None,
2075 order_by: self.order_by,
2076 limit: self.limit,
2077 offset: self.offset,
2078 distribute_by: None,
2079 sort_by: None,
2080 cluster_by: None,
2081 by_name: false,
2082 side: None,
2083 kind: None,
2084 corresponding: false,
2085 strict: false,
2086 on_columns: Vec::new(),
2087 })),
2088 SetOpKind::Except => Expression::Except(Box::new(Except {
2089 left: self.left,
2090 right: self.right,
2091 all: self.all,
2092 distinct: false,
2093 with: None,
2094 order_by: self.order_by,
2095 limit: self.limit,
2096 offset: self.offset,
2097 distribute_by: None,
2098 sort_by: None,
2099 cluster_by: None,
2100 by_name: false,
2101 side: None,
2102 kind: None,
2103 corresponding: false,
2104 strict: false,
2105 on_columns: Vec::new(),
2106 })),
2107 }
2108 }
2109
2110 pub fn to_sql(self) -> String {
2112 Generator::sql(&self.build()).unwrap_or_default()
2113 }
2114}
2115
2116pub fn union(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2120 SetOpBuilder::new(SetOpKind::Union, left, right, false)
2121}
2122
2123pub fn union_all(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2127 SetOpBuilder::new(SetOpKind::Union, left, right, true)
2128}
2129
2130pub fn intersect(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2134 SetOpBuilder::new(SetOpKind::Intersect, left, right, false)
2135}
2136
2137pub fn intersect_all(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2141 SetOpBuilder::new(SetOpKind::Intersect, left, right, true)
2142}
2143
2144pub fn except_(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2148 SetOpBuilder::new(SetOpKind::Except, left, right, false)
2149}
2150
2151pub fn except_all(left: SelectBuilder, right: SelectBuilder) -> SetOpBuilder {
2155 SetOpBuilder::new(SetOpKind::Except, left, right, true)
2156}
2157
2158pub struct WindowDefBuilder {
2183 partition_by: Vec<Expression>,
2184 order_by: Vec<Ordered>,
2185}
2186
2187impl WindowDefBuilder {
2188 pub fn new() -> Self {
2190 WindowDefBuilder {
2191 partition_by: Vec::new(),
2192 order_by: Vec::new(),
2193 }
2194 }
2195
2196 pub fn partition_by<I, E>(mut self, expressions: I) -> Self
2198 where
2199 I: IntoIterator<Item = E>,
2200 E: IntoExpr,
2201 {
2202 self.partition_by = expressions.into_iter().map(|e| e.into_expr().0).collect();
2203 self
2204 }
2205
2206 pub fn order_by<I, E>(mut self, expressions: I) -> Self
2211 where
2212 I: IntoIterator<Item = E>,
2213 E: IntoExpr,
2214 {
2215 self.order_by = expressions
2216 .into_iter()
2217 .map(|e| {
2218 let expr = e.into_expr().0;
2219 match expr {
2220 Expression::Ordered(o) => *o,
2221 other => Ordered {
2222 this: other,
2223 desc: false,
2224 nulls_first: None,
2225 explicit_asc: false,
2226 with_fill: None,
2227 },
2228 }
2229 })
2230 .collect();
2231 self
2232 }
2233}
2234
2235pub trait IntoExpr {
2254 fn into_expr(self) -> Expr;
2256}
2257
2258impl IntoExpr for Expr {
2259 fn into_expr(self) -> Expr {
2260 self
2261 }
2262}
2263
2264impl IntoExpr for &str {
2265 fn into_expr(self) -> Expr {
2267 col(self)
2268 }
2269}
2270
2271impl IntoExpr for String {
2272 fn into_expr(self) -> Expr {
2274 col(&self)
2275 }
2276}
2277
2278impl IntoExpr for Expression {
2279 fn into_expr(self) -> Expr {
2281 Expr(self)
2282 }
2283}
2284
2285pub trait IntoLiteral {
2300 fn into_literal(self) -> Expr;
2302}
2303
2304impl IntoLiteral for &str {
2305 fn into_literal(self) -> Expr {
2307 Expr(Expression::Literal(Literal::String(self.to_string())))
2308 }
2309}
2310
2311impl IntoLiteral for String {
2312 fn into_literal(self) -> Expr {
2314 Expr(Expression::Literal(Literal::String(self)))
2315 }
2316}
2317
2318impl IntoLiteral for i64 {
2319 fn into_literal(self) -> Expr {
2321 Expr(Expression::Literal(Literal::Number(self.to_string())))
2322 }
2323}
2324
2325impl IntoLiteral for i32 {
2326 fn into_literal(self) -> Expr {
2328 Expr(Expression::Literal(Literal::Number(self.to_string())))
2329 }
2330}
2331
2332impl IntoLiteral for usize {
2333 fn into_literal(self) -> Expr {
2335 Expr(Expression::Literal(Literal::Number(self.to_string())))
2336 }
2337}
2338
2339impl IntoLiteral for f64 {
2340 fn into_literal(self) -> Expr {
2342 Expr(Expression::Literal(Literal::Number(self.to_string())))
2343 }
2344}
2345
2346impl IntoLiteral for bool {
2347 fn into_literal(self) -> Expr {
2349 Expr(Expression::Boolean(BooleanLiteral { value: self }))
2350 }
2351}
2352
2353fn binary_op(left: Expression, right: Expression) -> BinaryOp {
2358 BinaryOp {
2359 left,
2360 right,
2361 left_comments: Vec::new(),
2362 operator_comments: Vec::new(),
2363 trailing_comments: Vec::new(),
2364 }
2365}
2366
2367pub fn merge_into(target: &str) -> MergeBuilder {
2389 MergeBuilder {
2390 target: Expression::Table(builder_table_ref(target)),
2391 using: None,
2392 on: None,
2393 whens: Vec::new(),
2394 }
2395}
2396
2397pub struct MergeBuilder {
2401 target: Expression,
2402 using: Option<Expression>,
2403 on: Option<Expression>,
2404 whens: Vec<Expression>,
2405}
2406
2407impl MergeBuilder {
2408 pub fn using(mut self, source: &str, on: Expr) -> Self {
2410 self.using = Some(Expression::Table(builder_table_ref(source)));
2411 self.on = Some(on.0);
2412 self
2413 }
2414
2415 pub fn when_matched_update(mut self, assignments: Vec<(&str, Expr)>) -> Self {
2417 let eqs: Vec<Expression> = assignments
2418 .into_iter()
2419 .map(|(col_name, val)| {
2420 Expression::Eq(Box::new(BinaryOp {
2421 left: Expression::Column(Column {
2422 name: builder_identifier(col_name),
2423 table: None,
2424 join_mark: false,
2425 trailing_comments: Vec::new(),
2426 span: None,
2427 }),
2428 right: val.0,
2429 left_comments: Vec::new(),
2430 operator_comments: Vec::new(),
2431 trailing_comments: Vec::new(),
2432 }))
2433 })
2434 .collect();
2435
2436 let action = Expression::Tuple(Box::new(Tuple {
2437 expressions: vec![
2438 Expression::Var(Box::new(Var {
2439 this: "UPDATE".to_string(),
2440 })),
2441 Expression::Tuple(Box::new(Tuple { expressions: eqs })),
2442 ],
2443 }));
2444
2445 let when = Expression::When(Box::new(When {
2446 matched: Some(Box::new(Expression::Boolean(BooleanLiteral {
2447 value: true,
2448 }))),
2449 source: None,
2450 condition: None,
2451 then: Box::new(action),
2452 }));
2453 self.whens.push(when);
2454 self
2455 }
2456
2457 pub fn when_matched_update_where(
2459 mut self,
2460 condition: Expr,
2461 assignments: Vec<(&str, Expr)>,
2462 ) -> Self {
2463 let eqs: Vec<Expression> = assignments
2464 .into_iter()
2465 .map(|(col_name, val)| {
2466 Expression::Eq(Box::new(BinaryOp {
2467 left: Expression::Column(Column {
2468 name: builder_identifier(col_name),
2469 table: None,
2470 join_mark: false,
2471 trailing_comments: Vec::new(),
2472 span: None,
2473 }),
2474 right: val.0,
2475 left_comments: Vec::new(),
2476 operator_comments: Vec::new(),
2477 trailing_comments: Vec::new(),
2478 }))
2479 })
2480 .collect();
2481
2482 let action = Expression::Tuple(Box::new(Tuple {
2483 expressions: vec![
2484 Expression::Var(Box::new(Var {
2485 this: "UPDATE".to_string(),
2486 })),
2487 Expression::Tuple(Box::new(Tuple { expressions: eqs })),
2488 ],
2489 }));
2490
2491 let when = Expression::When(Box::new(When {
2492 matched: Some(Box::new(Expression::Boolean(BooleanLiteral {
2493 value: true,
2494 }))),
2495 source: None,
2496 condition: Some(Box::new(condition.0)),
2497 then: Box::new(action),
2498 }));
2499 self.whens.push(when);
2500 self
2501 }
2502
2503 pub fn when_matched_delete(mut self) -> Self {
2505 let action = Expression::Var(Box::new(Var {
2506 this: "DELETE".to_string(),
2507 }));
2508
2509 let when = Expression::When(Box::new(When {
2510 matched: Some(Box::new(Expression::Boolean(BooleanLiteral {
2511 value: true,
2512 }))),
2513 source: None,
2514 condition: None,
2515 then: Box::new(action),
2516 }));
2517 self.whens.push(when);
2518 self
2519 }
2520
2521 pub fn when_not_matched_insert(mut self, columns: &[&str], values: Vec<Expr>) -> Self {
2523 let col_exprs: Vec<Expression> = columns
2524 .iter()
2525 .map(|c| {
2526 Expression::Column(Column {
2527 name: builder_identifier(c),
2528 table: None,
2529 join_mark: false,
2530 trailing_comments: Vec::new(),
2531 span: None,
2532 })
2533 })
2534 .collect();
2535 let val_exprs: Vec<Expression> = values.into_iter().map(|v| v.0).collect();
2536
2537 let action = Expression::Tuple(Box::new(Tuple {
2538 expressions: vec![
2539 Expression::Var(Box::new(Var {
2540 this: "INSERT".to_string(),
2541 })),
2542 Expression::Tuple(Box::new(Tuple {
2543 expressions: col_exprs,
2544 })),
2545 Expression::Tuple(Box::new(Tuple {
2546 expressions: val_exprs,
2547 })),
2548 ],
2549 }));
2550
2551 let when = Expression::When(Box::new(When {
2552 matched: Some(Box::new(Expression::Boolean(BooleanLiteral {
2553 value: false,
2554 }))),
2555 source: None,
2556 condition: None,
2557 then: Box::new(action),
2558 }));
2559 self.whens.push(when);
2560 self
2561 }
2562
2563 pub fn build(self) -> Expression {
2565 let whens_expr = Expression::Whens(Box::new(Whens {
2566 expressions: self.whens,
2567 }));
2568
2569 Expression::Merge(Box::new(Merge {
2570 this: Box::new(self.target),
2571 using: Box::new(
2572 self.using
2573 .unwrap_or(Expression::Null(crate::expressions::Null)),
2574 ),
2575 on: self.on.map(Box::new),
2576 using_cond: None,
2577 whens: Some(Box::new(whens_expr)),
2578 with_: None,
2579 returning: None,
2580 }))
2581 }
2582
2583 pub fn to_sql(self) -> String {
2585 Generator::sql(&self.build()).unwrap_or_default()
2586 }
2587}
2588
2589fn parse_simple_data_type(name: &str) -> DataType {
2590 let upper = name.trim().to_uppercase();
2591 match upper.as_str() {
2592 "INT" | "INTEGER" => DataType::Int {
2593 length: None,
2594 integer_spelling: upper == "INTEGER",
2595 },
2596 "BIGINT" => DataType::BigInt { length: None },
2597 "SMALLINT" => DataType::SmallInt { length: None },
2598 "TINYINT" => DataType::TinyInt { length: None },
2599 "FLOAT" => DataType::Float {
2600 precision: None,
2601 scale: None,
2602 real_spelling: false,
2603 },
2604 "DOUBLE" => DataType::Double {
2605 precision: None,
2606 scale: None,
2607 },
2608 "BOOLEAN" | "BOOL" => DataType::Boolean,
2609 "TEXT" => DataType::Text,
2610 "DATE" => DataType::Date,
2611 "TIMESTAMP" => DataType::Timestamp {
2612 precision: None,
2613 timezone: false,
2614 },
2615 "VARCHAR" => DataType::VarChar {
2616 length: None,
2617 parenthesized_length: false,
2618 },
2619 "CHAR" => DataType::Char { length: None },
2620 _ => {
2621 if let Ok(ast) =
2623 crate::parser::Parser::parse_sql(&format!("SELECT CAST(x AS {})", name))
2624 {
2625 if let Expression::Select(s) = &ast[0] {
2626 if let Some(Expression::Cast(c)) = s.expressions.first() {
2627 return c.to.clone();
2628 }
2629 }
2630 }
2631 DataType::Custom {
2633 name: name.to_string(),
2634 }
2635 }
2636 }
2637}
2638
2639#[cfg(test)]
2640mod tests {
2641 use super::*;
2642
2643 #[test]
2644 fn test_simple_select() {
2645 let sql = select(["id", "name"]).from("users").to_sql();
2646 assert_eq!(sql, "SELECT id, name FROM users");
2647 }
2648
2649 #[test]
2650 fn test_builder_quotes_unsafe_identifier_tokens() {
2651 let sql = select(["Name; DROP TABLE titanic"]).to_sql();
2652 assert_eq!(sql, r#"SELECT "Name; DROP TABLE titanic""#);
2653 }
2654
2655 #[test]
2656 fn test_builder_string_literal_requires_lit() {
2657 let sql = select([lit("Name; DROP TABLE titanic")]).to_sql();
2658 assert_eq!(sql, "SELECT 'Name; DROP TABLE titanic'");
2659 }
2660
2661 #[test]
2662 fn test_builder_quotes_unsafe_table_name_tokens() {
2663 let sql = select(["id"]).from("users; DROP TABLE x").to_sql();
2664 assert_eq!(sql, r#"SELECT id FROM "users; DROP TABLE x""#);
2665 }
2666
2667 #[test]
2668 fn test_select_star() {
2669 let sql = select([star()]).from("users").to_sql();
2670 assert_eq!(sql, "SELECT * FROM users");
2671 }
2672
2673 #[test]
2674 fn test_select_with_where() {
2675 let sql = select(["id", "name"])
2676 .from("users")
2677 .where_(col("age").gt(lit(18)))
2678 .to_sql();
2679 assert_eq!(sql, "SELECT id, name FROM users WHERE age > 18");
2680 }
2681
2682 #[test]
2683 fn test_select_with_join() {
2684 let sql = select(["u.id", "o.amount"])
2685 .from("users")
2686 .join("orders", col("u.id").eq(col("o.user_id")))
2687 .to_sql();
2688 assert_eq!(
2689 sql,
2690 "SELECT u.id, o.amount FROM users JOIN orders ON u.id = o.user_id"
2691 );
2692 }
2693
2694 #[test]
2695 fn test_select_with_group_by_having() {
2696 let sql = select([col("dept"), func("COUNT", [star()]).alias("cnt")])
2697 .from("employees")
2698 .group_by(["dept"])
2699 .having(func("COUNT", [star()]).gt(lit(5)))
2700 .to_sql();
2701 assert_eq!(
2702 sql,
2703 "SELECT dept, COUNT(*) AS cnt FROM employees GROUP BY dept HAVING COUNT(*) > 5"
2704 );
2705 }
2706
2707 #[test]
2708 fn test_select_with_order_limit_offset() {
2709 let sql = select(["id", "name"])
2710 .from("users")
2711 .order_by(["name"])
2712 .limit(10)
2713 .offset(20)
2714 .to_sql();
2715 assert_eq!(
2716 sql,
2717 "SELECT id, name FROM users ORDER BY name LIMIT 10 OFFSET 20"
2718 );
2719 }
2720
2721 #[test]
2722 fn test_select_distinct() {
2723 let sql = select(["name"]).from("users").distinct().to_sql();
2724 assert_eq!(sql, "SELECT DISTINCT name FROM users");
2725 }
2726
2727 #[test]
2728 fn test_insert_values() {
2729 let sql = insert_into("users")
2730 .columns(["id", "name"])
2731 .values([lit(1), lit("Alice")])
2732 .values([lit(2), lit("Bob")])
2733 .to_sql();
2734 assert_eq!(
2735 sql,
2736 "INSERT INTO users (id, name) VALUES (1, 'Alice'), (2, 'Bob')"
2737 );
2738 }
2739
2740 #[test]
2741 fn test_insert_select() {
2742 let sql = insert_into("archive")
2743 .columns(["id", "name"])
2744 .query(select(["id", "name"]).from("users"))
2745 .to_sql();
2746 assert_eq!(
2747 sql,
2748 "INSERT INTO archive (id, name) SELECT id, name FROM users"
2749 );
2750 }
2751
2752 #[test]
2753 fn test_update() {
2754 let sql = update("users")
2755 .set("name", lit("Bob"))
2756 .set("age", lit(30))
2757 .where_(col("id").eq(lit(1)))
2758 .to_sql();
2759 assert_eq!(sql, "UPDATE users SET name = 'Bob', age = 30 WHERE id = 1");
2760 }
2761
2762 #[test]
2763 fn test_delete() {
2764 let sql = delete("users").where_(col("id").eq(lit(1))).to_sql();
2765 assert_eq!(sql, "DELETE FROM users WHERE id = 1");
2766 }
2767
2768 #[test]
2769 fn test_complex_where() {
2770 let sql = select(["id"])
2771 .from("users")
2772 .where_(
2773 col("age")
2774 .gte(lit(18))
2775 .and(col("active").eq(boolean(true)))
2776 .and(col("name").like(lit("%test%"))),
2777 )
2778 .to_sql();
2779 assert_eq!(
2780 sql,
2781 "SELECT id FROM users WHERE age >= 18 AND active = TRUE AND name LIKE '%test%'"
2782 );
2783 }
2784
2785 #[test]
2786 fn test_in_list() {
2787 let sql = select(["id"])
2788 .from("users")
2789 .where_(col("status").in_list([lit("active"), lit("pending")]))
2790 .to_sql();
2791 assert_eq!(
2792 sql,
2793 "SELECT id FROM users WHERE status IN ('active', 'pending')"
2794 );
2795 }
2796
2797 #[test]
2798 fn test_between() {
2799 let sql = select(["id"])
2800 .from("orders")
2801 .where_(col("amount").between(lit(100), lit(500)))
2802 .to_sql();
2803 assert_eq!(
2804 sql,
2805 "SELECT id FROM orders WHERE amount BETWEEN 100 AND 500"
2806 );
2807 }
2808
2809 #[test]
2810 fn test_is_null() {
2811 let sql = select(["id"])
2812 .from("users")
2813 .where_(col("email").is_null())
2814 .to_sql();
2815 assert_eq!(sql, "SELECT id FROM users WHERE email IS NULL");
2816 }
2817
2818 #[test]
2819 fn test_arithmetic() {
2820 let sql = select([col("price").mul(col("quantity")).alias("total")])
2821 .from("items")
2822 .to_sql();
2823 assert_eq!(sql, "SELECT price * quantity AS total FROM items");
2824 }
2825
2826 #[test]
2827 fn test_cast() {
2828 let sql = select([col("id").cast("VARCHAR")]).from("users").to_sql();
2829 assert_eq!(sql, "SELECT CAST(id AS VARCHAR) FROM users");
2830 }
2831
2832 #[test]
2833 fn test_from_starter() {
2834 let sql = from("users").select_cols(["id", "name"]).to_sql();
2835 assert_eq!(sql, "SELECT id, name FROM users");
2836 }
2837
2838 #[test]
2839 fn test_qualified_column() {
2840 let sql = select([col("u.id"), col("u.name")]).from("users").to_sql();
2841 assert_eq!(sql, "SELECT u.id, u.name FROM users");
2842 }
2843
2844 #[test]
2845 fn test_not_condition() {
2846 let sql = select(["id"])
2847 .from("users")
2848 .where_(not(col("active").eq(boolean(true))))
2849 .to_sql();
2850 assert_eq!(sql, "SELECT id FROM users WHERE NOT active = TRUE");
2851 }
2852
2853 #[test]
2854 fn test_order_by_desc() {
2855 let sql = select(["id", "name"])
2856 .from("users")
2857 .order_by([col("name").desc()])
2858 .to_sql();
2859 assert_eq!(sql, "SELECT id, name FROM users ORDER BY name DESC");
2860 }
2861
2862 #[test]
2863 fn test_left_join() {
2864 let sql = select(["u.id", "o.amount"])
2865 .from("users")
2866 .left_join("orders", col("u.id").eq(col("o.user_id")))
2867 .to_sql();
2868 assert_eq!(
2869 sql,
2870 "SELECT u.id, o.amount FROM users LEFT JOIN orders ON u.id = o.user_id"
2871 );
2872 }
2873
2874 #[test]
2875 fn test_build_returns_expression() {
2876 let expr = select(["id"]).from("users").build();
2877 assert!(matches!(expr, Expression::Select(_)));
2878 }
2879
2880 #[test]
2881 fn test_expr_interop() {
2882 let age_check = col("age").gt(lit(18));
2884 let sql = select([col("id"), age_check.alias("is_adult")])
2885 .from("users")
2886 .to_sql();
2887 assert_eq!(sql, "SELECT id, age > 18 AS is_adult FROM users");
2888 }
2889
2890 #[test]
2893 fn test_sql_expr_simple() {
2894 let expr = sql_expr("age > 18");
2895 let sql = select(["id"]).from("users").where_(expr).to_sql();
2896 assert_eq!(sql, "SELECT id FROM users WHERE age > 18");
2897 }
2898
2899 #[test]
2900 fn test_sql_expr_compound() {
2901 let expr = sql_expr("a > 1 AND b < 10");
2902 let sql = select(["*"]).from("t").where_(expr).to_sql();
2903 assert_eq!(sql, "SELECT * FROM t WHERE a > 1 AND b < 10");
2904 }
2905
2906 #[test]
2907 fn test_sql_expr_function() {
2908 let expr = sql_expr("COALESCE(a, b, 0)");
2909 let sql = select([expr.alias("val")]).from("t").to_sql();
2910 assert_eq!(sql, "SELECT COALESCE(a, b, 0) AS val FROM t");
2911 }
2912
2913 #[test]
2914 fn test_condition_alias() {
2915 let cond = condition("x > 0");
2916 let sql = select(["*"]).from("t").where_(cond).to_sql();
2917 assert_eq!(sql, "SELECT * FROM t WHERE x > 0");
2918 }
2919
2920 #[test]
2923 fn test_ilike() {
2924 let sql = select(["id"])
2925 .from("users")
2926 .where_(col("name").ilike(lit("%test%")))
2927 .to_sql();
2928 assert_eq!(sql, "SELECT id FROM users WHERE name ILIKE '%test%'");
2929 }
2930
2931 #[test]
2932 fn test_rlike() {
2933 let sql = select(["id"])
2934 .from("users")
2935 .where_(col("name").rlike(lit("^[A-Z]")))
2936 .to_sql();
2937 assert_eq!(
2938 sql,
2939 "SELECT id FROM users WHERE REGEXP_LIKE(name, '^[A-Z]')"
2940 );
2941 }
2942
2943 #[test]
2944 fn test_not_in() {
2945 let sql = select(["id"])
2946 .from("users")
2947 .where_(col("status").not_in([lit("deleted"), lit("banned")]))
2948 .to_sql();
2949 assert_eq!(
2950 sql,
2951 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
2952 );
2953 }
2954
2955 #[test]
2958 fn test_case_searched() {
2959 let expr = case()
2960 .when(col("x").gt(lit(0)), lit("positive"))
2961 .when(col("x").eq(lit(0)), lit("zero"))
2962 .else_(lit("negative"))
2963 .build();
2964 let sql = select([expr.alias("label")]).from("t").to_sql();
2965 assert_eq!(
2966 sql,
2967 "SELECT CASE WHEN x > 0 THEN 'positive' WHEN x = 0 THEN 'zero' ELSE 'negative' END AS label FROM t"
2968 );
2969 }
2970
2971 #[test]
2972 fn test_case_simple() {
2973 let expr = case_of(col("status"))
2974 .when(lit(1), lit("active"))
2975 .when(lit(0), lit("inactive"))
2976 .build();
2977 let sql = select([expr.alias("status_label")]).from("t").to_sql();
2978 assert_eq!(
2979 sql,
2980 "SELECT CASE status WHEN 1 THEN 'active' WHEN 0 THEN 'inactive' END AS status_label FROM t"
2981 );
2982 }
2983
2984 #[test]
2985 fn test_case_no_else() {
2986 let expr = case().when(col("x").gt(lit(0)), lit("yes")).build();
2987 let sql = select([expr]).from("t").to_sql();
2988 assert_eq!(sql, "SELECT CASE WHEN x > 0 THEN 'yes' END FROM t");
2989 }
2990
2991 #[test]
2994 fn test_subquery_in_from() {
2995 let inner = select(["id", "name"])
2996 .from("users")
2997 .where_(col("active").eq(boolean(true)));
2998 let outer = select(["sub.id"])
2999 .from_expr(subquery(inner, "sub"))
3000 .to_sql();
3001 assert_eq!(
3002 outer,
3003 "SELECT sub.id FROM (SELECT id, name FROM users WHERE active = TRUE) AS sub"
3004 );
3005 }
3006
3007 #[test]
3008 fn test_subquery_in_join() {
3009 let inner = select([col("user_id"), func("SUM", [col("amount")]).alias("total")])
3010 .from("orders")
3011 .group_by(["user_id"]);
3012 let sql = select(["u.name", "o.total"])
3013 .from("users")
3014 .join("orders", col("u.id").eq(col("o.user_id")))
3015 .to_sql();
3016 assert!(sql.contains("JOIN"));
3017 let _sub = subquery(inner, "o");
3019 }
3020
3021 #[test]
3024 fn test_union() {
3025 let sql = union(select(["id"]).from("a"), select(["id"]).from("b")).to_sql();
3026 assert_eq!(sql, "SELECT id FROM a UNION SELECT id FROM b");
3027 }
3028
3029 #[test]
3030 fn test_union_all() {
3031 let sql = union_all(select(["id"]).from("a"), select(["id"]).from("b")).to_sql();
3032 assert_eq!(sql, "SELECT id FROM a UNION ALL SELECT id FROM b");
3033 }
3034
3035 #[test]
3036 fn test_intersect_builder() {
3037 let sql = intersect(select(["id"]).from("a"), select(["id"]).from("b")).to_sql();
3038 assert_eq!(sql, "SELECT id FROM a INTERSECT SELECT id FROM b");
3039 }
3040
3041 #[test]
3042 fn test_except_builder() {
3043 let sql = except_(select(["id"]).from("a"), select(["id"]).from("b")).to_sql();
3044 assert_eq!(sql, "SELECT id FROM a EXCEPT SELECT id FROM b");
3045 }
3046
3047 #[test]
3048 fn test_union_with_order_limit() {
3049 let sql = union(select(["id"]).from("a"), select(["id"]).from("b"))
3050 .order_by(["id"])
3051 .limit(10)
3052 .to_sql();
3053 assert!(sql.contains("UNION"));
3054 assert!(sql.contains("ORDER BY"));
3055 assert!(sql.contains("LIMIT"));
3056 }
3057
3058 #[test]
3059 fn test_select_builder_union() {
3060 let sql = select(["id"])
3061 .from("a")
3062 .union(select(["id"]).from("b"))
3063 .to_sql();
3064 assert_eq!(sql, "SELECT id FROM a UNION SELECT id FROM b");
3065 }
3066
3067 #[test]
3070 fn test_qualify() {
3071 let sql = select(["id", "name"])
3072 .from("users")
3073 .qualify(col("rn").eq(lit(1)))
3074 .to_sql();
3075 assert_eq!(sql, "SELECT id, name FROM users QUALIFY rn = 1");
3076 }
3077
3078 #[test]
3079 fn test_right_join() {
3080 let sql = select(["u.id", "o.amount"])
3081 .from("users")
3082 .right_join("orders", col("u.id").eq(col("o.user_id")))
3083 .to_sql();
3084 assert_eq!(
3085 sql,
3086 "SELECT u.id, o.amount FROM users RIGHT JOIN orders ON u.id = o.user_id"
3087 );
3088 }
3089
3090 #[test]
3091 fn test_cross_join() {
3092 let sql = select(["a.x", "b.y"]).from("a").cross_join("b").to_sql();
3093 assert_eq!(sql, "SELECT a.x, b.y FROM a CROSS JOIN b");
3094 }
3095
3096 #[test]
3097 fn test_lateral_view() {
3098 let sql = select(["id", "col_val"])
3099 .from("t")
3100 .lateral_view(func("EXPLODE", [col("arr")]), "lv", ["col_val"])
3101 .to_sql();
3102 assert!(sql.contains("LATERAL VIEW"));
3103 assert!(sql.contains("EXPLODE"));
3104 }
3105
3106 #[test]
3107 fn test_window_clause() {
3108 let sql = select(["id"])
3109 .from("t")
3110 .window(
3111 "w",
3112 WindowDefBuilder::new()
3113 .partition_by(["dept"])
3114 .order_by(["salary"]),
3115 )
3116 .to_sql();
3117 assert!(sql.contains("WINDOW"));
3118 assert!(sql.contains("PARTITION BY"));
3119 }
3120
3121 #[test]
3124 fn test_xor() {
3125 let sql = select(["*"])
3126 .from("t")
3127 .where_(col("a").xor(col("b")))
3128 .to_sql();
3129 assert_eq!(sql, "SELECT * FROM t WHERE a XOR b");
3130 }
3131
3132 #[test]
3135 fn test_for_update() {
3136 let sql = select(["id"]).from("t").for_update().to_sql();
3137 assert_eq!(sql, "SELECT id FROM t FOR UPDATE");
3138 }
3139
3140 #[test]
3141 fn test_for_share() {
3142 let sql = select(["id"]).from("t").for_share().to_sql();
3143 assert_eq!(sql, "SELECT id FROM t FOR SHARE");
3144 }
3145
3146 #[test]
3149 fn test_hint() {
3150 let sql = select(["*"]).from("t").hint("FULL(t)").to_sql();
3151 assert!(sql.contains("FULL(t)"), "Expected hint in: {}", sql);
3152 }
3153
3154 #[test]
3157 fn test_ctas() {
3158 let expr = select(["*"]).from("t").ctas("new_table");
3159 let sql = Generator::sql(&expr).unwrap();
3160 assert_eq!(sql, "CREATE TABLE new_table AS SELECT * FROM t");
3161 }
3162
3163 #[test]
3166 fn test_merge_update_insert() {
3167 let sql = merge_into("target")
3168 .using("source", col("target.id").eq(col("source.id")))
3169 .when_matched_update(vec![("name", col("source.name"))])
3170 .when_not_matched_insert(&["id", "name"], vec![col("source.id"), col("source.name")])
3171 .to_sql();
3172 assert!(
3173 sql.contains("MERGE INTO"),
3174 "Expected MERGE INTO in: {}",
3175 sql
3176 );
3177 assert!(sql.contains("USING"), "Expected USING in: {}", sql);
3178 assert!(
3179 sql.contains("WHEN MATCHED"),
3180 "Expected WHEN MATCHED in: {}",
3181 sql
3182 );
3183 assert!(
3184 sql.contains("UPDATE SET"),
3185 "Expected UPDATE SET in: {}",
3186 sql
3187 );
3188 assert!(
3189 sql.contains("WHEN NOT MATCHED"),
3190 "Expected WHEN NOT MATCHED in: {}",
3191 sql
3192 );
3193 assert!(sql.contains("INSERT"), "Expected INSERT in: {}", sql);
3194 }
3195
3196 #[test]
3197 fn test_merge_delete() {
3198 let sql = merge_into("target")
3199 .using("source", col("target.id").eq(col("source.id")))
3200 .when_matched_delete()
3201 .to_sql();
3202 assert!(
3203 sql.contains("MERGE INTO"),
3204 "Expected MERGE INTO in: {}",
3205 sql
3206 );
3207 assert!(
3208 sql.contains("WHEN MATCHED THEN DELETE"),
3209 "Expected WHEN MATCHED THEN DELETE in: {}",
3210 sql
3211 );
3212 }
3213
3214 #[test]
3215 fn test_merge_with_condition() {
3216 let sql = merge_into("target")
3217 .using("source", col("target.id").eq(col("source.id")))
3218 .when_matched_update_where(
3219 col("source.active").eq(boolean(true)),
3220 vec![("name", col("source.name"))],
3221 )
3222 .to_sql();
3223 assert!(
3224 sql.contains("MERGE INTO"),
3225 "Expected MERGE INTO in: {}",
3226 sql
3227 );
3228 assert!(
3229 sql.contains("AND source.active = TRUE"),
3230 "Expected condition in: {}",
3231 sql
3232 );
3233 }
3234}