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